@supabase/auth-js 2.73.0-rc.3 → 2.73.0-rc.6

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.
Files changed (66) hide show
  1. package/README.md +28 -1
  2. package/dist/main/GoTrueClient.d.ts +1 -1
  3. package/dist/main/GoTrueClient.d.ts.map +1 -1
  4. package/dist/main/GoTrueClient.js +43 -15
  5. package/dist/main/GoTrueClient.js.map +1 -1
  6. package/dist/main/lib/base64url.d.ts +3 -2
  7. package/dist/main/lib/base64url.d.ts.map +1 -1
  8. package/dist/main/lib/base64url.js.map +1 -1
  9. package/dist/main/lib/helpers.d.ts +2 -1
  10. package/dist/main/lib/helpers.d.ts.map +1 -1
  11. package/dist/main/lib/helpers.js.map +1 -1
  12. package/dist/main/lib/types.d.ts +140 -19
  13. package/dist/main/lib/types.d.ts.map +1 -1
  14. package/dist/main/lib/types.js +3 -2
  15. package/dist/main/lib/types.js.map +1 -1
  16. package/dist/main/lib/version.d.ts +1 -1
  17. package/dist/main/lib/version.js +1 -1
  18. package/dist/main/lib/webauthn.d.ts +274 -0
  19. package/dist/main/lib/webauthn.d.ts.map +1 -0
  20. package/dist/main/lib/webauthn.dom.d.ts +583 -0
  21. package/dist/main/lib/webauthn.dom.d.ts.map +1 -0
  22. package/dist/main/lib/webauthn.dom.js +4 -0
  23. package/dist/main/lib/webauthn.dom.js.map +1 -0
  24. package/dist/main/lib/webauthn.errors.d.ts +80 -0
  25. package/dist/main/lib/webauthn.errors.d.ts.map +1 -0
  26. package/dist/main/lib/webauthn.errors.js +265 -0
  27. package/dist/main/lib/webauthn.errors.js.map +1 -0
  28. package/dist/main/lib/webauthn.js +702 -0
  29. package/dist/main/lib/webauthn.js.map +1 -0
  30. package/dist/module/GoTrueClient.d.ts +1 -1
  31. package/dist/module/GoTrueClient.d.ts.map +1 -1
  32. package/dist/module/GoTrueClient.js +49 -21
  33. package/dist/module/GoTrueClient.js.map +1 -1
  34. package/dist/module/lib/base64url.d.ts +3 -2
  35. package/dist/module/lib/base64url.d.ts.map +1 -1
  36. package/dist/module/lib/base64url.js.map +1 -1
  37. package/dist/module/lib/helpers.d.ts +2 -1
  38. package/dist/module/lib/helpers.d.ts.map +1 -1
  39. package/dist/module/lib/helpers.js.map +1 -1
  40. package/dist/module/lib/types.d.ts +140 -19
  41. package/dist/module/lib/types.d.ts.map +1 -1
  42. package/dist/module/lib/types.js +2 -1
  43. package/dist/module/lib/types.js.map +1 -1
  44. package/dist/module/lib/version.d.ts +1 -1
  45. package/dist/module/lib/version.js +1 -1
  46. package/dist/module/lib/webauthn.d.ts +274 -0
  47. package/dist/module/lib/webauthn.d.ts.map +1 -0
  48. package/dist/module/lib/webauthn.dom.d.ts +583 -0
  49. package/dist/module/lib/webauthn.dom.d.ts.map +1 -0
  50. package/dist/module/lib/webauthn.dom.js +3 -0
  51. package/dist/module/lib/webauthn.dom.js.map +1 -0
  52. package/dist/module/lib/webauthn.errors.d.ts +80 -0
  53. package/dist/module/lib/webauthn.errors.d.ts.map +1 -0
  54. package/dist/module/lib/webauthn.errors.js +257 -0
  55. package/dist/module/lib/webauthn.errors.js.map +1 -0
  56. package/dist/module/lib/webauthn.js +685 -0
  57. package/dist/module/lib/webauthn.js.map +1 -0
  58. package/package.json +1 -1
  59. package/src/GoTrueClient.ts +198 -68
  60. package/src/lib/base64url.ts +4 -2
  61. package/src/lib/helpers.ts +2 -1
  62. package/src/lib/types.ts +205 -26
  63. package/src/lib/version.ts +1 -1
  64. package/src/lib/webauthn.dom.ts +636 -0
  65. package/src/lib/webauthn.errors.ts +317 -0
  66. package/src/lib/webauthn.ts +929 -0
