@agent-native/core 0.20.6 → 0.20.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/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +25 -1
- package/dist/server/auth.js.map +1 -1
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +12 -4
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +12 -4
- package/dist/server/onboarding-html.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-auth-plugin.d.ts","sourceRoot":"","sources":["../../src/server/google-auth-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAE/B,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9D,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"google-auth-plugin.d.ts","sourceRoot":"","sources":["../../src/server/google-auth-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAE/B,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9D,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AA2bD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,CAAC,EAAE,uBAAuB,GAChC,cAAc,CAYhB"}
|
|
@@ -300,6 +300,13 @@ function getGoogleLoginHtml(googleAuthMode) {
|
|
|
300
300
|
err.classList.add('show');
|
|
301
301
|
btn.disabled = false;
|
|
302
302
|
}
|
|
303
|
+
function __anHandlePopupOAuthFailure(ret, btn, err, flowId, redirectReason, builderFrameMessage) {
|
|
304
|
+
if (__anIsBuilderPreview() && __anIsInFrame()) {
|
|
305
|
+
__anShowOAuthError(err, btn, builderFrameMessage + ' Allow popups for this site and try again (flow ' + __anFlowDebugId(flowId) + ').');
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
__anStartRedirectOAuth(ret, btn, err, flowId, redirectReason);
|
|
309
|
+
}
|
|
303
310
|
function __anStartRedirectOAuth(ret, btn, err, flowId, reason) {
|
|
304
311
|
var params = new URLSearchParams();
|
|
305
312
|
var oauthReturn = __anIsBuilderPreview() ? __anOAuthReturnTarget(ret) : ret;
|
|
@@ -362,7 +369,7 @@ function getGoogleLoginHtml(googleAuthMode) {
|
|
|
362
369
|
try {
|
|
363
370
|
var popup = window.open('', '_blank', 'width=640,height=760');
|
|
364
371
|
if (!popup) {
|
|
365
|
-
|
|
372
|
+
__anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Google popup was blocked; falling back to redirect', 'Google popup was blocked.');
|
|
366
373
|
return;
|
|
367
374
|
}
|
|
368
375
|
try { popup.opener = null; } catch(e) {}
|
|
@@ -370,12 +377,12 @@ function getGoogleLoginHtml(googleAuthMode) {
|
|
|
370
377
|
popup.location.href = url;
|
|
371
378
|
} catch(e) {
|
|
372
379
|
try { popup.close(); } catch(closeErr) {}
|
|
373
|
-
|
|
380
|
+
__anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Could not navigate Google popup; falling back to redirect', 'Could not navigate Google popup.');
|
|
374
381
|
return;
|
|
375
382
|
}
|
|
376
383
|
__anSetOAuthDebug('Google popup opened; waiting for callback', flowId);
|
|
377
384
|
} catch(e) {
|
|
378
|
-
|
|
385
|
+
__anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Could not open Google popup; falling back to redirect', 'Could not open Google popup.');
|
|
379
386
|
return;
|
|
380
387
|
}
|
|
381
388
|
__anWaitForOAuthExchange(flowId, ret, btn, err);
|
|
@@ -411,7 +418,8 @@ function getGoogleLoginHtml(googleAuthMode) {
|
|
|
411
418
|
return;
|
|
412
419
|
}
|
|
413
420
|
if (__anIsBuilderPreview()) {
|
|
414
|
-
|
|
421
|
+
var flowId = __anNewOAuthFlowId();
|
|
422
|
+
__anStartRedirectOAuth(ret, btn, err, flowId, 'Opening Google sign-in redirect from Builder preview');
|
|
415
423
|
return;
|
|
416
424
|
}
|
|
417
425
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-auth-plugin.js","sourceRoot":"","sources":["../../src/server/google-auth-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EACL,qBAAqB,GAEtB,MAAM,uBAAuB,CAAC;AAgB/B,SAAS,kBAAkB,CAAC,cAA8B;IACxD,MAAM,iBAAiB,GAAG,oBAAoB,EAAE,CAAC;IACjD,MAAM,4BAA4B,GAAG,+BAA+B,EAAE,CAAC;IACvE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCA+E0B,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC;+CACrB,IAAI,CAAC,SAAS,CAAC,4BAA4B,CAAC;gCAC3D,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA0VtD,CAAC;AACT,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAiC;IAEjC,OAAO,gBAAgB,CAAC;QACtB,WAAW,EAAE;YACX,gCAAgC;YAChC,gCAAgC;YAChC,wBAAwB;YACxB,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC;SAChC;QACD,SAAS,EAAE,kBAAkB,CAC3B,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC,CAC/C;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { createAuthPlugin } from \"./auth-plugin.js\";\nimport { getPublicOAuthOrigin } from \"./oauth-public-origin.js\";\nimport { getWorkspaceGatewayReturnOrigin } from \"./oauth-return-url.js\";\nimport {\n resolveGoogleAuthMode,\n type GoogleAuthMode,\n} from \"./google-auth-mode.js\";\n\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\n\nexport interface GoogleAuthPluginOptions {\n /** Additional paths accessible without authentication */\n publicPaths?: string[];\n /**\n * Google sign-in flow: `'popup'`, `'redirect'`, or `'auto'` (default).\n * Falls back to `GOOGLE_AUTH_MODE` env var, then `'auto'`. Builder\n * iframes use popup; top-level Builder preview/editor surfaces use\n * redirect.\n */\n googleAuthMode?: GoogleAuthMode;\n}\n\nfunction getGoogleLoginHtml(googleAuthMode: GoogleAuthMode): string {\n const publicOAuthOrigin = getPublicOAuthOrigin();\n const workspaceGatewayReturnOrigin = getWorkspaceGatewayReturnOrigin();\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\">\n<title>Sign in</title>\n<style>\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n background: #0a0a0a;\n color: #e5e5e5;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n }\n .card {\n width: 100%;\n max-width: 360px;\n padding: 2rem;\n background: #141414;\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 12px;\n text-align: center;\n }\n h1 { font-size: 1.125rem; font-weight: 600; margin-bottom: 0.5rem; color: #fff; }\n .subtitle { font-size: 0.8125rem; color: #888; margin-bottom: 1.5rem; }\n button {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n padding: 0.625rem;\n background: #fff;\n color: #000;\n border: none;\n border-radius: 8px;\n font-size: 0.9375rem;\n font-weight: 500;\n cursor: pointer;\n }\n button:hover { opacity: 0.85; }\n button:disabled { opacity: 0.5; cursor: wait; }\n .error { margin-top: 0.75rem; font-size: 0.8125rem; color: #f87171; display: none; }\n .error.show { display: block; }\n .debug {\n display: none;\n margin-top: 0.625rem;\n font-size: 0.6875rem;\n line-height: 1.45;\n color: #777;\n word-break: break-word;\n }\n .debug.show { display: block; }\n svg { width: 18px; height: 18px; }\n</style>\n</head>\n<body>\n<div class=\"card\">\n <h1>Sign in</h1>\n <p class=\"subtitle\">Continue with your Google account</p>\n <button id=\"btn\" onclick=\"signIn()\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z\"/><path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/><path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/><path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/></svg>\n Sign in with Google\n </button>\n <p class=\"error\" id=\"err\"></p>\n <p class=\"debug\" id=\"debug\"></p>\n</div>\n<script>\n function __anBasePath() {\n var marker = '/_agent-native';\n var idx = window.location.pathname.indexOf(marker);\n return idx > 0 ? window.location.pathname.slice(0, idx) : '';\n }\n function __anPath(path) {\n return __anBasePath() + path;\n }\n var __AN_PUBLIC_OAUTH_ORIGIN = ${JSON.stringify(publicOAuthOrigin)};\n var __AN_WORKSPACE_GATEWAY_RETURN_ORIGIN = ${JSON.stringify(workspaceGatewayReturnOrigin)};\n var __AN_GOOGLE_AUTH_MODE = ${JSON.stringify(googleAuthMode)};\n function __anConfiguredOAuthOrigin() {\n if (!__AN_PUBLIC_OAUTH_ORIGIN) return '';\n try {\n var origin = new URL(__AN_PUBLIC_OAUTH_ORIGIN).origin;\n return origin && origin !== window.location.origin ? origin : '';\n } catch(e) {\n return '';\n }\n }\n function __anAuthPath(path) {\n var origin = __anIsBuilderPreview() ? __anConfiguredOAuthOrigin() : '';\n return origin ? origin + path : __anPath(path);\n }\n function __anGoogleAuthUrlPath() {\n return __anIsBuilderPreview()\n ? __anAuthPath('/_agent-native/google/auth-url')\n : __anPath('/_agent-native/google/auth-url');\n }\n function __anBuilderPreviewReturnOrigin() {\n var candidates = [window.location.href, document.referrer || ''];\n try {\n if (window.location.ancestorOrigins) {\n for (var j = 0; j < window.location.ancestorOrigins.length; j++) {\n candidates.push(window.location.ancestorOrigins[j]);\n }\n }\n } catch(e) {}\n for (var i = 0; i < candidates.length; i++) {\n try {\n var url = new URL(candidates[i]);\n var host = url.hostname.toLowerCase();\n var isPreviewHost =\n host === 'builderio.xyz' || host.slice(-14) === '.builderio.xyz' ||\n host === 'builderio.dev' || host.slice(-14) === '.builderio.dev' ||\n host === 'builder.codes' || host.slice(-14) === '.builder.codes' ||\n host === 'builder.my' || host.slice(-11) === '.builder.my';\n if (url.protocol === 'https:' && isPreviewHost) return url.origin;\n } catch(e) {}\n }\n return '';\n }\n function __anWorkspaceGatewayReturnOrigin() {\n var previewOrigin = __anBuilderPreviewReturnOrigin();\n if (previewOrigin) return previewOrigin;\n if (__AN_WORKSPACE_GATEWAY_RETURN_ORIGIN) return __AN_WORKSPACE_GATEWAY_RETURN_ORIGIN;\n return __anIsBuilderDesktop() ? 'http://127.0.0.1:8080' : '';\n }\n function __anNormalizeWorkspaceReturnPath(ret) {\n try {\n var url = new URL(ret || '/', window.location.origin);\n var path = url.pathname || '/';\n if (path === '/dispatch/dispatch') {\n path = '/dispatch';\n } else if (path.indexOf('/dispatch/') === 0) {\n var rest = path.slice('/dispatch/'.length);\n var first = rest.split('/')[0];\n var dispatchRoutes = {\n overview: true, apps: true, metrics: true, vault: true,\n integrations: true, messaging: true, workspace: true,\n agents: true, destinations: true, identities: true,\n approvals: true, audit: true, team: true, 'thread-debug': true,\n 'new-app': true\n };\n if (first === 'dispatch') {\n path = '/dispatch' + rest.slice(first.length);\n } else if (first && !dispatchRoutes[first]) {\n path = '/' + rest;\n }\n }\n return path + url.search + url.hash;\n } catch(e) {\n return ret || '/';\n }\n }\n function __anOAuthReturnTarget(ret) {\n var path = __anNormalizeWorkspaceReturnPath(ret);\n var origin = __anWorkspaceGatewayReturnOrigin();\n return origin ? origin + path : path;\n }\n function __anSessionBridgeUrl(ret, sessionToken) {\n try {\n var url = new URL(ret || window.location.pathname + window.location.search, window.location.origin);\n url.searchParams.set('_session', sessionToken);\n return url.pathname + url.search + url.hash;\n } catch(e) {\n var sep = (ret || '/').indexOf('?') === -1 ? '?' : '&';\n return (ret || '/') + sep + '_session=' + encodeURIComponent(sessionToken);\n }\n }\n function __anFinishOAuthExchange(ret, flowId, sessionToken) {\n if (__anIsBuilderPreview()) {\n if (sessionToken) {\n __anSetOAuthDebug('OAuth exchange redeemed; applying session bridge to embedded app', flowId);\n window.location.replace(__anSessionBridgeUrl(ret, sessionToken));\n return;\n }\n __anSetOAuthDebug('OAuth exchange redeemed; reloading the embedded app', flowId);\n window.location.reload();\n return;\n }\n __anSetOAuthDebug('OAuth exchange redeemed; returning to the app', flowId);\n window.location.href = ret || '/';\n }\n var __anBuilderPreviewSeen = false;\n function __anRememberBuilderPreview() {\n __anBuilderPreviewSeen = true;\n try { sessionStorage.setItem('__an_builder_preview_seen', '1'); } catch(e) {}\n }\n function __anHasBuilderPreviewSignal() {\n try {\n var params = new URLSearchParams(window.location.search);\n if (params.has('builder.preview') || params.has('builder.frameEditing') || params.has('__builder_editing__')) return true;\n } catch(e) {}\n return false;\n }\n function __anIsBuilderPreview() {\n if (__anBuilderPreviewSeen) return true;\n if (__anHasBuilderPreviewSignal()) {\n __anRememberBuilderPreview();\n return true;\n }\n try {\n if (sessionStorage.getItem('__an_builder_preview_seen') === '1') {\n __anBuilderPreviewSeen = true;\n return true;\n }\n } catch(e) {}\n try {\n var ref = document.referrer || '';\n var fromBuilder = ref.indexOf('builder.io') !== -1 || ref.indexOf('builder.my') !== -1 || ref.indexOf('builderio.xyz') !== -1 || ref.indexOf('builderio.dev') !== -1 || ref.indexOf('builder.codes') !== -1;\n if (fromBuilder) __anRememberBuilderPreview();\n return fromBuilder;\n } catch(e) {\n return false;\n }\n }\n __anIsBuilderPreview();\n function __anIsBuilderDesktop() {\n try {\n var ua = navigator.userAgent || '';\n return ua.indexOf('Electron') !== -1 && ua.indexOf('AgentNativeDesktop') === -1;\n } catch(e) {\n return false;\n }\n }\n function __anIsAgentNativeDesktop() {\n try {\n return (navigator.userAgent || '').indexOf('AgentNativeDesktop') !== -1;\n } catch(e) {\n return false;\n }\n }\n function __anIsInFrame() {\n try {\n return window.self !== window.top;\n } catch(e) {\n return true;\n }\n }\n function __anIsElectron() {\n try {\n return (navigator.userAgent || '').indexOf('Electron') !== -1;\n } catch(e) {\n return false;\n }\n }\n function __anResolveAuthFlow() {\n if (__anIsBuilderPreview()) return __anIsInFrame() ? 'popup' : 'redirect';\n var mode = __AN_GOOGLE_AUTH_MODE || 'auto';\n if (mode === 'popup') return 'popup';\n if (mode === 'redirect') return 'redirect';\n return __anIsAgentNativeDesktop() ? 'redirect' : 'popup';\n }\n var __anOAuthPollTimer = null;\n var __anOAuthPollCount = 0;\n function __anNewOAuthFlowId() {\n try {\n if (window.crypto && typeof window.crypto.randomUUID === 'function') {\n return window.crypto.randomUUID();\n }\n } catch(e) {}\n return 'builder-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2);\n }\n function __anFlowDebugId(flowId) {\n return flowId ? String(flowId).slice(-10) : '';\n }\n function __anShouldShowOAuthDebug() {\n try {\n var loc = window.location || {};\n return (typeof loc.hash === 'string' && loc.hash.indexOf('oauth-debug') !== -1) ||\n (typeof loc.search === 'string' && loc.search.indexOf('oauth_debug=1') !== -1);\n } catch(e) { return false; }\n }\n function __anSetOAuthDebug(message, flowId) {\n var text = message + (flowId ? ' (flow ' + __anFlowDebugId(flowId) + ')' : '');\n try {\n console.info('[agent-native][google-oauth] ' + text);\n } catch(e) {}\n var debug = document.getElementById('debug');\n if (debug) {\n debug.textContent = text;\n if (__anShouldShowOAuthDebug()) debug.classList.add('show');\n }\n }\n function __anShowOAuthError(err, btn, message) {\n if (__anOAuthPollTimer) {\n clearInterval(__anOAuthPollTimer);\n __anOAuthPollTimer = null;\n }\n err.textContent = message;\n err.classList.add('show');\n btn.disabled = false;\n }\n function __anStartRedirectOAuth(ret, btn, err, flowId, reason) {\n var params = new URLSearchParams();\n var oauthReturn = __anIsBuilderPreview() ? __anOAuthReturnTarget(ret) : ret;\n if (oauthReturn) params.set('return', oauthReturn);\n params.set('redirect', '1');\n __anSetOAuthDebug(reason || 'Opening Google sign-in redirect', flowId);\n try {\n __anOpenOAuthUrl(__anGoogleAuthUrlPath() + '?' + params.toString());\n } catch(e) {\n __anShowOAuthError(err, btn, 'Could not start Google sign-in redirect' + (flowId ? ' for flow ' + __anFlowDebugId(flowId) : '') + ': ' + (e && e.message ? e.message : 'unknown error'));\n }\n }\n function __anWaitForOAuthExchange(flowId, ret, btn, err) {\n var started = Date.now();\n var timeoutMs = 5 * 60 * 1000;\n __anOAuthPollCount = 0;\n async function check() {\n __anOAuthPollCount++;\n try {\n var res = await fetch(__anPath('/_agent-native/auth/desktop-exchange') + '?flow_id=' + encodeURIComponent(flowId), { credentials: 'include' });\n var data = await res.json().catch(function() { return {}; });\n if (data && (data.email || data.token)) {\n if (__anOAuthPollTimer) clearInterval(__anOAuthPollTimer);\n __anOAuthPollTimer = null;\n __anFinishOAuthExchange(ret, flowId, data.token);\n return;\n }\n if (data && data.error) {\n __anSetOAuthDebug('OAuth exchange returned an error: ' + (data.message || data.error), flowId);\n __anShowOAuthError(err, btn, data.message || data.error);\n return;\n }\n if (data && data.pending && (__anOAuthPollCount === 1 || __anOAuthPollCount % 5 === 0)) {\n __anSetOAuthDebug('Waiting for the Google callback; polling attempt ' + __anOAuthPollCount, flowId);\n }\n } catch(e) {\n if (__anOAuthPollCount === 1 || __anOAuthPollCount % 5 === 0) {\n __anSetOAuthDebug('Could not reach the OAuth exchange endpoint: ' + (e && e.message ? e.message : 'network error'), flowId);\n }\n }\n if (Date.now() - started > timeoutMs) {\n __anShowOAuthError(err, btn, 'Google sign-in did not finish. Flow ' + __anFlowDebugId(flowId) + ' never reached this app. Check the Google OAuth redirect URI and server logs for [agent-native][google-oauth].');\n }\n }\n if (__anOAuthPollTimer) clearInterval(__anOAuthPollTimer);\n __anOAuthPollTimer = setInterval(check, 1000);\n setTimeout(check, 500);\n }\n function __anStartPopupOAuth(ret, btn, err) {\n var flowId = __anNewOAuthFlowId();\n var oauthReturn = __anIsBuilderPreview() ? __anOAuthReturnTarget(ret) : ret;\n var params = new URLSearchParams();\n if (oauthReturn) params.set('return', oauthReturn);\n params.set('desktop', '1');\n params.set('flow_id', flowId);\n params.set('redirect', '1');\n var url = __anGoogleAuthUrlPath() + '?' + params.toString();\n try { sessionStorage.setItem('__an_signin', '1'); } catch(e) {}\n __anSetOAuthDebug('Opening Google sign-in popup', flowId);\n try {\n var popup = window.open('', '_blank', 'width=640,height=760');\n if (!popup) {\n __anStartRedirectOAuth(ret, btn, err, flowId, 'Google popup was blocked; falling back to redirect');\n return;\n }\n try { popup.opener = null; } catch(e) {}\n try {\n popup.location.href = url;\n } catch(e) {\n try { popup.close(); } catch(closeErr) {}\n __anStartRedirectOAuth(ret, btn, err, flowId, 'Could not navigate Google popup; falling back to redirect');\n return;\n }\n __anSetOAuthDebug('Google popup opened; waiting for callback', flowId);\n } catch(e) {\n __anStartRedirectOAuth(ret, btn, err, flowId, 'Could not open Google popup; falling back to redirect');\n return;\n }\n __anWaitForOAuthExchange(flowId, ret, btn, err);\n }\n function __anStartNativeDesktopOAuth(ret, btn, err) {\n var flowId = __anNewOAuthFlowId();\n var params = new URLSearchParams();\n if (ret) params.set('return', ret);\n params.set('desktop', '1');\n params.set('flow_id', flowId);\n params.set('redirect', '1');\n var url = __anGoogleAuthUrlPath() + '?' + params.toString();\n __anSetOAuthDebug('Opening Google sign-in in system browser', flowId);\n __anOpenOAuthUrl(url);\n __anWaitForOAuthExchange(flowId, ret, btn, err);\n }\n function __anOpenOAuthUrl(url) {\n try { sessionStorage.setItem('__an_signin', '1'); } catch(e) {}\n window.location.href = url;\n }\n async function signIn() {\n var btn = document.getElementById('btn');\n var err = document.getElementById('err');\n var ret = window.location.pathname + window.location.search;\n btn.disabled = true;\n err.classList.remove('show');\n if (__anResolveAuthFlow() === 'popup') {\n __anStartPopupOAuth(ret, btn, err);\n return;\n }\n if (__anIsAgentNativeDesktop()) {\n __anStartNativeDesktopOAuth(ret, btn, err);\n return;\n }\n if (__anIsBuilderPreview()) {\n __anStartRedirectOAuth(ret, btn, err);\n return;\n }\n try {\n var res = await fetch(__anGoogleAuthUrlPath() + '?return=' + encodeURIComponent(ret));\n var data = await res.json();\n if (data.url) {\n __anOpenOAuthUrl(data.url);\n } else {\n err.textContent = data.message || 'Google OAuth is not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.';\n err.classList.add('show');\n btn.disabled = false;\n }\n } catch (e) {\n err.textContent = 'Failed to connect. Please try again.';\n err.classList.add('show');\n btn.disabled = false;\n }\n }\n</script>\n</body>\n</html>`;\n}\n\n/**\n * Create an auth plugin that uses Google OAuth for authentication.\n *\n * When a user visits the app unauthenticated, they see a \"Sign in with Google\"\n * page. The Google OAuth callback (handled by the template) creates a session\n * tied to the user's Google email. `getSession()` then returns `{ email }` for\n * all subsequent requests.\n *\n * Better Auth handles Google OAuth internally when GOOGLE_CLIENT_ID and\n * GOOGLE_CLIENT_SECRET are set. The template's callback route at\n * /_agent-native/google/callback handles mobile deep linking.\n *\n * Usage in a template's `server/plugins/auth.ts`:\n * ```ts\n * import { createGoogleAuthPlugin } from \"@agent-native/core/server\";\n * export default createGoogleAuthPlugin();\n * ```\n */\nexport function createGoogleAuthPlugin(\n options?: GoogleAuthPluginOptions,\n): NitroPluginDef {\n return createAuthPlugin({\n publicPaths: [\n \"/_agent-native/google/callback\",\n \"/_agent-native/google/auth-url\",\n \"/_agent-native/auth/ba\",\n ...(options?.publicPaths ?? []),\n ],\n loginHtml: getGoogleLoginHtml(\n resolveGoogleAuthMode(options?.googleAuthMode),\n ),\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"google-auth-plugin.js","sourceRoot":"","sources":["../../src/server/google-auth-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EACL,qBAAqB,GAEtB,MAAM,uBAAuB,CAAC;AAgB/B,SAAS,kBAAkB,CAAC,cAA8B;IACxD,MAAM,iBAAiB,GAAG,oBAAoB,EAAE,CAAC;IACjD,MAAM,4BAA4B,GAAG,+BAA+B,EAAE,CAAC;IACvE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCA+E0B,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC;+CACrB,IAAI,CAAC,SAAS,CAAC,4BAA4B,CAAC;gCAC3D,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkWtD,CAAC;AACT,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAiC;IAEjC,OAAO,gBAAgB,CAAC;QACtB,WAAW,EAAE;YACX,gCAAgC;YAChC,gCAAgC;YAChC,wBAAwB;YACxB,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC;SAChC;QACD,SAAS,EAAE,kBAAkB,CAC3B,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC,CAC/C;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { createAuthPlugin } from \"./auth-plugin.js\";\nimport { getPublicOAuthOrigin } from \"./oauth-public-origin.js\";\nimport { getWorkspaceGatewayReturnOrigin } from \"./oauth-return-url.js\";\nimport {\n resolveGoogleAuthMode,\n type GoogleAuthMode,\n} from \"./google-auth-mode.js\";\n\ntype NitroPluginDef = (nitroApp: any) => void | Promise<void>;\n\nexport interface GoogleAuthPluginOptions {\n /** Additional paths accessible without authentication */\n publicPaths?: string[];\n /**\n * Google sign-in flow: `'popup'`, `'redirect'`, or `'auto'` (default).\n * Falls back to `GOOGLE_AUTH_MODE` env var, then `'auto'`. Builder\n * iframes use popup; top-level Builder preview/editor surfaces use\n * redirect.\n */\n googleAuthMode?: GoogleAuthMode;\n}\n\nfunction getGoogleLoginHtml(googleAuthMode: GoogleAuthMode): string {\n const publicOAuthOrigin = getPublicOAuthOrigin();\n const workspaceGatewayReturnOrigin = getWorkspaceGatewayReturnOrigin();\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\">\n<title>Sign in</title>\n<style>\n *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n background: #0a0a0a;\n color: #e5e5e5;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n }\n .card {\n width: 100%;\n max-width: 360px;\n padding: 2rem;\n background: #141414;\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 12px;\n text-align: center;\n }\n h1 { font-size: 1.125rem; font-weight: 600; margin-bottom: 0.5rem; color: #fff; }\n .subtitle { font-size: 0.8125rem; color: #888; margin-bottom: 1.5rem; }\n button {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.625rem;\n padding: 0.625rem;\n background: #fff;\n color: #000;\n border: none;\n border-radius: 8px;\n font-size: 0.9375rem;\n font-weight: 500;\n cursor: pointer;\n }\n button:hover { opacity: 0.85; }\n button:disabled { opacity: 0.5; cursor: wait; }\n .error { margin-top: 0.75rem; font-size: 0.8125rem; color: #f87171; display: none; }\n .error.show { display: block; }\n .debug {\n display: none;\n margin-top: 0.625rem;\n font-size: 0.6875rem;\n line-height: 1.45;\n color: #777;\n word-break: break-word;\n }\n .debug.show { display: block; }\n svg { width: 18px; height: 18px; }\n</style>\n</head>\n<body>\n<div class=\"card\">\n <h1>Sign in</h1>\n <p class=\"subtitle\">Continue with your Google account</p>\n <button id=\"btn\" onclick=\"signIn()\">\n <svg viewBox=\"0 0 24 24\"><path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z\"/><path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/><path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/><path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/></svg>\n Sign in with Google\n </button>\n <p class=\"error\" id=\"err\"></p>\n <p class=\"debug\" id=\"debug\"></p>\n</div>\n<script>\n function __anBasePath() {\n var marker = '/_agent-native';\n var idx = window.location.pathname.indexOf(marker);\n return idx > 0 ? window.location.pathname.slice(0, idx) : '';\n }\n function __anPath(path) {\n return __anBasePath() + path;\n }\n var __AN_PUBLIC_OAUTH_ORIGIN = ${JSON.stringify(publicOAuthOrigin)};\n var __AN_WORKSPACE_GATEWAY_RETURN_ORIGIN = ${JSON.stringify(workspaceGatewayReturnOrigin)};\n var __AN_GOOGLE_AUTH_MODE = ${JSON.stringify(googleAuthMode)};\n function __anConfiguredOAuthOrigin() {\n if (!__AN_PUBLIC_OAUTH_ORIGIN) return '';\n try {\n var origin = new URL(__AN_PUBLIC_OAUTH_ORIGIN).origin;\n return origin && origin !== window.location.origin ? origin : '';\n } catch(e) {\n return '';\n }\n }\n function __anAuthPath(path) {\n var origin = __anIsBuilderPreview() ? __anConfiguredOAuthOrigin() : '';\n return origin ? origin + path : __anPath(path);\n }\n function __anGoogleAuthUrlPath() {\n return __anIsBuilderPreview()\n ? __anAuthPath('/_agent-native/google/auth-url')\n : __anPath('/_agent-native/google/auth-url');\n }\n function __anBuilderPreviewReturnOrigin() {\n var candidates = [window.location.href, document.referrer || ''];\n try {\n if (window.location.ancestorOrigins) {\n for (var j = 0; j < window.location.ancestorOrigins.length; j++) {\n candidates.push(window.location.ancestorOrigins[j]);\n }\n }\n } catch(e) {}\n for (var i = 0; i < candidates.length; i++) {\n try {\n var url = new URL(candidates[i]);\n var host = url.hostname.toLowerCase();\n var isPreviewHost =\n host === 'builderio.xyz' || host.slice(-14) === '.builderio.xyz' ||\n host === 'builderio.dev' || host.slice(-14) === '.builderio.dev' ||\n host === 'builder.codes' || host.slice(-14) === '.builder.codes' ||\n host === 'builder.my' || host.slice(-11) === '.builder.my';\n if (url.protocol === 'https:' && isPreviewHost) return url.origin;\n } catch(e) {}\n }\n return '';\n }\n function __anWorkspaceGatewayReturnOrigin() {\n var previewOrigin = __anBuilderPreviewReturnOrigin();\n if (previewOrigin) return previewOrigin;\n if (__AN_WORKSPACE_GATEWAY_RETURN_ORIGIN) return __AN_WORKSPACE_GATEWAY_RETURN_ORIGIN;\n return __anIsBuilderDesktop() ? 'http://127.0.0.1:8080' : '';\n }\n function __anNormalizeWorkspaceReturnPath(ret) {\n try {\n var url = new URL(ret || '/', window.location.origin);\n var path = url.pathname || '/';\n if (path === '/dispatch/dispatch') {\n path = '/dispatch';\n } else if (path.indexOf('/dispatch/') === 0) {\n var rest = path.slice('/dispatch/'.length);\n var first = rest.split('/')[0];\n var dispatchRoutes = {\n overview: true, apps: true, metrics: true, vault: true,\n integrations: true, messaging: true, workspace: true,\n agents: true, destinations: true, identities: true,\n approvals: true, audit: true, team: true, 'thread-debug': true,\n 'new-app': true\n };\n if (first === 'dispatch') {\n path = '/dispatch' + rest.slice(first.length);\n } else if (first && !dispatchRoutes[first]) {\n path = '/' + rest;\n }\n }\n return path + url.search + url.hash;\n } catch(e) {\n return ret || '/';\n }\n }\n function __anOAuthReturnTarget(ret) {\n var path = __anNormalizeWorkspaceReturnPath(ret);\n var origin = __anWorkspaceGatewayReturnOrigin();\n return origin ? origin + path : path;\n }\n function __anSessionBridgeUrl(ret, sessionToken) {\n try {\n var url = new URL(ret || window.location.pathname + window.location.search, window.location.origin);\n url.searchParams.set('_session', sessionToken);\n return url.pathname + url.search + url.hash;\n } catch(e) {\n var sep = (ret || '/').indexOf('?') === -1 ? '?' : '&';\n return (ret || '/') + sep + '_session=' + encodeURIComponent(sessionToken);\n }\n }\n function __anFinishOAuthExchange(ret, flowId, sessionToken) {\n if (__anIsBuilderPreview()) {\n if (sessionToken) {\n __anSetOAuthDebug('OAuth exchange redeemed; applying session bridge to embedded app', flowId);\n window.location.replace(__anSessionBridgeUrl(ret, sessionToken));\n return;\n }\n __anSetOAuthDebug('OAuth exchange redeemed; reloading the embedded app', flowId);\n window.location.reload();\n return;\n }\n __anSetOAuthDebug('OAuth exchange redeemed; returning to the app', flowId);\n window.location.href = ret || '/';\n }\n var __anBuilderPreviewSeen = false;\n function __anRememberBuilderPreview() {\n __anBuilderPreviewSeen = true;\n try { sessionStorage.setItem('__an_builder_preview_seen', '1'); } catch(e) {}\n }\n function __anHasBuilderPreviewSignal() {\n try {\n var params = new URLSearchParams(window.location.search);\n if (params.has('builder.preview') || params.has('builder.frameEditing') || params.has('__builder_editing__')) return true;\n } catch(e) {}\n return false;\n }\n function __anIsBuilderPreview() {\n if (__anBuilderPreviewSeen) return true;\n if (__anHasBuilderPreviewSignal()) {\n __anRememberBuilderPreview();\n return true;\n }\n try {\n if (sessionStorage.getItem('__an_builder_preview_seen') === '1') {\n __anBuilderPreviewSeen = true;\n return true;\n }\n } catch(e) {}\n try {\n var ref = document.referrer || '';\n var fromBuilder = ref.indexOf('builder.io') !== -1 || ref.indexOf('builder.my') !== -1 || ref.indexOf('builderio.xyz') !== -1 || ref.indexOf('builderio.dev') !== -1 || ref.indexOf('builder.codes') !== -1;\n if (fromBuilder) __anRememberBuilderPreview();\n return fromBuilder;\n } catch(e) {\n return false;\n }\n }\n __anIsBuilderPreview();\n function __anIsBuilderDesktop() {\n try {\n var ua = navigator.userAgent || '';\n return ua.indexOf('Electron') !== -1 && ua.indexOf('AgentNativeDesktop') === -1;\n } catch(e) {\n return false;\n }\n }\n function __anIsAgentNativeDesktop() {\n try {\n return (navigator.userAgent || '').indexOf('AgentNativeDesktop') !== -1;\n } catch(e) {\n return false;\n }\n }\n function __anIsInFrame() {\n try {\n return window.self !== window.top;\n } catch(e) {\n return true;\n }\n }\n function __anIsElectron() {\n try {\n return (navigator.userAgent || '').indexOf('Electron') !== -1;\n } catch(e) {\n return false;\n }\n }\n function __anResolveAuthFlow() {\n if (__anIsBuilderPreview()) return __anIsInFrame() ? 'popup' : 'redirect';\n var mode = __AN_GOOGLE_AUTH_MODE || 'auto';\n if (mode === 'popup') return 'popup';\n if (mode === 'redirect') return 'redirect';\n return __anIsAgentNativeDesktop() ? 'redirect' : 'popup';\n }\n var __anOAuthPollTimer = null;\n var __anOAuthPollCount = 0;\n function __anNewOAuthFlowId() {\n try {\n if (window.crypto && typeof window.crypto.randomUUID === 'function') {\n return window.crypto.randomUUID();\n }\n } catch(e) {}\n return 'builder-' + Date.now().toString(36) + '-' + Math.random().toString(36).slice(2);\n }\n function __anFlowDebugId(flowId) {\n return flowId ? String(flowId).slice(-10) : '';\n }\n function __anShouldShowOAuthDebug() {\n try {\n var loc = window.location || {};\n return (typeof loc.hash === 'string' && loc.hash.indexOf('oauth-debug') !== -1) ||\n (typeof loc.search === 'string' && loc.search.indexOf('oauth_debug=1') !== -1);\n } catch(e) { return false; }\n }\n function __anSetOAuthDebug(message, flowId) {\n var text = message + (flowId ? ' (flow ' + __anFlowDebugId(flowId) + ')' : '');\n try {\n console.info('[agent-native][google-oauth] ' + text);\n } catch(e) {}\n var debug = document.getElementById('debug');\n if (debug) {\n debug.textContent = text;\n if (__anShouldShowOAuthDebug()) debug.classList.add('show');\n }\n }\n function __anShowOAuthError(err, btn, message) {\n if (__anOAuthPollTimer) {\n clearInterval(__anOAuthPollTimer);\n __anOAuthPollTimer = null;\n }\n err.textContent = message;\n err.classList.add('show');\n btn.disabled = false;\n }\n function __anHandlePopupOAuthFailure(ret, btn, err, flowId, redirectReason, builderFrameMessage) {\n if (__anIsBuilderPreview() && __anIsInFrame()) {\n __anShowOAuthError(err, btn, builderFrameMessage + ' Allow popups for this site and try again (flow ' + __anFlowDebugId(flowId) + ').');\n return;\n }\n __anStartRedirectOAuth(ret, btn, err, flowId, redirectReason);\n }\n function __anStartRedirectOAuth(ret, btn, err, flowId, reason) {\n var params = new URLSearchParams();\n var oauthReturn = __anIsBuilderPreview() ? __anOAuthReturnTarget(ret) : ret;\n if (oauthReturn) params.set('return', oauthReturn);\n params.set('redirect', '1');\n __anSetOAuthDebug(reason || 'Opening Google sign-in redirect', flowId);\n try {\n __anOpenOAuthUrl(__anGoogleAuthUrlPath() + '?' + params.toString());\n } catch(e) {\n __anShowOAuthError(err, btn, 'Could not start Google sign-in redirect' + (flowId ? ' for flow ' + __anFlowDebugId(flowId) : '') + ': ' + (e && e.message ? e.message : 'unknown error'));\n }\n }\n function __anWaitForOAuthExchange(flowId, ret, btn, err) {\n var started = Date.now();\n var timeoutMs = 5 * 60 * 1000;\n __anOAuthPollCount = 0;\n async function check() {\n __anOAuthPollCount++;\n try {\n var res = await fetch(__anPath('/_agent-native/auth/desktop-exchange') + '?flow_id=' + encodeURIComponent(flowId), { credentials: 'include' });\n var data = await res.json().catch(function() { return {}; });\n if (data && (data.email || data.token)) {\n if (__anOAuthPollTimer) clearInterval(__anOAuthPollTimer);\n __anOAuthPollTimer = null;\n __anFinishOAuthExchange(ret, flowId, data.token);\n return;\n }\n if (data && data.error) {\n __anSetOAuthDebug('OAuth exchange returned an error: ' + (data.message || data.error), flowId);\n __anShowOAuthError(err, btn, data.message || data.error);\n return;\n }\n if (data && data.pending && (__anOAuthPollCount === 1 || __anOAuthPollCount % 5 === 0)) {\n __anSetOAuthDebug('Waiting for the Google callback; polling attempt ' + __anOAuthPollCount, flowId);\n }\n } catch(e) {\n if (__anOAuthPollCount === 1 || __anOAuthPollCount % 5 === 0) {\n __anSetOAuthDebug('Could not reach the OAuth exchange endpoint: ' + (e && e.message ? e.message : 'network error'), flowId);\n }\n }\n if (Date.now() - started > timeoutMs) {\n __anShowOAuthError(err, btn, 'Google sign-in did not finish. Flow ' + __anFlowDebugId(flowId) + ' never reached this app. Check the Google OAuth redirect URI and server logs for [agent-native][google-oauth].');\n }\n }\n if (__anOAuthPollTimer) clearInterval(__anOAuthPollTimer);\n __anOAuthPollTimer = setInterval(check, 1000);\n setTimeout(check, 500);\n }\n function __anStartPopupOAuth(ret, btn, err) {\n var flowId = __anNewOAuthFlowId();\n var oauthReturn = __anIsBuilderPreview() ? __anOAuthReturnTarget(ret) : ret;\n var params = new URLSearchParams();\n if (oauthReturn) params.set('return', oauthReturn);\n params.set('desktop', '1');\n params.set('flow_id', flowId);\n params.set('redirect', '1');\n var url = __anGoogleAuthUrlPath() + '?' + params.toString();\n try { sessionStorage.setItem('__an_signin', '1'); } catch(e) {}\n __anSetOAuthDebug('Opening Google sign-in popup', flowId);\n try {\n var popup = window.open('', '_blank', 'width=640,height=760');\n if (!popup) {\n __anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Google popup was blocked; falling back to redirect', 'Google popup was blocked.');\n return;\n }\n try { popup.opener = null; } catch(e) {}\n try {\n popup.location.href = url;\n } catch(e) {\n try { popup.close(); } catch(closeErr) {}\n __anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Could not navigate Google popup; falling back to redirect', 'Could not navigate Google popup.');\n return;\n }\n __anSetOAuthDebug('Google popup opened; waiting for callback', flowId);\n } catch(e) {\n __anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Could not open Google popup; falling back to redirect', 'Could not open Google popup.');\n return;\n }\n __anWaitForOAuthExchange(flowId, ret, btn, err);\n }\n function __anStartNativeDesktopOAuth(ret, btn, err) {\n var flowId = __anNewOAuthFlowId();\n var params = new URLSearchParams();\n if (ret) params.set('return', ret);\n params.set('desktop', '1');\n params.set('flow_id', flowId);\n params.set('redirect', '1');\n var url = __anGoogleAuthUrlPath() + '?' + params.toString();\n __anSetOAuthDebug('Opening Google sign-in in system browser', flowId);\n __anOpenOAuthUrl(url);\n __anWaitForOAuthExchange(flowId, ret, btn, err);\n }\n function __anOpenOAuthUrl(url) {\n try { sessionStorage.setItem('__an_signin', '1'); } catch(e) {}\n window.location.href = url;\n }\n async function signIn() {\n var btn = document.getElementById('btn');\n var err = document.getElementById('err');\n var ret = window.location.pathname + window.location.search;\n btn.disabled = true;\n err.classList.remove('show');\n if (__anResolveAuthFlow() === 'popup') {\n __anStartPopupOAuth(ret, btn, err);\n return;\n }\n if (__anIsAgentNativeDesktop()) {\n __anStartNativeDesktopOAuth(ret, btn, err);\n return;\n }\n if (__anIsBuilderPreview()) {\n var flowId = __anNewOAuthFlowId();\n __anStartRedirectOAuth(ret, btn, err, flowId, 'Opening Google sign-in redirect from Builder preview');\n return;\n }\n try {\n var res = await fetch(__anGoogleAuthUrlPath() + '?return=' + encodeURIComponent(ret));\n var data = await res.json();\n if (data.url) {\n __anOpenOAuthUrl(data.url);\n } else {\n err.textContent = data.message || 'Google OAuth is not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.';\n err.classList.add('show');\n btn.disabled = false;\n }\n } catch (e) {\n err.textContent = 'Failed to connect. Please try again.';\n err.classList.add('show');\n btn.disabled = false;\n }\n }\n</script>\n</body>\n</html>`;\n}\n\n/**\n * Create an auth plugin that uses Google OAuth for authentication.\n *\n * When a user visits the app unauthenticated, they see a \"Sign in with Google\"\n * page. The Google OAuth callback (handled by the template) creates a session\n * tied to the user's Google email. `getSession()` then returns `{ email }` for\n * all subsequent requests.\n *\n * Better Auth handles Google OAuth internally when GOOGLE_CLIENT_ID and\n * GOOGLE_CLIENT_SECRET are set. The template's callback route at\n * /_agent-native/google/callback handles mobile deep linking.\n *\n * Usage in a template's `server/plugins/auth.ts`:\n * ```ts\n * import { createGoogleAuthPlugin } from \"@agent-native/core/server\";\n * export default createGoogleAuthPlugin();\n * ```\n */\nexport function createGoogleAuthPlugin(\n options?: GoogleAuthPluginOptions,\n): NitroPluginDef {\n return createAuthPlugin({\n publicPaths: [\n \"/_agent-native/google/callback\",\n \"/_agent-native/google/auth-url\",\n \"/_agent-native/auth/ba\",\n ...(options?.publicPaths ?? []),\n ],\n loginHtml: getGoogleLoginHtml(\n resolveGoogleAuthMode(options?.googleAuthMode),\n ),\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding-html.d.ts","sourceRoot":"","sources":["../../src/server/onboarding-html.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAoC/B,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF;;;;OAIG;IACH,kBAAkB,CAAC,EAAE;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,qBAA0B,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"onboarding-html.d.ts","sourceRoot":"","sources":["../../src/server/onboarding-html.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAoC/B,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF;;;;OAIG;IACH,kBAAkB,CAAC,EAAE;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,qBAA0B,GAAG,MAAM,CA+rD1E;AAED,kDAAkD;AAClD,eAAO,MAAM,eAAe,QAAsB,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CA0G7C"}
|
|
@@ -1073,6 +1073,13 @@ ${googleOnly
|
|
|
1073
1073
|
err.classList.add('show');
|
|
1074
1074
|
btn.disabled = false;
|
|
1075
1075
|
}
|
|
1076
|
+
function __anHandlePopupOAuthFailure(ret, btn, err, flowId, redirectReason, builderFrameMessage) {
|
|
1077
|
+
if (__anIsBuilderPreview() && __anIsInFrame()) {
|
|
1078
|
+
__anShowOAuthError(err, btn, builderFrameMessage + ' Allow popups for this site and try again (flow ' + __anFlowDebugId(flowId) + ').');
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
__anStartRedirectOAuth(ret, btn, err, flowId, redirectReason);
|
|
1082
|
+
}
|
|
1076
1083
|
function __anStartRedirectOAuth(ret, btn, err, flowId, reason) {
|
|
1077
1084
|
var params = new URLSearchParams();
|
|
1078
1085
|
var oauthReturn = __anIsBuilderPreview() ? __anOAuthReturnTarget(ret) : ret;
|
|
@@ -1135,7 +1142,7 @@ ${googleOnly
|
|
|
1135
1142
|
try {
|
|
1136
1143
|
var popup = window.open('', '_blank', 'width=640,height=760');
|
|
1137
1144
|
if (!popup) {
|
|
1138
|
-
|
|
1145
|
+
__anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Google popup was blocked; falling back to redirect', 'Google popup was blocked.');
|
|
1139
1146
|
return;
|
|
1140
1147
|
}
|
|
1141
1148
|
try { popup.opener = null; } catch(e) {}
|
|
@@ -1143,12 +1150,12 @@ ${googleOnly
|
|
|
1143
1150
|
popup.location.href = url;
|
|
1144
1151
|
} catch(e) {
|
|
1145
1152
|
try { popup.close(); } catch(closeErr) {}
|
|
1146
|
-
|
|
1153
|
+
__anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Could not navigate Google popup; falling back to redirect', 'Could not navigate Google popup.');
|
|
1147
1154
|
return;
|
|
1148
1155
|
}
|
|
1149
1156
|
__anSetOAuthDebug('Google popup opened; waiting for callback', flowId);
|
|
1150
1157
|
} catch(e) {
|
|
1151
|
-
|
|
1158
|
+
__anHandlePopupOAuthFailure(ret, btn, err, flowId, 'Could not open Google popup; falling back to redirect', 'Could not open Google popup.');
|
|
1152
1159
|
return;
|
|
1153
1160
|
}
|
|
1154
1161
|
__anWaitForOAuthExchange(flowId, ret, btn, err);
|
|
@@ -1649,7 +1656,8 @@ ${showGoogle
|
|
|
1649
1656
|
return;
|
|
1650
1657
|
}
|
|
1651
1658
|
if (__anIsBuilderPreview()) {
|
|
1652
|
-
|
|
1659
|
+
var flowId = __anNewOAuthFlowId();
|
|
1660
|
+
__anStartRedirectOAuth(ret, btn, err, flowId, 'Opening Google sign-in redirect from Builder preview');
|
|
1653
1661
|
return;
|
|
1654
1662
|
}
|
|
1655
1663
|
try {
|