@netlify/identity 0.1.1-alpha.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +486 -29
- package/dist/index.cjs +268 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +141 -23
- package/dist/index.d.ts +141 -23
- package/dist/index.js +273 -165
- package/dist/index.js.map +1 -1
- package/package.json +10 -2
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
AUTH_EVENTS: () => AUTH_EVENTS,
|
|
33
34
|
AuthError: () => AuthError,
|
|
34
35
|
MissingIdentityError: () => MissingIdentityError,
|
|
35
36
|
acceptInvite: () => acceptInvite,
|
|
@@ -38,6 +39,7 @@ __export(index_exports, {
|
|
|
38
39
|
getSettings: () => getSettings,
|
|
39
40
|
getUser: () => getUser,
|
|
40
41
|
handleAuthCallback: () => handleAuthCallback,
|
|
42
|
+
hydrateSession: () => hydrateSession,
|
|
41
43
|
isAuthenticated: () => isAuthenticated,
|
|
42
44
|
login: () => login,
|
|
43
45
|
logout: () => logout,
|
|
@@ -58,7 +60,7 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
|
|
|
58
60
|
var import_gotrue_js = __toESM(require("gotrue-js"), 1);
|
|
59
61
|
|
|
60
62
|
// src/errors.ts
|
|
61
|
-
var AuthError = class extends Error {
|
|
63
|
+
var AuthError = class _AuthError extends Error {
|
|
62
64
|
constructor(message, status, options) {
|
|
63
65
|
super(message);
|
|
64
66
|
this.name = "AuthError";
|
|
@@ -67,9 +69,14 @@ var AuthError = class extends Error {
|
|
|
67
69
|
this.cause = options.cause;
|
|
68
70
|
}
|
|
69
71
|
}
|
|
72
|
+
static from(error) {
|
|
73
|
+
if (error instanceof _AuthError) return error;
|
|
74
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
75
|
+
return new _AuthError(message, void 0, { cause: error });
|
|
76
|
+
}
|
|
70
77
|
};
|
|
71
78
|
var MissingIdentityError = class extends Error {
|
|
72
|
-
constructor(message = "Identity is not available
|
|
79
|
+
constructor(message = "Netlify Identity is not available.") {
|
|
73
80
|
super(message);
|
|
74
81
|
this.name = "MissingIdentityError";
|
|
75
82
|
}
|
|
@@ -91,6 +98,8 @@ var discoverApiUrl = () => {
|
|
|
91
98
|
cachedApiUrl = identityContext.url;
|
|
92
99
|
} else if (globalThis.Netlify?.context?.url) {
|
|
93
100
|
cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href;
|
|
101
|
+
} else if (typeof process !== "undefined" && process.env?.URL) {
|
|
102
|
+
cachedApiUrl = new URL(IDENTITY_PATH, process.env.URL).href;
|
|
94
103
|
}
|
|
95
104
|
}
|
|
96
105
|
return cachedApiUrl ?? null;
|
|
@@ -107,7 +116,7 @@ var getGoTrueClient = () => {
|
|
|
107
116
|
}
|
|
108
117
|
return null;
|
|
109
118
|
}
|
|
110
|
-
goTrueClient = new import_gotrue_js.default({ APIUrl: apiUrl, setCookie:
|
|
119
|
+
goTrueClient = new import_gotrue_js.default({ APIUrl: apiUrl, setCookie: false });
|
|
111
120
|
return goTrueClient;
|
|
112
121
|
};
|
|
113
122
|
var getClient = () => {
|
|
@@ -126,6 +135,10 @@ var getIdentityContext = () => {
|
|
|
126
135
|
if (globalThis.Netlify?.context?.url) {
|
|
127
136
|
return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href };
|
|
128
137
|
}
|
|
138
|
+
const siteUrl = typeof process !== "undefined" ? process.env?.URL : void 0;
|
|
139
|
+
if (siteUrl) {
|
|
140
|
+
return { url: new URL(IDENTITY_PATH, siteUrl).href };
|
|
141
|
+
}
|
|
129
142
|
return null;
|
|
130
143
|
};
|
|
131
144
|
|
|
@@ -133,8 +146,14 @@ var getIdentityContext = () => {
|
|
|
133
146
|
var NF_JWT_COOKIE = "nf_jwt";
|
|
134
147
|
var NF_REFRESH_COOKIE = "nf_refresh";
|
|
135
148
|
var getCookie = (name) => {
|
|
149
|
+
if (typeof document === "undefined") return null;
|
|
136
150
|
const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]*)`));
|
|
137
|
-
|
|
151
|
+
if (!match) return null;
|
|
152
|
+
try {
|
|
153
|
+
return decodeURIComponent(match[1]);
|
|
154
|
+
} catch {
|
|
155
|
+
return match[1];
|
|
156
|
+
}
|
|
138
157
|
};
|
|
139
158
|
var setAuthCookies = (cookies, accessToken, refreshToken) => {
|
|
140
159
|
cookies.set({
|
|
@@ -161,14 +180,16 @@ var deleteAuthCookies = (cookies) => {
|
|
|
161
180
|
cookies.delete(NF_REFRESH_COOKIE);
|
|
162
181
|
};
|
|
163
182
|
var setBrowserAuthCookies = (accessToken, refreshToken) => {
|
|
183
|
+
if (typeof document === "undefined") return;
|
|
164
184
|
document.cookie = `${NF_JWT_COOKIE}=${encodeURIComponent(accessToken)}; path=/; secure; samesite=lax`;
|
|
165
185
|
if (refreshToken) {
|
|
166
186
|
document.cookie = `${NF_REFRESH_COOKIE}=${encodeURIComponent(refreshToken)}; path=/; secure; samesite=lax`;
|
|
167
187
|
}
|
|
168
188
|
};
|
|
169
189
|
var deleteBrowserAuthCookies = () => {
|
|
170
|
-
|
|
171
|
-
document.cookie = `${
|
|
190
|
+
if (typeof document === "undefined") return;
|
|
191
|
+
document.cookie = `${NF_JWT_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
192
|
+
document.cookie = `${NF_REFRESH_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
172
193
|
};
|
|
173
194
|
var getServerCookie = (name) => {
|
|
174
195
|
const cookies = globalThis.Netlify?.context?.cookies;
|
|
@@ -176,6 +197,34 @@ var getServerCookie = (name) => {
|
|
|
176
197
|
return cookies.get(name) ?? null;
|
|
177
198
|
};
|
|
178
199
|
|
|
200
|
+
// src/nextjs.ts
|
|
201
|
+
var nextHeadersFn;
|
|
202
|
+
var triggerNextjsDynamic = () => {
|
|
203
|
+
if (nextHeadersFn === null) return;
|
|
204
|
+
if (nextHeadersFn === void 0) {
|
|
205
|
+
try {
|
|
206
|
+
if (typeof require === "undefined") {
|
|
207
|
+
nextHeadersFn = null;
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const mod = require("next/headers");
|
|
211
|
+
nextHeadersFn = mod.headers;
|
|
212
|
+
} catch {
|
|
213
|
+
nextHeadersFn = null;
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const fn = nextHeadersFn;
|
|
218
|
+
if (!fn) return;
|
|
219
|
+
try {
|
|
220
|
+
fn();
|
|
221
|
+
} catch (e) {
|
|
222
|
+
if (e instanceof Error && ("digest" in e || /bail\s*out.*prerende/i.test(e.message))) {
|
|
223
|
+
throw e;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
179
228
|
// src/user.ts
|
|
180
229
|
var toAuthProvider = (value) => typeof value === "string" && AUTH_PROVIDERS.includes(value) ? value : void 0;
|
|
181
230
|
var toUser = (userData) => {
|
|
@@ -208,6 +257,35 @@ var claimsToUser = (claims) => {
|
|
|
208
257
|
metadata: userMeta
|
|
209
258
|
};
|
|
210
259
|
};
|
|
260
|
+
var hydrating = false;
|
|
261
|
+
var backgroundHydrate = (accessToken) => {
|
|
262
|
+
if (hydrating) return;
|
|
263
|
+
hydrating = true;
|
|
264
|
+
const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? "";
|
|
265
|
+
const decoded = decodeJwtPayload(accessToken);
|
|
266
|
+
const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1e3) + 3600;
|
|
267
|
+
const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1e3));
|
|
268
|
+
setTimeout(() => {
|
|
269
|
+
try {
|
|
270
|
+
const client = getClient();
|
|
271
|
+
client.createUser(
|
|
272
|
+
{
|
|
273
|
+
access_token: accessToken,
|
|
274
|
+
token_type: "bearer",
|
|
275
|
+
expires_in: expiresIn,
|
|
276
|
+
expires_at: expiresAt,
|
|
277
|
+
refresh_token: refreshToken
|
|
278
|
+
},
|
|
279
|
+
true
|
|
280
|
+
).catch(() => {
|
|
281
|
+
}).finally(() => {
|
|
282
|
+
hydrating = false;
|
|
283
|
+
});
|
|
284
|
+
} catch {
|
|
285
|
+
hydrating = false;
|
|
286
|
+
}
|
|
287
|
+
}, 0);
|
|
288
|
+
};
|
|
211
289
|
var decodeJwtPayload = (token) => {
|
|
212
290
|
try {
|
|
213
291
|
const parts = token.split(".");
|
|
@@ -223,32 +301,31 @@ var getUser = () => {
|
|
|
223
301
|
const client = getGoTrueClient();
|
|
224
302
|
const currentUser = client?.currentUser() ?? null;
|
|
225
303
|
if (currentUser) {
|
|
226
|
-
const
|
|
227
|
-
if (!
|
|
304
|
+
const jwt2 = getCookie(NF_JWT_COOKIE);
|
|
305
|
+
if (!jwt2) {
|
|
228
306
|
try {
|
|
229
|
-
currentUser.
|
|
307
|
+
currentUser.clearSession();
|
|
230
308
|
} catch {
|
|
231
309
|
}
|
|
232
310
|
return null;
|
|
233
311
|
}
|
|
234
312
|
return toUser(currentUser);
|
|
235
313
|
}
|
|
236
|
-
const
|
|
237
|
-
if (!
|
|
238
|
-
const claims = decodeJwtPayload(
|
|
314
|
+
const jwt = getCookie(NF_JWT_COOKIE);
|
|
315
|
+
if (!jwt) return null;
|
|
316
|
+
const claims = decodeJwtPayload(jwt);
|
|
239
317
|
if (!claims) return null;
|
|
318
|
+
backgroundHydrate(jwt);
|
|
240
319
|
return claimsToUser(claims);
|
|
241
320
|
}
|
|
321
|
+
triggerNextjsDynamic();
|
|
242
322
|
const identityContext = globalThis.netlifyIdentityContext;
|
|
243
323
|
if (identityContext?.user) {
|
|
244
324
|
return claimsToUser(identityContext.user);
|
|
245
325
|
}
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
`[@netlify/identity] getUser: no identityContext.user, but nf_jwt cookie found on request. Decoding JWT from cookie. (identityContext: ${identityContext ? `{ url: ${!!identityContext.url}, token: ${!!identityContext.token}, user: ${!!identityContext.user} }` : "null"}, Netlify.context: ${!!globalThis.Netlify?.context})`
|
|
250
|
-
);
|
|
251
|
-
const claims = decodeJwtPayload(jwt);
|
|
326
|
+
const serverJwt = getServerCookie(NF_JWT_COOKIE);
|
|
327
|
+
if (serverJwt) {
|
|
328
|
+
const claims = decodeJwtPayload(serverJwt);
|
|
252
329
|
if (claims) return claimsToUser(claims);
|
|
253
330
|
}
|
|
254
331
|
return null;
|
|
@@ -285,40 +362,36 @@ var getSettings = async () => {
|
|
|
285
362
|
}
|
|
286
363
|
};
|
|
287
364
|
|
|
288
|
-
// src/
|
|
289
|
-
var
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
};
|
|
296
|
-
var
|
|
297
|
-
const ctx = getIdentityContext();
|
|
298
|
-
if (!ctx?.url) {
|
|
299
|
-
throw new AuthError("Could not determine the Identity endpoint URL on the server");
|
|
300
|
-
}
|
|
301
|
-
return ctx.url;
|
|
302
|
-
};
|
|
303
|
-
var persistSession = true;
|
|
365
|
+
// src/events.ts
|
|
366
|
+
var AUTH_EVENTS = {
|
|
367
|
+
LOGIN: "login",
|
|
368
|
+
LOGOUT: "logout",
|
|
369
|
+
TOKEN_REFRESH: "token_refresh",
|
|
370
|
+
USER_UPDATED: "user_updated",
|
|
371
|
+
RECOVERY: "recovery"
|
|
372
|
+
};
|
|
373
|
+
var GOTRUE_STORAGE_KEY = "gotrue.user";
|
|
304
374
|
var listeners = /* @__PURE__ */ new Set();
|
|
305
375
|
var emitAuthEvent = (event, user) => {
|
|
306
376
|
for (const listener of listeners) {
|
|
307
|
-
|
|
377
|
+
try {
|
|
378
|
+
listener(event, user);
|
|
379
|
+
} catch {
|
|
380
|
+
}
|
|
308
381
|
}
|
|
309
382
|
};
|
|
310
383
|
var storageListenerAttached = false;
|
|
311
384
|
var attachStorageListener = () => {
|
|
312
|
-
if (storageListenerAttached) return;
|
|
385
|
+
if (storageListenerAttached || !isBrowser()) return;
|
|
313
386
|
storageListenerAttached = true;
|
|
314
387
|
window.addEventListener("storage", (event) => {
|
|
315
|
-
if (event.key !==
|
|
388
|
+
if (event.key !== GOTRUE_STORAGE_KEY) return;
|
|
316
389
|
if (event.newValue) {
|
|
317
390
|
const client = getGoTrueClient();
|
|
318
391
|
const currentUser = client?.currentUser();
|
|
319
|
-
emitAuthEvent(
|
|
392
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, currentUser ? toUser(currentUser) : null);
|
|
320
393
|
} else {
|
|
321
|
-
emitAuthEvent(
|
|
394
|
+
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
322
395
|
}
|
|
323
396
|
});
|
|
324
397
|
};
|
|
@@ -333,6 +406,23 @@ var onAuthChange = (callback) => {
|
|
|
333
406
|
listeners.delete(callback);
|
|
334
407
|
};
|
|
335
408
|
};
|
|
409
|
+
|
|
410
|
+
// src/auth.ts
|
|
411
|
+
var getCookies = () => {
|
|
412
|
+
const cookies = globalThis.Netlify?.context?.cookies;
|
|
413
|
+
if (!cookies) {
|
|
414
|
+
throw new AuthError("Server-side auth requires Netlify Functions runtime");
|
|
415
|
+
}
|
|
416
|
+
return cookies;
|
|
417
|
+
};
|
|
418
|
+
var getServerIdentityUrl = () => {
|
|
419
|
+
const ctx = getIdentityContext();
|
|
420
|
+
if (!ctx?.url) {
|
|
421
|
+
throw new AuthError("Could not determine the Identity endpoint URL on the server");
|
|
422
|
+
}
|
|
423
|
+
return ctx.url;
|
|
424
|
+
};
|
|
425
|
+
var persistSession = true;
|
|
336
426
|
var login = async (email, password) => {
|
|
337
427
|
if (!isBrowser()) {
|
|
338
428
|
const identityUrl = getServerIdentityUrl();
|
|
@@ -350,14 +440,11 @@ var login = async (email, password) => {
|
|
|
350
440
|
body: body.toString()
|
|
351
441
|
});
|
|
352
442
|
} catch (error) {
|
|
353
|
-
throw
|
|
443
|
+
throw AuthError.from(error);
|
|
354
444
|
}
|
|
355
445
|
if (!res.ok) {
|
|
356
446
|
const errorBody = await res.json().catch(() => ({}));
|
|
357
|
-
throw new AuthError(
|
|
358
|
-
errorBody.msg || errorBody.error_description || `Login failed (${res.status})`,
|
|
359
|
-
res.status
|
|
360
|
-
);
|
|
447
|
+
throw new AuthError(errorBody.msg || errorBody.error_description || `Login failed (${res.status})`, res.status);
|
|
361
448
|
}
|
|
362
449
|
const data = await res.json();
|
|
363
450
|
const accessToken = data.access_token;
|
|
@@ -367,14 +454,11 @@ var login = async (email, password) => {
|
|
|
367
454
|
headers: { Authorization: `Bearer ${accessToken}` }
|
|
368
455
|
});
|
|
369
456
|
} catch (error) {
|
|
370
|
-
throw
|
|
457
|
+
throw AuthError.from(error);
|
|
371
458
|
}
|
|
372
459
|
if (!userRes.ok) {
|
|
373
460
|
const errorBody = await userRes.json().catch(() => ({}));
|
|
374
|
-
throw new AuthError(
|
|
375
|
-
errorBody.msg || `Failed to fetch user data (${userRes.status})`,
|
|
376
|
-
userRes.status
|
|
377
|
-
);
|
|
461
|
+
throw new AuthError(errorBody.msg || `Failed to fetch user data (${userRes.status})`, userRes.status);
|
|
378
462
|
}
|
|
379
463
|
const userData = await userRes.json();
|
|
380
464
|
const user = toUser(userData);
|
|
@@ -385,12 +469,12 @@ var login = async (email, password) => {
|
|
|
385
469
|
try {
|
|
386
470
|
const gotrueUser = await client.login(email, password, persistSession);
|
|
387
471
|
const jwt = await gotrueUser.jwt();
|
|
388
|
-
setBrowserAuthCookies(jwt);
|
|
472
|
+
setBrowserAuthCookies(jwt, gotrueUser.tokenDetails()?.refresh_token);
|
|
389
473
|
const user = toUser(gotrueUser);
|
|
390
|
-
emitAuthEvent(
|
|
474
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
391
475
|
return user;
|
|
392
476
|
} catch (error) {
|
|
393
|
-
throw
|
|
477
|
+
throw AuthError.from(error);
|
|
394
478
|
}
|
|
395
479
|
};
|
|
396
480
|
var signup = async (email, password, data) => {
|
|
@@ -405,7 +489,7 @@ var signup = async (email, password, data) => {
|
|
|
405
489
|
body: JSON.stringify({ email, password, data })
|
|
406
490
|
});
|
|
407
491
|
} catch (error) {
|
|
408
|
-
throw
|
|
492
|
+
throw AuthError.from(error);
|
|
409
493
|
}
|
|
410
494
|
if (!res.ok) {
|
|
411
495
|
const errorBody = await res.json().catch(() => ({}));
|
|
@@ -414,10 +498,9 @@ var signup = async (email, password, data) => {
|
|
|
414
498
|
const responseData = await res.json();
|
|
415
499
|
const user = toUser(responseData);
|
|
416
500
|
if (responseData.confirmed_at) {
|
|
417
|
-
const
|
|
418
|
-
const accessToken = responseRecord.access_token;
|
|
501
|
+
const accessToken = responseData.access_token;
|
|
419
502
|
if (accessToken) {
|
|
420
|
-
setAuthCookies(cookies, accessToken,
|
|
503
|
+
setAuthCookies(cookies, accessToken, responseData.refresh_token);
|
|
421
504
|
}
|
|
422
505
|
}
|
|
423
506
|
return user;
|
|
@@ -427,11 +510,16 @@ var signup = async (email, password, data) => {
|
|
|
427
510
|
const response = await client.signup(email, password, data);
|
|
428
511
|
const user = toUser(response);
|
|
429
512
|
if (response.confirmed_at) {
|
|
430
|
-
|
|
513
|
+
const jwt = await response.jwt?.();
|
|
514
|
+
if (jwt) {
|
|
515
|
+
const refreshToken = response.tokenDetails?.()?.refresh_token;
|
|
516
|
+
setBrowserAuthCookies(jwt, refreshToken);
|
|
517
|
+
}
|
|
518
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
431
519
|
}
|
|
432
520
|
return user;
|
|
433
521
|
} catch (error) {
|
|
434
|
-
throw
|
|
522
|
+
throw AuthError.from(error);
|
|
435
523
|
}
|
|
436
524
|
};
|
|
437
525
|
var logout = async () => {
|
|
@@ -445,8 +533,7 @@ var logout = async () => {
|
|
|
445
533
|
method: "POST",
|
|
446
534
|
headers: { Authorization: `Bearer ${jwt}` }
|
|
447
535
|
});
|
|
448
|
-
} catch
|
|
449
|
-
throw new AuthError(error.message, void 0, { cause: error });
|
|
536
|
+
} catch {
|
|
450
537
|
}
|
|
451
538
|
}
|
|
452
539
|
deleteAuthCookies(cookies);
|
|
@@ -459,103 +546,111 @@ var logout = async () => {
|
|
|
459
546
|
await currentUser.logout();
|
|
460
547
|
}
|
|
461
548
|
deleteBrowserAuthCookies();
|
|
462
|
-
emitAuthEvent(
|
|
549
|
+
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
463
550
|
} catch (error) {
|
|
464
|
-
throw
|
|
551
|
+
throw AuthError.from(error);
|
|
465
552
|
}
|
|
466
553
|
};
|
|
467
554
|
var oauthLogin = (provider) => {
|
|
468
555
|
if (!isBrowser()) {
|
|
469
|
-
throw new
|
|
556
|
+
throw new AuthError("oauthLogin() is only available in the browser");
|
|
470
557
|
}
|
|
471
558
|
const client = getClient();
|
|
472
559
|
window.location.href = client.loginExternalUrl(provider);
|
|
473
|
-
throw new
|
|
560
|
+
throw new AuthError("Redirecting to OAuth provider");
|
|
474
561
|
};
|
|
475
562
|
var handleAuthCallback = async () => {
|
|
476
563
|
if (!isBrowser()) return null;
|
|
477
564
|
const hash = window.location.hash.substring(1);
|
|
478
565
|
if (!hash) return null;
|
|
479
566
|
const client = getClient();
|
|
567
|
+
const params = new URLSearchParams(hash);
|
|
480
568
|
try {
|
|
481
|
-
const params = new URLSearchParams(hash);
|
|
482
569
|
const accessToken = params.get("access_token");
|
|
483
|
-
if (accessToken)
|
|
484
|
-
const refreshToken = params.get("refresh_token") ?? "";
|
|
485
|
-
const gotrueUser = await client.createUser(
|
|
486
|
-
{
|
|
487
|
-
access_token: accessToken,
|
|
488
|
-
token_type: params.get("token_type") ?? "bearer",
|
|
489
|
-
expires_in: Number(params.get("expires_in")),
|
|
490
|
-
expires_at: Number(params.get("expires_at")),
|
|
491
|
-
refresh_token: refreshToken
|
|
492
|
-
},
|
|
493
|
-
persistSession
|
|
494
|
-
);
|
|
495
|
-
setBrowserAuthCookies(accessToken, refreshToken || void 0);
|
|
496
|
-
const user = toUser(gotrueUser);
|
|
497
|
-
clearHash();
|
|
498
|
-
emitAuthEvent("login", user);
|
|
499
|
-
return { type: "oauth", user };
|
|
500
|
-
}
|
|
570
|
+
if (accessToken) return await handleOAuthCallback(client, params, accessToken);
|
|
501
571
|
const confirmationToken = params.get("confirmation_token");
|
|
502
|
-
if (confirmationToken)
|
|
503
|
-
const gotrueUser = await client.confirm(confirmationToken, persistSession);
|
|
504
|
-
const jwt = await gotrueUser.jwt();
|
|
505
|
-
setBrowserAuthCookies(jwt);
|
|
506
|
-
const user = toUser(gotrueUser);
|
|
507
|
-
clearHash();
|
|
508
|
-
emitAuthEvent("login", user);
|
|
509
|
-
return { type: "confirmation", user };
|
|
510
|
-
}
|
|
572
|
+
if (confirmationToken) return await handleConfirmationCallback(client, confirmationToken);
|
|
511
573
|
const recoveryToken = params.get("recovery_token");
|
|
512
|
-
if (recoveryToken)
|
|
513
|
-
const gotrueUser = await client.recover(recoveryToken, persistSession);
|
|
514
|
-
const jwt = await gotrueUser.jwt();
|
|
515
|
-
setBrowserAuthCookies(jwt);
|
|
516
|
-
const user = toUser(gotrueUser);
|
|
517
|
-
clearHash();
|
|
518
|
-
emitAuthEvent("login", user);
|
|
519
|
-
return { type: "recovery", user };
|
|
520
|
-
}
|
|
574
|
+
if (recoveryToken) return await handleRecoveryCallback(client, recoveryToken);
|
|
521
575
|
const inviteToken = params.get("invite_token");
|
|
522
|
-
if (inviteToken)
|
|
523
|
-
clearHash();
|
|
524
|
-
return { type: "invite", user: null, token: inviteToken };
|
|
525
|
-
}
|
|
576
|
+
if (inviteToken) return handleInviteCallback(inviteToken);
|
|
526
577
|
const emailChangeToken = params.get("email_change_token");
|
|
527
|
-
if (emailChangeToken)
|
|
528
|
-
const currentUser = client.currentUser();
|
|
529
|
-
if (!currentUser) {
|
|
530
|
-
throw new AuthError("Email change verification requires an active browser session");
|
|
531
|
-
}
|
|
532
|
-
const jwt = await currentUser.jwt();
|
|
533
|
-
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
534
|
-
const emailChangeRes = await fetch(`${identityUrl}/user`, {
|
|
535
|
-
method: "PUT",
|
|
536
|
-
headers: {
|
|
537
|
-
"Content-Type": "application/json",
|
|
538
|
-
Authorization: `Bearer ${jwt}`
|
|
539
|
-
},
|
|
540
|
-
body: JSON.stringify({ email_change_token: emailChangeToken })
|
|
541
|
-
});
|
|
542
|
-
if (!emailChangeRes.ok) {
|
|
543
|
-
const errorBody = await emailChangeRes.json().catch(() => ({}));
|
|
544
|
-
throw new AuthError(
|
|
545
|
-
errorBody.msg || `Email change verification failed (${emailChangeRes.status})`,
|
|
546
|
-
emailChangeRes.status
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
const emailChangeData = await emailChangeRes.json();
|
|
550
|
-
const user = toUser(emailChangeData);
|
|
551
|
-
clearHash();
|
|
552
|
-
emitAuthEvent("user_updated", user);
|
|
553
|
-
return { type: "email_change", user };
|
|
554
|
-
}
|
|
578
|
+
if (emailChangeToken) return await handleEmailChangeCallback(client, emailChangeToken);
|
|
555
579
|
return null;
|
|
556
580
|
} catch (error) {
|
|
557
|
-
|
|
581
|
+
if (error instanceof AuthError) throw error;
|
|
582
|
+
throw AuthError.from(error);
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
var handleOAuthCallback = async (client, params, accessToken) => {
|
|
586
|
+
const refreshToken = params.get("refresh_token") ?? "";
|
|
587
|
+
const expiresIn = parseInt(params.get("expires_in") ?? "", 10);
|
|
588
|
+
const expiresAt = parseInt(params.get("expires_at") ?? "", 10);
|
|
589
|
+
const gotrueUser = await client.createUser(
|
|
590
|
+
{
|
|
591
|
+
access_token: accessToken,
|
|
592
|
+
token_type: params.get("token_type") ?? "bearer",
|
|
593
|
+
expires_in: isFinite(expiresIn) ? expiresIn : 3600,
|
|
594
|
+
expires_at: isFinite(expiresAt) ? expiresAt : Math.floor(Date.now() / 1e3) + 3600,
|
|
595
|
+
refresh_token: refreshToken
|
|
596
|
+
},
|
|
597
|
+
persistSession
|
|
598
|
+
);
|
|
599
|
+
setBrowserAuthCookies(accessToken, refreshToken || void 0);
|
|
600
|
+
const user = toUser(gotrueUser);
|
|
601
|
+
clearHash();
|
|
602
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
603
|
+
return { type: "oauth", user };
|
|
604
|
+
};
|
|
605
|
+
var handleConfirmationCallback = async (client, token) => {
|
|
606
|
+
const gotrueUser = await client.confirm(token, persistSession);
|
|
607
|
+
const jwt = await gotrueUser.jwt();
|
|
608
|
+
setBrowserAuthCookies(jwt, gotrueUser.tokenDetails()?.refresh_token);
|
|
609
|
+
const user = toUser(gotrueUser);
|
|
610
|
+
clearHash();
|
|
611
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
612
|
+
return { type: "confirmation", user };
|
|
613
|
+
};
|
|
614
|
+
var handleRecoveryCallback = async (client, token) => {
|
|
615
|
+
const gotrueUser = await client.recover(token, persistSession);
|
|
616
|
+
const jwt = await gotrueUser.jwt();
|
|
617
|
+
setBrowserAuthCookies(jwt, gotrueUser.tokenDetails()?.refresh_token);
|
|
618
|
+
const user = toUser(gotrueUser);
|
|
619
|
+
clearHash();
|
|
620
|
+
emitAuthEvent(AUTH_EVENTS.RECOVERY, user);
|
|
621
|
+
return { type: "recovery", user };
|
|
622
|
+
};
|
|
623
|
+
var handleInviteCallback = (token) => {
|
|
624
|
+
clearHash();
|
|
625
|
+
return { type: "invite", user: null, token };
|
|
626
|
+
};
|
|
627
|
+
var handleEmailChangeCallback = async (client, emailChangeToken) => {
|
|
628
|
+
const currentUser = client.currentUser();
|
|
629
|
+
if (!currentUser) {
|
|
630
|
+
throw new AuthError("Email change verification requires an active browser session");
|
|
558
631
|
}
|
|
632
|
+
const jwt = await currentUser.jwt();
|
|
633
|
+
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
634
|
+
const emailChangeRes = await fetch(`${identityUrl}/user`, {
|
|
635
|
+
method: "PUT",
|
|
636
|
+
headers: {
|
|
637
|
+
"Content-Type": "application/json",
|
|
638
|
+
Authorization: `Bearer ${jwt}`
|
|
639
|
+
},
|
|
640
|
+
body: JSON.stringify({ email_change_token: emailChangeToken })
|
|
641
|
+
});
|
|
642
|
+
if (!emailChangeRes.ok) {
|
|
643
|
+
const errorBody = await emailChangeRes.json().catch(() => ({}));
|
|
644
|
+
throw new AuthError(
|
|
645
|
+
errorBody.msg || `Email change verification failed (${emailChangeRes.status})`,
|
|
646
|
+
emailChangeRes.status
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
const emailChangeData = await emailChangeRes.json();
|
|
650
|
+
const user = toUser(emailChangeData);
|
|
651
|
+
clearHash();
|
|
652
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
653
|
+
return { type: "email_change", user };
|
|
559
654
|
};
|
|
560
655
|
var clearHash = () => {
|
|
561
656
|
history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
@@ -568,23 +663,32 @@ var hydrateSession = async () => {
|
|
|
568
663
|
const accessToken = getCookie(NF_JWT_COOKIE);
|
|
569
664
|
if (!accessToken) return null;
|
|
570
665
|
const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? "";
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
666
|
+
const decoded = decodeJwtPayload(accessToken);
|
|
667
|
+
const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1e3) + 3600;
|
|
668
|
+
const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1e3));
|
|
669
|
+
let gotrueUser;
|
|
670
|
+
try {
|
|
671
|
+
gotrueUser = await client.createUser(
|
|
672
|
+
{
|
|
673
|
+
access_token: accessToken,
|
|
674
|
+
token_type: "bearer",
|
|
675
|
+
expires_in: expiresIn,
|
|
676
|
+
expires_at: expiresAt,
|
|
677
|
+
refresh_token: refreshToken
|
|
678
|
+
},
|
|
679
|
+
persistSession
|
|
680
|
+
);
|
|
681
|
+
} catch {
|
|
682
|
+
deleteBrowserAuthCookies();
|
|
683
|
+
return null;
|
|
684
|
+
}
|
|
581
685
|
const user = toUser(gotrueUser);
|
|
582
|
-
emitAuthEvent(
|
|
686
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
583
687
|
return user;
|
|
584
688
|
};
|
|
585
689
|
|
|
586
690
|
// src/account.ts
|
|
587
|
-
var
|
|
691
|
+
var resolveCurrentUser = async () => {
|
|
588
692
|
const client = getClient();
|
|
589
693
|
let currentUser = client.currentUser();
|
|
590
694
|
if (!currentUser && isBrowser()) {
|
|
@@ -602,7 +706,7 @@ var requestPasswordRecovery = async (email) => {
|
|
|
602
706
|
try {
|
|
603
707
|
await client.requestPasswordRecovery(email);
|
|
604
708
|
} catch (error) {
|
|
605
|
-
throw
|
|
709
|
+
throw AuthError.from(error);
|
|
606
710
|
}
|
|
607
711
|
};
|
|
608
712
|
var recoverPassword = async (token, newPassword) => {
|
|
@@ -611,10 +715,10 @@ var recoverPassword = async (token, newPassword) => {
|
|
|
611
715
|
const gotrueUser = await client.recover(token, persistSession);
|
|
612
716
|
const updatedUser = await gotrueUser.update({ password: newPassword });
|
|
613
717
|
const user = toUser(updatedUser);
|
|
614
|
-
emitAuthEvent(
|
|
718
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
615
719
|
return user;
|
|
616
720
|
} catch (error) {
|
|
617
|
-
throw
|
|
721
|
+
throw AuthError.from(error);
|
|
618
722
|
}
|
|
619
723
|
};
|
|
620
724
|
var confirmEmail = async (token) => {
|
|
@@ -622,10 +726,10 @@ var confirmEmail = async (token) => {
|
|
|
622
726
|
try {
|
|
623
727
|
const gotrueUser = await client.confirm(token, persistSession);
|
|
624
728
|
const user = toUser(gotrueUser);
|
|
625
|
-
emitAuthEvent(
|
|
729
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
626
730
|
return user;
|
|
627
731
|
} catch (error) {
|
|
628
|
-
throw
|
|
732
|
+
throw AuthError.from(error);
|
|
629
733
|
}
|
|
630
734
|
};
|
|
631
735
|
var acceptInvite = async (token, password) => {
|
|
@@ -633,18 +737,18 @@ var acceptInvite = async (token, password) => {
|
|
|
633
737
|
try {
|
|
634
738
|
const gotrueUser = await client.acceptInvite(token, password, persistSession);
|
|
635
739
|
const user = toUser(gotrueUser);
|
|
636
|
-
emitAuthEvent(
|
|
740
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
637
741
|
return user;
|
|
638
742
|
} catch (error) {
|
|
639
|
-
throw
|
|
743
|
+
throw AuthError.from(error);
|
|
640
744
|
}
|
|
641
745
|
};
|
|
642
746
|
var verifyEmailChange = async (token) => {
|
|
643
747
|
if (!isBrowser()) throw new AuthError("verifyEmailChange() is only available in the browser");
|
|
644
|
-
const currentUser = await
|
|
645
|
-
const jwt = await currentUser.jwt();
|
|
646
|
-
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
748
|
+
const currentUser = await resolveCurrentUser();
|
|
647
749
|
try {
|
|
750
|
+
const jwt = await currentUser.jwt();
|
|
751
|
+
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
648
752
|
const res = await fetch(`${identityUrl}/user`, {
|
|
649
753
|
method: "PUT",
|
|
650
754
|
headers: {
|
|
@@ -655,33 +759,31 @@ var verifyEmailChange = async (token) => {
|
|
|
655
759
|
});
|
|
656
760
|
if (!res.ok) {
|
|
657
761
|
const errorBody = await res.json().catch(() => ({}));
|
|
658
|
-
throw new AuthError(
|
|
659
|
-
errorBody.msg || `Email change verification failed (${res.status})`,
|
|
660
|
-
res.status
|
|
661
|
-
);
|
|
762
|
+
throw new AuthError(errorBody.msg || `Email change verification failed (${res.status})`, res.status);
|
|
662
763
|
}
|
|
663
764
|
const userData = await res.json();
|
|
664
765
|
const user = toUser(userData);
|
|
665
|
-
emitAuthEvent(
|
|
766
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
666
767
|
return user;
|
|
667
768
|
} catch (error) {
|
|
668
769
|
if (error instanceof AuthError) throw error;
|
|
669
|
-
throw
|
|
770
|
+
throw AuthError.from(error);
|
|
670
771
|
}
|
|
671
772
|
};
|
|
672
773
|
var updateUser = async (updates) => {
|
|
673
|
-
const currentUser = await
|
|
774
|
+
const currentUser = await resolveCurrentUser();
|
|
674
775
|
try {
|
|
675
776
|
const updatedUser = await currentUser.update(updates);
|
|
676
777
|
const user = toUser(updatedUser);
|
|
677
|
-
emitAuthEvent(
|
|
778
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
678
779
|
return user;
|
|
679
780
|
} catch (error) {
|
|
680
|
-
throw
|
|
781
|
+
throw AuthError.from(error);
|
|
681
782
|
}
|
|
682
783
|
};
|
|
683
784
|
// Annotate the CommonJS export names for ESM import in node:
|
|
684
785
|
0 && (module.exports = {
|
|
786
|
+
AUTH_EVENTS,
|
|
685
787
|
AuthError,
|
|
686
788
|
MissingIdentityError,
|
|
687
789
|
acceptInvite,
|
|
@@ -690,6 +792,7 @@ var updateUser = async (updates) => {
|
|
|
690
792
|
getSettings,
|
|
691
793
|
getUser,
|
|
692
794
|
handleAuthCallback,
|
|
795
|
+
hydrateSession,
|
|
693
796
|
isAuthenticated,
|
|
694
797
|
login,
|
|
695
798
|
logout,
|