diff --git a/src/app/Console/Kernel.php b/src/app/Console/Kernel.php --- a/src/app/Console/Kernel.php +++ b/src/app/Console/Kernel.php @@ -11,10 +11,8 @@ * Define the application's command schedule. * * @param Schedule $schedule The application's command schedule - * - * @return void */ - protected function schedule(Schedule $schedule) + protected function schedule(Schedule $schedule): void { // This imports countries and the current set of IPv4 and IPv6 networks allocated to countries. $schedule->command('data:import')->dailyAt('05:00'); @@ -33,14 +31,15 @@ // This collects some statistics into the database $schedule->command('data:stats:collector')->dailyAt('23:00'); + + // https://laravel.com/docs/10.x/upgrade#redis-cache-tags + $schedule->command('cache:prune-stale-tags')->hourly(); } /** * Register the commands for the application. - * - * @return void */ - protected function commands() + protected function commands(): void { $this->load(__DIR__ . '/Commands'); diff --git a/src/app/Exceptions/Handler.php b/src/app/Exceptions/Handler.php --- a/src/app/Exceptions/Handler.php +++ b/src/app/Exceptions/Handler.php @@ -25,7 +25,7 @@ /** * Register the exception handling callbacks for the application. */ - public function register() + public function register(): void { $this->reportable(function (\Throwable $e) { // Rollback uncommitted transactions diff --git a/src/app/Http/Kernel.php b/src/app/Http/Kernel.php --- a/src/app/Http/Kernel.php +++ b/src/app/Http/Kernel.php @@ -58,7 +58,7 @@ * * @var array */ - protected $routeMiddleware = [ + protected $middlewareAliases = [ 'admin' => \App\Http\Middleware\AuthenticateAdmin::class, 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, diff --git a/src/app/Http/Middleware/TrustHosts.php b/src/app/Http/Middleware/TrustHosts.php --- a/src/app/Http/Middleware/TrustHosts.php +++ b/src/app/Http/Middleware/TrustHosts.php @@ -11,7 +11,7 @@ * * @return array */ - public function hosts() + public function hosts(): array { return [ $this->allSubdomainsOfApplicationUrl(), diff --git a/src/app/Providers/AppServiceProvider.php b/src/app/Providers/AppServiceProvider.php --- a/src/app/Providers/AppServiceProvider.php +++ b/src/app/Providers/AppServiceProvider.php @@ -13,10 +13,8 @@ { /** * Register any application services. - * - * @return void */ - public function register() + public function register(): void { Passport::ignoreMigrations(); Passport::ignoreRoutes(); @@ -62,10 +60,8 @@ /** * Bootstrap any application services. - * - * @return void */ - public function boot() + public function boot(): void { \App\Domain::observe(\App\Observers\DomainObserver::class); \App\Entitlement::observe(\App\Observers\EntitlementObserver::class); diff --git a/src/app/Providers/AuthServiceProvider.php b/src/app/Providers/AuthServiceProvider.php --- a/src/app/Providers/AuthServiceProvider.php +++ b/src/app/Providers/AuthServiceProvider.php @@ -16,11 +16,8 @@ /** * Register any authentication / authorization services. - * - * @return void */ - public function boot() + public function boot(): void { - $this->registerPolicies(); } } diff --git a/src/app/Providers/BroadcastServiceProvider.php b/src/app/Providers/BroadcastServiceProvider.php --- a/src/app/Providers/BroadcastServiceProvider.php +++ b/src/app/Providers/BroadcastServiceProvider.php @@ -9,10 +9,8 @@ { /** * Bootstrap any application services. - * - * @return void */ - public function boot() + public function boot(): void { Broadcast::routes(); diff --git a/src/app/Providers/EventServiceProvider.php b/src/app/Providers/EventServiceProvider.php --- a/src/app/Providers/EventServiceProvider.php +++ b/src/app/Providers/EventServiceProvider.php @@ -22,20 +22,16 @@ /** * Register any events for your application. - * - * @return void */ - public function boot() + public function boot(): void { // } /** * Determine if events and listeners should be automatically discovered. - * - * @return bool */ - public function shouldDiscoverEvents() + public function shouldDiscoverEvents(): bool { return false; } diff --git a/src/app/Providers/RouteServiceProvider.php b/src/app/Providers/RouteServiceProvider.php --- a/src/app/Providers/RouteServiceProvider.php +++ b/src/app/Providers/RouteServiceProvider.php @@ -12,10 +12,8 @@ { /** * Define your route model bindings, pattern filters, etc. - * - * @return void */ - public function boot() + public function boot(): void { $this->configureRateLimiting(); @@ -32,10 +30,8 @@ /** * Configure the rate limiters for the application. - * - * @return void */ - protected function configureRateLimiting() + protected function configureRateLimiting(): void { RateLimiter::for('api', function (Request $request) { return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); diff --git a/src/composer.json b/src/composer.json --- a/src/composer.json +++ b/src/composer.json @@ -16,30 +16,30 @@ "require": { "php": "^8.1", "bacon/bacon-qr-code": "^2.0", - "barryvdh/laravel-dompdf": "^2.0.0", - "doctrine/dbal": "^3.3.2", - "dyrynda/laravel-nullable-fields": "^4.2.0", + "barryvdh/laravel-dompdf": "^2.0.1", + "doctrine/dbal": "^3.6", + "dyrynda/laravel-nullable-fields": "^4.3.0", "guzzlehttp/guzzle": "^7.4.1", "kolab/net_ldap3": "dev-master", - "laravel/framework": "^9.2", + "laravel/framework": "^10.15.0", "laravel/horizon": "^5.9", - "laravel/octane": "^1.2", + "laravel/octane": "^2.0", "laravel/passport": "^11.3", - "laravel/tinker": "^2.7", + "laravel/tinker": "^2.8", "league/flysystem-aws-s3-v3": "^3.0", "mlocati/spf-lib": "^3.1", - "mollie/laravel-mollie": "^2.19", + "mollie/laravel-mollie": "^2.22", "pear/crypt_gpg": "^1.6.6", "predis/predis": "^2.0", "sabre/vobject": "^4.5", - "spatie/laravel-translatable": "^6.3", + "spatie/laravel-translatable": "^6.5", "spomky-labs/otphp": "~10.0.0", "stripe/stripe-php": "^10.7", "lcobucci/jwt": "^5.0" }, "require-dev": { "code-lts/doctum": "^5.5.1", - "laravel/dusk": "~7.5.0", + "laravel/dusk": "~7.8.0", "mockery/mockery": "^1.5", "nunomaduro/larastan": "^2.0", "phpstan/phpstan": "^1.4", diff --git a/src/config/app.php b/src/config/app.php --- a/src/config/app.php +++ b/src/config/app.php @@ -1,5 +1,8 @@ env('APP_DEBUG', false), + 'debug' => (bool) env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- @@ -165,33 +168,7 @@ | */ - 'providers' => [ - /* - * Laravel Framework Service Providers... - */ - Illuminate\Auth\AuthServiceProvider::class, - Illuminate\Broadcasting\BroadcastServiceProvider::class, - Illuminate\Bus\BusServiceProvider::class, - Illuminate\Cache\CacheServiceProvider::class, - Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, - Illuminate\Cookie\CookieServiceProvider::class, - Illuminate\Database\DatabaseServiceProvider::class, - Illuminate\Encryption\EncryptionServiceProvider::class, - Illuminate\Filesystem\FilesystemServiceProvider::class, - Illuminate\Foundation\Providers\FoundationServiceProvider::class, - Illuminate\Hashing\HashServiceProvider::class, - Illuminate\Mail\MailServiceProvider::class, - Illuminate\Notifications\NotificationServiceProvider::class, - Illuminate\Pagination\PaginationServiceProvider::class, - Illuminate\Pipeline\PipelineServiceProvider::class, - Illuminate\Queue\QueueServiceProvider::class, - Illuminate\Redis\RedisServiceProvider::class, - Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, - Illuminate\Session\SessionServiceProvider::class, - Illuminate\Translation\TranslationServiceProvider::class, - Illuminate\Validation\ValidationServiceProvider::class, - Illuminate\View\ViewServiceProvider::class, - + 'providers' => ServiceProvider::defaultProviders()->merge([ /* * Application Service Providers... */ @@ -202,7 +179,7 @@ App\Providers\HorizonServiceProvider::class, App\Providers\PassportServiceProvider::class, App\Providers\RouteServiceProvider::class, - ], + ])->toArray(), /* |-------------------------------------------------------------------------- @@ -215,7 +192,7 @@ | */ - 'aliases' => \Illuminate\Support\Facades\Facade::defaultAliases()->toArray(), + 'aliases' => Facade::defaultAliases()->toArray(), 'headers' => [ 'csp' => env('APP_HEADER_CSP', ""), diff --git a/src/config/auth.php b/src/config/auth.php --- a/src/config/auth.php +++ b/src/config/auth.php @@ -31,7 +31,7 @@ | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | - | Supported: "session", "token" + | Supported: "session" | */ @@ -85,10 +85,14 @@ | than one user table or model in the application and you want to have | separate password reset settings based on the specific user types. | - | The expire time is the number of minutes that the reset token should be + | The expire time is the number of minutes that each reset token will be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | */ 'passwords' => [ @@ -96,9 +100,22 @@ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, + 'throttle' => 60, ], ], + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | times out and the user is prompted to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + */ + + 'password_timeout' => 10800, + /* |-------------------------------------------------------------------------- diff --git a/src/config/broadcasting.php b/src/config/broadcasting.php --- a/src/config/broadcasting.php +++ b/src/config/broadcasting.php @@ -37,7 +37,11 @@ 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), - 'useTLS' => true, + 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', + 'port' => env('PUSHER_PORT', 443), + 'scheme' => env('PUSHER_SCHEME', 'https'), + 'encrypted' => true, + 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https', ], 'client_options' => [ // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html diff --git a/src/config/cache.php b/src/config/cache.php --- a/src/config/cache.php +++ b/src/config/cache.php @@ -12,10 +12,6 @@ | This option controls the default cache connection that gets used while | using this caching library. This connection is used when another is | not explicitly specified when executing a given caching function. - | - | Supported: "apc", "array", "database", "file", - | "memcached", "redis", "dynamodb" - | */ 'default' => env('CACHE_DRIVER', 'redis'), @@ -29,6 +25,8 @@ | well as their drivers. You may even define multiple stores for the | same cache driver to group types of items stored in your caches. | + | Supported drivers: "apc", "array", "database", "file", + | "memcached", "redis", "dynamodb", "octane", "null" */ 'stores' => [ @@ -52,6 +50,7 @@ 'file' => [ 'driver' => 'file', 'path' => storage_path('framework/cache/data'), + 'lock_path' => storage_path('framework/cache/data'), ], 'memcached' => [ diff --git a/src/config/cors.php b/src/config/cors.php new file mode 100644 --- /dev/null +++ b/src/config/cors.php @@ -0,0 +1,34 @@ + ['api/*', 'sanctum/csrf-cookie'], + + 'allowed_methods' => ['*'], + + 'allowed_origins' => ['*'], + + 'allowed_origins_patterns' => [], + + 'allowed_headers' => ['*'], + + 'exposed_headers' => [], + + 'max_age' => 0, + + 'supports_credentials' => false, + +]; diff --git a/src/config/database.php b/src/config/database.php --- a/src/config/database.php +++ b/src/config/database.php @@ -135,6 +135,7 @@ 'default' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_DB', 0), @@ -143,6 +144,7 @@ 'cache' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', 6379), 'database' => env('REDIS_CACHE_DB', 1), diff --git a/src/config/filesystems.php b/src/config/filesystems.php --- a/src/config/filesystems.php +++ b/src/config/filesystems.php @@ -33,6 +33,7 @@ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), + 'throw' => false, ], 'files' => [ @@ -50,6 +51,7 @@ 'root' => storage_path('app/public'), 'url' => env('APP_URL') . '/storage', 'visibility' => 'public', + 'throw' => false, ], 'minio' => [ @@ -71,6 +73,7 @@ 'url' => env('AWS_URL'), 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, ], ], diff --git a/src/config/logging.php b/src/config/logging.php --- a/src/config/logging.php +++ b/src/config/logging.php @@ -30,7 +30,10 @@ | */ - 'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => false, + ], /* |-------------------------------------------------------------------------- @@ -52,12 +55,14 @@ 'driver' => 'stack', 'channels' => ['daily'], 'ignore_exceptions' => false, + 'replace_placeholders' => true, ], 'single' => [ 'driver' => 'single', 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, ], 'daily' => [ @@ -65,6 +70,7 @@ 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), 'days' => 14, + 'replace_placeholders' => true, ], 'slack' => [ @@ -73,6 +79,7 @@ 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, ], 'papertrail' => [ @@ -109,11 +116,14 @@ 'syslog' => [ 'driver' => 'syslog', 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => LOG_USER, + 'replace_placeholders' => true, ], 'errorlog' => [ 'driver' => 'errorlog', 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, ], 'null' => [ diff --git a/src/config/mail.php b/src/config/mail.php --- a/src/config/mail.php +++ b/src/config/mail.php @@ -28,7 +28,7 @@ | sending an e-mail. You will specify which one you are using for your | mailers below. You are free to add additional mailers as required. | - | Supported: "smtp", "sendmail", "mailgun", "ses", + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", | "postmark", "log", "array", "failover" | */ @@ -36,12 +36,14 @@ 'mailers' => [ 'smtp' => [ 'transport' => 'smtp', + 'url' => env('MAIL_URL'), 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 'port' => env('MAIL_PORT', 587), 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'timeout' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN'), ], 'ses' => [ diff --git a/src/config/queue.php b/src/config/queue.php --- a/src/config/queue.php +++ b/src/config/queue.php @@ -73,6 +73,24 @@ ], + + /* + |-------------------------------------------------------------------------- + | Job Batching + |-------------------------------------------------------------------------- + | + | The following options configure the database and table that store job + | batching information. These options can be updated to any database + | connection and table which has been defined by your application. + | + */ + + 'batching' => [ + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'job_batches', + ], + + /* |-------------------------------------------------------------------------- | Failed Queue Jobs diff --git a/src/tests/Browser/Admin/UserTest.php b/src/tests/Browser/Admin/UserTest.php --- a/src/tests/Browser/Admin/UserTest.php +++ b/src/tests/Browser/Admin/UserTest.php @@ -86,8 +86,11 @@ { $this->browse(function (Browser $browser) { $jack = $this->getTestUser('jack@kolab.org'); - $jack->setSetting('limit_geo', null); - $jack->setSetting('guam_enabled', null); + $jack->setSettings([ + 'limit_geo' => null, + 'organization' => null, + 'guam_enabled' => null, + ]); $page = new UserPage($jack->id); diff --git a/src/tests/Browser/Reseller/UserTest.php b/src/tests/Browser/Reseller/UserTest.php --- a/src/tests/Browser/Reseller/UserTest.php +++ b/src/tests/Browser/Reseller/UserTest.php @@ -83,7 +83,10 @@ { $this->browse(function (Browser $browser) { $jack = $this->getTestUser('jack@kolab.org'); - $jack->setSetting('limit_geo', null); + $jack->setSettings([ + 'limit_geo' => null, + 'organization' => null, + ]); $page = new UserPage($jack->id); $browser->visit(new Home())