@proveanything/smartlinks-auth-ui 0.1.8 → 0.1.10

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
@@ -10610,16 +10610,51 @@ const MagicLinkForm = ({ onSubmit, onCancel, loading = false, error, }) => {
10610
10610
  return (jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className: "auth-form", children: [jsxRuntime.jsxs("div", { className: "auth-form-group", children: [jsxRuntime.jsx("label", { htmlFor: "magic-link-email", className: "auth-label", children: "Email Address" }), jsxRuntime.jsx("input", { id: "magic-link-email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), className: "auth-input", placeholder: "you@example.com", required: true, disabled: loading })] }), error && (jsxRuntime.jsx("div", { className: "auth-error-message", children: error })), jsxRuntime.jsx("button", { type: "submit", className: "auth-button auth-button-primary", disabled: loading || !email, children: loading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: "auth-spinner" }), "Sending..."] })) : ('Send Magic Link') }), jsxRuntime.jsx("button", { type: "button", onClick: onCancel, className: "auth-button auth-button-secondary", disabled: loading, children: "Cancel" })] }));
10611
10611
  };
10612
10612
 
10613
+ /**
10614
+ * Creates a normalized logger wrapper that works with different logger types
10615
+ * - If no logger provided, returns no-op logger (silent)
10616
+ * - If function logger, wraps it with level prefixes
10617
+ * - If console-like object, wraps methods with prefixes
10618
+ */
10619
+ function createLoggerWrapper(logger) {
10620
+ if (!logger) {
10621
+ // No-op logger when not provided
10622
+ return {
10623
+ log: () => { },
10624
+ warn: () => { },
10625
+ error: () => { },
10626
+ debug: () => { },
10627
+ };
10628
+ }
10629
+ if (typeof logger === 'function') {
10630
+ // Function logger - call it for all levels
10631
+ return {
10632
+ log: (...args) => logger('[Auth]', ...args),
10633
+ warn: (...args) => logger('[Auth WARN]', ...args),
10634
+ error: (...args) => logger('[Auth ERROR]', ...args),
10635
+ debug: (...args) => logger('[Auth DEBUG]', ...args),
10636
+ };
10637
+ }
10638
+ // Console-like object logger
10639
+ return {
10640
+ log: logger.log ? (...args) => logger.log('[Auth]', ...args) : () => { },
10641
+ warn: logger.warn ? (...args) => logger.warn('[Auth WARN]', ...args) : () => { },
10642
+ error: logger.error ? (...args) => logger.error('[Auth ERROR]', ...args) : () => { },
10643
+ debug: logger.debug ? (...args) => logger.debug('[Auth DEBUG]', ...args) : () => { },
10644
+ };
10645
+ }
10646
+
10613
10647
  /**
10614
10648
  * AuthAPI - Thin wrapper around Smartlinks SDK authKit namespace
10615
10649
  * All authentication operations now use the global Smartlinks SDK
10616
10650
  */
10617
10651
  class AuthAPI {
10618
- constructor(_apiEndpoint, clientId, clientName) {
10652
+ constructor(_apiEndpoint, clientId, clientName, logger) {
10619
10653
  // apiEndpoint is kept for backward compatibility but not used
10620
10654
  // Smartlinks SDK is pre-configured globally
10621
10655
  this.clientId = clientId;
10622
10656
  this.clientName = clientName;
10657
+ this.log = createLoggerWrapper(logger);
10623
10658
  }
10624
10659
  async login(email, password) {
10625
10660
  return smartlinks__namespace.authKit.login(this.clientId, email, password);
@@ -10674,15 +10709,15 @@ class AuthAPI {
10674
10709
  });
10675
10710
  }
10676
10711
  async fetchConfig() {
10677
- console.log('[AuthAPI] fetchConfig called with clientId:', this.clientId);
10712
+ this.log.log('fetchConfig called with clientId:', this.clientId);
10678
10713
  try {
10679
- console.log('[AuthAPI] Calling smartlinks.authKit.load...');
10714
+ this.log.log('Calling smartlinks.authKit.load...');
10680
10715
  const result = await smartlinks__namespace.authKit.load(this.clientId);
10681
- console.log('[AuthAPI] smartlinks.authKit.load returned:', result);
10716
+ this.log.log('smartlinks.authKit.load returned:', result);
10682
10717
  return result;
10683
10718
  }
10684
10719
  catch (error) {
10685
- console.warn('[AuthAPI] Failed to fetch UI config, using defaults:', error);
10720
+ this.log.warn('Failed to fetch UI config, using defaults:', error);
10686
10721
  return {
10687
10722
  branding: {
10688
10723
  title: 'Smartlinks Auth',
@@ -11479,7 +11514,7 @@ const loadGoogleIdentityServices = () => {
11479
11514
  document.head.appendChild(script);
11480
11515
  });
11481
11516
  };
11482
- const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'auto', className, customization, skipConfigFetch = false, minimal = false, }) => {
11517
+ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'auto', className, customization, skipConfigFetch = false, minimal = false, logger, }) => {
11483
11518
  const [mode, setMode] = React.useState(initialMode);
11484
11519
  const [loading, setLoading] = React.useState(false);
11485
11520
  const [error, setError] = React.useState();
@@ -11495,7 +11530,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11495
11530
  const [config, setConfig] = React.useState(null);
11496
11531
  const [configLoading, setConfigLoading] = React.useState(!skipConfigFetch);
11497
11532
  const [showEmailForm, setShowEmailForm] = React.useState(false); // Track if email form should be shown when emailDisplayMode is 'button'
11498
- const api = new AuthAPI(apiEndpoint, clientId, clientName);
11533
+ const [sdkReady, setSdkReady] = React.useState(false); // Track SDK initialization state
11534
+ const log = React.useMemo(() => createLoggerWrapper(logger), [logger]);
11535
+ const api = new AuthAPI(apiEndpoint, clientId, clientName, logger);
11499
11536
  const auth = useAuth();
11500
11537
  // Dark mode detection and theme management
11501
11538
  React.useEffect(() => {
@@ -11513,30 +11550,37 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11513
11550
  // Reinitialize Smartlinks SDK when apiEndpoint changes (for test/dev scenarios)
11514
11551
  // IMPORTANT: Preserve bearer token during reinitialization
11515
11552
  React.useEffect(() => {
11516
- console.log('[SmartlinksAuthUI] SDK reinitialize useEffect triggered', { apiEndpoint });
11553
+ log.log('SDK reinitialize useEffect triggered', { apiEndpoint });
11554
+ setSdkReady(false); // Mark SDK as not ready during reinitialization
11517
11555
  const reinitializeWithToken = async () => {
11518
11556
  if (apiEndpoint) {
11519
- console.log('[SmartlinksAuthUI] Reinitializing SDK with baseURL:', apiEndpoint);
11557
+ log.log('Reinitializing SDK with baseURL:', apiEndpoint);
11520
11558
  // Get current token before reinitializing
11521
11559
  const currentToken = await auth.getToken();
11522
11560
  smartlinks__namespace.initializeApi({
11523
11561
  baseURL: apiEndpoint,
11524
11562
  proxyMode: false, // Direct API calls when custom endpoint is provided
11525
11563
  ngrokSkipBrowserWarning: true,
11564
+ logger: logger, // Pass logger to SDK for verbose SDK logging
11526
11565
  });
11566
+ log.log('SDK reinitialized successfully');
11527
11567
  // Restore bearer token after reinitialization using auth.verifyToken
11528
11568
  if (currentToken) {
11529
11569
  smartlinks__namespace.auth.verifyToken(currentToken).catch(err => {
11530
- console.warn('Failed to restore bearer token after reinit:', err);
11570
+ log.warn('Failed to restore bearer token after reinit:', err);
11531
11571
  });
11532
11572
  }
11573
+ // Mark SDK as ready
11574
+ setSdkReady(true);
11533
11575
  }
11534
11576
  else {
11535
- console.log('[SmartlinksAuthUI] No apiEndpoint, skipping SDK reinitialize');
11577
+ log.log('No apiEndpoint, SDK already initialized by App');
11578
+ // SDK was initialized by App component, mark as ready
11579
+ setSdkReady(true);
11536
11580
  }
11537
11581
  };
11538
11582
  reinitializeWithToken();
11539
- }, [apiEndpoint, auth]);
11583
+ }, [apiEndpoint, auth, logger, log]);
11540
11584
  // Get the effective redirect URL (use prop or default to current page)
11541
11585
  const getRedirectUrl = () => {
11542
11586
  if (redirectUrl)
@@ -11548,22 +11592,28 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11548
11592
  };
11549
11593
  // Fetch UI configuration
11550
11594
  React.useEffect(() => {
11551
- console.log('[SmartlinksAuthUI] Config fetch useEffect triggered', {
11595
+ log.log('Config fetch useEffect triggered', {
11552
11596
  skipConfigFetch,
11553
11597
  clientId,
11554
11598
  clientIdType: typeof clientId,
11555
11599
  clientIdTruthy: !!clientId,
11556
- apiEndpoint
11600
+ apiEndpoint,
11601
+ sdkReady
11557
11602
  });
11603
+ // Wait for SDK to be ready before fetching config
11604
+ if (!sdkReady) {
11605
+ log.log('SDK not ready yet, waiting...');
11606
+ return;
11607
+ }
11558
11608
  if (skipConfigFetch) {
11559
- console.log('[SmartlinksAuthUI] Skipping config fetch - skipConfigFetch is true');
11609
+ log.log('Skipping config fetch - skipConfigFetch is true');
11560
11610
  setConfig(customization || {});
11561
11611
  return;
11562
11612
  }
11563
11613
  const fetchConfig = async () => {
11564
11614
  // If no clientId provided, use default config immediately without API call
11565
11615
  if (!clientId) {
11566
- console.log('[SmartlinksAuthUI] No clientId provided, using default config');
11616
+ log.log('No clientId provided, using default config');
11567
11617
  const defaultConfig = {
11568
11618
  ...DEFAULT_AUTH_CONFIG,
11569
11619
  enabledProviders: enabledProviders || ['email', 'google', 'phone']
@@ -11594,9 +11644,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11594
11644
  }
11595
11645
  }
11596
11646
  // Fetch from API
11597
- console.log('[SmartlinksAuthUI] Fetching config from API for clientId:', clientId);
11647
+ log.log('Fetching config from API for clientId:', clientId);
11598
11648
  const fetchedConfig = await api.fetchConfig();
11599
- console.log('[SmartlinksAuthUI] Received config:', fetchedConfig);
11649
+ log.log('Received config:', fetchedConfig);
11600
11650
  // Merge with customization props (props take precedence)
11601
11651
  const mergedConfig = { ...fetchedConfig, ...customization };
11602
11652
  setConfig(mergedConfig);
@@ -11607,7 +11657,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11607
11657
  }));
11608
11658
  }
11609
11659
  catch (err) {
11610
- console.error('Failed to fetch config:', err);
11660
+ log.error('Failed to fetch config:', err);
11611
11661
  setConfig(customization || {});
11612
11662
  }
11613
11663
  finally {
@@ -11615,7 +11665,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11615
11665
  }
11616
11666
  };
11617
11667
  fetchConfig();
11618
- }, [apiEndpoint, clientId, customization, skipConfigFetch]);
11668
+ }, [apiEndpoint, clientId, customization, skipConfigFetch, sdkReady, log]);
11619
11669
  // Reset showEmailForm when mode changes away from login/register
11620
11670
  React.useEffect(() => {
11621
11671
  if (mode !== 'login' && mode !== 'register') {
@@ -11640,7 +11690,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11640
11690
  const params = getUrlParams();
11641
11691
  const urlMode = params.get('mode');
11642
11692
  const token = params.get('token');
11643
- console.log('URL params detected:', { urlMode, token, hash: window.location.hash, search: window.location.search });
11693
+ log.log('URL params detected:', { urlMode, token, hash: window.location.hash, search: window.location.search });
11644
11694
  if (urlMode && token) {
11645
11695
  handleURLBasedAuth(urlMode, token);
11646
11696
  }
@@ -11650,7 +11700,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11650
11700
  setError(undefined);
11651
11701
  try {
11652
11702
  if (urlMode === 'verifyEmail') {
11653
- console.log('Verifying email with token:', token);
11703
+ log.log('Verifying email with token:', token);
11654
11704
  const response = await api.verifyEmailWithToken(token);
11655
11705
  // Get email verification mode from response or config
11656
11706
  const verificationMode = response.emailVerificationMode || config?.emailVerification?.mode || 'verify-then-auto-login';
@@ -11685,7 +11735,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11685
11735
  }
11686
11736
  }
11687
11737
  else if (urlMode === 'resetPassword') {
11688
- console.log('Verifying reset token:', token);
11738
+ log.log('Verifying reset token:', token);
11689
11739
  // Verify token is valid, then show password reset form
11690
11740
  await api.verifyResetToken(token);
11691
11741
  setResetToken(token); // Store token for use in password reset
@@ -11695,7 +11745,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11695
11745
  window.history.replaceState({}, document.title, cleanUrl);
11696
11746
  }
11697
11747
  else if (urlMode === 'magicLink') {
11698
- console.log('Verifying magic link token:', token);
11748
+ log.log('Verifying magic link token:', token);
11699
11749
  const response = await api.verifyMagicLink(token);
11700
11750
  // Auto-login with magic link if token is provided
11701
11751
  if (response.token) {
@@ -11719,7 +11769,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11719
11769
  }
11720
11770
  }
11721
11771
  catch (err) {
11722
- console.error('URL-based auth error:', err);
11772
+ log.error('URL-based auth error:', err);
11723
11773
  const errorMessage = err instanceof Error ? err.message : 'An error occurred';
11724
11774
  // If it's an email verification error (expired/invalid token), show resend option
11725
11775
  if (urlMode === 'verifyEmail') {