@proveanything/smartlinks-auth-ui 0.5.6 → 0.5.8

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/api.d.ts CHANGED
@@ -74,7 +74,13 @@ export declare class AuthAPI {
74
74
  buttonLabel: string;
75
75
  buttonUrl: string;
76
76
  };
77
- }, prefillMessage?: string): Promise<{
77
+ }, prefillMessage?: string, contactData?: {
78
+ name?: string;
79
+ email?: string;
80
+ source?: string;
81
+ customFields?: Record<string, any>;
82
+ [key: string]: any;
83
+ }): Promise<{
78
84
  waLink: string;
79
85
  code: string;
80
86
  token: string;
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AccountManagement.d.ts","sourceRoot":"","sources":["../../src/components/AccountManagement.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAOhE,OAAO,KAAK,EAAE,sBAAsB,EAAe,MAAM,UAAU,CAAC;AACpE,OAAO,qBAAqB,CAAC;AAK7B,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA4vB9D,CAAC"}
1
+ {"version":3,"file":"AccountManagement.d.ts","sourceRoot":"","sources":["../../src/components/AccountManagement.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAOhE,OAAO,KAAK,EAAE,sBAAsB,EAAe,MAAM,UAAU,CAAC;AACpE,OAAO,qBAAqB,CAAC;AAK7B,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAgzB9D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAapE,OAAO,KAAK,EAAE,qBAAqB,EAAyF,MAAM,UAAU,CAAC;AAqQ7I,QAAA,MAAM,mBAAmB,QAAa,OAAO,CAAC,IAAI,CAqBjD,CAAC;AAqDF,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAI/B,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAq+D5D,CAAC"}
1
+ {"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAapE,OAAO,KAAK,EAAE,qBAAqB,EAAyF,MAAM,UAAU,CAAC;AAqQ7I,QAAA,MAAM,mBAAmB,QAAa,OAAO,CAAC,IAAI,CAqBjD,CAAC;AAqDF,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAI/B,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAq/D5D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/context/AuthContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAOnG,OAAO,KAAK,EAAqC,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAGvG,eAAO,MAAM,WAAW,6CAAyD,CAAC;AAGlF,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA81BpD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,gBAM1B,CAAC"}
1
+ {"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/context/AuthContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAOnG,OAAO,KAAK,EAAqC,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAGvG,eAAO,MAAM,WAAW,6CAAyD,CAAC;AAGlF,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAw4BpD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,gBAM1B,CAAC"}
package/dist/index.esm.js CHANGED
@@ -11493,15 +11493,18 @@ class AuthAPI {
11493
11493
  return smartlinks.authKit.verifyMagicLink(this.clientId, token);
11494
11494
  }
11495
11495
  // ============= WhatsApp =============
11496
- async sendWhatsApp(redirectUrl, phoneNumber, reply, prefillMessage) {
11496
+ async sendWhatsApp(redirectUrl, phoneNumber, reply, prefillMessage, contactData) {
11497
11497
  // phoneNumber is optional — backend extracts it from the inbound WhatsApp webhook.
11498
11498
  // `reply`, when provided, is sent back to the user via WhatsApp on successful verification.
11499
11499
  // `prefillMessage` customizes the message body pre-filled in the wa.me link.
11500
+ // `contactData` is upserted onto the contact when the backend creates/links it,
11501
+ // so the returned session.user is fully formed (name, email, custom fields, etc.).
11500
11502
  return smartlinks.authKit.sendWhatsApp(this.clientId, {
11501
11503
  phoneNumber: phoneNumber ?? '',
11502
11504
  redirectUrl,
11503
11505
  ...(reply ? { reply } : {}),
11504
11506
  ...(prefillMessage ? { prefillMessage } : {}),
11507
+ ...(contactData ? { contactData } : {}),
11505
11508
  });
11506
11509
  }
11507
11510
  async exchangeWhatsAppSession(token, sessionKey) {
@@ -12693,6 +12696,44 @@ collectionId, enableContactSync, enableInteractionTracking, interactionAppId, in
12693
12696
  }
12694
12697
  }
12695
12698
  }, [token, user, isVerified, accountData, accountInfo, contact, contactId, notifyAuthStateChange, isNetworkError, logout]);
