mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-07 12:32:16 +00:00
Merge pull request #4776 from Dokploy/fix/sso-trusted-origins-restart
fix(sso): apply trusted origin changes without server restart
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
|||||||
requestToHeaders,
|
requestToHeaders,
|
||||||
} from "@dokploy/server/index";
|
} from "@dokploy/server/index";
|
||||||
import { auth } from "@dokploy/server/lib/auth";
|
import { auth } from "@dokploy/server/lib/auth";
|
||||||
|
import { invalidateTrustedOriginsCache } from "@dokploy/server/services/admin";
|
||||||
import { getWebServerSettings } from "@dokploy/server/services/web-server-settings";
|
import { getWebServerSettings } from "@dokploy/server/services/web-server-settings";
|
||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { and, asc, eq } from "drizzle-orm";
|
import { and, asc, eq } from "drizzle-orm";
|
||||||
@@ -319,6 +320,7 @@ export const ssoRouter = createTRPCRouter({
|
|||||||
.update(user)
|
.update(user)
|
||||||
.set({ trustedOrigins: next })
|
.set({ trustedOrigins: next })
|
||||||
.where(eq(user.id, ownerId));
|
.where(eq(user.id, ownerId));
|
||||||
|
invalidateTrustedOriginsCache();
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}),
|
}),
|
||||||
removeTrustedOrigin: enterpriseProcedure
|
removeTrustedOrigin: enterpriseProcedure
|
||||||
@@ -346,6 +348,7 @@ export const ssoRouter = createTRPCRouter({
|
|||||||
.update(user)
|
.update(user)
|
||||||
.set({ trustedOrigins: next })
|
.set({ trustedOrigins: next })
|
||||||
.where(eq(user.id, ownerId));
|
.where(eq(user.id, ownerId));
|
||||||
|
invalidateTrustedOriginsCache();
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}),
|
}),
|
||||||
updateTrustedOrigin: enterpriseProcedure
|
updateTrustedOrigin: enterpriseProcedure
|
||||||
@@ -379,6 +382,7 @@ export const ssoRouter = createTRPCRouter({
|
|||||||
.update(user)
|
.update(user)
|
||||||
.set({ trustedOrigins: next })
|
.set({ trustedOrigins: next })
|
||||||
.where(eq(user.id, ownerId));
|
.where(eq(user.id, ownerId));
|
||||||
|
invalidateTrustedOriginsCache();
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { sso } from "@better-auth/sso";
|
|||||||
import * as bcrypt from "bcrypt";
|
import * as bcrypt from "bcrypt";
|
||||||
import { betterAuth } from "better-auth";
|
import { betterAuth } from "better-auth";
|
||||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
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 { admin, organization, twoFactor } from "better-auth/plugins";
|
||||||
import { and, desc, eq } from "drizzle-orm";
|
import { and, desc, eq } from "drizzle-orm";
|
||||||
import { IS_CLOUD } from "../constants";
|
import { IS_CLOUD } from "../constants";
|
||||||
@@ -29,6 +29,37 @@ import { getPublicIpWithFallback } from "../wss/utils";
|
|||||||
import { ac, adminRole, memberRole, ownerRole } from "./access-control";
|
import { ac, adminRole, memberRole, ownerRole } from "./access-control";
|
||||||
import { betterAuthSecret } from "./auth-secret";
|
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({
|
const { handler, api } = betterAuth({
|
||||||
database: drizzleAdapter(db, {
|
database: drizzleAdapter(db, {
|
||||||
provider: "pg",
|
provider: "pg",
|
||||||
@@ -80,33 +111,14 @@ const { handler, api } = betterAuth({
|
|||||||
logger: {
|
logger: {
|
||||||
disabled: process.env.NODE_ENV === "production",
|
disabled: process.env.NODE_ENV === "production",
|
||||||
},
|
},
|
||||||
async trustedOrigins() {
|
trustedOrigins: resolveTrustedOrigins,
|
||||||
try {
|
hooks: {
|
||||||
if (IS_CLOUD) {
|
before: createAuthMiddleware(async (ctx) => {
|
||||||
return await getTrustedOrigins();
|
ctx.context.trustedOrigins = [
|
||||||
}
|
...(ctx.context.baseURL ? [new URL(ctx.context.baseURL).origin] : []),
|
||||||
const [trustedOrigins, settings] = await Promise.all([
|
...(await resolveTrustedOrigins()),
|
||||||
getTrustedOrigins(),
|
].filter(Boolean);
|
||||||
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 [];
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
emailVerification: {
|
emailVerification: {
|
||||||
sendOnSignUp: true,
|
sendOnSignUp: true,
|
||||||
|
|||||||
@@ -120,6 +120,10 @@ export const getDokployUrl = async () => {
|
|||||||
const TRUSTED_ORIGINS_CACHE_TTL_MS = 30 * 60_000;
|
const TRUSTED_ORIGINS_CACHE_TTL_MS = 30 * 60_000;
|
||||||
let trustedOriginsCache: { data: string[]; expiresAt: number } | null = null;
|
let trustedOriginsCache: { data: string[]; expiresAt: number } | null = null;
|
||||||
|
|
||||||
|
export const invalidateTrustedOriginsCache = () => {
|
||||||
|
trustedOriginsCache = null;
|
||||||
|
};
|
||||||
|
|
||||||
export const getTrustedOrigins = async () => {
|
export const getTrustedOrigins = async () => {
|
||||||
const runQuery = async () => {
|
const runQuery = async () => {
|
||||||
const rows = await db
|
const rows = await db
|
||||||
|
|||||||
Reference in New Issue
Block a user