1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-06-04 05:24:05 +02:00

refactor: パスキーまわりのライブラリを更新 (#17354)

* refactor: パスキーまわりのライブラリを更新

* fix
This commit is contained in:
かっこかり
2026-05-03 17:16:06 +09:00
committed by GitHub
parent 9d20152e05
commit 723d8add2f
20 changed files with 96 additions and 243 deletions

View File

@@ -161,7 +161,6 @@
"@nestjs/platform-express": "11.1.19",
"@rollup/plugin-esm-shim": "0.1.8",
"@sentry/vue": "10.48.0",
"@simplewebauthn/types": "12.0.0",
"@types/accepts": "1.3.7",
"@types/archiver": "7.0.0",
"@types/body-parser": "1.19.6",

View File

@@ -24,7 +24,7 @@ import type {
PublicKeyCredentialCreationOptionsJSON,
PublicKeyCredentialRequestOptionsJSON,
RegistrationResponseJSON,
} from '@simplewebauthn/types';
} from '@simplewebauthn/server';
@Injectable()
export class WebAuthnService {

View File

@@ -7,7 +7,7 @@ import { Inject, Injectable } from '@nestjs/common';
import cors from '@fastify/cors';
import multipart from '@fastify/multipart';
import { ModuleRef } from '@nestjs/core';
import { AuthenticationResponseJSON } from '@simplewebauthn/types';
import type { AuthenticationResponseJSON } from '@simplewebauthn/server';
import type { Config } from '@/config.js';
import type { InstancesRepository, AccessTokensRepository } from '@/models/_.js';
import { DI } from '@/di-symbols.js';

View File

@@ -28,7 +28,7 @@ import { LoggerService } from '@/core/LoggerService.js';
import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
import { RateLimiterService } from './RateLimiterService.js';
import { SigninService } from './SigninService.js';
import type { AuthenticationResponseJSON } from '@simplewebauthn/types';
import type { AuthenticationResponseJSON } from '@simplewebauthn/server';
import type { FastifyReply, FastifyRequest } from 'fastify';
@Injectable()

View File

@@ -23,7 +23,7 @@ import { LoggerService } from '@/core/LoggerService.js';
import type { IdentifiableError } from '@/misc/identifiable-error.js';
import { RateLimiterService } from './RateLimiterService.js';
import { SigninService } from './SigninService.js';
import type { AuthenticationResponseJSON } from '@simplewebauthn/types';
import type { AuthenticationResponseJSON } from '@simplewebauthn/server';
import type { FastifyReply, FastifyRequest } from 'fastify';
@Injectable()

View File

@@ -39,137 +39,6 @@ export const meta = {
res: {
type: 'object',
nullable: false,
optional: false,
properties: {
rp: {
type: 'object',
properties: {
id: {
type: 'string',
optional: true,
},
},
},
user: {
type: 'object',
properties: {
id: {
type: 'string',
},
name: {
type: 'string',
},
displayName: {
type: 'string',
},
},
},
challenge: {
type: 'string',
},
pubKeyCredParams: {
type: 'array',
items: {
type: 'object',
properties: {
type: {
type: 'string',
},
alg: {
type: 'number',
},
},
},
},
timeout: {
type: 'number',
nullable: true,
},
excludeCredentials: {
type: 'array',
nullable: true,
items: {
type: 'object',
properties: {
id: {
type: 'string',
},
type: {
type: 'string',
},
transports: {
type: 'array',
items: {
type: 'string',
enum: [
'ble',
'cable',
'hybrid',
'internal',
'nfc',
'smart-card',
'usb',
],
},
},
},
},
},
authenticatorSelection: {
type: 'object',
nullable: true,
properties: {
authenticatorAttachment: {
type: 'string',
enum: [
'cross-platform',
'platform',
],
},
requireResidentKey: {
type: 'boolean',
},
userVerification: {
type: 'string',
enum: [
'discouraged',
'preferred',
'required',
],
},
},
},
attestation: {
type: 'string',
nullable: true,
enum: [
'direct',
'enterprise',
'indirect',
'none',
null,
],
},
extensions: {
type: 'object',
nullable: true,
properties: {
appid: {
type: 'string',
nullable: true,
},
credProps: {
type: 'boolean',
nullable: true,
},
hmacCreateSecret: {
type: 'boolean',
nullable: true,
},
},
},
},
},
} as const;

View File

@@ -18,7 +18,7 @@ import type {
PublicKeyCredentialCreationOptionsJSON,
PublicKeyCredentialRequestOptionsJSON,
RegistrationResponseJSON,
} from '@simplewebauthn/types';
} from '@simplewebauthn/server';
import type * as misskey from 'misskey-js';
import { describe, beforeAll, test } from 'vitest';

