@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.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/types.ts
|
|
2
9
|
var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "saml", "email"];
|
|
3
10
|
|
|
@@ -5,7 +12,7 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
|
|
|
5
12
|
import GoTrue from "gotrue-js";
|
|
6
13
|
|
|
7
14
|
// src/errors.ts
|
|
8
|
-
var AuthError = class extends Error {
|
|
15
|
+
var AuthError = class _AuthError extends Error {
|
|
9
16
|
constructor(message, status, options) {
|
|
10
17
|
super(message);
|
|
11
18
|
this.name = "AuthError";
|
|
@@ -14,9 +21,14 @@ var AuthError = class extends Error {
|
|
|
14
21
|
this.cause = options.cause;
|
|
15
22
|
}
|
|
16
23
|
}
|
|
24
|
+
static from(error) {
|
|
25
|
+
if (error instanceof _AuthError) return error;
|
|
26
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
27
|
+
return new _AuthError(message, void 0, { cause: error });
|
|
28
|
+
}
|
|
17
29
|
};
|
|
18
30
|
var MissingIdentityError = class extends Error {
|
|
19
|
-
constructor(message = "Identity is not available
|
|
31
|
+
constructor(message = "Netlify Identity is not available.") {
|
|
20
32
|
super(message);
|
|
21
33
|
this.name = "MissingIdentityError";
|
|
22
34
|
}
|
|
@@ -38,6 +50,8 @@ var discoverApiUrl = () => {
|
|
|
38
50
|
cachedApiUrl = identityContext.url;
|
|
39
51
|
} else if (globalThis.Netlify?.context?.url) {
|
|
40
52
|
cachedApiUrl = new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href;
|
|
53
|
+
} else if (typeof process !== "undefined" && process.env?.URL) {
|
|
54
|
+
cachedApiUrl = new URL(IDENTITY_PATH, process.env.URL).href;
|
|
41
55
|
}
|
|
42
56
|
}
|
|
43
57
|
return cachedApiUrl ?? null;
|
|
@@ -54,7 +68,7 @@ var getGoTrueClient = () => {
|
|
|
54
68
|
}
|
|
55
69
|
return null;
|
|
56
70
|
}
|
|
57
|
-
goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie:
|
|
71
|
+
goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: false });
|
|
58
72
|
return goTrueClient;
|
|
59
73
|
};
|
|
60
74
|
var getClient = () => {
|
|
@@ -73,6 +87,10 @@ var getIdentityContext = () => {
|
|
|
73
87
|
if (globalThis.Netlify?.context?.url) {
|
|
74
88
|
return { url: new URL(IDENTITY_PATH, globalThis.Netlify.context.url).href };
|
|
75
89
|
}
|
|
90
|
+
const siteUrl = typeof process !== "undefined" ? process.env?.URL : void 0;
|
|
91
|
+
if (siteUrl) {
|
|
92
|
+
return { url: new URL(IDENTITY_PATH, siteUrl).href };
|
|
93
|
+
}
|
|
76
94
|
return null;
|
|
77
95
|
};
|
|
78
96
|
|
|
@@ -80,8 +98,14 @@ var getIdentityContext = () => {
|
|
|
80
98
|
var NF_JWT_COOKIE = "nf_jwt";
|
|
81
99
|
var NF_REFRESH_COOKIE = "nf_refresh";
|
|
82
100
|
var getCookie = (name) => {
|
|
101
|
+
if (typeof document === "undefined") return null;
|
|
83
102
|
const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]*)`));
|
|
84
|
-
|
|
103
|
+
if (!match) return null;
|
|
104
|
+
try {
|
|
105
|
+
return decodeURIComponent(match[1]);
|
|
106
|
+
} catch {
|
|
107
|
+
return match[1];
|
|
108
|
+
}
|
|
85
109
|
};
|
|
86
110
|
var setAuthCookies = (cookies, accessToken, refreshToken) => {
|
|
87
111
|
cookies.set({
|
|
@@ -108,14 +132,16 @@ var deleteAuthCookies = (cookies) => {
|
|
|
108
132
|
cookies.delete(NF_REFRESH_COOKIE);
|
|
109
133
|
};
|
|
110
134
|
var setBrowserAuthCookies = (accessToken, refreshToken) => {
|
|
135
|
+
if (typeof document === "undefined") return;
|
|
111
136
|
document.cookie = `${NF_JWT_COOKIE}=${encodeURIComponent(accessToken)}; path=/; secure; samesite=lax`;
|
|
112
137
|
if (refreshToken) {
|
|
113
138
|
document.cookie = `${NF_REFRESH_COOKIE}=${encodeURIComponent(refreshToken)}; path=/; secure; samesite=lax`;
|
|
114
139
|
}
|
|
115
140
|
};
|
|
116
141
|
var deleteBrowserAuthCookies = () => {
|
|
117
|
-
|
|
118
|
-
document.cookie = `${
|
|
142
|
+
if (typeof document === "undefined") return;
|
|
143
|
+
document.cookie = `${NF_JWT_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
144
|
+
document.cookie = `${NF_REFRESH_COOKIE}=; path=/; secure; samesite=lax; expires=Thu, 01 Jan 1970 00:00:00 GMT`;
|
|
119
145
|
};
|
|
120
146
|
var getServerCookie = (name) => {
|
|
121
147
|
const cookies = globalThis.Netlify?.context?.cookies;
|
|
@@ -123,6 +149,34 @@ var getServerCookie = (name) => {
|
|
|
123
149
|
return cookies.get(name) ?? null;
|
|
124
150
|
};
|
|
125
151
|
|
|
152
|
+
// src/nextjs.ts
|
|
153
|
+
var nextHeadersFn;
|
|
154
|
+
var triggerNextjsDynamic = () => {
|
|
155
|
+
if (nextHeadersFn === null) return;
|
|
156
|
+
if (nextHeadersFn === void 0) {
|
|
157
|
+
try {
|
|
158
|
+
if (typeof __require === "undefined") {
|
|
159
|
+
nextHeadersFn = null;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const mod = __require("next/headers");
|
|
163
|
+
nextHeadersFn = mod.headers;
|
|
164
|
+
} catch {
|
|
165
|
+
nextHeadersFn = null;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const fn = nextHeadersFn;
|
|
170
|
+
if (!fn) return;
|
|
171
|
+
try {
|
|
172
|
+
fn();
|
|
173
|
+
} catch (e) {
|
|
174
|
+
if (e instanceof Error && ("digest" in e || /bail\s*out.*prerende/i.test(e.message))) {
|
|
175
|
+
throw e;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
126
180
|
// src/user.ts
|
|
127
181
|
var toAuthProvider = (value) => typeof value === "string" && AUTH_PROVIDERS.includes(value) ? value : void 0;
|
|
128
182
|
var toUser = (userData) => {
|
|
@@ -155,6 +209,35 @@ var claimsToUser = (claims) => {
|
|
|
155
209
|
metadata: userMeta
|
|
156
210
|
};
|
|
157
211
|
};
|
|
212
|
+
var hydrating = false;
|
|
213
|
+
var backgroundHydrate = (accessToken) => {
|
|
214
|
+
if (hydrating) return;
|
|
215
|
+
hydrating = true;
|
|
216
|
+
const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? "";
|
|
217
|
+
const decoded = decodeJwtPayload(accessToken);
|
|
218
|
+
const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1e3) + 3600;
|
|
219
|
+
const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1e3));
|
|
220
|
+
setTimeout(() => {
|
|
221
|
+
try {
|
|
222
|
+
const client = getClient();
|
|
223
|
+
client.createUser(
|
|
224
|
+
{
|
|
225
|
+
access_token: accessToken,
|
|
226
|
+
token_type: "bearer",
|
|
227
|
+
expires_in: expiresIn,
|
|
228
|
+
expires_at: expiresAt,
|
|
229
|
+
refresh_token: refreshToken
|
|
230
|
+
},
|
|
231
|
+
true
|
|
232
|
+
).catch(() => {
|
|
233
|
+
}).finally(() => {
|
|
234
|
+
hydrating = false;
|
|
235
|
+
});
|
|
236
|
+
} catch {
|
|
237
|
+
hydrating = false;
|
|
238
|
+
}
|
|
239
|
+
}, 0);
|
|
240
|
+
};
|
|
158
241
|
var decodeJwtPayload = (token) => {
|
|
159
242
|
try {
|
|
160
243
|
const parts = token.split(".");
|
|
@@ -170,32 +253,31 @@ var getUser = () => {
|
|
|
170
253
|
const client = getGoTrueClient();
|
|
171
254
|
const currentUser = client?.currentUser() ?? null;
|
|
172
255
|
if (currentUser) {
|
|
173
|
-
const
|
|
174
|
-
if (!
|
|
256
|
+
const jwt2 = getCookie(NF_JWT_COOKIE);
|
|
257
|
+
if (!jwt2) {
|
|
175
258
|
try {
|
|
176
|
-
currentUser.
|
|
259
|
+
currentUser.clearSession();
|
|
177
260
|
} catch {
|
|
178
261
|
}
|
|
179
262
|
return null;
|
|
180
263
|
}
|
|
181
264
|
return toUser(currentUser);
|
|
182
265
|
}
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
185
|
-
const claims = decodeJwtPayload(
|
|
266
|
+
const jwt = getCookie(NF_JWT_COOKIE);
|
|
267
|
+
if (!jwt) return null;
|
|
268
|
+
const claims = decodeJwtPayload(jwt);
|
|
186
269
|
if (!claims) return null;
|
|
270
|
+
backgroundHydrate(jwt);
|
|
187
271
|
return claimsToUser(claims);
|
|
188
272
|
}
|
|
273
|
+
triggerNextjsDynamic();
|
|
189
274
|
const identityContext = globalThis.netlifyIdentityContext;
|
|
190
275
|
if (identityContext?.user) {
|
|
191
276
|
return claimsToUser(identityContext.user);
|
|
192
277
|
}
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
`[@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})`
|
|
197
|
-
);
|
|
198
|
-
const claims = decodeJwtPayload(jwt);
|
|
278
|
+
const serverJwt = getServerCookie(NF_JWT_COOKIE);
|
|
279
|
+
if (serverJwt) {
|
|
280
|
+
const claims = decodeJwtPayload(serverJwt);
|
|
199
281
|
if (claims) return claimsToUser(claims);
|
|
200
282
|
}
|
|
201
283
|
return null;
|
|
@@ -232,40 +314,36 @@ var getSettings = async () => {
|
|
|
232
314
|
}
|
|
233
315
|
};
|
|
234
316
|
|
|
235
|
-
// src/
|
|
236
|
-
var
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
};
|
|
243
|
-
var
|
|
244
|
-
const ctx = getIdentityContext();
|
|
245
|
-
if (!ctx?.url) {
|
|
246
|
-
throw new AuthError("Could not determine the Identity endpoint URL on the server");
|
|
247
|
-
}
|
|
248
|
-
return ctx.url;
|
|
249
|
-
};
|
|
250
|
-
var persistSession = true;
|
|
317
|
+
// src/events.ts
|
|
318
|
+
var AUTH_EVENTS = {
|
|
319
|
+
LOGIN: "login",
|
|
320
|
+
LOGOUT: "logout",
|
|
321
|
+
TOKEN_REFRESH: "token_refresh",
|
|
322
|
+
USER_UPDATED: "user_updated",
|
|
323
|
+
RECOVERY: "recovery"
|
|
324
|
+
};
|
|
325
|
+
var GOTRUE_STORAGE_KEY = "gotrue.user";
|
|
251
326
|
var listeners = /* @__PURE__ */ new Set();
|
|
252
327
|
var emitAuthEvent = (event, user) => {
|
|
253
328
|
for (const listener of listeners) {
|
|
254
|
-
|
|
329
|
+
try {
|
|
330
|
+
listener(event, user);
|
|
331
|
+
} catch {
|
|
332
|
+
}
|
|
255
333
|
}
|
|
256
334
|
};
|
|
257
335
|
var storageListenerAttached = false;
|
|
258
336
|
var attachStorageListener = () => {
|
|
259
|
-
if (storageListenerAttached) return;
|
|
337
|
+
if (storageListenerAttached || !isBrowser()) return;
|
|
260
338
|
storageListenerAttached = true;
|
|
261
339
|
window.addEventListener("storage", (event) => {
|
|
262
|
-
if (event.key !==
|
|
340
|
+
if (event.key !== GOTRUE_STORAGE_KEY) return;
|
|
263
341
|
if (event.newValue) {
|
|
264
342
|
const client = getGoTrueClient();
|
|
265
343
|
const currentUser = client?.currentUser();
|
|
266
|
-
emitAuthEvent(
|
|
344
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, currentUser ? toUser(currentUser) : null);
|
|
267
345
|
} else {
|
|
268
|
-
emitAuthEvent(
|
|
346
|
+
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
269
347
|
}
|
|
270
348
|
});
|
|
271
349
|
};
|
|
@@ -280,6 +358,23 @@ var onAuthChange = (callback) => {
|
|
|
280
358
|
listeners.delete(callback);
|
|
281
359
|
};
|
|
282
360
|
};
|
|
361
|
+
|
|
362
|
+
// src/auth.ts
|
|
363
|
+
var getCookies = () => {
|
|
364
|
+
const cookies = globalThis.Netlify?.context?.cookies;
|
|
365
|
+
if (!cookies) {
|
|
366
|
+
throw new AuthError("Server-side auth requires Netlify Functions runtime");
|
|
367
|
+
}
|
|
368
|
+
return cookies;
|
|
369
|
+
};
|
|
370
|
+
var getServerIdentityUrl = () => {
|
|
371
|
+
const ctx = getIdentityContext();
|
|
372
|
+
if (!ctx?.url) {
|
|
373
|
+
throw new AuthError("Could not determine the Identity endpoint URL on the server");
|
|
374
|
+
}
|
|
375
|
+
return ctx.url;
|
|
376
|
+
};
|
|
377
|
+
var persistSession = true;
|
|
283
378
|
var login = async (email, password) => {
|
|
284
379
|
if (!isBrowser()) {
|
|
285
380
|
const identityUrl = getServerIdentityUrl();
|
|
@@ -297,14 +392,11 @@ var login = async (email, password) => {
|
|
|
297
392
|
body: body.toString()
|
|
298
393
|
});
|
|
299
394
|
} catch (error) {
|
|
300
|
-
throw
|
|
395
|
+
throw AuthError.from(error);
|
|
301
396
|
}
|
|
302
397
|
if (!res.ok) {
|
|
303
398
|
const errorBody = await res.json().catch(() => ({}));
|
|
304
|
-
throw new AuthError(
|
|
305
|
-
errorBody.msg || errorBody.error_description || `Login failed (${res.status})`,
|
|
306
|
-
res.status
|
|
307
|
-
);
|
|
399
|
+
throw new AuthError(errorBody.msg || errorBody.error_description || `Login failed (${res.status})`, res.status);
|
|
308
400
|
}
|
|
309
401
|
const data = await res.json();
|
|
310
402
|
const accessToken = data.access_token;
|
|
@@ -314,14 +406,11 @@ var login = async (email, password) => {
|
|
|
314
406
|
headers: { Authorization: `Bearer ${accessToken}` }
|
|
315
407
|
});
|
|
316
408
|
} catch (error) {
|
|
317
|
-
throw
|
|
409
|
+
throw AuthError.from(error);
|
|
318
410
|
}
|
|
319
411
|
if (!userRes.ok) {
|
|
320
412
|
const errorBody = await userRes.json().catch(() => ({}));
|
|
321
|
-
throw new AuthError(
|
|
322
|
-
errorBody.msg || `Failed to fetch user data (${userRes.status})`,
|
|
323
|
-
userRes.status
|
|
324
|
-
);
|
|
413
|
+
throw new AuthError(errorBody.msg || `Failed to fetch user data (${userRes.status})`, userRes.status);
|
|
325
414
|
}
|
|
326
415
|
const userData = await userRes.json();
|
|
327
416
|
const user = toUser(userData);
|
|
@@ -332,12 +421,12 @@ var login = async (email, password) => {
|
|
|
332
421
|
try {
|
|
333
422
|
const gotrueUser = await client.login(email, password, persistSession);
|
|
334
423
|
const jwt = await gotrueUser.jwt();
|
|
335
|
-
setBrowserAuthCookies(jwt);
|
|
424
|
+
setBrowserAuthCookies(jwt, gotrueUser.tokenDetails()?.refresh_token);
|
|
336
425
|
const user = toUser(gotrueUser);
|
|
337
|
-
emitAuthEvent(
|
|
426
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
338
427
|
return user;
|
|
339
428
|
} catch (error) {
|
|
340
|
-
throw
|
|
429
|
+
throw AuthError.from(error);
|
|
341
430
|
}
|
|
342
431
|
};
|
|
343
432
|
var signup = async (email, password, data) => {
|
|
@@ -352,7 +441,7 @@ var signup = async (email, password, data) => {
|
|
|
352
441
|
body: JSON.stringify({ email, password, data })
|
|
353
442
|
});
|
|
354
443
|
} catch (error) {
|
|
355
|
-
throw
|
|
444
|
+
throw AuthError.from(error);
|
|
356
445
|
}
|
|
357
446
|
if (!res.ok) {
|
|
358
447
|
const errorBody = await res.json().catch(() => ({}));
|
|
@@ -361,10 +450,9 @@ var signup = async (email, password, data) => {
|
|
|
361
450
|
const responseData = await res.json();
|
|
362
451
|
const user = toUser(responseData);
|
|
363
452
|
if (responseData.confirmed_at) {
|
|
364
|
-
const
|
|
365
|
-
const accessToken = responseRecord.access_token;
|
|
453
|
+
const accessToken = responseData.access_token;
|
|
366
454
|
if (accessToken) {
|
|
367
|
-
setAuthCookies(cookies, accessToken,
|
|
455
|
+
setAuthCookies(cookies, accessToken, responseData.refresh_token);
|
|
368
456
|
}
|
|
369
457
|
}
|
|
370
458
|
return user;
|
|
@@ -374,11 +462,16 @@ var signup = async (email, password, data) => {
|
|
|
374
462
|
const response = await client.signup(email, password, data);
|
|
375
463
|
const user = toUser(response);
|
|
376
464
|
if (response.confirmed_at) {
|
|
377
|
-
|
|
465
|
+
const jwt = await response.jwt?.();
|
|
466
|
+
if (jwt) {
|
|
467
|
+
const refreshToken = response.tokenDetails?.()?.refresh_token;
|
|
468
|
+
setBrowserAuthCookies(jwt, refreshToken);
|
|
469
|
+
}
|
|
470
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
378
471
|
}
|
|
379
472
|
return user;
|
|
380
473
|
} catch (error) {
|
|
381
|
-
throw
|
|
474
|
+
throw AuthError.from(error);
|
|
382
475
|
}
|
|
383
476
|
};
|
|
384
477
|
var logout = async () => {
|
|
@@ -392,8 +485,7 @@ var logout = async () => {
|
|
|
392
485
|
method: "POST",
|
|
393
486
|
headers: { Authorization: `Bearer ${jwt}` }
|
|
394
487
|
});
|
|
395
|
-
} catch
|
|
396
|
-
throw new AuthError(error.message, void 0, { cause: error });
|
|
488
|
+
} catch {
|
|
397
489
|
}
|
|
398
490
|
}
|
|
399
491
|
deleteAuthCookies(cookies);
|
|
@@ -406,103 +498,111 @@ var logout = async () => {
|
|
|
406
498
|
await currentUser.logout();
|
|
407
499
|
}
|
|
408
500
|
deleteBrowserAuthCookies();
|
|
409
|
-
emitAuthEvent(
|
|
501
|
+
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
410
502
|
} catch (error) {
|
|
411
|
-
throw
|
|
503
|
+
throw AuthError.from(error);
|
|
412
504
|
}
|
|
413
505
|
};
|
|
414
506
|
var oauthLogin = (provider) => {
|
|
415
507
|
if (!isBrowser()) {
|
|
416
|
-
throw new
|
|
508
|
+
throw new AuthError("oauthLogin() is only available in the browser");
|
|
417
509
|
}
|
|
418
510
|
const client = getClient();
|
|
419
511
|
window.location.href = client.loginExternalUrl(provider);
|
|
420
|
-
throw new
|
|
512
|
+
throw new AuthError("Redirecting to OAuth provider");
|
|
421
513
|
};
|
|
422
514
|
var handleAuthCallback = async () => {
|
|
423
515
|
if (!isBrowser()) return null;
|
|
424
516
|
const hash = window.location.hash.substring(1);
|
|
425
517
|
if (!hash) return null;
|
|
426
518
|
const client = getClient();
|
|
519
|
+
const params = new URLSearchParams(hash);
|
|
427
520
|
try {
|
|
428
|
-
const params = new URLSearchParams(hash);
|
|
429
521
|
const accessToken = params.get("access_token");
|
|
430
|
-
if (accessToken)
|
|
431
|
-
const refreshToken = params.get("refresh_token") ?? "";
|
|
432
|
-
const gotrueUser = await client.createUser(
|
|
433
|
-
{
|
|
434
|
-
access_token: accessToken,
|
|
435
|
-
token_type: params.get("token_type") ?? "bearer",
|
|
436
|
-
expires_in: Number(params.get("expires_in")),
|
|
437
|
-
expires_at: Number(params.get("expires_at")),
|
|
438
|
-
refresh_token: refreshToken
|
|
439
|
-
},
|
|
440
|
-
persistSession
|
|
441
|
-
);
|
|
442
|
-
setBrowserAuthCookies(accessToken, refreshToken || void 0);
|
|
443
|
-
const user = toUser(gotrueUser);
|
|
444
|
-
clearHash();
|
|
445
|
-
emitAuthEvent("login", user);
|
|
446
|
-
return { type: "oauth", user };
|
|
447
|
-
}
|
|
522
|
+
if (accessToken) return await handleOAuthCallback(client, params, accessToken);
|
|
448
523
|
const confirmationToken = params.get("confirmation_token");
|
|
449
|
-
if (confirmationToken)
|
|
450
|
-
const gotrueUser = await client.confirm(confirmationToken, persistSession);
|
|
451
|
-
const jwt = await gotrueUser.jwt();
|
|
452
|
-
setBrowserAuthCookies(jwt);
|
|
453
|
-
const user = toUser(gotrueUser);
|
|
454
|
-
clearHash();
|
|
455
|
-
emitAuthEvent("login", user);
|
|
456
|
-
return { type: "confirmation", user };
|
|
457
|
-
}
|
|
524
|
+
if (confirmationToken) return await handleConfirmationCallback(client, confirmationToken);
|
|
458
525
|
const recoveryToken = params.get("recovery_token");
|
|
459
|
-
if (recoveryToken)
|
|
460
|
-
const gotrueUser = await client.recover(recoveryToken, persistSession);
|
|
461
|
-
const jwt = await gotrueUser.jwt();
|
|
462
|
-
setBrowserAuthCookies(jwt);
|
|
463
|
-
const user = toUser(gotrueUser);
|
|
464
|
-
clearHash();
|
|
465
|
-
emitAuthEvent("login", user);
|
|
466
|
-
return { type: "recovery", user };
|
|
467
|
-
}
|
|
526
|
+
if (recoveryToken) return await handleRecoveryCallback(client, recoveryToken);
|
|
468
527
|
const inviteToken = params.get("invite_token");
|
|
469
|
-
if (inviteToken)
|
|
470
|
-
clearHash();
|
|
471
|
-
return { type: "invite", user: null, token: inviteToken };
|
|
472
|
-
}
|
|
528
|
+
if (inviteToken) return handleInviteCallback(inviteToken);
|
|
473
529
|
const emailChangeToken = params.get("email_change_token");
|
|
474
|
-
if (emailChangeToken)
|
|
475
|
-
const currentUser = client.currentUser();
|
|
476
|
-
if (!currentUser) {
|
|
477
|
-
throw new AuthError("Email change verification requires an active browser session");
|
|
478
|
-
}
|
|
479
|
-
const jwt = await currentUser.jwt();
|
|
480
|
-
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
481
|
-
const emailChangeRes = await fetch(`${identityUrl}/user`, {
|
|
482
|
-
method: "PUT",
|
|
483
|
-
headers: {
|
|
484
|
-
"Content-Type": "application/json",
|
|
485
|
-
Authorization: `Bearer ${jwt}`
|
|
486
|
-
},
|
|
487
|
-
body: JSON.stringify({ email_change_token: emailChangeToken })
|
|
488
|
-
});
|
|
489
|
-
if (!emailChangeRes.ok) {
|
|
490
|
-
const errorBody = await emailChangeRes.json().catch(() => ({}));
|
|
491
|
-
throw new AuthError(
|
|
492
|
-
errorBody.msg || `Email change verification failed (${emailChangeRes.status})`,
|
|
493
|
-
emailChangeRes.status
|
|
494
|
-
);
|
|
495
|
-
}
|
|
496
|
-
const emailChangeData = await emailChangeRes.json();
|
|
497
|
-
const user = toUser(emailChangeData);
|
|
498
|
-
clearHash();
|
|
499
|
-
emitAuthEvent("user_updated", user);
|
|
500
|
-
return { type: "email_change", user };
|
|
501
|
-
}
|
|
530
|
+
if (emailChangeToken) return await handleEmailChangeCallback(client, emailChangeToken);
|
|
502
531
|
return null;
|
|
503
532
|
} catch (error) {
|
|
504
|
-
|
|
533
|
+
if (error instanceof AuthError) throw error;
|
|
534
|
+
throw AuthError.from(error);
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
var handleOAuthCallback = async (client, params, accessToken) => {
|
|
538
|
+
const refreshToken = params.get("refresh_token") ?? "";
|
|
539
|
+
const expiresIn = parseInt(params.get("expires_in") ?? "", 10);
|
|
540
|
+
const expiresAt = parseInt(params.get("expires_at") ?? "", 10);
|
|
541
|
+
const gotrueUser = await client.createUser(
|
|
542
|
+
{
|
|
543
|
+
access_token: accessToken,
|
|
544
|
+
token_type: params.get("token_type") ?? "bearer",
|
|
545
|
+
expires_in: isFinite(expiresIn) ? expiresIn : 3600,
|
|
546
|
+
expires_at: isFinite(expiresAt) ? expiresAt : Math.floor(Date.now() / 1e3) + 3600,
|
|
547
|
+
refresh_token: refreshToken
|
|
548
|
+
},
|
|
549
|
+
persistSession
|
|
550
|
+
);
|
|
551
|
+
setBrowserAuthCookies(accessToken, refreshToken || void 0);
|
|
552
|
+
const user = toUser(gotrueUser);
|
|
553
|
+
clearHash();
|
|
554
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
555
|
+
return { type: "oauth", user };
|
|
556
|
+
};
|
|
557
|
+
var handleConfirmationCallback = async (client, token) => {
|
|
558
|
+
const gotrueUser = await client.confirm(token, persistSession);
|
|
559
|
+
const jwt = await gotrueUser.jwt();
|
|
560
|
+
setBrowserAuthCookies(jwt, gotrueUser.tokenDetails()?.refresh_token);
|
|
561
|
+
const user = toUser(gotrueUser);
|
|
562
|
+
clearHash();
|
|
563
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
564
|
+
return { type: "confirmation", user };
|
|
565
|
+
};
|
|
566
|
+
var handleRecoveryCallback = async (client, token) => {
|
|
567
|
+
const gotrueUser = await client.recover(token, persistSession);
|
|
568
|
+
const jwt = await gotrueUser.jwt();
|
|
569
|
+
setBrowserAuthCookies(jwt, gotrueUser.tokenDetails()?.refresh_token);
|
|
570
|
+
const user = toUser(gotrueUser);
|
|
571
|
+
clearHash();
|
|
572
|
+
emitAuthEvent(AUTH_EVENTS.RECOVERY, user);
|
|
573
|
+
return { type: "recovery", user };
|
|
574
|
+
};
|
|
575
|
+
var handleInviteCallback = (token) => {
|
|
576
|
+
clearHash();
|
|
577
|
+
return { type: "invite", user: null, token };
|
|
578
|
+
};
|
|
579
|
+
var handleEmailChangeCallback = async (client, emailChangeToken) => {
|
|
580
|
+
const currentUser = client.currentUser();
|
|
581
|
+
if (!currentUser) {
|
|
582
|
+
throw new AuthError("Email change verification requires an active browser session");
|
|
505
583
|
}
|
|
584
|
+
const jwt = await currentUser.jwt();
|
|
585
|
+
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
586
|
+
const emailChangeRes = await fetch(`${identityUrl}/user`, {
|
|
587
|
+
method: "PUT",
|
|
588
|
+
headers: {
|
|
589
|
+
"Content-Type": "application/json",
|
|
590
|
+
Authorization: `Bearer ${jwt}`
|
|
591
|
+
},
|
|
592
|
+
body: JSON.stringify({ email_change_token: emailChangeToken })
|
|
593
|
+
});
|
|
594
|
+
if (!emailChangeRes.ok) {
|
|
595
|
+
const errorBody = await emailChangeRes.json().catch(() => ({}));
|
|
596
|
+
throw new AuthError(
|
|
597
|
+
errorBody.msg || `Email change verification failed (${emailChangeRes.status})`,
|
|
598
|
+
emailChangeRes.status
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
const emailChangeData = await emailChangeRes.json();
|
|
602
|
+
const user = toUser(emailChangeData);
|
|
603
|
+
clearHash();
|
|
604
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
605
|
+
return { type: "email_change", user };
|
|
506
606
|
};
|
|
507
607
|
var clearHash = () => {
|
|
508
608
|
history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
@@ -515,23 +615,32 @@ var hydrateSession = async () => {
|
|
|
515
615
|
const accessToken = getCookie(NF_JWT_COOKIE);
|
|
516
616
|
if (!accessToken) return null;
|
|
517
617
|
const refreshToken = getCookie(NF_REFRESH_COOKIE) ?? "";
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
618
|
+
const decoded = decodeJwtPayload(accessToken);
|
|
619
|
+
const expiresAt = decoded?.exp ?? Math.floor(Date.now() / 1e3) + 3600;
|
|
620
|
+
const expiresIn = Math.max(0, expiresAt - Math.floor(Date.now() / 1e3));
|
|
621
|
+
let gotrueUser;
|
|
622
|
+
try {
|
|
623
|
+
gotrueUser = await client.createUser(
|
|
624
|
+
{
|
|
625
|
+
access_token: accessToken,
|
|
626
|
+
token_type: "bearer",
|
|
627
|
+
expires_in: expiresIn,
|
|
628
|
+
expires_at: expiresAt,
|
|
629
|
+
refresh_token: refreshToken
|
|
630
|
+
},
|
|
631
|
+
persistSession
|
|
632
|
+
);
|
|
633
|
+
} catch {
|
|
634
|
+
deleteBrowserAuthCookies();
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
528
637
|
const user = toUser(gotrueUser);
|
|
529
|
-
emitAuthEvent(
|
|
638
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
530
639
|
return user;
|
|
531
640
|
};
|
|
532
641
|
|
|
533
642
|
// src/account.ts
|
|
534
|
-
var
|
|
643
|
+
var resolveCurrentUser = async () => {
|
|
535
644
|
const client = getClient();
|
|
536
645
|
let currentUser = client.currentUser();
|
|
537
646
|
if (!currentUser && isBrowser()) {
|
|
@@ -549,7 +658,7 @@ var requestPasswordRecovery = async (email) => {
|
|
|
549
658
|
try {
|
|
550
659
|
await client.requestPasswordRecovery(email);
|
|
551
660
|
} catch (error) {
|
|
552
|
-
throw
|
|
661
|
+
throw AuthError.from(error);
|
|
553
662
|
}
|
|
554
663
|
};
|
|
555
664
|
var recoverPassword = async (token, newPassword) => {
|
|
@@ -558,10 +667,10 @@ var recoverPassword = async (token, newPassword) => {
|
|
|
558
667
|
const gotrueUser = await client.recover(token, persistSession);
|
|
559
668
|
const updatedUser = await gotrueUser.update({ password: newPassword });
|
|
560
669
|
const user = toUser(updatedUser);
|
|
561
|
-
emitAuthEvent(
|
|
670
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
562
671
|
return user;
|
|
563
672
|
} catch (error) {
|
|
564
|
-
throw
|
|
673
|
+
throw AuthError.from(error);
|
|
565
674
|
}
|
|
566
675
|
};
|
|
567
676
|
var confirmEmail = async (token) => {
|
|
@@ -569,10 +678,10 @@ var confirmEmail = async (token) => {
|
|
|
569
678
|
try {
|
|
570
679
|
const gotrueUser = await client.confirm(token, persistSession);
|
|
571
680
|
const user = toUser(gotrueUser);
|
|
572
|
-
emitAuthEvent(
|
|
681
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
573
682
|
return user;
|
|
574
683
|
} catch (error) {
|
|
575
|
-
throw
|
|
684
|
+
throw AuthError.from(error);
|
|
576
685
|
}
|
|
577
686
|
};
|
|
578
687
|
var acceptInvite = async (token, password) => {
|
|
@@ -580,18 +689,18 @@ var acceptInvite = async (token, password) => {
|
|
|
580
689
|
try {
|
|
581
690
|
const gotrueUser = await client.acceptInvite(token, password, persistSession);
|
|
582
691
|
const user = toUser(gotrueUser);
|
|
583
|
-
emitAuthEvent(
|
|
692
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
584
693
|
return user;
|
|
585
694
|
} catch (error) {
|
|
586
|
-
throw
|
|
695
|
+
throw AuthError.from(error);
|
|
587
696
|
}
|
|
588
697
|
};
|
|
589
698
|
var verifyEmailChange = async (token) => {
|
|
590
699
|
if (!isBrowser()) throw new AuthError("verifyEmailChange() is only available in the browser");
|
|
591
|
-
const currentUser = await
|
|
592
|
-
const jwt = await currentUser.jwt();
|
|
593
|
-
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
700
|
+
const currentUser = await resolveCurrentUser();
|
|
594
701
|
try {
|
|
702
|
+
const jwt = await currentUser.jwt();
|
|
703
|
+
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
595
704
|
const res = await fetch(`${identityUrl}/user`, {
|
|
596
705
|
method: "PUT",
|
|
597
706
|
headers: {
|
|
@@ -602,32 +711,30 @@ var verifyEmailChange = async (token) => {
|
|
|
602
711
|
});
|
|
603
712
|
if (!res.ok) {
|
|
604
713
|
const errorBody = await res.json().catch(() => ({}));
|
|
605
|
-
throw new AuthError(
|
|
606
|
-
errorBody.msg || `Email change verification failed (${res.status})`,
|
|
607
|
-
res.status
|
|
608
|
-
);
|
|
714
|
+
throw new AuthError(errorBody.msg || `Email change verification failed (${res.status})`, res.status);
|
|
609
715
|
}
|
|
610
716
|
const userData = await res.json();
|
|
611
717
|
const user = toUser(userData);
|
|
612
|
-
emitAuthEvent(
|
|
718
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
613
719
|
return user;
|
|
614
720
|
} catch (error) {
|
|
615
721
|
if (error instanceof AuthError) throw error;
|
|
616
|
-
throw
|
|
722
|
+
throw AuthError.from(error);
|
|
617
723
|
}
|
|
618
724
|
};
|
|
619
725
|
var updateUser = async (updates) => {
|
|
620
|
-
const currentUser = await
|
|
726
|
+
const currentUser = await resolveCurrentUser();
|
|
621
727
|
try {
|
|
622
728
|
const updatedUser = await currentUser.update(updates);
|
|
623
729
|
const user = toUser(updatedUser);
|
|
624
|
-
emitAuthEvent(
|
|
730
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
625
731
|
return user;
|
|
626
732
|
} catch (error) {
|
|
627
|
-
throw
|
|
733
|
+
throw AuthError.from(error);
|
|
628
734
|
}
|
|
629
735
|
};
|
|
630
736
|
export {
|
|
737
|
+
AUTH_EVENTS,
|
|
631
738
|
AuthError,
|
|
632
739
|
MissingIdentityError,
|
|
633
740
|
acceptInvite,
|
|
@@ -636,6 +743,7 @@ export {
|
|
|
636
743
|
getSettings,
|
|
637
744
|
getUser,
|
|
638
745
|
handleAuthCallback,
|
|
746
|
+
hydrateSession,
|
|
639
747
|
isAuthenticated,
|
|
640
748
|
login,
|
|
641
749
|
logout,
|