Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions app/Filament/Pages/Auth/EditProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use Filament\Schemas\Components\Tabs;
use Filament\Schemas\Components\Tabs\Tab;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\View;
use Filament\Schemas\Schema;
use Filament\Support\Colors\Color;
use Filament\Support\Enums\Width;
Expand Down Expand Up @@ -234,6 +235,16 @@ protected function getDefaultTabs(): array
->map(fn (MultiFactorAuthenticationProvider $multiFactorAuthenticationProvider) => Group::make($multiFactorAuthenticationProvider->getManagementSchemaComponents())
->statePath($multiFactorAuthenticationProvider->getId()))
->all()),
Tab::make('passkeys')
->label(trans('profile.tabs.passkeys'))
->icon(TablerIcon::Fingerprint)
->schema([
Section::make(trans('profile.tabs.passkeys'))
->description(trans('passkeys.description'))
->schema([
View::make('passkeys.livewire.passkeys-tab'),
]),
]),
Tab::make('api_keys')
->label(trans('profile.tabs.api_keys'))
->icon(TablerIcon::Key)
Expand Down
11 changes: 11 additions & 0 deletions app/Filament/Pages/Auth/Login.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Actions;
use Filament\Schemas\Components\Component;
use Filament\Schemas\Components\View;
use Filament\Schemas\Schema;
use Filament\Support\Colors\Color;
use Illuminate\Validation\ValidationException;
Expand All @@ -25,6 +26,16 @@ public function boot(OAuthService $oauthService, CaptchaService $captchaService)
$this->captchaService = $captchaService;
}

public function content(Schema $schema): Schema
Copy link
Member

Choose a reason for hiding this comment

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

Use the form function that's already there. And remove all the extra views.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I was checking this, and I don't seem to find a way to make it how you want, as the view is required for the button to appear.
I would like it if you could give me some kind of direction so I can fix it.

Copy link
Member

Choose a reason for hiding this comment

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

You extract the components that are used in the views and add them to the form instead, e.g. with Action::make or TextInput::make or whatever is needed.

Copy link
Contributor Author

@JoanFo1456 JoanFo1456 Feb 11, 2026

Choose a reason for hiding this comment

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

You extract the components that are used in the views and add them to the form instead, e.g. with Action::make or TextInput::make or whatever is needed.

I was checking this, and I don't seem to know how, as each method will always return me to the same point. JS won't call passkeys or if it does, it won't log in.
MarcelWeldium passkeys worked this way, and it requires the views for the actions to work.

It uses a lot of custom JS on a lot of files to do certain things, view is necessary to ensure everything works, as each file imports another view.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll still try to find a way, but I'm not sure about it...

{
return $schema
->components([
$this->getFormContentComponent(),
$this->getMultiFactorChallengeFormContentComponent(),
View::make('passkeys.login'),
]);
}

public function form(Schema $schema): Schema
{
$components = [
Expand Down
61 changes: 61 additions & 0 deletions app/Livewire/Passkeys.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace App\Livewire;

use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Notifications\Notification;
use Filament\Schemas\Concerns\InteractsWithSchemas;
use Filament\Schemas\Contracts\HasSchemas;
use Illuminate\View\View;
use Spatie\LaravelPasskeys\Livewire\PasskeysComponent;

final class Passkeys extends PasskeysComponent implements HasActions, HasSchemas
{
use InteractsWithActions;
use InteractsWithSchemas;

public function confirmDelete(int $passkeyId): void
{
$this->mountAction('deleteAction', ['passkey' => $passkeyId]);
}

public function deleteAction(): Action
{
return Action::make('deleteAction')
->label(trans('passkeys.delete'))
->color('danger')
->requiresConfirmation()
->action(fn (array $arguments) => $this->deletePasskey((int) $arguments['passkey']));
}

public function deletePasskey(int $passkeyId): void
{
$this->currentUser()->passkeys()->findOrFail($passkeyId);

parent::deletePasskey($passkeyId);

Notification::make()
->title(trans('passkeys.deleted_notification_title'))
->success()
->send();
}

public function storePasskey(string $passkey): void
{
parent::storePasskey($passkey);

Notification::make()
->title(trans('passkeys.created_notification_title'))
->success()
->send();
}

public function render(): View
{
return view('passkeys.livewire.passkeys', data: [
'passkeys' => $this->currentUser()->passkeys()->get(),
]);
}
}
15 changes: 14 additions & 1 deletion app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\In;
use ResourceBundle;
use Spatie\LaravelPasskeys\Models\Concerns\HasPasskeys;
use Spatie\LaravelPasskeys\Models\Concerns\InteractsWithPasskeys;
use Spatie\Permission\Traits\HasRoles;

/**
Expand Down Expand Up @@ -94,7 +96,7 @@
* @method static Builder|User whereUsername($value)
* @method static Builder|User whereUuid($value)
*/
class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract, FilamentUser, HasAppAuthentication, HasAppAuthenticationRecovery, HasAvatar, HasEmailAuthentication, HasName, HasTenants, Validatable
class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract, FilamentUser, HasAppAuthentication, HasAppAuthenticationRecovery, HasAvatar, HasEmailAuthentication, HasName, HasPasskeys, HasTenants, Validatable
{
use Authenticatable;
use Authorizable { can as protected canned; }
Expand All @@ -103,6 +105,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
use HasFactory;
use HasRoles;
use HasValidation { getRules as getValidationRules; }
use InteractsWithPasskeys;
use Notifiable;

public const USER_LEVEL_USER = 0;
Expand Down Expand Up @@ -504,4 +507,14 @@ public function toggleEmailAuthentication(bool $condition): void
{
$this->update(['mfa_email_enabled' => $condition]);
}

public function getPasskeyDisplayName(): string
{
return $this->username ?? $this->email;
}

public function getPasskeyUserId(): int
{
return $this->id;
}
}
2 changes: 2 additions & 0 deletions app/Providers/Filament/FilamentServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Enums\CustomizationKey;
use App\Enums\TablerIcon;
use App\Livewire\Passkeys;
use Filament\Actions\Action;
use Filament\Actions\CreateAction;
use Filament\Actions\DeleteAction;
Expand Down Expand Up @@ -257,6 +258,7 @@ public function boot(): void

SchemaIconAlias::COMPONENTS_WIZARD_COMPLETED_STEP => TablerIcon::Check,
]);
Livewire::component('filament-passkeys', Passkeys::class);
}

