@supabase/gotrue-js 3.0.0-next.2 → 3.0.0-next.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main/GoTrueAdminApi.d.ts +28 -4
- package/dist/main/GoTrueAdminApi.d.ts.map +1 -1
- package/dist/main/GoTrueAdminApi.js +50 -3
- package/dist/main/GoTrueAdminApi.js.map +1 -1
- package/dist/main/GoTrueClient.d.ts +80 -7
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +387 -35
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/lib/fetch.d.ts +28 -8
- package/dist/main/lib/fetch.d.ts.map +1 -1
- package/dist/main/lib/fetch.js +15 -2
- package/dist/main/lib/fetch.js.map +1 -1
- package/dist/main/lib/helpers.d.ts +4 -1
- package/dist/main/lib/helpers.d.ts.map +1 -1
- package/dist/main/lib/helpers.js +9 -3
- package/dist/main/lib/helpers.js.map +1 -1
- package/dist/main/lib/locks.d.ts.map +1 -1
- package/dist/main/lib/locks.js +8 -3
- package/dist/main/lib/locks.js.map +1 -1
- package/dist/main/lib/types.d.ts +138 -11
- package/dist/main/lib/types.d.ts.map +1 -1
- package/dist/main/lib/types.js.map +1 -1
- package/dist/main/lib/version.d.ts +1 -1
- package/dist/main/lib/version.d.ts.map +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/main/lib/version.js.map +1 -1
- package/dist/main/lib/webauthn.d.ts +8 -0
- package/dist/main/lib/webauthn.d.ts.map +1 -1
- package/dist/main/lib/webauthn.dom.d.ts +3 -3
- package/dist/main/lib/webauthn.dom.d.ts.map +1 -1
- package/dist/main/lib/webauthn.errors.d.ts +5 -0
- package/dist/main/lib/webauthn.errors.d.ts.map +1 -1
- package/dist/main/lib/webauthn.errors.js +7 -0
- package/dist/main/lib/webauthn.errors.js.map +1 -1
- package/dist/main/lib/webauthn.js +1 -0
- package/dist/main/lib/webauthn.js.map +1 -1
- package/dist/module/GoTrueAdminApi.d.ts +28 -4
- package/dist/module/GoTrueAdminApi.d.ts.map +1 -1
- package/dist/module/GoTrueAdminApi.js +51 -4
- package/dist/module/GoTrueAdminApi.js.map +1 -1
- package/dist/module/GoTrueClient.d.ts +80 -7
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +389 -37
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/fetch.d.ts +28 -8
- package/dist/module/lib/fetch.d.ts.map +1 -1
- package/dist/module/lib/fetch.js +15 -2
- package/dist/module/lib/fetch.js.map +1 -1
- package/dist/module/lib/helpers.d.ts +4 -1
- package/dist/module/lib/helpers.d.ts.map +1 -1
- package/dist/module/lib/helpers.js +8 -3
- package/dist/module/lib/helpers.js.map +1 -1
- package/dist/module/lib/locks.d.ts.map +1 -1
- package/dist/module/lib/locks.js +8 -3
- package/dist/module/lib/locks.js.map +1 -1
- package/dist/module/lib/types.d.ts +138 -11
- package/dist/module/lib/types.d.ts.map +1 -1
- package/dist/module/lib/types.js.map +1 -1
- package/dist/module/lib/version.d.ts +1 -1
- package/dist/module/lib/version.d.ts.map +1 -1
- package/dist/module/lib/version.js +1 -1
- package/dist/module/lib/version.js.map +1 -1
- package/dist/module/lib/webauthn.d.ts +8 -0
- package/dist/module/lib/webauthn.d.ts.map +1 -1
- package/dist/module/lib/webauthn.dom.d.ts +3 -3
- package/dist/module/lib/webauthn.dom.d.ts.map +1 -1
- package/dist/module/lib/webauthn.errors.d.ts +5 -0
- package/dist/module/lib/webauthn.errors.d.ts.map +1 -1
- package/dist/module/lib/webauthn.errors.js +7 -0
- package/dist/module/lib/webauthn.errors.js.map +1 -1
- package/dist/module/lib/webauthn.js +1 -1
- package/dist/module/lib/webauthn.js.map +1 -1
- package/dist/tsconfig.module.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/GoTrueAdminApi.ts +82 -3
- package/src/GoTrueClient.ts +462 -15
- package/src/lib/fetch.ts +53 -19
- package/src/lib/helpers.ts +13 -5
- package/src/lib/locks.ts +14 -7
- package/src/lib/types.ts +195 -10
- package/src/lib/version.ts +1 -1
- package/src/lib/webauthn.dom.ts +3 -3
- package/src/lib/webauthn.errors.ts +12 -0
- package/src/lib/webauthn.ts +1 -1
|
@@ -2,14 +2,14 @@ import GoTrueAdminApi from './GoTrueAdminApi';
|
|
|
2
2
|
import { AUTO_REFRESH_TICK_DURATION_MS, AUTO_REFRESH_TICK_THRESHOLD, DEFAULT_HEADERS, EXPIRY_MARGIN_MS, GOTRUE_URL, JWKS_TTL, STORAGE_KEY, } from './lib/constants';
|
|
3
3
|
import { AuthImplicitGrantRedirectError, AuthInvalidCredentialsError, AuthInvalidJwtError, AuthInvalidTokenResponseError, AuthPKCECodeVerifierMissingError, AuthPKCEGrantCodeExchangeError, AuthSessionMissingError, AuthUnknownError, isAuthApiError, isAuthError, isAuthImplicitGrantRedirectError, isAuthRetryableFetchError, isAuthSessionMissingError, } from './lib/errors';
|
|
4
4
|
import { _request, _sessionResponse, _sessionResponsePassword, _ssoResponse, _userResponse, } from './lib/fetch';
|
|
5
|
-
import { decodeJWT, deepClone, Deferred, generateCallbackId, getAlgorithm, getCodeChallengeAndMethod, getItemAsync, insecureUserWarningProxy, isBrowser, parseParametersFromURL, removeItemAsync, resolveFetch, retryable, setItemAsync, sleep, supportsLocalStorage, userNotAvailableProxy, validateExp, } from './lib/helpers';
|
|
5
|
+
import { assertPasskeyExperimentalEnabled, decodeJWT, deepClone, Deferred, generateCallbackId, getAlgorithm, getCodeChallengeAndMethod, getItemAsync, insecureUserWarningProxy, isBrowser, parseParametersFromURL, removeItemAsync, resolveFetch, retryable, setItemAsync, sleep, supportsLocalStorage, userNotAvailableProxy, validateExp, } from './lib/helpers';
|
|
6
6
|
import { memoryLocalStorageAdapter } from './lib/local-storage';
|
|
7
7
|
import { LockAcquireTimeoutError, navigatorLock } from './lib/locks';
|
|
8
8
|
import { polyfillGlobalThis } from './lib/polyfills';
|
|
9
9
|
import { version } from './lib/version';
|
|
10
10
|
import { bytesToBase64URL, stringToUint8Array } from './lib/base64url';
|
|
11
11
|
import { createSiweMessage, fromHex, getAddress, toHex, } from './lib/web3/ethereum';
|
|
12
|
-
import { deserializeCredentialCreationOptions, deserializeCredentialRequestOptions, serializeCredentialCreationResponse, serializeCredentialRequestResponse, WebAuthnApi, } from './lib/webauthn';
|
|
12
|
+
import { createCredential, deserializeCredentialCreationOptions, deserializeCredentialRequestOptions, getCredential, serializeCredentialCreationResponse, serializeCredentialRequestResponse, browserSupportsWebAuthn, webAuthnAbortService, WebAuthnApi, } from './lib/webauthn';
|
|
13
13
|
polyfillGlobalThis(); // Make "globalThis" available
|
|
14
14
|
const DEFAULT_OPTIONS = {
|
|
15
15
|
url: GOTRUE_URL,
|
|
@@ -24,6 +24,7 @@ const DEFAULT_OPTIONS = {
|
|
|
24
24
|
throwOnError: false,
|
|
25
25
|
lockAcquireTimeout: 5000, // 5 seconds
|
|
26
26
|
skipAutoInitialize: false,
|
|
27
|
+
experimental: {},
|
|
27
28
|
};
|
|
28
29
|
async function lockNoOp(name, acquireTimeout, fn) {
|
|
29
30
|
return await fn();
|
|
@@ -62,7 +63,7 @@ class GoTrueClient {
|
|
|
62
63
|
* ```ts
|
|
63
64
|
* import { createClient } from '@supabase/supabase-js'
|
|
64
65
|
*
|
|
65
|
-
* const supabase = createClient('https://xyzcompany.supabase.co', 'publishable-
|
|
66
|
+
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
|
66
67
|
* const { data, error } = await supabase.auth.getUser()
|
|
67
68
|
* ```
|
|
68
69
|
*
|
|
@@ -72,13 +73,13 @@ class GoTrueClient {
|
|
|
72
73
|
*
|
|
73
74
|
* const auth = new GoTrueClient({
|
|
74
75
|
* url: 'https://xyzcompany.supabase.co/auth/v1',
|
|
75
|
-
* headers: { apikey: 'publishable-
|
|
76
|
+
* headers: { apikey: 'your-publishable-key' },
|
|
76
77
|
* storageKey: 'supabase-auth',
|
|
77
78
|
* })
|
|
78
79
|
* ```
|
|
79
80
|
*/
|
|
80
81
|
constructor(options) {
|
|
81
|
-
var _a, _b, _c;
|
|
82
|
+
var _a, _b, _c, _d;
|
|
82
83
|
/**
|
|
83
84
|
* @experimental
|
|
84
85
|
*/
|
|
@@ -123,10 +124,12 @@ class GoTrueClient {
|
|
|
123
124
|
}
|
|
124
125
|
this.persistSession = settings.persistSession;
|
|
125
126
|
this.autoRefreshToken = settings.autoRefreshToken;
|
|
127
|
+
this.experimental = (_b = settings.experimental) !== null && _b !== void 0 ? _b : {};
|
|
126
128
|
this.admin = new GoTrueAdminApi({
|
|
127
129
|
url: settings.url,
|
|
128
130
|
headers: settings.headers,
|
|
129
131
|
fetch: settings.fetch,
|
|
132
|
+
experimental: this.experimental,
|
|
130
133
|
});
|
|
131
134
|
this.url = settings.url;
|
|
132
135
|
this.headers = settings.headers;
|
|
@@ -140,7 +143,7 @@ class GoTrueClient {
|
|
|
140
143
|
if (settings.lock) {
|
|
141
144
|
this.lock = settings.lock;
|
|
142
145
|
}
|
|
143
|
-
else if (this.persistSession && isBrowser() && ((
|
|
146
|
+
else if (this.persistSession && isBrowser() && ((_c = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _c === void 0 ? void 0 : _c.locks)) {
|
|
144
147
|
this.lock = navigatorLock;
|
|
145
148
|
}
|
|
146
149
|
else {
|
|
@@ -167,6 +170,15 @@ class GoTrueClient {
|
|
|
167
170
|
listGrants: this._listOAuthGrants.bind(this),
|
|
168
171
|
revokeGrant: this._revokeOAuthGrant.bind(this),
|
|
169
172
|
};
|
|
173
|
+
this.passkey = {
|
|
174
|
+
startRegistration: this._startPasskeyRegistration.bind(this),
|
|
175
|
+
verifyRegistration: this._verifyPasskeyRegistration.bind(this),
|
|
176
|
+
startAuthentication: this._startPasskeyAuthentication.bind(this),
|
|
177
|
+
verifyAuthentication: this._verifyPasskeyAuthentication.bind(this),
|
|
178
|
+
list: this._listPasskeys.bind(this),
|
|
179
|
+
update: this._updatePasskey.bind(this),
|
|
180
|
+
delete: this._deletePasskey.bind(this),
|
|
181
|
+
};
|
|
170
182
|
if (this.persistSession) {
|
|
171
183
|
if (settings.storage) {
|
|
172
184
|
this.storage = settings.storage;
|
|
@@ -195,7 +207,7 @@ class GoTrueClient {
|
|
|
195
207
|
catch (e) {
|
|
196
208
|
console.error('Failed to create a new BroadcastChannel, multi-tab state changes will not be available', e);
|
|
197
209
|
}
|
|
198
|
-
(
|
|
210
|
+
(_d = this.broadcastChannel) === null || _d === void 0 ? void 0 : _d.addEventListener('message', async (event) => {
|
|
199
211
|
this._debug('received broadcast notification from other tab or client', event);
|
|
200
212
|
try {
|
|
201
213
|
await this._notifyAllSubscribers(event.data.event, event.data.session, false); // broadcast = false so we don't get an endless loop of messages
|
|
@@ -1210,7 +1222,7 @@ class GoTrueClient {
|
|
|
1210
1222
|
}
|
|
1211
1223
|
}
|
|
1212
1224
|
async signInWithEthereum(credentials) {
|
|
1213
|
-
var _a, _b, _c, _d,
|
|
1225
|
+
var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m;
|
|
1214
1226
|
// TODO: flatten type
|
|
1215
1227
|
let message;
|
|
1216
1228
|
let signature;
|
|
@@ -1270,11 +1282,11 @@ class GoTrueClient {
|
|
|
1270
1282
|
version: '1',
|
|
1271
1283
|
chainId: chainId,
|
|
1272
1284
|
nonce: (_c = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _c === void 0 ? void 0 : _c.nonce,
|
|
1273
|
-
issuedAt: (
|
|
1274
|
-
expirationTime: (
|
|
1275
|
-
notBefore: (
|
|
1276
|
-
requestId: (
|
|
1277
|
-
resources: (
|
|
1285
|
+
issuedAt: (_f = (_d = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _d === void 0 ? void 0 : _d.issuedAt) !== null && _f !== void 0 ? _f : new Date(),
|
|
1286
|
+
expirationTime: (_g = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _g === void 0 ? void 0 : _g.expirationTime,
|
|
1287
|
+
notBefore: (_h = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _h === void 0 ? void 0 : _h.notBefore,
|
|
1288
|
+
requestId: (_j = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _j === void 0 ? void 0 : _j.requestId,
|
|
1289
|
+
resources: (_k = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _k === void 0 ? void 0 : _k.resources,
|
|
1278
1290
|
};
|
|
1279
1291
|
message = createSiweMessage(siweMessage);
|
|
1280
1292
|
// Sign message
|
|
@@ -1287,8 +1299,8 @@ class GoTrueClient {
|
|
|
1287
1299
|
const { data, error } = await _request(this.fetch, 'POST', `${this.url}/token?grant_type=web3`, {
|
|
1288
1300
|
headers: this.headers,
|
|
1289
1301
|
body: Object.assign({ chain: 'ethereum', message,
|
|
1290
|
-
signature }, (((
|
|
1291
|
-
? { gotrue_meta_security: { captcha_token: (
|
|
1302
|
+
signature }, (((_l = credentials.options) === null || _l === void 0 ? void 0 : _l.captchaToken)
|
|
1303
|
+
? { gotrue_meta_security: { captcha_token: (_m = credentials.options) === null || _m === void 0 ? void 0 : _m.captchaToken } }
|
|
1292
1304
|
: null)),
|
|
1293
1305
|
xform: _sessionResponse,
|
|
1294
1306
|
});
|
|
@@ -1313,7 +1325,7 @@ class GoTrueClient {
|
|
|
1313
1325
|
}
|
|
1314
1326
|
}
|
|
1315
1327
|
async signInWithSolana(credentials) {
|
|
1316
|
-
var _a, _b, _c, _d,
|
|
1328
|
+
var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
1317
1329
|
let message;
|
|
1318
1330
|
let signature;
|
|
1319
1331
|
if ('message' in credentials) {
|
|
@@ -1398,17 +1410,17 @@ class GoTrueClient {
|
|
|
1398
1410
|
...(((_d = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _d === void 0 ? void 0 : _d.notBefore)
|
|
1399
1411
|
? [`Not Before: ${options.signInWithSolana.notBefore}`]
|
|
1400
1412
|
: []),
|
|
1401
|
-
...(((
|
|
1413
|
+
...(((_f = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _f === void 0 ? void 0 : _f.expirationTime)
|
|
1402
1414
|
? [`Expiration Time: ${options.signInWithSolana.expirationTime}`]
|
|
1403
1415
|
: []),
|
|
1404
|
-
...(((
|
|
1416
|
+
...(((_g = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _g === void 0 ? void 0 : _g.chainId)
|
|
1405
1417
|
? [`Chain ID: ${options.signInWithSolana.chainId}`]
|
|
1406
1418
|
: []),
|
|
1407
|
-
...(((
|
|
1408
|
-
...(((
|
|
1419
|
+
...(((_h = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _h === void 0 ? void 0 : _h.nonce) ? [`Nonce: ${options.signInWithSolana.nonce}`] : []),
|
|
1420
|
+
...(((_j = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _j === void 0 ? void 0 : _j.requestId)
|
|
1409
1421
|
? [`Request ID: ${options.signInWithSolana.requestId}`]
|
|
1410
1422
|
: []),
|
|
1411
|
-
...(((
|
|
1423
|
+
...(((_l = (_k = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _k === void 0 ? void 0 : _k.resources) === null || _l === void 0 ? void 0 : _l.length)
|
|
1412
1424
|
? [
|
|
1413
1425
|
'Resources',
|
|
1414
1426
|
...options.signInWithSolana.resources.map((resource) => `- ${resource}`),
|
|
@@ -1425,8 +1437,8 @@ class GoTrueClient {
|
|
|
1425
1437
|
try {
|
|
1426
1438
|
const { data, error } = await _request(this.fetch, 'POST', `${this.url}/token?grant_type=web3`, {
|
|
1427
1439
|
headers: this.headers,
|
|
1428
|
-
body: Object.assign({ chain: 'solana', message, signature: bytesToBase64URL(signature) }, (((
|
|
1429
|
-
? { gotrue_meta_security: { captcha_token: (
|
|
1440
|
+
body: Object.assign({ chain: 'solana', message, signature: bytesToBase64URL(signature) }, (((_m = credentials.options) === null || _m === void 0 ? void 0 : _m.captchaToken)
|
|
1441
|
+
? { gotrue_meta_security: { captcha_token: (_o = credentials.options) === null || _o === void 0 ? void 0 : _o.captchaToken } }
|
|
1430
1442
|
: null)),
|
|
1431
1443
|
xform: _sessionResponse,
|
|
1432
1444
|
});
|
|
@@ -1478,7 +1490,7 @@ class GoTrueClient {
|
|
|
1478
1490
|
}
|
|
1479
1491
|
if (data.session) {
|
|
1480
1492
|
await this._saveSession(data.session);
|
|
1481
|
-
await this._notifyAllSubscribers('SIGNED_IN', data.session);
|
|
1493
|
+
await this._notifyAllSubscribers(redirectType === 'recovery' ? 'PASSWORD_RECOVERY' : 'SIGNED_IN', data.session);
|
|
1482
1494
|
}
|
|
1483
1495
|
return this._returnResult({ data: Object.assign(Object.assign({}, data), { redirectType: redirectType !== null && redirectType !== void 0 ? redirectType : null }), error });
|
|
1484
1496
|
}
|
|
@@ -1681,7 +1693,7 @@ class GoTrueClient {
|
|
|
1681
1693
|
* ```
|
|
1682
1694
|
*/
|
|
1683
1695
|
async signInWithOtp(credentials) {
|
|
1684
|
-
var _a, _b, _c, _d,
|
|
1696
|
+
var _a, _b, _c, _d, _f;
|
|
1685
1697
|
try {
|
|
1686
1698
|
if ('email' in credentials) {
|
|
1687
1699
|
const { email, options } = credentials;
|
|
@@ -1714,7 +1726,7 @@ class GoTrueClient {
|
|
|
1714
1726
|
data: (_c = options === null || options === void 0 ? void 0 : options.data) !== null && _c !== void 0 ? _c : {},
|
|
1715
1727
|
create_user: (_d = options === null || options === void 0 ? void 0 : options.shouldCreateUser) !== null && _d !== void 0 ? _d : true,
|
|
1716
1728
|
gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
|
|
1717
|
-
channel: (
|
|
1729
|
+
channel: (_f = options === null || options === void 0 ? void 0 : options.channel) !== null && _f !== void 0 ? _f : 'sms',
|
|
1718
1730
|
},
|
|
1719
1731
|
});
|
|
1720
1732
|
return this._returnResult({
|
|
@@ -1960,7 +1972,7 @@ class GoTrueClient {
|
|
|
1960
1972
|
* ```
|
|
1961
1973
|
*/
|
|
1962
1974
|
async signInWithSSO(params) {
|
|
1963
|
-
var _a, _b, _c, _d,
|
|
1975
|
+
var _a, _b, _c, _d, _f;
|
|
1964
1976
|
try {
|
|
1965
1977
|
let codeChallenge = null;
|
|
1966
1978
|
let codeChallengeMethod = null;
|
|
@@ -1976,7 +1988,7 @@ class GoTrueClient {
|
|
|
1976
1988
|
xform: _ssoResponse,
|
|
1977
1989
|
});
|
|
1978
1990
|
// Automatically redirect in browser unless skipBrowserRedirect is true
|
|
1979
|
-
if (((_d = result.data) === null || _d === void 0 ? void 0 : _d.url) && isBrowser() && !((
|
|
1991
|
+
if (((_d = result.data) === null || _d === void 0 ? void 0 : _d.url) && isBrowser() && !((_f = params.options) === null || _f === void 0 ? void 0 : _f.skipBrowserRedirect)) {
|
|
1980
1992
|
window.location.assign(result.data.url);
|
|
1981
1993
|
}
|
|
1982
1994
|
return this._returnResult(result);
|
|
@@ -2249,7 +2261,7 @@ class GoTrueClient {
|
|
|
2249
2261
|
try {
|
|
2250
2262
|
await result;
|
|
2251
2263
|
}
|
|
2252
|
-
catch (
|
|
2264
|
+
catch (_e) {
|
|
2253
2265
|
// we just care if it finished
|
|
2254
2266
|
}
|
|
2255
2267
|
})());
|
|
@@ -3007,6 +3019,7 @@ class GoTrueClient {
|
|
|
3007
3019
|
* Gets the session data from a URL string
|
|
3008
3020
|
*/
|
|
3009
3021
|
async _getSessionFromURL(params, callbackUrlType) {
|
|
3022
|
+
var _a;
|
|
3010
3023
|
try {
|
|
3011
3024
|
if (!isBrowser())
|
|
3012
3025
|
throw new AuthImplicitGrantRedirectError('No browser detected.');
|
|
@@ -3045,7 +3058,10 @@ class GoTrueClient {
|
|
|
3045
3058
|
const url = new URL(window.location.href);
|
|
3046
3059
|
url.searchParams.delete('code');
|
|
3047
3060
|
window.history.replaceState(window.history.state, '', url.toString());
|
|
3048
|
-
return {
|
|
3061
|
+
return {
|
|
3062
|
+
data: { session: data.session, redirectType: (_a = data.redirectType) !== null && _a !== void 0 ? _a : null },
|
|
3063
|
+
error: null,
|
|
3064
|
+
};
|
|
3049
3065
|
}
|
|
3050
3066
|
const { provider_token, provider_refresh_token, access_token, refresh_token, expires_in, expires_at, token_type, } = params;
|
|
3051
3067
|
if (!access_token || !expires_in || !refresh_token || !token_type) {
|
|
@@ -3121,24 +3137,35 @@ class GoTrueClient {
|
|
|
3121
3137
|
*
|
|
3122
3138
|
* If using `others` scope, no `SIGNED_OUT` event is fired!
|
|
3123
3139
|
*
|
|
3140
|
+
* **Warning:** the default `scope` is `'global'`. This signs the user out of
|
|
3141
|
+
* **every device they are currently signed in on**, not just the current
|
|
3142
|
+
* tab/session. If you only want to sign the user out of the current session
|
|
3143
|
+
* (the behavior most other auth libraries default to), pass
|
|
3144
|
+
* `{ scope: 'local' }` explicitly.
|
|
3145
|
+
*
|
|
3124
3146
|
* @category Auth
|
|
3125
3147
|
*
|
|
3126
3148
|
* @remarks
|
|
3127
3149
|
* - In order to use the `signOut()` method, the user needs to be signed in first.
|
|
3128
|
-
* - By default, `signOut()` uses the global scope, which signs out
|
|
3150
|
+
* - By default, `signOut()` uses the **global** scope, which signs out the user
|
|
3151
|
+
* on every device they are signed in on (not just the current one). Pass
|
|
3152
|
+
* `{ scope: 'local' }` to only sign out the current session. This is
|
|
3153
|
+
* usually what apps want on a "Sign out" button, especially when users
|
|
3154
|
+
* sign in from multiple devices and do not expect signing out of one to
|
|
3155
|
+
* terminate the others.
|
|
3129
3156
|
* - Since Supabase Auth uses JWTs for authentication, the access token JWT will be valid until it's expired. When the user signs out, Supabase revokes the refresh token and deletes the JWT from the client-side. This does not revoke the JWT and it will still be valid until it expires.
|
|
3130
3157
|
*
|
|
3131
|
-
* @example Sign out (
|
|
3158
|
+
* @example Sign out of every device (global – default)
|
|
3132
3159
|
* ```js
|
|
3133
3160
|
* const { error } = await supabase.auth.signOut()
|
|
3134
3161
|
* ```
|
|
3135
3162
|
*
|
|
3136
|
-
* @example Sign out
|
|
3163
|
+
* @example Sign out only the current session (recommended for most apps)
|
|
3137
3164
|
* ```js
|
|
3138
3165
|
* const { error } = await supabase.auth.signOut({ scope: 'local' })
|
|
3139
3166
|
* ```
|
|
3140
3167
|
*
|
|
3141
|
-
* @example Sign out
|
|
3168
|
+
* @example Sign out of all other sessions, keep the current one
|
|
3142
3169
|
* ```js
|
|
3143
3170
|
* const { error } = await supabase.auth.signOut({ scope: 'others' })
|
|
3144
3171
|
* ```
|
|
@@ -3592,7 +3619,7 @@ class GoTrueClient {
|
|
|
3592
3619
|
var _a;
|
|
3593
3620
|
try {
|
|
3594
3621
|
const { data, error } = await this._useSession(async (result) => {
|
|
3595
|
-
var _a, _b, _c, _d,
|
|
3622
|
+
var _a, _b, _c, _d, _f;
|
|
3596
3623
|
const { data, error } = result;
|
|
3597
3624
|
if (error)
|
|
3598
3625
|
throw error;
|
|
@@ -3604,7 +3631,7 @@ class GoTrueClient {
|
|
|
3604
3631
|
});
|
|
3605
3632
|
return await _request(this.fetch, 'GET', url, {
|
|
3606
3633
|
headers: this.headers,
|
|
3607
|
-
jwt: (
|
|
3634
|
+
jwt: (_f = (_d = data.session) === null || _d === void 0 ? void 0 : _d.access_token) !== null && _f !== void 0 ? _f : undefined,
|
|
3608
3635
|
});
|
|
3609
3636
|
});
|
|
3610
3637
|
if (error)
|
|
@@ -4187,7 +4214,7 @@ class GoTrueClient {
|
|
|
4187
4214
|
});
|
|
4188
4215
|
}
|
|
4189
4216
|
catch (e) {
|
|
4190
|
-
if (e
|
|
4217
|
+
if (e instanceof LockAcquireTimeoutError) {
|
|
4191
4218
|
this._debug('auto refresh token tick lock not available');
|
|
4192
4219
|
}
|
|
4193
4220
|
else {
|
|
@@ -4852,6 +4879,331 @@ class GoTrueClient {
|
|
|
4852
4879
|
throw error;
|
|
4853
4880
|
}
|
|
4854
4881
|
}
|
|
4882
|
+
// --- Passkey Methods ---
|
|
4883
|
+
/**
|
|
4884
|
+
* Sign in with a passkey. Handles the full WebAuthn ceremony:
|
|
4885
|
+
* 1. Fetches authentication challenge from server
|
|
4886
|
+
* 2. Prompts user via navigator.credentials.get()
|
|
4887
|
+
* 3. Verifies credential with server and creates session
|
|
4888
|
+
*
|
|
4889
|
+
* Requires `auth.experimental.passkey: true`.
|
|
4890
|
+
*/
|
|
4891
|
+
async signInWithPasskey(credentials) {
|
|
4892
|
+
var _a, _b, _c;
|
|
4893
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
4894
|
+
try {
|
|
4895
|
+
if (!browserSupportsWebAuthn()) {
|
|
4896
|
+
return this._returnResult({
|
|
4897
|
+
data: null,
|
|
4898
|
+
error: new AuthUnknownError('Browser does not support WebAuthn', null),
|
|
4899
|
+
});
|
|
4900
|
+
}
|
|
4901
|
+
// 1. Get challenge options from server
|
|
4902
|
+
const { data: options, error: optionsError } = await this._startPasskeyAuthentication({
|
|
4903
|
+
options: { captchaToken: (_a = credentials === null || credentials === void 0 ? void 0 : credentials.options) === null || _a === void 0 ? void 0 : _a.captchaToken },
|
|
4904
|
+
});
|
|
4905
|
+
if (optionsError || !options) {
|
|
4906
|
+
return this._returnResult({ data: null, error: optionsError });
|
|
4907
|
+
}
|
|
4908
|
+
// 2. Deserialize and prompt user via browser WebAuthn API
|
|
4909
|
+
const publicKeyOptions = deserializeCredentialRequestOptions(options.options);
|
|
4910
|
+
const signal = (_c = (_b = credentials === null || credentials === void 0 ? void 0 : credentials.options) === null || _b === void 0 ? void 0 : _b.signal) !== null && _c !== void 0 ? _c : webAuthnAbortService.createNewAbortSignal();
|
|
4911
|
+
const { data: credential, error: credentialError } = await getCredential({
|
|
4912
|
+
publicKey: publicKeyOptions,
|
|
4913
|
+
signal,
|
|
4914
|
+
});
|
|
4915
|
+
if (credentialError || !credential) {
|
|
4916
|
+
return this._returnResult({
|
|
4917
|
+
data: null,
|
|
4918
|
+
error: credentialError !== null && credentialError !== void 0 ? credentialError : new AuthUnknownError('WebAuthn ceremony failed', null),
|
|
4919
|
+
});
|
|
4920
|
+
}
|
|
4921
|
+
// 3. Serialize and verify with server
|
|
4922
|
+
const serialized = serializeCredentialRequestResponse(credential);
|
|
4923
|
+
return this._verifyPasskeyAuthentication({
|
|
4924
|
+
challengeId: options.challenge_id,
|
|
4925
|
+
credential: serialized,
|
|
4926
|
+
});
|
|
4927
|
+
}
|
|
4928
|
+
catch (error) {
|
|
4929
|
+
if (isAuthError(error)) {
|
|
4930
|
+
return this._returnResult({ data: null, error });
|
|
4931
|
+
}
|
|
4932
|
+
throw error;
|
|
4933
|
+
}
|
|
4934
|
+
}
|
|
4935
|
+
/**
|
|
4936
|
+
* Register a passkey for the current authenticated user. Handles the full WebAuthn ceremony:
|
|
4937
|
+
* 1. Fetches registration challenge from server
|
|
4938
|
+
* 2. Prompts user via navigator.credentials.create()
|
|
4939
|
+
* 3. Verifies credential with server
|
|
4940
|
+
*
|
|
4941
|
+
* Requires an active session. Requires `auth.experimental.passkey: true`.
|
|
4942
|
+
*/
|
|
4943
|
+
async registerPasskey(credentials) {
|
|
4944
|
+
var _a, _b;
|
|
4945
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
4946
|
+
try {
|
|
4947
|
+
if (!browserSupportsWebAuthn()) {
|
|
4948
|
+
return this._returnResult({
|
|
4949
|
+
data: null,
|
|
4950
|
+
error: new AuthUnknownError('Browser does not support WebAuthn', null),
|
|
4951
|
+
});
|
|
4952
|
+
}
|
|
4953
|
+
// 1. Get challenge options from server
|
|
4954
|
+
const { data: options, error: optionsError } = await this._startPasskeyRegistration();
|
|
4955
|
+
if (optionsError || !options) {
|
|
4956
|
+
return this._returnResult({ data: null, error: optionsError });
|
|
4957
|
+
}
|
|
4958
|
+
// 2. Deserialize and prompt user via browser WebAuthn API
|
|
4959
|
+
const publicKeyOptions = deserializeCredentialCreationOptions(options.options);
|
|
4960
|
+
const signal = (_b = (_a = credentials === null || credentials === void 0 ? void 0 : credentials.options) === null || _a === void 0 ? void 0 : _a.signal) !== null && _b !== void 0 ? _b : webAuthnAbortService.createNewAbortSignal();
|
|
4961
|
+
const { data: credential, error: credentialError } = await createCredential({
|
|
4962
|
+
publicKey: publicKeyOptions,
|
|
4963
|
+
signal,
|
|
4964
|
+
});
|
|
4965
|
+
if (credentialError || !credential) {
|
|
4966
|
+
return this._returnResult({
|
|
4967
|
+
data: null,
|
|
4968
|
+
error: credentialError !== null && credentialError !== void 0 ? credentialError : new AuthUnknownError('WebAuthn ceremony failed', null),
|
|
4969
|
+
});
|
|
4970
|
+
}
|
|
4971
|
+
// 3. Serialize and verify with server
|
|
4972
|
+
const serialized = serializeCredentialCreationResponse(credential);
|
|
4973
|
+
return this._verifyPasskeyRegistration({
|
|
4974
|
+
challengeId: options.challenge_id,
|
|
4975
|
+
credential: serialized,
|
|
4976
|
+
});
|
|
4977
|
+
}
|
|
4978
|
+
catch (error) {
|
|
4979
|
+
if (isAuthError(error)) {
|
|
4980
|
+
return this._returnResult({ data: null, error });
|
|
4981
|
+
}
|
|
4982
|
+
throw error;
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
/**
|
|
4986
|
+
* Start passkey registration for the current authenticated user.
|
|
4987
|
+
* Returns WebAuthn credential creation options to pass to navigator.credentials.create().
|
|
4988
|
+
*/
|
|
4989
|
+
async _startPasskeyRegistration() {
|
|
4990
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
4991
|
+
try {
|
|
4992
|
+
return await this._useSession(async (result) => {
|
|
4993
|
+
const { data: { session }, error: sessionError, } = result;
|
|
4994
|
+
if (sessionError) {
|
|
4995
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
4996
|
+
}
|
|
4997
|
+
if (!session) {
|
|
4998
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() });
|
|
4999
|
+
}
|
|
5000
|
+
const { data, error } = await _request(this.fetch, 'POST', `${this.url}/passkeys/registration/options`, {
|
|
5001
|
+
headers: this.headers,
|
|
5002
|
+
jwt: session.access_token,
|
|
5003
|
+
body: {},
|
|
5004
|
+
});
|
|
5005
|
+
if (error) {
|
|
5006
|
+
return this._returnResult({ data: null, error });
|
|
5007
|
+
}
|
|
5008
|
+
return this._returnResult({ data, error: null });
|
|
5009
|
+
});
|
|
5010
|
+
}
|
|
5011
|
+
catch (error) {
|
|
5012
|
+
if (isAuthError(error)) {
|
|
5013
|
+
return this._returnResult({ data: null, error });
|
|
5014
|
+
}
|
|
5015
|
+
throw error;
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
/**
|
|
5019
|
+
* Verify passkey registration with the credential response.
|
|
5020
|
+
* The credentialResponse should be the serialized output of navigator.credentials.create().
|
|
5021
|
+
*/
|
|
5022
|
+
async _verifyPasskeyRegistration(params) {
|
|
5023
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
5024
|
+
try {
|
|
5025
|
+
return await this._useSession(async (result) => {
|
|
5026
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5027
|
+
if (sessionError) {
|
|
5028
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5029
|
+
}
|
|
5030
|
+
if (!session) {
|
|
5031
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() });
|
|
5032
|
+
}
|
|
5033
|
+
const { data, error } = await _request(this.fetch, 'POST', `${this.url}/passkeys/registration/verify`, {
|
|
5034
|
+
headers: this.headers,
|
|
5035
|
+
jwt: session.access_token,
|
|
5036
|
+
body: {
|
|
5037
|
+
challenge_id: params.challengeId,
|
|
5038
|
+
credential: params.credential,
|
|
5039
|
+
},
|
|
5040
|
+
});
|
|
5041
|
+
if (error) {
|
|
5042
|
+
return this._returnResult({ data: null, error });
|
|
5043
|
+
}
|
|
5044
|
+
return this._returnResult({ data, error: null });
|
|
5045
|
+
});
|
|
5046
|
+
}
|
|
5047
|
+
catch (error) {
|
|
5048
|
+
if (isAuthError(error)) {
|
|
5049
|
+
return this._returnResult({ data: null, error });
|
|
5050
|
+
}
|
|
5051
|
+
throw error;
|
|
5052
|
+
}
|
|
5053
|
+
}
|
|
5054
|
+
/**
|
|
5055
|
+
* Start passkey authentication.
|
|
5056
|
+
* Returns WebAuthn credential request options to pass to navigator.credentials.get().
|
|
5057
|
+
*/
|
|
5058
|
+
async _startPasskeyAuthentication(params) {
|
|
5059
|
+
var _a;
|
|
5060
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
5061
|
+
try {
|
|
5062
|
+
const { data, error } = await _request(this.fetch, 'POST', `${this.url}/passkeys/authentication/options`, {
|
|
5063
|
+
headers: this.headers,
|
|
5064
|
+
body: {
|
|
5065
|
+
gotrue_meta_security: { captcha_token: (_a = params === null || params === void 0 ? void 0 : params.options) === null || _a === void 0 ? void 0 : _a.captchaToken },
|
|
5066
|
+
},
|
|
5067
|
+
});
|
|
5068
|
+
if (error) {
|
|
5069
|
+
return this._returnResult({ data: null, error });
|
|
5070
|
+
}
|
|
5071
|
+
return this._returnResult({ data, error: null });
|
|
5072
|
+
}
|
|
5073
|
+
catch (error) {
|
|
5074
|
+
if (isAuthError(error)) {
|
|
5075
|
+
return this._returnResult({ data: null, error });
|
|
5076
|
+
}
|
|
5077
|
+
throw error;
|
|
5078
|
+
}
|
|
5079
|
+
}
|
|
5080
|
+
/**
|
|
5081
|
+
* Verify passkey authentication and create a session.
|
|
5082
|
+
* The credential should be the serialized output of navigator.credentials.get().
|
|
5083
|
+
*/
|
|
5084
|
+
async _verifyPasskeyAuthentication(params) {
|
|
5085
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
5086
|
+
try {
|
|
5087
|
+
const { data, error } = await _request(this.fetch, 'POST', `${this.url}/passkeys/authentication/verify`, {
|
|
5088
|
+
headers: this.headers,
|
|
5089
|
+
body: {
|
|
5090
|
+
challenge_id: params.challengeId,
|
|
5091
|
+
credential: params.credential,
|
|
5092
|
+
},
|
|
5093
|
+
xform: _sessionResponse,
|
|
5094
|
+
});
|
|
5095
|
+
if (error) {
|
|
5096
|
+
return this._returnResult({ data: null, error });
|
|
5097
|
+
}
|
|
5098
|
+
if (data.session) {
|
|
5099
|
+
await this._saveSession(data.session);
|
|
5100
|
+
await this._notifyAllSubscribers('SIGNED_IN', data.session);
|
|
5101
|
+
}
|
|
5102
|
+
return this._returnResult({ data, error: null });
|
|
5103
|
+
}
|
|
5104
|
+
catch (error) {
|
|
5105
|
+
if (isAuthError(error)) {
|
|
5106
|
+
return this._returnResult({ data: null, error });
|
|
5107
|
+
}
|
|
5108
|
+
throw error;
|
|
5109
|
+
}
|
|
5110
|
+
}
|
|
5111
|
+
/**
|
|
5112
|
+
* List all passkeys for the current user.
|
|
5113
|
+
*/
|
|
5114
|
+
async _listPasskeys() {
|
|
5115
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
5116
|
+
try {
|
|
5117
|
+
return await this._useSession(async (result) => {
|
|
5118
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5119
|
+
if (sessionError) {
|
|
5120
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5121
|
+
}
|
|
5122
|
+
if (!session) {
|
|
5123
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() });
|
|
5124
|
+
}
|
|
5125
|
+
const { data, error } = await _request(this.fetch, 'GET', `${this.url}/passkeys`, {
|
|
5126
|
+
headers: this.headers,
|
|
5127
|
+
jwt: session.access_token,
|
|
5128
|
+
xform: (data) => ({ data, error: null }),
|
|
5129
|
+
});
|
|
5130
|
+
if (error) {
|
|
5131
|
+
return this._returnResult({ data: null, error });
|
|
5132
|
+
}
|
|
5133
|
+
return this._returnResult({ data, error: null });
|
|
5134
|
+
});
|
|
5135
|
+
}
|
|
5136
|
+
catch (error) {
|
|
5137
|
+
if (isAuthError(error)) {
|
|
5138
|
+
return this._returnResult({ data: null, error });
|
|
5139
|
+
}
|
|
5140
|
+
throw error;
|
|
5141
|
+
}
|
|
5142
|
+
}
|
|
5143
|
+
/**
|
|
5144
|
+
* Update a passkey.
|
|
5145
|
+
*/
|
|
5146
|
+
async _updatePasskey(params) {
|
|
5147
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
5148
|
+
try {
|
|
5149
|
+
return await this._useSession(async (result) => {
|
|
5150
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5151
|
+
if (sessionError) {
|
|
5152
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5153
|
+
}
|
|
5154
|
+
if (!session) {
|
|
5155
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() });
|
|
5156
|
+
}
|
|
5157
|
+
const { data, error } = await _request(this.fetch, 'PATCH', `${this.url}/passkeys/${params.passkeyId}`, {
|
|
5158
|
+
headers: this.headers,
|
|
5159
|
+
jwt: session.access_token,
|
|
5160
|
+
body: { friendly_name: params.friendlyName },
|
|
5161
|
+
});
|
|
5162
|
+
if (error) {
|
|
5163
|
+
return this._returnResult({ data: null, error });
|
|
5164
|
+
}
|
|
5165
|
+
return this._returnResult({ data, error: null });
|
|
5166
|
+
});
|
|
5167
|
+
}
|
|
5168
|
+
catch (error) {
|
|
5169
|
+
if (isAuthError(error)) {
|
|
5170
|
+
return this._returnResult({ data: null, error });
|
|
5171
|
+
}
|
|
5172
|
+
throw error;
|
|
5173
|
+
}
|
|
5174
|
+
}
|
|
5175
|
+
/**
|
|
5176
|
+
* Delete a passkey.
|
|
5177
|
+
*/
|
|
5178
|
+
async _deletePasskey(params) {
|
|
5179
|
+
assertPasskeyExperimentalEnabled(this.experimental);
|
|
5180
|
+
try {
|
|
5181
|
+
return await this._useSession(async (result) => {
|
|
5182
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5183
|
+
if (sessionError) {
|
|
5184
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5185
|
+
}
|
|
5186
|
+
if (!session) {
|
|
5187
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() });
|
|
5188
|
+
}
|
|
5189
|
+
const { error } = await _request(this.fetch, 'DELETE', `${this.url}/passkeys/${params.passkeyId}`, {
|
|
5190
|
+
headers: this.headers,
|
|
5191
|
+
jwt: session.access_token,
|
|
5192
|
+
noResolveJson: true,
|
|
5193
|
+
});
|
|
5194
|
+
if (error) {
|
|
5195
|
+
return this._returnResult({ data: null, error });
|
|
5196
|
+
}
|
|
5197
|
+
return this._returnResult({ data: null, error: null });
|
|
5198
|
+
});
|
|
5199
|
+
}
|
|
5200
|
+
catch (error) {
|
|
5201
|
+
if (isAuthError(error)) {
|
|
5202
|
+
return this._returnResult({ data: null, error });
|
|
5203
|
+
}
|
|
5204
|
+
throw error;
|
|
5205
|
+
}
|
|
5206
|
+
}
|
|
4855
5207
|
}
|
|
4856
5208
|
GoTrueClient.nextInstanceID = {};
|
|
4857
5209
|
export default GoTrueClient;
|