Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow each domains to have its own routes to avoid duplicate route registration #12462

Merged
merged 13 commits into from
Apr 28, 2024

Conversation

declum
Copy link
Contributor

@declum declum commented Apr 23, 2024

Description

if we register the Panel with multiple domains, php artisan optimize fails with Unable to prepare route [login] for serialization. Another route has already been assigned name [filament.dashboard.auth.login].

It is because panel logic is registrying routes with the same name for each domain. This PR tries to fix that.

Closes: #11837

Visual changes

Nil

Functional changes

  • Code style has been fixed by running the composer cs command.
  • Changes have been tested to not break existing functionality.
  • Documentation is up-to-date.

Copy link
Member

@danharrin danharrin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make it so this is only used on panels with > 1 domain, not > 0 domains

@danharrin danharrin added the bug Something isn't working label Apr 24, 2024
@danharrin danharrin added this to the v3 milestone Apr 24, 2024
@danharrin danharrin self-assigned this Apr 24, 2024
@declum
Copy link
Contributor Author

declum commented Apr 24, 2024

@danharrin Changed it. Please have look.

@danharrin
Copy link
Member

I have a feeling you didnt test that, the routes file still needs updating as its adding the extra param for 1 domain. Please manually test this with one domain or write a test for our suite.

@declum
Copy link
Contributor Author

declum commented Apr 24, 2024

I have a feeling you didnt test that, the routes file still needs updating as its adding the extra param for 1 domain. Please manually test this with one domain or write a test for our suite.

Ya didn't test after changing to < 1 👍🏽

How do I write test for routes? Is there a sample reference in the repo?

@declum declum closed this Apr 24, 2024
@declum declum reopened this Apr 24, 2024
@danharrin
Copy link
Member

The only test we really need is to hit the dashboard and check it renders, right? Set up a new panel provider with domain configuration. Basically to make sure the routing doesnt error out

@danharrin
Copy link
Member

Maybe have one panel provider for single domain, one for multi domains

@declum
Copy link
Contributor Author

declum commented Apr 24, 2024

Bellow are the tests performed.

  1. With no domain: Verified that site and admin panel is accessible with domain 127.0.0.1:8000
  2. With single domain: Verified that site is accessible with domain 127.0.0.1:8000, and admin panel is only available at the given domain
  3. With multiple domains: Verified that site is accessible with domain 127.0.0.1:8000, and admin panel is only available at the given domains (first.* and second.*)

Below are the output of php artisan route:list for the above scenarios.

Tested the fix with no domain

% php artisan route:list

GET|HEAD / ...................................................................................................................................................................................................................................................................................................................................................................
POST _ignition/execute-solution ............................................................................................................................................................................................................................................................ ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
GET|HEAD _ignition/health-check ........................................................................................................................................................................................................................................................................ ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
POST _ignition/update-config ..................................................................................................................................................................................................................................................................... ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
GET|HEAD admin ..................................................................................................................................................................................................................................................................................................... filament.admin.pages.dashboard › Filament\Pages\Dashboard
GET|HEAD admin/login ................................................................................................................................................................................................................................................................................................... filament.admin.auth.login › Filament\Pages\Auth\Login
POST admin/logout ........................................................................................................................................................................................................................................................................... filament.admin.auth.logout › Filament\Http\Controllers\Auth\LogoutController
GET|HEAD filament/exports/{export}/download ............................................................................................................................................................................................................................................. filament.exports.download › Filament\Actions\Exports\Http\Controllers\DownloadExport
GET|HEAD filament/imports/{import}/failed-rows/download ........................................................................................................................................................................................................... filament.imports.failed-rows.download › Filament\Actions\Imports\Http\Controllers\DownloadImportFailureCsv
GET|HEAD livewire/livewire.js .................................................................................................................................................................................................................................................................................... Livewire\Mechanisms › FrontendAssets@returnJavaScriptAsFile
GET|HEAD livewire/livewire.min.js.map .............................................................................................................................................................................................................................................................................................. Livewire\Mechanisms › FrontendAssets@maps
GET|HEAD livewire/preview-file/{filename} ........................................................................................................................................................................................................................................................... livewire.preview-file › Livewire\Features › FilePreviewController@handle
POST livewire/update ................................................................................................................................................................................................................................................................................. livewire.update › Livewire\Mechanisms › HandleRequests@handleUpdate
POST livewire/upload-file ......................................................................................................................................................................................................................................................................... livewire.upload-file › Livewire\Features › FileUploadController@handle
GET|HEAD up ..................................................................................................................................................................................................................................................................................................................................................................

