@proveanything/smartlinks-auth-ui 0.1.28 → 0.1.30
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 +1 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/components/SmartlinksAuthUI.d.ts.map +1 -1
- package/dist/index.esm.js +158 -36
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +158 -36
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +13 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export declare class AuthAPI {
|
|
|
19
19
|
};
|
|
20
20
|
tokenType?: 'id_token' | 'access_token';
|
|
21
21
|
}): Promise<AuthResponse>;
|
|
22
|
+
loginWithGoogleCode(code: string, redirectUri: string): Promise<AuthResponse>;
|
|
22
23
|
sendPhoneCode(phoneNumber: string): Promise<{
|
|
23
24
|
verificationId: string;
|
|
24
25
|
}>;
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGpF;;;GAGG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAyC;gBAExC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU;IAQtF,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI7D,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAWnD,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAC7C,cAAc,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACjF,SAAS,CAAC,EAAE,UAAU,GAAG,cAAc,CAAC;KACzC,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBnB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAc7E,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAIvE,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,YAAY,CAAC;IAIlB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAQxG,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAIlH,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAIzG,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IASzH,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAIhF,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAStH,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC;IA2BpC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAOjG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAGlF"}
|
|
@@ -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;AA4G3G,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAsrC5D,CAAC"}
|
package/dist/index.esm.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import React, { useEffect, useState, useMemo, useRef, useCallback, createContext, useContext } from 'react';
|
|
3
3
|
import * as smartlinks from '@proveanything/smartlinks';
|
|
4
4
|
import { iframe } from '@proveanything/smartlinks';
|
|
5
|
+
import { post } from '@proveanything/smartlinks/dist/http';
|
|
5
6
|
|
|
6
7
|
const AuthContainer = ({ children, theme = 'light', className = '', config, minimal = false, }) => {
|
|
7
8
|
// Apply CSS variables for customization
|
|
@@ -10789,6 +10790,18 @@ class AuthAPI {
|
|
|
10789
10790
|
// Pass token to SDK - backend verifies with Google
|
|
10790
10791
|
return smartlinks.authKit.googleLogin(this.clientId, token);
|
|
10791
10792
|
}
|
|
10793
|
+
async loginWithGoogleCode(code, redirectUri) {
|
|
10794
|
+
this.log.log('loginWithGoogleCode called:', {
|
|
10795
|
+
codeLength: code?.length,
|
|
10796
|
+
redirectUri,
|
|
10797
|
+
});
|
|
10798
|
+
// Exchange authorization code for tokens via backend
|
|
10799
|
+
// Use direct HTTP call since SDK may not have this method in authKit namespace yet
|
|
10800
|
+
return post(`/api/v1/authkit/${this.clientId}/google-code`, {
|
|
10801
|
+
code,
|
|
10802
|
+
redirectUri,
|
|
10803
|
+
});
|
|
10804
|
+
}
|
|
10792
10805
|
async sendPhoneCode(phoneNumber) {
|
|
10793
10806
|
return smartlinks.authKit.sendPhoneCode(this.clientId, phoneNumber);
|
|
10794
10807
|
}
|
|
@@ -12176,6 +12189,28 @@ const loadGoogleIdentityServices = () => {
|
|
|
12176
12189
|
document.head.appendChild(script);
|
|
12177
12190
|
});
|
|
12178
12191
|
};
|
|
12192
|
+
// Helper to detect WebView environments (Android/iOS)
|
|
12193
|
+
const detectWebView = () => {
|
|
12194
|
+
const ua = navigator.userAgent;
|
|
12195
|
+
// Android WebView detection
|
|
12196
|
+
if (/Android/i.test(ua)) {
|
|
12197
|
+
// Modern Android WebViews include "wv" in UA string
|
|
12198
|
+
if (/\bwv\b/i.test(ua))
|
|
12199
|
+
return true;
|
|
12200
|
+
// Check for legacy Android bridge
|
|
12201
|
+
if (typeof window.Android !== 'undefined')
|
|
12202
|
+
return true;
|
|
12203
|
+
}
|
|
12204
|
+
// iOS WKWebView detection
|
|
12205
|
+
if (/iPhone|iPad|iPod/i.test(ua)) {
|
|
12206
|
+
const hasWebKitHandlers = !!window.webkit?.messageHandlers;
|
|
12207
|
+
const isSafari = !!window.safari;
|
|
12208
|
+
// WKWebView has webkit handlers but no safari object
|
|
12209
|
+
if (hasWebKitHandlers && !isSafari)
|
|
12210
|
+
return true;
|
|
12211
|
+
}
|
|
12212
|
+
return false;
|
|
12213
|
+
};
|
|
12179
12214
|
// Helper to convert generic SDK errors to user-friendly messages
|
|
12180
12215
|
const getFriendlyErrorMessage = (errorMessage) => {
|
|
12181
12216
|
// Check for common HTTP status codes in the error message
|
|
@@ -12203,7 +12238,7 @@ const getFriendlyErrorMessage = (errorMessage) => {
|
|
|
12203
12238
|
// Return original message if no pattern matches
|
|
12204
12239
|
return errorMessage;
|
|
12205
12240
|
};
|
|
12206
|
-
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, }) => {
|
|
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, disableConfigCache = false, }) => {
|
|
12207
12242
|
const [mode, setMode] = useState(initialMode);
|
|
12208
12243
|
const [loading, setLoading] = useState(false);
|
|
12209
12244
|
const [error, setError] = useState();
|
|
@@ -12344,31 +12379,38 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12344
12379
|
return;
|
|
12345
12380
|
}
|
|
12346
12381
|
try {
|
|
12347
|
-
// Check localStorage cache first
|
|
12348
12382
|
const cacheKey = `auth_ui_config_${clientId}`;
|
|
12349
|
-
|
|
12350
|
-
if (
|
|
12351
|
-
const
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
console.log('[SmartlinksAuthUI]
|
|
12362
|
-
|
|
12363
|
-
config
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12383
|
+
// Check localStorage cache first (unless caching is disabled)
|
|
12384
|
+
if (!disableConfigCache) {
|
|
12385
|
+
const cached = localStorage.getItem(cacheKey);
|
|
12386
|
+
if (cached) {
|
|
12387
|
+
const { config: cachedConfig, timestamp } = JSON.parse(cached);
|
|
12388
|
+
const age = Date.now() - timestamp;
|
|
12389
|
+
// Use cache if less than 1 hour old
|
|
12390
|
+
if (age < 3600000) {
|
|
12391
|
+
console.log('[SmartlinksAuthUI] 📦 Using cached config (age:', Math.round(age / 1000), 'seconds)');
|
|
12392
|
+
setConfig({ ...cachedConfig, ...customization });
|
|
12393
|
+
setConfigLoading(false);
|
|
12394
|
+
// Fetch in background to update cache
|
|
12395
|
+
console.log('[SmartlinksAuthUI] 🔄 Background refresh of config via SDK...');
|
|
12396
|
+
api.fetchConfig().then(freshConfig => {
|
|
12397
|
+
console.log('[SmartlinksAuthUI] ✅ Background config refresh complete');
|
|
12398
|
+
localStorage.setItem(cacheKey, JSON.stringify({
|
|
12399
|
+
config: freshConfig,
|
|
12400
|
+
timestamp: Date.now()
|
|
12401
|
+
}));
|
|
12402
|
+
// Update config if it changed
|
|
12403
|
+
setConfig({ ...freshConfig, ...customization });
|
|
12404
|
+
}).catch(err => {
|
|
12405
|
+
console.log('[SmartlinksAuthUI] ❌ Background config refresh failed:', err);
|
|
12406
|
+
});
|
|
12407
|
+
return;
|
|
12408
|
+
}
|
|
12370
12409
|
}
|
|
12371
12410
|
}
|
|
12411
|
+
else {
|
|
12412
|
+
console.log('[SmartlinksAuthUI] ⚠️ Config caching disabled, fetching fresh config');
|
|
12413
|
+
}
|
|
12372
12414
|
// Fetch from API
|
|
12373
12415
|
console.log('[SmartlinksAuthUI] 🌐 Fetching config via SDK for clientId:', clientId, 'proxyMode:', proxyMode);
|
|
12374
12416
|
log.log('Fetching config from API for clientId:', clientId);
|
|
@@ -12378,11 +12420,13 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12378
12420
|
// Merge with customization props (props take precedence)
|
|
12379
12421
|
const mergedConfig = { ...fetchedConfig, ...customization };
|
|
12380
12422
|
setConfig(mergedConfig);
|
|
12381
|
-
// Cache the fetched config
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12423
|
+
// Cache the fetched config (unless caching is disabled)
|
|
12424
|
+
if (!disableConfigCache) {
|
|
12425
|
+
localStorage.setItem(cacheKey, JSON.stringify({
|
|
12426
|
+
config: fetchedConfig,
|
|
12427
|
+
timestamp: Date.now()
|
|
12428
|
+
}));
|
|
12429
|
+
}
|
|
12386
12430
|
}
|
|
12387
12431
|
catch (err) {
|
|
12388
12432
|
console.log('[SmartlinksAuthUI] ❌ Config fetch failed:', err);
|
|
@@ -12437,8 +12481,15 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12437
12481
|
const params = getUrlParams();
|
|
12438
12482
|
const urlMode = params.get('mode');
|
|
12439
12483
|
const token = params.get('token');
|
|
12440
|
-
|
|
12441
|
-
|
|
12484
|
+
// Check for Google OAuth redirect callback
|
|
12485
|
+
const authCode = params.get('code');
|
|
12486
|
+
const state = params.get('state');
|
|
12487
|
+
log.log('URL params detected:', { urlMode, token, authCode: !!authCode, state: !!state, hash: window.location.hash, search: window.location.search });
|
|
12488
|
+
if (authCode && state) {
|
|
12489
|
+
// Google OAuth redirect callback
|
|
12490
|
+
handleGoogleAuthCodeCallback(authCode, state);
|
|
12491
|
+
}
|
|
12492
|
+
else if (urlMode && token) {
|
|
12442
12493
|
handleURLBasedAuth(urlMode, token);
|
|
12443
12494
|
}
|
|
12444
12495
|
}, []);
|
|
@@ -12551,6 +12602,43 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12551
12602
|
setLoading(false);
|
|
12552
12603
|
}
|
|
12553
12604
|
};
|
|
12605
|
+
// Handle Google OAuth authorization code callback (from redirect flow)
|
|
12606
|
+
const handleGoogleAuthCodeCallback = async (code, stateParam) => {
|
|
12607
|
+
setLoading(true);
|
|
12608
|
+
setError(undefined);
|
|
12609
|
+
try {
|
|
12610
|
+
// Parse state to get context
|
|
12611
|
+
const state = JSON.parse(decodeURIComponent(stateParam));
|
|
12612
|
+
log.log('Google OAuth redirect callback:', { clientId: state.clientId, returnPath: state.returnPath });
|
|
12613
|
+
// Determine the redirect URI that was used (must match exactly)
|
|
12614
|
+
const redirectUri = state.redirectUri || window.location.origin + window.location.pathname;
|
|
12615
|
+
// Exchange authorization code for tokens
|
|
12616
|
+
const response = await api.loginWithGoogleCode(code, redirectUri);
|
|
12617
|
+
if (response.token) {
|
|
12618
|
+
auth.login(response.token, response.user, response.accountData, response.isNewUser, getExpirationFromResponse(response));
|
|
12619
|
+
setAuthSuccess(true);
|
|
12620
|
+
setSuccessMessage('Google login successful!');
|
|
12621
|
+
onAuthSuccess(response.token, response.user, response.accountData);
|
|
12622
|
+
}
|
|
12623
|
+
else {
|
|
12624
|
+
throw new Error('Authentication failed - no token received');
|
|
12625
|
+
}
|
|
12626
|
+
// Clean URL parameters
|
|
12627
|
+
const cleanUrl = window.location.origin + window.location.pathname + (state.returnPath?.includes('#') ? state.returnPath.split('?')[0] : window.location.hash.split('?')[0]);
|
|
12628
|
+
window.history.replaceState({}, document.title, cleanUrl);
|
|
12629
|
+
}
|
|
12630
|
+
catch (err) {
|
|
12631
|
+
const errorMessage = err instanceof Error ? err.message : 'Google login failed';
|
|
12632
|
+
setError(getFriendlyErrorMessage(errorMessage));
|
|
12633
|
+
onAuthError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
12634
|
+
// Clean URL parameters even on error
|
|
12635
|
+
const cleanUrl = window.location.origin + window.location.pathname + window.location.hash.split('?')[0];
|
|
12636
|
+
window.history.replaceState({}, document.title, cleanUrl);
|
|
12637
|
+
}
|
|
12638
|
+
finally {
|
|
12639
|
+
setLoading(false);
|
|
12640
|
+
}
|
|
12641
|
+
};
|
|
12554
12642
|
const handleEmailAuth = async (data) => {
|
|
12555
12643
|
setLoading(true);
|
|
12556
12644
|
setError(undefined);
|
|
@@ -12703,11 +12791,16 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12703
12791
|
// Use custom client ID from config, or fall back to default Smartlinks client ID
|
|
12704
12792
|
const googleClientId = config?.googleClientId || DEFAULT_GOOGLE_CLIENT_ID;
|
|
12705
12793
|
// Determine OAuth flow: default to 'oneTap' for better UX, but allow 'popup' for iframe compatibility
|
|
12706
|
-
const
|
|
12794
|
+
const configuredFlow = config?.googleOAuthFlow || 'oneTap';
|
|
12795
|
+
// For oneTap, automatically use redirect flow in WebView environments
|
|
12796
|
+
const isWebView = detectWebView();
|
|
12797
|
+
const oauthFlow = (configuredFlow === 'oneTap' && isWebView) ? 'redirect' : configuredFlow;
|
|
12707
12798
|
// Log Google Auth configuration for debugging
|
|
12708
12799
|
log.log('Google Auth initiated:', {
|
|
12709
12800
|
googleClientId,
|
|
12710
|
-
|
|
12801
|
+
configuredFlow,
|
|
12802
|
+
effectiveFlow: oauthFlow,
|
|
12803
|
+
isWebView,
|
|
12711
12804
|
currentOrigin: window.location.origin,
|
|
12712
12805
|
currentHref: window.location.href,
|
|
12713
12806
|
configGoogleClientId: config?.googleClientId,
|
|
@@ -12723,7 +12816,37 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12723
12816
|
throw new Error('Google Identity Services failed to initialize');
|
|
12724
12817
|
}
|
|
12725
12818
|
log.log('Google Identity Services loaded, using flow:', oauthFlow);
|
|
12726
|
-
if (oauthFlow === '
|
|
12819
|
+
if (oauthFlow === 'redirect') {
|
|
12820
|
+
// Use OAuth2 redirect flow (works in WebViews and everywhere)
|
|
12821
|
+
if (!google.accounts.oauth2) {
|
|
12822
|
+
throw new Error('Google OAuth2 not available');
|
|
12823
|
+
}
|
|
12824
|
+
// Build the redirect URI - use current URL without query params
|
|
12825
|
+
const redirectUri = getRedirectUrl();
|
|
12826
|
+
// Build state parameter to preserve context across redirect
|
|
12827
|
+
const state = encodeURIComponent(JSON.stringify({
|
|
12828
|
+
clientId,
|
|
12829
|
+
returnPath: window.location.hash || window.location.pathname,
|
|
12830
|
+
redirectUri,
|
|
12831
|
+
}));
|
|
12832
|
+
log.log('Initializing Google OAuth2 redirect flow:', {
|
|
12833
|
+
client_id: googleClientId,
|
|
12834
|
+
scope: 'openid email profile',
|
|
12835
|
+
redirect_uri: redirectUri,
|
|
12836
|
+
state,
|
|
12837
|
+
});
|
|
12838
|
+
const client = google.accounts.oauth2.initCodeClient({
|
|
12839
|
+
client_id: googleClientId,
|
|
12840
|
+
scope: 'openid email profile',
|
|
12841
|
+
ux_mode: 'redirect',
|
|
12842
|
+
redirect_uri: redirectUri,
|
|
12843
|
+
state,
|
|
12844
|
+
});
|
|
12845
|
+
// This will navigate away from the page
|
|
12846
|
+
client.requestCode();
|
|
12847
|
+
return; // Don't set loading to false - we're navigating away
|
|
12848
|
+
}
|
|
12849
|
+
else if (oauthFlow === 'popup') {
|
|
12727
12850
|
// Use OAuth2 popup flow (works in iframes but requires popup permission)
|
|
12728
12851
|
if (!google.accounts.oauth2) {
|
|
12729
12852
|
throw new Error('Google OAuth2 not available');
|
|
@@ -12814,7 +12937,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12814
12937
|
client.requestAccessToken();
|
|
12815
12938
|
}
|
|
12816
12939
|
else {
|
|
12817
|
-
// Use One Tap / Sign-In button flow (smoother UX but doesn't work in iframes)
|
|
12940
|
+
// Use One Tap / Sign-In button flow (smoother UX but doesn't work in iframes or WebViews)
|
|
12818
12941
|
log.log('Initializing Google OneTap flow:', {
|
|
12819
12942
|
client_id: googleClientId,
|
|
12820
12943
|
origin: window.location.origin,
|
|
@@ -12847,8 +12970,7 @@ const SmartlinksAuthUI = ({ apiEndpoint, clientId, clientName, accountData, onAu
|
|
|
12847
12970
|
},
|
|
12848
12971
|
auto_select: false,
|
|
12849
12972
|
cancel_on_tap_outside: true,
|
|
12850
|
-
|
|
12851
|
-
// Will be needed when FedCM becomes mandatory in the future
|
|
12973
|
+
use_fedcm_for_prompt: true, // Enable FedCM for future browser compatibility
|
|
12852
12974
|
});
|
|
12853
12975
|
// Use timeout fallback instead of deprecated notification methods
|
|
12854
12976
|
// (isNotDisplayed/isSkippedMoment will stop working when FedCM becomes mandatory)
|