@oddington/sdk 0.1.11 → 0.1.12

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.
@@ -0,0 +1,3909 @@
1
+ function __rest(s, e) {
2
+ var t = {};
3
+ for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
4
+ if (s != null && typeof Object.getOwnPropertySymbols == "function")
5
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++)
6
+ e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
7
+ return t;
8
+ }
9
+
10
+ var version = "2.116.0";
11
+
12
+ var AUTO_REFRESH_TICK_DURATION_MS = 30 * 1e3, AUTO_REFRESH_TICK_THRESHOLD = 3, EXPIRY_MARGIN_MS = AUTO_REFRESH_TICK_THRESHOLD * AUTO_REFRESH_TICK_DURATION_MS, REFRESH_FAILURE_COOLDOWN_MS = 2 * AUTO_REFRESH_TICK_DURATION_MS, GOTRUE_URL = "http://localhost:9999", STORAGE_KEY = "supabase.auth.token";
13
+ var DEFAULT_HEADERS = { "X-Client-Info": `gotrue-js/${version}` };
14
+ var API_VERSION_HEADER_NAME = "X-Supabase-Api-Version", API_VERSIONS = {
15
+ "2024-01-01": {
16
+ timestamp: Date.parse("2024-01-01T00:00:00.0Z"),
17
+ name: "2024-01-01"
18
+ }
19
+ }, BASE64URL_REGEX = /^([a-z0-9_-]{4})*($|[a-z0-9_-]{3}$|[a-z0-9_-]{2}$)$/i, PKCE_FLOW_ID_PARAM = "sb_flow_id", PKCE_MAX_CONCURRENT_FLOWS = 5, JWKS_TTL = 600 * 1e3;
20
+
21
+ var AuthError = class extends Error {
22
+ constructor(message, status, code) {
23
+ super(message), this.__isAuthError = !0, this.name = "AuthError", this.status = status, this.code = code;
24
+ }
25
+ toJSON() {
26
+ return {
27
+ name: this.name,
28
+ message: this.message,
29
+ status: this.status,
30
+ code: this.code
31
+ };
32
+ }
33
+ };
34
+ function isAuthError(error) {
35
+ return typeof error == "object" && error !== null && "__isAuthError" in error;
36
+ }
37
+ var AuthApiError = class extends AuthError {
38
+ constructor(message, status, code) {
39
+ super(message, status, code), this.name = "AuthApiError", this.status = status, this.code = code;
40
+ }
41
+ };
42
+ function isAuthApiError(error) {
43
+ return isAuthError(error) && error.name === "AuthApiError";
44
+ }
45
+ var AuthUnknownError = class extends AuthError {
46
+ constructor(message, originalError) {
47
+ super(message), this.name = "AuthUnknownError", this.originalError = originalError;
48
+ }
49
+ }, CustomAuthError = class extends AuthError {
50
+ constructor(message, name, status, code) {
51
+ super(message, status, code), this.name = name, this.status = status;
52
+ }
53
+ }, AuthSessionMissingError = class extends CustomAuthError {
54
+ constructor() {
55
+ super("Auth session missing!", "AuthSessionMissingError", 400, void 0);
56
+ }
57
+ };
58
+ function isAuthSessionMissingError(error) {
59
+ return isAuthError(error) && error.name === "AuthSessionMissingError";
60
+ }
61
+ var AuthInvalidTokenResponseError = class extends CustomAuthError {
62
+ constructor() {
63
+ super("Auth session or user missing", "AuthInvalidTokenResponseError", 500, void 0);
64
+ }
65
+ }, AuthInvalidCredentialsError = class extends CustomAuthError {
66
+ constructor(message) {
67
+ super(message, "AuthInvalidCredentialsError", 400, void 0);
68
+ }
69
+ }, AuthImplicitGrantRedirectError = class extends CustomAuthError {
70
+ constructor(message, details = null) {
71
+ super(message, "AuthImplicitGrantRedirectError", 500, void 0), this.details = null, this.details = details;
72
+ }
73
+ toJSON() {
74
+ return Object.assign(Object.assign({}, super.toJSON()), { details: this.details });
75
+ }
76
+ };
77
+ function isAuthImplicitGrantRedirectError(error) {
78
+ return isAuthError(error) && error.name === "AuthImplicitGrantRedirectError";
79
+ }
80
+ var AuthPKCEGrantCodeExchangeError = class extends CustomAuthError {
81
+ constructor(message, details = null) {
82
+ super(message, "AuthPKCEGrantCodeExchangeError", 500, void 0), this.details = null, this.details = details;
83
+ }
84
+ toJSON() {
85
+ return Object.assign(Object.assign({}, super.toJSON()), { details: this.details });
86
+ }
87
+ }, AuthPKCECodeVerifierMissingError = class extends CustomAuthError {
88
+ constructor() {
89
+ super("PKCE code verifier not found in storage. This can happen if the auth flow was initiated in a different browser or device, or if the storage was cleared. For SSR frameworks (Next.js, SvelteKit, etc.), use @supabase/ssr on both the server and client to store the code verifier in cookies.", "AuthPKCECodeVerifierMissingError", 400, "pkce_code_verifier_not_found");
90
+ }
91
+ };
92
+ var AuthRetryableFetchError = class extends CustomAuthError {
93
+ constructor(message, status) {
94
+ super(message, "AuthRetryableFetchError", status, void 0);
95
+ }
96
+ };
97
+ function isAuthRetryableFetchError(error) {
98
+ return isAuthError(error) && error.name === "AuthRetryableFetchError";
99
+ }
100
+ var AuthRefreshDiscardedError = class extends CustomAuthError {
101
+ constructor(message = "Refresh result discarded: session state changed mid-flight (e.g., concurrent signOut)") {
102
+ super(message, "AuthRefreshDiscardedError", 409, void 0);
103
+ }
104
+ };
105
+ function isAuthRefreshDiscardedError(error) {
106
+ return isAuthError(error) && error.name === "AuthRefreshDiscardedError";
107
+ }
108
+ var AuthWeakPasswordError = class extends CustomAuthError {
109
+ constructor(message, status, reasons) {
110
+ super(message, "AuthWeakPasswordError", status, "weak_password"), this.reasons = reasons;
111
+ }
112
+ toJSON() {
113
+ return Object.assign(Object.assign({}, super.toJSON()), { reasons: this.reasons });
114
+ }
115
+ };
116
+ var AuthInvalidJwtError = class extends CustomAuthError {
117
+ constructor(message) {
118
+ super(message, "AuthInvalidJwtError", 400, "invalid_jwt");
119
+ }
120
+ };
121
+
122
+ var TO_BASE64URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".split(""), IGNORE_BASE64URL = `
123
+ \r=`.split(""), FROM_BASE64URL = (() => {
124
+ let charMap = new Array(128);
125
+ for (let i = 0; i < charMap.length; i += 1)
126
+ charMap[i] = -1;
127
+ for (let i = 0; i < IGNORE_BASE64URL.length; i += 1)
128
+ charMap[IGNORE_BASE64URL[i].charCodeAt(0)] = -2;
129
+ for (let i = 0; i < TO_BASE64URL.length; i += 1)
130
+ charMap[TO_BASE64URL[i].charCodeAt(0)] = i;
131
+ return charMap;
132
+ })();
133
+ function byteToBase64URL(byte, state, emit) {
134
+ if (byte !== null)
135
+ for (state.queue = state.queue << 8 | byte, state.queuedBits += 8; state.queuedBits >= 6; ) {
136
+ let pos = state.queue >> state.queuedBits - 6 & 63;
137
+ emit(TO_BASE64URL[pos]), state.queuedBits -= 6;
138
+ }
139
+ else if (state.queuedBits > 0)
140
+ for (state.queue = state.queue << 6 - state.queuedBits, state.queuedBits = 6; state.queuedBits >= 6; ) {
141
+ let pos = state.queue >> state.queuedBits - 6 & 63;
142
+ emit(TO_BASE64URL[pos]), state.queuedBits -= 6;
143
+ }
144
+ }
145
+ function byteFromBase64URL(charCode, state, emit) {
146
+ let bits = FROM_BASE64URL[charCode];
147
+ if (bits > -1)
148
+ for (state.queue = state.queue << 6 | bits, state.queuedBits += 6; state.queuedBits >= 8; )
149
+ emit(state.queue >> state.queuedBits - 8 & 255), state.queuedBits -= 8;
150
+ else {
151
+ if (bits === -2)
152
+ return;
153
+ throw new Error(`Invalid Base64-URL character "${String.fromCharCode(charCode)}"`);
154
+ }
155
+ }
156
+ function stringFromBase64URL(str) {
157
+ let conv = [], utf8Emit = (codepoint) => {
158
+ conv.push(String.fromCodePoint(codepoint));
159
+ }, utf8State = {
160
+ utf8seq: 0,
161
+ codepoint: 0
162
+ }, b64State = { queue: 0, queuedBits: 0 }, byteEmit = (byte) => {
163
+ stringFromUTF8(byte, utf8State, utf8Emit);
164
+ };
165
+ for (let i = 0; i < str.length; i += 1)
166
+ byteFromBase64URL(str.charCodeAt(i), b64State, byteEmit);
167
+ return conv.join("");
168
+ }
169
+ function codepointToUTF8(codepoint, emit) {
170
+ if (codepoint <= 127) {
171
+ emit(codepoint);
172
+ return;
173
+ } else if (codepoint <= 2047) {
174
+ emit(192 | codepoint >> 6), emit(128 | codepoint & 63);
175
+ return;
176
+ } else if (codepoint <= 65535) {
177
+ emit(224 | codepoint >> 12), emit(128 | codepoint >> 6 & 63), emit(128 | codepoint & 63);
178
+ return;
179
+ } else if (codepoint <= 1114111) {
180
+ emit(240 | codepoint >> 18), emit(128 | codepoint >> 12 & 63), emit(128 | codepoint >> 6 & 63), emit(128 | codepoint & 63);
181
+ return;
182
+ }
183
+ throw new Error(`Unrecognized Unicode codepoint: ${codepoint.toString(16)}`);
184
+ }
185
+ function stringToUTF8(str, emit) {
186
+ for (let i = 0; i < str.length; i += 1) {
187
+ let codepoint = str.charCodeAt(i);
188
+ if (codepoint > 55295 && codepoint <= 56319) {
189
+ let highSurrogate = (codepoint - 55296) * 1024 & 65535;
190
+ codepoint = (str.charCodeAt(i + 1) - 56320 & 65535 | highSurrogate) + 65536, i += 1;
191
+ }
192
+ codepointToUTF8(codepoint, emit);
193
+ }
194
+ }
195
+ function stringFromUTF8(byte, state, emit) {
196
+ if (state.utf8seq === 0) {
197
+ if (byte <= 127) {
198
+ emit(byte);
199
+ return;
200
+ }
201
+ for (let leadingBit = 1; leadingBit < 6; leadingBit += 1)
202
+ if ((byte >> 7 - leadingBit & 1) === 0) {
203
+ state.utf8seq = leadingBit;
204
+ break;
205
+ }
206
+ if (state.utf8seq === 2)
207
+ state.codepoint = byte & 31;
208
+ else if (state.utf8seq === 3)
209
+ state.codepoint = byte & 15;
210
+ else if (state.utf8seq === 4)
211
+ state.codepoint = byte & 7;
212
+ else
213
+ throw new Error("Invalid UTF-8 sequence");
214
+ state.utf8seq -= 1;
215
+ } else if (state.utf8seq > 0) {
216
+ if (byte <= 127)
217
+ throw new Error("Invalid UTF-8 sequence");
218
+ state.codepoint = state.codepoint << 6 | byte & 63, state.utf8seq -= 1, state.utf8seq === 0 && emit(state.codepoint);
219
+ }
220
+ }
221
+ function base64UrlToUint8Array(str) {
222
+ let result = [], state = { queue: 0, queuedBits: 0 }, onByte = (byte) => {
223
+ result.push(byte);
224
+ };
225
+ for (let i = 0; i < str.length; i += 1)
226
+ byteFromBase64URL(str.charCodeAt(i), state, onByte);
227
+ return new Uint8Array(result);
228
+ }
229
+ function stringToUint8Array(str) {
230
+ let result = [];
231
+ return stringToUTF8(str, (byte) => result.push(byte)), new Uint8Array(result);
232
+ }
233
+ function bytesToBase64URL(bytes) {
234
+ let result = [], state = { queue: 0, queuedBits: 0 }, onChar = (char) => {
235
+ result.push(char);
236
+ };
237
+ return bytes.forEach((byte) => byteToBase64URL(byte, state, onChar)), byteToBase64URL(null, state, onChar), result.join("");
238
+ }
239
+
240
+ function expiresAt(expiresIn) {
241
+ return Math.round(Date.now() / 1e3) + expiresIn;
242
+ }
243
+ function generateCallbackId() {
244
+ return /* @__PURE__ */ Symbol("auth-callback");
245
+ }
246
+ var isBrowser = () => typeof window < "u" && typeof document < "u", localStorageWriteTests = {
247
+ tested: !1,
248
+ writable: !1
249
+ }, supportsLocalStorage = () => {
250
+ if (!isBrowser())
251
+ return !1;
252
+ try {
253
+ if (typeof globalThis.localStorage != "object")
254
+ return !1;
255
+ } catch {
256
+ return !1;
257
+ }
258
+ if (localStorageWriteTests.tested)
259
+ return localStorageWriteTests.writable;
260
+ let randomKey = `lswt-${Math.random()}${Math.random()}`;
261
+ try {
262
+ globalThis.localStorage.setItem(randomKey, randomKey), globalThis.localStorage.removeItem(randomKey), localStorageWriteTests.tested = !0, localStorageWriteTests.writable = !0;
263
+ } catch {
264
+ localStorageWriteTests.tested = !0, localStorageWriteTests.writable = !1;
265
+ }
266
+ return localStorageWriteTests.writable;
267
+ };
268
+ function parseParametersFromURL(href) {
269
+ let result = {}, url = new URL(href);
270
+ if (url.hash && url.hash[0] === "#")
271
+ try {
272
+ new URLSearchParams(url.hash.substring(1)).forEach((value, key) => {
273
+ result[key] = value;
274
+ });
275
+ } catch {
276
+ }
277
+ return url.searchParams.forEach((value, key) => {
278
+ result[key] = value;
279
+ }), result;
280
+ }
281
+ var resolveFetch = (customFetch) => customFetch ? (...args) => customFetch(...args) : (...args) => fetch(...args), looksLikeFetchResponse = (maybeResponse) => typeof maybeResponse == "object" && maybeResponse !== null && "status" in maybeResponse && "ok" in maybeResponse && "json" in maybeResponse && typeof maybeResponse.json == "function", setItemAsync = async (storage, key, data) => {
282
+ await storage.setItem(key, JSON.stringify(data));
283
+ }, getItemAsync = async (storage, key) => {
284
+ let value = await storage.getItem(key);
285
+ if (!value)
286
+ return null;
287
+ try {
288
+ return JSON.parse(value);
289
+ } catch {
290
+ return null;
291
+ }
292
+ }, removeItemAsync = async (storage, key) => {
293
+ await storage.removeItem(key);
294
+ }, Deferred = class _Deferred {
295
+ constructor() {
296
+ this.promise = new _Deferred.promiseConstructor((res, rej) => {
297
+ this.resolve = res, this.reject = rej;
298
+ });
299
+ }
300
+ };
301
+ Deferred.promiseConstructor = Promise;
302
+ function decodeJWT(token) {
303
+ let parts = token.split(".");
304
+ if (parts.length !== 3)
305
+ throw new AuthInvalidJwtError("Invalid JWT structure");
306
+ for (let i = 0; i < parts.length; i++)
307
+ if (!BASE64URL_REGEX.test(parts[i]))
308
+ throw new AuthInvalidJwtError("JWT not in base64url format");
309
+ return {
310
+ // using base64url lib
311
+ header: JSON.parse(stringFromBase64URL(parts[0])),
312
+ payload: JSON.parse(stringFromBase64URL(parts[1])),
313
+ signature: base64UrlToUint8Array(parts[2]),
314
+ raw: {
315
+ header: parts[0],
316
+ payload: parts[1]
317
+ }
318
+ };
319
+ }
320
+ async function sleep(time) {
321
+ return await new Promise((accept) => {
322
+ setTimeout(() => accept(null), time);
323
+ });
324
+ }
325
+ function retryable(fn, isRetryable) {
326
+ return new Promise((accept, reject) => {
327
+ (async () => {
328
+ for (let attempt = 0; attempt < 1 / 0; attempt++)
329
+ try {
330
+ let result = await fn(attempt);
331
+ if (!isRetryable(attempt, null, result)) {
332
+ accept(result);
333
+ return;
334
+ }
335
+ } catch (e) {
336
+ if (!isRetryable(attempt, e)) {
337
+ reject(e);
338
+ return;
339
+ }
340
+ }
341
+ })();
342
+ });
343
+ }
344
+ function dec2hex(dec) {
345
+ return ("0" + dec.toString(16)).substr(-2);
346
+ }
347
+ function generatePKCEVerifier() {
348
+ let array = new Uint32Array(56);
349
+ if (typeof crypto > "u") {
350
+ let charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~", charSetLen = charSet.length, verifier = "";
351
+ for (let i = 0; i < 56; i++)
352
+ verifier += charSet.charAt(Math.floor(Math.random() * charSetLen));
353
+ return verifier;
354
+ }
355
+ return crypto.getRandomValues(array), Array.from(array, dec2hex).join("");
356
+ }
357
+ async function sha256(randomString) {
358
+ let encodedData = new TextEncoder().encode(randomString), hash = await crypto.subtle.digest("SHA-256", encodedData), bytes = new Uint8Array(hash);
359
+ return Array.from(bytes).map((c) => String.fromCharCode(c)).join("");
360
+ }
361
+ async function generatePKCEChallenge(verifier) {
362
+ if (!(typeof crypto < "u" && typeof crypto.subtle < "u" && typeof TextEncoder < "u"))
363
+ return console.warn("WebCrypto API is not supported. Code challenge method will default to use plain instead of sha256."), verifier;
364
+ let hashed = await sha256(verifier);
365
+ return btoa(hashed).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
366
+ }
367
+ var PKCE_FLOW_ID_PATTERN = /^[a-zA-Z0-9_-]{8,64}$/;
368
+ function validatePKCEFlowId(flowId) {
369
+ return typeof flowId == "string" && PKCE_FLOW_ID_PATTERN.test(flowId) ? flowId : null;
370
+ }
371
+ function generatePKCEFlowId() {
372
+ if (typeof crypto < "u" && typeof crypto.getRandomValues == "function") {
373
+ let bytes = new Uint8Array(16);
374
+ return crypto.getRandomValues(bytes), Array.from(bytes, dec2hex).join("");
375
+ }
376
+ let flowId = "";
377
+ for (let i = 0; i < 32; i++)
378
+ flowId += Math.floor(Math.random() * 16).toString(16);
379
+ return flowId;
380
+ }
381
+ var pkceVerifierSlotKey = (storageKey, flowId) => `${storageKey}-flow-${flowId}-code-verifier`, pkceFlowIndexKey = (storageKey) => `${storageKey}-flows-code-verifier`;
382
+ async function getPKCEFlowIndex(storage, storageKey) {
383
+ let index = await getItemAsync(storage, pkceFlowIndexKey(storageKey));
384
+ return Array.isArray(index) ? index.filter((id) => validatePKCEFlowId(id) !== null) : [];
385
+ }
386
+ async function storePKCEVerifier(storage, storageKey, flowId, verifier, onEvictFlow) {
387
+ await setItemAsync(storage, pkceVerifierSlotKey(storageKey, flowId), verifier);
388
+ let index = (await getPKCEFlowIndex(storage, storageKey)).filter((id) => id !== flowId);
389
+ for (index.push(flowId); index.length > PKCE_MAX_CONCURRENT_FLOWS; ) {
390
+ let evicted = index.shift();
391
+ await removeItemAsync(storage, pkceVerifierSlotKey(storageKey, evicted)), onEvictFlow?.(evicted);
392
+ }
393
+ await setItemAsync(storage, pkceFlowIndexKey(storageKey), index), await setItemAsync(storage, `${storageKey}-code-verifier`, verifier);
394
+ }
395
+ async function retrievePKCEVerifier(storage, storageKey, flowId) {
396
+ if (flowId) {
397
+ let verifier2 = await getItemAsync(storage, pkceVerifierSlotKey(storageKey, flowId));
398
+ return { verifier: typeof verifier2 == "string" ? verifier2 : null, flowId };
399
+ }
400
+ let verifier = await getItemAsync(storage, `${storageKey}-code-verifier`);
401
+ return { verifier: typeof verifier == "string" ? verifier : null, flowId: null };
402
+ }
403
+ async function removePKCEVerifier(storage, storageKey, flowId) {
404
+ let legacyKey = `${storageKey}-code-verifier`;
405
+ if (!flowId) {
406
+ await removeItemAsync(storage, legacyKey);
407
+ return;
408
+ }
409
+ let slotKey = pkceVerifierSlotKey(storageKey, flowId), slotValue = await getItemAsync(storage, slotKey);
410
+ await removeItemAsync(storage, slotKey);
411
+ let index = await getPKCEFlowIndex(storage, storageKey), remaining = index.filter((id) => id !== flowId);
412
+ remaining.length !== index.length && (remaining.length > 0 ? await setItemAsync(storage, pkceFlowIndexKey(storageKey), remaining) : await removeItemAsync(storage, pkceFlowIndexKey(storageKey))), slotValue != null && slotValue === await getItemAsync(storage, legacyKey) && await removeItemAsync(storage, legacyKey);
413
+ }
414
+ async function removeAllPKCEVerifiers(storage, storageKey) {
415
+ let index = await getPKCEFlowIndex(storage, storageKey);
416
+ for (let flowId of index)
417
+ await removeItemAsync(storage, pkceVerifierSlotKey(storageKey, flowId));
418
+ await removeItemAsync(storage, pkceFlowIndexKey(storageKey)), await removeItemAsync(storage, `${storageKey}-code-verifier`);
419
+ }
420
+ function appendFlowIdToRedirectTo(redirectTo, flowId) {
421
+ let hashIndex = redirectTo.indexOf("#"), base = hashIndex === -1 ? redirectTo : redirectTo.slice(0, hashIndex), fragment = hashIndex === -1 ? "" : redirectTo.slice(hashIndex), queryIndex = base.indexOf("?");
422
+ if (queryIndex !== -1) {
423
+ let path = base.slice(0, queryIndex), remaining = base.slice(queryIndex + 1).split("&").filter((pair) => pair !== "" && pair !== PKCE_FLOW_ID_PARAM && !pair.startsWith(`${PKCE_FLOW_ID_PARAM}=`));
424
+ base = remaining.length > 0 ? `${path}?${remaining.join("&")}` : path;
425
+ }
426
+ let separator = base.includes("?") ? "&" : "?";
427
+ return `${base}${separator}${PKCE_FLOW_ID_PARAM}=${encodeURIComponent(flowId)}${fragment}`;
428
+ }
429
+ async function getCodeChallengeAndMethod(storage, storageKey, isPasswordRecovery = !1, onEvictFlow) {
430
+ let codeVerifier = generatePKCEVerifier(), storedCodeVerifier = codeVerifier;
431
+ isPasswordRecovery && (storedCodeVerifier += "/recovery");
432
+ let flowId = generatePKCEFlowId();
433
+ await storePKCEVerifier(storage, storageKey, flowId, storedCodeVerifier, onEvictFlow);
434
+ let codeChallenge = await generatePKCEChallenge(codeVerifier);
435
+ return [codeChallenge, codeVerifier === codeChallenge ? "plain" : "s256", flowId];
436
+ }
437
+ var API_VERSION_REGEX = /^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[0-1])$/i;
438
+ function parseResponseAPIVersion(response) {
439
+ let apiVersion = response.headers.get(API_VERSION_HEADER_NAME);
440
+ if (!apiVersion || !apiVersion.match(API_VERSION_REGEX))
441
+ return null;
442
+ try {
443
+ return /* @__PURE__ */ new Date(`${apiVersion}T00:00:00.0Z`);
444
+ } catch {
445
+ return null;
446
+ }
447
+ }
448
+ function validateExp(exp) {
449
+ if (!exp)
450
+ throw new Error("Missing exp claim");
451
+ let timeNow = Math.floor(Date.now() / 1e3);
452
+ if (exp <= timeNow)
453
+ throw new Error("JWT has expired");
454
+ }
455
+ function getAlgorithm(alg) {
456
+ switch (alg) {
457
+ case "RS256":
458
+ return {
459
+ name: "RSASSA-PKCS1-v1_5",
460
+ hash: { name: "SHA-256" }
461
+ };
462
+ case "ES256":
463
+ return {
464
+ name: "ECDSA",
465
+ namedCurve: "P-256",
466
+ hash: { name: "SHA-256" }
467
+ };
468
+ default:
469
+ throw new Error("Invalid alg claim");
470
+ }
471
+ }
472
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
473
+ function validateUUID(str) {
474
+ if (!UUID_REGEX.test(str))
475
+ throw new Error("@supabase/auth-js: Expected parameter to be UUID but is not");
476
+ }
477
+ function assertPasskeyExperimentalEnabled(experimental) {
478
+ if (!experimental.passkey)
479
+ throw new Error("@supabase/auth-js: the passkey API is experimental and disabled by default. Enable it by passing `auth: { experimental: { passkey: true } }` to createClient (or to the GoTrueClient constructor).");
480
+ }
481
+ function assertRecoveryCodesExperimentalEnabled(experimental) {
482
+ if (!experimental.recoveryCodes)
483
+ throw new Error("@supabase/auth-js: the MFA recovery codes API is experimental and disabled by default. Enable it by passing `auth: { experimental: { recoveryCodes: true } }` to createClient (or to the GoTrueClient constructor).");
484
+ }
485
+ function userNotAvailableProxy() {
486
+ let proxyTarget = {};
487
+ return new Proxy(proxyTarget, {
488
+ get: (target, prop) => {
489
+ if (prop === "__isUserNotAvailableProxy")
490
+ return !0;
491
+ if (typeof prop == "symbol") {
492
+ let sProp = prop.toString();
493
+ if (sProp === "Symbol(Symbol.toPrimitive)" || sProp === "Symbol(Symbol.toStringTag)" || sProp === "Symbol(util.inspect.custom)")
494
+ return;
495
+ }
496
+ throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Accessing the "${prop}" property of the session object is not supported. Please use getUser() instead.`);
497
+ },
498
+ set: (_target, prop) => {
499
+ throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Setting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`);
500
+ },
501
+ deleteProperty: (_target, prop) => {
502
+ throw new Error(`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Deleting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`);
503
+ }
504
+ });
505
+ }
506
+ function insecureUserWarningProxy(user, suppressWarningRef) {
507
+ return new Proxy(user, {
508
+ get: (target, prop, receiver) => {
509
+ if (prop === "__isInsecureUserWarningProxy")
510
+ return !0;
511
+ if (typeof prop == "symbol") {
512
+ let sProp = prop.toString();
513
+ if (sProp === "Symbol(Symbol.toPrimitive)" || sProp === "Symbol(Symbol.toStringTag)" || sProp === "Symbol(util.inspect.custom)" || sProp === "Symbol(nodejs.util.inspect.custom)")
514
+ return Reflect.get(target, prop, receiver);
515
+ }
516
+ return !suppressWarningRef.value && typeof prop == "string" && (console.warn("Using the user object as returned from supabase.auth.getSession() or from some supabase.auth.onAuthStateChange() events could be insecure! This value comes directly from the storage medium (usually cookies on the server) and may not be authentic. Use supabase.auth.getUser() instead which authenticates the data by contacting the Supabase Auth server."), suppressWarningRef.value = !0), Reflect.get(target, prop, receiver);
517
+ }
518
+ });
519
+ }
520
+ function deepClone(obj) {
521
+ return JSON.parse(JSON.stringify(obj));
522
+ }
523
+
524
+ var _getErrorMessage = (err) => {
525
+ if (typeof err == "object" && err !== null) {
526
+ let e = err;
527
+ if (typeof e.msg == "string")
528
+ return e.msg;
529
+ if (typeof e.message == "string")
530
+ return e.message;
531
+ if (typeof e.error_description == "string")
532
+ return e.error_description;
533
+ if (typeof e.error == "string")
534
+ return e.error;
535
+ }
536
+ return JSON.stringify(err);
537
+ }, NETWORK_ERROR_CODES = [
538
+ 500,
539
+ 501,
540
+ 502,
541
+ 503,
542
+ 504,
543
+ 520,
544
+ 521,
545
+ 522,
546
+ 523,
547
+ 524,
548
+ 525,
549
+ 526,
550
+ 527,
551
+ 528,
552
+ 529,
553
+ 530
554
+ ];
555
+ async function handleError(error) {
556
+ var _a;
557
+ if (!looksLikeFetchResponse(error))
558
+ throw new AuthRetryableFetchError(_getErrorMessage(error), 0);
559
+ let data;
560
+ try {
561
+ data = await error.json();
562
+ } catch (e) {
563
+ throw NETWORK_ERROR_CODES.includes(error.status) ? new AuthRetryableFetchError(error.statusText || `HTTP ${error.status}`, error.status) : new AuthUnknownError(_getErrorMessage(e), e);
564
+ }
565
+ if (NETWORK_ERROR_CODES.includes(error.status))
566
+ throw new AuthRetryableFetchError(_getErrorMessage(data), error.status);
567
+ let errorCode, responseAPIVersion = parseResponseAPIVersion(error);
568
+ if (responseAPIVersion && responseAPIVersion.getTime() >= API_VERSIONS["2024-01-01"].timestamp && typeof data == "object" && data && typeof data.code == "string" ? errorCode = data.code : typeof data == "object" && data && typeof data.error_code == "string" && (errorCode = data.error_code), errorCode) {
569
+ if (errorCode === "weak_password")
570
+ throw new AuthWeakPasswordError(_getErrorMessage(data), error.status, ((_a = data.weak_password) === null || _a === void 0 ? void 0 : _a.reasons) || []);
571
+ if (errorCode === "session_not_found")
572
+ throw new AuthSessionMissingError();
573
+ } else if (typeof data == "object" && data && typeof data.weak_password == "object" && data.weak_password && Array.isArray(data.weak_password.reasons) && data.weak_password.reasons.length && data.weak_password.reasons.reduce((a, i) => a && typeof i == "string", !0))
574
+ throw new AuthWeakPasswordError(_getErrorMessage(data), error.status, data.weak_password.reasons);
575
+ throw new AuthApiError(_getErrorMessage(data), error.status || 500, errorCode);
576
+ }
577
+ var _getRequestParams = (method, options, parameters, body) => {
578
+ let params = { method, headers: options?.headers || {} };
579
+ return method === "GET" ? params : (params.headers = Object.assign({ "Content-Type": "application/json;charset=UTF-8" }, options?.headers), params.body = JSON.stringify(body), Object.assign(Object.assign({}, params), parameters));
580
+ };
581
+ async function _request(fetcher, method, url, options) {
582
+ var _a;
583
+ let headers = Object.assign({}, options?.headers);
584
+ headers[API_VERSION_HEADER_NAME] || (headers[API_VERSION_HEADER_NAME] = API_VERSIONS["2024-01-01"].name), options?.jwt && (headers.Authorization = `Bearer ${options.jwt}`);
585
+ let qs = (_a = options?.query) !== null && _a !== void 0 ? _a : {};
586
+ options?.redirectTo && (qs.redirect_to = options.redirectTo);
587
+ let queryString = Object.keys(qs).length ? "?" + new URLSearchParams(qs).toString() : "", data = await _handleRequest(fetcher, method, url + queryString, {
588
+ headers,
589
+ noResolveJson: options?.noResolveJson
590
+ }, {}, options?.body);
591
+ return options?.xform ? options?.xform(data) : { data: Object.assign({}, data), error: null };
592
+ }
593
+ async function _handleRequest(fetcher, method, url, options, parameters, body) {
594
+ let requestParams = _getRequestParams(method, options, parameters, body), result;
595
+ try {
596
+ result = await fetcher(url, Object.assign({}, requestParams));
597
+ } catch (e) {
598
+ throw new AuthRetryableFetchError(_getErrorMessage(e), 0);
599
+ }
600
+ if (result.ok || await handleError(result), options?.noResolveJson)
601
+ return result;
602
+ try {
603
+ return await result.json();
604
+ } catch (e) {
605
+ await handleError(e);
606
+ }
607
+ }
608
+ function _sessionResponse(data) {
609
+ var _a;
610
+ let session = null;
611
+ hasSession(data) && (session = Object.assign({}, data), data.expires_at || (session.expires_at = expiresAt(data.expires_in)));
612
+ let user = (_a = data.user) !== null && _a !== void 0 ? _a : typeof data?.id == "string" ? data : null;
613
+ return { data: { session, user }, error: null };
614
+ }
615
+ function _sessionResponsePassword(data) {
616
+ let response = _sessionResponse(data);
617
+ return !response.error && data.weak_password && typeof data.weak_password == "object" && Array.isArray(data.weak_password.reasons) && data.weak_password.reasons.length && data.weak_password.message && typeof data.weak_password.message == "string" && data.weak_password.reasons.reduce((a, i) => a && typeof i == "string", !0) && (response.data.weak_password = data.weak_password), response;
618
+ }
619
+ function _userResponse(data) {
620
+ var _a;
621
+ return { data: { user: (_a = data.user) !== null && _a !== void 0 ? _a : data }, error: null };
622
+ }
623
+ function _ssoResponse(data) {
624
+ return { data, error: null };
625
+ }
626
+ function _generateLinkResponse(data) {
627
+ let { action_link, email_otp, hashed_token, redirect_to, verification_type } = data, rest = __rest(data, ["action_link", "email_otp", "hashed_token", "redirect_to", "verification_type"]), properties = {
628
+ action_link,
629
+ email_otp,
630
+ hashed_token,
631
+ redirect_to,
632
+ verification_type
633
+ }, user = Object.assign({}, rest);
634
+ return {
635
+ data: {
636
+ properties,
637
+ user
638
+ },
639
+ error: null
640
+ };
641
+ }
642
+ function _noResolveJsonResponse(data) {
643
+ return data;
644
+ }
645
+ function hasSession(data) {
646
+ return !!data.access_token && !!data.refresh_token && !!data.expires_in;
647
+ }
648
+
649
+ var SIGN_OUT_SCOPES = ["global", "local", "others"];
650
+
651
+ var GoTrueAdminApi = class {
652
+ constructor({ url = "", headers = {}, fetch: fetch2, experimental }) {
653
+ this.url = url, this.headers = headers, this.fetch = resolveFetch(fetch2), this.experimental = experimental ?? {}, this.mfa = {
654
+ listFactors: this._listFactors.bind(this),
655
+ deleteFactor: this._deleteFactor.bind(this)
656
+ }, this.oauth = {
657
+ listClients: this._listOAuthClients.bind(this),
658
+ createClient: this._createOAuthClient.bind(this),
659
+ getClient: this._getOAuthClient.bind(this),
660
+ updateClient: this._updateOAuthClient.bind(this),
661
+ deleteClient: this._deleteOAuthClient.bind(this),
662
+ regenerateClientSecret: this._regenerateOAuthClientSecret.bind(this)
663
+ }, this.customProviders = {
664
+ listProviders: this._listCustomProviders.bind(this),
665
+ createProvider: this._createCustomProvider.bind(this),
666
+ getProvider: this._getCustomProvider.bind(this),
667
+ updateProvider: this._updateCustomProvider.bind(this),
668
+ deleteProvider: this._deleteCustomProvider.bind(this)
669
+ }, this.passkey = {
670
+ listPasskeys: this._adminListPasskeys.bind(this),
671
+ deletePasskey: this._adminDeletePasskey.bind(this)
672
+ };
673
+ }
674
+ async signOut(jwt, scope = SIGN_OUT_SCOPES[0]) {
675
+ if (SIGN_OUT_SCOPES.indexOf(scope) < 0)
676
+ throw new Error(`@supabase/auth-js: Parameter scope must be one of ${SIGN_OUT_SCOPES.join(", ")}`);
677
+ try {
678
+ return await _request(this.fetch, "POST", `${this.url}/logout?scope=${scope}`, {
679
+ headers: this.headers,
680
+ jwt,
681
+ noResolveJson: !0
682
+ }), { data: null, error: null };
683
+ } catch (error) {
684
+ if (isAuthError(error))
685
+ return { data: null, error };
686
+ throw error;
687
+ }
688
+ }
689
+ async inviteUserByEmail(email, options = {}) {
690
+ try {
691
+ return await _request(this.fetch, "POST", `${this.url}/invite`, {
692
+ body: { email, data: options.data },
693
+ headers: this.headers,
694
+ redirectTo: options.redirectTo,
695
+ xform: _userResponse
696
+ });
697
+ } catch (error) {
698
+ if (isAuthError(error))
699
+ return { data: { user: null }, error };
700
+ throw error;
701
+ }
702
+ }
703
+ async generateLink(params) {
704
+ try {
705
+ let { options } = params, rest = __rest(params, ["options"]), body = Object.assign(Object.assign({}, rest), options);
706
+ return "newEmail" in rest && (body.new_email = rest?.newEmail, delete body.newEmail), await _request(this.fetch, "POST", `${this.url}/admin/generate_link`, {
707
+ body,
708
+ headers: this.headers,
709
+ xform: _generateLinkResponse,
710
+ redirectTo: options?.redirectTo
711
+ });
712
+ } catch (error) {
713
+ if (isAuthError(error))
714
+ return {
715
+ data: {
716
+ properties: null,
717
+ user: null
718
+ },
719
+ error
720
+ };
721
+ throw error;
722
+ }
723
+ }
724
+ // User Admin API
725
+ async createUser(attributes) {
726
+ try {
727
+ return await _request(this.fetch, "POST", `${this.url}/admin/users`, {
728
+ body: attributes,
729
+ headers: this.headers,
730
+ xform: _userResponse
731
+ });
732
+ } catch (error) {
733
+ if (isAuthError(error))
734
+ return { data: { user: null }, error };
735
+ throw error;
736
+ }
737
+ }
738
+ async listUsers(params) {
739
+ var _a, _b, _c, _d, _e, _f, _g;
740
+ try {
741
+ let pagination = { nextPage: null, lastPage: 0, total: 0 }, response = await _request(this.fetch, "GET", `${this.url}/admin/users`, {
742
+ headers: this.headers,
743
+ noResolveJson: !0,
744
+ query: {
745
+ page: (_b = (_a = params?.page) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "",
746
+ per_page: (_d = (_c = params?.perPage) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : ""
747
+ },
748
+ xform: _noResolveJsonResponse
749
+ });
750
+ if (response.error)
751
+ throw response.error;
752
+ let users = await response.json(), total = (_e = response.headers.get("x-total-count")) !== null && _e !== void 0 ? _e : 0, links = (_g = (_f = response.headers.get("link")) === null || _f === void 0 ? void 0 : _f.split(",")) !== null && _g !== void 0 ? _g : [];
753
+ return links.length > 0 && (links.forEach((link) => {
754
+ let page = parseInt(link.split(";")[0].split("=")[1].substring(0, 1)), rel = JSON.parse(link.split(";")[1].split("=")[1]);
755
+ pagination[`${rel}Page`] = page;
756
+ }), pagination.total = parseInt(total)), { data: Object.assign(Object.assign({}, users), pagination), error: null };
757
+ } catch (error) {
758
+ if (isAuthError(error))
759
+ return { data: { users: [] }, error };
760
+ throw error;
761
+ }
762
+ }
763
+ async getUserById(uid) {
764
+ validateUUID(uid);
765
+ try {
766
+ return await _request(this.fetch, "GET", `${this.url}/admin/users/${uid}`, {
767
+ headers: this.headers,
768
+ xform: _userResponse
769
+ });
770
+ } catch (error) {
771
+ if (isAuthError(error))
772
+ return { data: { user: null }, error };
773
+ throw error;
774
+ }
775
+ }
776
+ async updateUserById(uid, attributes) {
777
+ validateUUID(uid);
778
+ try {
779
+ return await _request(this.fetch, "PUT", `${this.url}/admin/users/${uid}`, {
780
+ body: attributes,
781
+ headers: this.headers,
782
+ xform: _userResponse
783
+ });
784
+ } catch (error) {
785
+ if (isAuthError(error))
786
+ return { data: { user: null }, error };
787
+ throw error;
788
+ }
789
+ }
790
+ async deleteUser(id, shouldSoftDelete = !1) {
791
+ validateUUID(id);
792
+ try {
793
+ return await _request(this.fetch, "DELETE", `${this.url}/admin/users/${id}`, {
794
+ headers: this.headers,
795
+ body: {
796
+ should_soft_delete: shouldSoftDelete
797
+ },
798
+ xform: _userResponse
799
+ });
800
+ } catch (error) {
801
+ if (isAuthError(error))
802
+ return { data: { user: null }, error };
803
+ throw error;
804
+ }
805
+ }
806
+ async _listFactors(params) {
807
+ validateUUID(params.userId);
808
+ try {
809
+ let { data, error } = await _request(this.fetch, "GET", `${this.url}/admin/users/${params.userId}/factors`, {
810
+ headers: this.headers,
811
+ xform: (factors) => ({ data: { factors }, error: null })
812
+ });
813
+ return { data, error };
814
+ } catch (error) {
815
+ if (isAuthError(error))
816
+ return { data: null, error };
817
+ throw error;
818
+ }
819
+ }
820
+ async _deleteFactor(params) {
821
+ validateUUID(params.userId), validateUUID(params.id);
822
+ try {
823
+ return { data: await _request(this.fetch, "DELETE", `${this.url}/admin/users/${params.userId}/factors/${params.id}`, {
824
+ headers: this.headers
825
+ }), error: null };
826
+ } catch (error) {
827
+ if (isAuthError(error))
828
+ return { data: null, error };
829
+ throw error;
830
+ }
831
+ }
832
+ async _listOAuthClients(params) {
833
+ var _a, _b, _c, _d, _e, _f, _g;
834
+ try {
835
+ let pagination = { nextPage: null, lastPage: 0, total: 0 }, response = await _request(this.fetch, "GET", `${this.url}/admin/oauth/clients`, {
836
+ headers: this.headers,
837
+ noResolveJson: !0,
838
+ query: {
839
+ page: (_b = (_a = params?.page) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "",
840
+ per_page: (_d = (_c = params?.perPage) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : ""
841
+ },
842
+ xform: _noResolveJsonResponse
843
+ });
844
+ if (response.error)
845
+ throw response.error;
846
+ let clients = await response.json(), total = (_e = response.headers.get("x-total-count")) !== null && _e !== void 0 ? _e : 0, links = (_g = (_f = response.headers.get("link")) === null || _f === void 0 ? void 0 : _f.split(",")) !== null && _g !== void 0 ? _g : [];
847
+ return links.length > 0 && (links.forEach((link) => {
848
+ let page = parseInt(link.split(";")[0].split("=")[1].substring(0, 1)), rel = JSON.parse(link.split(";")[1].split("=")[1]);
849
+ pagination[`${rel}Page`] = page;
850
+ }), pagination.total = parseInt(total)), { data: Object.assign(Object.assign({}, clients), pagination), error: null };
851
+ } catch (error) {
852
+ if (isAuthError(error))
853
+ return { data: { clients: [] }, error };
854
+ throw error;
855
+ }
856
+ }
857
+ async _createOAuthClient(params) {
858
+ try {
859
+ return await _request(this.fetch, "POST", `${this.url}/admin/oauth/clients`, {
860
+ body: params,
861
+ headers: this.headers,
862
+ xform: (client) => ({ data: client, error: null })
863
+ });
864
+ } catch (error) {
865
+ if (isAuthError(error))
866
+ return { data: null, error };
867
+ throw error;
868
+ }
869
+ }
870
+ async _getOAuthClient(clientId) {
871
+ try {
872
+ return await _request(this.fetch, "GET", `${this.url}/admin/oauth/clients/${clientId}`, {
873
+ headers: this.headers,
874
+ xform: (client) => ({ data: client, error: null })
875
+ });
876
+ } catch (error) {
877
+ if (isAuthError(error))
878
+ return { data: null, error };
879
+ throw error;
880
+ }
881
+ }
882
+ async _updateOAuthClient(clientId, params) {
883
+ try {
884
+ return await _request(this.fetch, "PUT", `${this.url}/admin/oauth/clients/${clientId}`, {
885
+ body: params,
886
+ headers: this.headers,
887
+ xform: (client) => ({ data: client, error: null })
888
+ });
889
+ } catch (error) {
890
+ if (isAuthError(error))
891
+ return { data: null, error };
892
+ throw error;
893
+ }
894
+ }
895
+ async _deleteOAuthClient(clientId) {
896
+ try {
897
+ return await _request(this.fetch, "DELETE", `${this.url}/admin/oauth/clients/${clientId}`, {
898
+ headers: this.headers,
899
+ noResolveJson: !0
900
+ }), { data: null, error: null };
901
+ } catch (error) {
902
+ if (isAuthError(error))
903
+ return { data: null, error };
904
+ throw error;
905
+ }
906
+ }
907
+ async _regenerateOAuthClientSecret(clientId) {
908
+ try {
909
+ return await _request(this.fetch, "POST", `${this.url}/admin/oauth/clients/${clientId}/regenerate_secret`, {
910
+ headers: this.headers,
911
+ xform: (client) => ({ data: client, error: null })
912
+ });
913
+ } catch (error) {
914
+ if (isAuthError(error))
915
+ return { data: null, error };
916
+ throw error;
917
+ }
918
+ }
919
+ async _listCustomProviders(params) {
920
+ try {
921
+ let query = {};
922
+ return params?.type && (query.type = params.type), await _request(this.fetch, "GET", `${this.url}/admin/custom-providers`, {
923
+ headers: this.headers,
924
+ query,
925
+ xform: (data) => {
926
+ var _a;
927
+ return { data: { providers: (_a = data?.providers) !== null && _a !== void 0 ? _a : [] }, error: null };
928
+ }
929
+ });
930
+ } catch (error) {
931
+ if (isAuthError(error))
932
+ return { data: { providers: [] }, error };
933
+ throw error;
934
+ }
935
+ }
936
+ async _createCustomProvider(params) {
937
+ try {
938
+ return await _request(this.fetch, "POST", `${this.url}/admin/custom-providers`, {
939
+ body: params,
940
+ headers: this.headers,
941
+ xform: (provider) => ({ data: provider, error: null })
942
+ });
943
+ } catch (error) {
944
+ if (isAuthError(error))
945
+ return { data: null, error };
946
+ throw error;
947
+ }
948
+ }
949
+ async _getCustomProvider(identifier) {
950
+ try {
951
+ return await _request(this.fetch, "GET", `${this.url}/admin/custom-providers/${identifier}`, {
952
+ headers: this.headers,
953
+ xform: (provider) => ({ data: provider, error: null })
954
+ });
955
+ } catch (error) {
956
+ if (isAuthError(error))
957
+ return { data: null, error };
958
+ throw error;
959
+ }
960
+ }
961
+ async _updateCustomProvider(identifier, params) {
962
+ try {
963
+ return await _request(this.fetch, "PUT", `${this.url}/admin/custom-providers/${identifier}`, {
964
+ body: params,
965
+ headers: this.headers,
966
+ xform: (provider) => ({ data: provider, error: null })
967
+ });
968
+ } catch (error) {
969
+ if (isAuthError(error))
970
+ return { data: null, error };
971
+ throw error;
972
+ }
973
+ }
974
+ async _deleteCustomProvider(identifier) {
975
+ try {
976
+ return await _request(this.fetch, "DELETE", `${this.url}/admin/custom-providers/${identifier}`, {
977
+ headers: this.headers,
978
+ noResolveJson: !0
979
+ }), { data: null, error: null };
980
+ } catch (error) {
981
+ if (isAuthError(error))
982
+ return { data: null, error };
983
+ throw error;
984
+ }
985
+ }
986
+ async _adminListPasskeys(params) {
987
+ assertPasskeyExperimentalEnabled(this.experimental), validateUUID(params.userId);
988
+ try {
989
+ return await _request(this.fetch, "GET", `${this.url}/admin/users/${params.userId}/passkeys`, { headers: this.headers, xform: (data) => ({ data, error: null }) });
990
+ } catch (error) {
991
+ if (isAuthError(error))
992
+ return { data: null, error };
993
+ throw error;
994
+ }
995
+ }
996
+ async _adminDeletePasskey(params) {
997
+ assertPasskeyExperimentalEnabled(this.experimental), validateUUID(params.userId), validateUUID(params.passkeyId);
998
+ try {
999
+ return await _request(this.fetch, "DELETE", `${this.url}/admin/users/${params.userId}/passkeys/${params.passkeyId}`, { headers: this.headers, noResolveJson: !0 }), { data: null, error: null };
1000
+ } catch (error) {
1001
+ if (isAuthError(error))
1002
+ return { data: null, error };
1003
+ throw error;
1004
+ }
1005
+ }
1006
+ };
1007
+
1008
+ function memoryLocalStorageAdapter(store = {}) {
1009
+ return {
1010
+ getItem: (key) => store[key] || null,
1011
+ setItem: (key, value) => {
1012
+ store[key] = value;
1013
+ },
1014
+ removeItem: (key) => {
1015
+ delete store[key];
1016
+ }
1017
+ };
1018
+ }
1019
+
1020
+ var internals = {
1021
+ debug: !!(globalThis && supportsLocalStorage() && globalThis.localStorage && globalThis.localStorage.getItem("supabase.gotrue-js.locks.debug") === "true")
1022
+ }, LockAcquireTimeoutError = class extends Error {
1023
+ constructor(message) {
1024
+ super(message), this.isAcquireTimeout = !0;
1025
+ }
1026
+ };
1027
+
1028
+ function polyfillGlobalThis() {
1029
+ if (typeof globalThis != "object")
1030
+ try {
1031
+ Object.defineProperty(Object.prototype, "__magic__", {
1032
+ get: function() {
1033
+ return this;
1034
+ },
1035
+ configurable: !0
1036
+ }), __magic__.globalThis = __magic__, delete Object.prototype.__magic__;
1037
+ } catch {
1038
+ typeof self < "u" && (self.globalThis = self);
1039
+ }
1040
+ }
1041
+
1042
+ function getAddress(address) {
1043
+ if (!/^0x[a-fA-F0-9]{40}$/.test(address))
1044
+ throw new Error(`@supabase/auth-js: Address "${address}" is invalid.`);
1045
+ return address.toLowerCase();
1046
+ }
1047
+ function fromHex(hex) {
1048
+ return parseInt(hex, 16);
1049
+ }
1050
+ function toHex(value) {
1051
+ let bytes = new TextEncoder().encode(value);
1052
+ return "0x" + Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
1053
+ }
1054
+ function createSiweMessage(parameters) {
1055
+ var _a;
1056
+ let { chainId, domain, expirationTime, issuedAt = /* @__PURE__ */ new Date(), nonce, notBefore, requestId, resources, scheme, uri, version: version2 } = parameters;
1057
+ {
1058
+ if (!Number.isInteger(chainId))
1059
+ throw new Error(`@supabase/auth-js: Invalid SIWE message field "chainId". Chain ID must be a EIP-155 chain ID. Provided value: ${chainId}`);
1060
+ if (!domain)
1061
+ throw new Error('@supabase/auth-js: Invalid SIWE message field "domain". Domain must be provided.');
1062
+ if (nonce && nonce.length < 8)
1063
+ throw new Error(`@supabase/auth-js: Invalid SIWE message field "nonce". Nonce must be at least 8 characters. Provided value: ${nonce}`);
1064
+ if (!uri)
1065
+ throw new Error('@supabase/auth-js: Invalid SIWE message field "uri". URI must be provided.');
1066
+ if (version2 !== "1")
1067
+ throw new Error(`@supabase/auth-js: Invalid SIWE message field "version". Version must be '1'. Provided value: ${version2}`);
1068
+ if (!((_a = parameters.statement) === null || _a === void 0) && _a.includes(`
1069
+ `))
1070
+ throw new Error(`@supabase/auth-js: Invalid SIWE message field "statement". Statement must not include '\\n'. Provided value: ${parameters.statement}`);
1071
+ }
1072
+ let address = getAddress(parameters.address), origin = scheme ? `${scheme}://${domain}` : domain, statement = parameters.statement ? `${parameters.statement}
1073
+ ` : "", prefix = `${origin} wants you to sign in with your Ethereum account:
1074
+ ${address}
1075
+
1076
+ ${statement}`, suffix = `URI: ${uri}
1077
+ Version: ${version2}
1078
+ Chain ID: ${chainId}${nonce ? `
1079
+ Nonce: ${nonce}` : ""}
1080
+ Issued At: ${issuedAt.toISOString()}`;
1081
+ if (expirationTime && (suffix += `
1082
+ Expiration Time: ${expirationTime.toISOString()}`), notBefore && (suffix += `
1083
+ Not Before: ${notBefore.toISOString()}`), requestId && (suffix += `
1084
+ Request ID: ${requestId}`), resources) {
1085
+ let content = `
1086
+ Resources:`;
1087
+ for (let resource of resources) {
1088
+ if (!resource || typeof resource != "string")
1089
+ throw new Error(`@supabase/auth-js: Invalid SIWE message field "resources". Every resource must be a valid string. Provided value: ${resource}`);
1090
+ content += `
1091
+ - ${resource}`;
1092
+ }
1093
+ suffix += content;
1094
+ }
1095
+ return `${prefix}
1096
+ ${suffix}`;
1097
+ }
1098
+
1099
+ var WebAuthnError = class extends Error {
1100
+ constructor({ message, code, cause, name }) {
1101
+ var _a;
1102
+ super(message, { cause }), this.__isWebAuthnError = !0, this.name = (_a = name ?? (cause instanceof Error ? cause.name : void 0)) !== null && _a !== void 0 ? _a : "Unknown Error", this.code = code;
1103
+ }
1104
+ toJSON() {
1105
+ return {
1106
+ name: this.name,
1107
+ message: this.message,
1108
+ code: this.code
1109
+ };
1110
+ }
1111
+ }, WebAuthnUnknownError = class extends WebAuthnError {
1112
+ constructor(message, originalError) {
1113
+ super({
1114
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
1115
+ cause: originalError,
1116
+ message
1117
+ }), this.name = "WebAuthnUnknownError", this.originalError = originalError;
1118
+ }
1119
+ };
1120
+ function identifyRegistrationError({ error, options }) {
1121
+ var _a, _b, _c;
1122
+ let { publicKey } = options;
1123
+ if (!publicKey)
1124
+ throw Error("options was missing required publicKey property");
1125
+ if (error.name === "AbortError") {
1126
+ if (options.signal instanceof AbortSignal)
1127
+ return new WebAuthnError({
1128
+ message: "Registration ceremony was sent an abort signal",
1129
+ code: "ERROR_CEREMONY_ABORTED",
1130
+ cause: error
1131
+ });
1132
+ } else if (error.name === "ConstraintError") {
1133
+ if (((_a = publicKey.authenticatorSelection) === null || _a === void 0 ? void 0 : _a.requireResidentKey) === !0)
1134
+ return new WebAuthnError({
1135
+ message: "Discoverable credentials were required but no available authenticator supported it",
1136
+ code: "ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",
1137
+ cause: error
1138
+ });
1139
+ if (
1140
+ // @ts-ignore: `mediation` doesn't yet exist on CredentialCreationOptions but it's possible as of Sept 2024
1141
+ options.mediation === "conditional" && ((_b = publicKey.authenticatorSelection) === null || _b === void 0 ? void 0 : _b.userVerification) === "required"
1142
+ )
1143
+ return new WebAuthnError({
1144
+ message: "User verification was required during automatic registration but it could not be performed",
1145
+ code: "ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",
1146
+ cause: error
1147
+ });
1148
+ if (((_c = publicKey.authenticatorSelection) === null || _c === void 0 ? void 0 : _c.userVerification) === "required")
1149
+ return new WebAuthnError({
1150
+ message: "User verification was required but no available authenticator supported it",
1151
+ code: "ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",
1152
+ cause: error
1153
+ });
1154
+ } else {
1155
+ if (error.name === "InvalidStateError")
1156
+ return new WebAuthnError({
1157
+ message: "The authenticator was previously registered",
1158
+ code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",
1159
+ cause: error
1160
+ });
1161
+ if (error.name === "NotAllowedError")
1162
+ return new WebAuthnError({
1163
+ message: error.message,
1164
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
1165
+ cause: error
1166
+ });
1167
+ if (error.name === "NotSupportedError")
1168
+ return publicKey.pubKeyCredParams.filter((param) => param.type === "public-key").length === 0 ? new WebAuthnError({
1169
+ message: 'No entry in pubKeyCredParams was of type "public-key"',
1170
+ code: "ERROR_MALFORMED_PUBKEYCREDPARAMS",
1171
+ cause: error
1172
+ }) : new WebAuthnError({
1173
+ message: "No available authenticator supported any of the specified pubKeyCredParams algorithms",
1174
+ code: "ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",
1175
+ cause: error
1176
+ });
1177
+ if (error.name === "SecurityError") {
1178
+ let effectiveDomain = window.location.hostname;
1179
+ if (isValidDomain(effectiveDomain)) {
1180
+ if (publicKey.rp.id !== effectiveDomain)
1181
+ return new WebAuthnError({
1182
+ message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`,
1183
+ code: "ERROR_INVALID_RP_ID",
1184
+ cause: error
1185
+ });
1186
+ } else return new WebAuthnError({
1187
+ message: `${window.location.hostname} is an invalid domain`,
1188
+ code: "ERROR_INVALID_DOMAIN",
1189
+ cause: error
1190
+ });
1191
+ } else if (error.name === "TypeError") {
1192
+ if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64)
1193
+ return new WebAuthnError({
1194
+ message: "User ID was not between 1 and 64 characters",
1195
+ code: "ERROR_INVALID_USER_ID_LENGTH",
1196
+ cause: error
1197
+ });
1198
+ } else if (error.name === "UnknownError")
1199
+ return new WebAuthnError({
1200
+ message: "The authenticator was unable to process the specified options, or could not create a new credential",
1201
+ code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
1202
+ cause: error
1203
+ });
1204
+ }
1205
+ return new WebAuthnError({
1206
+ message: "a Non-Webauthn related error has occurred",
1207
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
1208
+ cause: error
1209
+ });
1210
+ }
1211
+ function identifyAuthenticationError({ error, options }) {
1212
+ let { publicKey } = options;
1213
+ if (!publicKey)
1214
+ throw Error("options was missing required publicKey property");
1215
+ if (error.name === "AbortError") {
1216
+ if (options.signal instanceof AbortSignal)
1217
+ return new WebAuthnError({
1218
+ message: "Authentication ceremony was sent an abort signal",
1219
+ code: "ERROR_CEREMONY_ABORTED",
1220
+ cause: error
1221
+ });
1222
+ } else {
1223
+ if (error.name === "NotAllowedError")
1224
+ return new WebAuthnError({
1225
+ message: error.message,
1226
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
1227
+ cause: error
1228
+ });
1229
+ if (error.name === "SecurityError") {
1230
+ let effectiveDomain = window.location.hostname;
1231
+ if (isValidDomain(effectiveDomain)) {
1232
+ if (publicKey.rpId !== effectiveDomain)
1233
+ return new WebAuthnError({
1234
+ message: `The RP ID "${publicKey.rpId}" is invalid for this domain`,
1235
+ code: "ERROR_INVALID_RP_ID",
1236
+ cause: error
1237
+ });
1238
+ } else return new WebAuthnError({
1239
+ message: `${window.location.hostname} is an invalid domain`,
1240
+ code: "ERROR_INVALID_DOMAIN",
1241
+ cause: error
1242
+ });
1243
+ } else if (error.name === "UnknownError")
1244
+ return new WebAuthnError({
1245
+ message: "The authenticator was unable to process the specified options, or could not create a new assertion signature",
1246
+ code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
1247
+ cause: error
1248
+ });
1249
+ }
1250
+ return new WebAuthnError({
1251
+ message: "a Non-Webauthn related error has occurred",
1252
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
1253
+ cause: error
1254
+ });
1255
+ }
1256
+
1257
+ var WebAuthnAbortService = class {
1258
+ createNewAbortSignal() {
1259
+ if (this.controller) {
1260
+ let abortError = new Error("Cancelling existing WebAuthn API call for new one");
1261
+ abortError.name = "AbortError", this.controller.abort(abortError);
1262
+ }
1263
+ let newController = new AbortController();
1264
+ return this.controller = newController, newController.signal;
1265
+ }
1266
+ cancelCeremony() {
1267
+ if (this.controller) {
1268
+ let abortError = new Error("Manually cancelling existing WebAuthn API call");
1269
+ abortError.name = "AbortError", this.controller.abort(abortError), this.controller = void 0;
1270
+ }
1271
+ }
1272
+ }, webAuthnAbortService = new WebAuthnAbortService();
1273
+ function deserializeCredentialCreationOptions(options) {
1274
+ if (!options)
1275
+ throw new Error("Credential creation options are required");
1276
+ if (typeof PublicKeyCredential < "u" && "parseCreationOptionsFromJSON" in PublicKeyCredential && typeof PublicKeyCredential.parseCreationOptionsFromJSON == "function")
1277
+ return PublicKeyCredential.parseCreationOptionsFromJSON(
1278
+ /** we assert the options here as typescript still doesn't know about future webauthn types */
1279
+ options
1280
+ );
1281
+ let { challenge: challengeStr, user: userOpts, excludeCredentials } = options, restOptions = __rest(
1282
+ options,
1283
+ ["challenge", "user", "excludeCredentials"]
1284
+ ), challenge = base64UrlToUint8Array(challengeStr).buffer, user = Object.assign(Object.assign({}, userOpts), { id: base64UrlToUint8Array(userOpts.id).buffer }), result = Object.assign(Object.assign({}, restOptions), {
1285
+ challenge,
1286
+ user
1287
+ });
1288
+ if (excludeCredentials && excludeCredentials.length > 0) {
1289
+ result.excludeCredentials = new Array(excludeCredentials.length);
1290
+ for (let i = 0; i < excludeCredentials.length; i++) {
1291
+ let cred = excludeCredentials[i];
1292
+ result.excludeCredentials[i] = Object.assign(Object.assign({}, cred), {
1293
+ id: base64UrlToUint8Array(cred.id).buffer,
1294
+ type: cred.type || "public-key",
1295
+ // Cast transports to handle future transport types like "cable"
1296
+ transports: cred.transports
1297
+ });
1298
+ }
1299
+ }
1300
+ return result;
1301
+ }
1302
+ function deserializeCredentialRequestOptions(options) {
1303
+ if (!options)
1304
+ throw new Error("Credential request options are required");
1305
+ if (typeof PublicKeyCredential < "u" && "parseRequestOptionsFromJSON" in PublicKeyCredential && typeof PublicKeyCredential.parseRequestOptionsFromJSON == "function")
1306
+ return PublicKeyCredential.parseRequestOptionsFromJSON(options);
1307
+ let { challenge: challengeStr, allowCredentials } = options, restOptions = __rest(
1308
+ options,
1309
+ ["challenge", "allowCredentials"]
1310
+ ), challenge = base64UrlToUint8Array(challengeStr).buffer, result = Object.assign(Object.assign({}, restOptions), { challenge });
1311
+ if (allowCredentials && allowCredentials.length > 0) {
1312
+ result.allowCredentials = new Array(allowCredentials.length);
1313
+ for (let i = 0; i < allowCredentials.length; i++) {
1314
+ let cred = allowCredentials[i];
1315
+ result.allowCredentials[i] = Object.assign(Object.assign({}, cred), {
1316
+ id: base64UrlToUint8Array(cred.id).buffer,
1317
+ type: cred.type || "public-key",
1318
+ // Cast transports to handle future transport types like "cable"
1319
+ transports: cred.transports
1320
+ });
1321
+ }
1322
+ }
1323
+ return result;
1324
+ }
1325
+ function serializeCredentialCreationResponse(credential) {
1326
+ var _a;
1327
+ if ("toJSON" in credential && typeof credential.toJSON == "function")
1328
+ return credential.toJSON();
1329
+ let credentialWithAttachment = credential;
1330
+ return {
1331
+ id: credential.id,
1332
+ rawId: credential.id,
1333
+ response: {
1334
+ attestationObject: bytesToBase64URL(new Uint8Array(credential.response.attestationObject)),
1335
+ clientDataJSON: bytesToBase64URL(new Uint8Array(credential.response.clientDataJSON))
1336
+ },
1337
+ type: "public-key",
1338
+ clientExtensionResults: credential.getClientExtensionResults(),
1339
+ // Convert null to undefined and cast to AuthenticatorAttachment type
1340
+ authenticatorAttachment: (_a = credentialWithAttachment.authenticatorAttachment) !== null && _a !== void 0 ? _a : void 0
1341
+ };
1342
+ }
1343
+ function serializeCredentialRequestResponse(credential) {
1344
+ var _a;
1345
+ if ("toJSON" in credential && typeof credential.toJSON == "function")
1346
+ return credential.toJSON();
1347
+ let credentialWithAttachment = credential, clientExtensionResults = credential.getClientExtensionResults(), assertionResponse = credential.response;
1348
+ return {
1349
+ id: credential.id,
1350
+ rawId: credential.id,
1351
+ // W3C spec expects rawId to match id for JSON format
1352
+ response: {
1353
+ authenticatorData: bytesToBase64URL(new Uint8Array(assertionResponse.authenticatorData)),
1354
+ clientDataJSON: bytesToBase64URL(new Uint8Array(assertionResponse.clientDataJSON)),
1355
+ signature: bytesToBase64URL(new Uint8Array(assertionResponse.signature)),
1356
+ userHandle: assertionResponse.userHandle ? bytesToBase64URL(new Uint8Array(assertionResponse.userHandle)) : void 0
1357
+ },
1358
+ type: "public-key",
1359
+ clientExtensionResults,
1360
+ // Convert null to undefined and cast to AuthenticatorAttachment type
1361
+ authenticatorAttachment: (_a = credentialWithAttachment.authenticatorAttachment) !== null && _a !== void 0 ? _a : void 0
1362
+ };
1363
+ }
1364
+ function isValidDomain(hostname) {
1365
+ return (
1366
+ // Consider localhost valid as well since it's okay wrt Secure Contexts
1367
+ hostname === "localhost" || /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname)
1368
+ );
1369
+ }
1370
+ function browserSupportsWebAuthn() {
1371
+ var _a, _b;
1372
+ return !!(isBrowser() && "PublicKeyCredential" in window && window.PublicKeyCredential && "credentials" in navigator && typeof ((_a = navigator?.credentials) === null || _a === void 0 ? void 0 : _a.create) == "function" && typeof ((_b = navigator?.credentials) === null || _b === void 0 ? void 0 : _b.get) == "function");
1373
+ }
1374
+ async function createCredential(options) {
1375
+ try {
1376
+ let response = await navigator.credentials.create(
1377
+ /** we assert the type here until typescript types are updated */
1378
+ options
1379
+ );
1380
+ return response ? response instanceof PublicKeyCredential ? { data: response, error: null } : {
1381
+ data: null,
1382
+ error: new WebAuthnUnknownError("Browser returned unexpected credential type", response)
1383
+ } : {
1384
+ data: null,
1385
+ error: new WebAuthnUnknownError("Empty credential response", response)
1386
+ };
1387
+ } catch (err) {
1388
+ return {
1389
+ data: null,
1390
+ error: identifyRegistrationError({
1391
+ error: err,
1392
+ options
1393
+ })
1394
+ };
1395
+ }
1396
+ }
1397
+ async function getCredential(options) {
1398
+ try {
1399
+ let response = await navigator.credentials.get(
1400
+ /** we assert the type here until typescript types are updated */
1401
+ options
1402
+ );
1403
+ return response ? response instanceof PublicKeyCredential ? { data: response, error: null } : {
1404
+ data: null,
1405
+ error: new WebAuthnUnknownError("Browser returned unexpected credential type", response)
1406
+ } : {
1407
+ data: null,
1408
+ error: new WebAuthnUnknownError("Empty credential response", response)
1409
+ };
1410
+ } catch (err) {
1411
+ return {
1412
+ data: null,
1413
+ error: identifyAuthenticationError({
1414
+ error: err,
1415
+ options
1416
+ })
1417
+ };
1418
+ }
1419
+ }
1420
+ var DEFAULT_CREATION_OPTIONS = {
1421
+ hints: ["security-key"],
1422
+ authenticatorSelection: {
1423
+ authenticatorAttachment: "cross-platform",
1424
+ requireResidentKey: !1,
1425
+ /** set to preferred because older yubikeys don't have PIN/Biometric */
1426
+ userVerification: "preferred",
1427
+ residentKey: "discouraged"
1428
+ },
1429
+ attestation: "direct"
1430
+ }, DEFAULT_REQUEST_OPTIONS = {
1431
+ /** set to preferred because older yubikeys don't have PIN/Biometric */
1432
+ userVerification: "preferred",
1433
+ hints: ["security-key"],
1434
+ attestation: "direct"
1435
+ };
1436
+ function deepMerge(...sources) {
1437
+ let isObject = (val) => val !== null && typeof val == "object" && !Array.isArray(val), isArrayBufferLike = (val) => val instanceof ArrayBuffer || ArrayBuffer.isView(val), result = {};
1438
+ for (let source of sources)
1439
+ if (source)
1440
+ for (let key in source) {
1441
+ let value = source[key];
1442
+ if (value !== void 0)
1443
+ if (Array.isArray(value))
1444
+ result[key] = value;
1445
+ else if (isArrayBufferLike(value))
1446
+ result[key] = value;
1447
+ else if (isObject(value)) {
1448
+ let existing = result[key];
1449
+ isObject(existing) ? result[key] = deepMerge(existing, value) : result[key] = deepMerge(value);
1450
+ } else
1451
+ result[key] = value;
1452
+ }
1453
+ return result;
1454
+ }
1455
+ function mergeCredentialCreationOptions(baseOptions, overrides) {
1456
+ return deepMerge(DEFAULT_CREATION_OPTIONS, baseOptions, overrides || {});
1457
+ }
1458
+ function mergeCredentialRequestOptions(baseOptions, overrides) {
1459
+ return deepMerge(DEFAULT_REQUEST_OPTIONS, baseOptions, overrides || {});
1460
+ }
1461
+ var WebAuthnApi = class {
1462
+ constructor(client) {
1463
+ this.client = client, this.enroll = this._enroll.bind(this), this.challenge = this._challenge.bind(this), this.verify = this._verify.bind(this), this.authenticate = this._authenticate.bind(this), this.register = this._register.bind(this);
1464
+ }
1465
+ async _enroll(params) {
1466
+ return this.client.mfa.enroll(Object.assign(Object.assign({}, params), { factorType: "webauthn" }));
1467
+ }
1468
+ async _challenge({ factorId, webauthn, friendlyName, signal }, overrides) {
1469
+ var _a;
1470
+ try {
1471
+ let { data: challengeResponse, error: challengeError } = await this.client.mfa.challenge({
1472
+ factorId,
1473
+ webauthn
1474
+ });
1475
+ if (!challengeResponse)
1476
+ return { data: null, error: challengeError };
1477
+ let abortSignal = signal ?? webAuthnAbortService.createNewAbortSignal();
1478
+ if (challengeResponse.webauthn.type === "create") {
1479
+ let { user } = challengeResponse.webauthn.credential_options.publicKey;
1480
+ if (!user.name) {
1481
+ let nameToUse = friendlyName;
1482
+ if (nameToUse)
1483
+ user.name = `${user.id}:${nameToUse}`;
1484
+ else {
1485
+ let userData = (await this.client.getUser()).data.user, fallbackName = ((_a = userData?.user_metadata) === null || _a === void 0 ? void 0 : _a.name) || userData?.email || userData?.id || "User";
1486
+ user.name = `${user.id}:${fallbackName}`;
1487
+ }
1488
+ }
1489
+ user.displayName || (user.displayName = user.name);
1490
+ }
1491
+ switch (challengeResponse.webauthn.type) {
1492
+ case "create": {
1493
+ let options = mergeCredentialCreationOptions(challengeResponse.webauthn.credential_options.publicKey, overrides?.create), { data, error } = await createCredential({
1494
+ publicKey: options,
1495
+ signal: abortSignal
1496
+ });
1497
+ return data ? {
1498
+ data: {
1499
+ factorId,
1500
+ challengeId: challengeResponse.id,
1501
+ webauthn: {
1502
+ type: challengeResponse.webauthn.type,
1503
+ credential_response: data
1504
+ }
1505
+ },
1506
+ error: null
1507
+ } : { data: null, error };
1508
+ }
1509
+ case "request": {
1510
+ let options = mergeCredentialRequestOptions(challengeResponse.webauthn.credential_options.publicKey, overrides?.request), { data, error } = await getCredential(Object.assign(Object.assign({}, challengeResponse.webauthn.credential_options), { publicKey: options, signal: abortSignal }));
1511
+ return data ? {
1512
+ data: {
1513
+ factorId,
1514
+ challengeId: challengeResponse.id,
1515
+ webauthn: {
1516
+ type: challengeResponse.webauthn.type,
1517
+ credential_response: data
1518
+ }
1519
+ },
1520
+ error: null
1521
+ } : { data: null, error };
1522
+ }
1523
+ }
1524
+ } catch (error) {
1525
+ return isAuthError(error) ? { data: null, error } : {
1526
+ data: null,
1527
+ error: new AuthUnknownError("Unexpected error in challenge", error)
1528
+ };
1529
+ }
1530
+ }
1531
+ /**
1532
+ * Verify a WebAuthn credential with the server.
1533
+ * Completes the WebAuthn ceremony by sending the credential to the server for verification.
1534
+ *
1535
+ * @experimental This method is experimental and may change in future releases
1536
+ * @param {Object} params - Verification parameters
1537
+ * @param {string} params.challengeId - ID of the challenge being verified
1538
+ * @param {string} params.factorId - ID of the WebAuthn factor
1539
+ * @param {MFAVerifyWebauthnParams<T>['webauthn']} params.webauthn - WebAuthn credential response
1540
+ * @returns {Promise<AuthMFAVerifyResponse>} Verification result with session or error
1541
+ * @see {@link https://w3c.github.io/webauthn/#sctn-verifying-assertion W3C WebAuthn Spec - Verifying an Authentication Assertion}
1542
+ * */
1543
+ async _verify({ challengeId, factorId, webauthn }) {
1544
+ return this.client.mfa.verify({
1545
+ factorId,
1546
+ challengeId,
1547
+ webauthn
1548
+ });
1549
+ }
1550
+ async _authenticate({ factorId, webauthn: { rpId = typeof window < "u" ? window.location.hostname : void 0, rpOrigins = typeof window < "u" ? [window.location.origin] : void 0, signal } = {} }, overrides) {
1551
+ if (!rpId)
1552
+ return {
1553
+ data: null,
1554
+ error: new AuthError("rpId is required for WebAuthn authentication")
1555
+ };
1556
+ try {
1557
+ if (!browserSupportsWebAuthn())
1558
+ return {
1559
+ data: null,
1560
+ error: new AuthUnknownError("Browser does not support WebAuthn", null)
1561
+ };
1562
+ let { data: challengeResponse, error: challengeError } = await this.challenge({
1563
+ factorId,
1564
+ webauthn: { rpId, rpOrigins },
1565
+ signal
1566
+ }, { request: overrides });
1567
+ if (!challengeResponse)
1568
+ return { data: null, error: challengeError };
1569
+ let { webauthn } = challengeResponse;
1570
+ return this._verify({
1571
+ factorId,
1572
+ challengeId: challengeResponse.challengeId,
1573
+ webauthn: {
1574
+ type: webauthn.type,
1575
+ rpId,
1576
+ rpOrigins,
1577
+ credential_response: webauthn.credential_response
1578
+ }
1579
+ });
1580
+ } catch (error) {
1581
+ return isAuthError(error) ? { data: null, error } : {
1582
+ data: null,
1583
+ error: new AuthUnknownError("Unexpected error in authenticate", error)
1584
+ };
1585
+ }
1586
+ }
1587
+ async _register({ friendlyName, webauthn: { rpId = typeof window < "u" ? window.location.hostname : void 0, rpOrigins = typeof window < "u" ? [window.location.origin] : void 0, signal } = {} }, overrides) {
1588
+ if (!rpId)
1589
+ return {
1590
+ data: null,
1591
+ error: new AuthError("rpId is required for WebAuthn registration")
1592
+ };
1593
+ try {
1594
+ if (!browserSupportsWebAuthn())
1595
+ return {
1596
+ data: null,
1597
+ error: new AuthUnknownError("Browser does not support WebAuthn", null)
1598
+ };
1599
+ let { data: factor, error: enrollError } = await this._enroll({
1600
+ friendlyName
1601
+ });
1602
+ if (!factor)
1603
+ return await this.client.mfa.listFactors().then((factors) => {
1604
+ var _a;
1605
+ return (_a = factors.data) === null || _a === void 0 ? void 0 : _a.all.find((v) => v.factor_type === "webauthn" && v.friendly_name === friendlyName && v.status === "unverified");
1606
+ }).then((factor2) => factor2 ? this.client.mfa.unenroll({ factorId: factor2?.id }) : void 0), { data: null, error: enrollError };
1607
+ let { data: challengeResponse, error: challengeError } = await this._challenge({
1608
+ factorId: factor.id,
1609
+ friendlyName: factor.friendly_name,
1610
+ webauthn: { rpId, rpOrigins },
1611
+ signal
1612
+ }, {
1613
+ create: overrides
1614
+ });
1615
+ return challengeResponse ? this._verify({
1616
+ factorId: factor.id,
1617
+ challengeId: challengeResponse.challengeId,
1618
+ webauthn: {
1619
+ rpId,
1620
+ rpOrigins,
1621
+ type: challengeResponse.webauthn.type,
1622
+ credential_response: challengeResponse.webauthn.credential_response
1623
+ }
1624
+ }) : { data: null, error: challengeError };
1625
+ } catch (error) {
1626
+ return isAuthError(error) ? { data: null, error } : {
1627
+ data: null,
1628
+ error: new AuthUnknownError("Unexpected error in register", error)
1629
+ };
1630
+ }
1631
+ }
1632
+ };
1633
+
1634
+ polyfillGlobalThis();
1635
+ var DEFAULT_OPTIONS = {
1636
+ url: GOTRUE_URL,
1637
+ storageKey: STORAGE_KEY,
1638
+ autoRefreshToken: !0,
1639
+ persistSession: !0,
1640
+ detectSessionInUrl: !0,
1641
+ headers: DEFAULT_HEADERS,
1642
+ flowType: "implicit",
1643
+ debug: !1,
1644
+ hasCustomAuthorizationHeader: !1,
1645
+ throwOnError: !1,
1646
+ lockAcquireTimeout: 5e3,
1647
+ // 5 seconds. Only used when a custom `lock` is supplied. TODO(v3): remove.
1648
+ skipAutoInitialize: !1,
1649
+ experimental: {}
1650
+ };
1651
+ var GLOBAL_JWKS = {}, deprecatedLockWarned = !1, GoTrueClient = class _GoTrueClient {
1652
+ get jwks() {
1653
+ var _a, _b;
1654
+ return (_b = (_a = GLOBAL_JWKS[this.storageKey]) === null || _a === void 0 ? void 0 : _a.jwks) !== null && _b !== void 0 ? _b : { keys: [] };
1655
+ }
1656
+ set jwks(value) {
1657
+ GLOBAL_JWKS[this.storageKey] = Object.assign(Object.assign({}, GLOBAL_JWKS[this.storageKey]), { jwks: value });
1658
+ }
1659
+ get jwks_cached_at() {
1660
+ var _a, _b;
1661
+ return (_b = (_a = GLOBAL_JWKS[this.storageKey]) === null || _a === void 0 ? void 0 : _a.cachedAt) !== null && _b !== void 0 ? _b : Number.MIN_SAFE_INTEGER;
1662
+ }
1663
+ set jwks_cached_at(value) {
1664
+ GLOBAL_JWKS[this.storageKey] = Object.assign(Object.assign({}, GLOBAL_JWKS[this.storageKey]), { cachedAt: value });
1665
+ }
1666
+ constructor(options) {
1667
+ var _a, _b, _c;
1668
+ this.userStorage = null, this.memoryStorage = null, this.stateChangeEmitters = /* @__PURE__ */ new Map(), this.autoRefreshTicker = null, this.autoRefreshTickTimeout = null, this.visibilityChangedCallback = null, this.refreshingDeferred = null, this.lastRefreshFailure = null, this._sessionRemovalEpoch = 0, this.initializePromise = null, this._pendingInitNotifications = null, this.detectSessionInUrl = !0, this.hasCustomAuthorizationHeader = !1, this.suppressGetSessionWarning = !1, this.lock = null, this.lockAcquired = !1, this.pendingInLock = [], this.broadcastChannel = null, this.logger = console.log;
1669
+ let settings = Object.assign(Object.assign({}, DEFAULT_OPTIONS), options);
1670
+ if (this.storageKey = settings.storageKey, this.instanceID = (_a = _GoTrueClient.nextInstanceID[this.storageKey]) !== null && _a !== void 0 ? _a : 0, _GoTrueClient.nextInstanceID[this.storageKey] = this.instanceID + 1, this.logDebugMessages = !!settings.debug, typeof settings.debug == "function" && (this.logger = settings.debug), this.instanceID > 0 && isBrowser()) {
1671
+ let message = `${this._logPrefix()} Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.`;
1672
+ console.warn(message), this.logDebugMessages && console.trace(message);
1673
+ }
1674
+ if (this.persistSession = settings.persistSession, this.autoRefreshToken = settings.autoRefreshToken, this.experimental = (_b = settings.experimental) !== null && _b !== void 0 ? _b : {}, this.admin = new GoTrueAdminApi({
1675
+ url: settings.url,
1676
+ headers: settings.headers,
1677
+ fetch: settings.fetch,
1678
+ experimental: this.experimental
1679
+ }), this.url = settings.url, this.headers = settings.headers, this.fetch = resolveFetch(settings.fetch), this.detectSessionInUrl = settings.detectSessionInUrl, this.flowType = settings.flowType, this.hasCustomAuthorizationHeader = settings.hasCustomAuthorizationHeader, this.throwOnError = settings.throwOnError, this.lockAcquireTimeout = settings.lockAcquireTimeout, settings.lock != null && (this.lock = settings.lock, deprecatedLockWarned || (deprecatedLockWarned = !0, console.warn(`${this._logPrefix()} The "lock" option is deprecated and will be removed in v3. The client now coordinates session refreshes without a lock, so most apps can drop the option. See https://github.com/supabase/supabase-js/blob/master/packages/core/auth-js/migrations/lockless-coordination.md`))), this.jwks || (this.jwks = { keys: [] }, this.jwks_cached_at = Number.MIN_SAFE_INTEGER), this.mfa = {
1680
+ verify: this._verify.bind(this),
1681
+ enroll: this._enroll.bind(this),
1682
+ unenroll: this._unenroll.bind(this),
1683
+ challenge: this._challenge.bind(this),
1684
+ listFactors: this._listFactors.bind(this),
1685
+ challengeAndVerify: this._challengeAndVerify.bind(this),
1686
+ getAuthenticatorAssuranceLevel: this._getAuthenticatorAssuranceLevel.bind(this),
1687
+ webauthn: new WebAuthnApi(this),
1688
+ recoveryCodes: {
1689
+ getStatus: this._getRecoveryCodesStatus.bind(this),
1690
+ generate: this._generateRecoveryCodes.bind(this),
1691
+ verify: this._verifyRecoveryCode.bind(this),
1692
+ regenerate: this._regenerateRecoveryCodes.bind(this),
1693
+ unenroll: this._unenrollRecoveryCodes.bind(this)
1694
+ }
1695
+ }, this.oauth = {
1696
+ getAuthorizationDetails: this._getAuthorizationDetails.bind(this),
1697
+ approveAuthorization: this._approveAuthorization.bind(this),
1698
+ denyAuthorization: this._denyAuthorization.bind(this),
1699
+ listGrants: this._listOAuthGrants.bind(this),
1700
+ revokeGrant: this._revokeOAuthGrant.bind(this)
1701
+ }, this.passkey = {
1702
+ startRegistration: this._startPasskeyRegistration.bind(this),
1703
+ verifyRegistration: this._verifyPasskeyRegistration.bind(this),
1704
+ startAuthentication: this._startPasskeyAuthentication.bind(this),
1705
+ verifyAuthentication: this._verifyPasskeyAuthentication.bind(this),
1706
+ list: this._listPasskeys.bind(this),
1707
+ update: this._updatePasskey.bind(this),
1708
+ delete: this._deletePasskey.bind(this)
1709
+ }, this.persistSession ? (settings.storage ? this.storage = settings.storage : supportsLocalStorage() ? this.storage = globalThis.localStorage : (this.memoryStorage = {}, this.storage = memoryLocalStorageAdapter(this.memoryStorage)), settings.userStorage && (this.userStorage = settings.userStorage)) : (this.memoryStorage = {}, this.storage = memoryLocalStorageAdapter(this.memoryStorage)), isBrowser() && globalThis.BroadcastChannel && this.persistSession && this.storageKey) {
1710
+ try {
1711
+ this.broadcastChannel = new globalThis.BroadcastChannel(this.storageKey);
1712
+ } catch (e) {
1713
+ console.error("Failed to create a new BroadcastChannel, multi-tab state changes will not be available", e);
1714
+ }
1715
+ (_c = this.broadcastChannel) === null || _c === void 0 || _c.addEventListener("message", async (event) => {
1716
+ this._debug("received broadcast notification from other tab or client", event), (event.data.event === "TOKEN_REFRESHED" || event.data.event === "SIGNED_IN") && (this.lastRefreshFailure = null);
1717
+ try {
1718
+ await this._notifyAllSubscribers(event.data.event, event.data.session, !1);
1719
+ } catch (error) {
1720
+ this._debug("#broadcastChannel", "error", error);
1721
+ }
1722
+ });
1723
+ }
1724
+ settings.skipAutoInitialize || this.initialize().catch((error) => {
1725
+ this._debug("#initialize()", "error", error);
1726
+ });
1727
+ }
1728
+ isThrowOnErrorEnabled() {
1729
+ return this.throwOnError;
1730
+ }
1731
+ _returnResult(result) {
1732
+ if (this.throwOnError && result && result.error)
1733
+ throw result.error;
1734
+ return result;
1735
+ }
1736
+ _logPrefix() {
1737
+ return `GoTrueClient@${this.storageKey}:${this.instanceID} (${version}) ${(/* @__PURE__ */ new Date()).toISOString()}`;
1738
+ }
1739
+ _debug(...args) {
1740
+ return this.logDebugMessages && this.logger(this._logPrefix(), ...args), this;
1741
+ }
1742
+ async initialize() {
1743
+ var _a;
1744
+ if (this.initializePromise)
1745
+ return await this.initializePromise;
1746
+ this._pendingInitNotifications = [], this.initializePromise = (async () => this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => await this._initialize()) : await this._initialize())();
1747
+ let result = await this.initializePromise, queue = (_a = this._pendingInitNotifications) !== null && _a !== void 0 ? _a : [];
1748
+ this._pendingInitNotifications = null;
1749
+ for (let n of queue)
1750
+ await this._notifyAllSubscribers(n.event, n.session, n.broadcast);
1751
+ return result;
1752
+ }
1753
+ async _initialize() {
1754
+ var _a;
1755
+ try {
1756
+ let params = {}, callbackUrlType = "none";
1757
+ if (isBrowser() && (params = parseParametersFromURL(window.location.href), this._isImplicitGrantCallback(params) ? callbackUrlType = "implicit" : await this._isPKCECallback(params) && (callbackUrlType = "pkce")), isBrowser() && this.detectSessionInUrl && callbackUrlType !== "none") {
1758
+ let { data, error } = await this._getSessionFromURL(params, callbackUrlType);
1759
+ if (error) {
1760
+ if (this._debug("#_initialize()", "error detecting session from URL", error), isAuthImplicitGrantRedirectError(error)) {
1761
+ let errorCode = (_a = error.details) === null || _a === void 0 ? void 0 : _a.code;
1762
+ if (errorCode === "identity_already_exists" || errorCode === "identity_not_found" || errorCode === "single_identity_not_deletable")
1763
+ return { error };
1764
+ }
1765
+ return { error };
1766
+ }
1767
+ let { session, redirectType } = data;
1768
+ return this._debug("#_initialize()", "detected session in URL", session, "redirect type", redirectType), await this._saveSession(session), setTimeout(async () => {
1769
+ redirectType === "recovery" ? await this._notifyAllSubscribers("PASSWORD_RECOVERY", session) : await this._notifyAllSubscribers("SIGNED_IN", session);
1770
+ }, 0), { error: null };
1771
+ }
1772
+ return await this._recoverAndRefresh(), { error: null };
1773
+ } catch (error) {
1774
+ return isAuthError(error) ? this._returnResult({ error }) : this._returnResult({
1775
+ error: new AuthUnknownError("Unexpected error during initialization", error)
1776
+ });
1777
+ } finally {
1778
+ await this._handleVisibilityChange(), this._debug("#_initialize()", "end");
1779
+ }
1780
+ }
1781
+ async signInAnonymously(credentials) {
1782
+ var _a, _b, _c;
1783
+ try {
1784
+ let res = await _request(this.fetch, "POST", `${this.url}/signup`, {
1785
+ headers: this.headers,
1786
+ body: {
1787
+ data: (_b = (_a = credentials?.options) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {},
1788
+ gotrue_meta_security: { captcha_token: (_c = credentials?.options) === null || _c === void 0 ? void 0 : _c.captchaToken }
1789
+ },
1790
+ xform: _sessionResponse
1791
+ }), { data, error } = res;
1792
+ if (error || !data)
1793
+ return this._returnResult({ data: { user: null, session: null }, error });
1794
+ let session = data.session, user = data.user;
1795
+ return data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("SIGNED_IN", session)), this._returnResult({ data: { user, session }, error: null });
1796
+ } catch (error) {
1797
+ if (isAuthError(error))
1798
+ return this._returnResult({ data: { user: null, session: null }, error });
1799
+ throw error;
1800
+ }
1801
+ }
1802
+ async signUp(credentials) {
1803
+ var _a, _b, _c;
1804
+ let flowId = null;
1805
+ try {
1806
+ let res;
1807
+ if ("email" in credentials) {
1808
+ let { email, password, options } = credentials, codeChallenge = null, codeChallengeMethod = null;
1809
+ this.flowType === "pkce" && ([codeChallenge, codeChallengeMethod, flowId] = await this._getCodeChallengeAndMethod()), res = await _request(this.fetch, "POST", `${this.url}/signup`, {
1810
+ headers: this.headers,
1811
+ redirectTo: this._maybeAppendFlowIdToRedirect(options?.emailRedirectTo, flowId),
1812
+ body: {
1813
+ email,
1814
+ password,
1815
+ data: (_a = options?.data) !== null && _a !== void 0 ? _a : {},
1816
+ gotrue_meta_security: { captcha_token: options?.captchaToken },
1817
+ code_challenge: codeChallenge,
1818
+ code_challenge_method: codeChallengeMethod
1819
+ },
1820
+ xform: _sessionResponse
1821
+ });
1822
+ } else if ("phone" in credentials) {
1823
+ let { phone, password, options } = credentials;
1824
+ res = await _request(this.fetch, "POST", `${this.url}/signup`, {
1825
+ headers: this.headers,
1826
+ body: {
1827
+ phone,
1828
+ password,
1829
+ data: (_b = options?.data) !== null && _b !== void 0 ? _b : {},
1830
+ channel: (_c = options?.channel) !== null && _c !== void 0 ? _c : "sms",
1831
+ gotrue_meta_security: { captcha_token: options?.captchaToken }
1832
+ },
1833
+ xform: _sessionResponse
1834
+ });
1835
+ } else
1836
+ throw new AuthInvalidCredentialsError("You must provide either an email or phone number and a password");
1837
+ let { data, error } = res;
1838
+ if (error || !data)
1839
+ return await removePKCEVerifier(this.storage, this.storageKey, flowId), this._returnResult({ data: { user: null, session: null }, error });
1840
+ let session = data.session, user = data.user;
1841
+ return data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("SIGNED_IN", session)), this._returnResult({ data: { user, session }, error: null });
1842
+ } catch (error) {
1843
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), isAuthError(error))
1844
+ return this._returnResult({ data: { user: null, session: null }, error });
1845
+ throw error;
1846
+ }
1847
+ }
1848
+ async signInWithPassword(credentials) {
1849
+ try {
1850
+ let res;
1851
+ if ("email" in credentials) {
1852
+ let { email, password, options } = credentials;
1853
+ res = await _request(this.fetch, "POST", `${this.url}/token?grant_type=password`, {
1854
+ headers: this.headers,
1855
+ body: {
1856
+ email,
1857
+ password,
1858
+ gotrue_meta_security: { captcha_token: options?.captchaToken }
1859
+ },
1860
+ xform: _sessionResponsePassword
1861
+ });
1862
+ } else if ("phone" in credentials) {
1863
+ let { phone, password, options } = credentials;
1864
+ res = await _request(this.fetch, "POST", `${this.url}/token?grant_type=password`, {
1865
+ headers: this.headers,
1866
+ body: {
1867
+ phone,
1868
+ password,
1869
+ gotrue_meta_security: { captcha_token: options?.captchaToken }
1870
+ },
1871
+ xform: _sessionResponsePassword
1872
+ });
1873
+ } else
1874
+ throw new AuthInvalidCredentialsError("You must provide either an email or phone number and a password");
1875
+ let { data, error } = res;
1876
+ if (error)
1877
+ return this._returnResult({ data: { user: null, session: null }, error });
1878
+ if (!data || !data.session || !data.user) {
1879
+ let invalidTokenError = new AuthInvalidTokenResponseError();
1880
+ return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError });
1881
+ }
1882
+ return data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("SIGNED_IN", data.session)), this._returnResult({
1883
+ data: Object.assign({ user: data.user, session: data.session }, data.weak_password ? { weakPassword: data.weak_password } : null),
1884
+ error
1885
+ });
1886
+ } catch (error) {
1887
+ if (isAuthError(error))
1888
+ return this._returnResult({ data: { user: null, session: null }, error });
1889
+ throw error;
1890
+ }
1891
+ }
1892
+ async signInWithOAuth(credentials) {
1893
+ var _a, _b, _c, _d;
1894
+ return await this._handleProviderSignIn(credentials.provider, {
1895
+ redirectTo: (_a = credentials.options) === null || _a === void 0 ? void 0 : _a.redirectTo,
1896
+ scopes: (_b = credentials.options) === null || _b === void 0 ? void 0 : _b.scopes,
1897
+ queryParams: (_c = credentials.options) === null || _c === void 0 ? void 0 : _c.queryParams,
1898
+ skipBrowserRedirect: (_d = credentials.options) === null || _d === void 0 ? void 0 : _d.skipBrowserRedirect
1899
+ });
1900
+ }
1901
+ async exchangeCodeForSession(authCode, options) {
1902
+ return await this.initializePromise, this.lock != null ? this._acquireLock(this.lockAcquireTimeout, async () => this._exchangeCodeForSession(authCode, options)) : this._exchangeCodeForSession(authCode, options);
1903
+ }
1904
+ async signInWithWeb3(credentials) {
1905
+ let { chain } = credentials;
1906
+ switch (chain) {
1907
+ case "ethereum":
1908
+ return await this.signInWithEthereum(credentials);
1909
+ case "solana":
1910
+ return await this.signInWithSolana(credentials);
1911
+ default:
1912
+ throw new Error(`@supabase/auth-js: Unsupported chain "${chain}"`);
1913
+ }
1914
+ }
1915
+ async signInWithEthereum(credentials) {
1916
+ var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m;
1917
+ let message, signature;
1918
+ if ("message" in credentials)
1919
+ message = credentials.message, signature = credentials.signature;
1920
+ else {
1921
+ let { chain, wallet, statement, options } = credentials, resolvedWallet;
1922
+ if (isBrowser())
1923
+ if (typeof wallet == "object")
1924
+ resolvedWallet = wallet;
1925
+ else {
1926
+ let windowAny = window;
1927
+ if ("ethereum" in windowAny && typeof windowAny.ethereum == "object" && "request" in windowAny.ethereum && typeof windowAny.ethereum.request == "function")
1928
+ resolvedWallet = windowAny.ethereum;
1929
+ else
1930
+ throw new Error("@supabase/auth-js: No compatible Ethereum wallet interface on the window object (window.ethereum) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'ethereum', wallet: resolvedUserWallet }) instead.");
1931
+ }
1932
+ else {
1933
+ if (typeof wallet != "object" || !options?.url)
1934
+ throw new Error("@supabase/auth-js: Both wallet and url must be specified in non-browser environments.");
1935
+ resolvedWallet = wallet;
1936
+ }
1937
+ let url = new URL((_a = options?.url) !== null && _a !== void 0 ? _a : window.location.href), accounts = await resolvedWallet.request({
1938
+ method: "eth_requestAccounts"
1939
+ }).then((accs) => accs).catch(() => {
1940
+ throw new Error("@supabase/auth-js: Wallet method eth_requestAccounts is missing or invalid");
1941
+ });
1942
+ if (!accounts || accounts.length === 0)
1943
+ throw new Error("@supabase/auth-js: No accounts available. Please ensure the wallet is connected.");
1944
+ let address = getAddress(accounts[0]), chainId = (_b = options?.signInWithEthereum) === null || _b === void 0 ? void 0 : _b.chainId;
1945
+ if (!chainId) {
1946
+ let chainIdHex = await resolvedWallet.request({
1947
+ method: "eth_chainId"
1948
+ });
1949
+ chainId = fromHex(chainIdHex);
1950
+ }
1951
+ let siweMessage = {
1952
+ domain: url.host,
1953
+ address,
1954
+ statement,
1955
+ uri: url.href,
1956
+ version: "1",
1957
+ chainId,
1958
+ nonce: (_c = options?.signInWithEthereum) === null || _c === void 0 ? void 0 : _c.nonce,
1959
+ issuedAt: (_f = (_d = options?.signInWithEthereum) === null || _d === void 0 ? void 0 : _d.issuedAt) !== null && _f !== void 0 ? _f : /* @__PURE__ */ new Date(),
1960
+ expirationTime: (_g = options?.signInWithEthereum) === null || _g === void 0 ? void 0 : _g.expirationTime,
1961
+ notBefore: (_h = options?.signInWithEthereum) === null || _h === void 0 ? void 0 : _h.notBefore,
1962
+ requestId: (_j = options?.signInWithEthereum) === null || _j === void 0 ? void 0 : _j.requestId,
1963
+ resources: (_k = options?.signInWithEthereum) === null || _k === void 0 ? void 0 : _k.resources
1964
+ };
1965
+ message = createSiweMessage(siweMessage), signature = await resolvedWallet.request({
1966
+ method: "personal_sign",
1967
+ params: [toHex(message), address]
1968
+ });
1969
+ }
1970
+ try {
1971
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/token?grant_type=web3`, {
1972
+ headers: this.headers,
1973
+ body: Object.assign({
1974
+ chain: "ethereum",
1975
+ message,
1976
+ signature
1977
+ }, !((_l = credentials.options) === null || _l === void 0) && _l.captchaToken ? { gotrue_meta_security: { captcha_token: (_m = credentials.options) === null || _m === void 0 ? void 0 : _m.captchaToken } } : null),
1978
+ xform: _sessionResponse
1979
+ });
1980
+ if (error)
1981
+ throw error;
1982
+ if (!data || !data.session || !data.user) {
1983
+ let invalidTokenError = new AuthInvalidTokenResponseError();
1984
+ return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError });
1985
+ }
1986
+ return data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("SIGNED_IN", data.session)), this._returnResult({ data: Object.assign({}, data), error });
1987
+ } catch (error) {
1988
+ if (isAuthError(error))
1989
+ return this._returnResult({ data: { user: null, session: null }, error });
1990
+ throw error;
1991
+ }
1992
+ }
1993
+ async signInWithSolana(credentials) {
1994
+ var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o;
1995
+ let message, signature;
1996
+ if ("message" in credentials)
1997
+ message = credentials.message, signature = credentials.signature;
1998
+ else {
1999
+ let { chain, wallet, statement, options } = credentials, resolvedWallet;
2000
+ if (isBrowser())
2001
+ if (typeof wallet == "object")
2002
+ resolvedWallet = wallet;
2003
+ else {
2004
+ let windowAny = window;
2005
+ if ("solana" in windowAny && typeof windowAny.solana == "object" && ("signIn" in windowAny.solana && typeof windowAny.solana.signIn == "function" || "signMessage" in windowAny.solana && typeof windowAny.solana.signMessage == "function"))
2006
+ resolvedWallet = windowAny.solana;
2007
+ else
2008
+ throw new Error("@supabase/auth-js: No compatible Solana wallet interface on the window object (window.solana) detected. Make sure the user already has a wallet installed and connected for this app. Prefer passing the wallet interface object directly to signInWithWeb3({ chain: 'solana', wallet: resolvedUserWallet }) instead.");
2009
+ }
2010
+ else {
2011
+ if (typeof wallet != "object" || !options?.url)
2012
+ throw new Error("@supabase/auth-js: Both wallet and url must be specified in non-browser environments.");
2013
+ resolvedWallet = wallet;
2014
+ }
2015
+ let url = new URL((_a = options?.url) !== null && _a !== void 0 ? _a : window.location.href);
2016
+ if ("signIn" in resolvedWallet && resolvedWallet.signIn) {
2017
+ let output = await resolvedWallet.signIn(Object.assign(Object.assign(Object.assign({ issuedAt: (/* @__PURE__ */ new Date()).toISOString() }, options?.signInWithSolana), {
2018
+ // non-overridable properties
2019
+ version: "1",
2020
+ domain: url.host,
2021
+ uri: url.href
2022
+ }), statement ? { statement } : null)), outputToProcess;
2023
+ if (Array.isArray(output) && output[0] && typeof output[0] == "object")
2024
+ outputToProcess = output[0];
2025
+ else if (output && typeof output == "object" && "signedMessage" in output && "signature" in output)
2026
+ outputToProcess = output;
2027
+ else
2028
+ throw new Error("@supabase/auth-js: Wallet method signIn() returned unrecognized value");
2029
+ if ("signedMessage" in outputToProcess && "signature" in outputToProcess && (typeof outputToProcess.signedMessage == "string" || outputToProcess.signedMessage instanceof Uint8Array) && outputToProcess.signature instanceof Uint8Array)
2030
+ message = typeof outputToProcess.signedMessage == "string" ? outputToProcess.signedMessage : new TextDecoder().decode(outputToProcess.signedMessage), signature = outputToProcess.signature;
2031
+ else
2032
+ throw new Error("@supabase/auth-js: Wallet method signIn() API returned object without signedMessage and signature fields");
2033
+ } else {
2034
+ if (!("signMessage" in resolvedWallet) || typeof resolvedWallet.signMessage != "function" || !("publicKey" in resolvedWallet) || typeof resolvedWallet != "object" || !resolvedWallet.publicKey || !("toBase58" in resolvedWallet.publicKey) || typeof resolvedWallet.publicKey.toBase58 != "function")
2035
+ throw new Error("@supabase/auth-js: Wallet does not have a compatible signMessage() and publicKey.toBase58() API");
2036
+ message = [
2037
+ `${url.host} wants you to sign in with your Solana account:`,
2038
+ resolvedWallet.publicKey.toBase58(),
2039
+ ...statement ? ["", statement, ""] : [""],
2040
+ "Version: 1",
2041
+ `URI: ${url.href}`,
2042
+ `Issued At: ${(_c = (_b = options?.signInWithSolana) === null || _b === void 0 ? void 0 : _b.issuedAt) !== null && _c !== void 0 ? _c : (/* @__PURE__ */ new Date()).toISOString()}`,
2043
+ ...!((_d = options?.signInWithSolana) === null || _d === void 0) && _d.notBefore ? [`Not Before: ${options.signInWithSolana.notBefore}`] : [],
2044
+ ...!((_f = options?.signInWithSolana) === null || _f === void 0) && _f.expirationTime ? [`Expiration Time: ${options.signInWithSolana.expirationTime}`] : [],
2045
+ ...!((_g = options?.signInWithSolana) === null || _g === void 0) && _g.chainId ? [`Chain ID: ${options.signInWithSolana.chainId}`] : [],
2046
+ ...!((_h = options?.signInWithSolana) === null || _h === void 0) && _h.nonce ? [`Nonce: ${options.signInWithSolana.nonce}`] : [],
2047
+ ...!((_j = options?.signInWithSolana) === null || _j === void 0) && _j.requestId ? [`Request ID: ${options.signInWithSolana.requestId}`] : [],
2048
+ ...!((_l = (_k = options?.signInWithSolana) === null || _k === void 0 ? void 0 : _k.resources) === null || _l === void 0) && _l.length ? [
2049
+ "Resources",
2050
+ ...options.signInWithSolana.resources.map((resource) => `- ${resource}`)
2051
+ ] : []
2052
+ ].join(`
2053
+ `);
2054
+ let maybeSignature = await resolvedWallet.signMessage(new TextEncoder().encode(message), "utf8");
2055
+ if (!maybeSignature || !(maybeSignature instanceof Uint8Array))
2056
+ throw new Error("@supabase/auth-js: Wallet signMessage() API returned an recognized value");
2057
+ signature = maybeSignature;
2058
+ }
2059
+ }
2060
+ try {
2061
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/token?grant_type=web3`, {
2062
+ headers: this.headers,
2063
+ body: Object.assign({ chain: "solana", message, signature: bytesToBase64URL(signature) }, !((_m = credentials.options) === null || _m === void 0) && _m.captchaToken ? { gotrue_meta_security: { captcha_token: (_o = credentials.options) === null || _o === void 0 ? void 0 : _o.captchaToken } } : null),
2064
+ xform: _sessionResponse
2065
+ });
2066
+ if (error)
2067
+ throw error;
2068
+ if (!data || !data.session || !data.user) {
2069
+ let invalidTokenError = new AuthInvalidTokenResponseError();
2070
+ return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError });
2071
+ }
2072
+ return data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("SIGNED_IN", data.session)), this._returnResult({ data: Object.assign({}, data), error });
2073
+ } catch (error) {
2074
+ if (isAuthError(error))
2075
+ return this._returnResult({ data: { user: null, session: null }, error });
2076
+ throw error;
2077
+ }
2078
+ }
2079
+ async _exchangeCodeForSession(authCode, options) {
2080
+ let hasExplicitFlowId = options?.flowId != null, requestedFlowId = hasExplicitFlowId ? validatePKCEFlowId(options?.flowId) : isBrowser() ? validatePKCEFlowId(parseParametersFromURL(window.location.href)[PKCE_FLOW_ID_PARAM]) : null;
2081
+ hasExplicitFlowId && !requestedFlowId && this._debug("#_exchangeCodeForSession()", "provided flowId is not a valid flow id", options?.flowId);
2082
+ let { verifier: storageItem, flowId } = hasExplicitFlowId && !requestedFlowId ? { verifier: null, flowId: null } : await retrievePKCEVerifier(this.storage, this.storageKey, requestedFlowId), [codeVerifier, redirectType] = (storageItem ?? "").split("/");
2083
+ try {
2084
+ if (!codeVerifier && this.flowType === "pkce")
2085
+ throw new AuthPKCECodeVerifierMissingError();
2086
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/token?grant_type=pkce`, {
2087
+ headers: this.headers,
2088
+ body: {
2089
+ auth_code: authCode,
2090
+ code_verifier: codeVerifier
2091
+ },
2092
+ xform: _sessionResponse
2093
+ });
2094
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), error)
2095
+ throw error;
2096
+ if (!data || !data.session || !data.user) {
2097
+ let invalidTokenError = new AuthInvalidTokenResponseError();
2098
+ return this._returnResult({
2099
+ data: { user: null, session: null, redirectType: null },
2100
+ error: invalidTokenError
2101
+ });
2102
+ }
2103
+ return data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers(redirectType === "recovery" ? "PASSWORD_RECOVERY" : "SIGNED_IN", data.session)), this._returnResult({ data: Object.assign(Object.assign({}, data), { redirectType: redirectType ?? null }), error });
2104
+ } catch (error) {
2105
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), isAuthError(error))
2106
+ return this._returnResult({
2107
+ data: { user: null, session: null, redirectType: null },
2108
+ error
2109
+ });
2110
+ throw error;
2111
+ }
2112
+ }
2113
+ async signInWithIdToken(credentials) {
2114
+ try {
2115
+ let { options, provider, token, access_token, nonce } = credentials, res = await _request(this.fetch, "POST", `${this.url}/token?grant_type=id_token`, {
2116
+ headers: this.headers,
2117
+ body: {
2118
+ provider,
2119
+ id_token: token,
2120
+ access_token,
2121
+ nonce,
2122
+ gotrue_meta_security: { captcha_token: options?.captchaToken }
2123
+ },
2124
+ xform: _sessionResponse
2125
+ }), { data, error } = res;
2126
+ if (error)
2127
+ return this._returnResult({ data: { user: null, session: null }, error });
2128
+ if (!data || !data.session || !data.user) {
2129
+ let invalidTokenError = new AuthInvalidTokenResponseError();
2130
+ return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError });
2131
+ }
2132
+ return data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("SIGNED_IN", data.session)), this._returnResult({ data, error });
2133
+ } catch (error) {
2134
+ if (isAuthError(error))
2135
+ return this._returnResult({ data: { user: null, session: null }, error });
2136
+ throw error;
2137
+ }
2138
+ }
2139
+ async signInWithOtp(credentials) {
2140
+ var _a, _b, _c, _d, _f;
2141
+ let flowId = null;
2142
+ try {
2143
+ if ("email" in credentials) {
2144
+ let { email, options } = credentials, codeChallenge = null, codeChallengeMethod = null;
2145
+ this.flowType === "pkce" && ([codeChallenge, codeChallengeMethod, flowId] = await this._getCodeChallengeAndMethod());
2146
+ let { error } = await _request(this.fetch, "POST", `${this.url}/otp`, {
2147
+ headers: this.headers,
2148
+ body: {
2149
+ email,
2150
+ data: (_a = options?.data) !== null && _a !== void 0 ? _a : {},
2151
+ create_user: (_b = options?.shouldCreateUser) !== null && _b !== void 0 ? _b : !0,
2152
+ gotrue_meta_security: { captcha_token: options?.captchaToken },
2153
+ code_challenge: codeChallenge,
2154
+ code_challenge_method: codeChallengeMethod
2155
+ },
2156
+ redirectTo: this._maybeAppendFlowIdToRedirect(options?.emailRedirectTo, flowId)
2157
+ });
2158
+ return this._returnResult({ data: { user: null, session: null }, error });
2159
+ }
2160
+ if ("phone" in credentials) {
2161
+ let { phone, options } = credentials, { data, error } = await _request(this.fetch, "POST", `${this.url}/otp`, {
2162
+ headers: this.headers,
2163
+ body: {
2164
+ phone,
2165
+ data: (_c = options?.data) !== null && _c !== void 0 ? _c : {},
2166
+ create_user: (_d = options?.shouldCreateUser) !== null && _d !== void 0 ? _d : !0,
2167
+ gotrue_meta_security: { captcha_token: options?.captchaToken },
2168
+ channel: (_f = options?.channel) !== null && _f !== void 0 ? _f : "sms"
2169
+ }
2170
+ });
2171
+ return this._returnResult({
2172
+ data: { user: null, session: null, messageId: data?.message_id },
2173
+ error
2174
+ });
2175
+ }
2176
+ throw new AuthInvalidCredentialsError("You must provide either an email or phone number.");
2177
+ } catch (error) {
2178
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), isAuthError(error))
2179
+ return this._returnResult({ data: { user: null, session: null }, error });
2180
+ throw error;
2181
+ }
2182
+ }
2183
+ async verifyOtp(params) {
2184
+ var _a, _b;
2185
+ try {
2186
+ let redirectTo, captchaToken;
2187
+ "options" in params && (redirectTo = (_a = params.options) === null || _a === void 0 ? void 0 : _a.redirectTo, captchaToken = (_b = params.options) === null || _b === void 0 ? void 0 : _b.captchaToken);
2188
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/verify`, {
2189
+ headers: this.headers,
2190
+ body: Object.assign(Object.assign({}, params), { gotrue_meta_security: { captcha_token: captchaToken } }),
2191
+ redirectTo,
2192
+ xform: _sessionResponse
2193
+ });
2194
+ if (error)
2195
+ throw error;
2196
+ if (!data)
2197
+ throw new Error("An error occurred on token verification.");
2198
+ let session = data.session, user = data.user;
2199
+ return session?.access_token && (await this._saveSession(session), await this._notifyAllSubscribers(params.type == "recovery" ? "PASSWORD_RECOVERY" : "SIGNED_IN", session)), this._returnResult({ data: { user, session }, error: null });
2200
+ } catch (error) {
2201
+ if (isAuthError(error))
2202
+ return this._returnResult({ data: { user: null, session: null }, error });
2203
+ throw error;
2204
+ }
2205
+ }
2206
+ async signInWithSSO(params) {
2207
+ var _a, _b, _c, _d;
2208
+ let flowId = null;
2209
+ try {
2210
+ let codeChallenge = null, codeChallengeMethod = null;
2211
+ this.flowType === "pkce" && ([codeChallenge, codeChallengeMethod, flowId] = await this._getCodeChallengeAndMethod());
2212
+ let result = await _request(this.fetch, "POST", `${this.url}/sso`, {
2213
+ body: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, "providerId" in params ? { provider_id: params.providerId } : null), "domain" in params ? { domain: params.domain } : null), { redirect_to: this._maybeAppendFlowIdToRedirect((_a = params.options) === null || _a === void 0 ? void 0 : _a.redirectTo, flowId) }), !((_b = params?.options) === null || _b === void 0) && _b.captchaToken ? { gotrue_meta_security: { captcha_token: params.options.captchaToken } } : null), { skip_http_redirect: !0, code_challenge: codeChallenge, code_challenge_method: codeChallengeMethod }),
2214
+ headers: this.headers,
2215
+ xform: _ssoResponse
2216
+ });
2217
+ return !((_c = result.data) === null || _c === void 0) && _c.url && isBrowser() && !(!((_d = params.options) === null || _d === void 0) && _d.skipBrowserRedirect) && window.location.assign(result.data.url), this._returnResult(result);
2218
+ } catch (error) {
2219
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), isAuthError(error))
2220
+ return this._returnResult({ data: null, error });
2221
+ throw error;
2222
+ }
2223
+ }
2224
+ async reauthenticate() {
2225
+ return await this.initializePromise, this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => await this._reauthenticate()) : await this._reauthenticate();
2226
+ }
2227
+ async _reauthenticate() {
2228
+ try {
2229
+ return await this._useSession(async (result) => {
2230
+ let { data: { session }, error: sessionError } = result;
2231
+ if (sessionError)
2232
+ throw sessionError;
2233
+ if (!session)
2234
+ throw new AuthSessionMissingError();
2235
+ let { error } = await _request(this.fetch, "GET", `${this.url}/reauthenticate`, {
2236
+ headers: this.headers,
2237
+ jwt: session.access_token
2238
+ });
2239
+ return this._returnResult({ data: { user: null, session: null }, error });
2240
+ });
2241
+ } catch (error) {
2242
+ if (isAuthError(error))
2243
+ return this._returnResult({ data: { user: null, session: null }, error });
2244
+ throw error;
2245
+ }
2246
+ }
2247
+ async resend(credentials) {
2248
+ let flowId = null;
2249
+ try {
2250
+ let endpoint = `${this.url}/resend`;
2251
+ if ("email" in credentials) {
2252
+ let { email, type, options } = credentials, codeChallenge = null, codeChallengeMethod = null;
2253
+ this.flowType === "pkce" && ([codeChallenge, codeChallengeMethod, flowId] = await this._getCodeChallengeAndMethod());
2254
+ let { error } = await _request(this.fetch, "POST", endpoint, {
2255
+ headers: this.headers,
2256
+ body: {
2257
+ email,
2258
+ type,
2259
+ gotrue_meta_security: { captcha_token: options?.captchaToken },
2260
+ code_challenge: codeChallenge,
2261
+ code_challenge_method: codeChallengeMethod
2262
+ },
2263
+ redirectTo: this._maybeAppendFlowIdToRedirect(options?.emailRedirectTo, flowId)
2264
+ });
2265
+ return error && await removePKCEVerifier(this.storage, this.storageKey, flowId), this._returnResult({ data: { user: null, session: null }, error });
2266
+ } else if ("phone" in credentials) {
2267
+ let { phone, type, options } = credentials, { data, error } = await _request(this.fetch, "POST", endpoint, {
2268
+ headers: this.headers,
2269
+ body: {
2270
+ phone,
2271
+ type,
2272
+ gotrue_meta_security: { captcha_token: options?.captchaToken }
2273
+ }
2274
+ });
2275
+ return this._returnResult({
2276
+ data: { user: null, session: null, messageId: data?.message_id },
2277
+ error
2278
+ });
2279
+ }
2280
+ throw new AuthInvalidCredentialsError("You must provide either an email or phone number and a type");
2281
+ } catch (error) {
2282
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), isAuthError(error))
2283
+ return this._returnResult({ data: { user: null, session: null }, error });
2284
+ throw error;
2285
+ }
2286
+ }
2287
+ async getSession() {
2288
+ return await this.initializePromise, this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => this._useSession(async (result) => result)) : await this._useSession(async (result) => result);
2289
+ }
2290
+ async _acquireLock(acquireTimeout, fn) {
2291
+ this._debug("#_acquireLock", "begin", acquireTimeout);
2292
+ try {
2293
+ if (this.lockAcquired) {
2294
+ let last = this.pendingInLock.length ? this.pendingInLock[this.pendingInLock.length - 1] : Promise.resolve(), result = (async () => (await last, await fn()))();
2295
+ return this.pendingInLock.push((async () => {
2296
+ try {
2297
+ await result;
2298
+ } catch {
2299
+ }
2300
+ })()), result;
2301
+ }
2302
+ return await this.lock(`lock:${this.storageKey}`, acquireTimeout, async () => {
2303
+ this._debug("#_acquireLock", "lock acquired for storage key", this.storageKey);
2304
+ try {
2305
+ this.lockAcquired = !0;
2306
+ let result = fn();
2307
+ for (this.pendingInLock.push((async () => {
2308
+ try {
2309
+ await result;
2310
+ } catch {
2311
+ }
2312
+ })()), await result; this.pendingInLock.length; ) {
2313
+ let waitOn = [...this.pendingInLock];
2314
+ await Promise.all(waitOn), this.pendingInLock.splice(0, waitOn.length);
2315
+ }
2316
+ return await result;
2317
+ } finally {
2318
+ this._debug("#_acquireLock", "lock released for storage key", this.storageKey), this.lockAcquired = !1;
2319
+ }
2320
+ });
2321
+ } finally {
2322
+ this._debug("#_acquireLock", "end");
2323
+ }
2324
+ }
2325
+ async _useSession(fn) {
2326
+ this._debug("#_useSession", "begin");
2327
+ try {
2328
+ let result = await this.__loadSession();
2329
+ return await fn(result);
2330
+ } finally {
2331
+ this._debug("#_useSession", "end");
2332
+ }
2333
+ }
2334
+ async __loadSession() {
2335
+ this._debug("#__loadSession()", "begin"), this.lock != null && !this.lockAcquired && this._debug("#__loadSession()", "used outside of an acquired lock!", new Error().stack);
2336
+ try {
2337
+ let currentSession = null, maybeSession = await getItemAsync(this.storage, this.storageKey);
2338
+ if (this._debug("#getSession()", "session from storage", maybeSession), maybeSession !== null && (this._isValidSession(maybeSession) ? currentSession = maybeSession : (this._debug("#getSession()", "session from storage is not valid"), await this._removeSession())), !currentSession)
2339
+ return { data: { session: null }, error: null };
2340
+ let hasExpired = currentSession.expires_at ? currentSession.expires_at * 1e3 - Date.now() < EXPIRY_MARGIN_MS : !1;
2341
+ if (this._debug("#__loadSession()", `session has${hasExpired ? "" : " not"} expired`, "expires_at", currentSession.expires_at), !hasExpired) {
2342
+ if (this.userStorage) {
2343
+ let maybeUser = await getItemAsync(this.userStorage, this.storageKey + "-user");
2344
+ maybeUser?.user ? currentSession.user = maybeUser.user : currentSession.user = userNotAvailableProxy();
2345
+ }
2346
+ if (this.storage.isServer && currentSession.user && !currentSession.user.__isUserNotAvailableProxy) {
2347
+ let suppressWarningRef = { value: this.suppressGetSessionWarning };
2348
+ currentSession.user = insecureUserWarningProxy(currentSession.user, suppressWarningRef), suppressWarningRef.value && (this.suppressGetSessionWarning = !0);
2349
+ }
2350
+ return { data: { session: currentSession }, error: null };
2351
+ }
2352
+ let { data: session, error } = await this._callRefreshToken(currentSession.refresh_token);
2353
+ if (error) {
2354
+ if (!!(currentSession.expires_at && currentSession.expires_at * 1e3 > Date.now())) {
2355
+ let stillStored = await getItemAsync(this.storage, this.storageKey);
2356
+ if (stillStored && stillStored.refresh_token === currentSession.refresh_token)
2357
+ return this._returnResult({ data: { session: currentSession }, error: null });
2358
+ }
2359
+ return this._returnResult({ data: { session: null }, error });
2360
+ }
2361
+ return this._returnResult({ data: { session }, error: null });
2362
+ } finally {
2363
+ this._debug("#__loadSession()", "end");
2364
+ }
2365
+ }
2366
+ async getUser(jwt) {
2367
+ if (jwt)
2368
+ return await this._getUser(jwt);
2369
+ await this.initializePromise;
2370
+ let result;
2371
+ return this.lock != null ? result = await this._acquireLock(this.lockAcquireTimeout, async () => await this._getUser()) : result = await this._getUser(), result.data.user && (this.suppressGetSessionWarning = !0), result;
2372
+ }
2373
+ async _getUser(jwt) {
2374
+ try {
2375
+ return jwt ? await _request(this.fetch, "GET", `${this.url}/user`, {
2376
+ headers: this.headers,
2377
+ jwt,
2378
+ xform: _userResponse
2379
+ }) : await this._useSession(async (result) => {
2380
+ var _a, _b, _c;
2381
+ let { data, error } = result;
2382
+ if (error)
2383
+ throw error;
2384
+ return !(!((_a = data.session) === null || _a === void 0) && _a.access_token) && !this.hasCustomAuthorizationHeader ? { data: { user: null }, error: new AuthSessionMissingError() } : await _request(this.fetch, "GET", `${this.url}/user`, {
2385
+ headers: this.headers,
2386
+ jwt: (_c = (_b = data.session) === null || _b === void 0 ? void 0 : _b.access_token) !== null && _c !== void 0 ? _c : void 0,
2387
+ xform: _userResponse
2388
+ });
2389
+ });
2390
+ } catch (error) {
2391
+ if (isAuthError(error))
2392
+ return isAuthSessionMissingError(error) && await this._removeSession(), this._returnResult({ data: { user: null }, error });
2393
+ throw error;
2394
+ }
2395
+ }
2396
+ async updateUser(attributes, options = {}) {
2397
+ return await this.initializePromise, this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => await this._updateUser(attributes, options)) : await this._updateUser(attributes, options);
2398
+ }
2399
+ async _updateUser(attributes, options = {}) {
2400
+ let flowId = null;
2401
+ try {
2402
+ return await this._useSession(async (result) => {
2403
+ let { data: sessionData, error: sessionError } = result;
2404
+ if (sessionError)
2405
+ throw sessionError;
2406
+ if (!sessionData.session)
2407
+ throw new AuthSessionMissingError();
2408
+ let session = sessionData.session, codeChallenge = null, codeChallengeMethod = null;
2409
+ this.flowType === "pkce" && attributes.email != null && ([codeChallenge, codeChallengeMethod, flowId] = await this._getCodeChallengeAndMethod());
2410
+ let { data, error: userError } = await _request(this.fetch, "PUT", `${this.url}/user`, {
2411
+ headers: this.headers,
2412
+ redirectTo: this._maybeAppendFlowIdToRedirect(options?.emailRedirectTo, flowId),
2413
+ body: Object.assign(Object.assign({}, attributes), { code_challenge: codeChallenge, code_challenge_method: codeChallengeMethod }),
2414
+ jwt: session.access_token,
2415
+ xform: _userResponse
2416
+ });
2417
+ if (userError)
2418
+ throw userError;
2419
+ return session.user = data.user, await this._saveSession(session), await this._notifyAllSubscribers("USER_UPDATED", session), this._returnResult({ data: { user: session.user }, error: null });
2420
+ });
2421
+ } catch (error) {
2422
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), isAuthError(error))
2423
+ return this._returnResult({ data: { user: null }, error });
2424
+ throw error;
2425
+ }
2426
+ }
2427
+ async setSession(currentSession) {
2428
+ return await this.initializePromise, this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => await this._setSession(currentSession)) : await this._setSession(currentSession);
2429
+ }
2430
+ async _setSession(currentSession) {
2431
+ try {
2432
+ if (!currentSession.access_token || !currentSession.refresh_token)
2433
+ throw new AuthSessionMissingError();
2434
+ let timeNow = Date.now() / 1e3, expiresAt2 = timeNow, hasExpired = !0, session = null, { payload } = decodeJWT(currentSession.access_token);
2435
+ if (payload.exp && (expiresAt2 = payload.exp, hasExpired = expiresAt2 <= timeNow), hasExpired) {
2436
+ let { data: refreshedSession, error } = await this._callRefreshToken(currentSession.refresh_token);
2437
+ if (error)
2438
+ return this._returnResult({ data: { user: null, session: null }, error });
2439
+ if (!refreshedSession)
2440
+ return { data: { user: null, session: null }, error: null };
2441
+ session = refreshedSession;
2442
+ } else {
2443
+ let { data, error } = await this._getUser(currentSession.access_token);
2444
+ if (error)
2445
+ return this._returnResult({ data: { user: null, session: null }, error });
2446
+ session = {
2447
+ access_token: currentSession.access_token,
2448
+ refresh_token: currentSession.refresh_token,
2449
+ user: data.user,
2450
+ token_type: "bearer",
2451
+ expires_in: expiresAt2 - timeNow,
2452
+ expires_at: expiresAt2
2453
+ }, await this._saveSession(session), await this._notifyAllSubscribers("SIGNED_IN", session);
2454
+ }
2455
+ return this._returnResult({ data: { user: session.user, session }, error: null });
2456
+ } catch (error) {
2457
+ if (isAuthError(error))
2458
+ return this._returnResult({ data: { session: null, user: null }, error });
2459
+ throw error;
2460
+ }
2461
+ }
2462
+ async refreshSession(currentSession) {
2463
+ return await this.initializePromise, this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => await this._refreshSession(currentSession)) : await this._refreshSession(currentSession);
2464
+ }
2465
+ async _refreshSession(currentSession) {
2466
+ try {
2467
+ return await this._useSession(async (result) => {
2468
+ var _a;
2469
+ if (!currentSession) {
2470
+ let { data, error: error2 } = result;
2471
+ if (error2)
2472
+ throw error2;
2473
+ currentSession = (_a = data.session) !== null && _a !== void 0 ? _a : void 0;
2474
+ }
2475
+ if (!currentSession?.refresh_token)
2476
+ throw new AuthSessionMissingError();
2477
+ let { data: session, error } = await this._callRefreshToken(currentSession.refresh_token);
2478
+ return error ? this._returnResult({ data: { user: null, session: null }, error }) : session ? this._returnResult({ data: { user: session.user, session }, error: null }) : this._returnResult({ data: { user: null, session: null }, error: null });
2479
+ });
2480
+ } catch (error) {
2481
+ if (isAuthError(error))
2482
+ return this._returnResult({ data: { user: null, session: null }, error });
2483
+ throw error;
2484
+ }
2485
+ }
2486
+ async _getSessionFromURL(params, callbackUrlType) {
2487
+ var _a;
2488
+ try {
2489
+ if (!isBrowser())
2490
+ throw new AuthImplicitGrantRedirectError("No browser detected.");
2491
+ if (params.error || params.error_description || params.error_code)
2492
+ throw new AuthImplicitGrantRedirectError(params.error_description || "Error in URL with unspecified error_description", {
2493
+ error: params.error || "unspecified_error",
2494
+ code: params.error_code || "unspecified_code"
2495
+ });
2496
+ switch (callbackUrlType) {
2497
+ case "implicit":
2498
+ if (this.flowType === "pkce")
2499
+ throw new AuthPKCEGrantCodeExchangeError("Not a valid PKCE flow url.");
2500
+ break;
2501
+ case "pkce":
2502
+ if (this.flowType === "implicit")
2503
+ throw new AuthImplicitGrantRedirectError("Not a valid implicit grant flow url.");
2504
+ break;
2505
+ default:
2506
+ }
2507
+ if (callbackUrlType === "pkce") {
2508
+ if (this._debug("#_initialize()", "begin", "is PKCE flow", !0), !params.code)
2509
+ throw new AuthPKCEGrantCodeExchangeError("No code detected.");
2510
+ let { data: data2, error: error2 } = await this._exchangeCodeForSession(params.code, {
2511
+ flowId: params[PKCE_FLOW_ID_PARAM]
2512
+ });
2513
+ if (error2)
2514
+ throw error2;
2515
+ let url = new URL(window.location.href);
2516
+ return url.searchParams.delete("code"), url.searchParams.delete(PKCE_FLOW_ID_PARAM), window.history.replaceState(window.history.state, "", url.toString()), {
2517
+ data: { session: data2.session, redirectType: (_a = data2.redirectType) !== null && _a !== void 0 ? _a : null },
2518
+ error: null
2519
+ };
2520
+ }
2521
+ let { provider_token, provider_refresh_token, access_token, refresh_token, expires_in, expires_at, token_type } = params;
2522
+ if (!access_token || !expires_in || !refresh_token || !token_type)
2523
+ throw new AuthImplicitGrantRedirectError("No session defined in URL");
2524
+ let timeNow = Math.round(Date.now() / 1e3), expiresIn = parseInt(expires_in), expiresAt2 = timeNow + expiresIn;
2525
+ expires_at && (expiresAt2 = parseInt(expires_at));
2526
+ let actuallyExpiresIn = expiresAt2 - timeNow;
2527
+ actuallyExpiresIn * 1e3 <= AUTO_REFRESH_TICK_DURATION_MS && console.warn(`@supabase/gotrue-js: Session as retrieved from URL expires in ${actuallyExpiresIn}s, should have been closer to ${expiresIn}s`);
2528
+ let issuedAt = expiresAt2 - expiresIn;
2529
+ timeNow - issuedAt >= 120 ? console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued over 120s ago, URL could be stale", issuedAt, expiresAt2, timeNow) : timeNow - issuedAt < 0 && console.warn("@supabase/gotrue-js: Session as retrieved from URL was issued in the future? Check the device clock for skew", issuedAt, expiresAt2, timeNow);
2530
+ let { data, error } = await this._getUser(access_token);
2531
+ if (error)
2532
+ throw error;
2533
+ let session = {
2534
+ provider_token,
2535
+ provider_refresh_token,
2536
+ access_token,
2537
+ expires_in: expiresIn,
2538
+ expires_at: expiresAt2,
2539
+ refresh_token,
2540
+ token_type,
2541
+ user: data.user
2542
+ };
2543
+ return window.location.hash = "", this._debug("#_getSessionFromURL()", "clearing window.location.hash"), this._returnResult({ data: { session, redirectType: params.type }, error: null });
2544
+ } catch (error) {
2545
+ if (isAuthError(error))
2546
+ return this._returnResult({ data: { session: null, redirectType: null }, error });
2547
+ throw error;
2548
+ }
2549
+ }
2550
+ _isImplicitGrantCallback(params) {
2551
+ return typeof this.detectSessionInUrl == "function" ? this.detectSessionInUrl(new URL(window.location.href), params) : !!(params.access_token || params.error || params.error_description || params.error_code);
2552
+ }
2553
+ async _isPKCECallback(params) {
2554
+ if (!params.code)
2555
+ return !1;
2556
+ let flowId = validatePKCEFlowId(params[PKCE_FLOW_ID_PARAM]);
2557
+ return flowId && await getItemAsync(this.storage, pkceVerifierSlotKey(this.storageKey, flowId)) ? !0 : !!await getItemAsync(this.storage, `${this.storageKey}-code-verifier`);
2558
+ }
2559
+ async signOut(options = { scope: "global" }) {
2560
+ return await this.initializePromise, this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => await this._signOut(options)) : await this._signOut(options);
2561
+ }
2562
+ async _signOut({ scope } = { scope: "global" }) {
2563
+ return await this._useSession(async (result) => {
2564
+ var _a;
2565
+ let removeCurrentSession = async () => {
2566
+ await this._removeSession();
2567
+ }, { data, error: sessionError } = result;
2568
+ if (sessionError && !isAuthSessionMissingError(sessionError))
2569
+ return this._returnResult({ error: sessionError });
2570
+ let accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token;
2571
+ if (accessToken) {
2572
+ let { error } = await this.admin.signOut(accessToken, scope);
2573
+ if (error && !(isAuthApiError(error) && (error.status === 404 || error.status === 401 || error.status === 403) || isAuthSessionMissingError(error)))
2574
+ return scope !== "others" && await removeCurrentSession(), this._returnResult({ error });
2575
+ }
2576
+ return scope !== "others" && await removeCurrentSession(), this._returnResult({ error: null });
2577
+ });
2578
+ }
2579
+ /** *
2580
+ * @category Auth
2581
+ *
2582
+ * @remarks
2583
+ * - Subscribes to important events occurring on the user's session.
2584
+ * - Use on the frontend/client. It is less useful on the server.
2585
+ * - Events are emitted across tabs to keep your application's UI up-to-date. Some events can fire very frequently, based on the number of tabs open. Use a quick and efficient callback function, and defer or debounce as many operations as you can to be performed outside of the callback.
2586
+ * - Callbacks can be `async` and can safely call other Supabase auth methods (`getUser`, `setSession`, etc.) from inside the callback.
2587
+ * - Keep callbacks quick. Events are awaited in order, so a slow callback delays subsequent events to subscribers in this tab.
2588
+ * - Emitted events:
2589
+ * - `INITIAL_SESSION`
2590
+ * - Emitted right after the Supabase client is constructed and the initial session from storage is loaded.
2591
+ * - `SIGNED_IN`
2592
+ * - Emitted each time a user session is confirmed or re-established, including on user sign in and when refocusing a tab.
2593
+ * - Avoid making assumptions as to when this event is fired, this may occur even when the user is already signed in. Instead, check the user object attached to the event to see if a new user has signed in and update your application's UI.
2594
+ * - This event can fire very frequently depending on the number of tabs open in your application.
2595
+ * - `SIGNED_OUT`
2596
+ * - Emitted when the user signs out. This can be after:
2597
+ * - A call to `supabase.auth.signOut()`.
2598
+ * - After the user's session has expired for any reason:
2599
+ * - User has signed out on another device.
2600
+ * - The session has reached its timebox limit or inactivity timeout.
2601
+ * - User has signed in on another device with single session per user enabled.
2602
+ * - Check the [User Sessions](/docs/guides/auth/sessions) docs for more information.
2603
+ * - Use this to clean up any local storage your application has associated with the user.
2604
+ * - `TOKEN_REFRESHED`
2605
+ * - Emitted each time a new access and refresh token are fetched for the signed in user.
2606
+ * - It's best practice and highly recommended to extract the access token (JWT) and store it in memory for further use in your application.
2607
+ * - Avoid frequent calls to `supabase.auth.getSession()` for the same purpose.
2608
+ * - There is a background process that keeps track of when the session should be refreshed so you will always receive valid tokens by listening to this event.
2609
+ * - The frequency of this event is related to the JWT expiry limit configured on your project.
2610
+ * - `USER_UPDATED`
2611
+ * - Emitted each time the `supabase.auth.updateUser()` method finishes successfully. Listen to it to update your application's UI based on new profile information.
2612
+ * - `PASSWORD_RECOVERY`
2613
+ * - Emitted instead of the `SIGNED_IN` event when the user lands on a page that includes a password recovery link in the URL.
2614
+ * - Use it to show a UI to the user where they can [reset their password](/docs/guides/auth/passwords#resetting-a-users-password-forgot-password).
2615
+ *
2616
+ * @example Listen to auth changes
2617
+ * ```js
2618
+ * const { data } = supabase.auth.onAuthStateChange((event, session) => {
2619
+ * console.log(event, session)
2620
+ *
2621
+ * if (event === 'INITIAL_SESSION') {
2622
+ * // handle initial session
2623
+ * } else if (event === 'SIGNED_IN') {
2624
+ * // handle sign in event
2625
+ * } else if (event === 'SIGNED_OUT') {
2626
+ * // handle sign out event
2627
+ * } else if (event === 'PASSWORD_RECOVERY') {
2628
+ * // handle password recovery event
2629
+ * } else if (event === 'TOKEN_REFRESHED') {
2630
+ * // handle token refreshed event
2631
+ * } else if (event === 'USER_UPDATED') {
2632
+ * // handle user updated event
2633
+ * }
2634
+ * })
2635
+ *
2636
+ * // call unsubscribe to remove the callback
2637
+ * data.subscription.unsubscribe()
2638
+ * ```
2639
+ *
2640
+ * @exampleDescription Listen to sign out
2641
+ * Make sure you clear out any local data, such as local and session storage, after the client library has detected the user's sign out.
2642
+ *
2643
+ * @example Listen to sign out
2644
+ * ```js
2645
+ * supabase.auth.onAuthStateChange((event, session) => {
2646
+ * if (event === 'SIGNED_OUT') {
2647
+ * console.log('SIGNED_OUT', session)
2648
+ *
2649
+ * // clear local and session storage
2650
+ * [
2651
+ * window.localStorage,
2652
+ * window.sessionStorage,
2653
+ * ].forEach((storage) => {
2654
+ * Object.entries(storage)
2655
+ * .forEach(([key]) => {
2656
+ * storage.removeItem(key)
2657
+ * })
2658
+ * })
2659
+ * }
2660
+ * })
2661
+ * ```
2662
+ *
2663
+ * @exampleDescription Store OAuth provider tokens on sign in
2664
+ * When using [OAuth (Social Login)](/docs/guides/auth/social-login) you sometimes wish to get access to the provider's access token and refresh token, in order to call provider APIs in the name of the user.
2665
+ *
2666
+ * For example, if you are using [Sign in with Google](/docs/guides/auth/social-login/auth-google) you may want to use the provider token to call Google APIs on behalf of the user. Supabase Auth does not keep track of the provider access and refresh token, but does return them for you once, immediately after sign in. You can use the `onAuthStateChange` method to listen for the presence of the provider tokens and store them in local storage. You can further send them to your server's APIs for use on the backend.
2667
+ *
2668
+ * Finally, make sure you remove them from local storage on the `SIGNED_OUT` event. If the OAuth provider supports token revocation, make sure you call those APIs either from the frontend or schedule them to be called on the backend.
2669
+ *
2670
+ * @example Store OAuth provider tokens on sign in
2671
+ * ```js
2672
+ * // Register this immediately after calling createClient!
2673
+ * // Because signInWithOAuth causes a redirect, you need to fetch the
2674
+ * // provider tokens from the callback.
2675
+ * supabase.auth.onAuthStateChange((event, session) => {
2676
+ * if (session && session.provider_token) {
2677
+ * window.localStorage.setItem('oauth_provider_token', session.provider_token)
2678
+ * }
2679
+ *
2680
+ * if (session && session.provider_refresh_token) {
2681
+ * window.localStorage.setItem('oauth_provider_refresh_token', session.provider_refresh_token)
2682
+ * }
2683
+ *
2684
+ * if (event === 'SIGNED_OUT') {
2685
+ * window.localStorage.removeItem('oauth_provider_token')
2686
+ * window.localStorage.removeItem('oauth_provider_refresh_token')
2687
+ * }
2688
+ * })
2689
+ * ```
2690
+ *
2691
+ * @exampleDescription Use React Context for the User's session
2692
+ * Instead of relying on `supabase.auth.getSession()` within your React components, you can use a [React Context](https://react.dev/reference/react/createContext) to store the latest session information from the `onAuthStateChange` callback and access it that way.
2693
+ *
2694
+ * @example Use React Context for the User's session
2695
+ * ```js
2696
+ * const SessionContext = React.createContext(null)
2697
+ *
2698
+ * function main() {
2699
+ * const [session, setSession] = React.useState(null)
2700
+ *
2701
+ * React.useEffect(() => {
2702
+ * const {data: { subscription }} = supabase.auth.onAuthStateChange(
2703
+ * (event, session) => {
2704
+ * if (event === 'SIGNED_OUT') {
2705
+ * setSession(null)
2706
+ * } else if (session) {
2707
+ * setSession(session)
2708
+ * }
2709
+ * })
2710
+ *
2711
+ * return () => {
2712
+ * subscription.unsubscribe()
2713
+ * }
2714
+ * }, [])
2715
+ *
2716
+ * return (
2717
+ * <SessionContext.Provider value={session}>
2718
+ * <App />
2719
+ * </SessionContext.Provider>
2720
+ * )
2721
+ * }
2722
+ * ```
2723
+ *
2724
+ * @example Listen to password recovery events
2725
+ * ```js
2726
+ * supabase.auth.onAuthStateChange((event, session) => {
2727
+ * if (event === 'PASSWORD_RECOVERY') {
2728
+ * console.log('PASSWORD_RECOVERY', session)
2729
+ * // show screen to update user's password
2730
+ * showPasswordResetScreen(true)
2731
+ * }
2732
+ * })
2733
+ * ```
2734
+ *
2735
+ * @example Listen to sign in
2736
+ * ```js
2737
+ * supabase.auth.onAuthStateChange((event, session) => {
2738
+ * if (event === 'SIGNED_IN') console.log('SIGNED_IN', session)
2739
+ * })
2740
+ * ```
2741
+ *
2742
+ * @example Listen to token refresh
2743
+ * ```js
2744
+ * supabase.auth.onAuthStateChange((event, session) => {
2745
+ * if (event === 'TOKEN_REFRESHED') console.log('TOKEN_REFRESHED', session)
2746
+ * })
2747
+ * ```
2748
+ *
2749
+ * @example Listen to user updates
2750
+ * ```js
2751
+ * supabase.auth.onAuthStateChange((event, session) => {
2752
+ * if (event === 'USER_UPDATED') console.log('USER_UPDATED', session)
2753
+ * })
2754
+ * ```
2755
+ */
2756
+ onAuthStateChange(callback) {
2757
+ let id = generateCallbackId(), subscription = {
2758
+ id,
2759
+ callback,
2760
+ unsubscribe: () => {
2761
+ this._debug("#unsubscribe()", "state change callback with id removed", id), this.stateChangeEmitters.delete(id);
2762
+ }
2763
+ };
2764
+ return this._debug("#onAuthStateChange()", "registered callback with id", id), this.stateChangeEmitters.set(id, subscription), (async () => (await this.initializePromise, this.lock != null ? await this._acquireLock(this.lockAcquireTimeout, async () => {
2765
+ this._emitInitialSession(id);
2766
+ }) : await this._emitInitialSession(id)))(), { data: { subscription } };
2767
+ }
2768
+ async _emitInitialSession(id) {
2769
+ return await this._useSession(async (result) => {
2770
+ var _a, _b;
2771
+ try {
2772
+ let { data: { session }, error } = result;
2773
+ if (error)
2774
+ throw error;
2775
+ await ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback("INITIAL_SESSION", session)), this._debug("INITIAL_SESSION", "callback id", id, "session", session);
2776
+ } catch (err) {
2777
+ if (await ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback("INITIAL_SESSION", null)), this._debug("INITIAL_SESSION", "callback id", id, "error", err), isAuthRefreshDiscardedError(err))
2778
+ return;
2779
+ isAuthSessionMissingError(err) || isAuthRetryableFetchError(err) || isAuthApiError(err) && (err.code === "refresh_token_not_found" || err.code === "refresh_token_already_used" || err.code === "session_expired") ? console.warn(err) : console.error(err);
2780
+ }
2781
+ });
2782
+ }
2783
+ async resetPasswordForEmail(email, options = {}) {
2784
+ let codeChallenge = null, codeChallengeMethod = null, flowId = null;
2785
+ this.flowType === "pkce" && ([codeChallenge, codeChallengeMethod, flowId] = await this._getCodeChallengeAndMethod(
2786
+ !0
2787
+ // isPasswordRecovery
2788
+ ));
2789
+ try {
2790
+ return await _request(this.fetch, "POST", `${this.url}/recover`, {
2791
+ body: {
2792
+ email,
2793
+ code_challenge: codeChallenge,
2794
+ code_challenge_method: codeChallengeMethod,
2795
+ gotrue_meta_security: { captcha_token: options.captchaToken }
2796
+ },
2797
+ headers: this.headers,
2798
+ redirectTo: this._maybeAppendFlowIdToRedirect(options.redirectTo, flowId)
2799
+ });
2800
+ } catch (error) {
2801
+ if (await removePKCEVerifier(this.storage, this.storageKey, flowId), isAuthError(error))
2802
+ return this._returnResult({ data: null, error });
2803
+ throw error;
2804
+ }
2805
+ }
2806
+ async getUserIdentities() {
2807
+ var _a;
2808
+ try {
2809
+ let { data, error } = await this.getUser();
2810
+ if (error)
2811
+ throw error;
2812
+ return this._returnResult({ data: { identities: (_a = data.user.identities) !== null && _a !== void 0 ? _a : [] }, error: null });
2813
+ } catch (error) {
2814
+ if (isAuthError(error))
2815
+ return this._returnResult({ data: null, error });
2816
+ throw error;
2817
+ }
2818
+ }
2819
+ /** *
2820
+ * @category Auth
2821
+ *
2822
+ * @remarks
2823
+ * - The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/auth/providers).
2824
+ * - The user needs to be signed in to call `linkIdentity()`.
2825
+ * - If the candidate identity is already linked to the existing user or another user, `linkIdentity()` will fail.
2826
+ * - If `linkIdentity` is run in the browser, the user is automatically redirected to the returned URL. On the server, you should handle the redirect.
2827
+ *
2828
+ * @example Link an identity to a user
2829
+ * ```js
2830
+ * const { data, error } = await supabase.auth.linkIdentity({
2831
+ * provider: 'github'
2832
+ * })
2833
+ * ```
2834
+ *
2835
+ * @exampleResponse Link an identity to a user
2836
+ * ```json
2837
+ * {
2838
+ * data: {
2839
+ * provider: 'github',
2840
+ * url: <PROVIDER_URL_TO_REDIRECT_TO>,
2841
+ * flowId: <PKCE_FLOW_ID_OR_NULL>
2842
+ * },
2843
+ * error: null
2844
+ * }
2845
+ * ```
2846
+ */
2847
+ async linkIdentity(credentials) {
2848
+ return "token" in credentials ? this.linkIdentityIdToken(credentials) : this.linkIdentityOAuth(credentials);
2849
+ }
2850
+ async linkIdentityOAuth(credentials) {
2851
+ var _a;
2852
+ let flowId = null;
2853
+ try {
2854
+ let { data, error } = await this._useSession(async (result) => {
2855
+ var _a2, _b, _c, _d, _f;
2856
+ let { data: data2, error: error2 } = result;
2857
+ if (error2)
2858
+ throw error2;
2859
+ let { url, flowId: urlFlowId } = await this._getUrlForProvider(`${this.url}/user/identities/authorize`, credentials.provider, {
2860
+ redirectTo: (_a2 = credentials.options) === null || _a2 === void 0 ? void 0 : _a2.redirectTo,
2861
+ scopes: (_b = credentials.options) === null || _b === void 0 ? void 0 : _b.scopes,
2862
+ queryParams: (_c = credentials.options) === null || _c === void 0 ? void 0 : _c.queryParams,
2863
+ skipBrowserRedirect: !0
2864
+ });
2865
+ return flowId = urlFlowId, await _request(this.fetch, "GET", url, {
2866
+ headers: this.headers,
2867
+ jwt: (_f = (_d = data2.session) === null || _d === void 0 ? void 0 : _d.access_token) !== null && _f !== void 0 ? _f : void 0
2868
+ });
2869
+ });
2870
+ if (error)
2871
+ throw error;
2872
+ return isBrowser() && !(!((_a = credentials.options) === null || _a === void 0) && _a.skipBrowserRedirect) && window.location.assign(data?.url), this._returnResult({
2873
+ data: { provider: credentials.provider, url: data?.url, flowId },
2874
+ error: null
2875
+ });
2876
+ } catch (error) {
2877
+ if (isAuthError(error))
2878
+ return this._returnResult({
2879
+ data: { provider: credentials.provider, url: null, flowId },
2880
+ error
2881
+ });
2882
+ throw error;
2883
+ }
2884
+ }
2885
+ async linkIdentityIdToken(credentials) {
2886
+ return await this._useSession(async (result) => {
2887
+ var _a;
2888
+ try {
2889
+ let { error: sessionError, data: { session } } = result;
2890
+ if (sessionError)
2891
+ throw sessionError;
2892
+ let { options, provider, token, access_token, nonce } = credentials, res = await _request(this.fetch, "POST", `${this.url}/token?grant_type=id_token`, {
2893
+ headers: this.headers,
2894
+ jwt: (_a = session?.access_token) !== null && _a !== void 0 ? _a : void 0,
2895
+ body: {
2896
+ provider,
2897
+ id_token: token,
2898
+ access_token,
2899
+ nonce,
2900
+ link_identity: !0,
2901
+ gotrue_meta_security: { captcha_token: options?.captchaToken }
2902
+ },
2903
+ xform: _sessionResponse
2904
+ }), { data, error } = res;
2905
+ return error ? this._returnResult({ data: { user: null, session: null }, error }) : !data || !data.session || !data.user ? this._returnResult({
2906
+ data: { user: null, session: null },
2907
+ error: new AuthInvalidTokenResponseError()
2908
+ }) : (data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("USER_UPDATED", data.session)), this._returnResult({ data, error }));
2909
+ } catch (error) {
2910
+ if (await removePKCEVerifier(this.storage, this.storageKey, null), isAuthError(error))
2911
+ return this._returnResult({ data: { user: null, session: null }, error });
2912
+ throw error;
2913
+ }
2914
+ });
2915
+ }
2916
+ async unlinkIdentity(identity) {
2917
+ try {
2918
+ return await this._useSession(async (result) => {
2919
+ var _a, _b;
2920
+ let { data, error } = result;
2921
+ if (error)
2922
+ throw error;
2923
+ return await _request(this.fetch, "DELETE", `${this.url}/user/identities/${identity.identity_id}`, {
2924
+ headers: this.headers,
2925
+ jwt: (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : void 0
2926
+ });
2927
+ });
2928
+ } catch (error) {
2929
+ if (isAuthError(error))
2930
+ return this._returnResult({ data: null, error });
2931
+ throw error;
2932
+ }
2933
+ }
2934
+ async _refreshAccessToken(refreshToken) {
2935
+ let debugName = "#_refreshAccessToken()";
2936
+ this._debug(debugName, "begin");
2937
+ try {
2938
+ let startedAt = Date.now();
2939
+ return await retryable(async (attempt) => (attempt > 0 && await sleep(200 * Math.pow(2, attempt - 1)), this._debug(debugName, "refreshing attempt", attempt), await _request(this.fetch, "POST", `${this.url}/token?grant_type=refresh_token`, {
2940
+ body: { refresh_token: refreshToken },
2941
+ headers: this.headers,
2942
+ xform: _sessionResponse
2943
+ })), (attempt, error) => {
2944
+ let nextBackOffInterval = 200 * Math.pow(2, attempt);
2945
+ return error && isAuthRetryableFetchError(error) && // retryable only if the request can be sent before the backoff overflows the tick duration
2946
+ Date.now() + nextBackOffInterval - startedAt < AUTO_REFRESH_TICK_DURATION_MS;
2947
+ });
2948
+ } catch (error) {
2949
+ if (this._debug(debugName, "error", error), isAuthError(error))
2950
+ return this._returnResult({ data: { session: null, user: null }, error });
2951
+ throw error;
2952
+ } finally {
2953
+ this._debug(debugName, "end");
2954
+ }
2955
+ }
2956
+ _isValidSession(maybeSession) {
2957
+ return typeof maybeSession == "object" && maybeSession !== null && "access_token" in maybeSession && "refresh_token" in maybeSession && "expires_at" in maybeSession;
2958
+ }
2959
+ async _handleProviderSignIn(provider, options) {
2960
+ let { url, flowId } = await this._getUrlForProvider(`${this.url}/authorize`, provider, {
2961
+ redirectTo: options.redirectTo,
2962
+ scopes: options.scopes,
2963
+ queryParams: options.queryParams
2964
+ });
2965
+ return this._debug("#_handleProviderSignIn()", "provider", provider, "options", options, "url", url), isBrowser() && !options.skipBrowserRedirect && window.location.assign(url), { data: { provider, url, flowId }, error: null };
2966
+ }
2967
+ async _recoverAndRefresh() {
2968
+ var _a, _b;
2969
+ let debugName = "#_recoverAndRefresh()";
2970
+ this._debug(debugName, "begin");
2971
+ try {
2972
+ let currentSession = await getItemAsync(this.storage, this.storageKey);
2973
+ if (currentSession && this.userStorage) {
2974
+ let maybeUser = await getItemAsync(this.userStorage, this.storageKey + "-user");
2975
+ !this.storage.isServer && Object.is(this.storage, this.userStorage) && !maybeUser && (maybeUser = { user: currentSession.user }, await setItemAsync(this.userStorage, this.storageKey + "-user", maybeUser)), currentSession.user = (_a = maybeUser?.user) !== null && _a !== void 0 ? _a : userNotAvailableProxy();
2976
+ } else if (currentSession && !currentSession.user && !currentSession.user) {
2977
+ let separateUser = await getItemAsync(this.storage, this.storageKey + "-user");
2978
+ separateUser && separateUser?.user ? (currentSession.user = separateUser.user, await removeItemAsync(this.storage, this.storageKey + "-user"), await setItemAsync(this.storage, this.storageKey, currentSession)) : currentSession.user = userNotAvailableProxy();
2979
+ }
2980
+ if (this._debug(debugName, "session from storage", currentSession), !this._isValidSession(currentSession)) {
2981
+ this._debug(debugName, "session is not valid"), currentSession !== null && await this._removeSession();
2982
+ return;
2983
+ }
2984
+ let expiresWithMargin = ((_b = currentSession.expires_at) !== null && _b !== void 0 ? _b : 1 / 0) * 1e3 - Date.now() < EXPIRY_MARGIN_MS;
2985
+ if (this._debug(debugName, `session has${expiresWithMargin ? "" : " not"} expired with margin of ${EXPIRY_MARGIN_MS}s`), expiresWithMargin) {
2986
+ if (this.autoRefreshToken && currentSession.refresh_token) {
2987
+ let { error } = await this._callRefreshToken(currentSession.refresh_token);
2988
+ error && (isAuthRefreshDiscardedError(error) ? this._debug(debugName, "refresh discarded by commit guard", error) : this._debug(debugName, "refresh failed", error));
2989
+ }
2990
+ } else if (currentSession.user && currentSession.user.__isUserNotAvailableProxy === !0)
2991
+ try {
2992
+ let { data, error: userError } = await this._getUser(currentSession.access_token);
2993
+ !userError && data?.user ? (currentSession.user = data.user, await this._saveSession(currentSession), await this._notifyAllSubscribers("SIGNED_IN", currentSession)) : this._debug(debugName, "could not get user data, skipping SIGNED_IN notification");
2994
+ } catch (getUserError) {
2995
+ console.error("Error getting user data:", getUserError), this._debug(debugName, "error getting user data, skipping SIGNED_IN notification", getUserError);
2996
+ }
2997
+ else
2998
+ await this._notifyAllSubscribers("SIGNED_IN", currentSession);
2999
+ } catch (err) {
3000
+ this._debug(debugName, "error", err), isAuthRetryableFetchError(err) ? console.warn(err) : console.error(err);
3001
+ return;
3002
+ } finally {
3003
+ this._debug(debugName, "end");
3004
+ }
3005
+ }
3006
+ async _callRefreshToken(refreshToken) {
3007
+ var _a, _b;
3008
+ if (!refreshToken)
3009
+ throw new AuthSessionMissingError();
3010
+ if (this.refreshingDeferred)
3011
+ return this.refreshingDeferred.promise;
3012
+ if (this.lastRefreshFailure && this.lastRefreshFailure.refreshToken === refreshToken && Date.now() < this.lastRefreshFailure.expiresAt)
3013
+ return this._debug("#_callRefreshToken()", "returning cached failure (cooldown active)"), this.lastRefreshFailure.result;
3014
+ let debugName = "#_callRefreshToken()";
3015
+ this._debug(debugName, "begin");
3016
+ try {
3017
+ this.refreshingDeferred = new Deferred(), this.refreshingDeferred.promise.then(void 0, () => {
3018
+ });
3019
+ let storedAtStart = await getItemAsync(this.storage, this.storageKey), { data, error } = await this._refreshAccessToken(refreshToken);
3020
+ if (error)
3021
+ throw error;
3022
+ if (!data.session)
3023
+ throw new AuthSessionMissingError();
3024
+ let storedAfter = await getItemAsync(this.storage, this.storageKey);
3025
+ if (storedAtStart !== null && (storedAfter === null || storedAfter.refresh_token !== storedAtStart.refresh_token)) {
3026
+ this._debug(debugName, "commit guard: storage changed since refresh started, discarding rotated tokens", {
3027
+ // Presence indicators only — never log refresh token fragments,
3028
+ // even partial. Logs may be forwarded to third-party services.
3029
+ startedWith: "present",
3030
+ nowHolds: storedAfter ? "replaced" : "cleared"
3031
+ });
3032
+ let discarded = {
3033
+ data: null,
3034
+ error: new AuthRefreshDiscardedError()
3035
+ };
3036
+ return this.refreshingDeferred.resolve(discarded), discarded;
3037
+ }
3038
+ let epochBeforeSave = this._sessionRemovalEpoch;
3039
+ if (await this._saveSession(data.session), this._sessionRemovalEpoch !== epochBeforeSave) {
3040
+ this._debug(debugName, "commit guard (post-save): _removeSession ran during _saveSession, undoing write"), await removeItemAsync(this.storage, this.storageKey), this.userStorage && await removeItemAsync(this.userStorage, this.storageKey + "-user");
3041
+ let discarded = {
3042
+ data: null,
3043
+ error: new AuthRefreshDiscardedError()
3044
+ };
3045
+ return this.refreshingDeferred.resolve(discarded), discarded;
3046
+ }
3047
+ await this._notifyAllSubscribers("TOKEN_REFRESHED", data.session);
3048
+ let result = { data: data.session, error: null };
3049
+ return this.lastRefreshFailure = null, this.refreshingDeferred.resolve(result), result;
3050
+ } catch (error) {
3051
+ if (this._debug(debugName, "error", error), isAuthError(error)) {
3052
+ let result = { data: null, error };
3053
+ if (!isAuthRetryableFetchError(error)) {
3054
+ let storedNow = await getItemAsync(this.storage, this.storageKey);
3055
+ !!(storedNow?.expires_at && storedNow.expires_at * 1e3 > Date.now()) ? this._debug(debugName, "proactive refresh failed, access token still valid \u2014 preserving session") : await this._removeSession();
3056
+ }
3057
+ return this.lastRefreshFailure = {
3058
+ refreshToken,
3059
+ result,
3060
+ expiresAt: Date.now() + REFRESH_FAILURE_COOLDOWN_MS
3061
+ }, (_a = this.refreshingDeferred) === null || _a === void 0 || _a.resolve(result), result;
3062
+ }
3063
+ throw (_b = this.refreshingDeferred) === null || _b === void 0 || _b.reject(error), error;
3064
+ } finally {
3065
+ this.refreshingDeferred = null, this._debug(debugName, "end");
3066
+ }
3067
+ }
3068
+ async _notifyAllSubscribers(event, session, broadcast = !0) {
3069
+ if (this._pendingInitNotifications !== null && broadcast) {
3070
+ this._pendingInitNotifications.push({ event, session, broadcast });
3071
+ return;
3072
+ }
3073
+ let debugName = `#_notifyAllSubscribers(${event})`;
3074
+ this._debug(debugName, "begin", session, `broadcast = ${broadcast}`);
3075
+ try {
3076
+ this.broadcastChannel && broadcast && this.broadcastChannel.postMessage({ event, session });
3077
+ let errors = [], promises = Array.from(this.stateChangeEmitters.values()).map(async (x) => {
3078
+ try {
3079
+ await x.callback(event, session);
3080
+ } catch (e) {
3081
+ errors.push(e);
3082
+ }
3083
+ });
3084
+ if (await Promise.all(promises), errors.length > 0) {
3085
+ for (let i = 0; i < errors.length; i += 1)
3086
+ console.error(errors[i]);
3087
+ throw errors[0];
3088
+ }
3089
+ } finally {
3090
+ this._debug(debugName, "end");
3091
+ }
3092
+ }
3093
+ async _saveSession(session) {
3094
+ this._debug("#_saveSession()", session), this.suppressGetSessionWarning = !0;
3095
+ let sessionToProcess = Object.assign({}, session), userIsProxy = sessionToProcess.user && sessionToProcess.user.__isUserNotAvailableProxy === !0;
3096
+ if (this.userStorage) {
3097
+ !userIsProxy && sessionToProcess.user && await setItemAsync(this.userStorage, this.storageKey + "-user", {
3098
+ user: sessionToProcess.user
3099
+ });
3100
+ let mainSessionData = Object.assign({}, sessionToProcess);
3101
+ delete mainSessionData.user;
3102
+ let clonedMainSessionData = deepClone(mainSessionData);
3103
+ await setItemAsync(this.storage, this.storageKey, clonedMainSessionData);
3104
+ } else {
3105
+ let clonedSession = deepClone(sessionToProcess);
3106
+ await setItemAsync(this.storage, this.storageKey, clonedSession);
3107
+ }
3108
+ }
3109
+ async _removeSession() {
3110
+ this._sessionRemovalEpoch += 1, this._debug("#_removeSession()"), this.lastRefreshFailure = null, this.suppressGetSessionWarning = !1, await removeItemAsync(this.storage, this.storageKey), await removeAllPKCEVerifiers(this.storage, this.storageKey), await removeItemAsync(this.storage, this.storageKey + "-user"), this.userStorage && await removeItemAsync(this.userStorage, this.storageKey + "-user"), await this._notifyAllSubscribers("SIGNED_OUT", null);
3111
+ }
3112
+ _removeVisibilityChangedCallback() {
3113
+ this._debug("#_removeVisibilityChangedCallback()");
3114
+ let callback = this.visibilityChangedCallback;
3115
+ this.visibilityChangedCallback = null;
3116
+ try {
3117
+ callback && isBrowser() && window?.removeEventListener && window.removeEventListener("visibilitychange", callback);
3118
+ } catch (e) {
3119
+ console.error("removing visibilitychange callback failed", e);
3120
+ }
3121
+ }
3122
+ async _startAutoRefresh() {
3123
+ await this._stopAutoRefresh(), this._debug("#_startAutoRefresh()");
3124
+ let ticker = setInterval(() => this._autoRefreshTokenTick(), AUTO_REFRESH_TICK_DURATION_MS);
3125
+ this.autoRefreshTicker = ticker, ticker && typeof ticker == "object" && typeof ticker.unref == "function" ? ticker.unref() : typeof Deno < "u" && typeof Deno.unrefTimer == "function" && Deno.unrefTimer(ticker);
3126
+ let timeout = setTimeout(async () => {
3127
+ await this.initializePromise, await this._autoRefreshTokenTick();
3128
+ }, 0);
3129
+ this.autoRefreshTickTimeout = timeout, timeout && typeof timeout == "object" && typeof timeout.unref == "function" ? timeout.unref() : typeof Deno < "u" && typeof Deno.unrefTimer == "function" && Deno.unrefTimer(timeout);
3130
+ }
3131
+ async _stopAutoRefresh() {
3132
+ this._debug("#_stopAutoRefresh()");
3133
+ let ticker = this.autoRefreshTicker;
3134
+ this.autoRefreshTicker = null, ticker && clearInterval(ticker);
3135
+ let timeout = this.autoRefreshTickTimeout;
3136
+ this.autoRefreshTickTimeout = null, timeout && clearTimeout(timeout);
3137
+ }
3138
+ async startAutoRefresh() {
3139
+ this._removeVisibilityChangedCallback(), await this._startAutoRefresh();
3140
+ }
3141
+ async stopAutoRefresh() {
3142
+ this._removeVisibilityChangedCallback(), await this._stopAutoRefresh();
3143
+ }
3144
+ async dispose() {
3145
+ var _a;
3146
+ this._removeVisibilityChangedCallback(), await this._stopAutoRefresh(), (_a = this.broadcastChannel) === null || _a === void 0 || _a.close(), this.broadcastChannel = null, this.stateChangeEmitters.clear();
3147
+ }
3148
+ async _autoRefreshTokenTick() {
3149
+ if (this._debug("#_autoRefreshTokenTick()", "begin"), this.lock != null) {
3150
+ try {
3151
+ await this._acquireLock(0, async () => {
3152
+ try {
3153
+ let now = Date.now();
3154
+ try {
3155
+ return await this._useSession(async (result) => {
3156
+ let { data: { session } } = result;
3157
+ if (!session || !session.refresh_token || !session.expires_at) {
3158
+ this._debug("#_autoRefreshTokenTick()", "no session");
3159
+ return;
3160
+ }
3161
+ let expiresInTicks = Math.floor((session.expires_at * 1e3 - now) / AUTO_REFRESH_TICK_DURATION_MS);
3162
+ this._debug("#_autoRefreshTokenTick()", `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION_MS}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`), expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD && await this._callRefreshToken(session.refresh_token);
3163
+ });
3164
+ } catch (e) {
3165
+ console.error("Auto refresh tick failed with error. This is likely a transient error.", e);
3166
+ }
3167
+ } finally {
3168
+ this._debug("#_autoRefreshTokenTick()", "end");
3169
+ }
3170
+ });
3171
+ } catch (e) {
3172
+ if (e instanceof LockAcquireTimeoutError)
3173
+ this._debug("auto refresh token tick lock not available");
3174
+ else
3175
+ throw e;
3176
+ }
3177
+ return;
3178
+ }
3179
+ if (this.refreshingDeferred !== null) {
3180
+ this._debug("#_autoRefreshTokenTick()", "refresh already in flight, skipping");
3181
+ return;
3182
+ }
3183
+ try {
3184
+ let now = Date.now();
3185
+ try {
3186
+ await this._useSession(async (result) => {
3187
+ let { data: { session } } = result;
3188
+ if (!session || !session.refresh_token || !session.expires_at) {
3189
+ this._debug("#_autoRefreshTokenTick()", "no session");
3190
+ return;
3191
+ }
3192
+ let expiresInTicks = Math.floor((session.expires_at * 1e3 - now) / AUTO_REFRESH_TICK_DURATION_MS);
3193
+ this._debug("#_autoRefreshTokenTick()", `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION_MS}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`), expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD && await this._callRefreshToken(session.refresh_token);
3194
+ });
3195
+ } catch (e) {
3196
+ console.error("Auto refresh tick failed with error. This is likely a transient error.", e);
3197
+ }
3198
+ } finally {
3199
+ this._debug("#_autoRefreshTokenTick()", "end");
3200
+ }
3201
+ }
3202
+ async _handleVisibilityChange() {
3203
+ if (this._debug("#_handleVisibilityChange()"), !isBrowser() || !window?.addEventListener)
3204
+ return this.autoRefreshToken && this.startAutoRefresh(), !1;
3205
+ try {
3206
+ this.visibilityChangedCallback = async () => {
3207
+ try {
3208
+ await this._onVisibilityChanged(!1);
3209
+ } catch (error) {
3210
+ this._debug("#visibilityChangedCallback", "error", error);
3211
+ }
3212
+ }, window?.addEventListener("visibilitychange", this.visibilityChangedCallback), await this._onVisibilityChanged(!0);
3213
+ } catch (error) {
3214
+ console.error("_handleVisibilityChange", error);
3215
+ }
3216
+ }
3217
+ async _onVisibilityChanged(calledFromInitialize) {
3218
+ let methodName = `#_onVisibilityChanged(${calledFromInitialize})`;
3219
+ if (this._debug(methodName, "visibilityState", document.visibilityState), document.visibilityState === "visible") {
3220
+ if (this.autoRefreshToken && this._startAutoRefresh(), !calledFromInitialize)
3221
+ if (await this.initializePromise, this.lock != null)
3222
+ await this._acquireLock(this.lockAcquireTimeout, async () => {
3223
+ if (document.visibilityState !== "visible") {
3224
+ this._debug(methodName, "acquired the lock to recover the session, but the browser visibilityState is no longer visible, aborting");
3225
+ return;
3226
+ }
3227
+ await this._recoverAndRefresh();
3228
+ });
3229
+ else {
3230
+ if (document.visibilityState !== "visible") {
3231
+ this._debug(methodName, "visibilityState is no longer visible, skipping recovery");
3232
+ return;
3233
+ }
3234
+ await this._recoverAndRefresh();
3235
+ }
3236
+ } else document.visibilityState === "hidden" && this.autoRefreshToken && this._stopAutoRefresh();
3237
+ }
3238
+ async _getUrlForProvider(url, provider, options) {
3239
+ let redirectTo = options?.redirectTo, codeChallenge = null, codeChallengeMethod = null, flowId = null;
3240
+ this.flowType === "pkce" && ([codeChallenge, codeChallengeMethod, flowId] = await this._getCodeChallengeAndMethod(), redirectTo = this._maybeAppendFlowIdToRedirect(redirectTo, flowId));
3241
+ let urlParams = [`provider=${encodeURIComponent(provider)}`];
3242
+ if (redirectTo && urlParams.push(`redirect_to=${encodeURIComponent(redirectTo)}`), options?.scopes && urlParams.push(`scopes=${encodeURIComponent(options.scopes)}`), codeChallenge != null && codeChallengeMethod != null) {
3243
+ let flowParams = new URLSearchParams({
3244
+ code_challenge: `${encodeURIComponent(codeChallenge)}`,
3245
+ code_challenge_method: `${encodeURIComponent(codeChallengeMethod)}`
3246
+ });
3247
+ urlParams.push(flowParams.toString());
3248
+ }
3249
+ if (options?.queryParams) {
3250
+ let query = new URLSearchParams(options.queryParams);
3251
+ urlParams.push(query.toString());
3252
+ }
3253
+ return options?.skipBrowserRedirect && urlParams.push(`skip_http_redirect=${options.skipBrowserRedirect}`), { url: `${url}?${urlParams.join("&")}`, flowId };
3254
+ }
3255
+ _maybeAppendFlowIdToRedirect(redirectTo, flowId) {
3256
+ return !redirectTo || !flowId || !this.experimental.appendPkceFlowIdToRedirects ? redirectTo ?? void 0 : appendFlowIdToRedirectTo(redirectTo, flowId);
3257
+ }
3258
+ async _getCodeChallengeAndMethod(isPasswordRecovery = !1) {
3259
+ return getCodeChallengeAndMethod(this.storage, this.storageKey, isPasswordRecovery, (evictedFlowId) => this._debug("#_getCodeChallengeAndMethod()", "evicted oldest pending PKCE verifier slot", evictedFlowId));
3260
+ }
3261
+ async _unenroll(params) {
3262
+ try {
3263
+ return await this._useSession(async (result) => {
3264
+ var _a;
3265
+ let { data: sessionData, error: sessionError } = result;
3266
+ return sessionError ? this._returnResult({ data: null, error: sessionError }) : await _request(this.fetch, "DELETE", `${this.url}/factors/${params.factorId}`, {
3267
+ headers: this.headers,
3268
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3269
+ });
3270
+ });
3271
+ } catch (error) {
3272
+ if (isAuthError(error))
3273
+ return this._returnResult({ data: null, error });
3274
+ throw error;
3275
+ }
3276
+ }
3277
+ async _enroll(params) {
3278
+ try {
3279
+ return await this._useSession(async (result) => {
3280
+ var _a, _b;
3281
+ let { data: sessionData, error: sessionError } = result;
3282
+ if (sessionError)
3283
+ return this._returnResult({ data: null, error: sessionError });
3284
+ let body = Object.assign({ friendly_name: params.friendlyName, factor_type: params.factorType }, params.factorType === "phone" ? { phone: params.phone } : params.factorType === "totp" ? { issuer: params.issuer } : {}), { data, error } = await _request(this.fetch, "POST", `${this.url}/factors`, {
3285
+ body,
3286
+ headers: this.headers,
3287
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3288
+ });
3289
+ return error ? this._returnResult({ data: null, error }) : (params.factorType === "totp" && data.type === "totp" && (!((_b = data?.totp) === null || _b === void 0) && _b.qr_code) && (data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`), this._returnResult({ data, error: null }));
3290
+ });
3291
+ } catch (error) {
3292
+ if (isAuthError(error))
3293
+ return this._returnResult({ data: null, error });
3294
+ throw error;
3295
+ }
3296
+ }
3297
+ async _verify(params) {
3298
+ let run = async () => {
3299
+ try {
3300
+ return await this._useSession(async (result) => {
3301
+ var _a;
3302
+ let { data: sessionData, error: sessionError } = result;
3303
+ if (sessionError)
3304
+ return this._returnResult({ data: null, error: sessionError });
3305
+ let body = Object.assign({ challenge_id: params.challengeId }, "webauthn" in params ? {
3306
+ webauthn: Object.assign(Object.assign({}, params.webauthn), { credential_response: params.webauthn.type === "create" ? serializeCredentialCreationResponse(params.webauthn.credential_response) : serializeCredentialRequestResponse(params.webauthn.credential_response) })
3307
+ } : { code: params.code }), { data, error } = await _request(this.fetch, "POST", `${this.url}/factors/${params.factorId}/verify`, {
3308
+ body,
3309
+ headers: this.headers,
3310
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3311
+ });
3312
+ return error ? this._returnResult({ data: null, error }) : (await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1e3) + data.expires_in }, data)), await this._notifyAllSubscribers("MFA_CHALLENGE_VERIFIED", data), this._returnResult({ data, error }));
3313
+ });
3314
+ } catch (error) {
3315
+ if (isAuthError(error))
3316
+ return this._returnResult({ data: null, error });
3317
+ throw error;
3318
+ }
3319
+ };
3320
+ return this.lock != null ? this._acquireLock(this.lockAcquireTimeout, run) : run();
3321
+ }
3322
+ async _challenge(params) {
3323
+ let run = async () => {
3324
+ try {
3325
+ return await this._useSession(async (result) => {
3326
+ var _a;
3327
+ let { data: sessionData, error: sessionError } = result;
3328
+ if (sessionError)
3329
+ return this._returnResult({ data: null, error: sessionError });
3330
+ let response = await _request(this.fetch, "POST", `${this.url}/factors/${params.factorId}/challenge`, {
3331
+ body: params,
3332
+ headers: this.headers,
3333
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3334
+ });
3335
+ if (response.error)
3336
+ return response;
3337
+ let { data } = response;
3338
+ if (data.type !== "webauthn")
3339
+ return { data, error: null };
3340
+ switch (data.webauthn.type) {
3341
+ case "create":
3342
+ return {
3343
+ data: Object.assign(Object.assign({}, data), { webauthn: Object.assign(Object.assign({}, data.webauthn), { credential_options: Object.assign(Object.assign({}, data.webauthn.credential_options), { publicKey: deserializeCredentialCreationOptions(data.webauthn.credential_options.publicKey) }) }) }),
3344
+ error: null
3345
+ };
3346
+ case "request":
3347
+ return {
3348
+ data: Object.assign(Object.assign({}, data), { webauthn: Object.assign(Object.assign({}, data.webauthn), { credential_options: Object.assign(Object.assign({}, data.webauthn.credential_options), { publicKey: deserializeCredentialRequestOptions(data.webauthn.credential_options.publicKey) }) }) }),
3349
+ error: null
3350
+ };
3351
+ }
3352
+ });
3353
+ } catch (error) {
3354
+ if (isAuthError(error))
3355
+ return this._returnResult({ data: null, error });
3356
+ throw error;
3357
+ }
3358
+ };
3359
+ return this.lock != null ? this._acquireLock(this.lockAcquireTimeout, run) : run();
3360
+ }
3361
+ async _challengeAndVerify(params) {
3362
+ let { data: challengeData, error: challengeError } = await this._challenge({
3363
+ factorId: params.factorId
3364
+ });
3365
+ return challengeError ? this._returnResult({ data: null, error: challengeError }) : await this._verify({
3366
+ factorId: params.factorId,
3367
+ challengeId: challengeData.id,
3368
+ code: params.code
3369
+ });
3370
+ }
3371
+ async _listFactors() {
3372
+ var _a;
3373
+ let { data: { user }, error: userError } = await this.getUser();
3374
+ if (userError)
3375
+ return { data: null, error: userError };
3376
+ let data = {
3377
+ all: [],
3378
+ phone: [],
3379
+ totp: [],
3380
+ webauthn: [],
3381
+ recovery_code: []
3382
+ };
3383
+ for (let factor of (_a = user?.factors) !== null && _a !== void 0 ? _a : [])
3384
+ data.all.push(factor), factor.status === "verified" && factor.factor_type in data && Array.isArray(data[factor.factor_type]) && data[factor.factor_type].push(factor);
3385
+ return {
3386
+ data,
3387
+ error: null
3388
+ };
3389
+ }
3390
+ async _getAuthenticatorAssuranceLevel(jwt) {
3391
+ var _a, _b, _c, _d;
3392
+ if (jwt)
3393
+ try {
3394
+ let { payload: payload2 } = decodeJWT(jwt), currentLevel2 = null;
3395
+ payload2.aal && (currentLevel2 = payload2.aal);
3396
+ let nextLevel2 = currentLevel2, { data: { user }, error: userError } = await this.getUser(jwt);
3397
+ if (userError)
3398
+ return this._returnResult({ data: null, error: userError });
3399
+ ((_b = (_a = user?.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === "verified")) !== null && _b !== void 0 ? _b : []).length > 0 && (nextLevel2 = "aal2");
3400
+ let currentAuthenticationMethods2 = payload2.amr || [];
3401
+ return { data: { currentLevel: currentLevel2, nextLevel: nextLevel2, currentAuthenticationMethods: currentAuthenticationMethods2 }, error: null };
3402
+ } catch (error) {
3403
+ if (isAuthError(error))
3404
+ return this._returnResult({ data: null, error });
3405
+ throw error;
3406
+ }
3407
+ let { data: { session }, error: sessionError } = await this.getSession();
3408
+ if (sessionError)
3409
+ return this._returnResult({ data: null, error: sessionError });
3410
+ if (!session)
3411
+ return {
3412
+ data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
3413
+ error: null
3414
+ };
3415
+ let { payload } = decodeJWT(session.access_token), currentLevel = null;
3416
+ payload.aal && (currentLevel = payload.aal);
3417
+ let nextLevel = currentLevel;
3418
+ ((_d = (_c = session.user.factors) === null || _c === void 0 ? void 0 : _c.filter((factor) => factor.status === "verified")) !== null && _d !== void 0 ? _d : []).length > 0 && (nextLevel = "aal2");
3419
+ let currentAuthenticationMethods = payload.amr || [];
3420
+ return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null };
3421
+ }
3422
+ async _getRecoveryCodesStatus() {
3423
+ assertRecoveryCodesExperimentalEnabled(this.experimental);
3424
+ try {
3425
+ return await this._useSession(async (result) => {
3426
+ var _a;
3427
+ let { data: sessionData, error: sessionError } = result;
3428
+ if (sessionError)
3429
+ return this._returnResult({ data: null, error: sessionError });
3430
+ let { data, error } = await _request(this.fetch, "GET", `${this.url}/factors/recovery-codes`, {
3431
+ headers: this.headers,
3432
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3433
+ });
3434
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3435
+ });
3436
+ } catch (error) {
3437
+ if (isAuthError(error))
3438
+ return this._returnResult({ data: null, error });
3439
+ throw error;
3440
+ }
3441
+ }
3442
+ async _generateRecoveryCodes(params) {
3443
+ assertRecoveryCodesExperimentalEnabled(this.experimental);
3444
+ try {
3445
+ return await this._useSession(async (result) => {
3446
+ var _a;
3447
+ let { data: sessionData, error: sessionError } = result;
3448
+ if (sessionError)
3449
+ return this._returnResult({ data: null, error: sessionError });
3450
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/factors/recovery-codes`, {
3451
+ // The body is optional server-side; only send one when a name was given.
3452
+ body: params?.friendlyName ? { friendly_name: params.friendlyName } : void 0,
3453
+ headers: this.headers,
3454
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3455
+ });
3456
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3457
+ });
3458
+ } catch (error) {
3459
+ if (isAuthError(error))
3460
+ return this._returnResult({ data: null, error });
3461
+ throw error;
3462
+ }
3463
+ }
3464
+ async _verifyRecoveryCode(params) {
3465
+ assertRecoveryCodesExperimentalEnabled(this.experimental);
3466
+ let run = async () => {
3467
+ try {
3468
+ return await this._useSession(async (result) => {
3469
+ var _a;
3470
+ let { data: sessionData, error: sessionError } = result;
3471
+ if (sessionError)
3472
+ return this._returnResult({ data: null, error: sessionError });
3473
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/factors/recovery-codes/verify`, {
3474
+ body: { code: params.code },
3475
+ headers: this.headers,
3476
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3477
+ });
3478
+ if (error)
3479
+ return this._returnResult({ data: null, error });
3480
+ let session = Object.assign({ expires_at: expiresAt(data.expires_in) }, data);
3481
+ return await this._saveSession(session), await this._notifyAllSubscribers("MFA_CHALLENGE_VERIFIED", session), this._returnResult({ data, error: null });
3482
+ });
3483
+ } catch (error) {
3484
+ if (isAuthError(error))
3485
+ return this._returnResult({ data: null, error });
3486
+ throw error;
3487
+ }
3488
+ };
3489
+ return this.lock != null ? this._acquireLock(this.lockAcquireTimeout, run) : run();
3490
+ }
3491
+ async _regenerateRecoveryCodes() {
3492
+ assertRecoveryCodesExperimentalEnabled(this.experimental);
3493
+ try {
3494
+ return await this._useSession(async (result) => {
3495
+ var _a;
3496
+ let { data: sessionData, error: sessionError } = result;
3497
+ if (sessionError)
3498
+ return this._returnResult({ data: null, error: sessionError });
3499
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/factors/recovery-codes/regenerate`, {
3500
+ headers: this.headers,
3501
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3502
+ });
3503
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3504
+ });
3505
+ } catch (error) {
3506
+ if (isAuthError(error))
3507
+ return this._returnResult({ data: null, error });
3508
+ throw error;
3509
+ }
3510
+ }
3511
+ async _unenrollRecoveryCodes() {
3512
+ assertRecoveryCodesExperimentalEnabled(this.experimental);
3513
+ try {
3514
+ return await this._useSession(async (result) => {
3515
+ var _a;
3516
+ let { data: sessionData, error: sessionError } = result;
3517
+ if (sessionError)
3518
+ return this._returnResult({ data: null, error: sessionError });
3519
+ let { data, error } = await _request(this.fetch, "DELETE", `${this.url}/factors/recovery-codes`, {
3520
+ headers: this.headers,
3521
+ jwt: (_a = sessionData?.session) === null || _a === void 0 ? void 0 : _a.access_token
3522
+ });
3523
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3524
+ });
3525
+ } catch (error) {
3526
+ if (isAuthError(error))
3527
+ return this._returnResult({ data: null, error });
3528
+ throw error;
3529
+ }
3530
+ }
3531
+ async _getAuthorizationDetails(authorizationId) {
3532
+ try {
3533
+ return await this._useSession(async (result) => {
3534
+ let { data: { session }, error: sessionError } = result;
3535
+ return sessionError ? this._returnResult({ data: null, error: sessionError }) : session ? await _request(this.fetch, "GET", `${this.url}/oauth/authorizations/${authorizationId}`, {
3536
+ headers: this.headers,
3537
+ jwt: session.access_token,
3538
+ xform: (data) => ({ data, error: null })
3539
+ }) : this._returnResult({ data: null, error: new AuthSessionMissingError() });
3540
+ });
3541
+ } catch (error) {
3542
+ if (isAuthError(error))
3543
+ return this._returnResult({ data: null, error });
3544
+ throw error;
3545
+ }
3546
+ }
3547
+ async _approveAuthorization(authorizationId, options) {
3548
+ try {
3549
+ return await this._useSession(async (result) => {
3550
+ let { data: { session }, error: sessionError } = result;
3551
+ if (sessionError)
3552
+ return this._returnResult({ data: null, error: sessionError });
3553
+ if (!session)
3554
+ return this._returnResult({ data: null, error: new AuthSessionMissingError() });
3555
+ let response = await _request(this.fetch, "POST", `${this.url}/oauth/authorizations/${authorizationId}/consent`, {
3556
+ headers: this.headers,
3557
+ jwt: session.access_token,
3558
+ body: { action: "approve" },
3559
+ xform: (data) => ({ data, error: null })
3560
+ });
3561
+ return response.data && response.data.redirect_url && isBrowser() && !options?.skipBrowserRedirect && window.location.assign(response.data.redirect_url), response;
3562
+ });
3563
+ } catch (error) {
3564
+ if (isAuthError(error))
3565
+ return this._returnResult({ data: null, error });
3566
+ throw error;
3567
+ }
3568
+ }
3569
+ async _denyAuthorization(authorizationId, options) {
3570
+ try {
3571
+ return await this._useSession(async (result) => {
3572
+ let { data: { session }, error: sessionError } = result;
3573
+ if (sessionError)
3574
+ return this._returnResult({ data: null, error: sessionError });
3575
+ if (!session)
3576
+ return this._returnResult({ data: null, error: new AuthSessionMissingError() });
3577
+ let response = await _request(this.fetch, "POST", `${this.url}/oauth/authorizations/${authorizationId}/consent`, {
3578
+ headers: this.headers,
3579
+ jwt: session.access_token,
3580
+ body: { action: "deny" },
3581
+ xform: (data) => ({ data, error: null })
3582
+ });
3583
+ return response.data && response.data.redirect_url && isBrowser() && !options?.skipBrowserRedirect && window.location.assign(response.data.redirect_url), response;
3584
+ });
3585
+ } catch (error) {
3586
+ if (isAuthError(error))
3587
+ return this._returnResult({ data: null, error });
3588
+ throw error;
3589
+ }
3590
+ }
3591
+ async _listOAuthGrants() {
3592
+ try {
3593
+ return await this._useSession(async (result) => {
3594
+ let { data: { session }, error: sessionError } = result;
3595
+ return sessionError ? this._returnResult({ data: null, error: sessionError }) : session ? await _request(this.fetch, "GET", `${this.url}/user/oauth/grants`, {
3596
+ headers: this.headers,
3597
+ jwt: session.access_token,
3598
+ xform: (data) => ({ data, error: null })
3599
+ }) : this._returnResult({ data: null, error: new AuthSessionMissingError() });
3600
+ });
3601
+ } catch (error) {
3602
+ if (isAuthError(error))
3603
+ return this._returnResult({ data: null, error });
3604
+ throw error;
3605
+ }
3606
+ }
3607
+ async _revokeOAuthGrant(options) {
3608
+ try {
3609
+ return await this._useSession(async (result) => {
3610
+ let { data: { session }, error: sessionError } = result;
3611
+ return sessionError ? this._returnResult({ data: null, error: sessionError }) : session ? (await _request(this.fetch, "DELETE", `${this.url}/user/oauth/grants`, {
3612
+ headers: this.headers,
3613
+ jwt: session.access_token,
3614
+ query: { client_id: options.clientId },
3615
+ noResolveJson: !0
3616
+ }), { data: {}, error: null }) : this._returnResult({ data: null, error: new AuthSessionMissingError() });
3617
+ });
3618
+ } catch (error) {
3619
+ if (isAuthError(error))
3620
+ return this._returnResult({ data: null, error });
3621
+ throw error;
3622
+ }
3623
+ }
3624
+ async fetchJwk(kid, jwks = { keys: [] }) {
3625
+ let jwk = jwks.keys.find((key) => key.kid === kid);
3626
+ if (jwk)
3627
+ return jwk;
3628
+ let now = Date.now();
3629
+ if (jwk = this.jwks.keys.find((key) => key.kid === kid), jwk && this.jwks_cached_at + JWKS_TTL > now)
3630
+ return jwk;
3631
+ let { data, error } = await _request(this.fetch, "GET", `${this.url}/.well-known/jwks.json`, {
3632
+ headers: this.headers
3633
+ });
3634
+ if (error)
3635
+ throw error;
3636
+ return !data.keys || data.keys.length === 0 || (this.jwks = data, this.jwks_cached_at = now, jwk = data.keys.find((key) => key.kid === kid), !jwk) ? null : jwk;
3637
+ }
3638
+ async getClaims(jwt, options = {}) {
3639
+ try {
3640
+ let token = jwt;
3641
+ if (!token) {
3642
+ let { data, error } = await this.getSession();
3643
+ if (error || !data.session)
3644
+ return this._returnResult({ data: null, error });
3645
+ token = data.session.access_token;
3646
+ }
3647
+ let { header, payload, signature, raw: { header: rawHeader, payload: rawPayload } } = decodeJWT(token);
3648
+ if (!options?.allowExpired)
3649
+ try {
3650
+ validateExp(payload.exp);
3651
+ } catch (e) {
3652
+ throw new AuthInvalidJwtError(e instanceof Error ? e.message : "JWT validation failed");
3653
+ }
3654
+ let signingKey = !header.alg || header.alg.startsWith("HS") || !header.kid || !("crypto" in globalThis && "subtle" in globalThis.crypto) ? null : await this.fetchJwk(header.kid, options?.keys ? { keys: options.keys } : options?.jwks);
3655
+ if (!signingKey) {
3656
+ let { error } = await this.getUser(token);
3657
+ if (error)
3658
+ throw error;
3659
+ return {
3660
+ data: {
3661
+ claims: payload,
3662
+ header,
3663
+ signature
3664
+ },
3665
+ error: null
3666
+ };
3667
+ }
3668
+ let algorithm = getAlgorithm(header.alg), publicKey = await crypto.subtle.importKey("jwk", signingKey, algorithm, !0, [
3669
+ "verify"
3670
+ ]);
3671
+ if (!await crypto.subtle.verify(algorithm, publicKey, signature, stringToUint8Array(`${rawHeader}.${rawPayload}`)))
3672
+ throw new AuthInvalidJwtError("Invalid JWT signature");
3673
+ return {
3674
+ data: {
3675
+ claims: payload,
3676
+ header,
3677
+ signature
3678
+ },
3679
+ error: null
3680
+ };
3681
+ } catch (error) {
3682
+ if (isAuthError(error))
3683
+ return this._returnResult({ data: null, error });
3684
+ throw error;
3685
+ }
3686
+ }
3687
+ // --- Passkey Methods ---
3688
+ async signInWithPasskey(credentials) {
3689
+ var _a, _b, _c;
3690
+ assertPasskeyExperimentalEnabled(this.experimental);
3691
+ try {
3692
+ if (!browserSupportsWebAuthn())
3693
+ return this._returnResult({
3694
+ data: null,
3695
+ error: new AuthUnknownError("Browser does not support WebAuthn", null)
3696
+ });
3697
+ let { data: options, error: optionsError } = await this._startPasskeyAuthentication({
3698
+ options: { captchaToken: (_a = credentials?.options) === null || _a === void 0 ? void 0 : _a.captchaToken }
3699
+ });
3700
+ if (optionsError || !options)
3701
+ return this._returnResult({ data: null, error: optionsError });
3702
+ let publicKeyOptions = deserializeCredentialRequestOptions(options.options), signal = (_c = (_b = credentials?.options) === null || _b === void 0 ? void 0 : _b.signal) !== null && _c !== void 0 ? _c : webAuthnAbortService.createNewAbortSignal(), { data: credential, error: credentialError } = await getCredential({
3703
+ publicKey: publicKeyOptions,
3704
+ signal
3705
+ });
3706
+ if (credentialError || !credential)
3707
+ return this._returnResult({
3708
+ data: null,
3709
+ error: credentialError ?? new AuthUnknownError("WebAuthn ceremony failed", null)
3710
+ });
3711
+ let serialized = serializeCredentialRequestResponse(credential);
3712
+ return this._verifyPasskeyAuthentication({
3713
+ challengeId: options.challenge_id,
3714
+ credential: serialized
3715
+ });
3716
+ } catch (error) {
3717
+ if (isAuthError(error))
3718
+ return this._returnResult({ data: null, error });
3719
+ throw error;
3720
+ }
3721
+ }
3722
+ async registerPasskey(credentials) {
3723
+ var _a, _b;
3724
+ assertPasskeyExperimentalEnabled(this.experimental);
3725
+ try {
3726
+ if (!browserSupportsWebAuthn())
3727
+ return this._returnResult({
3728
+ data: null,
3729
+ error: new AuthUnknownError("Browser does not support WebAuthn", null)
3730
+ });
3731
+ let { data: options, error: optionsError } = await this._startPasskeyRegistration();
3732
+ if (optionsError || !options)
3733
+ return this._returnResult({ data: null, error: optionsError });
3734
+ let publicKeyOptions = deserializeCredentialCreationOptions(options.options), signal = (_b = (_a = credentials?.options) === null || _a === void 0 ? void 0 : _a.signal) !== null && _b !== void 0 ? _b : webAuthnAbortService.createNewAbortSignal(), { data: credential, error: credentialError } = await createCredential({
3735
+ publicKey: publicKeyOptions,
3736
+ signal
3737
+ });
3738
+ if (credentialError || !credential)
3739
+ return this._returnResult({
3740
+ data: null,
3741
+ error: credentialError ?? new AuthUnknownError("WebAuthn ceremony failed", null)
3742
+ });
3743
+ let serialized = serializeCredentialCreationResponse(credential);
3744
+ return this._verifyPasskeyRegistration({
3745
+ challengeId: options.challenge_id,
3746
+ credential: serialized
3747
+ });
3748
+ } catch (error) {
3749
+ if (isAuthError(error))
3750
+ return this._returnResult({ data: null, error });
3751
+ throw error;
3752
+ }
3753
+ }
3754
+ async _startPasskeyRegistration() {
3755
+ assertPasskeyExperimentalEnabled(this.experimental);
3756
+ try {
3757
+ return await this._useSession(async (result) => {
3758
+ let { data: { session }, error: sessionError } = result;
3759
+ if (sessionError)
3760
+ return this._returnResult({ data: null, error: sessionError });
3761
+ if (!session)
3762
+ return this._returnResult({ data: null, error: new AuthSessionMissingError() });
3763
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/passkeys/registration/options`, {
3764
+ headers: this.headers,
3765
+ jwt: session.access_token,
3766
+ body: {}
3767
+ });
3768
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3769
+ });
3770
+ } catch (error) {
3771
+ if (isAuthError(error))
3772
+ return this._returnResult({ data: null, error });
3773
+ throw error;
3774
+ }
3775
+ }
3776
+ async _verifyPasskeyRegistration(params) {
3777
+ assertPasskeyExperimentalEnabled(this.experimental);
3778
+ try {
3779
+ return await this._useSession(async (result) => {
3780
+ let { data: { session }, error: sessionError } = result;
3781
+ if (sessionError)
3782
+ return this._returnResult({ data: null, error: sessionError });
3783
+ if (!session)
3784
+ return this._returnResult({ data: null, error: new AuthSessionMissingError() });
3785
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/passkeys/registration/verify`, {
3786
+ headers: this.headers,
3787
+ jwt: session.access_token,
3788
+ body: {
3789
+ challenge_id: params.challengeId,
3790
+ credential: params.credential
3791
+ }
3792
+ });
3793
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3794
+ });
3795
+ } catch (error) {
3796
+ if (isAuthError(error))
3797
+ return this._returnResult({ data: null, error });
3798
+ throw error;
3799
+ }
3800
+ }
3801
+ async _startPasskeyAuthentication(params) {
3802
+ var _a;
3803
+ assertPasskeyExperimentalEnabled(this.experimental);
3804
+ try {
3805
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/passkeys/authentication/options`, {
3806
+ headers: this.headers,
3807
+ body: {
3808
+ gotrue_meta_security: { captcha_token: (_a = params?.options) === null || _a === void 0 ? void 0 : _a.captchaToken }
3809
+ }
3810
+ });
3811
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3812
+ } catch (error) {
3813
+ if (isAuthError(error))
3814
+ return this._returnResult({ data: null, error });
3815
+ throw error;
3816
+ }
3817
+ }
3818
+ async _verifyPasskeyAuthentication(params) {
3819
+ assertPasskeyExperimentalEnabled(this.experimental);
3820
+ try {
3821
+ let { data, error } = await _request(this.fetch, "POST", `${this.url}/passkeys/authentication/verify`, {
3822
+ headers: this.headers,
3823
+ body: {
3824
+ challenge_id: params.challengeId,
3825
+ credential: params.credential
3826
+ },
3827
+ xform: _sessionResponse
3828
+ });
3829
+ return error ? this._returnResult({ data: null, error }) : (data.session && (await this._saveSession(data.session), await this._notifyAllSubscribers("SIGNED_IN", data.session)), this._returnResult({ data, error: null }));
3830
+ } catch (error) {
3831
+ if (isAuthError(error))
3832
+ return this._returnResult({ data: null, error });
3833
+ throw error;
3834
+ }
3835
+ }
3836
+ async _listPasskeys() {
3837
+ assertPasskeyExperimentalEnabled(this.experimental);
3838
+ try {
3839
+ return await this._useSession(async (result) => {
3840
+ let { data: { session }, error: sessionError } = result;
3841
+ if (sessionError)
3842
+ return this._returnResult({ data: null, error: sessionError });
3843
+ if (!session)
3844
+ return this._returnResult({ data: null, error: new AuthSessionMissingError() });
3845
+ let { data, error } = await _request(this.fetch, "GET", `${this.url}/passkeys`, {
3846
+ headers: this.headers,
3847
+ jwt: session.access_token,
3848
+ xform: (data2) => ({ data: data2, error: null })
3849
+ });
3850
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3851
+ });
3852
+ } catch (error) {
3853
+ if (isAuthError(error))
3854
+ return this._returnResult({ data: null, error });
3855
+ throw error;
3856
+ }
3857
+ }
3858
+ async _updatePasskey(params) {
3859
+ assertPasskeyExperimentalEnabled(this.experimental);
3860
+ try {
3861
+ return await this._useSession(async (result) => {
3862
+ let { data: { session }, error: sessionError } = result;
3863
+ if (sessionError)
3864
+ return this._returnResult({ data: null, error: sessionError });
3865
+ if (!session)
3866
+ return this._returnResult({ data: null, error: new AuthSessionMissingError() });
3867
+ let { data, error } = await _request(this.fetch, "PATCH", `${this.url}/passkeys/${params.passkeyId}`, {
3868
+ headers: this.headers,
3869
+ jwt: session.access_token,
3870
+ body: { friendly_name: params.friendlyName }
3871
+ });
3872
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data, error: null });
3873
+ });
3874
+ } catch (error) {
3875
+ if (isAuthError(error))
3876
+ return this._returnResult({ data: null, error });
3877
+ throw error;
3878
+ }
3879
+ }
3880
+ async _deletePasskey(params) {
3881
+ assertPasskeyExperimentalEnabled(this.experimental);
3882
+ try {
3883
+ return await this._useSession(async (result) => {
3884
+ let { data: { session }, error: sessionError } = result;
3885
+ if (sessionError)
3886
+ return this._returnResult({ data: null, error: sessionError });
3887
+ if (!session)
3888
+ return this._returnResult({ data: null, error: new AuthSessionMissingError() });
3889
+ let { error } = await _request(this.fetch, "DELETE", `${this.url}/passkeys/${params.passkeyId}`, {
3890
+ headers: this.headers,
3891
+ jwt: session.access_token,
3892
+ noResolveJson: !0
3893
+ });
3894
+ return error ? this._returnResult({ data: null, error }) : this._returnResult({ data: null, error: null });
3895
+ });
3896
+ } catch (error) {
3897
+ if (isAuthError(error))
3898
+ return this._returnResult({ data: null, error });
3899
+ throw error;
3900
+ }
3901
+ }
3902
+ };
3903
+ GoTrueClient.nextInstanceID = {};
3904
+ var GoTrueClient_default = GoTrueClient;
3905
+
3906
+ var AuthClient = GoTrueClient_default, AuthClient_default = AuthClient;
3907
+ export {
3908
+ AuthClient_default as AuthClient
3909
+ };