Skip to content

Commit 15f4d9b

Browse files
committed
wip passkeys
1 parent 4b98580 commit 15f4d9b

9 files changed

Lines changed: 49 additions & 25 deletions

File tree

demo/app/Providers/DemoSharpServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected function configureSharp(SharpConfigBuilder $config): void
2828
->setAuthCustomGuard('web')
2929
->enable2faCustom(Demo2faNotificationHandler::class)
3030
->enableLoginRateLimiting(maxAttempts: 3)
31-
->enablePasskeys()
31+
->when(config('demo.enable_passkeys'))->enablePasskeys()
3232
->setLoginAttributes('email', 'password')
3333
->setUserDisplayAttribute('name')
3434
->setUserAvatarAttribute(fn () => auth()->user()->avatar?->thumbnail(200))

demo/app/Sharp/Profile/ProfileSingleShow.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use App\Sharp\Profile\Commands\Activate2faCommand;
66
use App\Sharp\Profile\Commands\ChangePasswordCommand;
77
use App\Sharp\Profile\Commands\Deactivate2faCommand;
8-
use Code16\Sharp\Auth\Passkeys\PasskeyEntity;
8+
use Code16\Sharp\Auth\Passkeys\Entity\PasskeyEntity;
99
use Code16\Sharp\Show\Fields\SharpShowEntityListField;
1010
use Code16\Sharp\Show\Fields\SharpShowPictureField;
1111
use Code16\Sharp\Show\Fields\SharpShowTextField;
@@ -28,9 +28,9 @@ protected function buildShowFields(FieldsContainer $showFields): void
2828
->addField(
2929
SharpShowPictureField::make('avatar'),
3030
)
31-
->addField(
31+
->when(config('demo.enable_passkeys'), fn () => $showFields->addField(
3232
SharpShowEntityListField::make(PasskeyEntity::class)
33-
);
33+
));
3434
}
3535

3636
protected function buildShowLayout(ShowLayout $showLayout): void
@@ -41,7 +41,7 @@ protected function buildShowLayout(ShowLayout $showLayout): void
4141
->addColumn(6, fn (ShowLayoutColumn $column) => $column->withField('email'))
4242
->addColumn(6, fn (ShowLayoutColumn $column) => $column->withField('avatar'));
4343
})
44-
->addEntityListSection(PasskeyEntity::class);
44+
->when(config('demo.enable_passkeys'))->addEntityListSection(PasskeyEntity::class);
4545
}
4646

4747
public function buildShowConfig(): void

demo/config/demo.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
return [
4+
'enable_passkeys' => env('DEMO_ENABLE_PASSKEYS', false),
5+
];

resources/js/entity-list/components/EntityList.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@
777777
<div class="size-2.5 bg-primary rounded-full"></div>
778778
</template>
779779
<template v-else>
780-
<Badge class="px-1.5 justify-center min-w-5.5">
780+
<Badge class="px-1.5 justify-center min-w-5.5 whitespace-nowrap">
781781
{{ item[field.key] }}
782782
</Badge>
783783
</template>

src/Auth/Passkeys/PasskeyEntity.php renamed to src/Auth/Passkeys/Entity/PasskeyEntity.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Code16\Sharp\Auth\Passkeys;
3+
namespace Code16\Sharp\Auth\Passkeys\Entity;
44

55
use Code16\Sharp\Utils\Entities\SharpEntity;
66

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
<?php
22

3-
namespace Code16\Sharp\Auth\Passkeys;
3+
namespace Code16\Sharp\Auth\Passkeys\Entity;
44

55
use Code16\Sharp\Auth\Passkeys\Commands\UpdatePasskeyNameCommand;
66
use Code16\Sharp\EntityList\Commands\EntityCommand;
7+
use Code16\Sharp\EntityList\Fields\EntityListBadgeField;
78
use Code16\Sharp\EntityList\Fields\EntityListField;
89
use Code16\Sharp\EntityList\Fields\EntityListFieldsContainer;
9-
use Code16\Sharp\EntityList\Filters\HiddenFilter;
1010
use Code16\Sharp\EntityList\SharpEntityList;
1111
use Illuminate\Contracts\Auth\Authenticatable;
1212
use Illuminate\Contracts\Support\Arrayable;
13+
use Illuminate\Database\Eloquent\Model;
1314
use Spatie\LaravelPasskeys\Models\Concerns\HasPasskeys;
1415

