diff --git a/.env.example b/.env.example index e392ece8..db3aa8a9 100644 --- a/.env.example +++ b/.env.example @@ -10,6 +10,8 @@ APP_FALLBACK_LOCALE=en APP_FAKER_LOCALE=de_DE APP_MAINTENANCE_DRIVER=file APP_MAINTENANCE_STORE=database +PHP_CLI_SERVER_WORKERS=4 + BCRYPT_ROUNDS=12 LOG_CHANNEL=stack @@ -45,7 +47,7 @@ SESSION_DOMAIN=null #MAIL_PORT=1025 #MAIL_USERNAME=null #MAIL_PASSWORD=null -#MAIL_ENCRYPTION=null +MAIL_SCHEME=null #MAIL_FROM_ADDRESS="hello@example.com" #MAIL_FROM_NAME="${APP_NAME}" diff --git a/.gitignore b/.gitignore index 1cb27830..a338fa83 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /public/build /public/storage /storage/*.key +/storage/pail /vendor .env .env.testing @@ -15,6 +16,7 @@ Homestead.yaml npm-debug.log yarn-error.log /.idea +/.nova /.vscode /public/css/app.css /public/js/app.js diff --git a/app/Console/Commands/LegacyChangeBankAccountId.php b/app/Console/Commands/LegacyChangeBankAccountId.php index d5714fcf..8e4925fd 100644 --- a/app/Console/Commands/LegacyChangeBankAccountId.php +++ b/app/Console/Commands/LegacyChangeBankAccountId.php @@ -29,7 +29,7 @@ class LegacyChangeBankAccountId extends Command /** * Execute the console command. */ - public function handle() + public function handle(): int { return DB::transaction(function () { $oldId = $this->argument('old-id'); diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index e749914f..2e8af07a 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -2,12 +2,4 @@ namespace App\Http\Controllers; -use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Illuminate\Foundation\Bus\DispatchesJobs; -use Illuminate\Foundation\Validation\ValidatesRequests; -use Illuminate\Routing\Controller as BaseController; - -abstract class Controller extends BaseController -{ - use AuthorizesRequests, DispatchesJobs, ValidatesRequests; -} +abstract class Controller {} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index a053d2c1..5ffb7bdc 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -10,7 +10,7 @@ class Authenticate extends Middleware { - public function handle($request, Closure $next, ...$guards): Response + public function handle(Request $request, Closure $next, ...$guards): Response { // do it like in the parent $this->authenticate($request, $guards); diff --git a/artisan b/artisan index 8e04b422..c35e31d6 100644 --- a/artisan +++ b/artisan @@ -1,6 +1,7 @@ #!/usr/bin/env php handleCommand(new ArgvInput); +/** @var Application $app */ +$app = require_once __DIR__.'/bootstrap/app.php'; + +$status = $app->handleCommand(new ArgvInput); exit($status); diff --git a/composer.json b/composer.json index 679f0fb0..dc370575 100644 --- a/composer.json +++ b/composer.json @@ -8,41 +8,43 @@ "ext-bcmath": "*", "ext-pdo": "*", "ext-zip": "*", - "blade-ui-kit/blade-heroicons": "^2.3", + "blade-ui-kit/blade-heroicons": "^2.6", "defuse/php-encryption": "^2.3", "globalcitizen/php-iban": "^4.2", "guzzlehttp/guzzle": "^7.8", - "intervention/validation": "^4.4", + "intervention/validation": "^4.5", "jumbojett/openid-connect-php": "^1.0", - "laravel/framework": "^11.41", - "livewire/flux": "^1.0", + "laravel/framework": "12.x-dev", + "livewire/flux": "^1.1", "livewire/flux-pro": "^1.0", "livewire/livewire": "^v3.5", "maatwebsite/excel": "^3.1", "meyfa/php-svg": "^0.11.3", "nemiah/php-fints": "dev-master", "open-administration/php-latex-renderer": "^1.1", - "owenvoke/blade-fontawesome": "^2.6", + "owenvoke/blade-fontawesome": "^2.9", "propaganistas/laravel-phone": "^5.3", "socialiteproviders/laravelpassport": "^4.3", - "spatie/laravel-backup": "^8.6", + "spatie/laravel-backup": "^9.2", "spatie/regex": "*" }, "require-dev": { - "barryvdh/laravel-debugbar": "^3.12", - "barryvdh/laravel-ide-helper": "^3.0", + "barryvdh/laravel-debugbar": "^3.15", + "barryvdh/laravel-ide-helper": "^3.5", "fakerphp/faker": "^1.23", - "larastan/larastan": "^2.9", + "larastan/larastan": "^3.1", "laravel/pint": "^1.20", - "laravel/sail": "^1.26", - "laravel/tinker": "^2.9", + "laravel/sail": "^1.41", + "laravel/tinker": "^2.10.1", "magentron/laravel-blade-lint": "^2.0", "mockery/mockery": "^1.6", - "nunomaduro/collision": "^8.0", + "nunomaduro/collision": "^8.6", "pestphp/pest": "^2.34", "pestphp/pest-plugin-laravel": "^2.4", "pestphp/pest-plugin-livewire": "^2.1", - "roave/security-advisories": "dev-latest" + "roave/security-advisories": "dev-latest", + "laravel/pail": "^1.2.2", + "phpunit/phpunit": "^11.5.3" }, "autoload": { "psr-4": { @@ -75,6 +77,10 @@ ], "post-create-project-cmd": [ "@php artisan key:generate --ansi" + ], + "dev": [ + "Composer\\Config::disableProcessTimeout", + "npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen --tries=1\" \"php artisan pail --timeout=0\" \"npm run dev\" --names=server,queue,logs,vite" ] }, "extra": { diff --git a/config/database.php b/config/database.php index f2d610e8..6dab0df8 100644 --- a/config/database.php +++ b/config/database.php @@ -1,19 +1,78 @@ env('DB_CONNECTION', 'sqlite'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Below are all of the database connections defined for your application. + | An example configuration is provided for each database system which + | is supported by Laravel. You're free to add / remove connections. + | + */ + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DB_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + 'busy_timeout' => null, + 'journal_mode' => null, + 'synchronous' => null, + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + 'mariadb' => [ 'driver' => 'mariadb', 'url' => env('DB_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), - 'database' => env('DB_DATABASE', 'forge'), - 'username' => env('DB_USERNAME', 'forge'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), - 'charset' => 'utf8mb4', - 'collation' => 'utf8mb4_unicode_ci', + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), 'prefix' => env('DB_TABLE_PREFIX', ''), 'prefix_indexes' => true, 'strict' => false, // laravel suggested true @@ -42,11 +101,94 @@ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + ], + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run on the database. + | + */ + 'migrations' => [ 'table' => 'migrations', 'update_date_on_publish' => false, // disable to preserve original behavior for existing applications ], + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as Memcached. You may define your connection settings here. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + 'persistent' => env('REDIS_PERSISTENT', false), + ], + + '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'), + ], + + '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/config/filesystems.php b/config/filesystems.php index f0ceef74..660fec11 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -2,11 +2,40 @@ return [ + /* + |-------------------------------------------------------------------------- + | Default Filesystem Disk + |-------------------------------------------------------------------------- + | + | Here you may specify the default filesystem disk that should be used + | by the framework. The "local" disk, as well as a variety of cloud + | based disks are available to your application for file storage. + | + */ + + 'default' => env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Below you may configure as many filesystem disks as necessary, and you + | may even configure multiple disks for the same driver. Examples for + | most supported storage drivers are configured here for reference. + | + | Supported drivers: "local", "ftp", "sftp", "s3" + | + */ + 'disks' => [ + 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), + 'serve' => true, 'throw' => false, + 'report' => false, ], 'backups' => [ @@ -26,6 +55,44 @@ 'root' => storage_path('demo'), 'throw' => false, ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + 'throw' => false, + 'report' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + 'report' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), ], ]; diff --git a/config/mail.php b/config/mail.php index 44352036..ff262cba 100644 --- a/config/mail.php +++ b/config/mail.php @@ -2,10 +2,102 @@ return [ + /* + |-------------------------------------------------------------------------- + | Default Mailer + |-------------------------------------------------------------------------- + | + | This option controls the default mailer that is used to send all email + | messages unless another mailer is explicitly specified when sending + | the message. All additional mailers can be configured within the + | "mailers" array. Examples of each type of mailer are provided. + | + */ + + 'default' => env('MAIL_MAILER', 'log'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers that can be used + | when delivering an email. You may specify which one you're using for + | your mailers below. You may also add additional mailers if needed. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", + | "postmark", "resend", "log", "array", + | "failover", "roundrobin" + | + */ + 'mailers' => [ 'mailgun' => [ 'transport' => 'mailgun', ], + + 'smtp' => [ + 'transport' => 'smtp', + 'scheme' => env('MAIL_SCHEME'), + 'url' => env('MAIL_URL'), + 'host' => env('MAIL_HOST', '127.0.0.1'), + 'port' => env('MAIL_PORT', 2525), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL', 'http://localhost'), PHP_URL_HOST)), + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'postmark' => [ + 'transport' => 'postmark', + // 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'), + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'resend' => [ + 'transport' => 'resend', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + ], + + 'roundrobin' => [ + 'transport' => 'roundrobin', + 'mailers' => [ + 'ses', + 'postmark', + ], + ], + ], 'markdown' => [ @@ -16,4 +108,20 @@ ], ], + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all emails sent by your application to be sent from + | the same address. Here you may specify a name and address that is + | used globally for all emails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + ]; diff --git a/config/services.php b/config/services.php index 24ecad49..6ff99a9a 100644 --- a/config/services.php +++ b/config/services.php @@ -63,4 +63,37 @@ ], ], + /* + |-------------------------------------------------------------------------- + | Third Party Services + |-------------------------------------------------------------------------- + | + | This file is for storing the credentials for third party services such + | as Mailgun, Postmark, AWS and more. This file provides the de facto + | location for this type of information, allowing packages to have + | a conventional file to locate the various service credentials. + | + */ + + 'postmark' => [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'resend' => [ + 'key' => env('RESEND_KEY'), + ], + + 'slack' => [ + 'notifications' => [ + 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), + 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'), + ], + ], + ]; diff --git a/package.json b/package.json index c796782f..1783a2e5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "axios": "^0.28", "tailwindcss": "^3.0.24", "vite": "^3.0.2", - "laravel-vite-plugin": "^0.6.0" + "laravel-vite-plugin": "^0.6.0", + "concurrently": "^9.0.1" }, "dependencies": { "@tailwindcss/aspect-ratio": "^0.4.2", diff --git a/public/.htaccess b/public/.htaccess index 3aec5e27..b574a597 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -9,6 +9,10 @@ RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + # Handle X-XSRF-Token Header + RewriteCond %{HTTP:x-xsrf-token} . + RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}] + # Redirect Trailing Slashes If Not A Folder... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ diff --git a/public/index.php b/public/index.php index 947d9896..ee8f07e9 100644 --- a/public/index.php +++ b/public/index.php @@ -1,5 +1,6 @@ handleRequest(Request::capture()); +/** @var Application $app */ +$app = require_once __DIR__.'/../bootstrap/app.php'; + +$app->handleRequest(Request::capture()); diff --git a/storage/app/.gitignore b/storage/app/.gitignore index 8f4803c0..fedb287f 100644 --- a/storage/app/.gitignore +++ b/storage/app/.gitignore @@ -1,3 +1,4 @@ * +!private/ !public/ !.gitignore diff --git a/storage/app/private/.gitignore b/storage/app/private/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/storage/app/private/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore