diff --git a/server/private/routers/external.ts b/server/private/routers/external.ts index 53960b743..7872da700 100644 --- a/server/private/routers/external.ts +++ b/server/private/routers/external.ts @@ -89,6 +89,7 @@ authenticated.put( "/org/:orgId/idp/oidc", verifyValidLicense, verifyValidSubscription(tierMatrix.orgOidc), + orgIdp.requireOrgIdentityProviderMode, verifyOrgAccess, verifyLimits, verifyUserHasAction(ActionsEnum.createIdp), @@ -100,6 +101,7 @@ authenticated.post( "/org/:orgId/idp/:idpId/import", verifyValidLicense, verifyValidSubscription(tierMatrix.orgOidc), + orgIdp.requireOrgIdentityProviderMode, verifyOrgAccess, verifyLimits, verifyAdmin, @@ -111,6 +113,7 @@ authenticated.post( "/org/:orgId/idp/:idpId/oidc", verifyValidLicense, verifyValidSubscription(tierMatrix.orgOidc), + orgIdp.requireOrgIdentityProviderMode, verifyOrgAccess, verifyIdpAccess, verifyLimits, @@ -122,6 +125,7 @@ authenticated.post( authenticated.delete( "/org/:orgId/idp/:idpId", verifyValidLicense, + orgIdp.requireOrgIdentityProviderMode, verifyOrgAccess, verifyIdpAccess, verifyUserHasAction(ActionsEnum.deleteIdp), @@ -132,6 +136,7 @@ authenticated.delete( authenticated.delete( "/org/:orgId/idp/:idpId/association", verifyValidLicense, + orgIdp.requireOrgIdentityProviderMode, verifyOrgAccess, verifyIdpAccess, verifyUserHasAction(ActionsEnum.deleteIdp), diff --git a/server/private/routers/orgIdp/createOrgOidcIdp.ts b/server/private/routers/orgIdp/createOrgOidcIdp.ts index b14348a2a..e01d27607 100644 --- a/server/private/routers/orgIdp/createOrgOidcIdp.ts +++ b/server/private/routers/orgIdp/createOrgOidcIdp.ts @@ -27,7 +27,6 @@ import config from "@server/lib/config"; import { CreateOrgIdpResponse } from "@server/routers/orgIdp/types"; import { isSubscribed } from "#private/lib/isSubscribed"; import { tierMatrix } from "@server/lib/billing/tierMatrix"; -import privateConfig from "#private/lib/config"; import { build } from "@server/build"; const paramsSchema = z.strictObject({ orgId: z.string().nonempty() }); @@ -94,18 +93,6 @@ export async function createOrgOidcIdp( ); } - if ( - privateConfig.getRawPrivateConfig().app.identity_provider_mode !== - "org" - ) { - return next( - createHttpError( - HttpCode.BAD_REQUEST, - "Organization-specific IdP creation is not allowed in the current identity provider mode. Set app.identity_provider_mode to 'org' in the private configuration to enable this feature." - ) - ); - } - const { clientId, clientSecret, diff --git a/server/private/routers/orgIdp/deleteOrgIdp.ts b/server/private/routers/orgIdp/deleteOrgIdp.ts index 304826cd1..9e5dfccee 100644 --- a/server/private/routers/orgIdp/deleteOrgIdp.ts +++ b/server/private/routers/orgIdp/deleteOrgIdp.ts @@ -22,7 +22,6 @@ import { fromError } from "zod-validation-error"; import { idp, idpOidcConfig, idpOrg } from "@server/db"; import { eq } from "drizzle-orm"; import { OpenAPITags, registry } from "@server/openApi"; -import privateConfig from "#private/lib/config"; const paramsSchema = z .object({ @@ -60,18 +59,6 @@ export async function deleteOrgIdp( const { idpId } = parsedParams.data; - if ( - privateConfig.getRawPrivateConfig().app.identity_provider_mode !== - "org" - ) { - return next( - createHttpError( - HttpCode.BAD_REQUEST, - "Organization-specific IdP creation is not allowed in the current identity provider mode. Set app.identity_provider_mode to 'org' in the private configuration to enable this feature." - ) - ); - } - // Check if IDP exists const [existingIdp] = await db .select() diff --git a/server/private/routers/orgIdp/importOrgIdp.ts b/server/private/routers/orgIdp/importOrgIdp.ts index 906c504d8..88c62cbac 100644 --- a/server/private/routers/orgIdp/importOrgIdp.ts +++ b/server/private/routers/orgIdp/importOrgIdp.ts @@ -24,7 +24,6 @@ import { idp, idpOrg, orgs, roles, userOrgs } from "@server/db"; import { and, eq, inArray } from "drizzle-orm"; import { CreateOrgIdpResponse } from "@server/routers/orgIdp/types"; import { generateOidcRedirectUrl } from "@server/lib/idp/generateRedirectUrl"; -import privateConfig from "#private/lib/config"; import { checkOrgAccessPolicy } from "#dynamic/lib/checkOrgAccessPolicy"; import { getUserOrgRoleIds } from "@server/lib/userOrgRoles"; @@ -105,18 +104,6 @@ export async function importOrgIdp( const { sourceOrgId } = parsedBody.data; - if ( - privateConfig.getRawPrivateConfig().app.identity_provider_mode !== - "org" - ) { - return next( - createHttpError( - HttpCode.BAD_REQUEST, - "Organization-specific IdP creation is not allowed in the current identity provider mode. Set app.identity_provider_mode to 'org' in the private configuration to enable this feature." - ) - ); - } - if (sourceOrgId === targetOrgId) { return next( createHttpError( diff --git a/server/private/routers/orgIdp/index.ts b/server/private/routers/orgIdp/index.ts index 2997468be..192d883a6 100644 --- a/server/private/routers/orgIdp/index.ts +++ b/server/private/routers/orgIdp/index.ts @@ -19,3 +19,4 @@ export * from "./listUserAdminOrgIdps"; export * from "./updateOrgOidcIdp"; export * from "./deleteOrgIdp"; export * from "./unassociateOrgIdp"; +export * from "./requireOrgIdentityProviderMode"; diff --git a/server/private/routers/orgIdp/requireOrgIdentityProviderMode.ts b/server/private/routers/orgIdp/requireOrgIdentityProviderMode.ts new file mode 100644 index 000000000..7942af123 --- /dev/null +++ b/server/private/routers/orgIdp/requireOrgIdentityProviderMode.ts @@ -0,0 +1,34 @@ +/* + * This file is part of a proprietary work. + * + * Copyright (c) 2025-2026 Fossorial, Inc. + * All rights reserved. + * + * This file is licensed under the Fossorial Commercial License. + * You may not use this file except in compliance with the License. + * Unauthorized use, copying, modification, or distribution is strictly prohibited. + * + * This file is not licensed under the AGPLv3. + */ + +import { NextFunction, Request, Response } from "express"; +import createHttpError from "http-errors"; +import privateConfig from "#private/lib/config"; +import HttpCode from "@server/types/HttpCode"; + +export function requireOrgIdentityProviderMode( + _req: Request, + _res: Response, + next: NextFunction +): void { + if (privateConfig.getRawPrivateConfig().app.identity_provider_mode !== "org") { + return next( + createHttpError( + HttpCode.BAD_REQUEST, + "Organization-specific IdP creation is not allowed in the current identity provider mode. Set app.identity_provider_mode to 'org' in the private configuration to enable this feature." + ) + ); + } + + return next(); +} diff --git a/server/private/routers/orgIdp/unassociateOrgIdp.ts b/server/private/routers/orgIdp/unassociateOrgIdp.ts index e6b0a6a2e..f6ab557b3 100644 --- a/server/private/routers/orgIdp/unassociateOrgIdp.ts +++ b/server/private/routers/orgIdp/unassociateOrgIdp.ts @@ -21,7 +21,6 @@ import logger from "@server/logger"; import { fromError } from "zod-validation-error"; import { and, eq, sql } from "drizzle-orm"; import { OpenAPITags, registry } from "@server/openApi"; -import privateConfig from "#private/lib/config"; const paramsSchema = z .object({ @@ -48,18 +47,6 @@ export async function unassociateOrgIdp( const { orgId, idpId } = parsedParams.data; - if ( - privateConfig.getRawPrivateConfig().app.identity_provider_mode !== - "org" - ) { - return next( - createHttpError( - HttpCode.BAD_REQUEST, - "Organization-specific IdP creation is not allowed in the current identity provider mode. Set app.identity_provider_mode to 'org' in the private configuration to enable this feature." - ) - ); - } - const [association] = await db .select() .from(idpOrg) diff --git a/server/private/routers/orgIdp/updateOrgOidcIdp.ts b/server/private/routers/orgIdp/updateOrgOidcIdp.ts index 17bf2ee35..4043369b3 100644 --- a/server/private/routers/orgIdp/updateOrgOidcIdp.ts +++ b/server/private/routers/orgIdp/updateOrgOidcIdp.ts @@ -26,7 +26,6 @@ import { encrypt } from "@server/lib/crypto"; import config from "@server/lib/config"; import { isSubscribed } from "#private/lib/isSubscribed"; import { tierMatrix } from "@server/lib/billing/tierMatrix"; -import privateConfig from "#private/lib/config"; import { build } from "@server/build"; const paramsSchema = z @@ -99,18 +98,6 @@ export async function updateOrgOidcIdp( ); } - if ( - privateConfig.getRawPrivateConfig().app.identity_provider_mode !== - "org" - ) { - return next( - createHttpError( - HttpCode.BAD_REQUEST, - "Organization-specific IdP creation is not allowed in the current identity provider mode. Set app.identity_provider_mode to 'org' in the private configuration to enable this feature." - ) - ); - } - const { idpId, orgId } = parsedParams.data; const { clientId,