@zpg6-test-pkgs/better-auth
Version:
The most comprehensive authentication library for TypeScript.
188 lines (185 loc) • 6.82 kB
JavaScript
import * as z from 'zod/v4';
import 'better-call';
import { o as originCheck } from '../../shared/better-auth.D7aTFyWE.mjs';
import { c as createAuthMiddleware, a as createAuthEndpoint } from '../../shared/better-auth.BfeJWAMn.mjs';
import { e as env } from '../../shared/better-auth.CMQ3rA-I.mjs';
import '@better-auth/utils/base64';
import '@better-auth/utils/hmac';
import '../../shared/better-auth.BjBlybv-.mjs';
import { g as getOrigin } from '../../shared/better-auth.CuS_eDdK.mjs';
import '@better-auth/utils/binary';
import '../../shared/better-auth.n2KFGwjY.mjs';
import { symmetricEncrypt, symmetricDecrypt } from '../../crypto/index.mjs';
import '../../shared/better-auth.CW6D9eSx.mjs';
import '@better-auth/utils/hash';
import '@better-fetch/fetch';
import 'jose';
import '@noble/ciphers/chacha';
import '@noble/ciphers/utils';
import '@noble/ciphers/webcrypto';
import '@noble/hashes/scrypt';
import '@better-auth/utils';
import '@better-auth/utils/hex';
import '@noble/hashes/utils';
import '../../shared/better-auth.B4Qoxdgc.mjs';
import '@better-auth/utils/random';
import '../../shared/better-auth.DF-MUmVw.mjs';
import '../../shared/better-auth.DdzSJf-n.mjs';
import '../../shared/better-auth.BZZKN1g7.mjs';
import 'jose/errors';
import '../../shared/better-auth.BUPPRXfK.mjs';
import 'defu';
function getVenderBaseURL() {
const vercel = env.VERCEL_URL ? `https://${env.VERCEL_URL}` : void 0;
const netlify = env.NETLIFY_URL;
const render = env.RENDER_URL;
const aws = env.AWS_LAMBDA_FUNCTION_NAME;
const google = env.GOOGLE_CLOUD_FUNCTION_NAME;
const azure = 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: createAuthEndpoint(
"/oauth-proxy-callback",
{
method: "GET",
query: z.object({
callbackURL: z.string().meta({
description: "The URL to redirect to after the proxy"
}),
cookies: z.string().meta({
description: "The cookies to set after the proxy"
})
}),
use: [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 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: 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 === 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 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: 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.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
};
})
}
]
}
};
};
export { oAuthProxy };