@proveanything/smartlinks-auth-ui 0.1.29 → 0.1.31
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/components/SmartlinksAuthUI.d.ts.map +1 -1
- package/dist/index.esm.js +184 -33
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +184 -33
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAW5D,OAAO,KAAK,EAAE,qBAAqB,EAAuD,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"SmartlinksAuthUI.d.ts","sourceRoot":"","sources":["../../src/components/SmartlinksAuthUI.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAW5D,OAAO,KAAK,EAAE,qBAAqB,EAAuD,MAAM,UAAU,CAAC;AA4I3G,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA6zC5D,CAAC"}
|
package/dist/index.esm.js
CHANGED
|
@@ -12192,25 +12192,51 @@ const loadGoogleIdentityServices = () => {
|
|
|
12192
12192
|
// Helper to detect WebView environments (Android/iOS)
|
|
12193
12193
|
const detectWebView = () => {
|
|
12194
12194
|
const ua = navigator.userAgent;
|
|
12195
|
+
console.log('[SmartlinksAuthUI] 🔍 detectWebView checking UA:', ua);
|
|
12195
12196
|
// Android WebView detection
|
|
12196
12197
|
if (/Android/i.test(ua)) {
|
|
12198
|
+
console.log('[SmartlinksAuthUI] 🔍 Android device detected');
|
|
12197
12199
|
// Modern Android WebViews include "wv" in UA string
|
|
12198
|
-
if (/\bwv\b/i.test(ua))
|
|
12200
|
+
if (/\bwv\b/i.test(ua)) {
|
|
12201
|
+
console.log('[SmartlinksAuthUI] ✅ Android WebView detected (wv in UA)');
|
|
12199
12202
|
return true;
|
|
12203
|
+
}
|
|
12200
12204
|
// Check for legacy Android bridge
|
|
12201
|
-
if (typeof window.Android !== 'undefined')
|
|
12205
|
+
if (typeof window.Android !== 'undefined') {
|
|
12206
|
+
console.log('[SmartlinksAuthUI] ✅ Android WebView detected (Android bridge exists)');
|
|
12202
12207
|
return true;
|
|
12208
|
+
}
|
|
12209
|
+
console.log('[SmartlinksAuthUI] ❌ Android but not WebView');
|
|
12203
12210
|
}
|
|
12204
12211
|
// iOS WKWebView detection
|
|
12205
12212
|
if (/iPhone|iPad|iPod/i.test(ua)) {
|
|
12213
|
+
console.log('[SmartlinksAuthUI] 🔍 iOS device detected');
|
|
12206
12214
|
const hasWebKitHandlers = !!window.webkit?.messageHandlers;
|
|
12207
12215
|
const isSafari = !!window.safari;
|
|
12216
|
+
console.log('[SmartlinksAuthUI] 🔍 iOS check:', { hasWebKitHandlers, isSafari });
|
|
12208
12217
|
// WKWebView has webkit handlers but no safari object
|
|
12209
|
-
if (hasWebKitHandlers && !isSafari)
|
|
12218
|
+
if (hasWebKitHandlers && !isSafari) {
|
|
12219
|
+
console.log('[SmartlinksAuthUI] ✅ iOS WKWebView detected');
|
|
12210
12220
|
return true;
|
|
12221
|
+
}
|
|
12222
|
+
console.log('[SmartlinksAuthUI] ❌ iOS but not WKWebView (likely Safari)');
|
|
12211
12223
|
}
|
|
12224
|
+
console.log('[SmartlinksAuthUI] ❌ Not a WebView environment');
|
|
12212
12225
|
return false;
|
|
12213
12226
|
};
|
|
12227
|
+
// Helper to detect native bridge for Google Sign-In delegation
|
|
12228
|
+
// Android apps can expose SmartlinksNative.signInWithGoogle() to handle OAuth natively
|
|
12229
|
+
const getNativeBridge = () => {
|
|
12230
|
+
console.log('[SmartlinksAuthUI] 🔍 getNativeBridge checking for SmartlinksNative...');
|
|
12231
|
+
console.log('[SmartlinksAuthUI] 🔍 window.SmartlinksNative:', window.SmartlinksNative);
|
|
12232
|
+
const native = window.SmartlinksNative;
|
|
12233
|
+
if (native?.signInWithGoogle) {
|
|
12234
|
+
console.log('[SmartlinksAuthUI] ✅ Native bridge found! SmartlinksNative.signInWithGoogle is available');
|
|
12235
|
+
return native;
|
|
12236
|
+
}
|
|
12237
|
+
console.log('[SmartlinksAuthUI] ❌ No native bridge found (SmartlinksNative.signInWithGoogle not available)');
|
|
12238
|
+
return null;
|
|
12239
|
+
};
|
|
12214
12240
|
// Helper to convert generic SDK errors to user-friendly messages
|
|
12215
12241
|
const getFriendlyErrorMessage = (errorMessage) => {
|
|
12216
12242
|
// Check for common HTTP status codes in the error message
|
|
@@ -12238,7 +12264,7 @@ const getFriendlyErrorMessage = (errorMessage) => {
|
|
|
12238
12264
|
// Return original message if no pattern matches
|
|
12239
12265
|
return errorMessage;
|
|
12240
12266
|
};
|
|
12241
|
-
const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'auto', className, customization, skipConfigFetch = false, minimal = false, logger, proxyMode = false, collectionId, }) => {
|
|
12267
|
+
const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAuthSuccess, onAuthError, enabledProviders = ['email', 'google', 'phone'], initialMode = 'login', redirectUrl, theme = 'auto', className, customization, skipConfigFetch = false, minimal = false, logger, proxyMode = false, collectionId, disableConfigCache = false, }) => {
|
|
12242
12268
|
const [mode, setMode] = useState(initialMode);
|
|
12243
12269
|
const [loading, setLoading] = useState(false);
|
|
12244
12270
|
const [error, setError] = useState();
|
|
@@ -12379,31 +12405,38 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12379
12405
|
return;
|
|
12380
12406
|
}
|
|
12381
12407
|
try {
|
|
12382
|
-
// Check localStorage cache first
|
|
12383
12408
|
const cacheKey = `auth_ui_config_${clientId}`;
|
|
12384
|
-
|
|
12385
|
-
if (
|
|
12386
|
-
const
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
console.log('[SmartlinksAuthUI]
|
|
12397
|
-
|
|
12398
|
-
config
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12409
|
+
// Check localStorage cache first (unless caching is disabled)
|
|
12410
|
+
if (!disableConfigCache) {
|
|
12411
|
+
const cached = localStorage.getItem(cacheKey);
|
|
12412
|
+
if (cached) {
|
|
12413
|
+
const { config: cachedConfig, timestamp } = JSON.parse(cached);
|
|
12414
|
+
const age = Date.now() - timestamp;
|
|
12415
|
+
// Use cache if less than 1 hour old
|
|
12416
|
+
if (age < 3600000) {
|
|
12417
|
+
console.log('[SmartlinksAuthUI] 📦 Using cached config (age:', Math.round(age / 1000), 'seconds)');
|
|
12418
|
+
setConfig({ ...cachedConfig, ...customization });
|
|
12419
|
+
setConfigLoading(false);
|
|
12420
|
+
// Fetch in background to update cache
|
|
12421
|
+
console.log('[SmartlinksAuthUI] 🔄 Background refresh of config via SDK...');
|
|
12422
|
+
api.fetchConfig().then(freshConfig => {
|
|
12423
|
+
console.log('[SmartlinksAuthUI] ✅ Background config refresh complete');
|
|
12424
|
+
localStorage.setItem(cacheKey, JSON.stringify({
|
|
12425
|
+
config: freshConfig,
|
|
12426
|
+
timestamp: Date.now()
|
|
12427
|
+
}));
|
|
12428
|
+
// Update config if it changed
|
|
12429
|
+
setConfig({ ...freshConfig, ...customization });
|
|
12430
|
+
}).catch(err => {
|
|
12431
|
+
console.log('[SmartlinksAuthUI] ❌ Background config refresh failed:', err);
|
|
12432
|
+
});
|
|
12433
|
+
return;
|
|
12434
|
+
}
|
|
12405
12435
|
}
|
|
12406
12436
|
}
|
|
12437
|
+
else {
|
|
12438
|
+
console.log('[SmartlinksAuthUI] ⚠️ Config caching disabled, fetching fresh config');
|
|
12439
|
+
}
|
|
12407
12440
|
// Fetch from API
|
|
12408
12441
|
console.log('[SmartlinksAuthUI] 🌐 Fetching config via SDK for clientId:', clientId, 'proxyMode:', proxyMode);
|
|
12409
12442
|
log.log('Fetching config from API for clientId:', clientId);
|
|
@@ -12413,11 +12446,13 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12413
12446
|
// Merge with customization props (props take precedence)
|
|
12414
12447
|
const mergedConfig = { ...fetchedConfig, ...customization };
|
|
12415
12448
|
setConfig(mergedConfig);
|
|
12416
|
-
// Cache the fetched config
|
|
12417
|
-
|
|
12418
|
-
|
|
12419
|
-
|
|
12420
|
-
|
|
12449
|
+
// Cache the fetched config (unless caching is disabled)
|
|
12450
|
+
if (!disableConfigCache) {
|
|
12451
|
+
localStorage.setItem(cacheKey, JSON.stringify({
|
|
12452
|
+
config: fetchedConfig,
|
|
12453
|
+
timestamp: Date.now()
|
|
12454
|
+
}));
|
|
12455
|
+
}
|
|
12421
12456
|
}
|
|
12422
12457
|
catch (err) {
|
|
12423
12458
|
console.log('[SmartlinksAuthUI] ❌ Config fetch failed:', err);
|
|
@@ -12779,19 +12814,35 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12779
12814
|
}
|
|
12780
12815
|
};
|
|
12781
12816
|
const handleGoogleLogin = async () => {
|
|
12817
|
+
console.log('[SmartlinksAuthUI] 🚀 handleGoogleLogin called');
|
|
12782
12818
|
// Use custom client ID from config, or fall back to default Smartlinks client ID
|
|
12783
12819
|
const googleClientId = config?.googleClientId || DEFAULT_GOOGLE_CLIENT_ID;
|
|
12784
12820
|
// Determine OAuth flow: default to 'oneTap' for better UX, but allow 'popup' for iframe compatibility
|
|
12785
12821
|
const configuredFlow = config?.googleOAuthFlow || 'oneTap';
|
|
12786
|
-
//
|
|
12822
|
+
// Check for native bridge and WebView environment
|
|
12823
|
+
console.log('[SmartlinksAuthUI] 🔍 Checking environment...');
|
|
12787
12824
|
const isWebView = detectWebView();
|
|
12788
|
-
const
|
|
12825
|
+
const nativeBridge = getNativeBridge();
|
|
12826
|
+
// For oneTap, automatically use redirect flow in WebView environments (if no native bridge)
|
|
12827
|
+
const oauthFlow = (configuredFlow === 'oneTap' && isWebView && !nativeBridge) ? 'redirect' : configuredFlow;
|
|
12789
12828
|
// Log Google Auth configuration for debugging
|
|
12829
|
+
console.log('[SmartlinksAuthUI] 📋 Google Auth configuration:', {
|
|
12830
|
+
googleClientId,
|
|
12831
|
+
configuredFlow,
|
|
12832
|
+
effectiveFlow: oauthFlow,
|
|
12833
|
+
isWebView,
|
|
12834
|
+
hasNativeBridge: !!nativeBridge,
|
|
12835
|
+
currentOrigin: window.location.origin,
|
|
12836
|
+
currentHref: window.location.href,
|
|
12837
|
+
configGoogleClientId: config?.googleClientId,
|
|
12838
|
+
usingDefaultClientId: !config?.googleClientId,
|
|
12839
|
+
});
|
|
12790
12840
|
log.log('Google Auth initiated:', {
|
|
12791
12841
|
googleClientId,
|
|
12792
12842
|
configuredFlow,
|
|
12793
12843
|
effectiveFlow: oauthFlow,
|
|
12794
12844
|
isWebView,
|
|
12845
|
+
hasNativeBridge: !!nativeBridge,
|
|
12795
12846
|
currentOrigin: window.location.origin,
|
|
12796
12847
|
currentHref: window.location.href,
|
|
12797
12848
|
configGoogleClientId: config?.googleClientId,
|
|
@@ -12800,6 +12851,106 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12800
12851
|
setLoading(true);
|
|
12801
12852
|
setError(undefined);
|
|
12802
12853
|
try {
|
|
12854
|
+
// Priority 1: Use native bridge if available (for WebView environments)
|
|
12855
|
+
if (nativeBridge) {
|
|
12856
|
+
console.log('[SmartlinksAuthUI] 🌉 NATIVE BRIDGE PATH - Using native bridge for Google Sign-In');
|
|
12857
|
+
log.log('Using native bridge for Google Sign-In');
|
|
12858
|
+
const callbackId = `google_auth_${Date.now()}`;
|
|
12859
|
+
console.log('[SmartlinksAuthUI] 🔑 Generated callbackId:', callbackId);
|
|
12860
|
+
// Set up callback for native response
|
|
12861
|
+
console.log('[SmartlinksAuthUI] 📡 Registering window.smartlinksNativeCallback...');
|
|
12862
|
+
window.smartlinksNativeCallback = async (result) => {
|
|
12863
|
+
console.log('[SmartlinksAuthUI] 📨 smartlinksNativeCallback INVOKED with:', {
|
|
12864
|
+
callbackId: result.callbackId,
|
|
12865
|
+
success: result.success,
|
|
12866
|
+
hasIdToken: !!result.idToken,
|
|
12867
|
+
idTokenLength: result.idToken?.length,
|
|
12868
|
+
email: result.email,
|
|
12869
|
+
name: result.name,
|
|
12870
|
+
error: result.error,
|
|
12871
|
+
errorCode: result.errorCode,
|
|
12872
|
+
});
|
|
12873
|
+
// Ignore stale callbacks
|
|
12874
|
+
if (result.callbackId !== callbackId) {
|
|
12875
|
+
console.log('[SmartlinksAuthUI] ⚠️ Ignoring stale callback. Expected:', callbackId, 'Got:', result.callbackId);
|
|
12876
|
+
log.log('Ignoring stale native callback:', result.callbackId);
|
|
12877
|
+
return;
|
|
12878
|
+
}
|
|
12879
|
+
console.log('[SmartlinksAuthUI] ✅ Callback ID matches, processing result...');
|
|
12880
|
+
log.log('Native callback received:', {
|
|
12881
|
+
success: result.success,
|
|
12882
|
+
hasIdToken: !!result.idToken,
|
|
12883
|
+
email: result.email,
|
|
12884
|
+
error: result.error,
|
|
12885
|
+
errorCode: result.errorCode,
|
|
12886
|
+
});
|
|
12887
|
+
try {
|
|
12888
|
+
if (result.success && result.idToken) {
|
|
12889
|
+
console.log('[SmartlinksAuthUI] 🔐 Success! Calling api.loginWithGoogle with idToken...');
|
|
12890
|
+
// Process through existing Google auth flow
|
|
12891
|
+
const authResponse = await api.loginWithGoogle(result.idToken);
|
|
12892
|
+
console.log('[SmartlinksAuthUI] 📦 api.loginWithGoogle response:', {
|
|
12893
|
+
hasToken: !!authResponse.token,
|
|
12894
|
+
hasUser: !!authResponse.user,
|
|
12895
|
+
isNewUser: authResponse.isNewUser,
|
|
12896
|
+
});
|
|
12897
|
+
if (authResponse.token) {
|
|
12898
|
+
console.log('[SmartlinksAuthUI] 🎉 Login successful! Calling auth.login and onAuthSuccess...');
|
|
12899
|
+
auth.login(authResponse.token, authResponse.user, authResponse.accountData, authResponse.isNewUser, getExpirationFromResponse(authResponse));
|
|
12900
|
+
setAuthSuccess(true);
|
|
12901
|
+
setSuccessMessage('Google login successful!');
|
|
12902
|
+
onAuthSuccess(authResponse.token, authResponse.user, authResponse.accountData);
|
|
12903
|
+
}
|
|
12904
|
+
else {
|
|
12905
|
+
console.log('[SmartlinksAuthUI] ❌ No token in authResponse');
|
|
12906
|
+
throw new Error('Authentication failed - no token received');
|
|
12907
|
+
}
|
|
12908
|
+
}
|
|
12909
|
+
else {
|
|
12910
|
+
// Handle error from native
|
|
12911
|
+
console.log('[SmartlinksAuthUI] ❌ Native returned error:', result.error, result.errorCode);
|
|
12912
|
+
const errorMessage = result.error || 'Google Sign-In failed';
|
|
12913
|
+
setError(errorMessage);
|
|
12914
|
+
onAuthError?.(new Error(errorMessage));
|
|
12915
|
+
}
|
|
12916
|
+
}
|
|
12917
|
+
catch (err) {
|
|
12918
|
+
console.log('[SmartlinksAuthUI] 💥 Exception in callback handler:', err);
|
|
12919
|
+
const errorMessage = err instanceof Error ? err.message : 'Google login failed';
|
|
12920
|
+
setError(errorMessage);
|
|
12921
|
+
onAuthError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
12922
|
+
}
|
|
12923
|
+
finally {
|
|
12924
|
+
console.log('[SmartlinksAuthUI] 🏁 Callback processing complete, setting loading=false');
|
|
12925
|
+
setLoading(false);
|
|
12926
|
+
}
|
|
12927
|
+
};
|
|
12928
|
+
console.log('[SmartlinksAuthUI] ✅ window.smartlinksNativeCallback registered');
|
|
12929
|
+
// Invoke native sign-in
|
|
12930
|
+
const payload = JSON.stringify({
|
|
12931
|
+
type: 'GOOGLE_SIGN_IN',
|
|
12932
|
+
clientId,
|
|
12933
|
+
googleClientId,
|
|
12934
|
+
callbackId,
|
|
12935
|
+
});
|
|
12936
|
+
console.log('[SmartlinksAuthUI] 📤 Calling nativeBridge.signInWithGoogle with payload:', payload);
|
|
12937
|
+
log.log('Invoking native signInWithGoogle with payload:', payload);
|
|
12938
|
+
nativeBridge.signInWithGoogle(payload);
|
|
12939
|
+
console.log('[SmartlinksAuthUI] ✅ nativeBridge.signInWithGoogle called successfully');
|
|
12940
|
+
console.log('[SmartlinksAuthUI] ⏳ Waiting for native callback...');
|
|
12941
|
+
// Don't set loading to false - waiting for native callback
|
|
12942
|
+
return;
|
|
12943
|
+
}
|
|
12944
|
+
// Priority 2: If WebView but no native bridge, show helpful error
|
|
12945
|
+
if (isWebView) {
|
|
12946
|
+
console.log('[SmartlinksAuthUI] ⚠️ WebView detected but NO native bridge - showing error');
|
|
12947
|
+
log.log('WebView detected but no native bridge available');
|
|
12948
|
+
setError('Google Sign-In is not available in this app. Please use email or phone login instead.');
|
|
12949
|
+
setLoading(false);
|
|
12950
|
+
return;
|
|
12951
|
+
}
|
|
12952
|
+
console.log('[SmartlinksAuthUI] 🌐 WEB PATH - Using web-based OAuth flow:', oauthFlow);
|
|
12953
|
+
// Priority 3: Web-based flows (redirect, popup, oneTap)
|
|
12803
12954
|
// Dynamically load Google Identity Services if not already loaded
|
|
12804
12955
|
await loadGoogleIdentityServices();
|
|
12805
12956
|
const google = window.google;
|