12699
+ // Apply a session refresh from SDK calls that rotate the bearer token
12700
+ // (e.g. authKit.updateProfile returns { token, ...profile }). Without this
12701
+ // the persisted token still decodes to the OLD claims, so a page refresh
12702
+ // would resurrect stale displayName / email / phone values.
12703
+ const applySessionRefresh = useCallback(async (payload) => {
12704
+ const nextToken = payload.token;
12705
+ const nextUser = user
12706
+ ? { ...user, ...(payload.user || {}) }
12707
+ : (payload.user && payload.user.uid ? payload.user : null);
12708
+ const nextAccountData = payload.accountData ?? accountData;
12709
+ if (nextToken && !proxyMode) {
12710
+ // Match the 7-day lifetime used by login()/refreshToken() — backend mints fresh JWTs with the same TTL.
12711
+ await tokenStorage.saveToken(nextToken, Date.now() + 7 * 24 * 60 * 60 * 1000);
12712
+ if (nextUser)
12713
+ await tokenStorage.saveUser(nextUser);
12714
+ if (payload.accountData)
12715
+ await tokenStorage.saveAccountData(payload.accountData);
12716
+ }
12717
+ if (nextToken)
12718
+ setToken(nextToken);
12719
+ if (nextUser)
12720
+ setUser(nextUser);
12721
+ if (payload.accountData)
12722
+ setAccountData(nextAccountData);
12723
+ // Refresh contact too — the backend's account/contact unification means
12724
+ // the contact record may now reflect the new displayName/email/phone.
12725
+ if (collectionId && shouldSyncContacts) {
12726
+ try {
12727
+ const fresh = await smartlinks.contact.publicGetMine(collectionId);
12728
+ if (fresh?.contact)
12729
+ setContact(fresh.contact);
12730
+ }
12731
+ catch {
12732
+ // Non-fatal
12733
+ }
12734
+ }
12735
+ notifyAuthStateChange('TOKEN_REFRESH', nextUser, nextToken ?? token, nextAccountData, accountInfo, isVerified, contact, contactId);
12736
+ }, [proxyMode, user, accountData, accountInfo, isVerified, contact, contactId, collectionId, shouldSyncContacts, token, notifyAuthStateChange]);
12696
12737
  // Online/offline event listener for auto-retry verification
12697
12738
  useEffect(() => {
12698
12739
  if (proxyMode)
@@ -12770,6 +12811,7 @@ collectionId, enableContactSync, enableInteractionTracking, interactionAppId, in
12770
12811
  clearAccountCache,
12771
12812
  onAuthStateChange,
12772
12813
  retryVerification,
12814
+ applySessionRefresh,
12773
12815
  };
12774
12816
  return jsx(AuthContext.Provider, { value: value, children: children });
12775
12817
  };
@@ -14271,8 +14313,17 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14271
14313
  });
14272
14314
  // Resolve outbound prefill message: per-call prop wins, then AuthKit default.
14273
14315
  const prefillMessage = whatsappPrefillMessage ?? config?.whatsappPrefillMessage;
14274
- const result = await api.sendWhatsApp(getRedirectUrl(), undefined, reply, prefillMessage);
14275
- whatsappSendRef.current = { token: result.token, sessionKey: result.sessionKey };
14316
+ // Pass collected signup details as contactData so the backend creates the
14317
+ // contact with name/customFields already attached and returns a fully
14318
+ // formed session.user — no follow-up updateProfile call needed.
14319
+ const trimmedName = displayName?.trim() || undefined;
14320
+ const contactData = trimmedName ? { name: trimmedName } : undefined;
14321
+ const result = await api.sendWhatsApp(getRedirectUrl(), undefined, reply, prefillMessage, contactData);
14322
+ whatsappSendRef.current = {
14323
+ token: result.token,
14324
+ sessionKey: result.sessionKey,
14325
+ displayName: trimmedName,
14326
+ };
14276
14327
  return result;