View File

@@ -8,7 +8,7 @@ import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vites
import { mockDeep } from 'vitest-mock-extended';
import { Test, TestingModule } from '@nestjs/testing';
import { FastifyReply, FastifyRequest } from 'fastify';
import { AuthenticationResponseJSON } from '@simplewebauthn/types';
import type { AuthenticationResponseJSON } from '@simplewebauthn/server';
import { HttpHeader } from 'fastify/types/utils.js';
import { MiUser } from '@/models/User.js';
import { MiUserProfile, UserProfilesRepository, UsersRepository } from '@/models/_.js';

View File

@@ -18,10 +18,10 @@
"dependencies": {
"@analytics/google-analytics": "1.1.0",
"@discordapp/twemoji": "16.0.1",
"@github/webauthn-json": "2.1.1",
"@mcaptcha/core-glue": "0.1.0-alpha-5",
"@misskey-dev/browser-image-resizer": "2024.1.0",
"@sentry/vue": "10.48.0",
"@simplewebauthn/browser": "13.3.0",
"@syuilo/aiscript": "1.2.1",
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
"@twemoji/parser": "16.0.0",

View File

@@ -22,21 +22,21 @@ SPDX-License-Identifier: AGPL-3.0-only
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { get as webAuthnRequest } from '@github/webauthn-json/browser-ponyfill';
import { startAuthentication } from '@simplewebauthn/browser';
import { i18n } from '@/i18n.js';
import MkButton from '@/components/MkButton.vue';
import type { AuthenticationPublicKeyCredential } from '@github/webauthn-json/browser-ponyfill';
import type { PublicKeyCredentialRequestOptionsJSON, AuthenticationResponseJSON } from '@simplewebauthn/browser';
const props = defineProps<{
credentialRequest: CredentialRequestOptions;
credentialRequest: PublicKeyCredentialRequestOptionsJSON;
isPerformingPasswordlessLogin?: boolean;
}>();
const emit = defineEmits<{
(ev: 'done', credential: AuthenticationPublicKeyCredential): void;
(ev: 'done', credential: AuthenticationResponseJSON): void;
(ev: 'useTotp'): void;
}>();
@@ -44,7 +44,7 @@ const queryingKey = ref(true);
async function queryKey() {
queryingKey.value = true;
await webAuthnRequest(props.credentialRequest)
await startAuthentication({ optionsJSON: props.credentialRequest })
.catch(() => {
return Promise.reject(null);
})

View File

@@ -67,8 +67,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<script setup lang="ts">
import { nextTick, onBeforeUnmount, ref, shallowRef, useTemplateRef } from 'vue';
import * as Misskey from 'misskey-js';
import { supported as webAuthnSupported, parseRequestOptionsFromJSON } from '@github/webauthn-json/browser-ponyfill';
import type { AuthenticationPublicKeyCredential } from '@github/webauthn-json/browser-ponyfill';
import { browserSupportsWebAuthn } from '@simplewebauthn/browser';
import type { PublicKeyCredentialRequestOptionsJSON, AuthenticationResponseJSON } from '@simplewebauthn/browser';
import type { OpenOnRemoteOptions } from '@/utility/please-login.js';
import type { PwResponse } from '@/components/MkSignin.password.vue';
import { misskeyApi } from '@/utility/misskey-api.js';
@@ -108,21 +108,18 @@ const userInfo = ref<null | Misskey.entities.UserDetailed>(null);
const password = ref('');
//#region Passkey Passwordless
const credentialRequest = shallowRef<CredentialRequestOptions | null>(null);
const credentialRequest = shallowRef<PublicKeyCredentialRequestOptionsJSON | null>(null);
const passkeyContext = ref('');
const doingPasskeyFromInputPage = ref(false);
function onPasskeyLogin(): void {
if (webAuthnSupported()) {
if (browserSupportsWebAuthn()) {
doingPasskeyFromInputPage.value = true;
waiting.value = true;
misskeyApi('signin-with-passkey', {})
.then((res) => {
passkeyContext.value = res.context ?? '';
credentialRequest.value = parseRequestOptionsFromJSON({
// @ts-expect-error TODO: misskey-js由来の型@simplewebauthn/typesとフロントエンド由来の型@github/webauthn-jsonが合わない
publicKey: res.option,
});
credentialRequest.value = res.option;
page.value = 'passkey';
waiting.value = false;
@@ -131,12 +128,12 @@ function onPasskeyLogin(): void {
}
}
function onPasskeyDone(credential: AuthenticationPublicKeyCredential): void {
function onPasskeyDone(credential: AuthenticationResponseJSON): void {
waiting.value = true;
if (doingPasskeyFromInputPage.value) {
misskeyApi<Misskey.entities.SigninWithPasskeyResponse>('signin-with-passkey', {
credential: credential.toJSON(),
misskeyApi('signin-with-passkey', {
credential: credential,
context: passkeyContext.value,
}).then((res) => {
if (res.signinResponse == null) {
@@ -150,8 +147,7 @@ function onPasskeyDone(credential: AuthenticationPublicKeyCredential): void {
tryLogin({
username: userInfo.value.username,
password: password.value,
// @ts-expect-error TODO: misskey-js由来の型@simplewebauthn/typesとフロントエンド由来の型@github/webauthn-jsonが合わない
credential: credential.toJSON(),
credential: credential,
});
}
}
@@ -253,11 +249,8 @@ async function tryLogin(req: Partial<Misskey.entities.SigninFlowRequest>): Promi
break;
}
case 'passkey': {
if (webAuthnSupported()) {
credentialRequest.value = parseRequestOptionsFromJSON({
// @ts-expect-error TODO: misskey-js由来の型@simplewebauthn/typesとフロントエンド由来の型@github/webauthn-jsonが合わない
publicKey: res.authRequest,
});
if (browserSupportsWebAuthn()) {
credentialRequest.value = res.authRequest;
page.value = 'passkey';
} else {
page.value = 'totp';

View File

@@ -48,11 +48,11 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._2fa.securityKeyInfo }}
</MkInfo>
<MkInfo v-if="!webAuthnSupported()" warn>
<MkInfo v-if="!browserSupportsWebAuthn()" warn>
{{ i18n.ts._2fa.securityKeyNotSupported }}
</MkInfo>
<MkInfo v-else-if="webAuthnSupported() && !$i.twoFactorEnabled" warn>
<MkInfo v-else-if="browserSupportsWebAuthn() && !$i.twoFactorEnabled" warn>
{{ i18n.ts._2fa.registerTOTPBeforeKey }}
</MkInfo>
@@ -83,8 +83,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { defineAsyncComponent, computed } from 'vue';
import { supported as webAuthnSupported, create as webAuthnCreate, parseCreationOptionsFromJSON } from '@github/webauthn-json/browser-ponyfill';
import { computed } from 'vue';
import { browserSupportsWebAuthn, startRegistration } from '@simplewebauthn/browser';
import * as Misskey from 'misskey-js';
import MkButton from '@/components/MkButton.vue';
import MkInfo from '@/components/MkInfo.vue';
@@ -196,12 +196,9 @@ async function addSecurityKey() {
const auth = await os.authenticateDialog();
if (auth.canceled) return;
const registrationOptions = parseCreationOptionsFromJSON({
// @ts-expect-error misskey-js側に型がない
publicKey: await os.apiWithDialog('i/2fa/register-key', {
password: auth.result.password,
token: auth.result.token,
}),
const registrationOptions = await os.apiWithDialog('i/2fa/register-key', {
password: auth.result.password,
token: auth.result.token,
});
const name = await os.inputText({
@@ -214,7 +211,7 @@ async function addSecurityKey() {
if (name.canceled) return;
const credential = await os.promiseDialog(
webAuthnCreate(registrationOptions),
startRegistration({ optionsJSON: registrationOptions }),
null,
() => {}, // ユーザーのキャンセルはrejectなのでエラーダイアログを出さない
i18n.ts._2fa.tapSecurityKey,
@@ -228,8 +225,7 @@ async function addSecurityKey() {
password: auth.result.password,
token: auth.result.token,
name: name.result,
// @ts-expect-error misskey-js側に型がない
credential: credential.toJSON(),
credential: credential,
});
}

View File

@@ -4,11 +4,13 @@
```ts
import type { AuthenticationResponseJSON } from '@simplewebauthn/types';
import type { AuthenticationResponseJSON } from '@simplewebauthn/browser';
import { EventEmitter } from 'eventemitter3';
import { Options } from 'reconnecting-websocket';
import type { PublicKeyCredentialRequestOptionsJSON as PublicKeyCredentialRequestOptionsJSON_2 } from '@simplewebauthn/types';
import type { PublicKeyCredentialCreationOptionsJSON as PublicKeyCredentialCreationOptionsJSON_2 } from '@simplewebauthn/browser';
import type { PublicKeyCredentialRequestOptionsJSON as PublicKeyCredentialRequestOptionsJSON_2 } from '@simplewebauthn/browser';
import _ReconnectingWebSocket from 'reconnecting-websocket';
import type { RegistrationResponseJSON } from '@simplewebauthn/browser';
// Warning: (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts
//
@@ -1471,6 +1473,14 @@ export type Endpoints = Overwrite<Endpoints_2, {
};
};
};
'i/2fa/register-key': {
req: I2faRegisterKeyRequest;
res: I2faRegisterKeyResponse_2;
};
'i/2fa/key-done': {
req: I2faKeyDoneRequest_2;
res: I2faKeyDoneResponse;
};
'admin/roles/create': {
req: Overwrite<AdminRolesCreateRequest, {
policies: PartialRolePolicyOverride;
@@ -1510,6 +1520,8 @@ declare namespace entities {
SigninWithPasskeyRequest,
SigninWithPasskeyInitResponse,
SigninWithPasskeyResponse,
I2faRegisterKeyResponse_2 as I2faRegisterKeyResponse,
I2faKeyDoneRequest_2 as I2faKeyDoneRequest,
PartialRolePolicyOverride,
EmptyRequest,
EmptyResponse,
@@ -1911,13 +1923,11 @@ declare namespace entities {
IResponse,
I2faDoneRequest,
I2faDoneResponse,
I2faKeyDoneRequest,
I2faKeyDoneResponse,
I2faPasswordLessRequest,
I2faRegisterRequest,
I2faRegisterResponse,
I2faRegisterKeyRequest,
I2faRegisterKeyResponse,
I2faRemoveKeyRequest,
I2faUnregisterRequest,
I2faUpdateKeyRequest,
@@ -2515,7 +2525,12 @@ type I2faDoneRequest = operations['i___2fa___done']['requestBody']['content']['a
type I2faDoneResponse = operations['i___2fa___done']['responses']['200']['content']['application/json'];
// @public (undocumented)
type I2faKeyDoneRequest = operations['i___2fa___key-done']['requestBody']['content']['application/json'];
type I2faKeyDoneRequest_2 = {
password: string;
token?: string | null;
name: string;
credential: RegistrationResponseJSON;
};
// @public (undocumented)
type I2faKeyDoneResponse = operations['i___2fa___key-done']['responses']['200']['content']['application/json'];
@@ -2527,7 +2542,7 @@ type I2faPasswordLessRequest = operations['i___2fa___password-less']['requestBod
type I2faRegisterKeyRequest = operations['i___2fa___register-key']['requestBody']['content']['application/json'];
// @public (undocumented)
type I2faRegisterKeyResponse = operations['i___2fa___register-key']['responses']['200']['content']['application/json'];
type I2faRegisterKeyResponse_2 = PublicKeyCredentialCreationOptionsJSON_2;
// @public (undocumented)
type I2faRegisterRequest = operations['i___2fa___register']['requestBody']['content']['application/json'];
@@ -3880,7 +3895,7 @@ type VerifyEmailRequest = operations['verify-email']['requestBody']['content']['
// Warnings were encountered during analysis:
//
// src/entities.ts:55:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
// src/entities.ts:60:2 - (ae-forgotten-export) The symbol "ModerationLogPayloads" needs to be exported by the entry point index.d.ts
// src/streaming.ts:57:3 - (ae-forgotten-export) The symbol "ReconnectingWebSocket" needs to be exported by the entry point index.d.ts
// src/streaming.types.ts:226:4 - (ae-forgotten-export) The symbol "ReversiUpdateKey" needs to be exported by the entry point index.d.ts
// src/streaming.types.ts:241:4 - (ae-forgotten-export) The symbol "ReversiUpdateSettings" needs to be exported by the entry point index.d.ts

View File

@@ -414,7 +414,7 @@ async function main() {
await generateEndpoints(openApiDocs, typeFileName, entitiesFileName, endpointFileName);
const apiClientWarningFileName = `${generatePath}/apiClientJSDoc.ts`;
await generateApiClientJSDoc(openApiDocs, '../api.ts', endpointFileName, apiClientWarningFileName);
await generateApiClientJSDoc(openApiDocs, '../api.ts', '../api.types.ts', apiClientWarningFileName);
}
main();

View File

@@ -54,7 +54,7 @@
"built"
],
"dependencies": {
"@simplewebauthn/types": "12.0.0",
"@simplewebauthn/browser": "13.3.0",
"eventemitter3": "5.0.4",
"reconnecting-websocket": "4.4.0"
}

View File

@@ -5,6 +5,8 @@ import {
AdminRolesCreateResponse,
EmptyRequest,
EmptyResponse,
I2faRegisterKeyRequest,
I2faKeyDoneResponse,
UsersShowRequest,
} from './autogen/entities.js';
import {
@@ -18,6 +20,8 @@ import {
SignupPendingResponse,
SignupRequest,
SignupResponse,
I2faRegisterKeyResponse,
I2faKeyDoneRequest,
} from './entities.js';
type Overwrite<T, U extends { [Key in keyof T]?: unknown }> = Omit<
@@ -109,6 +113,14 @@ export type Endpoints = Overwrite<
},
},
},
'i/2fa/register-key': {
req: I2faRegisterKeyRequest;
res: I2faRegisterKeyResponse;
},
'i/2fa/key-done': {
req: I2faKeyDoneRequest;
res: I2faKeyDoneResponse;
},
'admin/roles/create': {
req: Overwrite<AdminRolesCreateRequest, { policies: PartialRolePolicyOverride }>;
res: AdminRolesCreateResponse;

View File

@@ -1,5 +1,5 @@
import type { SwitchCaseResponseType } from '../api.js';
import type { Endpoints } from './endpoint.js';
import type { Endpoints } from '../api.types.js';
declare module '../api.js' {
export interface APIClient {

View File

@@ -24446,41 +24446,7 @@ export interface operations {
[name: string]: unknown;
};
content: {
'application/json': {
rp: {
id?: string;
};
user: {
id: string;
name: string;
displayName: string;
};
challenge: string;
pubKeyCredParams: {
type: string;
alg: number;
}[];
timeout: number | null;
excludeCredentials: {
id: string;
type: string;
transports: ('ble' | 'cable' | 'hybrid' | 'internal' | 'nfc' | 'smart-card' | 'usb')[];
}[] | null;
authenticatorSelection: {
/** @enum {string} */
authenticatorAttachment: 'cross-platform' | 'platform';
requireResidentKey: boolean;
/** @enum {string} */
userVerification: 'discouraged' | 'preferred' | 'required';
} | null;
/** @enum {string|null} */
attestation: 'direct' | 'enterprise' | 'indirect' | 'none' | null;
extensions: {
appid: string | null;
credProps: boolean | null;
hmacCreateSecret: boolean | null;
} | null;
};
'application/json': Record<string, never>;
};
};
/** @description Client error */

View File

@@ -10,7 +10,12 @@ import {
User,
UserDetailedNotMe,
} from './autogen/models.js';
import type { AuthenticationResponseJSON, PublicKeyCredentialRequestOptionsJSON } from '@simplewebauthn/types';
import type {
AuthenticationResponseJSON,
RegistrationResponseJSON,
PublicKeyCredentialCreationOptionsJSON,
PublicKeyCredentialRequestOptionsJSON,
} from '@simplewebauthn/browser';
export * from './autogen/entities.js';
export * from './autogen/models.js';
@@ -324,6 +329,15 @@ export type SigninWithPasskeyResponse = {
signinResponse: SigninFlowResponse & { finished: true };
};
export type I2faRegisterKeyResponse = PublicKeyCredentialCreationOptionsJSON;
export type I2faKeyDoneRequest = {
password: string;
token?: string | null;
name: string;
credential: RegistrationResponseJSON;
};
type Values<T extends Record<PropertyKey, unknown>> = T[keyof T];
export type PartialRolePolicyOverride = Partial<{ [k in keyof RolePolicies]: Omit<Values<Role['policies']>, 'value'> & { value: RolePolicies[k] } }>;

33
pnpm-lock.yaml generated
View File

@@ -409,9 +409,6 @@ importers:
'@sentry/vue':
specifier: 10.48.0
version: 10.48.0(vue@3.5.32(typescript@5.9.3))
'@simplewebauthn/types':
specifier: 12.0.0
version: 12.0.0
'@types/accepts':
specifier: 1.3.7
version: 1.3.7
@@ -614,9 +611,6 @@ importers:
'@discordapp/twemoji':
specifier: 16.0.1
version: 16.0.1
'@github/webauthn-json':
specifier: 2.1.1
version: 2.1.1
'@mcaptcha/core-glue':
specifier: 0.1.0-alpha-5
version: 0.1.0-alpha-5
@@ -626,6 +620,9 @@ importers:
'@sentry/vue':
specifier: 10.48.0
version: 10.48.0(vue@3.5.32(typescript@5.9.3))
'@simplewebauthn/browser':
specifier: 13.3.0
version: 13.3.0
'@syuilo/aiscript':
specifier: 1.2.1
version: 1.2.1
@@ -1302,9 +1299,9 @@ importers:
packages/misskey-js:
dependencies:
'@simplewebauthn/types':
specifier: 12.0.0
version: 12.0.0
'@simplewebauthn/browser':
specifier: 13.3.0
version: 13.3.0
eventemitter3:
specifier: 5.0.4
version: 5.0.4
@@ -2243,11 +2240,6 @@ packages:
'@file-type/xml@0.4.4':
resolution: {integrity: sha512-NhCyXoHlVZ8TqM476hyzwGJ24+D5IPSaZhmrPj7qXnEVb3q6jrFzA3mM9TBpknKSI9EuQeGTKRg2DXGUwvBBoQ==}
'@github/webauthn-json@2.1.1':
resolution: {integrity: sha512-XrftRn4z75SnaJOmZQbt7Mk+IIjqVHw+glDGOxuHwXkZBZh/MBoRS7MHjSZMDaLhT4RjN2VqiEU7EOYleuJWSQ==}
deprecated: 'Deprecated: Modern browsers support built-in WebAuthn JSON methods. Please use native browser methods instead. For more information, visit https://github.com/github/webauthn-json'
hasBin: true
'@hapi/address@5.1.1':
resolution: {integrity: sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==}
engines: {node: '>=14.0.0'}
@@ -3596,14 +3588,13 @@ packages:
'@sideway/pinpoint@2.0.0':
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
'@simplewebauthn/browser@13.3.0':
resolution: {integrity: sha512-BE/UWv6FOToAdVk0EokzkqQQDOWtNydYlY6+OrmiZ5SCNmb41VehttboTetUM3T/fr6EAFYVXjz4My2wg230rQ==}
'@simplewebauthn/server@13.3.0':
resolution: {integrity: sha512-MLHYFrYG8/wK2i+86XMhiecK72nMaHKKt4bo+7Q1TbuG9iGjlSdfkPWKO5ZFE/BX+ygCJ7pr8H/AJeyAj1EaTQ==}
engines: {node: '>=20.0.0'}
'@simplewebauthn/types@12.0.0':
resolution: {integrity: sha512-q6y8MkoV8V8jB4zzp18Uyj2I7oFp2/ONL8c3j8uT06AOWu3cIChc1au71QYHrP2b+xDapkGTiv+9lX7xkTlAsA==}
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
'@sinclair/typebox@0.27.8':
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
@@ -11644,8 +11635,6 @@ snapshots:
sax: 1.5.0
strtok3: 10.3.5
'@github/webauthn-json@2.1.1': {}
'@hapi/address@5.1.1':
dependencies:
'@hapi/hoek': 11.0.7
@@ -12968,6 +12957,8 @@ snapshots:
'@sideway/pinpoint@2.0.0': {}
'@simplewebauthn/browser@13.3.0': {}
'@simplewebauthn/server@13.3.0':
dependencies:
'@hexagon/base64': 1.1.28
@@ -12979,8 +12970,6 @@ snapshots:
'@peculiar/asn1-x509': 2.6.1
'@peculiar/x509': 1.14.3
'@simplewebauthn/types@12.0.0': {}
'@sinclair/typebox@0.27.8': {}
'@sindresorhus/is@7.1.1': {}