@proveanything/smartlinks-auth-ui 0.5.16 → 0.5.17

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;AA2V7I,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,CA4rE5D,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;AA2V7I,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,CAutE5D,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,CA4oCpD,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,CAoqCpD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,gBAM1B,CAAC"}
package/dist/index.esm.js CHANGED
@@ -12134,10 +12134,34 @@ collectionId, enableContactSync, enableInteractionTracking, interactionAppId, in
12134
12134
  }
12135
12135
  });
12136
12136
  }, []);
12137
- // Sync contact to Smartlinks (non-blocking)
12137
+ // Sync contact to Smartlinks (non-blocking).
12138
+ // Strategy: call publicGetMine() first — the "me" endpoint tells us if a
12139
+ // contact already exists for this (org, userId) pair. If it does, we skip
12140
+ // the upsert entirely (the backend's "upsert" currently calls
12141
+ // prisma.contact.create() unconditionally and 400s on the unique
12142
+ // constraint, so we must not call it for returning users). Only when no
12143
+ // contact exists do we create one via publicUpsert.
12138
12144
  const syncContact = useCallback(async (authUser, customFields) => {
12139
12145
  if (!collectionId || !shouldSyncContacts)
12140
12146
  return null;
12147
+ // 1. Look up existing contact via the "me" endpoint.
12148
+ try {
12149
+ const myContactResponse = await smartlinks.contact.publicGetMine(collectionId);
12150
+ const existing = myContactResponse?.contact;
12151
+ if (existing?.contactId) {
12152
+ if (!proxyMode) {
12153
+ await tokenStorage.saveContactId(existing.contactId);
12154
+ }
12155
+ setContact(existing);
12156
+ setContactId(existing.contactId);
12157
+ notifyAuthStateChange('CONTACT_SYNCED', authUser, token, accountData, accountInfo, isVerified, existing, existing.contactId);
12158
+ return existing.contactId;
12159
+ }
12160
+ }
12161
+ catch (lookupErr) {
12162
+ // Non-fatal — fall through to create.
12163
+ }
12164
+ // 2. No existing contact — create one.
12141
12165
  try {
12142
12166
  const result = await smartlinks.contact.publicUpsert(collectionId, {
12143
12167
  userId: authUser.uid,
@@ -14771,18 +14795,40 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14771
14795
  try {
14772
14796
  // No ensureAccount and no phone number — the backend creates/links the
14773
14797
  // account from the inbound WhatsApp webhook (sender's number is the proof).
14774
- // Resolve reply config: per-call prop wins, otherwise fall back to AuthKit default.
14775
- const replyConfig = whatsappReply ?? config?.whatsappReply;
14798
+ // Resolve reply config: per-call prop wins, then AuthKit config, then a
14799
+ // sensible built-in default so the post-verification WhatsApp reply ALWAYS
14800
+ // carries a "Continue" CTA back to the app with the resume token in the URL.
14801
+ // Without this, a user verifying in WhatsApp on one device/browser can't
14802
+ // resume the session by tapping back into our app from the chat thread.
14776
14803
  const effectiveRedirectUrl = getRedirectUrl();
14777
14804
  const resumableRedirectUrl = appendWhatsAppResumeParams(effectiveRedirectUrl, '{{token}}');
14805
+ const friendlyClientName = (clientName && clientName.trim()) || 'this app';
14806
+ const defaultReplyConfig = {
14807
+ enabled: true,
14808
+ text: `You're verified! Tap below to continue signing in to ${friendlyClientName}.`,
14809
+ cta: {
14810
+ body: `You're verified! Tap below to continue signing in to ${friendlyClientName}.`,
14811
+ buttonLabel: 'Continue',
14812
+ buttonUrl: '{{returnUrl}}',
14813
+ },
14814
+ };
14815
+ const replyConfig = whatsappReply ??
14816
+ config?.whatsappReply ??
14817
+ defaultReplyConfig;
14778
14818
  const reply = buildWhatsAppReply(replyConfig, {
14779
14819
  name: displayName,
14780
14820
  clientName,
14781
14821
  returnUrl: resumableRedirectUrl,
14782
14822
  clientId,
14783
14823
  });
14784
- // Resolve outbound prefill message: per-call prop wins, then AuthKit default.
14785
- const prefillMessage = whatsappPrefillMessage ?? config?.whatsappPrefillMessage;
14824
+ // Resolve outbound prefill message: per-call prop wins, then AuthKit config,
14825
+ // then a sensible built-in default so the wa.me body is never blank and always
14826
+ // carries the verification token (the SDK appends {{token}} if missing, but we
14827
+ // also want friendly human context for the recipient).
14828
+ const defaultPrefill = `Hi! I'd like to sign in to ${friendlyClientName}. Code: {{token}}`;
14829
+ const prefillMessage = whatsappPrefillMessage ??
14830
+ config?.whatsappPrefillMessage ??
14831
+ defaultPrefill;
14786
14832
  // Pass collected signup details as contactData so the backend creates the
14787
14833
  // contact with name/customFields already attached and returns a fully
14788
14834
  // formed session.user — no follow-up updateProfile call needed.
@@ -14904,9 +14950,12 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14904
14950
  color: config?.branding?.inheritHostStyles
14905
14951
  ? 'hsl(var(--foreground, 215 25% 15%))'
14906
14952
  : (resolvedTheme === 'dark' ? '#f1f5f9' : 'inherit')
14907
- }, children: successMessage?.includes('verified') ? 'Email Verified!' :
14908
- successMessage?.includes('Magic link') ? 'Check Your Email!' :
14909
- mode === 'register' ? 'Account Created!' : 'Login Successful!' }), jsx("p", { style: {
14953
+ }, children: successMessage?.includes('WhatsApp') ? 'WhatsApp Verified!' :
14954
+ successMessage?.includes('Phone') ? 'Phone Verified!' :
14955
+ successMessage?.includes('Email verified') || successMessage?.includes('email verified') ? 'Email Verified!' :
14956
+ successMessage?.includes('Magic link') ? 'Check Your Email!' :
14957
+ successMessage?.includes('verified') ? 'Verified!' :
14958
+ mode === 'register' ? 'Account Created!' : 'Login Successful!' }), jsx("p", { style: {
14910
14959
  color: config?.branding?.inheritHostStyles
14911
14960
  ? 'hsl(var(--muted-foreground, 215 15% 45%))'
14912
14961
  : (resolvedTheme === 'dark' ? '#94a3b8' : '#6B7280'),