From 18d63a3375af2180440562c93089e2cf3cf9a224 Mon Sep 17 00:00:00 2001 From: Darko Gjorgjijoski <5760249+gdarko@users.noreply.github.com> Date: Fri, 19 Sep 2025 15:42:53 +0200 Subject: [PATCH] Configurations cleanup & database configurations for mail and pdfs (#479) * Move Mail, PDF configuration to Database, standardize configurations * Set default currency to USD on install * Pint code --- .env.example | 46 +--- .../Settings/MailConfigurationController.php | 134 +++++++++-- .../Settings/PDFConfigurationController.php | 60 ++++- app/Http/Middleware/ConfigMiddleware.php | 10 +- app/Http/Requests/MailEnvironmentRequest.php | 114 +++++---- app/Http/Requests/PDFConfigurationRequest.php | 17 +- app/Models/FileDisk.php | 2 +- app/Providers/AppConfigProvider.php | 176 ++++++++++++++ .../PDFDrivers/GotenbergPDFDriver.php | 4 +- app/Space/EnvironmentManager.php | 217 ------------------ bootstrap/providers.php | 1 + config/abilities.php | 13 ++ config/app.php | 14 +- config/auth.php | 67 +++++- config/cache.php | 12 + config/filesystems.php | 51 ++-- config/pdf.php | 34 ++- config/queue.php | 107 +++++++++ config/services.php | 34 +-- config/session.php | 217 ++++++++++++++++++ docker/production/docker-compose.mysql.yml | 7 - docker/production/docker-compose.sqlite.yml | 7 - docker/production/inject.sh | 32 --- .../installation/Step8CompanyPreferences.vue | 2 +- 24 files changed, 943 insertions(+), 435 deletions(-) create mode 100644 app/Providers/AppConfigProvider.php create mode 100644 config/session.php diff --git a/.env.example b/.env.example index 14639de9..4b158bf0 100644 --- a/.env.example +++ b/.env.example @@ -1,19 +1,11 @@ APP_ENV=production +APP_DEBUG=false APP_KEY=base64:kgk/4DW1vEVy7aEvet5FPp5un6PIGe/so8H0mvoUtW0= -APP_DEBUG=true + APP_NAME="InvoiceShelf" -APP_LOG_LEVEL=debug APP_TIMEZONE=UTC APP_URL= - APP_LOCALE=en -APP_FALLBACK_LOCALE=en -APP_FAKER_LOCALE=en_US - -APP_MAINTENANCE_DRIVER=file -APP_MAINTENANCE_STORE=database - -BCRYPT_ROUNDS=12 DB_CONNECTION=sqlite DB_HOST= @@ -22,38 +14,6 @@ DB_DATABASE= DB_USERNAME= DB_PASSWORD= -BROADCAST_CONNECTION=log -CACHE_STORE=file -QUEUE_CONNECTION=sync -SESSION_DRIVER=file -SESSION_LIFETIME=1440 -SESSION_ENCRYPT=false -SESSION_PATH=/ SESSION_DOMAIN=null - -REDIS_HOST=127.0.0.1 -REDIS_PASSWORD=null -REDIS_PORT=6379 - -MAIL_MAILER=smtp -MAIL_HOST= -MAIL_PORT= -MAIL_USERNAME= -MAIL_PASSWORD= -MAIL_ENCRYPTION= - -MAIL_FROM_NAME= -MAIL_FROM_ADDRESS= - -PUSHER_APP_ID= -PUSHER_KEY= -PUSHER_SECRET= - +SANCTUM_STATEFUL_DOMAIN= TRUSTED_PROXIES="*" - -CRON_JOB_AUTH_TOKEN="" -LOG_STACK=single - -PDF_DRIVER=dompdf -GOTENBERG_HOST= -GOTENBERG_PAPERSIZE= diff --git a/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php b/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php index a89f4d50..3128a360 100755 --- a/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php +++ b/app/Http/Controllers/V1/Admin/Settings/MailConfigurationController.php @@ -41,13 +41,79 @@ class MailConfigurationController extends Controller $this->authorize('manage email config'); $setting = Setting::getSetting('profile_complete'); - $results = $this->environmentManager->saveMailVariables($request); + + // Prepare mail settings for database storage + $mailSettings = $this->prepareMailSettingsForDatabase($request); + + // Save mail settings to database + Setting::setSettings($mailSettings); if ($setting !== 'COMPLETED') { Setting::setSetting('profile_complete', 4); } - return response()->json($results); + return response()->json([ + 'success' => 'mail_variables_save_successfully', + ]); + } + + /** + * Prepare mail settings for database storage + * + * @return array + */ + private function prepareMailSettingsForDatabase(MailEnvironmentRequest $request) + { + $driver = $request->get('mail_driver'); + + // Base settings that are always saved + $settings = [ + 'mail_driver' => $driver, + 'from_name' => $request->get('from_name'), + 'from_mail' => $request->get('from_mail'), + ]; + + // Driver-specific settings + switch ($driver) { + case 'smtp': + $settings = array_merge($settings, [ + 'mail_host' => $request->get('mail_host'), + 'mail_port' => $request->get('mail_port'), + 'mail_username' => $request->get('mail_username'), + 'mail_password' => $request->get('mail_password'), + 'mail_encryption' => $request->get('mail_encryption', 'none'), + 'mail_scheme' => $request->get('mail_scheme'), + 'mail_url' => $request->get('mail_url'), + 'mail_timeout' => $request->get('mail_timeout'), + 'mail_local_domain' => $request->get('mail_local_domain'), + ]); + break; + + case 'mailgun': + $settings = array_merge($settings, [ + 'mail_mailgun_domain' => $request->get('mail_mailgun_domain'), + 'mail_mailgun_secret' => $request->get('mail_mailgun_secret'), + 'mail_mailgun_endpoint' => $request->get('mail_mailgun_endpoint', 'api.mailgun.net'), + 'mail_mailgun_scheme' => $request->get('mail_mailgun_scheme', 'https'), + ]); + break; + + case 'ses': + $settings = array_merge($settings, [ + 'mail_ses_key' => $request->get('mail_ses_key'), + 'mail_ses_secret' => $request->get('mail_ses_secret'), + 'mail_ses_region' => $request->get('mail_ses_region', 'us-east-1'), + ]); + break; + + case 'sendmail': + $settings = array_merge($settings, [ + 'mail_sendmail_path' => $request->get('mail_sendmail_path', '/usr/sbin/sendmail -bs -i'), + ]); + break; + } + + return $settings; } /** @@ -61,51 +127,75 @@ class MailConfigurationController extends Controller { $this->authorize('manage email config'); - $driver = config('mail.default'); + // Get mail settings from database + $mailSettings = Setting::getSettings([ + 'mail_driver', + 'mail_host', + 'mail_port', + 'mail_username', + 'mail_password', + 'mail_encryption', + 'mail_scheme', + 'mail_url', + 'mail_timeout', + 'mail_local_domain', + 'from_name', + 'from_mail', + 'mail_mailgun_domain', + 'mail_mailgun_secret', + 'mail_mailgun_endpoint', + 'mail_mailgun_scheme', + 'mail_ses_key', + 'mail_ses_secret', + 'mail_ses_region', + 'mail_sendmail_path', + ]); + + $driver = $mailSettings['mail_driver'] ?? config('mail.default'); // Base data that's always available $MailData = [ 'mail_driver' => $driver, - 'from_name' => config('mail.from.name'), - 'from_mail' => config('mail.from.address'), + 'from_name' => $mailSettings['from_name'] ?? config('mail.from.name'), + 'from_mail' => $mailSettings['from_mail'] ?? config('mail.from.address'), ]; // Driver-specific configuration switch ($driver) { case 'smtp': $MailData = array_merge($MailData, [ - 'mail_host' => config('mail.mailers.smtp.host'), - 'mail_port' => config('mail.mailers.smtp.port'), - 'mail_username' => config('mail.mailers.smtp.username'), - 'mail_password' => config('mail.mailers.smtp.password'), - 'mail_encryption' => config('mail.mailers.smtp.scheme') ?? 'none', - 'mail_scheme' => config('mail.mailers.smtp.scheme'), - 'mail_url' => config('mail.mailers.smtp.url'), - 'mail_timeout' => config('mail.mailers.smtp.timeout'), - 'mail_local_domain' => config('mail.mailers.smtp.local_domain'), + 'mail_host' => $mailSettings['mail_host'] ?? '', + 'mail_port' => $mailSettings['mail_port'] ?? '', + 'mail_username' => $mailSettings['mail_username'] ?? '', + 'mail_password' => $mailSettings['mail_password'] ?? '', + 'mail_encryption' => $mailSettings['mail_encryption'] ?? 'none', + 'mail_scheme' => $mailSettings['mail_scheme'] ?? '', + 'mail_url' => $mailSettings['mail_url'] ?? '', + 'mail_timeout' => $mailSettings['mail_timeout'] ?? '', + 'mail_local_domain' => $mailSettings['mail_local_domain'] ?? '', ]); break; case 'mailgun': $MailData = array_merge($MailData, [ - 'mail_mailgun_domain' => config('mail.mailers.mailgun.domain'), - 'mail_mailgun_secret' => config('mail.mailers.mailgun.secret'), - 'mail_mailgun_endpoint' => config('mail.mailers.mailgun.endpoint'), - 'mail_mailgun_scheme' => config('mail.mailers.mailgun.scheme'), + 'mail_mailgun_domain' => $mailSettings['mail_mailgun_domain'] ?? '', + 'mail_mailgun_secret' => $mailSettings['mail_mailgun_secret'] ?? '', + 'mail_mailgun_endpoint' => $mailSettings['mail_mailgun_endpoint'] ?? 'api.mailgun.net', + 'mail_mailgun_scheme' => $mailSettings['mail_mailgun_scheme'] ?? 'https', ]); break; case 'ses': $MailData = array_merge($MailData, [ - 'mail_ses_key' => config('services.ses.key'), - 'mail_ses_secret' => config('services.ses.secret'), - 'mail_ses_region' => config('services.ses.region'), + 'mail_ses_key' => $mailSettings['mail_ses_key'] ?? '', + 'mail_ses_secret' => $mailSettings['mail_ses_secret'] ?? '', + 'mail_ses_region' => $mailSettings['mail_ses_region'] ?? 'us-east-1', ]); break; case 'sendmail': $MailData = array_merge($MailData, [ - 'mail_sendmail_path' => config('mail.mailers.sendmail.path'), + 'mail_sendmail_path' => $mailSettings['mail_sendmail_path'] ?? '/usr/sbin/sendmail -bs -i', ]); break; diff --git a/app/Http/Controllers/V1/Admin/Settings/PDFConfigurationController.php b/app/Http/Controllers/V1/Admin/Settings/PDFConfigurationController.php index 61212098..cf520cb9 100644 --- a/app/Http/Controllers/V1/Admin/Settings/PDFConfigurationController.php +++ b/app/Http/Controllers/V1/Admin/Settings/PDFConfigurationController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\V1\Admin\Settings; use App\Http\Controllers\Controller; use App\Http\Requests\PDFConfigurationRequest; +use App\Models\Setting; use App\Space\EnvironmentManager; class PDFConfigurationController extends Controller @@ -34,11 +35,19 @@ class PDFConfigurationController extends Controller { $this->authorize('manage pdf config'); + // Get PDF settings from database + $pdfSettings = Setting::getSettings([ + 'pdf_driver', + 'gotenberg_host', + 'gotenberg_papersize', + 'gotenberg_margins', + ]); + $config = [ - 'pdf_driver' => config('pdf.driver'), - 'gotenberg_host' => config('pdf.gotenberg.host'), - 'gotenberg_margins' => config('pdf.gotenberg.margins'), - 'gotenberg_papersize' => config('pdf.gotenberg.papersize'), + 'pdf_driver' => $pdfSettings['pdf_driver'] ?? config('pdf.driver'), + 'gotenberg_host' => $pdfSettings['gotenberg_host'] ?? config('pdf.connections.gotenberg.host'), + 'gotenberg_margins' => $pdfSettings['gotenberg_margins'] ?? config('pdf.connections.gotenberg.margins'), + 'gotenberg_papersize' => $pdfSettings['gotenberg_papersize'] ?? config('pdf.connections.gotenberg.papersize'), ]; return response()->json($config); @@ -47,8 +56,47 @@ class PDFConfigurationController extends Controller public function saveEnvironment(PDFConfigurationRequest $request) { $this->authorize('manage pdf config'); - $results = $this->environmentManager->savePDFVariables($request); - return response()->json($results); + // Prepare PDF settings for database storage + $pdfSettings = $this->preparePDFSettingsForDatabase($request); + + // Save PDF settings to database + Setting::setSettings($pdfSettings); + + return response()->json([ + 'success' => 'pdf_variables_save_successfully', + ]); + } + + /** + * Prepare PDF settings for database storage + * + * @return array + */ + private function preparePDFSettingsForDatabase(PDFConfigurationRequest $request) + { + $driver = $request->get('pdf_driver'); + + // Base settings that are always saved + $settings = [ + 'pdf_driver' => $driver, + ]; + + // Driver-specific settings + switch ($driver) { + case 'gotenberg': + $settings = array_merge($settings, [ + 'gotenberg_host' => $request->get('gotenberg_host'), + 'gotenberg_papersize' => $request->get('gotenberg_papersize'), + 'gotenberg_margins' => $request->get('gotenberg_margins'), + ]); + break; + + case 'dompdf': + // dompdf doesn't have additional configuration in the current setup + break; + } + + return $settings; } } diff --git a/app/Http/Middleware/ConfigMiddleware.php b/app/Http/Middleware/ConfigMiddleware.php index d4b918ad..bdff4b8e 100644 --- a/app/Http/Middleware/ConfigMiddleware.php +++ b/app/Http/Middleware/ConfigMiddleware.php @@ -18,15 +18,15 @@ class ConfigMiddleware public function handle(Request $request, Closure $next): Response { if (InstallUtils::isDbCreated()) { + // Only handle dynamic file disk switching when file_disk_id is provided if ($request->has('file_disk_id')) { $file_disk = FileDisk::find($request->file_disk_id); - } else { - $file_disk = FileDisk::whereSetAsDefault(true)->first(); - } - if ($file_disk) { - $file_disk->setConfig(); + if ($file_disk) { + $file_disk->setConfig(); + } } + // Default file disk is now handled by AppConfigProvider during boot } return $next($request); diff --git a/app/Http/Requests/MailEnvironmentRequest.php b/app/Http/Requests/MailEnvironmentRequest.php index 2dfc783b..384fdd23 100644 --- a/app/Http/Requests/MailEnvironmentRequest.php +++ b/app/Http/Requests/MailEnvironmentRequest.php @@ -33,10 +33,34 @@ class MailEnvironmentRequest extends FormRequest 'mail_port' => [ 'required', ], + 'mail_username' => [ + 'nullable', + 'string', + ], + 'mail_password' => [ + 'nullable', + 'string', + ], 'mail_encryption' => [ 'nullable', 'string', ], + 'mail_scheme' => [ + 'nullable', + 'string', + ], + 'mail_url' => [ + 'nullable', + 'string', + ], + 'mail_timeout' => [ + 'nullable', + 'integer', + ], + 'mail_local_domain' => [ + 'nullable', + 'string', + ], 'from_name' => [ 'required', 'string', @@ -44,11 +68,10 @@ class MailEnvironmentRequest extends FormRequest 'from_mail' => [ 'required', 'string', + 'email', ], ]; - break; - case 'mailgun': return [ 'mail_driver' => [ @@ -64,43 +87,10 @@ class MailEnvironmentRequest extends FormRequest 'string', ], 'mail_mailgun_endpoint' => [ - 'required', + 'nullable', 'string', ], - 'from_name' => [ - 'required', - 'string', - ], - 'from_mail' => [ - 'required', - 'string', - ], - ]; - - break; - - case 'ses': - return [ - 'mail_driver' => [ - 'required', - 'string', - ], - 'mail_host' => [ - 'required', - 'string', - ], - 'mail_port' => [ - 'required', - ], - 'mail_ses_key' => [ - 'required', - 'string', - ], - 'mail_ses_secret' => [ - 'required', - 'string', - ], - 'mail_encryption' => [ + 'mail_mailgun_scheme' => [ 'nullable', 'string', ], @@ -111,13 +101,28 @@ class MailEnvironmentRequest extends FormRequest 'from_mail' => [ 'required', 'string', + 'email', ], ]; - break; - - case 'mail': + case 'ses': return [ + 'mail_driver' => [ + 'required', + 'string', + ], + 'mail_ses_key' => [ + 'required', + 'string', + ], + 'mail_ses_secret' => [ + 'required', + 'string', + ], + 'mail_ses_region' => [ + 'nullable', + 'string', + ], 'from_name' => [ 'required', 'string', @@ -125,13 +130,20 @@ class MailEnvironmentRequest extends FormRequest 'from_mail' => [ 'required', 'string', + 'email', ], ]; - break; - case 'sendmail': return [ + 'mail_driver' => [ + 'required', + 'string', + ], + 'mail_sendmail_path' => [ + 'nullable', + 'string', + ], 'from_name' => [ 'required', 'string', @@ -139,10 +151,26 @@ class MailEnvironmentRequest extends FormRequest 'from_mail' => [ 'required', 'string', + 'email', ], ]; - break; + default: + return [ + 'mail_driver' => [ + 'required', + 'string', + ], + 'from_name' => [ + 'required', + 'string', + ], + 'from_mail' => [ + 'required', + 'string', + 'email', + ], + ]; } } } diff --git a/app/Http/Requests/PDFConfigurationRequest.php b/app/Http/Requests/PDFConfigurationRequest.php index 19f4dd85..3e6ef3ec 100644 --- a/app/Http/Requests/PDFConfigurationRequest.php +++ b/app/Http/Requests/PDFConfigurationRequest.php @@ -27,7 +27,6 @@ class PDFConfigurationRequest extends FormRequest 'string', ], ]; - break; case 'gotenberg': return [ @@ -40,18 +39,28 @@ class PDFConfigurationRequest extends FormRequest 'url', ], 'gotenberg_papersize' => [ + 'required', + 'string', function ($attribute, $value, $fail) { - ($attribute); // unused $reg = "/^\d+(pt|px|pc|mm|cm|in) \d+(pt|px|pc|mm|cm|in)$/"; if (! preg_match($reg, $value)) { $fail('Invalid papersize, must be in format "210mm 297mm". Accepts: pt,px,pc,mm,cm,in'); } }, ], + 'gotenberg_margins' => [ + 'nullable', + 'string', + ], ]; - break; + default: + return [ + 'pdf_driver' => [ + 'required', + 'string', + ], + ]; } - throw new \InvalidArgumentException('Invalid PDFDriver requested'); } } diff --git a/app/Models/FileDisk.php b/app/Models/FileDisk.php index 01725219..0755dcce 100644 --- a/app/Models/FileDisk.php +++ b/app/Models/FileDisk.php @@ -2,7 +2,7 @@ namespace App\Models; -use App\Carbon; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; diff --git a/app/Providers/AppConfigProvider.php b/app/Providers/AppConfigProvider.php new file mode 100644 index 00000000..d36e4931 --- /dev/null +++ b/app/Providers/AppConfigProvider.php @@ -0,0 +1,176 @@ +configureMailFromDatabase(); + $this->configurePDFFromDatabase(); + $this->configureFileSystemFromDatabase(); + } + + /** + * Configure mail settings from database + */ + protected function configureMailFromDatabase(): void + { + try { + // Get mail settings from database + $mailSettings = Setting::getSettings([ + 'mail_driver', + 'mail_host', + 'mail_port', + 'mail_username', + 'mail_password', + 'mail_encryption', + 'mail_scheme', + 'mail_url', + 'mail_timeout', + 'mail_local_domain', + 'from_name', + 'from_mail', + 'mail_mailgun_domain', + 'mail_mailgun_secret', + 'mail_mailgun_endpoint', + 'mail_mailgun_scheme', + 'mail_ses_key', + 'mail_ses_secret', + 'mail_ses_region', + 'mail_sendmail_path', + ]); + + if (! empty($mailSettings['mail_driver'])) { + $driver = $mailSettings['mail_driver']; + + // Set default mailer + Config::set('mail.default', $driver); + + // Configure based on driver + switch ($driver) { + case 'smtp': + Config::set('mail.mailers.smtp.host', $mailSettings['mail_host'] ?? '127.0.0.1'); + Config::set('mail.mailers.smtp.port', $mailSettings['mail_port'] ?? 2525); + Config::set('mail.mailers.smtp.username', $mailSettings['mail_username'] ?? null); + Config::set('mail.mailers.smtp.password', $mailSettings['mail_password'] ?? null); + Config::set('mail.mailers.smtp.encryption', $mailSettings['mail_encryption'] ?? 'none'); + Config::set('mail.mailers.smtp.scheme', $mailSettings['mail_scheme'] ?? null); + Config::set('mail.mailers.smtp.url', $mailSettings['mail_url'] ?? null); + Config::set('mail.mailers.smtp.timeout', $mailSettings['mail_timeout'] ?? null); + Config::set('mail.mailers.smtp.local_domain', $mailSettings['mail_local_domain'] ?? null); + break; + + case 'mailgun': + Config::set('mail.mailers.mailgun.domain', $mailSettings['mail_mailgun_domain'] ?? null); + Config::set('mail.mailers.mailgun.secret', $mailSettings['mail_mailgun_secret'] ?? null); + Config::set('mail.mailers.mailgun.endpoint', $mailSettings['mail_mailgun_endpoint'] ?? 'api.mailgun.net'); + Config::set('mail.mailers.mailgun.scheme', $mailSettings['mail_mailgun_scheme'] ?? 'https'); + + // Also set services config for mailgun + Config::set('services.mailgun.domain', $mailSettings['mail_mailgun_domain'] ?? null); + Config::set('services.mailgun.secret', $mailSettings['mail_mailgun_secret'] ?? null); + Config::set('services.mailgun.endpoint', $mailSettings['mail_mailgun_endpoint'] ?? 'api.mailgun.net'); + break; + + case 'ses': + Config::set('services.ses.key', $mailSettings['mail_ses_key'] ?? null); + Config::set('services.ses.secret', $mailSettings['mail_ses_secret'] ?? null); + Config::set('services.ses.region', $mailSettings['mail_ses_region'] ?? 'us-east-1'); + break; + + case 'sendmail': + Config::set('mail.mailers.sendmail.path', $mailSettings['mail_sendmail_path'] ?? '/usr/sbin/sendmail -bs -i'); + break; + } + + // Set global from address and name + if (! empty($mailSettings['from_mail'])) { + Config::set('mail.from.address', $mailSettings['from_mail']); + } + if (! empty($mailSettings['from_name'])) { + Config::set('mail.from.name', $mailSettings['from_name']); + } + } + } catch (\Exception $e) { + // Silently fail if database is not available (during installation, migrations, etc.) + // This prevents the application from breaking during setup + } + } + + /** + * Configure PDF settings from database + */ + protected function configurePDFFromDatabase(): void + { + try { + // Get PDF settings from database + $pdfSettings = Setting::getSettings([ + 'pdf_driver', + 'gotenberg_host', + 'gotenberg_papersize', + 'gotenberg_margins', + ]); + + if (! empty($pdfSettings['pdf_driver'])) { + $driver = $pdfSettings['pdf_driver']; + + // Set PDF driver + Config::set('pdf.driver', $driver); + + // Configure based on driver + switch ($driver) { + case 'gotenberg': + if (! empty($pdfSettings['gotenberg_host'])) { + Config::set('pdf.connections.gotenberg.host', $pdfSettings['gotenberg_host']); + } + if (! empty($pdfSettings['gotenberg_papersize'])) { + Config::set('pdf.connections.gotenberg.papersize', $pdfSettings['gotenberg_papersize']); + } + if (! empty($pdfSettings['gotenberg_margins'])) { + Config::set('pdf.connections.gotenberg.margins', $pdfSettings['gotenberg_margins']); + } + break; + + case 'dompdf': + // dompdf doesn't have additional configuration in the current setup + break; + } + } + } catch (\Exception $e) { + // Silently fail if database is not available (during installation, migrations, etc.) + // This prevents the application from breaking during setup + } + } + + /** + * Configure file system settings from database + */ + protected function configureFileSystemFromDatabase(): void + { + try { + // Get the default file disk from database + $fileDisk = \App\Models\FileDisk::whereSetAsDefault(true)->first(); + + if ($fileDisk) { + $fileDisk->setConfig(); + } + } catch (\Exception $e) { + // Silently fail if database is not available (during installation, migrations, etc.) + // This prevents the application from breaking during setup + } + } +} diff --git a/app/Services/PDFDrivers/GotenbergPDFDriver.php b/app/Services/PDFDrivers/GotenbergPDFDriver.php index bd2024e4..211803c9 100644 --- a/app/Services/PDFDrivers/GotenbergPDFDriver.php +++ b/app/Services/PDFDrivers/GotenbergPDFDriver.php @@ -36,12 +36,12 @@ class GotenbergPDFDriver { public function loadView(string $viewname): GotenbergPDFResponse { - $papersize = explode(' ', config('pdf.gotenberg.papersize')); + $papersize = explode(' ', config('pdf.connections.gotenberg.papersize')); if (count($papersize) != 2) { throw new \InvalidArgumentException('Invalid Gotenberg Papersize specified'); } - $host = config('pdf.gotenberg.host'); + $host = config('pdf.connections.gotenberg.host'); $request = Gotenberg::chromium($host) ->pdf() ->margins(0, 0, 0, 0) // Margins can be set using CSS diff --git a/app/Space/EnvironmentManager.php b/app/Space/EnvironmentManager.php index 9e7a209c..62df5bfe 100755 --- a/app/Space/EnvironmentManager.php +++ b/app/Space/EnvironmentManager.php @@ -3,9 +3,7 @@ namespace App\Space; use App\Http\Requests\DatabaseEnvironmentRequest; -use App\Http\Requests\DiskEnvironmentRequest; use App\Http\Requests\DomainEnvironmentRequest; -use App\Http\Requests\MailEnvironmentRequest; use App\Http\Requests\PDFConfigurationRequest; use Exception; use Illuminate\Support\Facades\Artisan; @@ -238,29 +236,6 @@ class EnvironmentManager return DB::connection()->getPdo(); } - /** - * Save the mail content to the .env file. - * - * @return array - */ - public function saveMailVariables(MailEnvironmentRequest $request) - { - $mailEnv = $this->getMailConfiguration($request); - - try { - - $this->updateEnv($mailEnv); - } catch (Exception $e) { - return [ - 'error' => 'mail_variables_save_error', - ]; - } - - return [ - 'success' => 'mail_variables_save_successfully', - ]; - } - /** * Save the pdf generation content to the .env file. * @@ -315,169 +290,6 @@ class EnvironmentManager return $pdfEnv; } - /** - * Returns the mail configuration - * - * @param MailEnvironmentRequest $request - * @return array - */ - private function getMailConfiguration($request) - { - $mailEnv = []; - - $driver = $request->get('mail_driver'); - - switch ($driver) { - case 'smtp': - - $mailEnv = [ - 'MAIL_MAILER' => $request->get('mail_driver'), - 'MAIL_HOST' => $request->get('mail_host'), - 'MAIL_PORT' => $request->get('mail_port'), - 'MAIL_USERNAME' => $request->get('mail_username'), - 'MAIL_PASSWORD' => $request->get('mail_password'), - 'MAIL_SCHEME' => $request->get('mail_encryption') !== 'none' ? $request->get('mail_encryption') : 'null', - 'MAIL_FROM_ADDRESS' => $request->get('from_mail'), - 'MAIL_FROM_NAME' => $request->get('from_name'), - ]; - - break; - - case 'mailgun': - - $mailEnv = [ - 'MAIL_MAILER' => $request->get('mail_driver'), - 'MAIL_HOST' => $request->get('mail_host'), - 'MAIL_PORT' => $request->get('mail_port'), - 'MAIL_USERNAME' => config('mail.username'), - 'MAIL_PASSWORD' => config('mail.password'), - 'MAIL_FROM_ADDRESS' => $request->get('from_mail'), - 'MAIL_FROM_NAME' => $request->get('from_name'), - 'MAILGUN_DOMAIN' => $request->get('mail_mailgun_domain'), - 'MAILGUN_SECRET' => $request->get('mail_mailgun_secret'), - 'MAILGUN_ENDPOINT' => $request->get('mail_mailgun_endpoint'), - ]; - - break; - - case 'ses': - - $mailEnv = [ - 'MAIL_MAILER' => $request->get('mail_driver'), - 'MAIL_HOST' => $request->get('mail_host'), - 'MAIL_PORT' => $request->get('mail_port'), - 'MAIL_USERNAME' => config('mail.username'), - 'MAIL_PASSWORD' => config('mail.password'), - 'MAIL_ENCRYPTION' => $request->get('mail_encryption'), - 'MAIL_FROM_ADDRESS' => $request->get('from_mail'), - 'MAIL_FROM_NAME' => $request->get('from_name'), - 'SES_KEY' => $request->get('mail_ses_key'), - 'SES_SECRET' => $request->get('mail_ses_secret'), - 'SES_REGION' => $request->get('mail_ses_region'), - ]; - - break; - - case 'sendmail': - case 'mail': - - $mailEnv = [ - 'MAIL_MAILER' => $request->get('mail_driver'), - 'MAIL_HOST' => config('mail.host'), - 'MAIL_PORT' => config('mail.port'), - 'MAIL_USERNAME' => config('mail.username'), - 'MAIL_PASSWORD' => config('mail.password'), - 'MAIL_ENCRYPTION' => config('mail.encryption'), - 'MAIL_FROM_ADDRESS' => $request->get('from_mail'), - 'MAIL_FROM_NAME' => $request->get('from_name'), - ]; - - break; - } - - return $mailEnv; - } - - /** - * Save the disk content to the .env file. - * - * @return array - */ - public function saveDiskVariables(DiskEnvironmentRequest $request) - { - $diskEnv = $this->getDiskConfiguration($request); - - try { - - $this->updateEnv($diskEnv); - } catch (Exception $e) { - return [ - 'error' => 'disk_variables_save_error', - ]; - } - - return [ - 'success' => 'disk_variables_save_successfully', - ]; - } - - /** - * Returns the disk configuration - * - * @return array - */ - private function getDiskConfiguration(DiskEnvironmentRequest $request) - { - $diskEnv = []; - - $driver = $request->get('app_domain'); - - if ($driver) { - $diskEnv['FILESYSTEM_DRIVER'] = $driver; - } - - switch ($request->get('selected_driver')) { - case 's3': - - $diskEnv = [ - 'AWS_KEY' => $request->get('aws_key'), - 'AWS_SECRET' => $request->get('aws_secret'), - 'AWS_REGION' => $request->get('aws_region'), - 'AWS_BUCKET' => $request->get('aws_bucket'), - 'AWS_ROOT' => $request->get('aws_root'), - ]; - - break; - - case 'doSpaces': - - $diskEnv = [ - 'DO_SPACES_KEY' => $request->get('do_spaces_key'), - 'DO_SPACES_SECRET' => $request->get('do_spaces_secret'), - 'DO_SPACES_REGION' => $request->get('do_spaces_region'), - 'DO_SPACES_BUCKET' => $request->get('do_spaces_bucket'), - 'DO_SPACES_ENDPOINT' => $request->get('do_spaces_endpoint'), - 'DO_SPACES_ROOT' => $request->get('do_spaces_root'), - ]; - - break; - - case 'dropbox': - - $diskEnv = [ - 'DROPBOX_TOKEN' => $request->get('dropbox_token'), - 'DROPBOX_KEY' => $request->get('dropbox_key'), - 'DROPBOX_SECRET' => $request->get('dropbox_secret'), - 'DROPBOX_APP' => $request->get('dropbox_app'), - 'DROPBOX_ROOT' => $request->get('dropbox_root'), - ]; - - break; - } - - return $diskEnv; - } - /** * Save sanctum stateful domain to the .env file. * @@ -507,35 +319,6 @@ class EnvironmentManager ]; } - /** - * Order the env contents - * - * @return void - */ - public function reoderEnv() - { - $contents = $this->getEnvContents(); - $contents = explode($this->delimiter, $contents); - if (empty($contents)) { - return; - } - natsort($contents); - - $formatted = ''; - $previous = ''; - foreach ($contents as $current) { - $parts_line = explode('_', $current); - $parts_last = explode('_', $previous); - if ($parts_line[0] != $parts_last[0]) { - $formatted .= $this->delimiter; - } - $formatted .= $current.$this->delimiter; - $previous = $current; - } - - file_put_contents($this->envPath, trim($formatted)); - } - private function getDomains(string $requestDomain): array { $appUrl = config('app.url'); diff --git a/bootstrap/providers.php b/bootstrap/providers.php index f9551ff3..10361695 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -6,4 +6,5 @@ return [ App\Providers\DropboxServiceProvider::class, App\Providers\ViewServiceProvider::class, App\Providers\PDFServiceProvider::class, + App\Providers\AppConfigProvider::class, ]; diff --git a/config/abilities.php b/config/abilities.php index 9e6a24b2..bf5c647e 100644 --- a/config/abilities.php +++ b/config/abilities.php @@ -13,6 +13,19 @@ use App\Models\RecurringInvoice; use App\Models\TaxType; return [ + + /* + |-------------------------------------------------------------------------- + | Abilities Configuration + |-------------------------------------------------------------------------- + | + | This file is for defining the abilities used in the application. Each + | ability includes a name, a unique identifier (ability), the associated + | model, and any dependencies on other abilities. This configuration helps + | manage user permissions and access control throughout the application. + | + */ + 'abilities' => [ // Customer diff --git a/config/app.php b/config/app.php index efd5f969..a6532276 100644 --- a/config/app.php +++ b/config/app.php @@ -4,11 +4,19 @@ use Illuminate\Support\Facades\Facade; return [ + /* + |-------------------------------------------------------------------------- + | Class Aliases + |-------------------------------------------------------------------------- + | + | This array of class aliases will be registered when this application + | is started. You may add any additional class aliases which should + | be loaded to the array. For speed, all aliases are lazy loaded. + | + */ + 'aliases' => Facade::defaultAliases()->merge([ - 'Flash' => Laracasts\Flash\Flash::class, 'Menu' => Lavary\Menu\Facade::class, - 'Pusher' => Pusher\Pusher::class, - 'Redis' => Illuminate\Support\Facades\Redis::class, ])->toArray(), ]; diff --git a/config/auth.php b/config/auth.php index 703318b7..50e4d934 100644 --- a/config/auth.php +++ b/config/auth.php @@ -2,13 +2,49 @@ return [ + /* + |-------------------------------------------------------------------------- + | Authentication Defaults + |-------------------------------------------------------------------------- + | + | This option defines the default authentication "guard" and password + | reset "broker" for your application. You may change these values + | as required, but they're a perfect start for most applications. + | + */ + + 'defaults' => [ + 'guard' => env('AUTH_GUARD', 'web'), + 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | which utilizes session storage plus the Eloquent user provider. + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | Supported: "session" + | + */ + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], 'api' => [ 'driver' => 'token', 'provider' => 'users', 'hash' => false, ], - 'customer' => [ 'driver' => 'session', 'provider' => 'customers', @@ -17,13 +53,42 @@ return [ ], 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => \App\Models\User::class, + ], 'customers' => [ 'driver' => 'eloquent', 'model' => \App\Models\Customer::class, ], ], + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | These configuration options specify the behavior of Laravel's password + | reset functionality, including the table utilized for token storage + | and the user provider that is invoked to actually retrieve users. + | + | The expiry 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' => [ + 'users' => [ + 'provider' => 'users', + 'table' => 'password_reset_tokens', + 'expire' => 60, + 'throttle' => 60, + ], 'customers' => [ 'provider' => 'customers', 'table' => 'password_reset_tokens', diff --git a/config/cache.php b/config/cache.php index a70ab8e5..84d39f70 100644 --- a/config/cache.php +++ b/config/cache.php @@ -1,5 +1,17 @@ env('CACHE_STORE', 'file'), ]; diff --git a/config/filesystems.php b/config/filesystems.php index a2be6bb0..169b37bd 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -2,9 +2,41 @@ return [ - 'cloud' => env('FILESYSTEM_CLOUD', 's3'), + /* + |-------------------------------------------------------------------------- + | 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'), + 'throw' => false, + 'report' => false, + ], + 's3' => [ 'driver' => 's3', 'key' => env('AWS_KEY'), @@ -24,11 +56,6 @@ return [ 'bucket' => env('S3_COMPAT_BUCKET'), ], - 'media' => [ - 'driver' => 'local', - 'root' => public_path('media'), - ], - 'doSpaces' => [ 'type' => 'AwsS3', 'driver' => 's3', @@ -51,6 +78,11 @@ return [ 'root' => env('DROPBOX_ROOT'), ], + 'media' => [ + 'driver' => 'local', + 'root' => public_path('media'), + ], + 'views' => [ 'driver' => 'local', 'root' => resource_path('views'), @@ -60,13 +92,6 @@ return [ 'driver' => 'local', 'root' => storage_path('app/templates/pdf'), ], - - 'local' => [ - 'driver' => 'local', - 'root' => storage_path('app'), - 'throw' => false, - 'report' => false, - ], ], ]; diff --git a/config/pdf.php b/config/pdf.php index b9265d73..a5b26cb7 100644 --- a/config/pdf.php +++ b/config/pdf.php @@ -2,13 +2,35 @@ return [ - 'driver' => env('PDF_DRIVER', 'gotenberg'), + /* + |-------------------------------------------------------------------------- + | Default PDF Driver + |-------------------------------------------------------------------------- + | Here you may specify which of the PDF drivers below you wish to use as + | your default driver for all PDF generation. + | + */ - 'gotenberg' => [ - 'host' => env('GOTENBERG_HOST', 'http://pdf:3000'), - 'papersize' => env('GOTENBERG_PAPERSIZE', '210mm 297mm'), + 'driver' => env('PDF_DRIVER', 'dompdf'), + + /* + |-------------------------------------------------------------------------- + | PDF Connections + |-------------------------------------------------------------------------- + | + | Here are each of the connections setup for your application. Example + | configuration has been included, but you may add as many connections as + | you would like. + | + */ + 'connections' => [ + + 'dompdf' => [], + + 'gotenberg' => [ + 'host' => env('GOTENBERG_HOST', 'http://pdf:3000'), + 'papersize' => env('GOTENBERG_PAPERSIZE', '210mm 297mm'), + ], ], - 'dompdf' => [], - ]; diff --git a/config/queue.php b/config/queue.php index e8ff285f..85280291 100644 --- a/config/queue.php +++ b/config/queue.php @@ -1,5 +1,112 @@ env('QUEUE_CONNECTION', 'sync'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection options for every queue backend + | used by your application. An example configuration is provided for + | each backend supported by Laravel. You're also free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_QUEUE_CONNECTION'), + 'table' => env('DB_QUEUE_TABLE', 'jobs'), + 'queue' => env('DB_QUEUE', 'default'), + 'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90), + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'), + 'queue' => env('BEANSTALKD_QUEUE', 'default'), + 'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90), + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_QUEUE_CONNECTION', 'default'), + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90), + 'block_for' => null, + 'after_commit' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | 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', 'sqlite'), + 'table' => 'job_batches', + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control how and where failed jobs are stored. Laravel ships with + | support for storing failed jobs in a simple file or in a database. + | + | Supported drivers: "database-uuids", "dynamodb", "file", "null" + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'failed_jobs', + ], + ]; diff --git a/config/services.php b/config/services.php index 9b00f7bf..3e2633b1 100644 --- a/config/services.php +++ b/config/services.php @@ -2,6 +2,18 @@ return [ + /* + |-------------------------------------------------------------------------- + | 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. + | + */ + 'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), @@ -26,28 +38,6 @@ return [ ], ], - 'facebook' => [ - 'client_id' => env('FACEBOOK_CLIENT_ID'), - 'client_secret' => env('FACEBOOK_CLIENT_SECRET'), - 'redirect' => env('FACEBOOK_REDIRECT_URL'), - ], - - 'google' => [ - 'client_id' => env('GOOGLE_CLIENT_ID'), - 'client_secret' => env('GOOGLE_CLIENT_SECRET'), - 'redirect' => env('GOOGLE_REDIRECT_URL'), - ], - - 'github' => [ - 'client_id' => env('GITHUB_CLIENT_ID'), - 'client_secret' => env('GITHUB_CLIENT_SECRET'), - 'redirect' => env('GITHUB_REDIRECT_URL'), - ], - - 'cron_job' => [ - 'auth_token' => env('CRON_JOB_AUTH_TOKEN', 0), - ], - 'ses' => [ 'key' => env('SES_KEY'), 'secret' => env('SES_SECRET'), diff --git a/config/session.php b/config/session.php new file mode 100644 index 00000000..176ac3af --- /dev/null +++ b/config/session.php @@ -0,0 +1,217 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to expire immediately when the browser is closed then you may + | indicate that via the expire_on_close configuration option. + | + */ + + 'lifetime' => (int) env('SESSION_LIFETIME', 1440), + + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it's stored. All encryption is performed + | automatically by Laravel and you may use the session like normal. + | + */ + + 'encrypt' => env('SESSION_ENCRYPT', false), + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When utilizing the "file" session driver, the session files are placed + | on disk. The default storage location is defined here; however, you + | are free to provide another location where they should be stored. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table to + | be used to store sessions. Of course, a sensible default is defined + | for you; however, you're welcome to change this to another table. + | + */ + + 'table' => env('SESSION_TABLE', 'sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using one of the framework's cache driven session backends, you may + | define the cache store which should be used to store the session data + | between requests. This must match one of your defined cache stores. + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the session cookie that is created by + | the framework. Typically, you should not need to change this value + | since doing so does not grant a meaningful security improvement. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application, but you're free to change this when necessary. + | + */ + + 'path' => env('SESSION_PATH', '/'), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | This value determines the domain and subdomains the session cookie is + | available to. By default, the cookie will be available to the root + | domain and all subdomains. Typically, this shouldn't be changed. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. It's unlikely you should disable this option. + | + */ + + 'http_only' => env('SESSION_HTTP_ONLY', true), + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" to permit secure cross-site requests. + | + | See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => env('SESSION_SAME_SITE', 'lax'), + + /* + |-------------------------------------------------------------------------- + | Partitioned Cookies + |-------------------------------------------------------------------------- + | + | Setting this value to true will tie the cookie to the top-level site for + | a cross-site context. Partitioned cookies are accepted by the browser + | when flagged "secure" and the Same-Site attribute is set to "none". + | + */ + + 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), + +]; diff --git a/docker/production/docker-compose.mysql.yml b/docker/production/docker-compose.mysql.yml index da63e1f6..a157f819 100644 --- a/docker/production/docker-compose.mysql.yml +++ b/docker/production/docker-compose.mysql.yml @@ -46,13 +46,6 @@ services: - SESSION_LIFETIME=240 - SESSION_DOMAIN=localhost - SANCTUM_STATEFUL_DOMAINS=localhost:8090 - #- MAIL_MAILER=smtp - #- MAIL_HOST=smtp.mailtrap.io - #- MAIL_PORT=2525 - #- MAIL_USERNAME=null - #- MAIL_PASSWORD=null - #- MAIL_PASSWORD_FILE= - #- MAIL_ENCRYPTION=null volumes: - invoiceshelf_storage:/var/www/html/storage/ ports: diff --git a/docker/production/docker-compose.sqlite.yml b/docker/production/docker-compose.sqlite.yml index 9de7b89f..b2c83319 100644 --- a/docker/production/docker-compose.sqlite.yml +++ b/docker/production/docker-compose.sqlite.yml @@ -27,13 +27,6 @@ services: - SESSION_LIFETIME=240 - SESSION_DOMAIN=localhost - SANCTUM_STATEFUL_DOMAINS=localhost:8090 - #- MAIL_DRIVER=smtp - #- MAIL_HOST=smtp.mailtrap.io - #- MAIL_PORT=2525 - #- MAIL_USERNAME=null - #- MAIL_PASSWORD=null - #- MAIL_PASSWORD_FILE= - #- MAIL_ENCRYPTION=null restart: unless-stopped networks: invoiceshelf: diff --git a/docker/production/inject.sh b/docker/production/inject.sh index 24f9e222..3119172e 100644 --- a/docker/production/inject.sh +++ b/docker/production/inject.sh @@ -1,5 +1,3 @@ - - #!/bin/bash function replace_or_insert() { # Voodoo magic: https://superuser.com/a/976712 @@ -71,36 +69,6 @@ fi if [ "$BROADCAST_CONNECTION" != '' ]; then replace_or_insert "BROADCAST_CONNECTION" "$BROADCAST_CONNECTION" fi -if [ "$MAIL_DRIVER" != '' ]; then - replace_or_insert "MAIL_MAILER" "$MAIL_DRIVER" -fi -if [ "$MAIL_MAILER" != '' ]; then - replace_or_insert "MAIL_MAILER" "$MAIL_MAILER" -fi -if [ "$MAIL_HOST" != '' ]; then - replace_or_insert "MAIL_HOST" "$MAIL_HOST" -fi -if [ "$MAIL_PORT" != '' ]; then - replace_or_insert "MAIL_PORT" "$MAIL_PORT" -fi -if [ "$MAIL_USERNAME" != '' ]; then - replace_or_insert "MAIL_USERNAME" "$MAIL_USERNAME" -fi -if [ "$MAIL_PASSWORD" != '' ]; then - replace_or_insert "MAIL_PASSWORD" "$MAIL_PASSWORD" -elif [ "$MAIL_PASSWORD_FILE" != '' ]; then - value=$(<$MAIL_PASSWORD_FILE) - replace_or_insert "MAIL_PASSWORD" "$value" -fi -if [ "$MAIL_SCHEME" != '' ]; then - replace_or_insert "MAIL_SCHEME" "$MAIL_SCHEME" -fi -if [ "$MAIL_FROM_NAME" != '' ]; then - replace_or_insert "MAIL_FROM_NAME" "$MAIL_FROM_NAME" -fi -if [ "$MAIL_FROM_ADDRESS" != '' ]; then - replace_or_insert "MAIL_FROM_ADDRESS" "$MAIL_FROM_ADDRESS" -fi if [ "$TRUSTED_PROXIES" != '' ]; then replace_or_insert "TRUSTED_PROXIES" "$TRUSTED_PROXIES" fi diff --git a/resources/scripts/admin/views/installation/Step8CompanyPreferences.vue b/resources/scripts/admin/views/installation/Step8CompanyPreferences.vue index f96b75a6..37d7f775 100644 --- a/resources/scripts/admin/views/installation/Step8CompanyPreferences.vue +++ b/resources/scripts/admin/views/installation/Step8CompanyPreferences.vue @@ -162,7 +162,7 @@ const isSaving = ref(false) let isFetchingInitialData = ref(false) let currentPreferences = reactive({ - currency: 1, + currency: 3, language: 'en', carbon_date_format: 'd M Y', time_zone: 'UTC',