@better-auth/passkey 1.4.10-beta.1 → 1.4.10
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 +2 -64
- package/dist/client.mjs +2 -4
- package/dist/{index-C3Ju4ySN.d.mts → index-DneB0hsm.d.mts} +8 -29
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +29 -17
- package/package.json +5 -5
- package/dist/error-codes-VuR_tYBt.mjs +0 -15
package/dist/client.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as WebAuthnChallengeValue, n as Passkey, r as PasskeyOptions, t as passkey } from "./index-
|
|
1
|
+
import { i as WebAuthnChallengeValue, n as Passkey, r as PasskeyOptions, t as passkey } from "./index-DneB0hsm.mjs";
|
|
2
2
|
import * as better_auth_client0 from "better-auth/client";
|
|
3
3
|
import * as nanostores0 from "nanostores";
|
|
4
4
|
import { atom } from "nanostores";
|
|
@@ -7,38 +7,6 @@ import { BetterFetch } from "@better-fetch/fetch";
|
|
|
7
7
|
import { Session, User } from "better-auth/types";
|
|
8
8
|
export * from "@simplewebauthn/server";
|
|
9
9
|
|
|
10
|
-
//#region src/error-codes.d.ts
|
|
11
|
-
declare const PASSKEY_ERROR_CODES: {
|
|
12
|
-
readonly CHALLENGE_NOT_FOUND: {
|
|
13
|
-
code: "CHALLENGE_NOT_FOUND";
|
|
14
|
-
message: "Challenge not found";
|
|
15
|
-
};
|
|
16
|
-
readonly YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: {
|
|
17
|
-
code: "YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY";
|
|
18
|
-
message: "You are not allowed to register this passkey";
|
|
19
|
-
};
|
|
20
|
-
readonly FAILED_TO_VERIFY_REGISTRATION: {
|
|
21
|
-
code: "FAILED_TO_VERIFY_REGISTRATION";
|
|
22
|
-
message: "Failed to verify registration";
|
|
23
|
-
};
|
|
24
|
-
readonly PASSKEY_NOT_FOUND: {
|
|
25
|
-
code: "PASSKEY_NOT_FOUND";
|
|
26
|
-
message: "Passkey not found";
|
|
27
|
-
};
|
|
28
|
-
readonly AUTHENTICATION_FAILED: {
|
|
29
|
-
code: "AUTHENTICATION_FAILED";
|
|
30
|
-
message: "Authentication failed";
|
|
31
|
-
};
|
|
32
|
-
readonly UNABLE_TO_CREATE_SESSION: {
|
|
33
|
-
code: "UNABLE_TO_CREATE_SESSION";
|
|
34
|
-
message: "Unable to create session";
|
|
35
|
-
};
|
|
36
|
-
readonly FAILED_TO_UPDATE_PASSKEY: {
|
|
37
|
-
code: "FAILED_TO_UPDATE_PASSKEY";
|
|
38
|
-
message: "Failed to update passkey";
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
//#endregion
|
|
42
10
|
//#region src/client.d.ts
|
|
43
11
|
declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
44
12
|
$listPasskeys,
|
|
@@ -224,36 +192,6 @@ declare const passkeyClient: () => {
|
|
|
224
192
|
matcher: (path: string) => path is "/passkey/verify-authentication";
|
|
225
193
|
signal: "$sessionSignal";
|
|
226
194
|
})[];
|
|
227
|
-
$ERROR_CODES: {
|
|
228
|
-
readonly CHALLENGE_NOT_FOUND: {
|
|
229
|
-
code: "CHALLENGE_NOT_FOUND";
|
|
230
|
-
message: "Challenge not found";
|
|
231
|
-
};
|
|
232
|
-
readonly YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: {
|
|
233
|
-
code: "YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY";
|
|
234
|
-
message: "You are not allowed to register this passkey";
|
|
235
|
-
};
|
|
236
|
-
readonly FAILED_TO_VERIFY_REGISTRATION: {
|
|
237
|
-
code: "FAILED_TO_VERIFY_REGISTRATION";
|
|
238
|
-
message: "Failed to verify registration";
|
|
239
|
-
};
|
|
240
|
-
readonly PASSKEY_NOT_FOUND: {
|
|
241
|
-
code: "PASSKEY_NOT_FOUND";
|
|
242
|
-
message: "Passkey not found";
|
|
243
|
-
};
|
|
244
|
-
readonly AUTHENTICATION_FAILED: {
|
|
245
|
-
code: "AUTHENTICATION_FAILED";
|
|
246
|
-
message: "Authentication failed";
|
|
247
|
-
};
|
|
248
|
-
readonly UNABLE_TO_CREATE_SESSION: {
|
|
249
|
-
code: "UNABLE_TO_CREATE_SESSION";
|
|
250
|
-
message: "Unable to create session";
|
|
251
|
-
};
|
|
252
|
-
readonly FAILED_TO_UPDATE_PASSKEY: {
|
|
253
|
-
code: "FAILED_TO_UPDATE_PASSKEY";
|
|
254
|
-
message: "Failed to update passkey";
|
|
255
|
-
};
|
|
256
|
-
};
|
|
257
195
|
};
|
|
258
196
|
//#endregion
|
|
259
|
-
export {
|
|
197
|
+
export { Passkey, PasskeyOptions, WebAuthnChallengeValue, getPasskeyActions, passkeyClient };
|
package/dist/client.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { t as PASSKEY_ERROR_CODES } from "./error-codes-VuR_tYBt.mjs";
|
|
2
1
|
import { WebAuthnError, startAuthentication, startRegistration } from "@simplewebauthn/browser";
|
|
3
2
|
import { useAuthQuery } from "better-auth/client";
|
|
4
3
|
import { atom } from "nanostores";
|
|
@@ -139,10 +138,9 @@ const passkeyClient = () => {
|
|
|
139
138
|
}, {
|
|
140
139
|
matcher: (path) => path === "/passkey/verify-authentication",
|
|
141
140
|
signal: "$sessionSignal"
|
|
142
|
-
}]
|
|
143
|
-
$ERROR_CODES: PASSKEY_ERROR_CODES
|
|
141
|
+
}]
|
|
144
142
|
};
|
|
145
143
|
};
|
|
146
144
|
|
|
147
145
|
//#endregion
|
|
148
|
-
export {
|
|
146
|
+
export { getPasskeyActions, passkeyClient };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as _simplewebauthn_server0 from "@simplewebauthn/server";
|
|
2
2
|
import { CredentialDeviceType } from "@simplewebauthn/server";
|
|
3
|
+
import * as better_call0 from "better-call";
|
|
3
4
|
import * as zod0 from "zod";
|
|
4
5
|
import { InferOptionSchema } from "better-auth/types";
|
|
5
|
-
import * as better_call0 from "better-call";
|
|
6
6
|
import * as better_auth0 from "better-auth";
|
|
7
7
|
|
|
8
8
|
//#region src/schema.d.ts
|
|
@@ -686,34 +686,13 @@ declare const passkey: (options?: PasskeyOptions | undefined) => {
|
|
|
686
686
|
};
|
|
687
687
|
};
|
|
688
688
|
$ERROR_CODES: {
|
|
689
|
-
readonly CHALLENGE_NOT_FOUND:
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
readonly
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
};
|
|
697
|
-
readonly FAILED_TO_VERIFY_REGISTRATION: {
|
|
698
|
-
code: "FAILED_TO_VERIFY_REGISTRATION";
|
|
699
|
-
message: "Failed to verify registration";
|
|
700
|
-
};
|
|
701
|
-
readonly PASSKEY_NOT_FOUND: {
|
|
702
|
-
code: "PASSKEY_NOT_FOUND";
|
|
703
|
-
message: "Passkey not found";
|
|
704
|
-
};
|
|
705
|
-
readonly AUTHENTICATION_FAILED: {
|
|
706
|
-
code: "AUTHENTICATION_FAILED";
|
|
707
|
-
message: "Authentication failed";
|
|
708
|
-
};
|
|
709
|
-
readonly UNABLE_TO_CREATE_SESSION: {
|
|
710
|
-
code: "UNABLE_TO_CREATE_SESSION";
|
|
711
|
-
message: "Unable to create session";
|
|
712
|
-
};
|
|
713
|
-
readonly FAILED_TO_UPDATE_PASSKEY: {
|
|
714
|
-
code: "FAILED_TO_UPDATE_PASSKEY";
|
|
715
|
-
message: "Failed to update passkey";
|
|
716
|
-
};
|
|
689
|
+
readonly CHALLENGE_NOT_FOUND: "Challenge not found";
|
|
690
|
+
readonly YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: "You are not allowed to register this passkey";
|
|
691
|
+
readonly FAILED_TO_VERIFY_REGISTRATION: "Failed to verify registration";
|
|
692
|
+
readonly PASSKEY_NOT_FOUND: "Passkey not found";
|
|
693
|
+
readonly AUTHENTICATION_FAILED: "Authentication failed";
|
|
694
|
+
readonly UNABLE_TO_CREATE_SESSION: "Unable to create session";
|
|
695
|
+
readonly FAILED_TO_UPDATE_PASSKEY: "Failed to update passkey";
|
|
717
696
|
};
|
|
718
697
|
options: PasskeyOptions | undefined;
|
|
719
698
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as Passkey, r as PasskeyOptions, t as passkey } from "./index-
|
|
1
|
+
import { n as Passkey, r as PasskeyOptions, t as passkey } from "./index-DneB0hsm.mjs";
|
|
2
2
|
export { Passkey, PasskeyOptions, passkey };
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
|
-
import { t as PASSKEY_ERROR_CODES } from "./error-codes-VuR_tYBt.mjs";
|
|
2
1
|
import { mergeSchema } from "better-auth/db";
|
|
2
|
+
import { defineErrorCodes } from "@better-auth/core/utils";
|
|
3
3
|
import { createAuthEndpoint } from "@better-auth/core/api";
|
|
4
|
-
import { APIError } from "@better-auth/core/error";
|
|
5
4
|
import { base64 } from "@better-auth/utils/base64";
|
|
6
5
|
import { generateAuthenticationOptions, generateRegistrationOptions, verifyAuthenticationResponse, verifyRegistrationResponse } from "@simplewebauthn/server";
|
|
7
6
|
import { freshSessionMiddleware, getSessionFromCtx, sessionMiddleware } from "better-auth/api";
|
|
8
7
|
import { setSessionCookie } from "better-auth/cookies";
|
|
9
8
|
import { generateRandomString } from "better-auth/crypto";
|
|
9
|
+
import { APIError } from "better-call";
|
|
10
10
|
import * as z from "zod";
|
|
11
11
|
|
|
12
|
+
//#region src/error-codes.ts
|
|
13
|
+
const PASSKEY_ERROR_CODES = defineErrorCodes({
|
|
14
|
+
CHALLENGE_NOT_FOUND: "Challenge not found",
|
|
15
|
+
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: "You are not allowed to register this passkey",
|
|
16
|
+
FAILED_TO_VERIFY_REGISTRATION: "Failed to verify registration",
|
|
17
|
+
PASSKEY_NOT_FOUND: "Passkey not found",
|
|
18
|
+
AUTHENTICATION_FAILED: "Authentication failed",
|
|
19
|
+
UNABLE_TO_CREATE_SESSION: "Unable to create session",
|
|
20
|
+
FAILED_TO_UPDATE_PASSKEY: "Failed to update passkey"
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
12
24
|
//#region src/utils.ts
|
|
13
25
|
function getRpID(options, baseURL) {
|
|
14
26
|
return options.rpID || (baseURL ? new URL(baseURL).hostname : "localhost");
|
|
@@ -260,11 +272,11 @@ const verifyPasskeyRegistration = (options) => createAuthEndpoint("/passkey/veri
|
|
|
260
272
|
const resp = ctx.body.response;
|
|
261
273
|
const webAuthnCookie = ctx.context.createAuthCookie(options.advanced.webAuthnChallengeCookie);
|
|
262
274
|
const verificationToken = await ctx.getSignedCookie(webAuthnCookie.name, ctx.context.secret);
|
|
263
|
-
if (!verificationToken) throw APIError
|
|
275
|
+
if (!verificationToken) throw new APIError("BAD_REQUEST", { message: PASSKEY_ERROR_CODES.CHALLENGE_NOT_FOUND });
|
|
264
276
|
const data = await ctx.context.internalAdapter.findVerificationValue(verificationToken);
|
|
265
277
|
if (!data) return ctx.json(null, { status: 400 });
|
|
266
278
|
const { expectedChallenge, userData } = JSON.parse(data.value);
|
|
267
|
-
if (userData.id !== ctx.context.session.user.id) throw APIError
|
|
279
|
+
if (userData.id !== ctx.context.session.user.id) throw new APIError("UNAUTHORIZED", { message: PASSKEY_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY });
|
|
268
280
|
try {
|
|
269
281
|
const { verified, registrationInfo } = await verifyRegistrationResponse({
|
|
270
282
|
response: resp,
|
|
@@ -292,11 +304,11 @@ const verifyPasskeyRegistration = (options) => createAuthEndpoint("/passkey/veri
|
|
|
292
304
|
model: "passkey",
|
|
293
305
|
data: newPasskey
|
|
294
306
|
});
|
|
295
|
-
await ctx.context.internalAdapter.
|
|
307
|
+
await ctx.context.internalAdapter.deleteVerificationValue(data.id);
|
|
296
308
|
return ctx.json(newPasskeyRes, { status: 200 });
|
|
297
309
|
} catch (e) {
|
|
298
310
|
ctx.context.logger.error("Failed to verify registration", e);
|
|
299
|
-
throw APIError
|
|
311
|
+
throw new APIError("INTERNAL_SERVER_ERROR", { message: PASSKEY_ERROR_CODES.FAILED_TO_VERIFY_REGISTRATION });
|
|
300
312
|
}
|
|
301
313
|
});
|
|
302
314
|
const verifyPasskeyAuthenticationBodySchema = z.object({ response: z.record(z.any(), z.any()) });
|
|
@@ -326,9 +338,9 @@ const verifyPasskeyAuthentication = (options) => createAuthEndpoint("/passkey/ve
|
|
|
326
338
|
const resp = ctx.body.response;
|
|
327
339
|
const webAuthnCookie = ctx.context.createAuthCookie(options.advanced.webAuthnChallengeCookie);
|
|
328
340
|
const verificationToken = await ctx.getSignedCookie(webAuthnCookie.name, ctx.context.secret);
|
|
329
|
-
if (!verificationToken) throw APIError
|
|
341
|
+
if (!verificationToken) throw new APIError("BAD_REQUEST", { message: PASSKEY_ERROR_CODES.CHALLENGE_NOT_FOUND });
|
|
330
342
|
const data = await ctx.context.internalAdapter.findVerificationValue(verificationToken);
|
|
331
|
-
if (!data) throw APIError
|
|
343
|
+
if (!data) throw new APIError("BAD_REQUEST", { message: PASSKEY_ERROR_CODES.CHALLENGE_NOT_FOUND });
|
|
332
344
|
const { expectedChallenge } = JSON.parse(data.value);
|
|
333
345
|
const passkey$1 = await ctx.context.adapter.findOne({
|
|
334
346
|
model: "passkey",
|
|
@@ -337,7 +349,7 @@ const verifyPasskeyAuthentication = (options) => createAuthEndpoint("/passkey/ve
|
|
|
337
349
|
value: resp.id
|
|
338
350
|
}]
|
|
339
351
|
});
|
|
340
|
-
if (!passkey$1) throw APIError
|
|
352
|
+
if (!passkey$1) throw new APIError("UNAUTHORIZED", { message: PASSKEY_ERROR_CODES.PASSKEY_NOT_FOUND });
|
|
341
353
|
try {
|
|
342
354
|
const verification = await verifyAuthenticationResponse({
|
|
343
355
|
response: resp,
|
|
@@ -353,7 +365,7 @@ const verifyPasskeyAuthentication = (options) => createAuthEndpoint("/passkey/ve
|
|
|
353
365
|
requireUserVerification: false
|
|
354
366
|
});
|
|
355
367
|
const { verified } = verification;
|
|
356
|
-
if (!verified) throw APIError
|
|
368
|
+
if (!verified) throw new APIError("UNAUTHORIZED", { message: PASSKEY_ERROR_CODES.AUTHENTICATION_FAILED });
|
|
357
369
|
await ctx.context.adapter.update({
|
|
358
370
|
model: "passkey",
|
|
359
371
|
where: [{
|
|
@@ -363,18 +375,18 @@ const verifyPasskeyAuthentication = (options) => createAuthEndpoint("/passkey/ve
|
|
|
363
375
|
update: { counter: verification.authenticationInfo.newCounter }
|
|
364
376
|
});
|
|
365
377
|
const s = await ctx.context.internalAdapter.createSession(passkey$1.userId);
|
|
366
|
-
if (!s) throw APIError
|
|
378
|
+
if (!s) throw new APIError("INTERNAL_SERVER_ERROR", { message: PASSKEY_ERROR_CODES.UNABLE_TO_CREATE_SESSION });
|
|
367
379
|
const user = await ctx.context.internalAdapter.findUserById(passkey$1.userId);
|
|
368
380
|
if (!user) throw new APIError("INTERNAL_SERVER_ERROR", { message: "User not found" });
|
|
369
381
|
await setSessionCookie(ctx, {
|
|
370
382
|
session: s,
|
|
371
383
|
user
|
|
372
384
|
});
|
|
373
|
-
await ctx.context.internalAdapter.
|
|
385
|
+
await ctx.context.internalAdapter.deleteVerificationValue(data.id);
|
|
374
386
|
return ctx.json({ session: s }, { status: 200 });
|
|
375
387
|
} catch (e) {
|
|
376
388
|
ctx.context.logger.error("Failed to verify authentication", e);
|
|
377
|
-
throw APIError
|
|
389
|
+
throw new APIError("BAD_REQUEST", { message: PASSKEY_ERROR_CODES.AUTHENTICATION_FAILED });
|
|
378
390
|
}
|
|
379
391
|
});
|
|
380
392
|
/**
|
|
@@ -467,7 +479,7 @@ const deletePasskey = createAuthEndpoint("/passkey/delete-passkey", {
|
|
|
467
479
|
value: ctx.body.id
|
|
468
480
|
}]
|
|
469
481
|
});
|
|
470
|
-
if (!passkey$1) throw APIError
|
|
482
|
+
if (!passkey$1) throw new APIError("NOT_FOUND", { message: PASSKEY_ERROR_CODES.PASSKEY_NOT_FOUND });
|
|
471
483
|
if (passkey$1.userId !== ctx.context.session.user.id) throw new APIError("UNAUTHORIZED");
|
|
472
484
|
await ctx.context.adapter.delete({
|
|
473
485
|
model: "passkey",
|
|
@@ -520,8 +532,8 @@ const updatePasskey = createAuthEndpoint("/passkey/update-passkey", {
|
|
|
520
532
|
value: ctx.body.id
|
|
521
533
|
}]
|
|
522
534
|
});
|
|
523
|
-
if (!passkey$1) throw APIError
|
|
524
|
-
if (passkey$1.userId !== ctx.context.session.user.id) throw APIError
|
|
535
|
+
if (!passkey$1) throw new APIError("NOT_FOUND", { message: PASSKEY_ERROR_CODES.PASSKEY_NOT_FOUND });
|
|
536
|
+
if (passkey$1.userId !== ctx.context.session.user.id) throw new APIError("UNAUTHORIZED", { message: PASSKEY_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY });
|
|
525
537
|
const updatedPasskey = await ctx.context.adapter.update({
|
|
526
538
|
model: "passkey",
|
|
527
539
|
where: [{
|
|
@@ -530,7 +542,7 @@ const updatePasskey = createAuthEndpoint("/passkey/update-passkey", {
|
|
|
530
542
|
}],
|
|
531
543
|
update: { name: ctx.body.name }
|
|
532
544
|
});
|
|
533
|
-
if (!updatedPasskey) throw APIError
|
|
545
|
+
if (!updatedPasskey) throw new APIError("INTERNAL_SERVER_ERROR", { message: PASSKEY_ERROR_CODES.FAILED_TO_UPDATE_PASSKEY });
|
|
534
546
|
return ctx.json({ passkey: updatedPasskey }, { status: 200 });
|
|
535
547
|
});
|
|
536
548
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/passkey",
|
|
3
|
-
"version": "1.4.10
|
|
3
|
+
"version": "1.4.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Passkey plugin for Better Auth",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"tsdown": "^0.17.2",
|
|
36
|
-
"better-auth": "1.4.10
|
|
37
|
-
"
|
|
36
|
+
"@better-auth/core": "1.4.10",
|
|
37
|
+
"better-auth": "1.4.10"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@simplewebauthn/browser": "^13.1.2",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@better-fetch/fetch": "1.1.21",
|
|
47
47
|
"better-call": "1.1.7",
|
|
48
48
|
"nanostores": "^1.0.1",
|
|
49
|
-
"@better-auth/core": "1.4.10
|
|
50
|
-
"better-auth": "1.4.10
|
|
49
|
+
"@better-auth/core": "1.4.10",
|
|
50
|
+
"better-auth": "1.4.10"
|
|
51
51
|
},
|
|
52
52
|
"files": [
|
|
53
53
|
"dist"
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { defineErrorCodes } from "@better-auth/core/utils";
|
|
2
|
-
|
|
3
|
-
//#region src/error-codes.ts
|
|
4
|
-
const PASSKEY_ERROR_CODES = defineErrorCodes({
|
|
5
|
-
CHALLENGE_NOT_FOUND: "Challenge not found",
|
|
6
|
-
YOU_ARE_NOT_ALLOWED_TO_REGISTER_THIS_PASSKEY: "You are not allowed to register this passkey",
|
|
7
|
-
FAILED_TO_VERIFY_REGISTRATION: "Failed to verify registration",
|
|
8
|
-
PASSKEY_NOT_FOUND: "Passkey not found",
|
|
9
|
-
AUTHENTICATION_FAILED: "Authentication failed",
|
|
10
|
-
UNABLE_TO_CREATE_SESSION: "Unable to create session",
|
|
11
|
-
FAILED_TO_UPDATE_PASSKEY: "Failed to update passkey"
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
//#endregion
|
|
15
|
-
export { PASSKEY_ERROR_CODES as t };
|