@proveanything/smartlinks-auth-ui 0.5.2 → 0.5.4

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
@@ -11002,9 +11002,9 @@ const WhatsAppAuthForm = ({ onSend, onPollStatus, onVerified, onBack, loading =
11002
11002
  const awaitingNameInput = collectName && !sent;
11003
11003
  const awaitingAutoSend = !collectName && !sent;
11004
11004
  return (jsxRuntime.jsxs("form", { className: "auth-form", onSubmit: awaitingNameInput ? handleNameSubmit : (e) => e.preventDefault(), children: [jsxRuntime.jsxs("div", { className: "auth-form-header", children: [jsxRuntime.jsx("h2", { className: "auth-form-title", children: "Continue with WhatsApp" }), jsxRuntime.jsx("p", { className: "auth-form-subtitle", children: sent
11005
- ? 'Send the pre-filled WhatsApp message to verify yourself. We\'ll log you in automatically.'
11005
+ ? "Tap below to open WhatsApp and send us the pre-filled message that's how we confirm your number. We'll log you in the moment we receive it."
11006
11006
  : awaitingNameInput
11007
- ? 'Tell us your name, then send us a WhatsApp message — no phone number needed.'
11007
+ ? "We'll open WhatsApp with a pre-filled message. Just hit send to confirm your number — no SMS code, no typing."
11008
11008
  : 'Preparing your WhatsApp link…' })] }), displayedError && (jsxRuntime.jsxs("div", { className: "auth-error", role: "alert", children: [jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm1 13H7v-2h2v2zm0-3H7V4h2v6z" }) }), displayedError] })), awaitingNameInput && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "auth-form-group", children: [jsxRuntime.jsx("label", { htmlFor: "waName", className: "auth-label", children: "Name" }), jsxRuntime.jsx("input", { id: "waName", type: "text", value: displayName, onChange: (e) => setDisplayName(e.target.value), className: "auth-input", placeholder: "John Smith", disabled: loading, autoComplete: "name", autoFocus: true })] }), jsxRuntime.jsx("button", { type: "submit", className: "auth-button auth-button-primary", disabled: loading, children: loading ? jsxRuntime.jsx("span", { className: "auth-spinner" }) : 'Continue' })] })), awaitingAutoSend && (jsxRuntime.jsx("div", { style: { textAlign: 'center', padding: '1.5rem' }, children: jsxRuntime.jsx("span", { className: "auth-spinner" }) })), sent && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!showOnDesktop && (jsxRuntime.jsxs("a", { href: sent.waLink, target: "_blank", rel: "noopener noreferrer", className: "auth-button auth-button-primary", style: {
11009
11009
  display: 'flex',
11010
11010
  alignItems: 'center',
@@ -11013,7 +11013,7 @@ const WhatsAppAuthForm = ({ onSend, onPollStatus, onVerified, onBack, loading =
11013
11013
  background: '#25D366',
11014
11014
  color: '#fff',
11015
11015
  textDecoration: 'none',
11016
- }, children: [jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.247-.694.247-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893A11.821 11.821 0 0020.464 3.488" }) }), "Open WhatsApp"] })), showOnDesktop && qrDataUrl && (jsxRuntime.jsxs("div", { style: { textAlign: 'center', margin: '0.75rem 0' }, children: [jsxRuntime.jsx("div", { style: {
11016
+ }, children: [jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.247-.694.247-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893A11.821 11.821 0 0020.464 3.488" }) }), "Open WhatsApp & send message"] })), showOnDesktop && qrDataUrl && (jsxRuntime.jsxs("div", { style: { textAlign: 'center', margin: '0.75rem 0' }, children: [jsxRuntime.jsx("div", { style: {
11017
11017
  display: 'inline-block',
11018
11018
  padding: '0.75rem',
11019
11019
  background: '#fff',
@@ -11023,7 +11023,7 @@ const WhatsAppAuthForm = ({ onSend, onPollStatus, onVerified, onBack, loading =
11023
11023
  fontSize: '0.8125rem',
11024
11024
  color: '#6B7280',
11025
11025
  marginTop: '0.5rem',
11026
- }, children: "Scan with your phone \u2014 your WhatsApp will open with a pre-filled message. Just hit send." })] })), showOnDesktop && (jsxRuntime.jsx("a", { href: sent.waLink, target: "_blank", rel: "noopener noreferrer", className: "auth-button auth-button-secondary", style: { display: 'block', textAlign: 'center', textDecoration: 'none' }, children: "Or open WhatsApp on this device" })), jsxRuntime.jsxs("div", { style: {
11026
+ }, children: "Scan with your phone \u2014 your WhatsApp will open with a pre-filled message. Just hit send." })] })), showOnDesktop && (jsxRuntime.jsx("a", { href: sent.waLink, target: "_blank", rel: "noopener noreferrer", className: "auth-button auth-button-secondary", style: { display: 'block', textAlign: 'center', textDecoration: 'none' }, children: "Or send the message from this device" })), jsxRuntime.jsxs("div", { style: {
11027
11027
  marginTop: '1rem',
11028
11028
  padding: '0.75rem',
11029
11029
  borderRadius: '0.5rem',
@@ -11032,7 +11032,7 @@ const WhatsAppAuthForm = ({ onSend, onPollStatus, onVerified, onBack, loading =
11032
11032
  fontSize: '0.8125rem',
11033
11033
  color: '#374151',
11034
11034
  textAlign: 'center',
11035
- }, children: [jsxRuntime.jsx("span", { className: "auth-spinner", style: { marginRight: '0.5rem' } }), "Waiting for your WhatsApp message\u2026", jsxRuntime.jsxs("div", { style: { marginTop: '0.25rem', fontSize: '0.75rem', opacity: 0.7 }, children: ["Code: ", jsxRuntime.jsx("code", { children: sent.code })] })] }), jsxRuntime.jsx("button", { type: "button", className: "auth-link", onClick: handleSendNew, disabled: loading, style: {
11035
+ }, children: [jsxRuntime.jsx("span", { className: "auth-spinner", style: { marginRight: '0.5rem' } }), "Waiting for your message \u2014 we'll log you in automatically\u2026", jsxRuntime.jsxs("div", { style: { marginTop: '0.25rem', fontSize: '0.75rem', opacity: 0.7 }, children: ["Code: ", jsxRuntime.jsx("code", { children: sent.code })] })] }), jsxRuntime.jsx("button", { type: "button", className: "auth-link", onClick: handleSendNew, disabled: loading, style: {
11036
11036
  marginTop: '0.75rem',
11037
11037
  background: 'none',
11038
11038
  border: 'none',
@@ -11509,15 +11509,20 @@ class AuthAPI {
11509
11509
  return smartlinks__namespace.authKit.verifyMagicLink(this.clientId, token);
11510
11510
  }
11511
11511
  // ============= WhatsApp =============
11512
- async sendWhatsApp(redirectUrl, phoneNumber, reply) {
11512
+ async sendWhatsApp(redirectUrl, phoneNumber, reply, prefillMessage) {
11513
11513
  // phoneNumber is optional — backend extracts it from the inbound WhatsApp webhook.
11514
11514
  // `reply`, when provided, is sent back to the user via WhatsApp on successful verification.
11515
+ // `prefillMessage` customizes the message body pre-filled in the wa.me link.
11515
11516
  return smartlinks__namespace.authKit.sendWhatsApp(this.clientId, {
11516
11517
  phoneNumber: phoneNumber ?? '',
11517
11518
  redirectUrl,
11518
11519
  ...(reply ? { reply } : {}),
11520
+ ...(prefillMessage ? { prefillMessage } : {}),
11519
11521
  });
11520
11522
  }
11523
+ async exchangeWhatsAppSession(token, sessionKey) {
11524
+ return smartlinks__namespace.authKit.exchangeWhatsAppSession(this.clientId, token, sessionKey);
11525
+ }
11521
11526
  async getWhatsAppStatus(token) {
11522
11527
  return smartlinks__namespace.authKit.getWhatsAppStatus(this.clientId, token);
11523
11528
  }
@@ -13049,7 +13054,7 @@ const checkSilentGoogleSignIn = async (clientId, googleClientId) => {
13049
13054
  });
13050
13055
  };
13051
13056
  // getFriendlyErrorMessage is now imported from ../utils/errorHandling
13052
- const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, onRedirect, enabledProviders = ['email', 'google', 'phone'], initialMode, signupProminence, redirectUrl, theme = 'light', className, customization, skipConfigFetch = false, minimal = false, logger, proxyMode = false, collectionId, disableConfigCache = false, enableSilentGoogleSignIn = false, whatsappReply, }) => {
13057
+ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, onRedirect, enabledProviders = ['email', 'google', 'phone'], initialMode, signupProminence, redirectUrl, theme = 'light', className, customization, skipConfigFetch = false, minimal = false, logger, proxyMode = false, collectionId, disableConfigCache = false, enableSilentGoogleSignIn = false, whatsappReply, whatsappPrefillMessage, }) => {
13053
13058
  // Resolve signup prominence from props, customization, config, or default
13054
13059
  const resolvedSignupProminence = signupProminence || customization?.signupProminence || 'minimal';
13055
13060
  // Determine initial mode based on signupProminence setting
@@ -14266,6 +14271,8 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14266
14271
  setLoading(false);
14267
14272
  }
14268
14273
  };
14274
+ // Track the most recent WhatsApp send so we can exchange its sessionKey for a real login session.
14275
+ const whatsappSendRef = React.useRef(null);
14269
14276
  const handleWhatsAppSend = async (displayName) => {
14270
14277
  setLoading(true);
14271
14278
  setError(undefined);
@@ -14278,7 +14285,10 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14278
14285
  name: displayName,
14279
14286
  clientName,
14280
14287
  });
14281
- const result = await api.sendWhatsApp(getRedirectUrl(), undefined, reply);
14288
+ // Resolve outbound prefill message: per-call prop wins, then AuthKit default.
14289
+ const prefillMessage = whatsappPrefillMessage ?? config?.whatsappPrefillMessage;
14290
+ const result = await api.sendWhatsApp(getRedirectUrl(), undefined, reply, prefillMessage);
14291
+ whatsappSendRef.current = { token: result.token, sessionKey: result.sessionKey };
14282
14292
  return result;
14283
14293
  }
14284
14294
  catch (err) {
@@ -14293,12 +14303,28 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
14293
14303
  const handleWhatsAppPoll = async (token) => {
14294
14304
  return api.getWhatsAppStatus(token);
14295
14305
  };
14296
- const handleWhatsAppVerified = (status) => {
14297
- // Backend returns a redirectUrl containing a magic-link-style token that
14298
- // completes the login on landing. Treat the same as magic-link verification.
14306
+ const handleWhatsAppVerified = async (status) => {
14299
14307
  const target = status.redirectUrl || getRedirectUrl();
14300
14308
  setAuthSuccess(true);
14301
14309
  setSuccessMessage('WhatsApp verified! Signing you in…');
14310
+ // Exchange the verified WhatsApp proof for a real Auth Kit session token,
14311
+ // so the user is fully logged in (not just verified) and any same-tab
14312
+ // continuation flows (claim, bid, etc.) pick up an authenticated session.
14313
+ const send = whatsappSendRef.current;
14314
+ if (send?.sessionKey) {
14315
+ try {
14316
+ const session = await api.exchangeWhatsAppSession(send.token, send.sessionKey);
14317
+ if (session?.token && session.user) {
14318
+ await auth.login(session.token, session.user, session.accountData, true, getExpirationFromResponse(session));
14319
+ if (!proxyMode) {
14320
+ onAuthSuccess(session.token, session.user, session.accountData);
14321
+ }
14322
+ }
14323
+ }
14324
+ catch (err) {
14325
+ log.warn('WhatsApp session exchange failed, falling back to redirect-only flow:', err);
14326
+ }
14327
+ }
14302
14328
  performRedirect(target, 'magic-link');
14303
14329
  };
14304
14330
  // Show processing state for URL-based auth (verification, magic link, password reset)