@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
|
@@ -27,6 +27,7 @@ const DEFAULT_OPTIONS = {
|
|
|
27
27
|
throwOnError: false,
|
|
28
28
|
lockAcquireTimeout: 5000, // 5 seconds
|
|
29
29
|
skipAutoInitialize: false,
|
|
30
|
+
experimental: {},
|
|
30
31
|
};
|
|
31
32
|
async function lockNoOp(name, acquireTimeout, fn) {
|
|
32
33
|
return await fn();
|
|
@@ -65,7 +66,7 @@ class GoTrueClient {
|
|
|
65
66
|
* ```ts
|
|
66
67
|
* import { createClient } from '@supabase/supabase-js'
|
|
67
68
|
*
|
|
68
|
-
* const supabase = createClient('https://xyzcompany.supabase.co', 'publishable-
|
|
69
|
+
* const supabase = createClient('https://xyzcompany.supabase.co', 'your-publishable-key')
|
|
69
70
|
* const { data, error } = await supabase.auth.getUser()
|
|
70
71
|
* ```
|
|
71
72
|
*
|
|
@@ -75,13 +76,13 @@ class GoTrueClient {
|
|
|
75
76
|
*
|
|
76
77
|
* const auth = new GoTrueClient({
|
|
77
78
|
* url: 'https://xyzcompany.supabase.co/auth/v1',
|
|
78
|
-
* headers: { apikey: 'publishable-
|
|
79
|
+
* headers: { apikey: 'your-publishable-key' },
|
|
79
80
|
* storageKey: 'supabase-auth',
|
|
80
81
|
* })
|
|
81
82
|
* ```
|
|
82
83
|
*/
|
|
83
84
|
constructor(options) {
|
|
84
|
-
var _a, _b, _c;
|
|
85
|
+
var _a, _b, _c, _d;
|
|
85
86
|
/**
|
|
86
87
|
* @experimental
|
|
87
88
|
*/
|
|
@@ -126,10 +127,12 @@ class GoTrueClient {
|
|
|
126
127
|
}
|
|
127
128
|
this.persistSession = settings.persistSession;
|
|
128
129
|
this.autoRefreshToken = settings.autoRefreshToken;
|
|
130
|
+
this.experimental = (_b = settings.experimental) !== null && _b !== void 0 ? _b : {};
|
|
129
131
|
this.admin = new GoTrueAdminApi_1.default({
|
|
130
132
|
url: settings.url,
|
|
131
133
|
headers: settings.headers,
|
|
132
134
|
fetch: settings.fetch,
|
|
135
|
+
experimental: this.experimental,
|
|
133
136
|
});
|
|
134
137
|
this.url = settings.url;
|
|
135
138
|
this.headers = settings.headers;
|
|
@@ -143,7 +146,7 @@ class GoTrueClient {
|
|
|
143
146
|
if (settings.lock) {
|
|
144
147
|
this.lock = settings.lock;
|
|
145
148
|
}
|
|
146
|
-
else if (this.persistSession && (0, helpers_1.isBrowser)() && ((
|
|
149
|
+
else if (this.persistSession && (0, helpers_1.isBrowser)() && ((_c = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _c === void 0 ? void 0 : _c.locks)) {
|
|
147
150
|
this.lock = locks_1.navigatorLock;
|
|
148
151
|
}
|
|
149
152
|
else {
|
|
@@ -170,6 +173,15 @@ class GoTrueClient {
|
|
|
170
173
|
listGrants: this._listOAuthGrants.bind(this),
|
|
171
174
|
revokeGrant: this._revokeOAuthGrant.bind(this),
|
|
172
175
|
};
|
|
176
|
+
this.passkey = {
|
|
177
|
+
startRegistration: this._startPasskeyRegistration.bind(this),
|
|
178
|
+
verifyRegistration: this._verifyPasskeyRegistration.bind(this),
|
|
179
|
+
startAuthentication: this._startPasskeyAuthentication.bind(this),
|
|
180
|
+
verifyAuthentication: this._verifyPasskeyAuthentication.bind(this),
|
|
181
|
+
list: this._listPasskeys.bind(this),
|
|
182
|
+
update: this._updatePasskey.bind(this),
|
|
183
|
+
delete: this._deletePasskey.bind(this),
|
|
184
|
+
};
|
|
173
185
|
if (this.persistSession) {
|
|
174
186
|
if (settings.storage) {
|
|
175
187
|
this.storage = settings.storage;
|
|
@@ -198,7 +210,7 @@ class GoTrueClient {
|
|
|
198
210
|
catch (e) {
|
|
199
211
|
console.error('Failed to create a new BroadcastChannel, multi-tab state changes will not be available', e);
|
|
200
212
|
}
|
|
201
|
-
(
|
|
213
|
+
(_d = this.broadcastChannel) === null || _d === void 0 ? void 0 : _d.addEventListener('message', async (event) => {
|
|
202
214
|
this._debug('received broadcast notification from other tab or client', event);
|
|
203
215
|
try {
|
|
204
216
|
await this._notifyAllSubscribers(event.data.event, event.data.session, false); // broadcast = false so we don't get an endless loop of messages
|
|
@@ -1213,7 +1225,7 @@ class GoTrueClient {
|
|
|
1213
1225
|
}
|
|
1214
1226
|
}
|
|
1215
1227
|
async signInWithEthereum(credentials) {
|
|
1216
|
-
var _a, _b, _c, _d,
|
|
1228
|
+
var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m;
|
|
1217
1229
|
// TODO: flatten type
|
|
1218
1230
|
let message;
|
|
1219
1231
|
let signature;
|
|
@@ -1273,11 +1285,11 @@ class GoTrueClient {
|
|
|
1273
1285
|
version: '1',
|
|
1274
1286
|
chainId: chainId,
|
|
1275
1287
|
nonce: (_c = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _c === void 0 ? void 0 : _c.nonce,
|
|
1276
|
-
issuedAt: (
|
|
1277
|
-
expirationTime: (
|
|
1278
|
-
notBefore: (
|
|
1279
|
-
requestId: (
|
|
1280
|
-
resources: (
|
|
1288
|
+
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(),
|
|
1289
|
+
expirationTime: (_g = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _g === void 0 ? void 0 : _g.expirationTime,
|
|
1290
|
+
notBefore: (_h = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _h === void 0 ? void 0 : _h.notBefore,
|
|
1291
|
+
requestId: (_j = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _j === void 0 ? void 0 : _j.requestId,
|
|
1292
|
+
resources: (_k = options === null || options === void 0 ? void 0 : options.signInWithEthereum) === null || _k === void 0 ? void 0 : _k.resources,
|
|
1281
1293
|
};
|
|
1282
1294
|
message = (0, ethereum_1.createSiweMessage)(siweMessage);
|
|
1283
1295
|
// Sign message
|
|
@@ -1290,8 +1302,8 @@ class GoTrueClient {
|
|
|
1290
1302
|
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=web3`, {
|
|
1291
1303
|
headers: this.headers,
|
|
1292
1304
|
body: Object.assign({ chain: 'ethereum', message,
|
|
1293
|
-
signature }, (((
|
|
1294
|
-
? { gotrue_meta_security: { captcha_token: (
|
|
1305
|
+
signature }, (((_l = credentials.options) === null || _l === void 0 ? void 0 : _l.captchaToken)
|
|
1306
|
+
? { gotrue_meta_security: { captcha_token: (_m = credentials.options) === null || _m === void 0 ? void 0 : _m.captchaToken } }
|
|
1295
1307
|
: null)),
|
|
1296
1308
|
xform: fetch_1._sessionResponse,
|
|
1297
1309
|
});
|
|
@@ -1316,7 +1328,7 @@ class GoTrueClient {
|
|
|
1316
1328
|
}
|
|
1317
1329
|
}
|
|
1318
1330
|
async signInWithSolana(credentials) {
|
|
1319
|
-
var _a, _b, _c, _d,
|
|
1331
|
+
var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
1320
1332
|
let message;
|
|
1321
1333
|
let signature;
|
|
1322
1334
|
if ('message' in credentials) {
|
|
@@ -1401,17 +1413,17 @@ class GoTrueClient {
|
|
|
1401
1413
|
...(((_d = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _d === void 0 ? void 0 : _d.notBefore)
|
|
1402
1414
|
? [`Not Before: ${options.signInWithSolana.notBefore}`]
|
|
1403
1415
|
: []),
|
|
1404
|
-
...(((
|
|
1416
|
+
...(((_f = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _f === void 0 ? void 0 : _f.expirationTime)
|
|
1405
1417
|
? [`Expiration Time: ${options.signInWithSolana.expirationTime}`]
|
|
1406
1418
|
: []),
|
|
1407
|
-
...(((
|
|
1419
|
+
...(((_g = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _g === void 0 ? void 0 : _g.chainId)
|
|
1408
1420
|
? [`Chain ID: ${options.signInWithSolana.chainId}`]
|
|
1409
1421
|
: []),
|
|
1410
|
-
...(((
|
|
1411
|
-
...(((
|
|
1422
|
+
...(((_h = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _h === void 0 ? void 0 : _h.nonce) ? [`Nonce: ${options.signInWithSolana.nonce}`] : []),
|
|
1423
|
+
...(((_j = options === null || options === void 0 ? void 0 : options.signInWithSolana) === null || _j === void 0 ? void 0 : _j.requestId)
|
|
1412
1424
|
? [`Request ID: ${options.signInWithSolana.requestId}`]
|
|
1413
1425
|
: []),
|
|
1414
|
-
...(((
|
|
1426
|
+
...(((_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)
|
|
1415
1427
|
? [
|
|
1416
1428
|
'Resources',
|
|
1417
1429
|
...options.signInWithSolana.resources.map((resource) => `- ${resource}`),
|
|
@@ -1428,8 +1440,8 @@ class GoTrueClient {
|
|
|
1428
1440
|
try {
|
|
1429
1441
|
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/token?grant_type=web3`, {
|
|
1430
1442
|
headers: this.headers,
|
|
1431
|
-
body: Object.assign({ chain: 'solana', message, signature: (0, base64url_1.bytesToBase64URL)(signature) }, (((
|
|
1432
|
-
? { gotrue_meta_security: { captcha_token: (
|
|
1443
|
+
body: Object.assign({ chain: 'solana', message, signature: (0, base64url_1.bytesToBase64URL)(signature) }, (((_m = credentials.options) === null || _m === void 0 ? void 0 : _m.captchaToken)
|
|
1444
|
+
? { gotrue_meta_security: { captcha_token: (_o = credentials.options) === null || _o === void 0 ? void 0 : _o.captchaToken } }
|
|
1433
1445
|
: null)),
|
|
1434
1446
|
xform: fetch_1._sessionResponse,
|
|
1435
1447
|
});
|
|
@@ -1481,7 +1493,7 @@ class GoTrueClient {
|
|
|
1481
1493
|
}
|
|
1482
1494
|
if (data.session) {
|
|
1483
1495
|
await this._saveSession(data.session);
|
|
1484
|
-
await this._notifyAllSubscribers('SIGNED_IN', data.session);
|
|
1496
|
+
await this._notifyAllSubscribers(redirectType === 'recovery' ? 'PASSWORD_RECOVERY' : 'SIGNED_IN', data.session);
|
|
1485
1497
|
}
|
|
1486
1498
|
return this._returnResult({ data: Object.assign(Object.assign({}, data), { redirectType: redirectType !== null && redirectType !== void 0 ? redirectType : null }), error });
|
|
1487
1499
|
}
|
|
@@ -1684,7 +1696,7 @@ class GoTrueClient {
|
|
|
1684
1696
|
* ```
|
|
1685
1697
|
*/
|
|
1686
1698
|
async signInWithOtp(credentials) {
|
|
1687
|
-
var _a, _b, _c, _d,
|
|
1699
|
+
var _a, _b, _c, _d, _f;
|
|
1688
1700
|
try {
|
|
1689
1701
|
if ('email' in credentials) {
|
|
1690
1702
|
const { email, options } = credentials;
|
|
@@ -1717,7 +1729,7 @@ class GoTrueClient {
|
|
|
1717
1729
|
data: (_c = options === null || options === void 0 ? void 0 : options.data) !== null && _c !== void 0 ? _c : {},
|
|
1718
1730
|
create_user: (_d = options === null || options === void 0 ? void 0 : options.shouldCreateUser) !== null && _d !== void 0 ? _d : true,
|
|
1719
1731
|
gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
|
|
1720
|
-
channel: (
|
|
1732
|
+
channel: (_f = options === null || options === void 0 ? void 0 : options.channel) !== null && _f !== void 0 ? _f : 'sms',
|
|
1721
1733
|
},
|
|
1722
1734
|
});
|
|
1723
1735
|
return this._returnResult({
|
|
@@ -1963,7 +1975,7 @@ class GoTrueClient {
|
|
|
1963
1975
|
* ```
|
|
1964
1976
|
*/
|
|
1965
1977
|
async signInWithSSO(params) {
|
|
1966
|
-
var _a, _b, _c, _d,
|
|
1978
|
+
var _a, _b, _c, _d, _f;
|
|
1967
1979
|
try {
|
|
1968
1980
|
let codeChallenge = null;
|
|
1969
1981
|
let codeChallengeMethod = null;
|
|
@@ -1979,7 +1991,7 @@ class GoTrueClient {
|
|
|
1979
1991
|
xform: fetch_1._ssoResponse,
|
|
1980
1992
|
});
|
|
1981
1993
|
// Automatically redirect in browser unless skipBrowserRedirect is true
|
|
1982
|
-
if (((_d = result.data) === null || _d === void 0 ? void 0 : _d.url) && (0, helpers_1.isBrowser)() && !((
|
|
1994
|
+
if (((_d = result.data) === null || _d === void 0 ? void 0 : _d.url) && (0, helpers_1.isBrowser)() && !((_f = params.options) === null || _f === void 0 ? void 0 : _f.skipBrowserRedirect)) {
|
|
1983
1995
|
window.location.assign(result.data.url);
|
|
1984
1996
|
}
|
|
1985
1997
|
return this._returnResult(result);
|
|
@@ -2252,7 +2264,7 @@ class GoTrueClient {
|
|
|
2252
2264
|
try {
|
|
2253
2265
|
await result;
|
|
2254
2266
|
}
|
|
2255
|
-
catch (
|
|
2267
|
+
catch (_e) {
|
|
2256
2268
|
// we just care if it finished
|
|
2257
2269
|
}
|
|
2258
2270
|
})());
|
|
@@ -3010,6 +3022,7 @@ class GoTrueClient {
|
|
|
3010
3022
|
* Gets the session data from a URL string
|
|
3011
3023
|
*/
|
|
3012
3024
|
async _getSessionFromURL(params, callbackUrlType) {
|
|
3025
|
+
var _a;
|
|
3013
3026
|
try {
|
|
3014
3027
|
if (!(0, helpers_1.isBrowser)())
|
|
3015
3028
|
throw new errors_1.AuthImplicitGrantRedirectError('No browser detected.');
|
|
@@ -3048,7 +3061,10 @@ class GoTrueClient {
|
|
|
3048
3061
|
const url = new URL(window.location.href);
|
|
3049
3062
|
url.searchParams.delete('code');
|
|
3050
3063
|
window.history.replaceState(window.history.state, '', url.toString());
|
|
3051
|
-
return {
|
|
3064
|
+
return {
|
|
3065
|
+
data: { session: data.session, redirectType: (_a = data.redirectType) !== null && _a !== void 0 ? _a : null },
|
|
3066
|
+
error: null,
|
|
3067
|
+
};
|
|
3052
3068
|
}
|
|
3053
3069
|
const { provider_token, provider_refresh_token, access_token, refresh_token, expires_in, expires_at, token_type, } = params;
|
|
3054
3070
|
if (!access_token || !expires_in || !refresh_token || !token_type) {
|
|
@@ -3124,24 +3140,35 @@ class GoTrueClient {
|
|
|
3124
3140
|
*
|
|
3125
3141
|
* If using `others` scope, no `SIGNED_OUT` event is fired!
|
|
3126
3142
|
*
|
|
3143
|
+
* **Warning:** the default `scope` is `'global'`. This signs the user out of
|
|
3144
|
+
* **every device they are currently signed in on**, not just the current
|
|
3145
|
+
* tab/session. If you only want to sign the user out of the current session
|
|
3146
|
+
* (the behavior most other auth libraries default to), pass
|
|
3147
|
+
* `{ scope: 'local' }` explicitly.
|
|
3148
|
+
*
|
|
3127
3149
|
* @category Auth
|
|
3128
3150
|
*
|
|
3129
3151
|
* @remarks
|
|
3130
3152
|
* - In order to use the `signOut()` method, the user needs to be signed in first.
|
|
3131
|
-
* - By default, `signOut()` uses the global scope, which signs out
|
|
3153
|
+
* - By default, `signOut()` uses the **global** scope, which signs out the user
|
|
3154
|
+
* on every device they are signed in on (not just the current one). Pass
|
|
3155
|
+
* `{ scope: 'local' }` to only sign out the current session. This is
|
|
3156
|
+
* usually what apps want on a "Sign out" button, especially when users
|
|
3157
|
+
* sign in from multiple devices and do not expect signing out of one to
|
|
3158
|
+
* terminate the others.
|
|
3132
3159
|
* - 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.
|
|
3133
3160
|
*
|
|
3134
|
-
* @example Sign out (
|
|
3161
|
+
* @example Sign out of every device (global – default)
|
|
3135
3162
|
* ```js
|
|
3136
3163
|
* const { error } = await supabase.auth.signOut()
|
|
3137
3164
|
* ```
|
|
3138
3165
|
*
|
|
3139
|
-
* @example Sign out
|
|
3166
|
+
* @example Sign out only the current session (recommended for most apps)
|
|
3140
3167
|
* ```js
|
|
3141
3168
|
* const { error } = await supabase.auth.signOut({ scope: 'local' })
|
|
3142
3169
|
* ```
|
|
3143
3170
|
*
|
|
3144
|
-
* @example Sign out
|
|
3171
|
+
* @example Sign out of all other sessions, keep the current one
|
|
3145
3172
|
* ```js
|
|
3146
3173
|
* const { error } = await supabase.auth.signOut({ scope: 'others' })
|
|
3147
3174
|
* ```
|
|
@@ -3595,7 +3622,7 @@ class GoTrueClient {
|
|
|
3595
3622
|
var _a;
|
|
3596
3623
|
try {
|
|
3597
3624
|
const { data, error } = await this._useSession(async (result) => {
|
|
3598
|
-
var _a, _b, _c, _d,
|
|
3625
|
+
var _a, _b, _c, _d, _f;
|
|
3599
3626
|
const { data, error } = result;
|
|
3600
3627
|
if (error)
|
|
3601
3628
|
throw error;
|
|
@@ -3607,7 +3634,7 @@ class GoTrueClient {
|
|
|
3607
3634
|
});
|
|
3608
3635
|
return await (0, fetch_1._request)(this.fetch, 'GET', url, {
|
|
3609
3636
|
headers: this.headers,
|
|
3610
|
-
jwt: (
|
|
3637
|
+
jwt: (_f = (_d = data.session) === null || _d === void 0 ? void 0 : _d.access_token) !== null && _f !== void 0 ? _f : undefined,
|
|
3611
3638
|
});
|
|
3612
3639
|
});
|
|
3613
3640
|
if (error)
|
|
@@ -4190,7 +4217,7 @@ class GoTrueClient {
|
|
|
4190
4217
|
});
|
|
4191
4218
|
}
|
|
4192
4219
|
catch (e) {
|
|
4193
|
-
if (e
|
|
4220
|
+
if (e instanceof locks_1.LockAcquireTimeoutError) {
|
|
4194
4221
|
this._debug('auto refresh token tick lock not available');
|
|
4195
4222
|
}
|
|
4196
4223
|
else {
|
|
@@ -4855,6 +4882,331 @@ class GoTrueClient {
|
|
|
4855
4882
|
throw error;
|
|
4856
4883
|
}
|
|
4857
4884
|
}
|
|
4885
|
+
// --- Passkey Methods ---
|
|
4886
|
+
/**
|
|
4887
|
+
* Sign in with a passkey. Handles the full WebAuthn ceremony:
|
|
4888
|
+
* 1. Fetches authentication challenge from server
|
|
4889
|
+
* 2. Prompts user via navigator.credentials.get()
|
|
4890
|
+
* 3. Verifies credential with server and creates session
|
|
4891
|
+
*
|
|
4892
|
+
* Requires `auth.experimental.passkey: true`.
|
|
4893
|
+
*/
|
|
4894
|
+
async signInWithPasskey(credentials) {
|
|
4895
|
+
var _a, _b, _c;
|
|
4896
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
4897
|
+
try {
|
|
4898
|
+
if (!(0, webauthn_1.browserSupportsWebAuthn)()) {
|
|
4899
|
+
return this._returnResult({
|
|
4900
|
+
data: null,
|
|
4901
|
+
error: new errors_1.AuthUnknownError('Browser does not support WebAuthn', null),
|
|
4902
|
+
});
|
|
4903
|
+
}
|
|
4904
|
+
// 1. Get challenge options from server
|
|
4905
|
+
const { data: options, error: optionsError } = await this._startPasskeyAuthentication({
|
|
4906
|
+
options: { captchaToken: (_a = credentials === null || credentials === void 0 ? void 0 : credentials.options) === null || _a === void 0 ? void 0 : _a.captchaToken },
|
|
4907
|
+
});
|
|
4908
|
+
if (optionsError || !options) {
|
|
4909
|
+
return this._returnResult({ data: null, error: optionsError });
|
|
4910
|
+
}
|
|
4911
|
+
// 2. Deserialize and prompt user via browser WebAuthn API
|
|
4912
|
+
const publicKeyOptions = (0, webauthn_1.deserializeCredentialRequestOptions)(options.options);
|
|
4913
|
+
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 : webauthn_1.webAuthnAbortService.createNewAbortSignal();
|
|
4914
|
+
const { data: credential, error: credentialError } = await (0, webauthn_1.getCredential)({
|
|
4915
|
+
publicKey: publicKeyOptions,
|
|
4916
|
+
signal,
|
|
4917
|
+
});
|
|
4918
|
+
if (credentialError || !credential) {
|
|
4919
|
+
return this._returnResult({
|
|
4920
|
+
data: null,
|
|
4921
|
+
error: credentialError !== null && credentialError !== void 0 ? credentialError : new errors_1.AuthUnknownError('WebAuthn ceremony failed', null),
|
|
4922
|
+
});
|
|
4923
|
+
}
|
|
4924
|
+
// 3. Serialize and verify with server
|
|
4925
|
+
const serialized = (0, webauthn_1.serializeCredentialRequestResponse)(credential);
|
|
4926
|
+
return this._verifyPasskeyAuthentication({
|
|
4927
|
+
challengeId: options.challenge_id,
|
|
4928
|
+
credential: serialized,
|
|
4929
|
+
});
|
|
4930
|
+
}
|
|
4931
|
+
catch (error) {
|
|
4932
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
4933
|
+
return this._returnResult({ data: null, error });
|
|
4934
|
+
}
|
|
4935
|
+
throw error;
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
/**
|
|
4939
|
+
* Register a passkey for the current authenticated user. Handles the full WebAuthn ceremony:
|
|
4940
|
+
* 1. Fetches registration challenge from server
|
|
4941
|
+
* 2. Prompts user via navigator.credentials.create()
|
|
4942
|
+
* 3. Verifies credential with server
|
|
4943
|
+
*
|
|
4944
|
+
* Requires an active session. Requires `auth.experimental.passkey: true`.
|
|
4945
|
+
*/
|
|
4946
|
+
async registerPasskey(credentials) {
|
|
4947
|
+
var _a, _b;
|
|
4948
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
4949
|
+
try {
|
|
4950
|
+
if (!(0, webauthn_1.browserSupportsWebAuthn)()) {
|
|
4951
|
+
return this._returnResult({
|
|
4952
|
+
data: null,
|
|
4953
|
+
error: new errors_1.AuthUnknownError('Browser does not support WebAuthn', null),
|
|
4954
|
+
});
|
|
4955
|
+
}
|
|
4956
|
+
// 1. Get challenge options from server
|
|
4957
|
+
const { data: options, error: optionsError } = await this._startPasskeyRegistration();
|
|
4958
|
+
if (optionsError || !options) {
|
|
4959
|
+
return this._returnResult({ data: null, error: optionsError });
|
|
4960
|
+
}
|
|
4961
|
+
// 2. Deserialize and prompt user via browser WebAuthn API
|
|
4962
|
+
const publicKeyOptions = (0, webauthn_1.deserializeCredentialCreationOptions)(options.options);
|
|
4963
|
+
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 : webauthn_1.webAuthnAbortService.createNewAbortSignal();
|
|
4964
|
+
const { data: credential, error: credentialError } = await (0, webauthn_1.createCredential)({
|
|
4965
|
+
publicKey: publicKeyOptions,
|
|
4966
|
+
signal,
|
|
4967
|
+
});
|
|
4968
|
+
if (credentialError || !credential) {
|
|
4969
|
+
return this._returnResult({
|
|
4970
|
+
data: null,
|
|
4971
|
+
error: credentialError !== null && credentialError !== void 0 ? credentialError : new errors_1.AuthUnknownError('WebAuthn ceremony failed', null),
|
|
4972
|
+
});
|
|
4973
|
+
}
|
|
4974
|
+
// 3. Serialize and verify with server
|
|
4975
|
+
const serialized = (0, webauthn_1.serializeCredentialCreationResponse)(credential);
|
|
4976
|
+
return this._verifyPasskeyRegistration({
|
|
4977
|
+
challengeId: options.challenge_id,
|
|
4978
|
+
credential: serialized,
|
|
4979
|
+
});
|
|
4980
|
+
}
|
|
4981
|
+
catch (error) {
|
|
4982
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
4983
|
+
return this._returnResult({ data: null, error });
|
|
4984
|
+
}
|
|
4985
|
+
throw error;
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4988
|
+
/**
|
|
4989
|
+
* Start passkey registration for the current authenticated user.
|
|
4990
|
+
* Returns WebAuthn credential creation options to pass to navigator.credentials.create().
|
|
4991
|
+
*/
|
|
4992
|
+
async _startPasskeyRegistration() {
|
|
4993
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
4994
|
+
try {
|
|
4995
|
+
return await this._useSession(async (result) => {
|
|
4996
|
+
const { data: { session }, error: sessionError, } = result;
|
|
4997
|
+
if (sessionError) {
|
|
4998
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
4999
|
+
}
|
|
5000
|
+
if (!session) {
|
|
5001
|
+
return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() });
|
|
5002
|
+
}
|
|
5003
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/passkeys/registration/options`, {
|
|
5004
|
+
headers: this.headers,
|
|
5005
|
+
jwt: session.access_token,
|
|
5006
|
+
body: {},
|
|
5007
|
+
});
|
|
5008
|
+
if (error) {
|
|
5009
|
+
return this._returnResult({ data: null, error });
|
|
5010
|
+
}
|
|
5011
|
+
return this._returnResult({ data, error: null });
|
|
5012
|
+
});
|
|
5013
|
+
}
|
|
5014
|
+
catch (error) {
|
|
5015
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
5016
|
+
return this._returnResult({ data: null, error });
|
|
5017
|
+
}
|
|
5018
|
+
throw error;
|
|
5019
|
+
}
|
|
5020
|
+
}
|
|
5021
|
+
/**
|
|
5022
|
+
* Verify passkey registration with the credential response.
|
|
5023
|
+
* The credentialResponse should be the serialized output of navigator.credentials.create().
|
|
5024
|
+
*/
|
|
5025
|
+
async _verifyPasskeyRegistration(params) {
|
|
5026
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
5027
|
+
try {
|
|
5028
|
+
return await this._useSession(async (result) => {
|
|
5029
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5030
|
+
if (sessionError) {
|
|
5031
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5032
|
+
}
|
|
5033
|
+
if (!session) {
|
|
5034
|
+
return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() });
|
|
5035
|
+
}
|
|
5036
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/passkeys/registration/verify`, {
|
|
5037
|
+
headers: this.headers,
|
|
5038
|
+
jwt: session.access_token,
|
|
5039
|
+
body: {
|
|
5040
|
+
challenge_id: params.challengeId,
|
|
5041
|
+
credential: params.credential,
|
|
5042
|
+
},
|
|
5043
|
+
});
|
|
5044
|
+
if (error) {
|
|
5045
|
+
return this._returnResult({ data: null, error });
|
|
5046
|
+
}
|
|
5047
|
+
return this._returnResult({ data, error: null });
|
|
5048
|
+
});
|
|
5049
|
+
}
|
|
5050
|
+
catch (error) {
|
|
5051
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
5052
|
+
return this._returnResult({ data: null, error });
|
|
5053
|
+
}
|
|
5054
|
+
throw error;
|
|
5055
|
+
}
|
|
5056
|
+
}
|
|
5057
|
+
/**
|
|
5058
|
+
* Start passkey authentication.
|
|
5059
|
+
* Returns WebAuthn credential request options to pass to navigator.credentials.get().
|
|
5060
|
+
*/
|
|
5061
|
+
async _startPasskeyAuthentication(params) {
|
|
5062
|
+
var _a;
|
|
5063
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
5064
|
+
try {
|
|
5065
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/passkeys/authentication/options`, {
|
|
5066
|
+
headers: this.headers,
|
|
5067
|
+
body: {
|
|
5068
|
+
gotrue_meta_security: { captcha_token: (_a = params === null || params === void 0 ? void 0 : params.options) === null || _a === void 0 ? void 0 : _a.captchaToken },
|
|
5069
|
+
},
|
|
5070
|
+
});
|
|
5071
|
+
if (error) {
|
|
5072
|
+
return this._returnResult({ data: null, error });
|
|
5073
|
+
}
|
|
5074
|
+
return this._returnResult({ data, error: null });
|
|
5075
|
+
}
|
|
5076
|
+
catch (error) {
|
|
5077
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
5078
|
+
return this._returnResult({ data: null, error });
|
|
5079
|
+
}
|
|
5080
|
+
throw error;
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
/**
|
|
5084
|
+
* Verify passkey authentication and create a session.
|
|
5085
|
+
* The credential should be the serialized output of navigator.credentials.get().
|
|
5086
|
+
*/
|
|
5087
|
+
async _verifyPasskeyAuthentication(params) {
|
|
5088
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
5089
|
+
try {
|
|
5090
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/passkeys/authentication/verify`, {
|
|
5091
|
+
headers: this.headers,
|
|
5092
|
+
body: {
|
|
5093
|
+
challenge_id: params.challengeId,
|
|
5094
|
+
credential: params.credential,
|
|
5095
|
+
},
|
|
5096
|
+
xform: fetch_1._sessionResponse,
|
|
5097
|
+
});
|
|
5098
|
+
if (error) {
|
|
5099
|
+
return this._returnResult({ data: null, error });
|
|
5100
|
+
}
|
|
5101
|
+
if (data.session) {
|
|
5102
|
+
await this._saveSession(data.session);
|
|
5103
|
+
await this._notifyAllSubscribers('SIGNED_IN', data.session);
|
|
5104
|
+
}
|
|
5105
|
+
return this._returnResult({ data, error: null });
|
|
5106
|
+
}
|
|
5107
|
+
catch (error) {
|
|
5108
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
5109
|
+
return this._returnResult({ data: null, error });
|
|
5110
|
+
}
|
|
5111
|
+
throw error;
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
/**
|
|
5115
|
+
* List all passkeys for the current user.
|
|
5116
|
+
*/
|
|
5117
|
+
async _listPasskeys() {
|
|
5118
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
5119
|
+
try {
|
|
5120
|
+
return await this._useSession(async (result) => {
|
|
5121
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5122
|
+
if (sessionError) {
|
|
5123
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5124
|
+
}
|
|
5125
|
+
if (!session) {
|
|
5126
|
+
return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() });
|
|
5127
|
+
}
|
|
5128
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/passkeys`, {
|
|
5129
|
+
headers: this.headers,
|
|
5130
|
+
jwt: session.access_token,
|
|
5131
|
+
xform: (data) => ({ data, error: null }),
|
|
5132
|
+
});
|
|
5133
|
+
if (error) {
|
|
5134
|
+
return this._returnResult({ data: null, error });
|
|
5135
|
+
}
|
|
5136
|
+
return this._returnResult({ data, error: null });
|
|
5137
|
+
});
|
|
5138
|
+
}
|
|
5139
|
+
catch (error) {
|
|
5140
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
5141
|
+
return this._returnResult({ data: null, error });
|
|
5142
|
+
}
|
|
5143
|
+
throw error;
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
/**
|
|
5147
|
+
* Update a passkey.
|
|
5148
|
+
*/
|
|
5149
|
+
async _updatePasskey(params) {
|
|
5150
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
5151
|
+
try {
|
|
5152
|
+
return await this._useSession(async (result) => {
|
|
5153
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5154
|
+
if (sessionError) {
|
|
5155
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5156
|
+
}
|
|
5157
|
+
if (!session) {
|
|
5158
|
+
return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() });
|
|
5159
|
+
}
|
|
5160
|
+
const { data, error } = await (0, fetch_1._request)(this.fetch, 'PATCH', `${this.url}/passkeys/${params.passkeyId}`, {
|
|
5161
|
+
headers: this.headers,
|
|
5162
|
+
jwt: session.access_token,
|
|
5163
|
+
body: { friendly_name: params.friendlyName },
|
|
5164
|
+
});
|
|
5165
|
+
if (error) {
|
|
5166
|
+
return this._returnResult({ data: null, error });
|
|
5167
|
+
}
|
|
5168
|
+
return this._returnResult({ data, error: null });
|
|
5169
|
+
});
|
|
5170
|
+
}
|
|
5171
|
+
catch (error) {
|
|
5172
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
5173
|
+
return this._returnResult({ data: null, error });
|
|
5174
|
+
}
|
|
5175
|
+
throw error;
|
|
5176
|
+
}
|
|
5177
|
+
}
|
|
5178
|
+
/**
|
|
5179
|
+
* Delete a passkey.
|
|
5180
|
+
*/
|
|
5181
|
+
async _deletePasskey(params) {
|
|
5182
|
+
(0, helpers_1.assertPasskeyExperimentalEnabled)(this.experimental);
|
|
5183
|
+
try {
|
|
5184
|
+
return await this._useSession(async (result) => {
|
|
5185
|
+
const { data: { session }, error: sessionError, } = result;
|
|
5186
|
+
if (sessionError) {
|
|
5187
|
+
return this._returnResult({ data: null, error: sessionError });
|
|
5188
|
+
}
|
|
5189
|
+
if (!session) {
|
|
5190
|
+
return this._returnResult({ data: null, error: new errors_1.AuthSessionMissingError() });
|
|
5191
|
+
}
|
|
5192
|
+
const { error } = await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/passkeys/${params.passkeyId}`, {
|
|
5193
|
+
headers: this.headers,
|
|
5194
|
+
jwt: session.access_token,
|
|
5195
|
+
noResolveJson: true,
|
|
5196
|
+
});
|
|
5197
|
+
if (error) {
|
|
5198
|
+
return this._returnResult({ data: null, error });
|
|
5199
|
+
}
|
|
5200
|
+
return this._returnResult({ data: null, error: null });
|
|
5201
|
+
});
|
|
5202
|
+
}
|
|
5203
|
+
catch (error) {
|
|
5204
|
+
if ((0, errors_1.isAuthError)(error)) {
|
|
5205
|
+
return this._returnResult({ data: null, error });
|
|
5206
|
+
}
|
|
5207
|
+
throw error;
|
|
5208
|
+
}
|
|
5209
|
+
}
|
|
4858
5210
|
}
|
|
4859
5211
|
GoTrueClient.nextInstanceID = {};
|
|
4860
5212
|
exports.default = GoTrueClient;
|