public function register(): void {}
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"filament/filament": "^4.5",
"gboquizosanchez/filament-log-viewer": "^2.1",
"guzzlehttp/guzzle": "^7.10",
"laravel/framework": "^12.49",
"laravel/framework": "~12.49.0",
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check the actual composer.json file to confirm the constraint
cat composer.json | head -50

Repository: pelican-dev/panel

Length of output: 1973


🌐 Web query:

spatie laravel-passkeys composer requirements

💡 Result:

spatie/laravel-passkeys Composer requirements (current Packagist release):

  • php: ^8.2 | ^8.3 | ^8.4
  • illuminate/contracts: ^11.0 | ^12.0 (i.e., Laravel 11 or 12 components)
  • spatie/laravel-package-tools: ^1.16
  • web-auth/webauthn-lib: ^5.0 [1]

Docs note (Spatie): the package “requires PHP 8.4+, Laravel 12+.” [2]

Practical requirement: it includes a Livewire component, so you should have Livewire installed. [3]

Sources: [1] (packagist.org) [2] (spatie.be) [3] (github.com)

Citations:


Unnecessarily restrictive Laravel version constraint.

Changing from ^12.49 to ~12.49.0 pins Laravel to patch-level updates only (12.49.x), blocking all future minor releases (12.50, 12.51, …). This prevents the project from receiving new features, bug fixes, and security patches shipped in minor versions.

spatie/laravel-passkeys supports illuminate/contracts: ^11.0 | ^12.0, meaning it's compatible with all Laravel 12.x versions—there is no technical reason to restrict Laravel to 12.49.x. This constraint appears to be a workaround for a dependency resolution issue rather than a legitimate compatibility requirement. Investigate and resolve the root cause instead of locking down the version.

Proposed fix: revert to the original caret constraint
-        "laravel/framework": "~12.49.0",
+        "laravel/framework": "^12.49",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"laravel/framework": "~12.49.0",
"laravel/framework": "^12.49",
🤖 Prompt for AI Agents
In `@composer.json` at line 18, The composer.json entry "laravel/framework":
"~12.49.0" is too restrictive and pins Laravel to patch releases only; change
this constraint back to a caret-based range (e.g. "^12.49") so the project can
receive minor releases within Laravel 12.x, and then run composer update to
confirm dependency resolution; if composer fails, identify and fix the
underlying conflicting package (inspect composer why/why-not and check packages
that require illuminate/* such as spatie/laravel-passkeys) rather than keeping
the tilde pin.

"laravel/helpers": "^1.8",
"laravel/sanctum": "^4.2",
"laravel/socialite": "^5.24",
Expand All @@ -35,6 +35,7 @@
"spatie/laravel-data": "^4.19",
"spatie/laravel-fractal": "^6.3",
"spatie/laravel-health": "^1.34",
"spatie/laravel-passkeys": "^1.5",
"spatie/laravel-permission": "^6.24",
"spatie/laravel-query-builder": "^6.4",
"spatie/temporary-directory": "^2.3",
Expand Down
Loading