@@ -0,0 +1,317 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+
3
+ import { StrictOmit } from './types'
4
+ import { isValidDomain } from './webauthn'
5
+ import {
6
+ PublicKeyCredentialCreationOptionsFuture,
7
+ PublicKeyCredentialRequestOptionsFuture,
8
+ } from './webauthn.dom'
9
+
10
+ /**
11
+ * A custom Error used to return a more nuanced error detailing _why_ one of the eight documented
12
+ * errors in the spec was raised after calling `navigator.credentials.create()` or
13
+ * `navigator.credentials.get()`:
14
+ *
15
+ * - `AbortError`
16
+ * - `ConstraintError`
17
+ * - `InvalidStateError`
18
+ * - `NotAllowedError`
19
+ * - `NotSupportedError`
20
+ * - `SecurityError`
21
+ * - `TypeError`
22
+ * - `UnknownError`
23
+ *
24
+ * Error messages were determined through investigation of the spec to determine under which
25
+ * scenarios a given error would be raised.
26
+ */
27
+ export class WebAuthnError extends Error {
28
+ code: WebAuthnErrorCode
29
+
30
+ protected __isWebAuthnError = true
31
+
32
+ constructor({
33
+ message,
34
+ code,
35
+ cause,
36
+ name,
37
+ }: {
38
+ message: string
39
+ code: WebAuthnErrorCode
40
+ cause?: Error | unknown
41
+ name?: string
42
+ }) {
43
+ // @ts-ignore: help Rollup understand that `cause` is okay to set
44
+ super(message, { cause })
45
+ this.name = name ?? (cause instanceof Error ? cause.name : undefined) ?? 'Unknown Error'
46
+ this.code = code
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Error class for unknown WebAuthn errors.
52
+ * Wraps unexpected errors that don't match known WebAuthn error conditions.
53
+ */
54
+ export class WebAuthnUnknownError extends WebAuthnError {
55
+ originalError: unknown
56
+
57
+ constructor(message: string, originalError: unknown) {
58
+ super({
59
+ code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',
60
+ cause: originalError,
61
+ message,
62
+ })
63
+ this.name = 'WebAuthnUnknownError'
64
+ this.originalError = originalError
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Type guard to check if an error is a WebAuthnError.
70
+ * @param {unknown} error - The error to check
71
+ * @returns {boolean} True if the error is a WebAuthnError
72
+ */
73
+ export function isWebAuthnError(error: unknown): error is WebAuthnError {
74
+ return typeof error === 'object' && error !== null && '__isWebAuthnError' in error
75
+ }
76
+
77
+ /**
78
+ * Error codes for WebAuthn operations.
79
+ * These codes provide specific information about why a WebAuthn ceremony failed.
80
+ * @see {@link https://w3c.github.io/webauthn/#sctn-defined-errors W3C WebAuthn Spec - Defined Errors}
81
+ */
82
+ export type WebAuthnErrorCode =
83
+ | 'ERROR_CEREMONY_ABORTED'
84
+ | 'ERROR_INVALID_DOMAIN'
85
+ | 'ERROR_INVALID_RP_ID'
86
+ | 'ERROR_INVALID_USER_ID_LENGTH'
87
+ | 'ERROR_MALFORMED_PUBKEYCREDPARAMS'
88
+ | 'ERROR_AUTHENTICATOR_GENERAL_ERROR'
89
+ | 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT'
90
+ | 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT'
91
+ | 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED'
92
+ | 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG'
93
+ | 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE'
94
+ | 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY'
95
+
96
+ /**
97
+ * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.create()`.
98
+ * Maps browser errors to specific WebAuthn error codes for better debugging.
99
+ * @param {Object} params - Error identification parameters
100
+ * @param {Error} params.error - The error thrown by the browser
101
+ * @param {CredentialCreationOptions} params.options - The options passed to credentials.create()
102
+ * @returns {WebAuthnError} A WebAuthnError with a specific error code
103
+ * @see {@link https://w3c.github.io/webauthn/#sctn-createCredential W3C WebAuthn Spec - Create Credential}
104
+ */
105
+ export function identifyRegistrationError({
106
+ error,
107
+ options,
108
+ }: {
109
+ error: Error
110
+ options: StrictOmit<CredentialCreationOptions, 'publicKey'> & {
111
+ publicKey: PublicKeyCredentialCreationOptionsFuture
112
+ }
113
+ }): WebAuthnError {
114
+ const { publicKey } = options
115
+
116
+ if (!publicKey) {
117
+ throw Error('options was missing required publicKey property')
118
+ }
119
+
120
+ if (error.name === 'AbortError') {
121
+ if (options.signal instanceof AbortSignal) {
122
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16)
123
+ return new WebAuthnError({
124
+ message: 'Registration ceremony was sent an abort signal',
125
+ code: 'ERROR_CEREMONY_ABORTED',
126
+ cause: error,
127
+ })
128
+ }
129
+ } else if (error.name === 'ConstraintError') {
130
+ if (publicKey.authenticatorSelection?.requireResidentKey === true) {
131
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 4)
132
+ return new WebAuthnError({
133
+ message:
134
+ 'Discoverable credentials were required but no available authenticator supported it',
135
+ code: 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT',
136
+ cause: error,
137
+ })
138
+ } else if (
139
+ // @ts-ignore: `mediation` doesn't yet exist on CredentialCreationOptions but it's possible as of Sept 2024
140
+ options.mediation === 'conditional' &&
141
+ publicKey.authenticatorSelection?.userVerification === 'required'
142
+ ) {
143
+ // https://w3c.github.io/webauthn/#sctn-createCredential (Step 22.4)
144
+ return new WebAuthnError({
145
+ message:
146
+ 'User verification was required during automatic registration but it could not be performed',
147
+ code: 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE',
148
+ cause: error,
149
+ })
150
+ } else if (publicKey.authenticatorSelection?.userVerification === 'required') {
151
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 5)
152
+ return new WebAuthnError({
153
+ message: 'User verification was required but no available authenticator supported it',
154
+ code: 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT',
155
+ cause: error,
156
+ })
157
+ }
158
+ } else if (error.name === 'InvalidStateError') {
159
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 20)
160
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 3)
161
+ return new WebAuthnError({
162
+ message: 'The authenticator was previously registered',
163
+ code: 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED',
164
+ cause: error,
165
+ })
166
+ } else if (error.name === 'NotAllowedError') {
167
+ /**
168
+ * Pass the error directly through. Platforms are overloading this error beyond what the spec
169
+ * defines and we don't want to overwrite potentially useful error messages.
170
+ */
171
+ return new WebAuthnError({
172
+ message: error.message,
173
+ code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',
174
+ cause: error,
175
+ })
176
+ } else if (error.name === 'NotSupportedError') {
177
+ const validPubKeyCredParams = publicKey.pubKeyCredParams.filter(
178
+ (param) => param.type === 'public-key'
179
+ )
180
+
181
+ if (validPubKeyCredParams.length === 0) {
182
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 10)
183
+ return new WebAuthnError({
184
+ message: 'No entry in pubKeyCredParams was of type "public-key"',
185
+ code: 'ERROR_MALFORMED_PUBKEYCREDPARAMS',
186
+ cause: error,
187
+ })
188
+ }
189
+
190
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 2)
191
+ return new WebAuthnError({
192
+ message:
193
+ 'No available authenticator supported any of the specified pubKeyCredParams algorithms',
194
+ code: 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG',
195
+ cause: error,
196
+ })
197
+ } else if (error.name === 'SecurityError') {
198
+ const effectiveDomain = window.location.hostname
199
+ if (!isValidDomain(effectiveDomain)) {
200
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 7)
201
+ return new WebAuthnError({
202
+ message: `${window.location.hostname} is an invalid domain`,
203
+ code: 'ERROR_INVALID_DOMAIN',
204
+ cause: error,
205
+ })
206
+ } else if (publicKey.rp.id !== effectiveDomain) {
207
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 8)
208
+ return new WebAuthnError({
209
+ message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`,
210
+ code: 'ERROR_INVALID_RP_ID',
211
+ cause: error,
212
+ })
213
+ }
214
+ } else if (error.name === 'TypeError') {
215
+ if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) {
216
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 5)
217
+ return new WebAuthnError({
218
+ message: 'User ID was not between 1 and 64 characters',
219
+ code: 'ERROR_INVALID_USER_ID_LENGTH',
220
+ cause: error,
221
+ })
222
+ }
223
+ } else if (error.name === 'UnknownError') {
224
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 1)
225
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 8)
226
+ return new WebAuthnError({
227
+ message:
228
+ 'The authenticator was unable to process the specified options, or could not create a new credential',
229
+ code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR',
230
+ cause: error,
231
+ })
232
+ }
233
+
234
+ return new WebAuthnError({
235
+ message: 'a Non-Webauthn related error has occurred',
236
+ code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',
237
+ cause: error,
238
+ })
239
+ }
240
+
241
+ /**
242
+ * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.get()`.
243
+ * Maps browser errors to specific WebAuthn error codes for better debugging.
244
+ * @param {Object} params - Error identification parameters
245
+ * @param {Error} params.error - The error thrown by the browser
246
+ * @param {CredentialRequestOptions} params.options - The options passed to credentials.get()
247
+ * @returns {WebAuthnError} A WebAuthnError with a specific error code
248
+ * @see {@link https://w3c.github.io/webauthn/#sctn-getAssertion W3C WebAuthn Spec - Get Assertion}
249
+ */
250
+ export function identifyAuthenticationError({
251
+ error,
252
+ options,
253
+ }: {
254
+ error: Error
255
+ options: StrictOmit<CredentialRequestOptions, 'publicKey'> & {
256
+ publicKey: PublicKeyCredentialRequestOptionsFuture
257
+ }
258
+ }): WebAuthnError {
259
+ const { publicKey } = options
260
+
261
+ if (!publicKey) {
262
+ throw Error('options was missing required publicKey property')
263
+ }
264
+
265
+ if (error.name === 'AbortError') {
266
+ if (options.signal instanceof AbortSignal) {
267
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16)
268
+ return new WebAuthnError({
269
+ message: 'Authentication ceremony was sent an abort signal',
270
+ code: 'ERROR_CEREMONY_ABORTED',
271
+ cause: error,
272
+ })
273
+ }
274
+ } else if (error.name === 'NotAllowedError') {
275
+ /**
276
+ * Pass the error directly through. Platforms are overloading this error beyond what the spec
277
+ * defines and we don't want to overwrite potentially useful error messages.
278
+ */
279
+ return new WebAuthnError({
280
+ message: error.message,
281
+ code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',
282
+ cause: error,
283
+ })
284
+ } else if (error.name === 'SecurityError') {
285
+ const effectiveDomain = window.location.hostname
286
+ if (!isValidDomain(effectiveDomain)) {
287
+ // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 5)
288
+ return new WebAuthnError({
289
+ message: `${window.location.hostname} is an invalid domain`,
290
+ code: 'ERROR_INVALID_DOMAIN',
291
+ cause: error,
292
+ })
293
+ } else if (publicKey.rpId !== effectiveDomain) {
294
+ // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 6)
295
+ return new WebAuthnError({
296
+ message: `The RP ID "${publicKey.rpId}" is invalid for this domain`,
297
+ code: 'ERROR_INVALID_RP_ID',
298
+ cause: error,
299
+ })
300
+ }
301
+ } else if (error.name === 'UnknownError') {
302
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 1)
303
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 12)
304
+ return new WebAuthnError({
305
+ message:
306
+ 'The authenticator was unable to process the specified options, or could not create a new assertion signature',
307
+ code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR',
308
+ cause: error,
309
+ })
310
+ }
311
+
312
+ return new WebAuthnError({
313
+ message: 'a Non-Webauthn related error has occurred',
314
+ code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',
315
+ cause: error,
316
+ })
317
+ }