1516
class PasskeyList extends SharpEntityList
@@ -21,6 +22,10 @@ public function buildList(EntityListFieldsContainer $fields): void
2122
EntityListField::make('name')
2223
->setLabel('Name')
2324
)
25+
->addField(
26+
EntityListBadgeField::make('usage')
27+
->setLabel('Usage')
28+
)
2429
->addField(
2530
EntityListField::make('created_at')
2631
->setLabel('Creation date')
@@ -63,32 +68,26 @@ public function getInstanceCommands(): ?array
6368
];
6469
}
6570

66-
protected function getFilters(): ?array
67-
{
68-
return [
69-
HiddenFilter::make('user_id'),
70-
];
71-
}
72-
7371
public function delete(mixed $id): void
7472
{
7573
$this->currentUser()->passKeys()->findOrFail($id)->delete();
7674
}
7775

7876
public function getListData(): array|Arrayable
7977
{
80-
return $this->transform(
81-
$this->currentUser()->passkeys
82-
);
78+
return $this
79+
->setCustomTransformer('usage', function ($value, Model $passkey) {
80+
return $passkey->getKey() == request()->cookie('sharp_last_used_passkey')
81+
? 'Used in this browser'
82+
: null;
83+
})
84+
->transform(
85+
$this->currentUser()->passkeys
86+
);
8387
}
8488

8589
protected function currentUser(): Authenticatable&HasPasskeys
8690
{
87-
// disabling for now (security concerns)
88-
// if($this->queryParams->filterFor('user_id')) {
89-
// return Config::getAuthenticatableModel()::findOrFail($this->queryParams->filterFor('user_id'));
90-
// }
91-
9291
/** @var Authenticatable&HasPasskeys $user */
9392
$user = auth()->user();
9493

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Code16\Sharp\Auth\Passkeys;
4+
5+
use Illuminate\Events\Dispatcher;
6+
use Illuminate\Support\Facades\Cookie;
7+
use Spatie\LaravelPasskeys\Events\PasskeyUsedToAuthenticateEvent;
8+
9+
class PasskeyEventSubscriber
10+
{
11+
public function subscribe(Dispatcher $events): void
12+
{
13+
$events->listen(PasskeyUsedToAuthenticateEvent::class, function (PasskeyUsedToAuthenticateEvent $event) {
14+
Cookie::queue('sharp_last_used_passkey', $event->passkey->id, 576000);
15+
});
16+
}
17+
}

src/Config/SharpConfigBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Closure;
66
use Code16\Sharp\Auth\Impersonate\SharpDefaultEloquentImpersonationHandler;
77
use Code16\Sharp\Auth\Impersonate\SharpImpersonationHandler;
8-
use Code16\Sharp\Auth\Passkeys\PasskeyEntity;
8+
use Code16\Sharp\Auth\Passkeys\Entity\PasskeyEntity;
99
use Code16\Sharp\Auth\TwoFactor\Sharp2faHandler;
1010
use Code16\Sharp\Exceptions\SharpInvalidConfigException;
1111
use Code16\Sharp\Exceptions\SharpInvalidEntityKeyException;

src/SharpInternalServiceProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Code16\Sharp;
44

55
use Code16\Sharp\Auth\Impersonate\SharpImpersonationHandler;
6+
use Code16\Sharp\Auth\Passkeys\PasskeyEventSubscriber;
67
use Code16\Sharp\Auth\SharpAuthorizationManager;
78
use Code16\Sharp\Auth\TwoFactor\Engines\GoogleTotpEngine;
89
use Code16\Sharp\Auth\TwoFactor\Engines\Sharp2faTotpEngine;
@@ -96,6 +97,8 @@ public function boot()
9697
}
9798

9899
$this->configureOctane();
100+
101+
Event::subscribe(PasskeyEventSubscriber::class);
99102
}
100103

101104
public function register()

0 commit comments

Comments
 (0)