@proveanything/smartlinks-auth-ui 0.1.7 → 0.1.9
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 +71 -14
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +71 -14
- 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,11 +10709,15 @@ class AuthAPI {
|
|
|
10674
10709
|
});
|
|
10675
10710
|
}
|
|
10676
10711
|
async fetchConfig() {
|
|
10712
|
+
this.log.log('fetchConfig called with clientId:', this.clientId);
|
|
10677
10713
|
try {
|
|
10678
|
-
|
|
10714
|
+
this.log.log('Calling smartlinks.authKit.load...');
|
|
10715
|
+
const result = await smartlinks__namespace.authKit.load(this.clientId);
|
|
10716
|
+
this.log.log('smartlinks.authKit.load returned:', result);
|
|
10717
|
+
return result;
|
|
10679
10718
|
}
|
|
10680
10719
|
catch (error) {
|
|
10681
|
-
|
|
10720
|
+
this.log.warn('Failed to fetch UI config, using defaults:', error);
|
|
10682
10721
|
return {
|
|
10683
10722
|
branding: {
|
|
10684
10723
|
title: 'Smartlinks Auth',
|
|
@@ -11475,7 +11514,7 @@ const loadGoogleIdentityServices = () => {
|
|
|
11475
11514
|
document.head.appendChild(script);
|
|
11476
11515
|
});
|
|
11477
11516
|
};
|
|
11478
|
-
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, }) => {
|
|
11479
11518
|
const [mode, setMode] = React.useState(initialMode);
|
|
11480
11519
|
const [loading, setLoading] = React.useState(false);
|
|
11481
11520
|
const [error, setError] = React.useState();
|
|
@@ -11491,7 +11530,8 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11491
11530
|
const [config, setConfig] = React.useState(null);
|
|
11492
11531
|
const [configLoading, setConfigLoading] = React.useState(!skipConfigFetch);
|
|
11493
11532
|
const [showEmailForm, setShowEmailForm] = React.useState(false); // Track if email form should be shown when emailDisplayMode is 'button'
|
|
11494
|
-
const
|
|
11533
|
+
const log = React.useMemo(() => createLoggerWrapper(logger), [logger]);
|
|
11534
|
+
const api = new AuthAPI(apiEndpoint, clientId, clientName, logger);
|
|
11495
11535
|
const auth = useAuth();
|
|
11496
11536
|
// Dark mode detection and theme management
|
|
11497
11537
|
React.useEffect(() => {
|
|
@@ -11509,25 +11549,31 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11509
11549
|
// Reinitialize Smartlinks SDK when apiEndpoint changes (for test/dev scenarios)
|
|
11510
11550
|
// IMPORTANT: Preserve bearer token during reinitialization
|
|
11511
11551
|
React.useEffect(() => {
|
|
11552
|
+
log.log('SDK reinitialize useEffect triggered', { apiEndpoint });
|
|
11512
11553
|
const reinitializeWithToken = async () => {
|
|
11513
11554
|
if (apiEndpoint) {
|
|
11555
|
+
log.log('Reinitializing SDK with baseURL:', apiEndpoint);
|
|
11514
11556
|
// Get current token before reinitializing
|
|
11515
11557
|
const currentToken = await auth.getToken();
|
|
11516
11558
|
smartlinks__namespace.initializeApi({
|
|
11517
11559
|
baseURL: apiEndpoint,
|
|
11518
11560
|
proxyMode: false, // Direct API calls when custom endpoint is provided
|
|
11519
11561
|
ngrokSkipBrowserWarning: true,
|
|
11562
|
+
logger: logger, // Pass logger to SDK for verbose SDK logging
|
|
11520
11563
|
});
|
|
11521
11564
|
// Restore bearer token after reinitialization using auth.verifyToken
|
|
11522
11565
|
if (currentToken) {
|
|
11523
11566
|
smartlinks__namespace.auth.verifyToken(currentToken).catch(err => {
|
|
11524
|
-
|
|
11567
|
+
log.warn('Failed to restore bearer token after reinit:', err);
|
|
11525
11568
|
});
|
|
11526
11569
|
}
|
|
11527
11570
|
}
|
|
11571
|
+
else {
|
|
11572
|
+
log.log('No apiEndpoint, skipping SDK reinitialize');
|
|
11573
|
+
}
|
|
11528
11574
|
};
|
|
11529
11575
|
reinitializeWithToken();
|
|
11530
|
-
}, [apiEndpoint, auth]);
|
|
11576
|
+
}, [apiEndpoint, auth, logger, log]);
|
|
11531
11577
|
// Get the effective redirect URL (use prop or default to current page)
|
|
11532
11578
|
const getRedirectUrl = () => {
|
|
11533
11579
|
if (redirectUrl)
|
|
@@ -11539,13 +11585,22 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11539
11585
|
};
|
|
11540
11586
|
// Fetch UI configuration
|
|
11541
11587
|
React.useEffect(() => {
|
|
11588
|
+
log.log('Config fetch useEffect triggered', {
|
|
11589
|
+
skipConfigFetch,
|
|
11590
|
+
clientId,
|
|
11591
|
+
clientIdType: typeof clientId,
|
|
11592
|
+
clientIdTruthy: !!clientId,
|
|
11593
|
+
apiEndpoint
|
|
11594
|
+
});
|
|
11542
11595
|
if (skipConfigFetch) {
|
|
11596
|
+
log.log('Skipping config fetch - skipConfigFetch is true');
|
|
11543
11597
|
setConfig(customization || {});
|
|
11544
11598
|
return;
|
|
11545
11599
|
}
|
|
11546
11600
|
const fetchConfig = async () => {
|
|
11547
11601
|
// If no clientId provided, use default config immediately without API call
|
|
11548
11602
|
if (!clientId) {
|
|
11603
|
+
log.log('No clientId provided, using default config');
|
|
11549
11604
|
const defaultConfig = {
|
|
11550
11605
|
...DEFAULT_AUTH_CONFIG,
|
|
11551
11606
|
enabledProviders: enabledProviders || ['email', 'google', 'phone']
|
|
@@ -11576,7 +11631,9 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11576
11631
|
}
|
|
11577
11632
|
}
|
|
11578
11633
|
// Fetch from API
|
|
11634
|
+
log.log('Fetching config from API for clientId:', clientId);
|
|
11579
11635
|
const fetchedConfig = await api.fetchConfig();
|
|
11636
|
+
log.log('Received config:', fetchedConfig);
|
|
11580
11637
|
// Merge with customization props (props take precedence)
|
|
11581
11638
|
const mergedConfig = { ...fetchedConfig, ...customization };
|
|
11582
11639
|
setConfig(mergedConfig);
|
|
@@ -11587,7 +11644,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11587
11644
|
}));
|
|
11588
11645
|
}
|
|
11589
11646
|
catch (err) {
|
|
11590
|
-
|
|
11647
|
+
log.error('Failed to fetch config:', err);
|
|
11591
11648
|
setConfig(customization || {});
|
|
11592
11649
|
}
|
|
11593
11650
|
finally {
|
|
@@ -11595,7 +11652,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11595
11652
|
}
|
|
11596
11653
|
};
|
|
11597
11654
|
fetchConfig();
|
|
11598
|
-
}, [apiEndpoint, clientId, customization, skipConfigFetch]);
|
|
11655
|
+
}, [apiEndpoint, clientId, customization, skipConfigFetch, log]);
|
|
11599
11656
|
// Reset showEmailForm when mode changes away from login/register
|
|
11600
11657
|
React.useEffect(() => {
|
|
11601
11658
|
if (mode !== 'login' && mode !== 'register') {
|
|
@@ -11620,7 +11677,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11620
11677
|
const params = getUrlParams();
|
|
11621
11678
|
const urlMode = params.get('mode');
|
|
11622
11679
|
const token = params.get('token');
|
|
11623
|
-
|
|
11680
|
+
log.log('URL params detected:', { urlMode, token, hash: window.location.hash, search: window.location.search });
|
|
11624
11681
|
if (urlMode && token) {
|
|
11625
11682
|
handleURLBasedAuth(urlMode, token);
|
|
11626
11683
|
}
|
|
@@ -11630,7 +11687,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11630
11687
|
setError(undefined);
|
|
11631
11688
|
try {
|
|
11632
11689
|
if (urlMode === 'verifyEmail') {
|
|
11633
|
-
|
|
11690
|
+
log.log('Verifying email with token:', token);
|
|
11634
11691
|
const response = await api.verifyEmailWithToken(token);
|
|
11635
11692
|
// Get email verification mode from response or config
|
|
11636
11693
|
const verificationMode = response.emailVerificationMode || config?.emailVerification?.mode || 'verify-then-auto-login';
|
|
@@ -11665,7 +11722,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11665
11722
|
}
|
|
11666
11723
|
}
|
|
11667
11724
|
else if (urlMode === 'resetPassword') {
|
|
11668
|
-
|
|
11725
|
+
log.log('Verifying reset token:', token);
|
|
11669
11726
|
// Verify token is valid, then show password reset form
|
|
11670
11727
|
await api.verifyResetToken(token);
|
|
11671
11728
|
setResetToken(token); // Store token for use in password reset
|
|
@@ -11675,7 +11732,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11675
11732
|
window.history.replaceState({}, document.title, cleanUrl);
|
|
11676
11733
|
}
|
|
11677
11734
|
else if (urlMode === 'magicLink') {
|
|
11678
|
-
|
|
11735
|
+
log.log('Verifying magic link token:', token);
|
|
11679
11736
|
const response = await api.verifyMagicLink(token);
|
|
11680
11737
|
// Auto-login with magic link if token is provided
|
|
11681
11738
|
if (response.token) {
|
|
@@ -11699,7 +11756,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
11699
11756
|
}
|
|
11700
11757
|
}
|
|
11701
11758
|
catch (err) {
|
|
11702
|
-
|
|
11759
|
+
log.error('URL-based auth error:', err);
|
|
11703
11760
|
const errorMessage = err instanceof Error ? err.message : 'An error occurred';
|
|
11704
11761
|
// If it's an email verification error (expired/invalid token), show resend option
|
|
11705
11762
|
if (urlMode === 'verifyEmail') {
|