commit
335acb130e
114 changed files with 4856 additions and 2575 deletions
|
|
@ -8,6 +8,9 @@ indent_style = space
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.{js,css}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ SESSION_SECURE_COOKIE=true
|
||||||
|
|
||||||
LOG_SLACK_WEBHOOK_URL=
|
LOG_SLACK_WEBHOOK_URL=
|
||||||
FLARE_KEY=
|
FLARE_KEY=
|
||||||
|
IGNITION_OPEN_AI_KEY=
|
||||||
|
|
||||||
FONT_LINK=
|
FONT_LINK=
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
parserOptions:
|
parserOptions:
|
||||||
sourceType: 'module'
|
sourceType: 'module'
|
||||||
|
ecmaVersion: 'latest'
|
||||||
extends: 'eslint:recommended'
|
extends: 'eslint:recommended'
|
||||||
env:
|
env:
|
||||||
browser: true
|
browser: true
|
||||||
|
|
@ -9,7 +10,7 @@ ignorePatterns:
|
||||||
rules:
|
rules:
|
||||||
indent:
|
indent:
|
||||||
- error
|
- error
|
||||||
- 4
|
- 2
|
||||||
linebreak-style:
|
linebreak-style:
|
||||||
- error
|
- error
|
||||||
- unix
|
- unix
|
||||||
|
|
@ -24,3 +25,14 @@ rules:
|
||||||
- allow:
|
- allow:
|
||||||
- warn
|
- warn
|
||||||
- error
|
- error
|
||||||
|
no-await-in-loop:
|
||||||
|
- error
|
||||||
|
no-promise-executor-return:
|
||||||
|
- error
|
||||||
|
require-atomic-updates:
|
||||||
|
- error
|
||||||
|
max-nested-callbacks:
|
||||||
|
- error
|
||||||
|
- 3
|
||||||
|
prefer-promise-reject-errors:
|
||||||
|
- error
|
||||||
|
|
|
||||||
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
|
|
@ -2,6 +2,8 @@ name: Deploy
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
|
|
|
||||||
2
.github/workflows/phpunit.yml
vendored
2
.github/workflows/phpunit.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
||||||
- name: Setup PHP with pecl extensions
|
- name: Setup PHP with pecl extensions
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: '8.1'
|
php-version: '8.2'
|
||||||
extensions: phpredis,imagick
|
extensions: phpredis,imagick
|
||||||
|
|
||||||
- name: Copy .env
|
- name: Copy .env
|
||||||
|
|
|
||||||
2
.github/workflows/pint.yml
vendored
2
.github/workflows/pint.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
||||||
- name: Setup PHP with pecl extensions
|
- name: Setup PHP with pecl extensions
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: '8.1'
|
php-version: '8.2'
|
||||||
|
|
||||||
- name: Get Composer Cache Directory
|
- name: Get Composer Cache Directory
|
||||||
id: composer-cache
|
id: composer-cache
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
{
|
{
|
||||||
"extends": ["stylelint-config-standard"],
|
"extends": ["stylelint-config-standard"]
|
||||||
"rules": {
|
|
||||||
"indentation": 4,
|
|
||||||
"import-notation": "string"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
*/
|
*/
|
||||||
class MigratePlaceDataFromPostgis extends Command
|
class MigratePlaceDataFromPostgis extends Command
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
||||||
use Illuminate\FileSystem\FileSystem;
|
use Illuminate\FileSystem\FileSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class ParseCachedWebMentions extends Command
|
class ParseCachedWebMentions extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ use App\Jobs\DownloadWebMention;
|
||||||
use App\Models\WebMention;
|
use App\Models\WebMention;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class ReDownloadWebMentions extends Command
|
class ReDownloadWebMentions extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,23 +7,12 @@ use Throwable;
|
||||||
|
|
||||||
class Handler extends ExceptionHandler
|
class Handler extends ExceptionHandler
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The list of the inputs that are never flashed to the session on validation exceptions.
|
|
||||||
*
|
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $dontFlash = [
|
|
||||||
'current_password',
|
|
||||||
'password',
|
|
||||||
'password_confirmation',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the exception handling callbacks for the application.
|
* Register the exception handling callbacks for the application.
|
||||||
*/
|
*/
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
$this->reportable(function (Throwable $e) {
|
$this->reportable(function (Throwable $_e) {
|
||||||
//
|
//
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
class TwitterContentException extends \Exception
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -9,6 +9,9 @@ use App\Models\Article;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class ArticlesController extends Controller
|
class ArticlesController extends Controller
|
||||||
{
|
{
|
||||||
public function index(): View
|
public function index(): View
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class BioController extends Controller
|
class BioController extends Controller
|
||||||
{
|
{
|
||||||
public function show(): View
|
public function show(): View
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ namespace App\Http\Controllers\Admin;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\MicropubClient;
|
use App\Models\MicropubClient;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class ClientsController extends Controller
|
class ClientsController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@ use App\Models\Contact;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use Illuminate\Filesystem\Filesystem;
|
use Illuminate\Filesystem\Filesystem;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class ContactsController extends Controller
|
class ContactsController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ namespace App\Http\Controllers\Admin;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ use App\Models\Like;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class LikesController extends Controller
|
class LikesController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
class NotesController extends Controller
|
class NotesController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
257
app/Http/Controllers/Admin/PasskeysController.php
Normal file
257
app/Http/Controllers/Admin/PasskeysController.php
Normal file
|
|
@ -0,0 +1,257 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Passkey;
|
||||||
|
use App\Models\User;
|
||||||
|
use Cose\Algorithm\Manager;
|
||||||
|
use Cose\Algorithm\Signature\ECDSA\ES256;
|
||||||
|
use Cose\Algorithm\Signature\EdDSA\Ed25519;
|
||||||
|
use Cose\Algorithm\Signature\RSA\RS256;
|
||||||
|
use Cose\Algorithms;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\App;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
use ParagonIE\ConstantTime\Base64UrlSafe;
|
||||||
|
use Throwable;
|
||||||
|
use Webauthn\AttestationStatement\AttestationObjectLoader;
|
||||||
|
use Webauthn\AttestationStatement\AttestationStatementSupportManager;
|
||||||
|
use Webauthn\AttestationStatement\NoneAttestationStatementSupport;
|
||||||
|
use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler;
|
||||||
|
use Webauthn\AuthenticatorAssertionResponse;
|
||||||
|
use Webauthn\AuthenticatorAssertionResponseValidator;
|
||||||
|
use Webauthn\AuthenticatorAttestationResponse;
|
||||||
|
use Webauthn\AuthenticatorAttestationResponseValidator;
|
||||||
|
use Webauthn\AuthenticatorSelectionCriteria;
|
||||||
|
use Webauthn\Exception\WebauthnException;
|
||||||
|
use Webauthn\PublicKeyCredentialCreationOptions;
|
||||||
|
use Webauthn\PublicKeyCredentialLoader;
|
||||||
|
use Webauthn\PublicKeyCredentialParameters;
|
||||||
|
use Webauthn\PublicKeyCredentialRequestOptions;
|
||||||
|
use Webauthn\PublicKeyCredentialRpEntity;
|
||||||
|
use Webauthn\PublicKeyCredentialSource;
|
||||||
|
use Webauthn\PublicKeyCredentialUserEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress UnusedClass
|
||||||
|
*/
|
||||||
|
class PasskeysController extends Controller
|
||||||
|
{
|
||||||
|
public function index(): View
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
$passkeys = $user->passkey;
|
||||||
|
|
||||||
|
return view('admin.passkeys.index', compact('passkeys'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreateOptions(): JsonResponse
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
// RP Entity i.e. the application
|
||||||
|
$rpEntity = PublicKeyCredentialRpEntity::create(
|
||||||
|
config('app.name'),
|
||||||
|
config('url.longurl'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// User Entity
|
||||||
|
$userEntity = PublicKeyCredentialUserEntity::create(
|
||||||
|
$user->name,
|
||||||
|
(string) $user->id,
|
||||||
|
$user->name,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Challenge
|
||||||
|
$challenge = random_bytes(16);
|
||||||
|
|
||||||
|
// List of supported public key parameters
|
||||||
|
$pubKeyCredParams = collect([
|
||||||
|
Algorithms::COSE_ALGORITHM_EDDSA,
|
||||||
|
Algorithms::COSE_ALGORITHM_ES256,
|
||||||
|
Algorithms::COSE_ALGORITHM_RS256,
|
||||||
|
])->map(
|
||||||
|
fn ($algorithm) => PublicKeyCredentialParameters::create('public-key', $algorithm)
|
||||||
|
)->toArray();
|
||||||
|
|
||||||
|
$authenticatorSelectionCriteria = AuthenticatorSelectionCriteria::create(
|
||||||
|
userVerification: AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED,
|
||||||
|
residentKey: AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_REQUIRED,
|
||||||
|
requireResidentKey: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
$options = PublicKeyCredentialCreationOptions::create(
|
||||||
|
$rpEntity,
|
||||||
|
$userEntity,
|
||||||
|
$challenge,
|
||||||
|
$pubKeyCredParams,
|
||||||
|
authenticatorSelection: $authenticatorSelectionCriteria,
|
||||||
|
attestation: PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE
|
||||||
|
);
|
||||||
|
|
||||||
|
$options = json_encode($options, JSON_THROW_ON_ERROR);
|
||||||
|
|
||||||
|
session(['create_options' => $options]);
|
||||||
|
|
||||||
|
return JsonResponse::fromJsonString($options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
$publicKeyCredentialCreationOptionsData = session('create_options');
|
||||||
|
if (empty($publicKeyCredentialCreationOptionsData)) {
|
||||||
|
throw new WebAuthnException('No public key credential request options found');
|
||||||
|
}
|
||||||
|
$publicKeyCredentialCreationOptions = PublicKeyCredentialCreationOptions::createFromString($publicKeyCredentialCreationOptionsData);
|
||||||
|
|
||||||
|
// Unset session data to mitigate replay attacks
|
||||||
|
session()->forget('create_options');
|
||||||
|
|
||||||
|
$attestationSupportManager = AttestationStatementSupportManager::create();
|
||||||
|
$attestationSupportManager->add(NoneAttestationStatementSupport::create());
|
||||||
|
$attestationObjectLoader = AttestationObjectLoader::create($attestationSupportManager);
|
||||||
|
$publicKeyCredentialLoader = PublicKeyCredentialLoader::create($attestationObjectLoader);
|
||||||
|
|
||||||
|
$publicKeyCredential = $publicKeyCredentialLoader->load(json_encode($request->all(), JSON_THROW_ON_ERROR));
|
||||||
|
|
||||||
|
if (! $publicKeyCredential->response instanceof AuthenticatorAttestationResponse) {
|
||||||
|
throw new WebAuthnException('Invalid response type');
|
||||||
|
}
|
||||||
|
|
||||||
|
$attestationStatementSupportManager = AttestationStatementSupportManager::create();
|
||||||
|
$attestationStatementSupportManager->add(NoneAttestationStatementSupport::create());
|
||||||
|
|
||||||
|
$authenticatorAttestationResponseValidator = AuthenticatorAttestationResponseValidator::create(
|
||||||
|
attestationStatementSupportManager: $attestationStatementSupportManager,
|
||||||
|
publicKeyCredentialSourceRepository: null,
|
||||||
|
tokenBindingHandler: null,
|
||||||
|
extensionOutputCheckerHandler: ExtensionOutputCheckerHandler::create(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$securedRelyingPartyId = [];
|
||||||
|
if (App::environment('local', 'development')) {
|
||||||
|
$securedRelyingPartyId = [config('url.longurl')];
|
||||||
|
}
|
||||||
|
|
||||||
|
$publicKeyCredentialSource = $authenticatorAttestationResponseValidator->check(
|
||||||
|
authenticatorAttestationResponse: $publicKeyCredential->response,
|
||||||
|
publicKeyCredentialCreationOptions: $publicKeyCredentialCreationOptions,
|
||||||
|
request: config('url.longurl'),
|
||||||
|
securedRelyingPartyId: $securedRelyingPartyId,
|
||||||
|
);
|
||||||
|
|
||||||
|
$user->passkey()->create([
|
||||||
|
'passkey_id' => Base64UrlSafe::encodeUnpadded($publicKeyCredentialSource->publicKeyCredentialId),
|
||||||
|
'passkey' => json_encode($publicKeyCredentialSource, JSON_THROW_ON_ERROR),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Passkey created successfully',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequestOptions(): JsonResponse
|
||||||
|
{
|
||||||
|
$publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions::create(
|
||||||
|
challenge: random_bytes(16),
|
||||||
|
userVerification: PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_REQUIRED
|
||||||
|
);
|
||||||
|
|
||||||
|
$publicKeyCredentialRequestOptions = json_encode($publicKeyCredentialRequestOptions, JSON_THROW_ON_ERROR);
|
||||||
|
|
||||||
|
session(['request_options' => $publicKeyCredentialRequestOptions]);
|
||||||
|
|
||||||
|
return JsonResponse::fromJsonString($publicKeyCredentialRequestOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function login(Request $request): JsonResponse
|
||||||
|
{
|
||||||
|
$requestOptions = session('request_options');
|
||||||
|
session()->forget('request_options');
|
||||||
|
|
||||||
|
if (empty($requestOptions)) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'No request options found',
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions::createFromString($requestOptions);
|
||||||
|
|
||||||
|
$attestationSupportManager = AttestationStatementSupportManager::create();
|
||||||
|
$attestationSupportManager->add(NoneAttestationStatementSupport::create());
|
||||||
|
$attestationObjectLoader = AttestationObjectLoader::create($attestationSupportManager);
|
||||||
|
$publicKeyCredentialLoader = PublicKeyCredentialLoader::create($attestationObjectLoader);
|
||||||
|
|
||||||
|
$publicKeyCredential = $publicKeyCredentialLoader->load(json_encode($request->all(), JSON_THROW_ON_ERROR));
|
||||||
|
|
||||||
|
if (! $publicKeyCredential->response instanceof AuthenticatorAssertionResponse) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Invalid response type',
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$passkey = Passkey::firstWhere('passkey_id', $publicKeyCredential->id);
|
||||||
|
if (! $passkey) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Passkey not found',
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$credential = PublicKeyCredentialSource::createFromArray(json_decode($passkey->passkey, true, 512, JSON_THROW_ON_ERROR));
|
||||||
|
|
||||||
|
$algorithmManager = Manager::create();
|
||||||
|
$algorithmManager->add(new Ed25519());
|
||||||
|
$algorithmManager->add(new ES256());
|
||||||
|
$algorithmManager->add(new RS256());
|
||||||
|
|
||||||
|
$authenticatorAssertionResponseValidator = new AuthenticatorAssertionResponseValidator(
|
||||||
|
publicKeyCredentialSourceRepository: null,
|
||||||
|
tokenBindingHandler: null,
|
||||||
|
extensionOutputCheckerHandler: ExtensionOutputCheckerHandler::create(),
|
||||||
|
algorithmManager: $algorithmManager,
|
||||||
|
);
|
||||||
|
|
||||||
|
$securedRelyingPartyId = [];
|
||||||
|
if (App::environment('local', 'development')) {
|
||||||
|
$securedRelyingPartyId = [config('url.longurl')];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$authenticatorAssertionResponseValidator->check(
|
||||||
|
credentialId: $credential,
|
||||||
|
authenticatorAssertionResponse: $publicKeyCredential->response,
|
||||||
|
publicKeyCredentialRequestOptions: $publicKeyCredentialRequestOptions,
|
||||||
|
request: config('url.longurl'),
|
||||||
|
userHandle: null,
|
||||||
|
securedRelyingPartyId: $securedRelyingPartyId,
|
||||||
|
);
|
||||||
|
} catch (Throwable) {
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Passkey could not be verified',
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = User::find($passkey->user_id);
|
||||||
|
Auth::login($user);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Passkey verified successfully',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue