diff --git a/.devcontainer/cli/Dockerfile b/.devcontainer/cli/Dockerfile index d2c44b1..ab13330 100644 --- a/.devcontainer/cli/Dockerfile +++ b/.devcontainer/cli/Dockerfile @@ -10,10 +10,7 @@ RUN apk add --no-cache composer RUN apk add --no-cache \ imagemagick-dev \ chromium \ - libzip-dev \ - freetype-dev \ - libpng-dev \ - libjpeg-turbo-dev + libzip-dev ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium ENV PUPPETEER_DOCKER=1 @@ -22,10 +19,8 @@ RUN mkdir -p /usr/src/php/ext/imagick RUN chmod 777 /usr/src/php/ext/imagick RUN curl -fsSL https://github.com/Imagick/imagick/archive/refs/tags/3.8.0.tar.gz | tar xvz -C "/usr/src/php/ext/imagick" --strip 1 -RUN docker-php-ext-configure gd --with-freetype --with-jpeg - # Install PHP extensions -RUN docker-php-ext-install imagick zip gd +RUN docker-php-ext-install imagick zip # Composer uses its php binary, but we want it to use the container's one RUN rm -f /usr/bin/php84 diff --git a/.devcontainer/fpm/Dockerfile b/.devcontainer/fpm/Dockerfile index d8ce6cc..3e658b6 100644 --- a/.devcontainer/fpm/Dockerfile +++ b/.devcontainer/fpm/Dockerfile @@ -15,11 +15,7 @@ RUN apk add --no-cache \ npm \ imagemagick-dev \ chromium \ - libzip-dev \ - freetype-dev \ - libpng-dev \ - libjpeg-turbo-dev - + libzip-dev ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium ENV PUPPETEER_DOCKER=1 @@ -28,10 +24,8 @@ RUN mkdir -p /usr/src/php/ext/imagick RUN chmod 777 /usr/src/php/ext/imagick RUN curl -fsSL https://github.com/Imagick/imagick/archive/refs/tags/3.8.0.tar.gz | tar xvz -C "/usr/src/php/ext/imagick" --strip 1 -RUN docker-php-ext-configure gd --with-freetype --with-jpeg - # Install PHP extensions -RUN docker-php-ext-install imagick zip gd +RUN docker-php-ext-install imagick zip RUN rm -f /usr/bin/php84 RUN ln -s /usr/local/bin/php /usr/bin/php84 diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php deleted file mode 100644 index 3c7c00c..0000000 --- a/app/Actions/Fortify/CreateNewUser.php +++ /dev/null @@ -1,33 +0,0 @@ - $input - */ - public function create(array $input): User - { - Validator::make($input, [ - ...$this->profileRules(), - 'password' => $this->passwordRules(), - ])->validate(); - - return User::create([ - 'name' => $input['name'], - 'email' => $input['email'], - 'password' => $input['password'], - ]); - } -} diff --git a/app/Actions/Fortify/ResetUserPassword.php b/app/Actions/Fortify/ResetUserPassword.php deleted file mode 100644 index 8fda5dd..0000000 --- a/app/Actions/Fortify/ResetUserPassword.php +++ /dev/null @@ -1,29 +0,0 @@ - $input - */ - public function reset(User $user, array $input): void - { - Validator::make($input, [ - 'password' => $this->passwordRules(), - ])->validate(); - - $user->forceFill([ - 'password' => $input['password'], - ])->save(); - } -} diff --git a/app/Concerns/PasswordValidationRules.php b/app/Concerns/PasswordValidationRules.php deleted file mode 100644 index 9b45ef0..0000000 --- a/app/Concerns/PasswordValidationRules.php +++ /dev/null @@ -1,28 +0,0 @@ -|string> - */ - protected function passwordRules(): array - { - return ['required', 'string', Password::default(), 'confirmed']; - } - - /** - * Get the validation rules used to validate the current password. - * - * @return array|string> - */ - protected function currentPasswordRules(): array - { - return ['required', 'string', 'current_password']; - } -} diff --git a/app/Concerns/ProfileValidationRules.php b/app/Concerns/ProfileValidationRules.php deleted file mode 100644 index 46e19ba..0000000 --- a/app/Concerns/ProfileValidationRules.php +++ /dev/null @@ -1,50 +0,0 @@ -|string>> - */ - protected function profileRules(?int $userId = null): array - { - return [ - 'name' => $this->nameRules(), - 'email' => $this->emailRules($userId), - ]; - } - - /** - * Get the validation rules used to validate user names. - * - * @return array|string> - */ - protected function nameRules(): array - { - return ['required', 'string', 'max:255']; - } - - /** - * Get the validation rules used to validate user emails. - * - * @return array|string> - */ - protected function emailRules(?int $userId = null): array - { - return [ - 'required', - 'string', - 'email', - 'max:255', - $userId === null - ? Rule::unique(User::class) - : Rule::unique(User::class)->ignore($userId), - ]; - } -} diff --git a/app/Facades/QrCode.php b/app/Facades/QrCode.php deleted file mode 100644 index 00de934..0000000 --- a/app/Facades/QrCode.php +++ /dev/null @@ -1,24 +0,0 @@ -errorCorrection($errorCorrection); } - return $qrCode->generate($text); + $svg = (string) $qrCode->generate($text); + + // Add class="qr-code" to the SVG element + // The SVG may start with and then + if (preg_match('/]*)>/', $svg, $matches)) { + $attributes = $matches[1]; + // Check if class already exists + if (mb_strpos($attributes, 'class=') === false) { + $svg = preg_replace('/]*)>/', '', $svg, 1); + } else { + // If class exists, add qr-code to it + $svg = preg_replace('/(]*class=["\'])([^"\']*)(["\'][^>]*>)/', '$1$2 qr-code$3', $svg, 1); + } + } else { + // Fallback: simple replacement if no attributes + $svg = preg_replace('//', '', $svg, 1); + } + + return $svg; } } diff --git a/app/Livewire/Actions/DeviceAutoJoin.php b/app/Livewire/Actions/DeviceAutoJoin.php index 82d63ed..183add4 100644 --- a/app/Livewire/Actions/DeviceAutoJoin.php +++ b/app/Livewire/Actions/DeviceAutoJoin.php @@ -12,7 +12,7 @@ class DeviceAutoJoin extends Component public function mount(): void { - $this->deviceAutojoin = (bool) (auth()->user()->assign_new_devices ?? false); + $this->deviceAutojoin = auth()->user()->assign_new_devices; $this->isFirstUser = auth()->user()->id === 1; } diff --git a/app/Models/Plugin.php b/app/Models/Plugin.php index 31841bc..68f8e7e 100644 --- a/app/Models/Plugin.php +++ b/app/Models/Plugin.php @@ -174,8 +174,8 @@ class Plugin extends Model // resolve and clean URLs $resolvedPollingUrls = $this->resolveLiquidVariables($this->polling_url); $urls = array_values(array_filter( // array_values ensures 0, 1, 2... - array_map(trim(...), explode("\n", $resolvedPollingUrls)), - filled(...) + array_map('trim', explode("\n", $resolvedPollingUrls)), + fn ($url): bool => filled($url) )); $combinedResponse = []; @@ -624,7 +624,7 @@ class Plugin extends Model // File doesn't exist, remove the view reference $attributes['render_markup_view'] = null; } - } catch (Exception) { + } catch (Exception $e) { // If file reading fails, remove the view reference $attributes['render_markup_view'] = null; } diff --git a/app/Models/User.php b/app/Models/User.php index 8d7aa7e..c6d39b8 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -8,13 +8,12 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Str; -use Laravel\Fortify\TwoFactorAuthenticatable; use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable // implements MustVerifyEmail { /** @use HasFactory<\Database\Factories\UserFactory> */ - use HasApiTokens, HasFactory, Notifiable, TwoFactorAuthenticatable; + use HasApiTokens, HasFactory, Notifiable; /** * The attributes that are mass assignable. diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 48178e8..b8ad9bb 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -3,7 +3,6 @@ namespace App\Providers; use App\Services\OidcProvider; -use App\Services\QrCodeService; use Illuminate\Http\Request; use Illuminate\Support\Facades\URL; use Illuminate\Support\ServiceProvider; @@ -16,7 +15,7 @@ class AppServiceProvider extends ServiceProvider */ public function register(): void { - $this->app->bind('qr-code', fn () => new QrCodeService); + // } /** diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php deleted file mode 100644 index bf7a1b3..0000000 --- a/app/Providers/FortifyServiceProvider.php +++ /dev/null @@ -1,72 +0,0 @@ -configureActions(); - $this->configureViews(); - $this->configureRateLimiting(); - } - - /** - * Configure Fortify actions. - */ - private function configureActions(): void - { - Fortify::resetUserPasswordsUsing(ResetUserPassword::class); - Fortify::createUsersUsing(CreateNewUser::class); - } - - /** - * Configure Fortify views. - */ - private function configureViews(): void - { - Fortify::loginView(fn (): Factory|View => view('pages::auth.login')); - Fortify::verifyEmailView(fn (): Factory|View => view('pages::auth.verify-email')); - Fortify::twoFactorChallengeView(fn (): Factory|View => view('pages::auth.two-factor-challenge')); - Fortify::confirmPasswordView(fn (): Factory|View => view('pages::auth.confirm-password')); - Fortify::registerView(fn (): Factory|View => view('pages::auth.register')); - Fortify::resetPasswordView(fn (): Factory|View => view('pages::auth.reset-password')); - Fortify::requestPasswordResetLinkView(fn (): Factory|View => view('pages::auth.forgot-password')); - } - - /** - * Configure rate limiting. - */ - private function configureRateLimiting(): void - { - RateLimiter::for('two-factor', fn (Request $request) => Limit::perMinute(5)->by($request->session()->get('login.id'))); - - RateLimiter::for('login', function (Request $request) { - $throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip()); - - return Limit::perMinute(5)->by($throttleKey); - }); - } -} diff --git a/app/Providers/VoltServiceProvider.php b/app/Providers/VoltServiceProvider.php new file mode 100644 index 0000000..e61d984 --- /dev/null +++ b/app/Providers/VoltServiceProvider.php @@ -0,0 +1,28 @@ +path('/images/generated/'.$uuid.'.'.$fileExtension); @@ -78,7 +78,7 @@ class ImageGenerationService $browserStage->html($markup); // Set timezone from user or fall back to app timezone - $timezone = $user->timezone ?? config('app.timezone'); + $timezone = $user?->timezone ?? config('app.timezone'); $browserStage->timezone($timezone); if (config('app.puppeteer_window_size_strategy') === 'v2') { @@ -186,7 +186,7 @@ class ImageGenerationService */ private static function getImageSettingsFromModel(?DeviceModel $deviceModel): array { - if ($deviceModel instanceof DeviceModel) { + if ($deviceModel) { return [ 'width' => $deviceModel->width, 'height' => $deviceModel->height, diff --git a/app/Services/PluginImportService.php b/app/Services/PluginImportService.php index 51a9aee..49dce99 100644 --- a/app/Services/PluginImportService.php +++ b/app/Services/PluginImportService.php @@ -33,11 +33,11 @@ class PluginImportService foreach ($settings['custom_fields'] as $field) { if (isset($field['field_type']) && $field['field_type'] === 'multi_string') { - if (isset($field['default']) && str_contains((string) $field['default'], ',')) { + if (isset($field['default']) && str_contains($field['default'], ',')) { throw new Exception("Validation Error: The default value for multistring fields like `{$field['keyname']}` cannot contain commas."); } - if (isset($field['placeholder']) && str_contains((string) $field['placeholder'], ',')) { + if (isset($field['placeholder']) && str_contains($field['placeholder'], ',')) { throw new Exception("Validation Error: The placeholder value for multistring fields like `{$field['keyname']}` cannot contain commas."); } @@ -159,7 +159,7 @@ class PluginImportService : null, 'polling_body' => $settings['polling_body'] ?? null, 'markup_language' => $markupLanguage, - 'render_markup' => $fullLiquid ?? null, + 'render_markup' => $fullLiquid, 'configuration_template' => $configurationTemplate, 'data_payload' => json_decode($settings['static_data'] ?? '{}', true), ]); @@ -321,7 +321,7 @@ class PluginImportService : null, 'polling_body' => $settings['polling_body'] ?? null, 'markup_language' => $markupLanguage, - 'render_markup' => $fullLiquid ?? null, + 'render_markup' => $fullLiquid, 'configuration_template' => $configurationTemplate, 'data_payload' => json_decode($settings['static_data'] ?? '{}', true), 'preferred_renderer' => $preferredRenderer, diff --git a/app/Services/QrCodeService.php b/app/Services/QrCodeService.php deleted file mode 100644 index 812415b..0000000 --- a/app/Services/QrCodeService.php +++ /dev/null @@ -1,147 +0,0 @@ -format = $format; - - return $this; - } - - /** - * Set the size of the QR code - * - * @param int $size The size in pixels - * @return $this - */ - public function size(int $size): self - { - $this->size = $size; - - return $this; - } - - /** - * Set the error correction level - * - * @param string $level Error correction level: 'l', 'm', 'q', 'h' - * @return $this - */ - public function errorCorrection(string $level): self - { - $this->errorCorrection = $level; - - return $this; - } - - /** - * Generate the QR code - * - * @param string $text The text to encode - * @return string The generated QR code (SVG string) - */ - public function generate(string $text): string - { - // Ensure format is set (default to SVG) - $format = $this->format ?? 'svg'; - - if ($format !== 'svg') { - throw new InvalidArgumentException("Format '{$format}' is not supported. Only 'svg' is currently supported."); - } - - // Calculate size and margin - // If size is not set, calculate from module size (default module size is 11) - if ($this->size === null) { - $moduleSize = 11; - $this->size = 29 * $moduleSize; - } - - // Calculate margin: 4 modules on each side - // Module size = size / 29, so margin = (size / 29) * 4 - $moduleSize = $this->size / 29; - $margin = (int) ($moduleSize * 4); - - // Map error correction level - $errorCorrectionLevel = ErrorCorrectionLevel::valueOf('M'); // default - if ($this->errorCorrection !== null) { - $errorCorrectionLevel = match (mb_strtoupper($this->errorCorrection)) { - 'L' => ErrorCorrectionLevel::valueOf('L'), - 'M' => ErrorCorrectionLevel::valueOf('M'), - 'Q' => ErrorCorrectionLevel::valueOf('Q'), - 'H' => ErrorCorrectionLevel::valueOf('H'), - default => ErrorCorrectionLevel::valueOf('M'), - }; - } - - // Create renderer style with size and margin - $rendererStyle = new RendererStyle($this->size, $margin); - - // Create SVG renderer - $renderer = new ImageRenderer( - $rendererStyle, - new SvgImageBackEnd() - ); - - // Create writer - $writer = new Writer($renderer); - - // Generate SVG - $svg = $writer->writeString($text, 'ISO-8859-1', $errorCorrectionLevel); - - // Add class="qr-code" to the SVG element - $svg = $this->addQrCodeClass($svg); - - return $svg; - } - - /** - * Add the 'qr-code' class to the SVG element - * - * @param string $svg The SVG string - * @return string The SVG string with the class added - */ - protected function addQrCodeClass(string $svg): string - { - // Match - if (preg_match('/]*)>/', $svg, $matches)) { - $attributes = $matches[1]; - // Check if class already exists - if (mb_strpos($attributes, 'class=') === false) { - $svg = preg_replace('/]*)>/', '', $svg, 1); - } else { - // If class exists, add qr-code to it - $svg = preg_replace('/(]*class=["\'])([^"\']*)(["\'][^>]*>)/', '$1$2 qr-code$3', $svg, 1); - } - } else { - // Fallback: simple replacement if no attributes - $svg = preg_replace('//', '', $svg, 1); - } - - return $svg; - } -} diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 0ad9c57..90915e8 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -2,5 +2,6 @@ return [ App\Providers\AppServiceProvider::class, - App\Providers\FortifyServiceProvider::class, + App\Providers\FolioServiceProvider::class, + App\Providers\VoltServiceProvider::class, ]; diff --git a/composer.json b/composer.json index a4951a0..f59e0f3 100644 --- a/composer.json +++ b/composer.json @@ -18,14 +18,15 @@ "bnussbau/laravel-trmnl-blade": "2.1.*", "bnussbau/trmnl-pipeline-php": "^0.6.0", "keepsuit/laravel-liquid": "^0.5.2", - "laravel/fortify": "^1.30", "laravel/framework": "^12.1", "laravel/sanctum": "^4.0", "laravel/socialite": "^5.23", "laravel/tinker": "^2.10.1", + "livewire/livewire": "^3.7", "livewire/flux": "^2.0", - "livewire/livewire": "^4.0", + "livewire/volt": "^1.7", "om/icalparser": "^3.2", + "simplesoftwareio/simple-qrcode": "^4.2", "spatie/browsershot": "^5.0", "stevebauman/purify": "^6.3", "symfony/yaml": "^7.3", diff --git a/composer.lock b/composer.lock index 52a9ed0..e5840ef 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cd2e6e87598cd99111e73d9ce8e0a9b8", + "content-hash": "ac6b1e352cb66f858a50b64e7e3c70d0", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.369.14", + "version": "3.369.13", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "b40eb1177d2e621c18cd797ca6cc9efb5a0e99d9" + "reference": "bedc36250c92b8287be855a2d25427fb0e065483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/b40eb1177d2e621c18cd797ca6cc9efb5a0e99d9", - "reference": "b40eb1177d2e621c18cd797ca6cc9efb5a0e99d9", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/bedc36250c92b8287be855a2d25427fb0e065483", + "reference": "bedc36250c92b8287be855a2d25427fb0e065483", "shasum": "" }, "require": { @@ -153,35 +153,34 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.369.14" + "source": "https://github.com/aws/aws-sdk-php/tree/3.369.13" }, - "time": "2026-01-15T19:10:54+00:00" + "time": "2026-01-14T19:13:46+00:00" }, { "name": "bacon/bacon-qr-code", - "version": "v3.0.3", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/Bacon/BaconQrCode.git", - "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563" + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/36a1cb2b81493fa5b82e50bf8068bf84d1542563", - "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", "shasum": "" }, "require": { "dasprid/enum": "^1.0.3", "ext-iconv": "*", - "php": "^8.1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "phly/keep-a-changelog": "^2.12", - "phpunit/phpunit": "^10.5.11 || ^11.0.4", - "spatie/phpunit-snapshot-assertions": "^5.1.5", - "spatie/pixelmatch-php": "^1.2.0", - "squizlabs/php_codesniffer": "^3.9" + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" }, "suggest": { "ext-imagick": "to generate QR code images" @@ -208,9 +207,9 @@ "homepage": "https://github.com/Bacon/BaconQrCode", "support": { "issues": "https://github.com/Bacon/BaconQrCode/issues", - "source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.3" + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" }, - "time": "2025-11-19T17:15:36+00:00" + "time": "2022-12-07T17:46:57+00:00" }, { "name": "bnussbau/laravel-trmnl-blade", @@ -1781,69 +1780,6 @@ }, "time": "2025-12-01T12:01:51+00:00" }, - { - "name": "laravel/fortify", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/fortify.git", - "reference": "e0666dabeec0b6428678af1d51f436dcfb24e3a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/fortify/zipball/e0666dabeec0b6428678af1d51f436dcfb24e3a9", - "reference": "e0666dabeec0b6428678af1d51f436dcfb24e3a9", - "shasum": "" - }, - "require": { - "bacon/bacon-qr-code": "^3.0", - "ext-json": "*", - "illuminate/support": "^10.0|^11.0|^12.0", - "php": "^8.1", - "pragmarx/google2fa": "^9.0", - "symfony/console": "^6.0|^7.0" - }, - "require-dev": { - "orchestra/testbench": "^8.36|^9.15|^10.8", - "phpstan/phpstan": "^1.10" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Fortify\\FortifyServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\Fortify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Backend controllers and scaffolding for Laravel authentication.", - "keywords": [ - "auth", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/fortify/issues", - "source": "https://github.com/laravel/fortify" - }, - "time": "2025-12-15T14:48:33+00:00" - }, { "name": "laravel/framework", "version": "v12.47.0", @@ -2068,16 +2004,16 @@ }, { "name": "laravel/prompts", - "version": "v0.3.10", + "version": "v0.3.9", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "360ba095ef9f51017473505191fbd4ab73e1cab3" + "reference": "5c41bf0555b7cfefaad4e66d3046675829581ac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/360ba095ef9f51017473505191fbd4ab73e1cab3", - "reference": "360ba095ef9f51017473505191fbd4ab73e1cab3", + "url": "https://api.github.com/repos/laravel/prompts/zipball/5c41bf0555b7cfefaad4e66d3046675829581ac4", + "reference": "5c41bf0555b7cfefaad4e66d3046675829581ac4", "shasum": "" }, "require": { @@ -2121,9 +2057,9 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.10" + "source": "https://github.com/laravel/prompts/tree/v0.3.9" }, - "time": "2026-01-13T20:29:29+00:00" + "time": "2026-01-07T21:00:29+00:00" }, { "name": "laravel/sanctum", @@ -3146,16 +3082,16 @@ }, { "name": "livewire/livewire", - "version": "v4.0.1", + "version": "v3.7.4", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "c7539589d5af82691bef17da17ce4e289269f8d9" + "reference": "5a8dffd4c0ab357ff7ed5b39e7c2453d962a68e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/c7539589d5af82691bef17da17ce4e289269f8d9", - "reference": "c7539589d5af82691bef17da17ce4e289269f8d9", + "url": "https://api.github.com/repos/livewire/livewire/zipball/5a8dffd4c0ab357ff7ed5b39e7c2453d962a68e0", + "reference": "5a8dffd4c0ab357ff7ed5b39e7c2453d962a68e0", "shasum": "" }, "require": { @@ -3210,7 +3146,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v4.0.1" + "source": "https://github.com/livewire/livewire/tree/v3.7.4" }, "funding": [ { @@ -3218,7 +3154,78 @@ "type": "github" } ], - "time": "2026-01-14T18:40:41+00:00" + "time": "2026-01-13T09:37:21+00:00" + }, + { + "name": "livewire/volt", + "version": "v1.10.1", + "source": { + "type": "git", + "url": "https://github.com/livewire/volt.git", + "reference": "48cff133990c6261c63ee279fc091af6f6c6654e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/livewire/volt/zipball/48cff133990c6261c63ee279fc091af6f6c6654e", + "reference": "48cff133990c6261c63ee279fc091af6f6c6654e", + "shasum": "" + }, + "require": { + "laravel/framework": "^10.38.2|^11.0|^12.0", + "livewire/livewire": "^3.6.1|^4.0", + "php": "^8.1" + }, + "require-dev": { + "laravel/folio": "^1.1", + "orchestra/testbench": "^8.36|^9.15|^10.8", + "pestphp/pest": "^2.9.5|^3.0|^4.0", + "phpstan/phpstan": "^1.10" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Livewire\\Volt\\VoltServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "functions.php" + ], + "psr-4": { + "Livewire\\Volt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "An elegantly crafted functional API for Laravel Livewire.", + "homepage": "https://github.com/livewire/volt", + "keywords": [ + "laravel", + "livewire", + "volt" + ], + "support": { + "issues": "https://github.com/livewire/volt/issues", + "source": "https://github.com/livewire/volt" + }, + "time": "2025-11-25T16:19:15+00:00" }, { "name": "maennchen/zipstream-php", @@ -4226,58 +4233,6 @@ ], "time": "2025-12-15T11:51:42+00:00" }, - { - "name": "pragmarx/google2fa", - "version": "v9.0.0", - "source": { - "type": "git", - "url": "https://github.com/antonioribeiro/google2fa.git", - "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/e6bc62dd6ae83acc475f57912e27466019a1f2cf", - "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf", - "shasum": "" - }, - "require": { - "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0", - "php": "^7.1|^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^7.5.15|^8.5|^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "PragmaRX\\Google2FA\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Antonio Carlos Ribeiro", - "email": "acr@antoniocarlosribeiro.com", - "role": "Creator & Designer" - } - ], - "description": "A One Time Password Authentication package, compatible with Google Authenticator.", - "keywords": [ - "2fa", - "Authentication", - "Two Factor Authentication", - "google2fa" - ], - "support": { - "issues": "https://github.com/antonioribeiro/google2fa/issues", - "source": "https://github.com/antonioribeiro/google2fa/tree/v9.0.0" - }, - "time": "2025-09-19T22:51:08+00:00" - }, { "name": "psr/clock", "version": "1.0.0", @@ -4967,6 +4922,74 @@ }, "time": "2025-12-14T04:43:48+00:00" }, + { + "name": "simplesoftwareio/simple-qrcode", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/SimpleSoftwareIO/simple-qrcode.git", + "reference": "916db7948ca6772d54bb617259c768c9cdc8d537" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SimpleSoftwareIO/simple-qrcode/zipball/916db7948ca6772d54bb617259c768c9cdc8d537", + "reference": "916db7948ca6772d54bb617259c768c9cdc8d537", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^2.0", + "ext-gd": "*", + "php": ">=7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "~1", + "phpunit/phpunit": "~9" + }, + "suggest": { + "ext-imagick": "Allows the generation of PNG QrCodes.", + "illuminate/support": "Allows for use within Laravel." + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "QrCode": "SimpleSoftwareIO\\QrCode\\Facades\\QrCode" + }, + "providers": [ + "SimpleSoftwareIO\\QrCode\\QrCodeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "SimpleSoftwareIO\\QrCode\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Simple Software LLC", + "email": "support@simplesoftware.io" + } + ], + "description": "Simple QrCode is a QR code generator made for Laravel.", + "homepage": "https://www.simplesoftware.io/#/docs/simple-qrcode", + "keywords": [ + "Simple", + "generator", + "laravel", + "qrcode", + "wrapper" + ], + "support": { + "issues": "https://github.com/SimpleSoftwareIO/simple-qrcode/issues", + "source": "https://github.com/SimpleSoftwareIO/simple-qrcode/tree/4.2.0" + }, + "time": "2021-02-08T20:43:55+00:00" + }, { "name": "spatie/browsershot", "version": "5.2.0", diff --git a/config/auth.php b/config/auth.php index 7d1eb0d..0ba5d5d 100644 --- a/config/auth.php +++ b/config/auth.php @@ -104,7 +104,7 @@ return [ | Password Confirmation Timeout |-------------------------------------------------------------------------- | - | Here you may define the number of seconds before a password confirmation + | Here you may define the amount of seconds before a password confirmation | window expires and users are asked to re-enter their password via the | confirmation screen. By default, the timeout lasts for three hours. | diff --git a/config/cache.php b/config/cache.php index b32aead..925f7d2 100644 --- a/config/cache.php +++ b/config/cache.php @@ -27,8 +27,7 @@ return [ | same cache driver to group types of items stored in your caches. | | Supported drivers: "array", "database", "file", "memcached", - | "redis", "dynamodb", "octane", - | "failover", "null" + | "redis", "dynamodb", "octane", "null" | */ @@ -91,14 +90,6 @@ return [ 'driver' => 'octane', ], - 'failover' => [ - 'driver' => 'failover', - 'stores' => [ - 'database', - 'array', - ], - ], - ], /* @@ -112,6 +103,6 @@ return [ | */ - 'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'), + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), ]; diff --git a/config/database.php b/config/database.php index 4da9dc6..8910562 100644 --- a/config/database.php +++ b/config/database.php @@ -40,7 +40,6 @@ return [ 'busy_timeout' => null, 'journal_mode' => null, 'synchronous' => null, - 'transaction_mode' => 'DEFERRED', ], 'mysql' => [ @@ -59,7 +58,7 @@ return [ 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ - (PHP_VERSION_ID >= 80500 ? Pdo\Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], @@ -79,7 +78,7 @@ return [ 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ - (PHP_VERSION_ID >= 80500 ? Pdo\Mysql::ATTR_SSL_CA : PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'), + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ], @@ -95,7 +94,7 @@ return [ 'prefix' => '', 'prefix_indexes' => true, 'search_path' => 'public', - 'sslmode' => env('DB_SSLMODE', 'prefer'), + 'sslmode' => 'prefer', ], 'sqlsrv' => [ @@ -148,7 +147,7 @@ return [ 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), - 'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), 'persistent' => env('REDIS_PERSISTENT', false), ], @@ -159,10 +158,6 @@ return [ 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', '6379'), 'database' => env('REDIS_DB', '0'), - 'max_retries' => env('REDIS_MAX_RETRIES', 3), - 'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'), - 'backoff_base' => env('REDIS_BACKOFF_BASE', 100), - 'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000), ], 'cache' => [ @@ -172,10 +167,6 @@ return [ 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', '6379'), 'database' => env('REDIS_CACHE_DB', '1'), - 'max_retries' => env('REDIS_MAX_RETRIES', 3), - 'backoff_algorithm' => env('REDIS_BACKOFF_ALGORITHM', 'decorrelated_jitter'), - 'backoff_base' => env('REDIS_BACKOFF_BASE', 100), - 'backoff_cap' => env('REDIS_BACKOFF_CAP', 1000), ], ], diff --git a/config/filesystems.php b/config/filesystems.php index ccaf2a9..b564035 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -35,16 +35,14 @@ return [ 'root' => storage_path('app/private'), 'serve' => true, 'throw' => false, - 'report' => false, ], 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), - 'url' => mb_rtrim(env('APP_URL'), '/').'/storage', + 'url' => env('APP_URL').'/storage', 'visibility' => 'public', 'throw' => false, - 'report' => false, ], 's3' => [ @@ -57,7 +55,6 @@ return [ 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'throw' => false, - 'report' => false, ], ], diff --git a/config/fortify.php b/config/fortify.php deleted file mode 100644 index ed7b0c0..0000000 --- a/config/fortify.php +++ /dev/null @@ -1,159 +0,0 @@ - 'web', - - /* - |-------------------------------------------------------------------------- - | Fortify Password Broker - |-------------------------------------------------------------------------- - | - | Here you may specify which password broker Fortify can use when a user - | is resetting their password. This configured value should match one - | of your password brokers setup in your "auth" configuration file. - | - */ - - 'passwords' => 'users', - - /* - |-------------------------------------------------------------------------- - | Username / Email - |-------------------------------------------------------------------------- - | - | This value defines which model attribute should be considered as your - | application's "username" field. Typically, this might be the email - | address of the users but you are free to change this value here. - | - | Out of the box, Fortify expects forgot password and reset password - | requests to have a field named 'email'. If the application uses - | another name for the field you may define it below as needed. - | - */ - - 'username' => 'email', - - 'email' => 'email', - - /* - |-------------------------------------------------------------------------- - | Lowercase Usernames - |-------------------------------------------------------------------------- - | - | This value defines whether usernames should be lowercased before saving - | them in the database, as some database system string fields are case - | sensitive. You may disable this for your application if necessary. - | - */ - - 'lowercase_usernames' => true, - - /* - |-------------------------------------------------------------------------- - | Home Path - |-------------------------------------------------------------------------- - | - | Here you may configure the path where users will get redirected during - | authentication or password reset when the operations are successful - | and the user is authenticated. You are free to change this value. - | - */ - - 'home' => '/dashboard', - - /* - |-------------------------------------------------------------------------- - | Fortify Routes Prefix / Subdomain - |-------------------------------------------------------------------------- - | - | Here you may specify which prefix Fortify will assign to all the routes - | that it registers with the application. If necessary, you may change - | subdomain under which all of the Fortify routes will be available. - | - */ - - 'prefix' => '', - - 'domain' => null, - - /* - |-------------------------------------------------------------------------- - | Fortify Routes Middleware - |-------------------------------------------------------------------------- - | - | Here you may specify which middleware Fortify will assign to the routes - | that it registers with the application. If necessary, you may change - | these middleware but typically this provided default is preferred. - | - */ - - 'middleware' => ['web'], - - /* - |-------------------------------------------------------------------------- - | Rate Limiting - |-------------------------------------------------------------------------- - | - | By default, Fortify will throttle logins to five requests per minute for - | every email and IP address combination. However, if you would like to - | specify a custom rate limiter to call then you may specify it here. - | - */ - - 'limiters' => [ - 'login' => 'login', - 'two-factor' => 'two-factor', - ], - - /* - |-------------------------------------------------------------------------- - | Register View Routes - |-------------------------------------------------------------------------- - | - | Here you may specify if the routes returning views should be disabled as - | you may not need them when building your own application. This may be - | especially true if you're writing a custom single-page application. - | - */ - - 'views' => true, - - /* - |-------------------------------------------------------------------------- - | Features - |-------------------------------------------------------------------------- - | - | Some of the Fortify features are optional. You may disable the features - | by removing them from this array. You're free to only remove some of - | these features or you can even remove all of these if you need to. - | - */ - - 'features' => [ - config('app.registration.enabled') && Features::registration(), - Features::resetPasswords(), - Features::emailVerification(), - // Features::updateProfileInformation(), - // Features::updatePasswords(), - Features::twoFactorAuthentication([ - 'confirm' => true, - 'confirmPassword' => true, - // 'window' => 0, - ]), - ], - -]; diff --git a/config/livewire.php b/config/livewire.php deleted file mode 100644 index 4c68f45..0000000 --- a/config/livewire.php +++ /dev/null @@ -1,277 +0,0 @@ - [ - resource_path('views/components'), - resource_path('views/livewire'), - ], - - /* - |--------------------------------------------------------------------------- - | Component Namespaces - |--------------------------------------------------------------------------- - | - | This value sets default namespaces that will be used to resolve view-based - | components like single-file and multi-file components. These folders'll - | also be referenced when creating new components via the make command. - | - */ - - 'component_namespaces' => [ - 'layouts' => resource_path('views/layouts'), - 'pages' => resource_path('views/pages'), - ], - - /* - |--------------------------------------------------------------------------- - | Page Layout - |--------------------------------------------------------------------------- - | The view that will be used as the layout when rendering a single component as - | an entire page via `Route::livewire('/post/create', 'pages::create-post')`. - | In this case, the content of pages::create-post will render into $slot. - | - */ - - 'component_layout' => 'layouts::app', - - /* - |--------------------------------------------------------------------------- - | Lazy Loading Placeholder - |--------------------------------------------------------------------------- - | Livewire allows you to lazy load components that would otherwise slow down - | the initial page load. Every component can have a custom placeholder or - | you can define the default placeholder view for all components below. - | - */ - - 'component_placeholder' => null, // Example: 'placeholders::skeleton' - - /* - |--------------------------------------------------------------------------- - | Make Command - |--------------------------------------------------------------------------- - | This value determines the default configuration for the artisan make command - | You can configure the component type (sfc, mfc, class) and whether to use - | the high-voltage (⚡) emoji as a prefix in the sfc|mfc component names. - | - */ - - 'make_command' => [ - 'type' => 'sfc', // Options: 'sfc', 'mfc', 'class' - 'emoji' => false, // Options: true, false - ], - - /* - |--------------------------------------------------------------------------- - | Class Namespace - |--------------------------------------------------------------------------- - | - | This value sets the root class namespace for Livewire component classes in - | your application. This value will change where component auto-discovery - | finds components. It's also referenced by the file creation commands. - | - */ - - 'class_namespace' => 'App\\Livewire', - - /* - |--------------------------------------------------------------------------- - | Class Path - |--------------------------------------------------------------------------- - | - | This value is used to specify the path where Livewire component class files - | are created when running creation commands like `artisan make:livewire`. - | This path is customizable to match your projects directory structure. - | - */ - - 'class_path' => app_path('Livewire'), - - /* - |--------------------------------------------------------------------------- - | View Path - |--------------------------------------------------------------------------- - | - | This value is used to specify where Livewire component Blade templates are - | stored when running file creation commands like `artisan make:livewire`. - | It is also used if you choose to omit a component's render() method. - | - */ - - 'view_path' => resource_path('views/livewire'), - - /* - |--------------------------------------------------------------------------- - | Temporary File Uploads - |--------------------------------------------------------------------------- - | - | Livewire handles file uploads by storing uploads in a temporary directory - | before the file is stored permanently. All file uploads are directed to - | a global endpoint for temporary storage. You may configure this below: - | - */ - - 'temporary_file_upload' => [ - 'disk' => env('LIVEWIRE_TEMPORARY_FILE_UPLOAD_DISK'), // Example: 'local', 's3' | Default: 'default' - 'rules' => null, // Example: ['file', 'mimes:png,jpg'] | Default: ['required', 'file', 'max:12288'] (12MB) - 'directory' => null, // Example: 'tmp' | Default: 'livewire-tmp' - 'middleware' => null, // Example: 'throttle:5,1' | Default: 'throttle:60,1' - 'preview_mimes' => [ // Supported file types for temporary pre-signed file URLs... - 'png', 'gif', 'bmp', 'svg', 'wav', 'mp4', - 'mov', 'avi', 'wmv', 'mp3', 'm4a', - 'jpg', 'jpeg', 'mpga', 'webp', 'wma', - ], - 'max_upload_time' => 5, // Max duration (in minutes) before an upload is invalidated... - 'cleanup' => true, // Should cleanup temporary uploads older than 24 hrs... - ], - - /* - |--------------------------------------------------------------------------- - | Render On Redirect - |--------------------------------------------------------------------------- - | - | This value determines if Livewire will run a component's `render()` method - | after a redirect has been triggered using something like `redirect(...)` - | Setting this to true will render the view once more before redirecting - | - */ - - 'render_on_redirect' => false, - - /* - |--------------------------------------------------------------------------- - | Eloquent Model Binding - |--------------------------------------------------------------------------- - | - | Previous versions of Livewire supported binding directly to eloquent model - | properties using wire:model by default. However, this behavior has been - | deemed too "magical" and has therefore been put under a feature flag. - | - */ - - 'legacy_model_binding' => false, - - /* - |--------------------------------------------------------------------------- - | Auto-inject Frontend Assets - |--------------------------------------------------------------------------- - | - | By default, Livewire automatically injects its JavaScript and CSS into the - | and of pages containing Livewire components. By disabling - | this behavior, you need to use @livewireStyles and @livewireScripts. - | - */ - - 'inject_assets' => true, - - /* - |--------------------------------------------------------------------------- - | Navigate (SPA mode) - |--------------------------------------------------------------------------- - | - | By adding `wire:navigate` to links in your Livewire application, Livewire - | will prevent the default link handling and instead request those pages - | via AJAX, creating an SPA-like effect. Configure this behavior here. - | - */ - - 'navigate' => [ - 'show_progress_bar' => true, - 'progress_bar_color' => '#E05B45', - ], - - /* - |--------------------------------------------------------------------------- - | HTML Morph Markers - |--------------------------------------------------------------------------- - | - | Livewire intelligently "morphs" existing HTML into the newly rendered HTML - | after each update. To make this process more reliable, Livewire injects - | "markers" into the rendered Blade surrounding @if, @class & @foreach. - | - */ - - 'inject_morph_markers' => true, - - /* - |--------------------------------------------------------------------------- - | Smart Wire Keys - |--------------------------------------------------------------------------- - | - | Livewire uses loops and keys used within loops to generate smart keys that - | are applied to nested components that don't have them. This makes using - | nested components more reliable by ensuring that they all have keys. - | - */ - - 'smart_wire_keys' => true, - - /* - |--------------------------------------------------------------------------- - | Pagination Theme - |--------------------------------------------------------------------------- - | - | When enabling Livewire's pagination feature by using the `WithPagination` - | trait, Livewire will use Tailwind templates to render pagination views - | on the page. If you want Bootstrap CSS, you can specify: "bootstrap" - | - */ - - 'pagination_theme' => 'tailwind', - - /* - |--------------------------------------------------------------------------- - | Release Token - |--------------------------------------------------------------------------- - | - | This token is stored client-side and sent along with each request to check - | a users session to see if a new release has invalidated it. If there is - | a mismatch it will throw an error and prompt for a browser refresh. - | - */ - - 'release_token' => 'a', - - /* - |--------------------------------------------------------------------------- - | CSP Safe - |--------------------------------------------------------------------------- - | - | This config is used to determine if Livewire will use the CSP-safe version - | of Alpine in its bundle. This is useful for applications that are using - | strict Content Security Policy (CSP) to protect against XSS attacks. - | - */ - - 'csp_safe' => false, - - /* - |--------------------------------------------------------------------------- - | Payload Guards - |--------------------------------------------------------------------------- - | - | These settings protect against malicious or oversized payloads that could - | cause denial of service. The default values should feel reasonable for - | most web applications. Each can be set to null to disable the limit. - | - */ - - 'payload' => [ - 'max_size' => 1024 * 1024, // 1MB - maximum request payload size in bytes - 'max_nesting_depth' => 10, // Maximum depth of dot-notation property paths - 'max_calls' => 50, // Maximum method calls per request - 'max_components' => 20, // Maximum components per batch request - ], -]; diff --git a/config/logging.php b/config/logging.php index 9f6e543..47b1d08 100644 --- a/config/logging.php +++ b/config/logging.php @@ -54,7 +54,7 @@ return [ 'stack' => [ 'driver' => 'stack', - 'channels' => explode(',', (string) env('LOG_STACK', 'single')), + 'channels' => explode(',', env('LOG_STACK', 'single')), 'ignore_exceptions' => false, ], @@ -98,10 +98,10 @@ return [ 'driver' => 'monolog', 'level' => env('LOG_LEVEL', 'debug'), 'handler' => StreamHandler::class, - 'handler_with' => [ + 'formatter' => env('LOG_STDOUT_FORMATTER'), + 'with' => [ 'stream' => 'php://stdout', ], - 'formatter' => env('LOG_STDOUT_FORMATTER'), 'processors' => [PsrLogMessageProcessor::class], ], @@ -109,10 +109,10 @@ return [ 'driver' => 'monolog', 'level' => env('LOG_LEVEL', 'debug'), 'handler' => StreamHandler::class, - 'handler_with' => [ + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ 'stream' => 'php://stderr', ], - 'formatter' => env('LOG_STDERR_FORMATTER'), 'processors' => [PsrLogMessageProcessor::class], ], diff --git a/config/mail.php b/config/mail.php index 522b284..756305b 100644 --- a/config/mail.php +++ b/config/mail.php @@ -46,7 +46,7 @@ return [ 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'timeout' => null, - 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url((string) env('APP_URL', 'http://localhost'), PHP_URL_HOST)), + 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL', 'http://localhost'), PHP_URL_HOST)), ], 'ses' => [ @@ -85,7 +85,6 @@ return [ 'smtp', 'log', ], - 'retry_after' => 60, ], 'roundrobin' => [ @@ -94,7 +93,6 @@ return [ 'ses', 'postmark', ], - 'retry_after' => 60, ], ], diff --git a/config/queue.php b/config/queue.php index 79c2c0a..116bd8d 100644 --- a/config/queue.php +++ b/config/queue.php @@ -24,8 +24,7 @@ return [ | 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", - | "deferred", "background", "failover", "null" + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" | */ @@ -73,22 +72,6 @@ return [ 'after_commit' => false, ], - 'deferred' => [ - 'driver' => 'deferred', - ], - - 'background' => [ - 'driver' => 'background', - ], - - 'failover' => [ - 'driver' => 'failover', - 'connections' => [ - 'database', - 'deferred', - ], - ], - ], /* diff --git a/config/services.php b/config/services.php index 82eeeef..d97255a 100644 --- a/config/services.php +++ b/config/services.php @@ -15,11 +15,7 @@ return [ */ 'postmark' => [ - 'key' => env('POSTMARK_API_KEY'), - ], - - 'resend' => [ - 'key' => env('RESEND_API_KEY'), + 'token' => env('POSTMARK_TOKEN'), ], 'ses' => [ @@ -28,6 +24,10 @@ return [ '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'), diff --git a/config/session.php b/config/session.php index 5b541b7..f0b6541 100644 --- a/config/session.php +++ b/config/session.php @@ -13,8 +13,8 @@ return [ | incoming requests. Laravel supports a variety of storage options to | persist session data. Database storage is a great default choice. | - | Supported: "file", "cookie", "database", "memcached", - | "redis", "dynamodb", "array" + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "dynamodb", "array" | */ @@ -32,7 +32,7 @@ return [ | */ - 'lifetime' => (int) env('SESSION_LIFETIME', 120), + 'lifetime' => env('SESSION_LIFETIME', 120), 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), @@ -97,7 +97,7 @@ return [ | 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: "dynamodb", "memcached", "redis" + | Affects: "apc", "dynamodb", "memcached", "redis" | */ @@ -129,7 +129,7 @@ return [ 'cookie' => env( 'SESSION_COOKIE', - Str::slug((string) env('APP_NAME', 'laravel')).'-session' + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' ), /* @@ -152,7 +152,7 @@ return [ | | This value determines the domain and subdomains the session cookie is | available to. By default, the cookie will be available to the root - | domain without subdomains. Typically, this shouldn't be changed. + | domain and all subdomains. Typically, this shouldn't be changed. | */ diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 80da5ac..c5d3f2c 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -29,9 +29,7 @@ class UserFactory extends Factory 'email_verified_at' => now(), 'password' => static::$password ??= Hash::make('password'), 'remember_token' => Str::random(10), - 'two_factor_secret' => null, - 'two_factor_recovery_codes' => null, - 'two_factor_confirmed_at' => null, + 'assign_new_devices' => false, ]; } @@ -44,16 +42,4 @@ class UserFactory extends Factory 'email_verified_at' => null, ]); } - - /** - * Indicate that the model has two-factor authentication configured. - */ - public function withTwoFactor(): static - { - return $this->state(fn (array $attributes) => [ - 'two_factor_secret' => encrypt('secret'), - 'two_factor_recovery_codes' => encrypt(json_encode(['recovery-code-1'])), - 'two_factor_confirmed_at' => now(), - ]); - } } diff --git a/database/migrations/2026_01_15_075243_add_two_factor_columns_to_users_table.php b/database/migrations/2026_01_15_075243_add_two_factor_columns_to_users_table.php deleted file mode 100644 index 187d974..0000000 --- a/database/migrations/2026_01_15_075243_add_two_factor_columns_to_users_table.php +++ /dev/null @@ -1,34 +0,0 @@ -text('two_factor_secret')->after('password')->nullable(); - $table->text('two_factor_recovery_codes')->after('two_factor_secret')->nullable(); - $table->timestamp('two_factor_confirmed_at')->after('two_factor_recovery_codes')->nullable(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('users', function (Blueprint $table) { - $table->dropColumn([ - 'two_factor_secret', - 'two_factor_recovery_codes', - 'two_factor_confirmed_at', - ]); - }); - } -}; diff --git a/resources/views/components/action-message.blade.php b/resources/views/components/action-message.blade.php index d313ee6..db63acf 100644 --- a/resources/views/components/action-message.blade.php +++ b/resources/views/components/action-message.blade.php @@ -8,7 +8,7 @@ x-show.transition.out.opacity.duration.1500ms="shown" x-transition:leave.opacity.duration.1500ms style="display: none" - {{ $attributes->merge(['class' => 'text-sm']) }} + {{ $attributes->merge(['class' => 'text-sm text-gray-600']) }} > {{ $slot->isEmpty() ? __('Saved.') : $slot }} diff --git a/resources/views/components/auth-header.blade.php b/resources/views/components/auth-header.blade.php index e596a3f..a68f69d 100644 --- a/resources/views/components/auth-header.blade.php +++ b/resources/views/components/auth-header.blade.php @@ -3,7 +3,7 @@ 'description', ]) -
- {{ $title }} - {{ $description }} +
+

