@proveanything/smartlinks-auth-ui 0.5.7 → 0.5.9

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/index.js CHANGED
@@ -12716,6 +12716,44 @@ collectionId, enableContactSync, enableInteractionTracking, interactionAppId, in
12716
12716
  }
12717
12717
  }
12718
12718
  }, [token, user, isVerified, accountData, accountInfo, contact, contactId, notifyAuthStateChange, isNetworkError, logout]);
12719
+ // Apply a session refresh from SDK calls that rotate the bearer token
12720
+ // (e.g. authKit.updateProfile returns { token, ...profile }). Without this
12721
+ // the persisted token still decodes to the OLD claims, so a page refresh
12722
+ // would resurrect stale displayName / email / phone values.
12723
+ const applySessionRefresh = React.useCallback(async (payload) => {
12724
+ const nextToken = payload.token;
12725
+ const nextUser = user
12726
+ ? { ...user, ...(payload.user || {}) }
12727
+ : (payload.user && payload.user.uid ? payload.user : null);
12728
+ const nextAccountData = payload.accountData ?? accountData;
12729
+ if (nextToken && !proxyMode) {
12730
+ // Match the 7-day lifetime used by login()/refreshToken() — backend mints fresh JWTs with the same TTL.
12731
+ await tokenStorage.saveToken(nextToken, Date.now() + 7 * 24 * 60 * 60 * 1000);
12732
+ if (nextUser)
12733
+ await tokenStorage.saveUser(nextUser);
12734
+ if (payload.accountData)
12735
+ await tokenStorage.saveAccountData(payload.accountData);
12736
+ }
12737
+ if (nextToken)
12738
+ setToken(nextToken);
12739
+ if (nextUser)
12740
+ setUser(nextUser);
12741
+ if (payload.accountData)
12742
+ setAccountData(nextAccountData);
12743
+ // Refresh contact too — the backend's account/contact unification means
12744
+ // the contact record may now reflect the new displayName/email/phone.
12745
+ if (collectionId && shouldSyncContacts) {
12746
+ try {
12747
+ const fresh = await smartlinks__namespace.contact.publicGetMine(collectionId);
12748
+ if (fresh?.contact)
12749
+ setContact(fresh.contact);
12750
+ }
12751
+ catch {
12752
+ // Non-fatal
12753
+ }
12754
+ }
12755
+ notifyAuthStateChange('TOKEN_REFRESH', nextUser, nextToken ?? token, nextAccountData, accountInfo, isVerified, contact, contactId);
12756
+ }, [proxyMode, user, accountData, accountInfo, isVerified, contact, contactId, collectionId, shouldSyncContacts, token, notifyAuthStateChange]);
12719
12757
  // Online/offline event listener for auto-retry verification
12720
12758
  React.useEffect(() => {
12721
12759
  if (proxyMode)
@@ -12793,6 +12831,7 @@ collectionId, enableContactSync, enableInteractionTracking, interactionAppId, in
12793
12831
  clearAccountCache,
12794
12832
  onAuthStateChange,
12795
12833
  retryVerification,
12834
+ applySessionRefresh,
12796
12835
  };
12797
12836
  return jsxRuntime.jsx(AuthContext.Provider, { value: value, children: children });
12798
12837
  };
@@ -14827,11 +14866,26 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14827
14866
  setError(undefined);
14828
14867
  setSuccess(undefined);
14829
14868
  try {
14830
- await smartlinks__namespace.authKit.updateProfile(resolvedClientId, { displayName });
14869
+ // SDK 1.13.17+: updateProfile returns a fresh bearer token with refreshed
14870
+ // claims (displayName/photoURL). We MUST persist the new token, otherwise
14871
+ // a page refresh would decode the old token and resurrect stale values.
14872
+ // Cast: older @proveanything/smartlinks type defs typed this as UserProfile
14873
+ // (no `token`). The runtime always returns the rotated token in 1.13.17+.
14874
+ const updated = await smartlinks__namespace.authKit.updateProfile(resolvedClientId, { displayName });
14875
+ await auth.applySessionRefresh({
14876
+ token: updated.token,
14877
+ user: {
14878
+ displayName: updated.displayName ?? displayName,
14879
+ email: updated.email,
14880
+ phoneNumber: updated.phoneNumber ?? undefined,
14881
+ photoURL: updated.photoURL ?? undefined,
14882
+ },
14883
+ accountData: updated.accountData,
14884
+ });
14831
14885
  setSuccess('Profile updated successfully!');
14832
14886
  setEditingSection(null);
14833
14887
  if (profile) {
14834
- setProfile({ ...profile, displayName });
14888
+ setProfile({ ...profile, displayName: updated.displayName ?? displayName });
14835
14889
  }
14836
14890
  }
14837
14891
  catch (err) {
@@ -14875,7 +14929,11 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14875
14929
  setSuccess(undefined);
14876
14930
  try {
14877
14931
  const redirectUrl = window.location.href;
14878
- await smartlinks__namespace.authKit.changeEmail(resolvedClientId, newEmail, emailPassword, redirectUrl);
14932
+ const res = await smartlinks__namespace.authKit.changeEmail(resolvedClientId, newEmail, emailPassword, redirectUrl);
14933
+ // SDK may rotate bearer token on email change — persist if present.
14934
+ if (res?.token) {
14935
+ await auth.applySessionRefresh({ token: res.token });
14936
+ }
14879
14937
  setSuccess('Email change requested. Please check your new email for verification.');
14880
14938
  setEditingSection(null);
14881
14939
  setNewEmail('');
@@ -14952,7 +15010,12 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14952
15010
  setError(undefined);
14953
15011
  setSuccess(undefined);
14954
15012
  try {
14955
- await smartlinks__namespace.authKit.updatePhone(resolvedClientId, newPhone, phoneCode);
15013
+ const res = await smartlinks__namespace.authKit.updatePhone(resolvedClientId, newPhone, phoneCode);
15014
+ // Phone change rotates the bearer token (phoneNumber is a JWT claim).
15015
+ await auth.applySessionRefresh({
15016
+ token: res?.token,
15017
+ user: { phoneNumber: newPhone },
15018
+ });
14956
15019
  setSuccess('Phone number updated successfully!');
14957
15020
  setEditingSection(null);
14958
15021
  setNewPhone('');