@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/api.d.ts +3 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/components/SmartlinksAuthUI.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +75 -25
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +75 -25
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/package.json +2 -2
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
|
-
|
|
10712
|
+
this.log.log('fetchConfig called with clientId:', this.clientId);
|
|
10678
10713
|
try {
|
|
10679
|
-
|
|
10714
|
+
this.log.log('Calling smartlinks.authKit.load...');
|
|
10680
10715
|
const result = await smartlinks__namespace.authKit.load(this.clientId);
|
|
10681
|
-
|
|
10716
|
+
this.log.log('smartlinks.authKit.load returned:', result);
|
|
10682
10717
|
return result;
|
|
10683
10718
|
}
|
|
10684
10719
|
catch (error) {
|
|
10685
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
11647
|
+
log.log('Fetching config from API for clientId:', clientId);
|
|
11598
11648
|
const fetchedConfig = await api.fetchConfig();
|
|
11599
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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') {
|