@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 CHANGED
@@ -1,4 +1,5 @@
1
- import { a as WebAuthnChallengeValue, i as PasskeyOptions, n as PASSKEY_ERROR_CODES, r as Passkey, t as passkey } from "./index-B6ZC0I-g.mjs";
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: better_auth0.RawError<"AUTH_CANCELLED">;
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
- data: null;
83
- error: {
84
- code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED";
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 | better_auth0.RawError<"UNKNOWN_ERROR">;
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: better_auth0.RawError<"AUTH_CANCELLED">;
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
- data: null;
182
- error: {
183
- code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED";
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 | better_auth0.RawError<"UNKNOWN_ERROR">;
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 { t as PASSKEY_ERROR_CODES } from "./error-codes-DJf-1Ecu.mjs";
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: await startAuthentication({
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: options.data,
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: res,
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