@better-auth/passkey 1.7.0-rc.1 → 1.7.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.mts
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import { a as Passkey, c as PasskeyOptions, d as WebAuthnChallengeValue, l as PasskeyRegistrationOptions, n as PASSKEY_ERROR_CODES, o as PasskeyAuthenticationOptions, s as PasskeyExtensionsResolver, t as passkey, u as PasskeyRegistrationUser } from "./index-
|
|
1
|
+
import { a as Passkey, c as PasskeyOptions, d as WebAuthnChallengeValue, l as PasskeyRegistrationOptions, n as PASSKEY_ERROR_CODES, o as PasskeyAuthenticationOptions, s as PasskeyExtensionsResolver, t as passkey, u as PasskeyRegistrationUser } from "./index-CatEiPwC.mjs";
|
|
2
2
|
import { AuthenticationExtensionsClientInputs, AuthenticationExtensionsClientOutputs, AuthenticationResponseJSON, RegistrationResponseJSON } from "@simplewebauthn/server";
|
|
3
|
-
import * as better_auth_client0 from "better-auth/client";
|
|
4
|
-
import * as nanostores from "nanostores";
|
|
5
3
|
import { atom } from "nanostores";
|
|
6
|
-
import * as better_auth0 from "better-auth";
|
|
7
4
|
import { ClientFetchOption, ClientStore } from "@better-auth/core";
|
|
8
5
|
import { BetterFetch } from "@better-fetch/fetch";
|
|
9
6
|
import { Session, User } from "better-auth/types";
|
|
10
|
-
export * from "@simplewebauthn/server";
|
|
11
|
-
|
|
7
|
+
export type * from "@simplewebauthn/server";
|
|
12
8
|
//#region src/client.d.ts
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
9
|
+
type AddPasskeyResponse = Passkey & {
|
|
10
|
+
session?: Session;
|
|
11
|
+
user?: User;
|
|
12
|
+
};
|
|
13
|
+
declare const getPasskeyActions: ($fetch: BetterFetch, { $listPasskeys, $store }: {
|
|
17
14
|
$listPasskeys: ReturnType<typeof atom<any>>;
|
|
18
15
|
$store: ClientStore;
|
|
19
16
|
}) => {
|
|
@@ -90,6 +87,10 @@ declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
|
90
87
|
* Optional context for passkey-first registration flows.
|
|
91
88
|
*/
|
|
92
89
|
context?: string | null;
|
|
90
|
+
/**
|
|
91
|
+
* Create a session after successfully registering the passkey.
|
|
92
|
+
*/
|
|
93
|
+
createSession?: boolean;
|
|
93
94
|
/**
|
|
94
95
|
* Optional WebAuthn extensions to include during registration.
|
|
95
96
|
*/
|
|
@@ -112,14 +113,14 @@ declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
|
112
113
|
statusText: string;
|
|
113
114
|
};
|
|
114
115
|
} | {
|
|
115
|
-
data:
|
|
116
|
+
data: AddPasskeyResponse;
|
|
116
117
|
error: null;
|
|
117
118
|
} | {
|
|
118
119
|
webauthn: {
|
|
119
120
|
response: RegistrationResponseJSON;
|
|
120
121
|
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
121
122
|
};
|
|
122
|
-
data:
|
|
123
|
+
data: AddPasskeyResponse;
|
|
123
124
|
error: null;
|
|
124
125
|
} | {
|
|
125
126
|
data: null;
|
|
@@ -216,6 +217,10 @@ declare const passkeyClient: () => {
|
|
|
216
217
|
* Optional context for passkey-first registration flows.
|
|
217
218
|
*/
|
|
218
219
|
context?: string | null;
|
|
220
|
+
/**
|
|
221
|
+
* Create a session after successfully registering the passkey.
|
|
222
|
+
*/
|
|
223
|
+
createSession?: boolean;
|
|
219
224
|
/**
|
|
220
225
|
* Optional WebAuthn extensions to include during registration.
|
|
221
226
|
*/
|
|
@@ -238,14 +243,14 @@ declare const passkeyClient: () => {
|
|
|
238
243
|
statusText: string;
|
|
239
244
|
};
|
|
240
245
|
} | {
|
|
241
|
-
data:
|
|
246
|
+
data: AddPasskeyResponse;
|
|
242
247
|
error: null;
|
|
243
248
|
} | {
|
|
244
249
|
webauthn: {
|
|
245
250
|
response: RegistrationResponseJSON;
|
|
246
251
|
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
247
252
|
};
|
|
248
|
-
data:
|
|
253
|
+
data: AddPasskeyResponse;
|
|
249
254
|
error: null;
|
|
250
255
|
} | {
|
|
251
256
|
data: null;
|
|
@@ -265,8 +270,8 @@ declare const passkeyClient: () => {
|
|
|
265
270
|
};
|
|
266
271
|
};
|
|
267
272
|
getAtoms($fetch: BetterFetch): {
|
|
268
|
-
listPasskeys:
|
|
269
|
-
$listPasskeys: nanostores.PreinitializedWritableAtom<any> & object;
|
|
273
|
+
listPasskeys: import("better-auth/client").AuthQueryAtom<Passkey[]>;
|
|
274
|
+
$listPasskeys: import("nanostores").PreinitializedWritableAtom<any> & object;
|
|
270
275
|
};
|
|
271
276
|
pathMethods: {
|
|
272
277
|
"/passkey/register": "POST";
|
|
@@ -280,21 +285,22 @@ declare const passkeyClient: () => {
|
|
|
280
285
|
signal: "$sessionSignal";
|
|
281
286
|
})[];
|
|
282
287
|
$ERROR_CODES: {
|
|
283
|
-
CHALLENGE_NOT_FOUND:
|
|
284
|
-
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY:
|
|
285
|
-
FAILED_TO_VERIFY_REGISTRATION:
|
|
286
|
-
PASSKEY_NOT_FOUND:
|
|
287
|
-
AUTHENTICATION_FAILED:
|
|
288
|
-
UNABLE_TO_CREATE_SESSION:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
288
|
+
CHALLENGE_NOT_FOUND: import("better-auth").RawError<"CHALLENGE_NOT_FOUND">;
|
|
289
|
+
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: import("better-auth").RawError<"YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY">;
|
|
290
|
+
FAILED_TO_VERIFY_REGISTRATION: import("better-auth").RawError<"FAILED_TO_VERIFY_REGISTRATION">;
|
|
291
|
+
PASSKEY_NOT_FOUND: import("better-auth").RawError<"PASSKEY_NOT_FOUND">;
|
|
292
|
+
AUTHENTICATION_FAILED: import("better-auth").RawError<"AUTHENTICATION_FAILED">;
|
|
293
|
+
UNABLE_TO_CREATE_SESSION: import("better-auth").RawError<"UNABLE_TO_CREATE_SESSION">;
|
|
294
|
+
USER_NOT_FOUND: import("better-auth").RawError<"USER_NOT_FOUND">;
|
|
295
|
+
FAILED_TO_UPDATE_PASSKEY: import("better-auth").RawError<"FAILED_TO_UPDATE_PASSKEY">;
|
|
296
|
+
PREVIOUSLY_REGISTERED: import("better-auth").RawError<"PREVIOUSLY_REGISTERED">;
|
|
297
|
+
REGISTRATION_CANCELLED: import("better-auth").RawError<"REGISTRATION_CANCELLED">;
|
|
298
|
+
AUTH_CANCELLED: import("better-auth").RawError<"AUTH_CANCELLED">;
|
|
299
|
+
UNKNOWN_ERROR: import("better-auth").RawError<"UNKNOWN_ERROR">;
|
|
300
|
+
SESSION_REQUIRED: import("better-auth").RawError<"SESSION_REQUIRED">;
|
|
301
|
+
RESOLVE_USER_REQUIRED: import("better-auth").RawError<"RESOLVE_USER_REQUIRED">;
|
|
302
|
+
RESOLVED_USER_INVALID: import("better-auth").RawError<"RESOLVED_USER_INVALID">;
|
|
297
303
|
};
|
|
298
304
|
};
|
|
299
305
|
//#endregion
|
|
300
|
-
export { PASSKEY_ERROR_CODES, Passkey, PasskeyAuthenticationOptions, PasskeyExtensionsResolver, PasskeyOptions, PasskeyRegistrationOptions, PasskeyRegistrationUser, WebAuthnChallengeValue, getPasskeyActions, passkeyClient };
|
|
306
|
+
export { PASSKEY_ERROR_CODES, type Passkey, type PasskeyAuthenticationOptions, type PasskeyExtensionsResolver, type PasskeyOptions, type PasskeyRegistrationOptions, type PasskeyRegistrationUser, type WebAuthnChallengeValue, getPasskeyActions, passkeyClient };
|
package/dist/client.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as PASSKEY_ERROR_CODES, t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { n as PASSKEY_ERROR_CODES, t as PACKAGE_VERSION } from "./version-02cV8Fcg.mjs";
|
|
2
2
|
import { WebAuthnError, startAuthentication, startRegistration } from "@simplewebauthn/browser";
|
|
3
3
|
import { useAuthQuery } from "better-auth/client";
|
|
4
4
|
import { atom } from "nanostores";
|
|
@@ -95,13 +95,15 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
95
95
|
...fetchOpts,
|
|
96
96
|
body: {
|
|
97
97
|
response: responseBody,
|
|
98
|
-
name: opts?.name
|
|
98
|
+
name: opts?.name,
|
|
99
|
+
...opts?.createSession && { createSession: true }
|
|
99
100
|
},
|
|
100
101
|
method: "POST",
|
|
101
102
|
throw: false
|
|
102
103
|
});
|
|
103
104
|
if (!verified.data) return verified;
|
|
104
105
|
$listPasskeys.set(Math.random());
|
|
106
|
+
if (verified.data.session) $store.notify("$sessionSignal");
|
|
105
107
|
if (opts?.returnWebAuthnResponse) return {
|
|
106
108
|
...verified,
|
|
107
109
|
webauthn: {
|
|
@@ -152,8 +154,19 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
152
154
|
}
|
|
153
155
|
};
|
|
154
156
|
return {
|
|
155
|
-
signIn: {
|
|
156
|
-
|
|
157
|
+
signIn: {
|
|
158
|
+
/**
|
|
159
|
+
* Sign in with a registered passkey
|
|
160
|
+
*/
|
|
161
|
+
passkey: signInPasskey },
|
|
162
|
+
passkey: {
|
|
163
|
+
/**
|
|
164
|
+
* Add a passkey to the user account
|
|
165
|
+
*/
|
|
166
|
+
addPasskey: registerPasskey },
|
|
167
|
+
/**
|
|
168
|
+
* Inferred Internal Types
|
|
169
|
+
*/
|
|
157
170
|
$Infer: {}
|
|
158
171
|
};
|
|
159
172
|
};
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import * as _simplewebauthn_server0 from "@simplewebauthn/server";
|
|
2
1
|
import { AuthenticationExtensionsClientInputs, AuthenticationResponseJSON, CredentialDeviceType, RegistrationResponseJSON, VerifiedAuthenticationResponse, VerifiedRegistrationResponse } from "@simplewebauthn/server";
|
|
3
|
-
import * as zod from "zod";
|
|
4
|
-
import * as better_auth0 from "better-auth";
|
|
5
2
|
import { GenericEndpointContext } from "@better-auth/core";
|
|
6
3
|
import { InferOptionSchema } from "better-auth/types";
|
|
7
|
-
import * as better_call0 from "better-call";
|
|
8
|
-
import * as zod_v4_core0 from "zod/v4/core";
|
|
9
|
-
|
|
10
4
|
//#region src/schema.d.ts
|
|
11
5
|
declare const schema: {
|
|
12
6
|
passkey: {
|
|
@@ -229,20 +223,21 @@ declare const getAuthenticatorName: (aaguid: string | null | undefined) => strin
|
|
|
229
223
|
//#endregion
|
|
230
224
|
//#region src/error-codes.d.ts
|
|
231
225
|
declare const PASSKEY_ERROR_CODES: {
|
|
232
|
-
CHALLENGE_NOT_FOUND:
|
|
233
|
-
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY:
|
|
234
|
-
FAILED_TO_VERIFY_REGISTRATION:
|
|
235
|
-
PASSKEY_NOT_FOUND:
|
|
236
|
-
AUTHENTICATION_FAILED:
|
|
237
|
-
UNABLE_TO_CREATE_SESSION:
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
226
|
+
CHALLENGE_NOT_FOUND: import("better-auth").RawError<"CHALLENGE_NOT_FOUND">;
|
|
227
|
+
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: import("better-auth").RawError<"YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY">;
|
|
228
|
+
FAILED_TO_VERIFY_REGISTRATION: import("better-auth").RawError<"FAILED_TO_VERIFY_REGISTRATION">;
|
|
229
|
+
PASSKEY_NOT_FOUND: import("better-auth").RawError<"PASSKEY_NOT_FOUND">;
|
|
230
|
+
AUTHENTICATION_FAILED: import("better-auth").RawError<"AUTHENTICATION_FAILED">;
|
|
231
|
+
UNABLE_TO_CREATE_SESSION: import("better-auth").RawError<"UNABLE_TO_CREATE_SESSION">;
|
|
232
|
+
USER_NOT_FOUND: import("better-auth").RawError<"USER_NOT_FOUND">;
|
|
233
|
+
FAILED_TO_UPDATE_PASSKEY: import("better-auth").RawError<"FAILED_TO_UPDATE_PASSKEY">;
|
|
234
|
+
PREVIOUSLY_REGISTERED: import("better-auth").RawError<"PREVIOUSLY_REGISTERED">;
|
|
235
|
+
REGISTRATION_CANCELLED: import("better-auth").RawError<"REGISTRATION_CANCELLED">;
|
|
236
|
+
AUTH_CANCELLED: import("better-auth").RawError<"AUTH_CANCELLED">;
|
|
237
|
+
UNKNOWN_ERROR: import("better-auth").RawError<"UNKNOWN_ERROR">;
|
|
238
|
+
SESSION_REQUIRED: import("better-auth").RawError<"SESSION_REQUIRED">;
|
|
239
|
+
RESOLVE_USER_REQUIRED: import("better-auth").RawError<"RESOLVE_USER_REQUIRED">;
|
|
240
|
+
RESOLVED_USER_INVALID: import("better-auth").RawError<"RESOLVED_USER_INVALID">;
|
|
246
241
|
};
|
|
247
242
|
//#endregion
|
|
248
243
|
//#region src/index.d.ts
|
|
@@ -257,9 +252,9 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
257
252
|
id: "passkey";
|
|
258
253
|
version: string;
|
|
259
254
|
endpoints: {
|
|
260
|
-
generatePasskeyRegistrationOptions:
|
|
255
|
+
generatePasskeyRegistrationOptions: import("better-call").StrictEndpoint<"/passkey/generate-register-options", {
|
|
261
256
|
method: "GET";
|
|
262
|
-
use: ((inputContext:
|
|
257
|
+
use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
263
258
|
session: {
|
|
264
259
|
session: Record<string, any> & {
|
|
265
260
|
id: string;
|
|
@@ -282,19 +277,19 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
282
277
|
};
|
|
283
278
|
};
|
|
284
279
|
}>)[];
|
|
285
|
-
query: zod.ZodOptional<zod.ZodObject<{
|
|
286
|
-
authenticatorAttachment: zod.ZodOptional<zod.ZodEnum<{
|
|
280
|
+
query: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
281
|
+
authenticatorAttachment: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
287
282
|
platform: "platform";
|
|
288
283
|
"cross-platform": "cross-platform";
|
|
289
284
|
}>>;
|
|
290
|
-
name: zod.ZodOptional<zod.ZodString>;
|
|
291
|
-
context: zod.ZodOptional<zod.ZodString>;
|
|
292
|
-
},
|
|
285
|
+
name: import("zod").ZodOptional<import("zod").ZodString>;
|
|
286
|
+
context: import("zod").ZodOptional<import("zod").ZodString>;
|
|
287
|
+
}, import("zod/v4/core").$strip>>;
|
|
293
288
|
metadata: {
|
|
294
289
|
openapi: {
|
|
295
290
|
operationId: string;
|
|
296
291
|
description: string;
|
|
297
|
-
parameters:
|
|
292
|
+
parameters: import("better-call").OpenAPIParameter[];
|
|
298
293
|
responses: {
|
|
299
294
|
200: {
|
|
300
295
|
description: string;
|
|
@@ -396,8 +391,8 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
396
391
|
};
|
|
397
392
|
};
|
|
398
393
|
};
|
|
399
|
-
},
|
|
400
|
-
generatePasskeyAuthenticationOptions:
|
|
394
|
+
}, import("@simplewebauthn/server").PublicKeyCredentialCreationOptionsJSON>;
|
|
395
|
+
generatePasskeyAuthenticationOptions: import("better-call").StrictEndpoint<"/passkey/generate-authenticate-options", {
|
|
401
396
|
method: "GET";
|
|
402
397
|
metadata: {
|
|
403
398
|
openapi: {
|
|
@@ -490,14 +485,15 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
490
485
|
};
|
|
491
486
|
};
|
|
492
487
|
};
|
|
493
|
-
},
|
|
494
|
-
verifyPasskeyRegistration:
|
|
488
|
+
}, import("@simplewebauthn/server").PublicKeyCredentialRequestOptionsJSON>;
|
|
489
|
+
verifyPasskeyRegistration: import("better-call").StrictEndpoint<"/passkey/verify-registration", {
|
|
495
490
|
method: "POST";
|
|
496
|
-
body: zod.ZodObject<{
|
|
497
|
-
response: zod.ZodAny;
|
|
498
|
-
name: zod.ZodOptional<zod.ZodString>;
|
|
499
|
-
|
|
500
|
-
|
|
491
|
+
body: import("zod").ZodObject<{
|
|
492
|
+
response: import("zod").ZodAny;
|
|
493
|
+
name: import("zod").ZodOptional<import("zod").ZodString>;
|
|
494
|
+
createSession: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
495
|
+
}, import("zod/v4/core").$strip>;
|
|
496
|
+
use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
501
497
|
session: {
|
|
502
498
|
session: Record<string, any> & {
|
|
503
499
|
id: string;
|
|
@@ -530,7 +526,20 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
530
526
|
content: {
|
|
531
527
|
"application/json": {
|
|
532
528
|
schema: {
|
|
533
|
-
|
|
529
|
+
readonly type: "object";
|
|
530
|
+
readonly allOf: readonly [{
|
|
531
|
+
readonly $ref: "#/components/schemas/Passkey";
|
|
532
|
+
}, {
|
|
533
|
+
readonly type: "object";
|
|
534
|
+
readonly properties: {
|
|
535
|
+
readonly session: {
|
|
536
|
+
readonly $ref: "#/components/schemas/Session";
|
|
537
|
+
};
|
|
538
|
+
readonly user: {
|
|
539
|
+
readonly $ref: "#/components/schemas/User";
|
|
540
|
+
};
|
|
541
|
+
};
|
|
542
|
+
}];
|
|
534
543
|
};
|
|
535
544
|
};
|
|
536
545
|
};
|
|
@@ -542,11 +551,11 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
542
551
|
};
|
|
543
552
|
};
|
|
544
553
|
}, Passkey>;
|
|
545
|
-
verifyPasskeyAuthentication:
|
|
554
|
+
verifyPasskeyAuthentication: import("better-call").StrictEndpoint<"/passkey/verify-authentication", {
|
|
546
555
|
method: "POST";
|
|
547
|
-
body: zod.ZodObject<{
|
|
548
|
-
response: zod.ZodRecord<zod.ZodAny, zod.ZodAny>;
|
|
549
|
-
},
|
|
556
|
+
body: import("zod").ZodObject<{
|
|
557
|
+
response: import("zod").ZodRecord<import("zod").ZodAny, import("zod").ZodAny>;
|
|
558
|
+
}, import("zod/v4/core").$strip>;
|
|
550
559
|
metadata: {
|
|
551
560
|
openapi: {
|
|
552
561
|
operationId: string;
|
|
@@ -574,7 +583,7 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
574
583
|
};
|
|
575
584
|
$Infer: {
|
|
576
585
|
body: {
|
|
577
|
-
response:
|
|
586
|
+
response: import("@simplewebauthn/server").AuthenticationResponseJSON;
|
|
578
587
|
};
|
|
579
588
|
};
|
|
580
589
|
};
|
|
@@ -599,9 +608,9 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
599
608
|
image?: string | null | undefined;
|
|
600
609
|
};
|
|
601
610
|
}>;
|
|
602
|
-
listPasskeys:
|
|
611
|
+
listPasskeys: import("better-call").StrictEndpoint<"/passkey/list-user-passkeys", {
|
|
603
612
|
method: "GET";
|
|
604
|
-
use: ((inputContext:
|
|
613
|
+
use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
605
614
|
session: {
|
|
606
615
|
session: Record<string, any> & {
|
|
607
616
|
id: string;
|
|
@@ -647,12 +656,12 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
647
656
|
};
|
|
648
657
|
};
|
|
649
658
|
}, Passkey[]>;
|
|
650
|
-
deletePasskey:
|
|
659
|
+
deletePasskey: import("better-call").StrictEndpoint<"/passkey/delete-passkey", {
|
|
651
660
|
method: "POST";
|
|
652
|
-
body: zod.ZodObject<{
|
|
653
|
-
id: zod.ZodString;
|
|
654
|
-
},
|
|
655
|
-
use: (((inputContext:
|
|
661
|
+
body: import("zod").ZodObject<{
|
|
662
|
+
id: import("zod").ZodString;
|
|
663
|
+
}, import("zod/v4/core").$strip>;
|
|
664
|
+
use: (((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
656
665
|
session: {
|
|
657
666
|
session: Record<string, any> & {
|
|
658
667
|
id: string;
|
|
@@ -674,7 +683,7 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
674
683
|
image?: string | null | undefined;
|
|
675
684
|
};
|
|
676
685
|
};
|
|
677
|
-
}>) | ((inputContext:
|
|
686
|
+
}>) | ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
678
687
|
verifiedResource: {};
|
|
679
688
|
}>))[];
|
|
680
689
|
metadata: {
|
|
@@ -704,13 +713,13 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
704
713
|
}, {
|
|
705
714
|
status: boolean;
|
|
706
715
|
}>;
|
|
707
|
-
updatePasskey:
|
|
716
|
+
updatePasskey: import("better-call").StrictEndpoint<"/passkey/update-passkey", {
|
|
708
717
|
method: "POST";
|
|
709
|
-
body: zod.ZodObject<{
|
|
710
|
-
id: zod.ZodString;
|
|
711
|
-
name: zod.ZodString;
|
|
712
|
-
},
|
|
713
|
-
use: (((inputContext:
|
|
718
|
+
body: import("zod").ZodObject<{
|
|
719
|
+
id: import("zod").ZodString;
|
|
720
|
+
name: import("zod").ZodString;
|
|
721
|
+
}, import("zod/v4/core").$strip>;
|
|
722
|
+
use: (((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
714
723
|
session: {
|
|
715
724
|
session: Record<string, any> & {
|
|
716
725
|
id: string;
|
|
@@ -732,7 +741,7 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
732
741
|
image?: string | null | undefined;
|
|
733
742
|
};
|
|
734
743
|
};
|
|
735
|
-
}>) | ((inputContext:
|
|
744
|
+
}>) | ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<{
|
|
736
745
|
verifiedResource: {};
|
|
737
746
|
}>))[];
|
|
738
747
|
metadata: {
|
|
@@ -815,20 +824,21 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
815
824
|
};
|
|
816
825
|
};
|
|
817
826
|
$ERROR_CODES: {
|
|
818
|
-
CHALLENGE_NOT_FOUND:
|
|
819
|
-
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY:
|
|
820
|
-
FAILED_TO_VERIFY_REGISTRATION:
|
|
821
|
-
PASSKEY_NOT_FOUND:
|
|
822
|
-
AUTHENTICATION_FAILED:
|
|
823
|
-
UNABLE_TO_CREATE_SESSION:
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
827
|
+
CHALLENGE_NOT_FOUND: import("better-auth").RawError<"CHALLENGE_NOT_FOUND">;
|
|
828
|
+
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: import("better-auth").RawError<"YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY">;
|
|
829
|
+
FAILED_TO_VERIFY_REGISTRATION: import("better-auth").RawError<"FAILED_TO_VERIFY_REGISTRATION">;
|
|
830
|
+
PASSKEY_NOT_FOUND: import("better-auth").RawError<"PASSKEY_NOT_FOUND">;
|
|
831
|
+
AUTHENTICATION_FAILED: import("better-auth").RawError<"AUTHENTICATION_FAILED">;
|
|
832
|
+
UNABLE_TO_CREATE_SESSION: import("better-auth").RawError<"UNABLE_TO_CREATE_SESSION">;
|
|
833
|
+
USER_NOT_FOUND: import("better-auth").RawError<"USER_NOT_FOUND">;
|
|
834
|
+
FAILED_TO_UPDATE_PASSKEY: import("better-auth").RawError<"FAILED_TO_UPDATE_PASSKEY">;
|
|
835
|
+
PREVIOUSLY_REGISTERED: import("better-auth").RawError<"PREVIOUSLY_REGISTERED">;
|
|
836
|
+
REGISTRATION_CANCELLED: import("better-auth").RawError<"REGISTRATION_CANCELLED">;
|
|
837
|
+
AUTH_CANCELLED: import("better-auth").RawError<"AUTH_CANCELLED">;
|
|
838
|
+
UNKNOWN_ERROR: import("better-auth").RawError<"UNKNOWN_ERROR">;
|
|
839
|
+
SESSION_REQUIRED: import("better-auth").RawError<"SESSION_REQUIRED">;
|
|
840
|
+
RESOLVE_USER_REQUIRED: import("better-auth").RawError<"RESOLVE_USER_REQUIRED">;
|
|
841
|
+
RESOLVED_USER_INVALID: import("better-auth").RawError<"RESOLVED_USER_INVALID">;
|
|
832
842
|
};
|
|
833
843
|
options: PasskeyOptions | undefined;
|
|
834
844
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as Passkey, c as PasskeyOptions, i as getAuthenticatorName, n as PASSKEY_ERROR_CODES, r as commonAuthenticatorNames, t as passkey } from "./index-
|
|
2
|
-
export { PASSKEY_ERROR_CODES, Passkey, PasskeyOptions, commonAuthenticatorNames, getAuthenticatorName, passkey };
|
|
1
|
+
import { a as Passkey, c as PasskeyOptions, i as getAuthenticatorName, n as PASSKEY_ERROR_CODES, r as commonAuthenticatorNames, t as passkey } from "./index-CatEiPwC.mjs";
|
|
2
|
+
export { PASSKEY_ERROR_CODES, type Passkey, type PasskeyOptions, commonAuthenticatorNames, getAuthenticatorName, passkey };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { n as PASSKEY_ERROR_CODES, t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { n as PASSKEY_ERROR_CODES, t as PACKAGE_VERSION } from "./version-02cV8Fcg.mjs";
|
|
2
2
|
import { mergeSchema } from "better-auth/db";
|
|
3
3
|
import { createAuthEndpoint } from "@better-auth/core/api";
|
|
4
|
+
import { getCurrentAdapter, runWithTransaction } from "@better-auth/core/context";
|
|
4
5
|
import { APIError } from "@better-auth/core/error";
|
|
5
6
|
import { base64 } from "@better-auth/utils/base64";
|
|
6
7
|
import { generateAuthenticationOptions, generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse } from "@simplewebauthn/server";
|
|
@@ -302,8 +303,19 @@ const generatePasskeyAuthenticationOptions = (opts, { maxAgeInSeconds }) => crea
|
|
|
302
303
|
});
|
|
303
304
|
const verifyPasskeyRegistrationBodySchema = z.object({
|
|
304
305
|
response: z.any(),
|
|
305
|
-
name: z.string().trim().meta({ description: "Name of the passkey" }).optional()
|
|
306
|
+
name: z.string().trim().meta({ description: "Name of the passkey" }).optional(),
|
|
307
|
+
createSession: z.boolean().meta({ description: "Create a session after registering the passkey" }).optional()
|
|
306
308
|
});
|
|
309
|
+
const passkeyRegistrationResponseSchema = {
|
|
310
|
+
type: "object",
|
|
311
|
+
allOf: [{ $ref: "#/components/schemas/Passkey" }, {
|
|
312
|
+
type: "object",
|
|
313
|
+
properties: {
|
|
314
|
+
session: { $ref: "#/components/schemas/Session" },
|
|
315
|
+
user: { $ref: "#/components/schemas/User" }
|
|
316
|
+
}
|
|
317
|
+
}]
|
|
318
|
+
};
|
|
307
319
|
const verifyPasskeyRegistration = (options) => {
|
|
308
320
|
const requireSession = options.registration?.requireSession ?? true;
|
|
309
321
|
return createAuthEndpoint("/passkey/verify-registration", {
|
|
@@ -316,7 +328,7 @@ const verifyPasskeyRegistration = (options) => {
|
|
|
316
328
|
responses: {
|
|
317
329
|
200: {
|
|
318
330
|
description: "Success",
|
|
319
|
-
content: { "application/json": { schema:
|
|
331
|
+
content: { "application/json": { schema: passkeyRegistrationResponseSchema } }
|
|
320
332
|
},
|
|
321
333
|
400: { description: "Bad request" }
|
|
322
334
|
}
|
|
@@ -345,47 +357,70 @@ const verifyPasskeyRegistration = (options) => {
|
|
|
345
357
|
const { verified, registrationInfo } = verification;
|
|
346
358
|
if (!verified || !registrationInfo) throw APIError.from("BAD_REQUEST", PASSKEY_ERROR_CODES.FAILED_TO_VERIFY_REGISTRATION);
|
|
347
359
|
const { aaguid, credentialDeviceType, credentialBackedUp, credential } = registrationInfo;
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
360
|
+
const persistRegistration = async () => {
|
|
361
|
+
const resolvedUser = {
|
|
362
|
+
id: userData.id,
|
|
363
|
+
name: userData.name || userData.id,
|
|
364
|
+
displayName: userData.displayName
|
|
365
|
+
};
|
|
366
|
+
let targetUserId = resolvedUser.id;
|
|
367
|
+
let resolvedName = ctx.body.name || void 0;
|
|
368
|
+
if (options.registration?.afterVerification) {
|
|
369
|
+
const result = await options.registration.afterVerification({
|
|
370
|
+
ctx,
|
|
371
|
+
verification,
|
|
372
|
+
user: resolvedUser,
|
|
373
|
+
clientData: resp,
|
|
374
|
+
context
|
|
375
|
+
});
|
|
376
|
+
if (result?.userId) {
|
|
377
|
+
if (typeof result.userId !== "string" || !result.userId) throw APIError.from("BAD_REQUEST", PASSKEY_ERROR_CODES.RESOLVED_USER_INVALID);
|
|
378
|
+
if (session?.user?.id && result.userId !== session.user.id) throw APIError.from("UNAUTHORIZED", PASSKEY_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY);
|
|
379
|
+
targetUserId = result.userId;
|
|
380
|
+
}
|
|
381
|
+
if (!resolvedName) resolvedName = result?.name?.trim() || void 0;
|
|
382
|
+
}
|
|
383
|
+
if (!targetUserId) throw APIError.from("BAD_REQUEST", PASSKEY_ERROR_CODES.RESOLVED_USER_INVALID);
|
|
384
|
+
const user = ctx.body.createSession ? await ctx.context.internalAdapter.findUserById(targetUserId) : null;
|
|
385
|
+
if (ctx.body.createSession && !user) throw APIError.from("INTERNAL_SERVER_ERROR", PASSKEY_ERROR_CODES.USER_NOT_FOUND);
|
|
386
|
+
const pubKey = base64.encode(credential.publicKey);
|
|
387
|
+
const passkey = await (await getCurrentAdapter(ctx.context.adapter)).create({
|
|
388
|
+
model: "passkey",
|
|
389
|
+
data: {
|
|
390
|
+
name: resolvedName,
|
|
391
|
+
userId: targetUserId,
|
|
392
|
+
credentialID: credential.id,
|
|
393
|
+
publicKey: pubKey,
|
|
394
|
+
counter: credential.counter,
|
|
395
|
+
deviceType: credentialDeviceType,
|
|
396
|
+
transports: resp.response.transports?.join(",") ?? "",
|
|
397
|
+
backedUp: credentialBackedUp,
|
|
398
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
399
|
+
aaguid
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
if (!user) return { passkey };
|
|
403
|
+
const createdSession = await ctx.context.internalAdapter.createSession(targetUserId, void 0, void 0, void 0, { deferSecondaryStorageWrites: true });
|
|
404
|
+
if (!createdSession) throw APIError.from("INTERNAL_SERVER_ERROR", PASSKEY_ERROR_CODES.UNABLE_TO_CREATE_SESSION);
|
|
405
|
+
return {
|
|
406
|
+
passkey,
|
|
407
|
+
session: createdSession,
|
|
408
|
+
user
|
|
409
|
+
};
|
|
352
410
|
};
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
verification,
|
|
359
|
-
user: resolvedUser,
|
|
360
|
-
clientData: resp,
|
|
361
|
-
context
|
|
411
|
+
const registration = ctx.body.createSession ? await runWithTransaction(ctx.context.adapter, persistRegistration) : await persistRegistration();
|
|
412
|
+
if (registration.session && registration.user) {
|
|
413
|
+
await setSessionCookie(ctx, {
|
|
414
|
+
session: registration.session,
|
|
415
|
+
user: registration.user
|
|
362
416
|
});
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
368
|
-
if (!resolvedName) resolvedName = result?.name?.trim() || void 0;
|
|
417
|
+
return ctx.json({
|
|
418
|
+
...registration.passkey,
|
|
419
|
+
session: registration.session,
|
|
420
|
+
user: registration.user
|
|
421
|
+
}, { status: 200 });
|
|
369
422
|
}
|
|
370
|
-
|
|
371
|
-
const pubKey = base64.encode(credential.publicKey);
|
|
372
|
-
const newPasskey = {
|
|
373
|
-
name: resolvedName,
|
|
374
|
-
userId: targetUserId,
|
|
375
|
-
credentialID: credential.id,
|
|
376
|
-
publicKey: pubKey,
|
|
377
|
-
counter: credential.counter,
|
|
378
|
-
deviceType: credentialDeviceType,
|
|
379
|
-
transports: resp.response.transports?.join(",") ?? "",
|
|
380
|
-
backedUp: credentialBackedUp,
|
|
381
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
382
|
-
aaguid
|
|
383
|
-
};
|
|
384
|
-
const newPasskeyRes = await ctx.context.adapter.create({
|
|
385
|
-
model: "passkey",
|
|
386
|
-
data: newPasskey
|
|
387
|
-
});
|
|
388
|
-
return ctx.json(newPasskeyRes, { status: 200 });
|
|
423
|
+
return ctx.json(registration.passkey, { status: 200 });
|
|
389
424
|
} catch (e) {
|
|
390
425
|
if (e instanceof APIError) throw e;
|
|
391
426
|
ctx.context.logger.error("Failed to verify registration", e);
|
|
@@ -7,6 +7,7 @@ const PASSKEY_ERROR_CODES = defineErrorCodes({
|
|
|
7
7
|
PASSKEY_NOT_FOUND: "Passkey not found",
|
|
8
8
|
AUTHENTICATION_FAILED: "Authentication failed",
|
|
9
9
|
UNABLE_TO_CREATE_SESSION: "Unable to create session",
|
|
10
|
+
USER_NOT_FOUND: "User not found",
|
|
10
11
|
FAILED_TO_UPDATE_PASSKEY: "Failed to update passkey",
|
|
11
12
|
PREVIOUSLY_REGISTERED: "Previously registered",
|
|
12
13
|
REGISTRATION_CANCELLED: "Registration cancelled",
|
|
@@ -18,6 +19,6 @@ const PASSKEY_ERROR_CODES = defineErrorCodes({
|
|
|
18
19
|
});
|
|
19
20
|
//#endregion
|
|
20
21
|
//#region src/version.ts
|
|
21
|
-
const PACKAGE_VERSION = "1.7.0-rc.
|
|
22
|
+
const PACKAGE_VERSION = "1.7.0-rc.3";
|
|
22
23
|
//#endregion
|
|
23
24
|
export { PASSKEY_ERROR_CODES as n, PACKAGE_VERSION as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/passkey",
|
|
3
|
-
"version": "1.7.0-rc.
|
|
3
|
+
"version": "1.7.0-rc.3",
|
|
4
4
|
"description": "Passkey plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,17 +55,17 @@
|
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"nanostores": "^1.3.0",
|
|
58
|
-
"tsdown": "0.
|
|
59
|
-
"@better-auth/core": "1.7.0-rc.
|
|
60
|
-
"better-auth": "1.7.0-rc.
|
|
58
|
+
"tsdown": "0.22.7",
|
|
59
|
+
"@better-auth/core": "1.7.0-rc.3",
|
|
60
|
+
"better-auth": "1.7.0-rc.3"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"@better-auth/utils": "0.4.2",
|
|
64
64
|
"@better-fetch/fetch": "1.3.1",
|
|
65
65
|
"better-call": "1.3.7",
|
|
66
66
|
"nanostores": "^1.0.1",
|
|
67
|
-
"@better-auth/core": "^1.7.0-rc.
|
|
68
|
-
"better-auth": "^1.7.0-rc.
|
|
67
|
+
"@better-auth/core": "^1.7.0-rc.3",
|
|
68
|
+
"better-auth": "^1.7.0-rc.3"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsdown",
|