@netlify/identity 0.1.1-alpha.22 → 0.1.1-alpha.24
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 +43 -10
- package/dist/index.cjs +122 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -5
- package/dist/index.d.ts +23 -5
- package/dist/index.js +121 -116
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ Processes the URL hash after an OAuth redirect, email confirmation, password rec
|
|
|
164
164
|
onAuthChange(callback: AuthCallback): () => void
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
-
Subscribes to auth state changes (login, logout, token refresh, user updates). Returns an unsubscribe function. Also fires on cross-tab session changes. No-op on the server.
|
|
167
|
+
Subscribes to auth state changes (login, logout, token refresh, user updates, and recovery). Returns an unsubscribe function. Also fires on cross-tab session changes. No-op on the server. The `'recovery'` event fires when `handleAuthCallback()` processes a password recovery token; listen for it to redirect users to a password reset form.
|
|
168
168
|
|
|
169
169
|
#### `hydrateSession`
|
|
170
170
|
|
|
@@ -323,10 +323,24 @@ interface AppMetadata {
|
|
|
323
323
|
}
|
|
324
324
|
```
|
|
325
325
|
|
|
326
|
+
#### `AUTH_EVENTS`
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
const AUTH_EVENTS: {
|
|
330
|
+
LOGIN: 'login'
|
|
331
|
+
LOGOUT: 'logout'
|
|
332
|
+
TOKEN_REFRESH: 'token_refresh'
|
|
333
|
+
USER_UPDATED: 'user_updated'
|
|
334
|
+
RECOVERY: 'recovery'
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Constants for auth event names. Use these instead of string literals for type safety and autocomplete.
|
|
339
|
+
|
|
326
340
|
#### `AuthEvent`
|
|
327
341
|
|
|
328
342
|
```ts
|
|
329
|
-
type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'
|
|
343
|
+
type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated' | 'recovery'
|
|
330
344
|
```
|
|
331
345
|
|
|
332
346
|
#### `AuthCallback`
|
|
@@ -646,6 +660,8 @@ export function CallbackHandler({ children }: { children: React.ReactNode }) {
|
|
|
646
660
|
}
|
|
647
661
|
if (result.type === 'invite') {
|
|
648
662
|
window.location.href = `/accept-invite?token=${result.token}`
|
|
663
|
+
} else if (result.type === 'recovery') {
|
|
664
|
+
window.location.href = '/reset-password'
|
|
649
665
|
} else {
|
|
650
666
|
window.location.href = '/dashboard'
|
|
651
667
|
}
|
|
@@ -704,25 +720,29 @@ function NavBar() {
|
|
|
704
720
|
|
|
705
721
|
### Listening for auth changes
|
|
706
722
|
|
|
707
|
-
Use `onAuthChange` to keep your UI in sync with auth state. It fires on login, logout, token refresh,
|
|
723
|
+
Use `onAuthChange` to keep your UI in sync with auth state. It fires on login, logout, token refresh, user updates, and recovery. It also detects session changes in other browser tabs (via `localStorage`).
|
|
708
724
|
|
|
709
725
|
```ts
|
|
710
|
-
import { onAuthChange } from '@netlify/identity'
|
|
726
|
+
import { onAuthChange, AUTH_EVENTS } from '@netlify/identity'
|
|
711
727
|
|
|
712
728
|
const unsubscribe = onAuthChange((event, user) => {
|
|
713
729
|
switch (event) {
|
|
714
|
-
case
|
|
730
|
+
case AUTH_EVENTS.LOGIN:
|
|
715
731
|
console.log('Logged in:', user?.email)
|
|
716
732
|
break
|
|
717
|
-
case
|
|
733
|
+
case AUTH_EVENTS.LOGOUT:
|
|
718
734
|
console.log('Logged out')
|
|
719
735
|
break
|
|
720
|
-
case
|
|
736
|
+
case AUTH_EVENTS.TOKEN_REFRESH:
|
|
721
737
|
console.log('Token refreshed for:', user?.email)
|
|
722
738
|
break
|
|
723
|
-
case
|
|
739
|
+
case AUTH_EVENTS.USER_UPDATED:
|
|
724
740
|
console.log('User updated:', user?.email)
|
|
725
741
|
break
|
|
742
|
+
case AUTH_EVENTS.RECOVERY:
|
|
743
|
+
console.log('Recovery login:', user?.email)
|
|
744
|
+
// Redirect to password reset form, then call updateUser({ password })
|
|
745
|
+
break
|
|
726
746
|
}
|
|
727
747
|
})
|
|
728
748
|
|
|
@@ -755,11 +775,11 @@ if (result?.type === 'oauth') {
|
|
|
755
775
|
}
|
|
756
776
|
```
|
|
757
777
|
|
|
758
|
-
`handleAuthCallback()` exchanges the token in the URL hash, logs the user in, clears the hash, and emits
|
|
778
|
+
`handleAuthCallback()` exchanges the token in the URL hash, logs the user in, clears the hash, and emits an auth event via `onAuthChange` (`'login'` for OAuth/confirmation, `'recovery'` for password recovery).
|
|
759
779
|
|
|
760
780
|
### Password recovery
|
|
761
781
|
|
|
762
|
-
Password recovery is a two-step flow. The library handles the token exchange automatically via `handleAuthCallback()`, which logs the user in and returns `{type: 'recovery', user}`. You then show a "set new password" form and call `updateUser()` to save it.
|
|
782
|
+
Password recovery is a two-step flow. The library handles the token exchange automatically via `handleAuthCallback()`, which logs the user in and returns `{type: 'recovery', user}`. A `'recovery'` event (not `'login'`) is emitted via `onAuthChange`, so event-based listeners can also detect this flow. You then show a "set new password" form and call `updateUser()` to save it.
|
|
763
783
|
|
|
764
784
|
**Step by step:**
|
|
765
785
|
|
|
@@ -780,6 +800,19 @@ if (result?.type === 'recovery') {
|
|
|
780
800
|
}
|
|
781
801
|
```
|
|
782
802
|
|
|
803
|
+
If you use the event-based pattern instead of checking `result.type`, listen for the `'recovery'` event:
|
|
804
|
+
|
|
805
|
+
```ts
|
|
806
|
+
import { onAuthChange, AUTH_EVENTS } from '@netlify/identity'
|
|
807
|
+
|
|
808
|
+
onAuthChange((event, user) => {
|
|
809
|
+
if (event === AUTH_EVENTS.RECOVERY) {
|
|
810
|
+
// Redirect to password reset form.
|
|
811
|
+
// The user is authenticated, so call updateUser({ password }) to set the new password.
|
|
812
|
+
}
|
|
813
|
+
})
|
|
814
|
+
```
|
|
815
|
+
|
|
783
816
|
### Invite acceptance
|
|
784
817
|
|
|
785
818
|
When an admin invites a user, they receive an email with an invite link. Clicking it redirects to your site with an `invite_token` in the URL hash. Unlike other callback types, the user is not logged in automatically because they need to set a password first.
|
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,
|
|
@@ -70,7 +71,7 @@ var AuthError = class extends Error {
|
|
|
70
71
|
}
|
|
71
72
|
};
|
|
72
73
|
var MissingIdentityError = class extends Error {
|
|
73
|
-
constructor(message = "Netlify Identity is not available.
|
|
74
|
+
constructor(message = "Netlify Identity is not available.") {
|
|
74
75
|
super(message);
|
|
75
76
|
this.name = "MissingIdentityError";
|
|
76
77
|
}
|
|
@@ -348,22 +349,15 @@ var getSettings = async () => {
|
|
|
348
349
|
}
|
|
349
350
|
};
|
|
350
351
|
|
|
351
|
-
// src/
|
|
352
|
-
var
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
};
|
|
359
|
-
var getServerIdentityUrl = () => {
|
|
360
|
-
const ctx = getIdentityContext();
|
|
361
|
-
if (!ctx?.url) {
|
|
362
|
-
throw new AuthError("Could not determine the Identity endpoint URL on the server");
|
|
363
|
-
}
|
|
364
|
-
return ctx.url;
|
|
352
|
+
// src/events.ts
|
|
353
|
+
var AUTH_EVENTS = {
|
|
354
|
+
LOGIN: "login",
|
|
355
|
+
LOGOUT: "logout",
|
|
356
|
+
TOKEN_REFRESH: "token_refresh",
|
|
357
|
+
USER_UPDATED: "user_updated",
|
|
358
|
+
RECOVERY: "recovery"
|
|
365
359
|
};
|
|
366
|
-
var
|
|
360
|
+
var GOTRUE_STORAGE_KEY = "gotrue.user";
|
|
367
361
|
var listeners = /* @__PURE__ */ new Set();
|
|
368
362
|
var emitAuthEvent = (event, user) => {
|
|
369
363
|
for (const listener of listeners) {
|
|
@@ -373,19 +367,18 @@ var emitAuthEvent = (event, user) => {
|
|
|
373
367
|
}
|
|
374
368
|
}
|
|
375
369
|
};
|
|
376
|
-
var GOTRUE_STORAGE_KEY = "gotrue.user";
|
|
377
370
|
var storageListenerAttached = false;
|
|
378
371
|
var attachStorageListener = () => {
|
|
379
|
-
if (storageListenerAttached) return;
|
|
372
|
+
if (storageListenerAttached || !isBrowser()) return;
|
|
380
373
|
storageListenerAttached = true;
|
|
381
374
|
window.addEventListener("storage", (event) => {
|
|
382
375
|
if (event.key !== GOTRUE_STORAGE_KEY) return;
|
|
383
376
|
if (event.newValue) {
|
|
384
377
|
const client = getGoTrueClient();
|
|
385
378
|
const currentUser = client?.currentUser();
|
|
386
|
-
emitAuthEvent(
|
|
379
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, currentUser ? toUser(currentUser) : null);
|
|
387
380
|
} else {
|
|
388
|
-
emitAuthEvent(
|
|
381
|
+
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
389
382
|
}
|
|
390
383
|
});
|
|
391
384
|
};
|
|
@@ -400,6 +393,23 @@ var onAuthChange = (callback) => {
|
|
|
400
393
|
listeners.delete(callback);
|
|
401
394
|
};
|
|
402
395
|
};
|
|
396
|
+
|
|
397
|
+
// src/auth.ts
|
|
398
|
+
var getCookies = () => {
|
|
399
|
+
const cookies = globalThis.Netlify?.context?.cookies;
|
|
400
|
+
if (!cookies) {
|
|
401
|
+
throw new AuthError("Server-side auth requires Netlify Functions runtime");
|
|
402
|
+
}
|
|
403
|
+
return cookies;
|
|
404
|
+
};
|
|
405
|
+
var getServerIdentityUrl = () => {
|
|
406
|
+
const ctx = getIdentityContext();
|
|
407
|
+
if (!ctx?.url) {
|
|
408
|
+
throw new AuthError("Could not determine the Identity endpoint URL on the server");
|
|
409
|
+
}
|
|
410
|
+
return ctx.url;
|
|
411
|
+
};
|
|
412
|
+
var persistSession = true;
|
|
403
413
|
var login = async (email, password) => {
|
|
404
414
|
if (!isBrowser()) {
|
|
405
415
|
const identityUrl = getServerIdentityUrl();
|
|
@@ -421,10 +431,7 @@ var login = async (email, password) => {
|
|
|
421
431
|
}
|
|
422
432
|
if (!res.ok) {
|
|
423
433
|
const errorBody = await res.json().catch(() => ({}));
|
|
424
|
-
throw new AuthError(
|
|
425
|
-
errorBody.msg || errorBody.error_description || `Login failed (${res.status})`,
|
|
426
|
-
res.status
|
|
427
|
-
);
|
|
434
|
+
throw new AuthError(errorBody.msg || errorBody.error_description || `Login failed (${res.status})`, res.status);
|
|
428
435
|
}
|
|
429
436
|
const data = await res.json();
|
|
430
437
|
const accessToken = data.access_token;
|
|
@@ -438,10 +445,7 @@ var login = async (email, password) => {
|
|
|
438
445
|
}
|
|
439
446
|
if (!userRes.ok) {
|
|
440
447
|
const errorBody = await userRes.json().catch(() => ({}));
|
|
441
|
-
throw new AuthError(
|
|
442
|
-
errorBody.msg || `Failed to fetch user data (${userRes.status})`,
|
|
443
|
-
userRes.status
|
|
444
|
-
);
|
|
448
|
+
throw new AuthError(errorBody.msg || `Failed to fetch user data (${userRes.status})`, userRes.status);
|
|
445
449
|
}
|
|
446
450
|
const userData = await userRes.json();
|
|
447
451
|
const user = toUser(userData);
|
|
@@ -454,7 +458,7 @@ var login = async (email, password) => {
|
|
|
454
458
|
const jwt = await gotrueUser.jwt();
|
|
455
459
|
setBrowserAuthCookies(jwt);
|
|
456
460
|
const user = toUser(gotrueUser);
|
|
457
|
-
emitAuthEvent(
|
|
461
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
458
462
|
return user;
|
|
459
463
|
} catch (error) {
|
|
460
464
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
@@ -481,10 +485,9 @@ var signup = async (email, password, data) => {
|
|
|
481
485
|
const responseData = await res.json();
|
|
482
486
|
const user = toUser(responseData);
|
|
483
487
|
if (responseData.confirmed_at) {
|
|
484
|
-
const
|
|
485
|
-
const accessToken = responseRecord.access_token;
|
|
488
|
+
const accessToken = responseData.access_token;
|
|
486
489
|
if (accessToken) {
|
|
487
|
-
setAuthCookies(cookies, accessToken,
|
|
490
|
+
setAuthCookies(cookies, accessToken, responseData.refresh_token);
|
|
488
491
|
}
|
|
489
492
|
}
|
|
490
493
|
return user;
|
|
@@ -498,7 +501,7 @@ var signup = async (email, password, data) => {
|
|
|
498
501
|
if (jwt) {
|
|
499
502
|
setBrowserAuthCookies(jwt);
|
|
500
503
|
}
|
|
501
|
-
emitAuthEvent(
|
|
504
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
502
505
|
}
|
|
503
506
|
return user;
|
|
504
507
|
} catch (error) {
|
|
@@ -529,7 +532,7 @@ var logout = async () => {
|
|
|
529
532
|
await currentUser.logout();
|
|
530
533
|
}
|
|
531
534
|
deleteBrowserAuthCookies();
|
|
532
|
-
emitAuthEvent(
|
|
535
|
+
emitAuthEvent(AUTH_EVENTS.LOGOUT, null);
|
|
533
536
|
} catch (error) {
|
|
534
537
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
535
538
|
}
|
|
@@ -547,87 +550,92 @@ var handleAuthCallback = async () => {
|
|
|
547
550
|
const hash = window.location.hash.substring(1);
|
|
548
551
|
if (!hash) return null;
|
|
549
552
|
const client = getClient();
|
|
553
|
+
const params = new URLSearchParams(hash);
|
|
550
554
|
try {
|
|
551
|
-
const params = new URLSearchParams(hash);
|
|
552
555
|
const accessToken = params.get("access_token");
|
|
553
|
-
if (accessToken)
|
|
554
|
-
const refreshToken = params.get("refresh_token") ?? "";
|
|
555
|
-
const gotrueUser = await client.createUser(
|
|
556
|
-
{
|
|
557
|
-
access_token: accessToken,
|
|
558
|
-
token_type: params.get("token_type") ?? "bearer",
|
|
559
|
-
expires_in: Number(params.get("expires_in")),
|
|
560
|
-
expires_at: Number(params.get("expires_at")),
|
|
561
|
-
refresh_token: refreshToken
|
|
562
|
-
},
|
|
563
|
-
persistSession
|
|
564
|
-
);
|
|
565
|
-
setBrowserAuthCookies(accessToken, refreshToken || void 0);
|
|
566
|
-
const user = toUser(gotrueUser);
|
|
567
|
-
clearHash();
|
|
568
|
-
emitAuthEvent("login", user);
|
|
569
|
-
return { type: "oauth", user };
|
|
570
|
-
}
|
|
556
|
+
if (accessToken) return await handleOAuthCallback(client, params, accessToken);
|
|
571
557
|
const confirmationToken = params.get("confirmation_token");
|
|
572
|
-
if (confirmationToken)
|
|
573
|
-
const gotrueUser = await client.confirm(confirmationToken, persistSession);
|
|
574
|
-
const jwt = await gotrueUser.jwt();
|
|
575
|
-
setBrowserAuthCookies(jwt);
|
|
576
|
-
const user = toUser(gotrueUser);
|
|
577
|
-
clearHash();
|
|
578
|
-
emitAuthEvent("login", user);
|
|
579
|
-
return { type: "confirmation", user };
|
|
580
|
-
}
|
|
558
|
+
if (confirmationToken) return await handleConfirmationCallback(client, confirmationToken);
|
|
581
559
|
const recoveryToken = params.get("recovery_token");
|
|
582
|
-
if (recoveryToken)
|
|
583
|
-
const gotrueUser = await client.recover(recoveryToken, persistSession);
|
|
584
|
-
const jwt = await gotrueUser.jwt();
|
|
585
|
-
setBrowserAuthCookies(jwt);
|
|
586
|
-
const user = toUser(gotrueUser);
|
|
587
|
-
clearHash();
|
|
588
|
-
emitAuthEvent("login", user);
|
|
589
|
-
return { type: "recovery", user };
|
|
590
|
-
}
|
|
560
|
+
if (recoveryToken) return await handleRecoveryCallback(client, recoveryToken);
|
|
591
561
|
const inviteToken = params.get("invite_token");
|
|
592
|
-
if (inviteToken)
|
|
593
|
-
clearHash();
|
|
594
|
-
return { type: "invite", user: null, token: inviteToken };
|
|
595
|
-
}
|
|
562
|
+
if (inviteToken) return handleInviteCallback(inviteToken);
|
|
596
563
|
const emailChangeToken = params.get("email_change_token");
|
|
597
|
-
if (emailChangeToken)
|
|
598
|
-
const currentUser = client.currentUser();
|
|
599
|
-
if (!currentUser) {
|
|
600
|
-
throw new AuthError("Email change verification requires an active browser session");
|
|
601
|
-
}
|
|
602
|
-
const jwt = await currentUser.jwt();
|
|
603
|
-
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
604
|
-
const emailChangeRes = await fetch(`${identityUrl}/user`, {
|
|
605
|
-
method: "PUT",
|
|
606
|
-
headers: {
|
|
607
|
-
"Content-Type": "application/json",
|
|
608
|
-
Authorization: `Bearer ${jwt}`
|
|
609
|
-
},
|
|
610
|
-
body: JSON.stringify({ email_change_token: emailChangeToken })
|
|
611
|
-
});
|
|
612
|
-
if (!emailChangeRes.ok) {
|
|
613
|
-
const errorBody = await emailChangeRes.json().catch(() => ({}));
|
|
614
|
-
throw new AuthError(
|
|
615
|
-
errorBody.msg || `Email change verification failed (${emailChangeRes.status})`,
|
|
616
|
-
emailChangeRes.status
|
|
617
|
-
);
|
|
618
|
-
}
|
|
619
|
-
const emailChangeData = await emailChangeRes.json();
|
|
620
|
-
const user = toUser(emailChangeData);
|
|
621
|
-
clearHash();
|
|
622
|
-
emitAuthEvent("user_updated", user);
|
|
623
|
-
return { type: "email_change", user };
|
|
624
|
-
}
|
|
564
|
+
if (emailChangeToken) return await handleEmailChangeCallback(client, emailChangeToken);
|
|
625
565
|
return null;
|
|
626
566
|
} catch (error) {
|
|
627
567
|
if (error instanceof AuthError) throw error;
|
|
628
568
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
629
569
|
}
|
|
630
570
|
};
|
|
571
|
+
var handleOAuthCallback = async (client, params, accessToken) => {
|
|
572
|
+
const refreshToken = params.get("refresh_token") ?? "";
|
|
573
|
+
const gotrueUser = await client.createUser(
|
|
574
|
+
{
|
|
575
|
+
access_token: accessToken,
|
|
576
|
+
token_type: params.get("token_type") ?? "bearer",
|
|
577
|
+
expires_in: Number(params.get("expires_in")),
|
|
578
|
+
expires_at: Number(params.get("expires_at")),
|
|
579
|
+
refresh_token: refreshToken
|
|
580
|
+
},
|
|
581
|
+
persistSession
|
|
582
|
+
);
|
|
583
|
+
setBrowserAuthCookies(accessToken, refreshToken || void 0);
|
|
584
|
+
const user = toUser(gotrueUser);
|
|
585
|
+
clearHash();
|
|
586
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
587
|
+
return { type: "oauth", user };
|
|
588
|
+
};
|
|
589
|
+
var handleConfirmationCallback = async (client, token) => {
|
|
590
|
+
const gotrueUser = await client.confirm(token, persistSession);
|
|
591
|
+
const jwt = await gotrueUser.jwt();
|
|
592
|
+
setBrowserAuthCookies(jwt);
|
|
593
|
+
const user = toUser(gotrueUser);
|
|
594
|
+
clearHash();
|
|
595
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
596
|
+
return { type: "confirmation", user };
|
|
597
|
+
};
|
|
598
|
+
var handleRecoveryCallback = async (client, token) => {
|
|
599
|
+
const gotrueUser = await client.recover(token, persistSession);
|
|
600
|
+
const jwt = await gotrueUser.jwt();
|
|
601
|
+
setBrowserAuthCookies(jwt);
|
|
602
|
+
const user = toUser(gotrueUser);
|
|
603
|
+
clearHash();
|
|
604
|
+
emitAuthEvent(AUTH_EVENTS.RECOVERY, user);
|
|
605
|
+
return { type: "recovery", user };
|
|
606
|
+
};
|
|
607
|
+
var handleInviteCallback = (token) => {
|
|
608
|
+
clearHash();
|
|
609
|
+
return { type: "invite", user: null, token };
|
|
610
|
+
};
|
|
611
|
+
var handleEmailChangeCallback = async (client, emailChangeToken) => {
|
|
612
|
+
const currentUser = client.currentUser();
|
|
613
|
+
if (!currentUser) {
|
|
614
|
+
throw new AuthError("Email change verification requires an active browser session");
|
|
615
|
+
}
|
|
616
|
+
const jwt = await currentUser.jwt();
|
|
617
|
+
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
618
|
+
const emailChangeRes = await fetch(`${identityUrl}/user`, {
|
|
619
|
+
method: "PUT",
|
|
620
|
+
headers: {
|
|
621
|
+
"Content-Type": "application/json",
|
|
622
|
+
Authorization: `Bearer ${jwt}`
|
|
623
|
+
},
|
|
624
|
+
body: JSON.stringify({ email_change_token: emailChangeToken })
|
|
625
|
+
});
|
|
626
|
+
if (!emailChangeRes.ok) {
|
|
627
|
+
const errorBody = await emailChangeRes.json().catch(() => ({}));
|
|
628
|
+
throw new AuthError(
|
|
629
|
+
errorBody.msg || `Email change verification failed (${emailChangeRes.status})`,
|
|
630
|
+
emailChangeRes.status
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
const emailChangeData = await emailChangeRes.json();
|
|
634
|
+
const user = toUser(emailChangeData);
|
|
635
|
+
clearHash();
|
|
636
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
637
|
+
return { type: "email_change", user };
|
|
638
|
+
};
|
|
631
639
|
var clearHash = () => {
|
|
632
640
|
history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
633
641
|
};
|
|
@@ -653,12 +661,12 @@ var hydrateSession = async () => {
|
|
|
653
661
|
persistSession
|
|
654
662
|
);
|
|
655
663
|
const user = toUser(gotrueUser);
|
|
656
|
-
emitAuthEvent(
|
|
664
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
657
665
|
return user;
|
|
658
666
|
};
|
|
659
667
|
|
|
660
668
|
// src/account.ts
|
|
661
|
-
var
|
|
669
|
+
var resolveCurrentUser = async () => {
|
|
662
670
|
const client = getClient();
|
|
663
671
|
let currentUser = client.currentUser();
|
|
664
672
|
if (!currentUser && isBrowser()) {
|
|
@@ -685,7 +693,7 @@ var recoverPassword = async (token, newPassword) => {
|
|
|
685
693
|
const gotrueUser = await client.recover(token, persistSession);
|
|
686
694
|
const updatedUser = await gotrueUser.update({ password: newPassword });
|
|
687
695
|
const user = toUser(updatedUser);
|
|
688
|
-
emitAuthEvent(
|
|
696
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
689
697
|
return user;
|
|
690
698
|
} catch (error) {
|
|
691
699
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
@@ -696,7 +704,7 @@ var confirmEmail = async (token) => {
|
|
|
696
704
|
try {
|
|
697
705
|
const gotrueUser = await client.confirm(token, persistSession);
|
|
698
706
|
const user = toUser(gotrueUser);
|
|
699
|
-
emitAuthEvent(
|
|
707
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
700
708
|
return user;
|
|
701
709
|
} catch (error) {
|
|
702
710
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
@@ -707,7 +715,7 @@ var acceptInvite = async (token, password) => {
|
|
|
707
715
|
try {
|
|
708
716
|
const gotrueUser = await client.acceptInvite(token, password, persistSession);
|
|
709
717
|
const user = toUser(gotrueUser);
|
|
710
|
-
emitAuthEvent(
|
|
718
|
+
emitAuthEvent(AUTH_EVENTS.LOGIN, user);
|
|
711
719
|
return user;
|
|
712
720
|
} catch (error) {
|
|
713
721
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
@@ -715,7 +723,7 @@ var acceptInvite = async (token, password) => {
|
|
|
715
723
|
};
|
|
716
724
|
var verifyEmailChange = async (token) => {
|
|
717
725
|
if (!isBrowser()) throw new AuthError("verifyEmailChange() is only available in the browser");
|
|
718
|
-
const currentUser = await
|
|
726
|
+
const currentUser = await resolveCurrentUser();
|
|
719
727
|
const jwt = await currentUser.jwt();
|
|
720
728
|
const identityUrl = `${window.location.origin}${IDENTITY_PATH}`;
|
|
721
729
|
try {
|
|
@@ -729,14 +737,11 @@ var verifyEmailChange = async (token) => {
|
|
|
729
737
|
});
|
|
730
738
|
if (!res.ok) {
|
|
731
739
|
const errorBody = await res.json().catch(() => ({}));
|
|
732
|
-
throw new AuthError(
|
|
733
|
-
errorBody.msg || `Email change verification failed (${res.status})`,
|
|
734
|
-
res.status
|
|
735
|
-
);
|
|
740
|
+
throw new AuthError(errorBody.msg || `Email change verification failed (${res.status})`, res.status);
|
|
736
741
|
}
|
|
737
742
|
const userData = await res.json();
|
|
738
743
|
const user = toUser(userData);
|
|
739
|
-
emitAuthEvent(
|
|
744
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
740
745
|
return user;
|
|
741
746
|
} catch (error) {
|
|
742
747
|
if (error instanceof AuthError) throw error;
|
|
@@ -744,11 +749,11 @@ var verifyEmailChange = async (token) => {
|
|
|
744
749
|
}
|
|
745
750
|
};
|
|
746
751
|
var updateUser = async (updates) => {
|
|
747
|
-
const currentUser = await
|
|
752
|
+
const currentUser = await resolveCurrentUser();
|
|
748
753
|
try {
|
|
749
754
|
const updatedUser = await currentUser.update(updates);
|
|
750
755
|
const user = toUser(updatedUser);
|
|
751
|
-
emitAuthEvent(
|
|
756
|
+
emitAuthEvent(AUTH_EVENTS.USER_UPDATED, user);
|
|
752
757
|
return user;
|
|
753
758
|
} catch (error) {
|
|
754
759
|
throw new AuthError(error.message, void 0, { cause: error });
|
|
@@ -756,6 +761,7 @@ var updateUser = async (updates) => {
|
|
|
756
761
|
};
|
|
757
762
|
// Annotate the CommonJS export names for ESM import in node:
|
|
758
763
|
0 && (module.exports = {
|
|
764
|
+
AUTH_EVENTS,
|
|
759
765
|
AuthError,
|
|
760
766
|
MissingIdentityError,
|
|
761
767
|
acceptInvite,
|