@proveanything/smartlinks-auth-ui 0.1.6 → 0.1.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/index.js CHANGED
@@ -10674,11 +10674,15 @@ class AuthAPI {
10674
10674
  });
10675
10675
  }
10676
10676
  async fetchConfig() {
10677
+ console.log('[AuthAPI] fetchConfig called with clientId:', this.clientId);
10677
10678
  try {
10678
- return await smartlinks__namespace.authKit.load(this.clientId);
10679
+ console.log('[AuthAPI] Calling smartlinks.authKit.load...');
10680
+ const result = await smartlinks__namespace.authKit.load(this.clientId);
10681
+ console.log('[AuthAPI] smartlinks.authKit.load returned:', result);
10682
+ return result;
10679
10683
  }
10680
10684
  catch (error) {
10681
- console.warn('Failed to fetch UI config, using defaults:', error);
10685
+ console.warn('[AuthAPI] Failed to fetch UI config, using defaults:', error);
10682
10686
  return {
10683
10687
  branding: {
10684
10688
  title: 'Smartlinks Auth',
@@ -11449,10 +11453,37 @@ const DEFAULT_AUTH_CONFIG = {
11449
11453
  emailDisplayMode: 'button',
11450
11454
  googleOAuthFlow: 'oneTap'
11451
11455
  };
11452
- const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'light', className, customization, skipConfigFetch = false, minimal = false, }) => {
11456
+ // Helper to dynamically load Google Identity Services if not already loaded
11457
+ const loadGoogleIdentityServices = () => {
11458
+ return new Promise((resolve, reject) => {
11459
+ // Check if already loaded
11460
+ if (window.google?.accounts) {
11461
+ resolve();
11462
+ return;
11463
+ }
11464
+ // Check if script is already being loaded
11465
+ const existingScript = document.querySelector('script[src="https://accounts.google.com/gsi/client"]');
11466
+ if (existingScript) {
11467
+ // Wait for existing script to load
11468
+ existingScript.addEventListener('load', () => resolve());
11469
+ existingScript.addEventListener('error', () => reject(new Error('Failed to load Google Identity Services')));
11470
+ return;
11471
+ }
11472
+ // Dynamically inject the script
11473
+ const script = document.createElement('script');
11474
+ script.src = 'https://accounts.google.com/gsi/client';
11475
+ script.async = true;
11476
+ script.defer = true;
11477
+ script.onload = () => resolve();
11478
+ script.onerror = () => reject(new Error('Failed to load Google Identity Services'));
11479
+ document.head.appendChild(script);
11480
+ });
11481
+ };
11482
+ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'auto', className, customization, skipConfigFetch = false, minimal = false, }) => {
11453
11483
  const [mode, setMode] = React.useState(initialMode);
11454
11484
  const [loading, setLoading] = React.useState(false);
11455
11485
  const [error, setError] = React.useState();
11486
+ const [resolvedTheme, setResolvedTheme] = React.useState('light');
11456
11487
  const [resetSuccess, setResetSuccess] = React.useState(false);
11457
11488
  const [authSuccess, setAuthSuccess] = React.useState(false);
11458
11489
  const [successMessage, setSuccessMessage] = React.useState();
@@ -11466,11 +11497,26 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11466
11497
  const [showEmailForm, setShowEmailForm] = React.useState(false); // Track if email form should be shown when emailDisplayMode is 'button'
11467
11498
  const api = new AuthAPI(apiEndpoint, clientId, clientName);
11468
11499
  const auth = useAuth();
11500
+ // Dark mode detection and theme management
11501
+ React.useEffect(() => {
11502
+ if (theme !== 'auto') {
11503
+ setResolvedTheme(theme);
11504
+ return;
11505
+ }
11506
+ // Auto-detect system theme preference
11507
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
11508
+ const updateTheme = () => setResolvedTheme(mediaQuery.matches ? 'dark' : 'light');
11509
+ updateTheme();
11510
+ mediaQuery.addEventListener('change', updateTheme);
11511
+ return () => mediaQuery.removeEventListener('change', updateTheme);
11512
+ }, [theme]);
11469
11513
  // Reinitialize Smartlinks SDK when apiEndpoint changes (for test/dev scenarios)
11470
11514
  // IMPORTANT: Preserve bearer token during reinitialization
11471
11515
  React.useEffect(() => {
11516
+ console.log('[SmartlinksAuthUI] SDK reinitialize useEffect triggered', { apiEndpoint });
11472
11517
  const reinitializeWithToken = async () => {
11473
11518
  if (apiEndpoint) {
11519
+ console.log('[SmartlinksAuthUI] Reinitializing SDK with baseURL:', apiEndpoint);
11474
11520
  // Get current token before reinitializing
11475
11521
  const currentToken = await auth.getToken();
11476
11522
  smartlinks__namespace.initializeApi({
@@ -11485,6 +11531,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11485
11531
  });
11486
11532
  }
11487
11533
  }
11534
+ else {
11535
+ console.log('[SmartlinksAuthUI] No apiEndpoint, skipping SDK reinitialize');
11536
+ }
11488
11537
  };
11489
11538
  reinitializeWithToken();
11490
11539
  }, [apiEndpoint, auth]);
@@ -11499,13 +11548,22 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11499
11548
  };
