fix(sso): apply trusted origin changes without server restart

This commit is contained in:
Mauricio Siu
2026-07-09 01:46:32 -06:00
parent 995a04d30f
commit b3621bcfff
3 changed files with 48 additions and 28 deletions

View File

@@ -4,7 +4,7 @@ import { sso } from "@better-auth/sso";
import * as bcrypt from "bcrypt";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { APIError } from "better-auth/api";
import { APIError, createAuthMiddleware } from "better-auth/api";
import { admin, organization, twoFactor } from "better-auth/plugins";
import { and, desc, eq } from "drizzle-orm";
import { IS_CLOUD } from "../constants";
@@ -29,6 +29,37 @@ import { getPublicIpWithFallback } from "../wss/utils";
import { ac, adminRole, memberRole, ownerRole } from "./access-control";
import { betterAuthSecret } from "./auth-secret";
const resolveTrustedOrigins = async () => {
try {
if (IS_CLOUD) {
return await getTrustedOrigins();
}
const [trustedOrigins, settings] = await Promise.all([
getTrustedOrigins(),
getWebServerSettings(),
]);
if (!settings) return [];
const devOrigins =
process.env.NODE_ENV === "development"
? [
"http://localhost:3000",
"https://absolutely-handy-falcon.ngrok-free.app",
]
: [];
return [
...(settings?.serverIp ? [`http://${settings?.serverIp}:3000`] : []),
...(settings?.host ? [`https://${settings?.host}`] : []),
...devOrigins,
...trustedOrigins,
];
} catch (error) {
console.error("Failed to resolve trusted origins:", error);
return [];
}
};
const { handler, api } = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
@@ -80,33 +111,14 @@ const { handler, api } = betterAuth({
logger: {
disabled: process.env.NODE_ENV === "production",
},
async trustedOrigins() {
try {
if (IS_CLOUD) {
return await getTrustedOrigins();
}
const [trustedOrigins, settings] = await Promise.all([
getTrustedOrigins(),
getWebServerSettings(),
]);
if (!settings) return [];
const devOrigins =
process.env.NODE_ENV === "development"
? [
"http://localhost:3000",
"https://absolutely-handy-falcon.ngrok-free.app",
]
: [];
return [
...(settings?.serverIp ? [`http://${settings?.serverIp}:3000`] : []),
...(settings?.host ? [`https://${settings?.host}`] : []),
...devOrigins,
...trustedOrigins,
];
} catch (error) {
console.error("Failed to resolve trusted origins:", error);
return [];
}
trustedOrigins: resolveTrustedOrigins,
hooks: {
before: createAuthMiddleware(async (ctx) => {
ctx.context.trustedOrigins = [
...(ctx.context.baseURL ? [new URL(ctx.context.baseURL).origin] : []),
...(await resolveTrustedOrigins()),
].filter(Boolean);
}),
},
emailVerification: {
sendOnSignUp: true,

View File

@@ -120,6 +120,10 @@ export const getDokployUrl = async () => {
const TRUSTED_ORIGINS_CACHE_TTL_MS = 30 * 60_000;
let trustedOriginsCache: { data: string[]; expiresAt: number } | null = null;
export const invalidateTrustedOriginsCache = () => {
trustedOriginsCache = null;
};
export const getTrustedOrigins = async () => {
const runQuery = async () => {
const rows = await db