{{ $title }}

+

{{ $description }}

diff --git a/resources/views/components/desktop-user-menu.blade.php b/resources/views/components/desktop-user-menu.blade.php deleted file mode 100644 index 5b386c5..0000000 --- a/resources/views/components/desktop-user-menu.blade.php +++ /dev/null @@ -1,39 +0,0 @@ - - only('name') }} - :initials="auth()->user()->initials()" - icon:trailing="chevrons-up-down" - data-test="sidebar-menu-button" - /> - - -
- -
- {{ auth()->user()->name }} - {{ auth()->user()->email }} -
-
- - - - {{ __('Settings') }} - -
- @csrf - - {{ __('Log Out') }} - -
-
-
-
diff --git a/resources/views/layouts/app.blade.php b/resources/views/components/layouts/app.blade.php similarity index 51% rename from resources/views/layouts/app.blade.php rename to resources/views/components/layouts/app.blade.php index e20d56b..ec0ebf7 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/components/layouts/app.blade.php @@ -1,5 +1,5 @@ - + {{ $slot }} - + diff --git a/resources/views/layouts/app/header.blade.php b/resources/views/components/layouts/app/header.blade.php similarity index 100% rename from resources/views/layouts/app/header.blade.php rename to resources/views/components/layouts/app/header.blade.php diff --git a/resources/views/components/layouts/auth.blade.php b/resources/views/components/layouts/auth.blade.php new file mode 100644 index 0000000..4ddd14d --- /dev/null +++ b/resources/views/components/layouts/auth.blade.php @@ -0,0 +1,3 @@ + + {{ $slot }} + diff --git a/resources/views/layouts/auth/card.blade.php b/resources/views/components/layouts/auth/card.blade.php similarity index 85% rename from resources/views/layouts/auth/card.blade.php rename to resources/views/components/layouts/auth/card.blade.php index db94716..b5a62c6 100644 --- a/resources/views/layouts/auth/card.blade.php +++ b/resources/views/components/layouts/auth/card.blade.php @@ -6,7 +6,7 @@
- + @@ -15,7 +15,7 @@
-
+
{{ $slot }}
diff --git a/resources/views/layouts/auth/simple.blade.php b/resources/views/components/layouts/auth/simple.blade.php similarity index 95% rename from resources/views/layouts/auth/simple.blade.php rename to resources/views/components/layouts/auth/simple.blade.php index 6e0d909..9dbbe92 100644 --- a/resources/views/layouts/auth/simple.blade.php +++ b/resources/views/components/layouts/auth/simple.blade.php @@ -6,7 +6,7 @@
- + diff --git a/resources/views/layouts/auth/split.blade.php b/resources/views/components/layouts/auth/split.blade.php similarity index 80% rename from resources/views/layouts/auth/split.blade.php rename to resources/views/components/layouts/auth/split.blade.php index 4e9788b..e7b5c67 100644 --- a/resources/views/layouts/auth/split.blade.php +++ b/resources/views/components/layouts/auth/split.blade.php @@ -5,11 +5,11 @@
-