UNPKG

better-auth

Version:

The most comprehensive authentication library for TypeScript.

202 lines (196 loc) • 7.16 kB
'use strict'; const z = require('zod/v4'); require('better-call'); const socialProviders_index = require('../../shared/better-auth.Bafolo-S.cjs'); const env = require('../../shared/better-auth.DiSjtgs9.cjs'); require('@better-auth/utils/base64'); require('@better-auth/utils/hmac'); const url = require('../../shared/better-auth.C-R0J0n1.cjs'); require('@better-auth/utils/binary'); require('../../shared/better-auth.BIMq4RPW.cjs'); require('../../shared/better-auth.CXhVNgXP.cjs'); require('defu'); const crypto_index = require('../../crypto/index.cjs'); require('../../shared/better-auth.C1hdVENX.cjs'); require('@better-auth/utils/hash'); require('@better-fetch/fetch'); require('jose'); require('@noble/ciphers/chacha'); require('@noble/ciphers/utils'); require('@noble/ciphers/webcrypto'); require('@noble/hashes/scrypt'); require('@better-auth/utils'); require('@better-auth/utils/hex'); require('@noble/hashes/utils'); require('../../shared/better-auth.CYeOI8C-.cjs'); require('@better-auth/utils/random'); require('../../cookies/index.cjs'); require('../../shared/better-auth.ANpbi45u.cjs'); require('../../shared/better-auth.D3mtHEZg.cjs'); require('jose/errors'); function _interopNamespaceCompat(e) { if (e && typeof e === 'object' && 'default' in e) return e; const n = Object.create(null); if (e) { for (const k in e) { n[k] = e[k]; } } n.default = e; return n; } const z__namespace = /*#__PURE__*/_interopNamespaceCompat(z); function getVenderBaseURL() { const vercel = env.env.VERCEL_URL ? `https://${env.env.VERCEL_URL}` : void 0; const netlify = env.env.NETLIFY_URL; const render = env.env.RENDER_URL; const aws = env.env.AWS_LAMBDA_FUNCTION_NAME; const google = env.env.GOOGLE_CLOUD_FUNCTION_NAME; const azure = env.env.AZURE_FUNCTION_NAME; return vercel || netlify || render || aws || google || azure; } const oAuthProxy = (opts) => { const resolveCurrentURL = (ctx) => { return new URL( opts?.currentURL || ctx.request?.url || getVenderBaseURL() || ctx.context.baseURL ); }; return { id: "oauth-proxy", endpoints: { oAuthProxy: socialProviders_index.createAuthEndpoint( "/oauth-proxy-callback", { method: "GET", query: z__namespace.object({ callbackURL: z__namespace.string().meta({ description: "The URL to redirect to after the proxy" }), cookies: z__namespace.string().meta({ description: "The cookies to set after the proxy" }) }), use: [socialProviders_index.originCheck((ctx) => ctx.query.callbackURL)], metadata: { openapi: { description: "OAuth Proxy Callback", parameters: [ { in: "query", name: "callbackURL", required: true, description: "The URL to redirect to after the proxy" }, { in: "query", name: "cookies", required: true, description: "The cookies to set after the proxy" } ], responses: { 302: { description: "Redirect", headers: { Location: { description: "The URL to redirect to", schema: { type: "string" } } } } } } } }, async (ctx) => { const cookies = ctx.query.cookies; const decryptedCookies = await crypto_index.symmetricDecrypt({ key: ctx.context.secret, data: cookies }).catch((e) => { ctx.context.logger.error(e); return null; }); const error = ctx.context.options.onAPIError?.errorURL || `${ctx.context.options.baseURL}/api/auth/error`; if (!decryptedCookies) { throw ctx.redirect( `${error}?error=OAuthProxy - Invalid cookies or secret` ); } const isSecureContext = resolveCurrentURL(ctx).protocol === "https:"; const prefix = ctx.context.options.advanced?.cookiePrefix || "better-auth"; const cookieToSet = isSecureContext ? decryptedCookies : decryptedCookies.replace("Secure;", "").replace(`__Secure-${prefix}`, prefix); ctx.setHeader("set-cookie", cookieToSet); throw ctx.redirect(ctx.query.callbackURL); } ) }, hooks: { after: [ { matcher(context) { return context.path?.startsWith("/callback") || context.path?.startsWith("/oauth2/callback"); }, handler: socialProviders_index.createAuthMiddleware(async (ctx) => { const headers = ctx.context.responseHeaders; const location = headers?.get("location"); if (location?.includes("/oauth-proxy-callback?callbackURL")) { if (!location.startsWith("http")) { return; } const locationURL = new URL(location); const origin = locationURL.origin; if (origin === url.getOrigin(ctx.context.baseURL)) { const newLocation = locationURL.searchParams.get("callbackURL"); if (!newLocation) { return; } ctx.setHeader("location", newLocation); return; } const setCookies = headers?.get("set-cookie"); if (!setCookies) { return; } const encryptedCookies = await crypto_index.symmetricEncrypt({ key: ctx.context.secret, data: setCookies }); const locationWithCookies = `${location}&cookies=${encodeURIComponent( encryptedCookies )}`; ctx.setHeader("location", locationWithCookies); } }) } ], before: [ { matcher(context) { return context.path?.startsWith("/sign-in/social") || context.path?.startsWith("/sign-in/oauth2"); }, handler: socialProviders_index.createAuthMiddleware(async (ctx) => { const skipProxy = ctx.request?.headers.get("x-skip-oauth-proxy"); if (skipProxy) { return; } const url = resolveCurrentURL(ctx); const productionURL = opts?.productionURL || env.env.BETTER_AUTH_URL; if (productionURL === ctx.context.options.baseURL) { return; } ctx.body.callbackURL = `${url.origin}${ctx.context.options.basePath || "/api/auth"}/oauth-proxy-callback?callbackURL=${encodeURIComponent( ctx.body.callbackURL || ctx.context.baseURL )}`; return { context: ctx }; }) } ] } }; }; exports.oAuthProxy = oAuthProxy;