11500
11549
  // Fetch UI configuration
11501
11550
  React.useEffect(() => {
11551
+ console.log('[SmartlinksAuthUI] Config fetch useEffect triggered', {
11552
+ skipConfigFetch,
11553
+ clientId,
11554
+ clientIdType: typeof clientId,
11555
+ clientIdTruthy: !!clientId,
11556
+ apiEndpoint
11557
+ });
11502
11558
  if (skipConfigFetch) {
11559
+ console.log('[SmartlinksAuthUI] Skipping config fetch - skipConfigFetch is true');
11503
11560
  setConfig(customization || {});
11504
11561
  return;
11505
11562
  }
11506
11563
  const fetchConfig = async () => {
11507
11564
  // If no clientId provided, use default config immediately without API call
11508
11565
  if (!clientId) {
11566
+ console.log('[SmartlinksAuthUI] No clientId provided, using default config');
11509
11567
  const defaultConfig = {
11510
11568
  ...DEFAULT_AUTH_CONFIG,
11511
11569
  enabledProviders: enabledProviders || ['email', 'google', 'phone']
@@ -11536,7 +11594,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11536
11594
  }
11537
11595
  }
11538
11596
  // Fetch from API
11597
+ console.log('[SmartlinksAuthUI] Fetching config from API for clientId:', clientId);
11539
11598
  const fetchedConfig = await api.fetchConfig();
11599
+ console.log('[SmartlinksAuthUI] Received config:', fetchedConfig);
11540
11600
  // Merge with customization props (props take precedence)
11541
11601
  const mergedConfig = { ...fetchedConfig, ...customization };
11542
11602
  setConfig(mergedConfig);
@@ -11834,9 +11894,11 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
11834
11894
  setLoading(true);
11835
11895
  setError(undefined);
11836
11896
  try {
11897
+ // Dynamically load Google Identity Services if not already loaded
11898
+ await loadGoogleIdentityServices();
11837
11899
  const google = window.google;
11838
- if (!google) {
11839
- throw new Error('Google Identity Services not loaded. Please check your internet connection.');
11900
+ if (!google?.accounts) {
11901
+ throw new Error('Google Identity Services failed to initialize');
11840
11902
  }
11841
11903
  if (oauthFlow === 'popup') {
11842
11904
  // Use OAuth2 popup flow (works in iframes but requires popup permission)
@@ -12006,9 +12068,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
12006
12068
  }
12007
12069
  };
12008
12070
  if (configLoading) {
12009
- return (jsxRuntime.jsx(AuthContainer, { theme: theme, className: className, minimal: minimal || config?.branding?.minimal || false, children: jsxRuntime.jsx("div", { style: { textAlign: 'center', padding: '2rem' }, children: jsxRuntime.jsx("div", { className: "auth-spinner" }) }) }));
12071
+ return (jsxRuntime.jsx(AuthContainer, { theme: resolvedTheme, className: className, minimal: minimal || config?.branding?.minimal || false, children: jsxRuntime.jsx("div", { style: { textAlign: 'center', padding: '2rem' }, children: jsxRuntime.jsx("div", { className: "auth-spinner" }) }) }));
12010
12072
  }
12011
- return (jsxRuntime.jsx(AuthContainer, { theme: theme, className: className, config: config, minimal: minimal || config?.branding?.minimal || false, children: authSuccess ? (jsxRuntime.jsxs("div", { style: { textAlign: 'center', padding: '2rem' }, children: [jsxRuntime.jsx("div", { style: {
12073
+ return (jsxRuntime.jsx(AuthContainer, { theme: resolvedTheme, className: className, config: config, minimal: minimal || config?.branding?.minimal || false, children: authSuccess ? (jsxRuntime.jsxs("div", { style: { textAlign: 'center', padding: '2rem' }, children: [jsxRuntime.jsx("div", { style: {
12012
12074
  color: 'var(--auth-primary-color, #4F46E5)',
12013
12075
  fontSize: '3rem',
12014
12076
  marginBottom: '1rem'