@better-auth/passkey 1.5.6 → 1.6.0-beta.0
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 +91 -35
- package/dist/client.mjs +45 -15
- package/dist/index-BzKpmgHh.d.mts +771 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +260 -187
- package/dist/{error-codes-DJf-1Ecu.mjs → version-B7zkjZSd.mjs} +8 -5
- package/package.json +10 -9
- package/dist/client.mjs.map +0 -1
- package/dist/error-codes-DJf-1Ecu.mjs.map +0 -1
- package/dist/index-B6ZC0I-g.d.mts +0 -727
- package/dist/index.mjs.map +0 -1
package/dist/client.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as PasskeyExtensionsResolver, c as PasskeyRegistrationUser, i as PasskeyAuthenticationOptions, l as WebAuthnChallengeValue, n as PASSKEY_ERROR_CODES, o as PasskeyOptions, r as Passkey, s as PasskeyRegistrationOptions, t as passkey } from "./index-BzKpmgHh.mjs";
|
|
2
|
+
import { AuthenticationExtensionsClientInputs, AuthenticationExtensionsClientOutputs, AuthenticationResponseJSON, RegistrationResponseJSON } from "@simplewebauthn/server";
|
|
2
3
|
import * as better_auth_client0 from "better-auth/client";
|
|
3
4
|
import * as nanostores from "nanostores";
|
|
4
5
|
import { atom } from "nanostores";
|
|
@@ -22,6 +23,8 @@ declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
|
22
23
|
*/
|
|
23
24
|
passkey: (opts?: {
|
|
24
25
|
autoFill?: boolean;
|
|
26
|
+
extensions?: AuthenticationExtensionsClientInputs;
|
|
27
|
+
returnWebAuthnResponse?: boolean;
|
|
25
28
|
fetchOptions?: ClientFetchOption;
|
|
26
29
|
} | undefined, options?: ClientFetchOption | undefined) => Promise<{
|
|
27
30
|
data: null;
|
|
@@ -36,11 +39,32 @@ declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
|
36
39
|
user: User;
|
|
37
40
|
};
|
|
38
41
|
error: null;
|
|
42
|
+
} | {
|
|
43
|
+
webauthn: {
|
|
44
|
+
response: AuthenticationResponseJSON;
|
|
45
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
46
|
+
};
|
|
47
|
+
data: null;
|
|
48
|
+
error: {
|
|
49
|
+
message?: string | undefined;
|
|
50
|
+
status: number;
|
|
51
|
+
statusText: string;
|
|
52
|
+
};
|
|
53
|
+
} | {
|
|
54
|
+
webauthn: {
|
|
55
|
+
response: AuthenticationResponseJSON;
|
|
56
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
57
|
+
};
|
|
58
|
+
data: {
|
|
59
|
+
session: Session;
|
|
60
|
+
user: User;
|
|
61
|
+
};
|
|
62
|
+
error: null;
|
|
39
63
|
} | {
|
|
40
64
|
data: null;
|
|
41
65
|
error: {
|
|
42
66
|
code: string;
|
|
43
|
-
message:
|
|
67
|
+
message: string;
|
|
44
68
|
status: number;
|
|
45
69
|
statusText: string;
|
|
46
70
|
};
|
|
@@ -62,12 +86,24 @@ declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
|
62
86
|
* platform and cross-platform allowed, with platform preferred.
|
|
63
87
|
*/
|
|
64
88
|
authenticatorAttachment?: "platform" | "cross-platform";
|
|
89
|
+
/**
|
|
90
|
+
* Optional context for passkey-first registration flows.
|
|
91
|
+
*/
|
|
92
|
+
context?: string | null;
|
|
93
|
+
/**
|
|
94
|
+
* Optional WebAuthn extensions to include during registration.
|
|
95
|
+
*/
|
|
96
|
+
extensions?: AuthenticationExtensionsClientInputs;
|
|
65
97
|
/**
|
|
66
98
|
* Try to silently create a passkey with the password manager that the user just signed
|
|
67
99
|
* in with.
|
|
68
100
|
* @default false
|
|
69
101
|
*/
|
|
70
102
|
useAutoRegister?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Return WebAuthn response and extension results.
|
|
105
|
+
*/
|
|
106
|
+
returnWebAuthnResponse?: boolean;
|
|
71
107
|
} | undefined, fetchOpts?: ClientFetchOption | undefined) => Promise<{
|
|
72
108
|
data: null;
|
|
73
109
|
error: {
|
|
@@ -79,26 +115,17 @@ declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
|
79
115
|
data: Passkey;
|
|
80
116
|
error: null;
|
|
81
117
|
} | {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
message: better_auth0.RawError<"PREVIOUSLY_REGISTERED">;
|
|
86
|
-
status: number;
|
|
87
|
-
statusText: string;
|
|
88
|
-
};
|
|
89
|
-
} | {
|
|
90
|
-
data: null;
|
|
91
|
-
error: {
|
|
92
|
-
code: "ERROR_CEREMONY_ABORTED";
|
|
93
|
-
message: better_auth0.RawError<"REGISTRATION_CANCELLED">;
|
|
94
|
-
status: number;
|
|
95
|
-
statusText: string;
|
|
118
|
+
webauthn: {
|
|
119
|
+
response: RegistrationResponseJSON;
|
|
120
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
96
121
|
};
|
|
122
|
+
data: Passkey;
|
|
123
|
+
error: null;
|
|
97
124
|
} | {
|
|
98
125
|
data: null;
|
|
99
126
|
error: {
|
|
100
127
|
code: string;
|
|
101
|
-
message: string
|
|
128
|
+
message: string;
|
|
102
129
|
status: number;
|
|
103
130
|
statusText: string;
|
|
104
131
|
};
|
|
@@ -113,6 +140,7 @@ declare const getPasskeyActions: ($fetch: BetterFetch, {
|
|
|
113
140
|
};
|
|
114
141
|
declare const passkeyClient: () => {
|
|
115
142
|
id: "passkey";
|
|
143
|
+
version: string;
|
|
116
144
|
$InferServerPlugin: ReturnType<typeof passkey>;
|
|
117
145
|
getActions: ($fetch: BetterFetch, $store: ClientStore) => {
|
|
118
146
|
signIn: {
|
|
@@ -121,6 +149,8 @@ declare const passkeyClient: () => {
|
|
|
121
149
|
*/
|
|
122
150
|
passkey: (opts?: {
|
|
123
151
|
autoFill?: boolean;
|
|
152
|
+
extensions?: AuthenticationExtensionsClientInputs;
|
|
153
|
+
returnWebAuthnResponse?: boolean;
|
|
124
154
|
fetchOptions?: ClientFetchOption;
|
|
125
155
|
} | undefined, options?: ClientFetchOption | undefined) => Promise<{
|
|
126
156
|
data: null;
|
|
@@ -135,11 +165,32 @@ declare const passkeyClient: () => {
|
|
|
135
165
|
user: User;
|
|
136
166
|
};
|
|
137
167
|
error: null;
|
|
168
|
+
} | {
|
|
169
|
+
webauthn: {
|
|
170
|
+
response: AuthenticationResponseJSON;
|
|
171
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
172
|
+
};
|
|
173
|
+
data: null;
|
|
174
|
+
error: {
|
|
175
|
+
message?: string | undefined;
|
|
176
|
+
status: number;
|
|
177
|
+
statusText: string;
|
|
178
|
+
};
|
|
179
|
+
} | {
|
|
180
|
+
webauthn: {
|
|
181
|
+
response: AuthenticationResponseJSON;
|
|
182
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
183
|
+
};
|
|
184
|
+
data: {
|
|
185
|
+
session: Session;
|
|
186
|
+
user: User;
|
|
187
|
+
};
|
|
188
|
+
error: null;
|
|
138
189
|
} | {
|
|
139
190
|
data: null;
|
|
140
191
|
error: {
|
|
141
192
|
code: string;
|
|
142
|
-
message:
|
|
193
|
+
message: string;
|
|
143
194
|
status: number;
|
|
144
195
|
statusText: string;
|
|
145
196
|
};
|
|
@@ -161,12 +212,24 @@ declare const passkeyClient: () => {
|
|
|
161
212
|
* platform and cross-platform allowed, with platform preferred.
|
|
162
213
|
*/
|
|
163
214
|
authenticatorAttachment?: "platform" | "cross-platform";
|
|
215
|
+
/**
|
|
216
|
+
* Optional context for passkey-first registration flows.
|
|
217
|
+
*/
|
|
218
|
+
context?: string | null;
|
|
219
|
+
/**
|
|
220
|
+
* Optional WebAuthn extensions to include during registration.
|
|
221
|
+
*/
|
|
222
|
+
extensions?: AuthenticationExtensionsClientInputs;
|
|
164
223
|
/**
|
|
165
224
|
* Try to silently create a passkey with the password manager that the user just signed
|
|
166
225
|
* in with.
|
|
167
226
|
* @default false
|
|
168
227
|
*/
|
|
169
228
|
useAutoRegister?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Return WebAuthn response and extension results.
|
|
231
|
+
*/
|
|
232
|
+
returnWebAuthnResponse?: boolean;
|
|
170
233
|
} | undefined, fetchOpts?: ClientFetchOption | undefined) => Promise<{
|
|
171
234
|
data: null;
|
|
172
235
|
error: {
|
|
@@ -178,26 +241,17 @@ declare const passkeyClient: () => {
|
|
|
178
241
|
data: Passkey;
|
|
179
242
|
error: null;
|
|
180
243
|
} | {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
message: better_auth0.RawError<"PREVIOUSLY_REGISTERED">;
|
|
185
|
-
status: number;
|
|
186
|
-
statusText: string;
|
|
187
|
-
};
|
|
188
|
-
} | {
|
|
189
|
-
data: null;
|
|
190
|
-
error: {
|
|
191
|
-
code: "ERROR_CEREMONY_ABORTED";
|
|
192
|
-
message: better_auth0.RawError<"REGISTRATION_CANCELLED">;
|
|
193
|
-
status: number;
|
|
194
|
-
statusText: string;
|
|
244
|
+
webauthn: {
|
|
245
|
+
response: RegistrationResponseJSON;
|
|
246
|
+
clientExtensionResults: AuthenticationExtensionsClientOutputs;
|
|
195
247
|
};
|
|
248
|
+
data: Passkey;
|
|
249
|
+
error: null;
|
|
196
250
|
} | {
|
|
197
251
|
data: null;
|
|
198
252
|
error: {
|
|
199
253
|
code: string;
|
|
200
|
-
message: string
|
|
254
|
+
message: string;
|
|
201
255
|
status: number;
|
|
202
256
|
statusText: string;
|
|
203
257
|
};
|
|
@@ -237,8 +291,10 @@ declare const passkeyClient: () => {
|
|
|
237
291
|
REGISTRATION_CANCELLED: better_auth0.RawError<"REGISTRATION_CANCELLED">;
|
|
238
292
|
AUTH_CANCELLED: better_auth0.RawError<"AUTH_CANCELLED">;
|
|
239
293
|
UNKNOWN_ERROR: better_auth0.RawError<"UNKNOWN_ERROR">;
|
|
294
|
+
SESSION_REQUIRED: better_auth0.RawError<"SESSION_REQUIRED">;
|
|
295
|
+
RESOLVE_USER_REQUIRED: better_auth0.RawError<"RESOLVE_USER_REQUIRED">;
|
|
296
|
+
RESOLVED_USER_INVALID: better_auth0.RawError<"RESOLVED_USER_INVALID">;
|
|
240
297
|
};
|
|
241
298
|
};
|
|
242
299
|
//#endregion
|
|
243
|
-
export { PASSKEY_ERROR_CODES, Passkey, PasskeyOptions, WebAuthnChallengeValue, getPasskeyActions, passkeyClient };
|
|
244
|
-
//# sourceMappingURL=client.d.mts.map
|
|
300
|
+
export { PASSKEY_ERROR_CODES, Passkey, PasskeyAuthenticationOptions, PasskeyExtensionsResolver, PasskeyOptions, PasskeyRegistrationOptions, PasskeyRegistrationUser, WebAuthnChallengeValue, getPasskeyActions, passkeyClient };
|
package/dist/client.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as PASSKEY_ERROR_CODES, t as PACKAGE_VERSION } from "./version-B7zkjZSd.mjs";
|
|
2
2
|
import { WebAuthnError, startAuthentication, startRegistration } from "@simplewebauthn/browser";
|
|
3
3
|
import { useAuthQuery } from "better-auth/client";
|
|
4
4
|
import { atom } from "nanostores";
|
|
5
|
-
|
|
6
5
|
//#region src/client.ts
|
|
7
6
|
const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
8
7
|
const signInPasskey = async (opts, options) => {
|
|
@@ -12,11 +11,20 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
12
11
|
});
|
|
13
12
|
if (!response.data) return response;
|
|
14
13
|
try {
|
|
14
|
+
const mergedExtensions = response.data.extensions || opts?.extensions ? {
|
|
15
|
+
...response.data.extensions || {},
|
|
16
|
+
...opts?.extensions || {}
|
|
17
|
+
} : void 0;
|
|
18
|
+
const res = await startAuthentication({
|
|
19
|
+
optionsJSON: {
|
|
20
|
+
...response.data,
|
|
21
|
+
extensions: mergedExtensions
|
|
22
|
+
},
|
|
23
|
+
useBrowserAutofill: opts?.autoFill
|
|
24
|
+
});
|
|
25
|
+
const { clientExtensionResults, ...responseBody } = res;
|
|
15
26
|
const verified = await $fetch("/passkey/verify-authentication", {
|
|
16
|
-
body: { response:
|
|
17
|
-
optionsJSON: response.data,
|
|
18
|
-
useBrowserAutofill: opts?.autoFill
|
|
19
|
-
}) },
|
|
27
|
+
body: { response: responseBody },
|
|
20
28
|
...opts?.fetchOptions,
|
|
21
29
|
...options,
|
|
22
30
|
method: "POST",
|
|
@@ -24,6 +32,13 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
24
32
|
});
|
|
25
33
|
$listPasskeys.set(Math.random());
|
|
26
34
|
$store.notify("$sessionSignal");
|
|
35
|
+
if (opts?.returnWebAuthnResponse) return {
|
|
36
|
+
...verified,
|
|
37
|
+
webauthn: {
|
|
38
|
+
response: res,
|
|
39
|
+
clientExtensionResults
|
|
40
|
+
}
|
|
41
|
+
};
|
|
27
42
|
return verified;
|
|
28
43
|
} catch (err) {
|
|
29
44
|
console.error(`[Better Auth] Error verifying passkey`, err);
|
|
@@ -31,7 +46,7 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
31
46
|
data: null,
|
|
32
47
|
error: {
|
|
33
48
|
code: "AUTH_CANCELLED",
|
|
34
|
-
message: PASSKEY_ERROR_CODES.AUTH_CANCELLED,
|
|
49
|
+
message: PASSKEY_ERROR_CODES.AUTH_CANCELLED.message,
|
|
35
50
|
status: 400,
|
|
36
51
|
statusText: "BAD_REQUEST"
|
|
37
52
|
}
|
|
@@ -43,21 +58,30 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
43
58
|
method: "GET",
|
|
44
59
|
query: {
|
|
45
60
|
...opts?.authenticatorAttachment && { authenticatorAttachment: opts.authenticatorAttachment },
|
|
46
|
-
...opts?.name && { name: opts.name }
|
|
61
|
+
...opts?.name && { name: opts.name },
|
|
62
|
+
...opts?.context && { context: opts.context }
|
|
47
63
|
},
|
|
48
64
|
throw: false
|
|
49
65
|
});
|
|
50
66
|
if (!options.data) return options;
|
|
51
67
|
try {
|
|
68
|
+
const mergedExtensions = options.data.extensions || opts?.extensions ? {
|
|
69
|
+
...options.data.extensions || {},
|
|
70
|
+
...opts?.extensions || {}
|
|
71
|
+
} : void 0;
|
|
52
72
|
const res = await startRegistration({
|
|
53
|
-
optionsJSON:
|
|
73
|
+
optionsJSON: {
|
|
74
|
+
...options.data,
|
|
75
|
+
extensions: mergedExtensions
|
|
76
|
+
},
|
|
54
77
|
useAutoRegister: opts?.useAutoRegister
|
|
55
78
|
});
|
|
79
|
+
const { clientExtensionResults, ...responseBody } = res;
|
|
56
80
|
const verified = await $fetch("/passkey/verify-registration", {
|
|
57
81
|
...opts?.fetchOptions,
|
|
58
82
|
...fetchOpts,
|
|
59
83
|
body: {
|
|
60
|
-
response:
|
|
84
|
+
response: responseBody,
|
|
61
85
|
name: opts?.name
|
|
62
86
|
},
|
|
63
87
|
method: "POST",
|
|
@@ -65,6 +89,13 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
65
89
|
});
|
|
66
90
|
if (!verified.data) return verified;
|
|
67
91
|
$listPasskeys.set(Math.random());
|
|
92
|
+
if (opts?.returnWebAuthnResponse) return {
|
|
93
|
+
...verified,
|
|
94
|
+
webauthn: {
|
|
95
|
+
response: res,
|
|
96
|
+
clientExtensionResults
|
|
97
|
+
}
|
|
98
|
+
};
|
|
68
99
|
return verified;
|
|
69
100
|
} catch (e) {
|
|
70
101
|
if (e instanceof WebAuthnError) {
|
|
@@ -72,7 +103,7 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
72
103
|
data: null,
|
|
73
104
|
error: {
|
|
74
105
|
code: e.code,
|
|
75
|
-
message: PASSKEY_ERROR_CODES.PREVIOUSLY_REGISTERED,
|
|
106
|
+
message: PASSKEY_ERROR_CODES.PREVIOUSLY_REGISTERED.message,
|
|
76
107
|
status: 400,
|
|
77
108
|
statusText: "BAD_REQUEST"
|
|
78
109
|
}
|
|
@@ -81,7 +112,7 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
81
112
|
data: null,
|
|
82
113
|
error: {
|
|
83
114
|
code: e.code,
|
|
84
|
-
message: PASSKEY_ERROR_CODES.REGISTRATION_CANCELLED,
|
|
115
|
+
message: PASSKEY_ERROR_CODES.REGISTRATION_CANCELLED.message,
|
|
85
116
|
status: 400,
|
|
86
117
|
statusText: "BAD_REQUEST"
|
|
87
118
|
}
|
|
@@ -100,7 +131,7 @@ const getPasskeyActions = ($fetch, { $listPasskeys, $store }) => {
|
|
|
100
131
|
data: null,
|
|
101
132
|
error: {
|
|
102
133
|
code: "UNKNOWN_ERROR",
|
|
103
|
-
message: e instanceof Error ? e.message : PASSKEY_ERROR_CODES.UNKNOWN_ERROR,
|
|
134
|
+
message: e instanceof Error ? e.message : PASSKEY_ERROR_CODES.UNKNOWN_ERROR.message,
|
|
104
135
|
status: 500,
|
|
105
136
|
statusText: "INTERNAL_SERVER_ERROR"
|
|
106
137
|
}
|
|
@@ -117,6 +148,7 @@ const passkeyClient = () => {
|
|
|
117
148
|
const $listPasskeys = atom();
|
|
118
149
|
return {
|
|
119
150
|
id: "passkey",
|
|
151
|
+
version: PACKAGE_VERSION,
|
|
120
152
|
$InferServerPlugin: {},
|
|
121
153
|
getActions: ($fetch, $store) => getPasskeyActions($fetch, {
|
|
122
154
|
$listPasskeys,
|
|
@@ -144,7 +176,5 @@ const passkeyClient = () => {
|
|
|
144
176
|
$ERROR_CODES: PASSKEY_ERROR_CODES
|
|
145
177
|
};
|
|
146
178
|
};
|
|
147
|
-
|
|
148
179
|
//#endregion
|
|
149
180
|
export { PASSKEY_ERROR_CODES, getPasskeyActions, passkeyClient };
|
|
150
|
-
//# sourceMappingURL=client.mjs.map
|