14277
14328
  }
14278
14329
  catch (err) {
@@ -14291,9 +14342,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14291
14342
  const target = status.redirectUrl || getRedirectUrl();
14292
14343
  setAuthSuccess(true);
14293
14344
  setSuccessMessage('WhatsApp verified! Signing you in…');
14294
- // Exchange the verified WhatsApp proof for a real Auth Kit session token,
14295
- // so the user is fully logged in (not just verified) and any same-tab
14296
- // continuation flows (claim, bid, etc.) pick up an authenticated session.
14345
+ // Exchange the verified WhatsApp proof for a real Auth Kit session token.
14346
+ // The backend has already created/updated the contact using contactData
14347
+ // sent at sendWhatsApp time, so session.user is fully formed.
14297
14348
  const send = whatsappSendRef.current;
14298
14349
  if (send?.sessionKey) {
14299
14350
  try {
@@ -14636,6 +14687,32 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14636
14687
  const [profile, setProfile] = useState(null);
14637
14688
  const [error, setError] = useState();
14638
14689
  const [success, setSuccess] = useState();
14690
+ const [resolvedClientId, setResolvedClientId] = useState(clientId);
14691
+ // Keep prop in sync
14692
+ useEffect(() => {
14693
+ if (clientId)
14694
+ setResolvedClientId(clientId);
14695
+ }, [clientId]);
14696
+ // If no clientId was provided, try to resolve the collection's default Auth Kit.
14697
+ // This supports "portal mode" where the host app only knows the collectionId.
14698
+ useEffect(() => {
14699
+ if (clientId || !collectionId)
14700
+ return;
14701
+ let cancelled = false;
14702
+ (async () => {
14703
+ try {
14704
+ const collection = await smartlinks.collection.get(collectionId);
14705
+ const defaultId = collection?.defaultAuthKitId;
14706
+ if (!cancelled && defaultId)
14707
+ setResolvedClientId(defaultId);
14708
+ }
14709
+ catch {
14710
+ // Non-fatal — handlers will surface a friendly error if still missing
14711
+ }
14712
+ })();
14713
+ return () => { cancelled = true; };
14714
+ }, [clientId, collectionId]);
14715
+ const NO_CLIENT_ID_MSG = 'This account section is not connected to an Auth Kit yet. Pass a clientId prop, or set a default Auth Kit on the collection in the admin console.';
14639
14716
  // Schema state — now uses SDK type directly
14640
14717
  const [schema, setSchema] = useState(null);
14641
14718
  const [schemaLoading, setSchemaLoading] = useState(false);
@@ -14707,26 +14784,29 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14707
14784
  setLoading(true);
14708
14785
  setError(undefined);
14709
14786
  try {
14787
+ // Pull contact first so we can fall back to fields the auth user object
14788
+ // may not carry (e.g. WhatsApp phone numbers, displayName, email).
14789
+ let contactData = auth.contact;
14790
+ if (collectionId && !contactData) {
14791
+ try {
14792
+ contactData = (await auth.getContact?.()) || null;
14793
+ }
14794
+ catch { /* non-fatal */ }
14795
+ }
14796
+ const contactAny = contactData;
14710
14797
  const profileData = {
14711
14798
  uid: auth.user?.uid || '',
14712
- email: auth.user?.email,
14713
- displayName: auth.user?.displayName,
14714
- phoneNumber: auth.user?.phoneNumber,
14799
+ email: auth.user?.email || contactAny?.email,
14800
+ displayName: auth.user?.displayName || contactAny?.displayName || contactAny?.name,
14801
+ phoneNumber: auth.user?.phoneNumber || contactAny?.phone || contactAny?.phoneNumber,
14715
14802
  photoURL: auth.user?.photoURL,
14716
14803
  emailVerified: true,
14717
14804
  accountData: auth.accountData || {},
14718
14805
  };
14719
14806
  setProfile(profileData);
14720
14807
  setDisplayName(profileData.displayName || '');
14721
- // Load contact custom fields if collectionId provided
14722
- if (collectionId && auth.contact) {
14723
- setCustomFieldValues(auth.contact.customFields || {});
14724
- }
14725
- else if (collectionId) {
14726
- const contact = await auth.getContact?.();
14727
- if (contact?.customFields) {
14728
- setCustomFieldValues(contact.customFields);
14729
- }
14808
+ if (collectionId && contactData?.customFields) {
14809
+ setCustomFieldValues(contactData.customFields);
14730
14810
  }
14731
14811
  }
14732
14812
  catch (err) {
@@ -14758,19 +14838,34 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14758
14838
  const editableCustomFields = getEditableFields(schema, customFieldValues).filter(f => !['email', 'displayName', 'phone', 'phoneNumber'].includes(f.key));
14759
14839
  const handleUpdateProfile = async (e) => {
14760
14840
  e.preventDefault();
14761
- if (!clientId) {
14762
- setError('Client ID is required');
14841
+ if (!resolvedClientId) {
14842
+ setError(NO_CLIENT_ID_MSG);
14763
14843
  return;
14764
14844
  }
14765
14845
  setLoading(true);
14766
14846
  setError(undefined);
14767
14847
  setSuccess(undefined);
14768
14848
  try {
14769
- await smartlinks.authKit.updateProfile(clientId, { displayName });
14849
+ // SDK 1.13.17+: updateProfile returns a fresh bearer token with refreshed
14850
+ // claims (displayName/photoURL). We MUST persist the new token, otherwise
14851
+ // a page refresh would decode the old token and resurrect stale values.
14852
+ // Cast: older @proveanything/smartlinks type defs typed this as UserProfile
14853
+ // (no `token`). The runtime always returns the rotated token in 1.13.17+.
14854
+ const updated = await smartlinks.authKit.updateProfile(resolvedClientId, { displayName });
14855
+ await auth.applySessionRefresh({
14856
+ token: updated.token,
14857
+ user: {
14858
+ displayName: updated.displayName ?? displayName,
14859
+ email: updated.email,
14860
+ phoneNumber: updated.phoneNumber ?? undefined,
14861
+ photoURL: updated.photoURL ?? undefined,
14862
+ },
14863
+ accountData: updated.accountData,
14864
+ });
14770
14865
  setSuccess('Profile updated successfully!');
14771
14866
  setEditingSection(null);
14772
14867
  if (profile) {
14773
- setProfile({ ...profile, displayName });
14868
+ setProfile({ ...profile, displayName: updated.displayName ?? displayName });
14774
14869
  }
14775
14870
  }
14776
14871
  catch (err) {
@@ -14805,8 +14900,8 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14805
14900
  };
14806
14901
  const handleChangeEmail = async (e) => {
14807
14902
  e.preventDefault();
14808
- if (!clientId) {
14809
- setError('Client ID is required');
14903
+ if (!resolvedClientId) {
14904
+ setError(NO_CLIENT_ID_MSG);
14810
14905
  return;
14811
14906
  }
14812
14907
  setLoading(true);
@@ -14814,7 +14909,11 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14814
14909
  setSuccess(undefined);
14815
14910
  try {
14816
14911
  const redirectUrl = window.location.href;
14817
- await smartlinks.authKit.changeEmail(clientId, newEmail, emailPassword, redirectUrl);
14912
+ const res = await smartlinks.authKit.changeEmail(resolvedClientId, newEmail, emailPassword, redirectUrl);
14913
+ // SDK may rotate bearer token on email change — persist if present.
14914
+ if (res?.token) {
14915
+ await auth.applySessionRefresh({ token: res.token });
14916
+ }
14818
14917
  setSuccess('Email change requested. Please check your new email for verification.');
14819
14918
  setEditingSection(null);
14820
14919
  setNewEmail('');
@@ -14830,8 +14929,8 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14830
14929
  };
14831
14930
  const handleChangePassword = async (e) => {
14832
14931
  e.preventDefault();
14833
- if (!clientId) {
14834
- setError('Client ID is required');
14932
+ if (!resolvedClientId) {
14933
+ setError(NO_CLIENT_ID_MSG);
14835
14934
  return;
14836
14935
  }
14837
14936
  if (newPassword !== confirmPassword) {
@@ -14846,7 +14945,7 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14846
14945
  setError(undefined);
14847
14946
  setSuccess(undefined);
14848
14947
  try {
14849
- await smartlinks.authKit.changePassword(clientId, currentPassword, newPassword);
14948
+ await smartlinks.authKit.changePassword(resolvedClientId, currentPassword, newPassword);
14850
14949
  setSuccess('Password changed successfully!');
14851
14950
  setEditingSection(null);
14852
14951
  setCurrentPassword('');
@@ -14862,14 +14961,14 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14862
14961
  }
14863
14962
  };
14864
14963
  const handleSendPhoneCode = async () => {
14865
- if (!clientId) {
14866
- setError('Client ID is required');
14964
+ if (!resolvedClientId) {
14965
+ setError(NO_CLIENT_ID_MSG);
14867
14966
  return;
14868
14967
  }
14869
14968
  setLoading(true);
14870
14969
  setError(undefined);
14871
14970
  try {
14872
- await smartlinks.authKit.sendPhoneCode(clientId, newPhone);
14971
+ await smartlinks.authKit.sendPhoneCode(resolvedClientId, newPhone);
14873
14972
  setPhoneCodeSent(true);
14874
14973
  setSuccess('Verification code sent to your phone');
14875
14974
  }
@@ -14883,15 +14982,20 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14883
14982
  };
14884
14983
  const handleUpdatePhone = async (e) => {
14885
14984
  e.preventDefault();
14886
- if (!clientId) {
14887
- setError('Client ID is required');
14985
+ if (!resolvedClientId) {
14986
+ setError(NO_CLIENT_ID_MSG);
14888
14987
  return;
14889
14988
  }
14890
14989
  setLoading(true);
14891
14990
  setError(undefined);
14892
14991
  setSuccess(undefined);
14893
14992
  try {
14894
- await smartlinks.authKit.updatePhone(clientId, newPhone, phoneCode);
14993
+ const res = await smartlinks.authKit.updatePhone(resolvedClientId, newPhone, phoneCode);
14994
+ // Phone change rotates the bearer token (phoneNumber is a JWT claim).
14995
+ await auth.applySessionRefresh({
14996
+ token: res?.token,
14997
+ user: { phoneNumber: newPhone },
14998
+ });
14895
14999
  setSuccess('Phone number updated successfully!');
14896
15000
  setEditingSection(null);
14897
15001
  setNewPhone('');
@@ -14908,8 +15012,8 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14908
15012
  }
14909
15013
  };
14910
15014
  const handleDeleteAccount = async () => {
14911
- if (!clientId) {
14912
- setError('Client ID is required');
15015
+ if (!resolvedClientId) {
15016
+ setError(NO_CLIENT_ID_MSG);
14913
15017
  return;
14914
15018
  }
14915
15019
  if (deleteConfirmText !== 'DELETE') {
@@ -14923,7 +15027,7 @@ const AccountManagement = ({ apiEndpoint, clientId, collectionId, onError, class
14923
15027
  setLoading(true);
14924
15028
  setError(undefined);
14925
15029
  try {
14926
- await smartlinks.authKit.deleteAccount(clientId, deletePassword, deleteConfirmText);
15030
+ await smartlinks.authKit.deleteAccount(resolvedClientId, deletePassword, deleteConfirmText);
14927
15031
  setSuccess('Account deleted successfully');
14928
15032
  await auth.logout();
14929
15033
  }