filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
15.9k stars 2.53k forks source link

Page expired (419) on user registration using the FileUpload component #13394

Open rpereira-tae opened 1 week ago

rpereira-tae commented 1 week ago

Package

filament/filament

Package Version

v3.2.92

Laravel Version

v11.11.1

Livewire Version

v3.5.1

PHP Version

PHP 8.2

Problem description

Hello! I’ve been trying to create a custom user registration page in Filament, but I’ve been dealing with a 419 "The page has expired" error when registering. The user does get registered, and the notification is sent successfully, but I always encounter this 419 error after clicking the "Sign up" button.

Yesterday, I noticed that if I remove the FileUpload component from the registration form, I don’t get that 419 error. It seems quite strange to me.

https://github.com/filamentphp/filament/assets/61505019/d5317019-0135-44f3-b156-cd8cb1014abc

It seems that when the image is uploaded to the temp directory the cookies are refreshed at least two times.

image

I'm using Redis as the session driver.

Expected behavior

The user should be registered without getting the 419 "The page has expired".

Steps to reproduce

  1. Create a custom registration page that extends Filament\Pages\Auth\Register.
  2. Add the custom page to one of the panel providers (such as AdminPanelProvider).
  3. Add the following form method:
public function form(Form $form): Form
{
    return $form
        ->schema([
            Forms\Components\Section::make('information')
                ->schema([
                    $this->getNameFormComponent(),

                    $this->getEmailFormComponent(),

                    $this->getPasswordFormComponent(),

                    $this->getPasswordConfirmationFormComponent(),

                    Forms\Components\FileUpload::make('image')
                        ->required()
                        ->image()
                        ->maxFiles(1)
                        ->placeholder('profile_image.jpg'),
                ]),
        ]);
}
  1. Register the user in the view.

I published a reproduction repository if you want to try it out.

Reproduction repository (issue will be closed if this is not valid)

https://github.com/rpereira-tae/test-app

Relevant log output

There was not log from the `laravel.log` file.

Donate 💰 to fund this issue

Fund with Polar

rpereira-tae commented 1 week ago

Not totally sure if it's a bug or something I missed during the configuration. Any suggestion or comment is appreciated 🙏🏻

urufudev commented 6 days ago

I remember seeing that error in my log as well, but in my case I was using Livewire. I compared my code to yours and the only differences I could find are that I don't have @csrf in the Blade template and I have ->statePath('data') in the form.

 <form x-data="{ isUploadingFile: false, isSubmitting: @entangle('isSubmitting'), isFinishedRegistration: @entangle('isFinishedRegistration') }" x-on:file-upload-started="isUploadingFile = true"
            x-on:file-upload-finished="isUploadingFile = false" wire:submit="register" class="fi-form grid gap-y-6">

            {{ $this->form }}

            <x-filament::button type="submit" wire:loading.attr="disabled"
                x-bind:disabled="isUploadingFile || isSubmitting || isFinishedRegistration"
                x-bind:class="{ 'enabled:opacity-70 enabled:cursor-wait': isSubmitting || isUploadingFile || isFinishedRegistration }">

                <x-filament::loading-indicator wire:loading wire:target="register" class="h-5 w-5 mr-1" />

                <span x-show="isUploadingFile">Subiendo archivo...</span>
                <span x-show=" isFinishedRegistration || isSubmitting && !isUploadingFile">Enviando...</span>
                <span x-show=" !isFinishedRegistration && !isSubmitting && !isUploadingFile">Solicitar Registro</span>

            </x-filament::button>
        </form>
public function form(Form $form): Form
    {
        return $form
            ->schema([
                $this->getDniFormComponent(),
                $this->getPhoneFormComponent(),
                $this->getEmailFormComponent(),
                $this->getPasswordFormComponent(),
                $this->getPasswordConfirmationFormComponent(),
                $this->getFileFormComponent(),
                Turnstile::make('turnstile')
                    ->size('normal')
                    ->language('es')

            ])
            ->statePath('data');
    }

        protected function getFileFormComponent(): FilamentComponent
    {
        return FileUpload::make('file')
            ->acceptedFileTypes(['application/pdf'])
            ->label('Formato de solicitud')
            ->hint(new HtmlString(Blade::render('<x-filament::link :href="asset(\'build/assets/pdf/formato_boletas.pdf\')" target="_blank" icon="heroicon-m-document-arrow-down"> Formato a adjuntar </x-filament::link>')))
            ->helperText('Procura los datos sean legibles para mayor rapidez de tramite.')
            ->directory('request-files')
            ->required();
    }
rpereira-tae commented 5 days ago

Initially I thought it was missing the @csrf directive in the blade template. But adding or not didn't make any difference.