With Single Domain ->domain('single.127-0-0-1.sslip.io')

`% php artisan route:list

GET|HEAD / ...................................................................................................................................................................................................................................................................................................................................................................
POST _ignition/execute-solution ............................................................................................................................................................................................................................................................ ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
GET|HEAD _ignition/health-check ........................................................................................................................................................................................................................................................................ ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
POST _ignition/update-config ..................................................................................................................................................................................................................................................................... ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
GET|HEAD admin ..................................................................................................................................................................................................................................................................................................... filament.admin.pages.dashboard › Filament\Pages\Dashboard
GET|HEAD admin/login ................................................................................................................................................................................................................................................................................................... filament.admin.auth.login › Filament\Pages\Auth\Login
POST admin/logout ........................................................................................................................................................................................................................................................................... filament.admin.auth.logout › Filament\Http\Controllers\Auth\LogoutController
GET|HEAD filament/exports/{export}/download ............................................................................................................................................................................................................................................. filament.exports.download › Filament\Actions\Exports\Http\Controllers\DownloadExport
GET|HEAD filament/imports/{import}/failed-rows/download ........................................................................................................................................................................................................... filament.imports.failed-rows.download › Filament\Actions\Imports\Http\Controllers\DownloadImportFailureCsv
GET|HEAD livewire/livewire.js .................................................................................................................................................................................................................................................................................... Livewire\Mechanisms › FrontendAssets@returnJavaScriptAsFile
GET|HEAD livewire/livewire.min.js.map .............................................................................................................................................................................................................................................................................................. Livewire\Mechanisms › FrontendAssets@maps
GET|HEAD livewire/preview-file/{filename} ........................................................................................................................................................................................................................................................... livewire.preview-file › Livewire\Features › FilePreviewController@handle
POST livewire/update ................................................................................................................................................................................................................................................................................. livewire.update › Livewire\Mechanisms › HandleRequests@handleUpdate
POST livewire/upload-file ......................................................................................................................................................................................................................................................................... livewire.upload-file › Livewire\Features › FileUploadController@handle
GET|HEAD up ..................................................................................................................................................................................................................................................................................................................................................................
`

With multiple domains ->domains(['first.127-0-0-1.sslip.io', 'second.127-0-0-1.sslip.io'])

