@proveanything/smartlinks-auth-ui 0.5.13 → 0.5.15

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.
@@ -1 +1 @@
1
- {"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAcpE,OAAO,KAAK,EAAE,qBAAqB,EAAyF,MAAM,UAAU,CAAC;AAiR7I,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,CA+nE5D,CAAC"}
1
+ {"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAcpE,OAAO,KAAK,EAAE,qBAAqB,EAAyF,MAAM,UAAU,CAAC;AAgT7I,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,CA8qE5D,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,CA0oCpD,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,CA4oCpD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,gBAM1B,CAAC"}
package/dist/index.esm.js CHANGED
@@ -12755,6 +12755,9 @@ collectionId, enableContactSync, enableInteractionTracking, interactionAppId, in
12755
12755
  await tokenStorage.saveAccountData(authAccountData);
12756
12756
  await tokenStorage.saveAccountInfo(authAccountData, accountCacheTTL);
12757
12757
  }
12758
+ else {
12759
+ await tokenStorage.clearAccountData();
12760
+ }
12758
12761
  smartlinks.auth.verifyToken(authToken).catch(() => { });
12759
12762
  }
12760
12763
  // Always update memory state (but NOT isVerified yet - wait for parent ack in iframe mode)
@@ -13099,6 +13102,25 @@ const normalizeQueryString = (query) => {
13099
13102
  const buildSearchParams = (rawQuery) => {
13100
13103
  return new URLSearchParams(normalizeQueryString(rawQuery));
13101
13104
  };
13105
+ const appendWhatsAppResumeParams = (url, token) => {
13106
+ try {
13107
+ const nextUrl = new URL(url, window.location.origin);
13108
+ nextUrl.searchParams.set('mode', 'whatsapp');
13109
+ if (token) {
13110
+ nextUrl.searchParams.set('token', token);
13111
+ }
13112
+ else {
13113
+ nextUrl.searchParams.delete('token');
13114
+ }
13115
+ const serializedUrl = nextUrl.toString();
13116
+ return token === '{{token}}'
13117
+ ? serializedUrl.replace(encodeURIComponent(token), token)
13118
+ : serializedUrl;
13119
+ }
13120
+ catch {
13121
+ return url;
13122
+ }
13123
+ };
13102
13124
  // Helper to check for URL auth params synchronously (runs during initialization)
13103
13125
  // This prevents the form from flashing before detecting deep-link flows
13104
13126
  const getInitialUrlAuthParams = () => {
@@ -13121,6 +13143,19 @@ const getExpirationFromResponse = (response) => {
13121
13143
  return Date.now() + response.expiresIn;
13122
13144
  return undefined; // Will use 7-day default in tokenStorage
13123
13145
  };
13146
+ const stripWhatsAppResumeParams = (url) => {
13147
+ try {
13148
+ const urlObj = new URL(url);
13149
+ if (urlObj.searchParams.get('mode') === 'whatsapp') {
13150
+ urlObj.searchParams.delete('mode');
13151
+ urlObj.searchParams.delete('token');
13152
+ }
13153
+ return urlObj.toString();
13154
+ }
13155
+ catch {
13156
+ return url;
13157
+ }
13158
+ };
13124
13159
  const getActionResultErrorMessage = (result) => {
13125
13160
  if (!result || typeof result !== 'object')
13126
13161
  return null;
@@ -13150,7 +13185,7 @@ const interpolateReply = (input, vars) => {
13150
13185
  .replace(/\{\{\s*phoneNumber\s*\}\}/gi, vars.phoneNumber?.trim() || '')
13151
13186
  .replace(/\{\{\s*returnUrl\s*\}\}/gi, vars.returnUrl?.trim() || '')
13152
13187
  .replace(/\{\{\s*clientId\s*\}\}/gi, vars.clientId?.trim() || '')
13153
- .replace(/\{\{\s*token\s*\}\}/gi, vars.token?.trim() || '');
13188
+ .replace(/\{\{\s*token\s*\}\}/gi, vars.token === undefined ? '{{token}}' : vars.token.trim());
13154
13189
  };
13155
13190
  const buildWhatsAppReply = (cfg, vars) => {
13156
13191
  if (!cfg)
@@ -13478,11 +13513,34 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
13478
13513
  // Get the full current URL including hash routes, strip query params
13479
13514
  return window.location.href.split('?')[0];
13480
13515
  };
13516
+ const syncWhatsAppResumeUrl = (pending) => {
13517
+ if (typeof window === 'undefined')
13518
+ return;
13519
+ try {
13520
+ const currentUrl = new URL(window.location.href);
13521
+ const isOnResumeUrl = currentUrl.searchParams.get('mode') === 'whatsapp';
13522
+ if (!pending) {
13523
+ if (!isOnResumeUrl)
13524
+ return;
13525
+ const cleanUrl = stripWhatsAppResumeParams(currentUrl.toString());
13526
+ window.history.replaceState({}, document.title, cleanUrl);
13527
+ return;
13528
+ }
13529
+ const resumedUrl = appendWhatsAppResumeParams(pending.redirectUrl || currentUrl.toString(), pending.token);
13530
+ if (currentUrl.toString() !== resumedUrl) {
13531
+ window.history.replaceState({}, document.title, resumedUrl);
13532
+ }
13533
+ }
13534
+ catch (err) {
13535
+ log.warn('Failed to sync WhatsApp resume URL state:', err);
13536
+ }
13537
+ };
13481
13538
  const savePendingWhatsAppSession = async (session) => {
13482
13539
  if (proxyMode)
13483
13540
  return;
13484
13541
  const storage = await getStorage();
13485
13542
  await storage.setItem(WHATSAPP_PENDING_SESSION_KEY, session);
13543
+ syncWhatsAppResumeUrl(session);
13486
13544
  };
13487
13545
  const loadPendingWhatsAppSession = async () => {
13488
13546
  if (proxyMode)
@@ -13495,6 +13553,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
13495
13553
  return;
13496
13554
  const storage = await getStorage();
13497
13555
  await storage.removeItem(WHATSAPP_PENDING_SESSION_KEY);
13556
+ syncWhatsAppResumeUrl(null);
13498
13557
  };
13499
13558
  const updatePendingWhatsAppSession = async (updates) => {
13500
13559
  if (proxyMode)
@@ -13678,6 +13737,12 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
13678
13737
  // Google OAuth redirect callback
13679
13738
  handleGoogleAuthCodeCallback(authCode, state);
13680
13739
  }
13740
+ else if (urlMode === 'whatsapp') {
13741
+ if (!auth.user?.uid) {
13742
+ setMode('whatsapp');
13743
+ }
13744
+ setUrlAuthProcessing(false);
13745
+ }
13681
13746
  else if (urlMode && token) {
13682
13747
  handleURLBasedAuth(urlMode, token);
13683
13748
  }
@@ -14601,14 +14666,26 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14601
14666
  let cancelled = false;
14602
14667
  const resumePendingWhatsAppSession = async () => {
14603
14668
  try {
14669
+ const urlParams = buildSearchParams(window.location.search);
14670
+ const resumeMode = urlParams.get('mode');
14671
+ const resumeToken = urlParams.get('token');
14604
14672
  const pending = await loadPendingWhatsAppSession();
14605
- if (!pending || cancelled)
14673
+ if (!pending || cancelled) {
14674
+ if (resumeMode === 'whatsapp') {
14675
+ syncWhatsAppResumeUrl(null);
14676
+ }
14606
14677
  return;
14678
+ }
14607
14679
  // Expire stale pending sessions after 30 minutes to avoid resurrecting old attempts.
14608
14680
  if (Date.now() - pending.createdAt > 30 * 60 * 1000) {
14609
14681
  await clearPendingWhatsAppSession();
14610
14682
  return;
14611
14683
  }
14684
+ if (resumeMode === 'whatsapp' && resumeToken && resumeToken !== pending.token) {
14685
+ await clearPendingWhatsAppSession();
14686
+ return;
14687
+ }
14688
+ syncWhatsAppResumeUrl(pending);
14612
14689
  whatsappSendRef.current = {
14613
14690
  token: pending.token,
14614
14691
  sessionKey: pending.sessionKey,
@@ -14631,7 +14708,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14631
14708
  }
14632
14709
  return;
14633
14710
  }
14634
- if (status.status === 'pending') {
14711
+ if (resumeMode === 'whatsapp' || status.status === 'pending') {
14635
14712
  setMode('whatsapp');
14636
14713
  }
14637
14714
  else if (status.status === 'failed' || status.status === 'expired' || status.status === 'unknown') {
@@ -14657,10 +14734,11 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14657
14734
  // Resolve reply config: per-call prop wins, otherwise fall back to AuthKit default.
14658
14735
  const replyConfig = whatsappReply ?? config?.whatsappReply;
14659
14736
  const effectiveRedirectUrl = getRedirectUrl();
14737
+ const resumableRedirectUrl = appendWhatsAppResumeParams(effectiveRedirectUrl, '{{token}}');
14660
14738
  const reply = buildWhatsAppReply(replyConfig, {
14661
14739
  name: displayName,
14662
14740
  clientName,
14663
- returnUrl: effectiveRedirectUrl,
14741
+ returnUrl: resumableRedirectUrl,
14664
14742
  clientId,
14665
14743
  });
14666
14744
  // Resolve outbound prefill message: per-call prop wins, then AuthKit default.
@@ -14670,7 +14748,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14670
14748
  // formed session.user — no follow-up updateProfile call needed.
14671
14749
  const trimmedName = displayName?.trim() || undefined;
14672
14750
  const contactData = trimmedName ? { name: trimmedName } : undefined;
14673
- const result = await api.sendWhatsApp(effectiveRedirectUrl, undefined, reply, prefillMessage, contactData);
14751
+ const result = await api.sendWhatsApp(resumableRedirectUrl, undefined, reply, prefillMessage, contactData);
14674
14752
  whatsappSendRef.current = {
14675
14753
  token: result.token,
14676
14754
  sessionKey: result.sessionKey,
@@ -14753,8 +14831,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14753
14831
  fontSize: '0.875rem'
14754
14832
  }, children: initialUrlParams.mode === 'verifyEmail' ? 'Verifying your email...' :
14755
14833
  initialUrlParams.mode === 'magicLink' ? 'Processing magic link...' :
14756
- initialUrlParams.mode === 'resetPassword' ? 'Validating reset link...' :
14757
- 'Processing...' })] }) }));
14834
+ initialUrlParams.mode === 'whatsapp' ? 'Resuming your WhatsApp sign-in...' :
14835
+ initialUrlParams.mode === 'resetPassword' ? 'Validating reset link...' :
14836
+ 'Processing...' })] }) }));
14758
14837
  }
14759
14838
  if (configLoading) {
14760
14839
  return (jsx(AuthContainer, { theme: resolvedTheme, className: className, minimal: minimal || config?.branding?.minimal || false, children: jsx("div", { style: { textAlign: 'center', padding: '2rem' }, children: jsx("div", { className: "auth-spinner" }) }) }));