`% php artisan route:list

GET|HEAD / ...................................................................................................................................................................................................................................................................................................................................................................
POST _ignition/execute-solution ............................................................................................................................................................................................................................................................ ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
GET|HEAD _ignition/health-check ........................................................................................................................................................................................................................................................................ ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
POST _ignition/update-config ..................................................................................................................................................................................................................................................................... ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
GET|HEAD first.127-0-0-1.sslip.io/admin ................................................................................................................................................................................................................................................... filament.admin.first.127-0-0-1.sslip.io.pages.dashboard › Filament\Pages\Dashboard
GET|HEAD second.127-0-0-1.sslip.io/admin ................................................................................................................................................................................................................................................. filament.admin.second.127-0-0-1.sslip.io.pages.dashboard › Filament\Pages\Dashboard
GET|HEAD first.127-0-0-1.sslip.io/admin/login ................................................................................................................................................................................................................................................. filament.admin.first.127-0-0-1.sslip.io.auth.login › Filament\Pages\Auth\Login
GET|HEAD second.127-0-0-1.sslip.io/admin/login ............................................................................................................................................................................................................................................... filament.admin.second.127-0-0-1.sslip.io.auth.login › Filament\Pages\Auth\Login
POST first.127-0-0-1.sslip.io/admin/logout ......................................................................................................................................................................................................................... filament.admin.first.127-0-0-1.sslip.io.auth.logout › Filament\Http\Controllers\Auth\LogoutController
POST second.127-0-0-1.sslip.io/admin/logout ....................................................................................................................................................................................................................... filament.admin.second.127-0-0-1.sslip.io.auth.logout › Filament\Http\Controllers\Auth\LogoutController
GET|HEAD filament/exports/{export}/download ............................................................................................................................................................................................................................................. filament.exports.download › Filament\Actions\Exports\Http\Controllers\DownloadExport
GET|HEAD filament/imports/{import}/failed-rows/download ........................................................................................................................................................................................................... filament.imports.failed-rows.download › Filament\Actions\Imports\Http\Controllers\DownloadImportFailureCsv
GET|HEAD livewire/livewire.js .................................................................................................................................................................................................................................................................................... Livewire\Mechanisms › FrontendAssets@returnJavaScriptAsFile
GET|HEAD livewire/livewire.min.js.map .............................................................................................................................................................................................................................................................................................. Livewire\Mechanisms › FrontendAssets@maps
GET|HEAD livewire/preview-file/{filename} ........................................................................................................................................................................................................................................................... livewire.preview-file › Livewire\Features › FilePreviewController@handle
POST livewire/update ................................................................................................................................................................................................................................................................................. livewire.update › Livewire\Mechanisms › HandleRequests@handleUpdate
POST livewire/upload-file ......................................................................................................................................................................................................................................................................... livewire.upload-file › Livewire\Features › FileUploadController@handle
GET|HEAD up ..................................................................................................................................................................................................................................................................................................................................................................
`

@declum
Copy link
Contributor Author

declum commented Apr 24, 2024

@danharrin Please check the pest tests. if it looks good. My first pest test. Manually i have verified that the app is working for NoDomain, SingleDomain and MultiDomain.

Only missing part in unit tests is how HasRoute handles the route resolution in QueueWorker and ArtisanCommand as triggers. (like calling routes for putting links in emails or notificaitons). For now, if the request doesnt have host, it fall back to first domain (assuming that to be the primary domain, hope app_url might fix)

% ./vendor/bin/pest tests/src/Panels/Routes/SingleAndMultiDomainTest.php

PASS Tests\src\Panels\Routes\SingleAndMultiDomainTest
✓ it admin panel without any domain should resolve to default routes 0.08s
✓ it admin panel with single domain should resolve to default routes 0.01s
✓ it admin panel with multi domain should resolve to their respective routes 0.01s

Tests: 3 passed (6 assertions)
Duration: 0.14s

@declum
Copy link
Contributor Author

declum commented Apr 24, 2024

If i run the tests in isolation all 3 new tests passes. But if i run alll tests with composer test, it fails, all of are with error Route [filament.multi-domain.localhost.auth.logout] not defined.

@declum
Copy link
Contributor Author

declum commented Apr 24, 2024

Fixed the unit tests by modifying HasRoutes to decide based on app()->runningInConsole().

Also, I have set the current Panel to admin for AuthTests (to avoid picking a random Panel, in my case, LoginTest picked multi-domain panel though it is not intended)

@declum declum requested a review from danharrin April 24, 2024 14:17
@danharrin
Copy link
Member

Refactored to only use the first domain while testing, since it could be dangerous to assume the current domain in jobs etc, which now needs to be manually specified

@danharrin danharrin merged commit 5a7df73 into filamentphp:3.x Apr 28, 2024
10 checks passed
@declum
Copy link
Contributor Author

declum commented Apr 29, 2024

Refactored to only use the first domain while testing, since it could be dangerous to assume the current domain in jobs etc, which now needs to be manually specified

@danharrin Instead of statically setting, shall we use primaryDomain as a field in each Panel itself with Closure?

@danharrin
Copy link
Member

If you want to make an additional PR, sure, but I don't mind the existing solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

artisan optimze fails if multiple domain is configured
2 participants