diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index fafd40dbc8..326fbafa61 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -455,7 +455,6 @@ export const registerRoutes = async ( userDAL, authService: loginService, serverCfgDAL: superAdminDAL, - orgDAL, orgService, keyStore }); diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index fe6dd972cd..063481c2c6 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -53,7 +53,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { allowedSignUpDomain: z.string().optional().nullable(), trustSamlEmails: z.boolean().optional(), trustLdapEmails: z.boolean().optional(), - defaultAuthOrgSlug: z.string().optional().nullable() + defaultAuthOrgId: z.string().optional().nullable() }), response: { 200: z.object({ diff --git a/backend/src/services/super-admin/super-admin-dal.ts b/backend/src/services/super-admin/super-admin-dal.ts index 9fd47b9acf..eae42cbe11 100644 --- a/backend/src/services/super-admin/super-admin-dal.ts +++ b/backend/src/services/super-admin/super-admin-dal.ts @@ -1,14 +1,16 @@ +import { Knex } from "knex"; + import { TDbClient } from "@app/db"; -import { TableName, TSuperAdmin } from "@app/db/schemas"; +import { TableName, TSuperAdmin, TSuperAdminUpdate } from "@app/db/schemas"; import { ormify } from "@app/lib/knex"; export type TSuperAdminDALFactory = ReturnType; export const superAdminDALFactory = (db: TDbClient) => { - const orm = ormify(db, TableName.SuperAdmin); + const superAdminOrm = ormify(db, TableName.SuperAdmin); - const findById = async (id: string) => { - const config = await db(TableName.SuperAdmin) + const findById = async (id: string, tx?: Knex) => { + const config = await (tx || db)(TableName.SuperAdmin) .where(`${TableName.SuperAdmin}.id`, id) .leftJoin(TableName.Organization, `${TableName.SuperAdmin}.defaultAuthOrgId`, `${TableName.Organization}.id`) .select( @@ -23,8 +25,20 @@ export const superAdminDALFactory = (db: TDbClient) => { } as TSuperAdmin & { defaultAuthOrgSlug: string | null }; }; + const updateById = async (id: string, data: TSuperAdminUpdate, tx?: Knex) => { + const updatedConfig = await superAdminOrm.transaction(async (trx) => { + await superAdminOrm.updateById(id, data, tx || trx); + const config = await findById(id, tx || trx); + + return config; + }); + + return updatedConfig; + }; + return { - ...orm, - findById + ...superAdminOrm, + findById, + updateById }; }; diff --git a/backend/src/services/super-admin/super-admin-service.ts b/backend/src/services/super-admin/super-admin-service.ts index 41d70b6989..6af6f670e5 100644 --- a/backend/src/services/super-admin/super-admin-service.ts +++ b/backend/src/services/super-admin/super-admin-service.ts @@ -1,24 +1,21 @@ import bcrypt from "bcrypt"; -import { TOrganizations, TSuperAdmin } from "@app/db/schemas"; +import { TSuperAdmin, TSuperAdminUpdate } from "@app/db/schemas"; import { TKeyStoreFactory } from "@app/keystore/keystore"; import { getConfig } from "@app/lib/config/env"; import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; import { getUserPrivateKey } from "@app/lib/crypto/srp"; import { BadRequestError } from "@app/lib/errors"; -import { omit } from "@app/lib/fn"; import { TAuthLoginFactory } from "../auth/auth-login-service"; import { AuthMethod } from "../auth/auth-type"; -import { TOrgDALFactory } from "../org/org-dal"; import { TOrgServiceFactory } from "../org/org-service"; import { TUserDALFactory } from "../user/user-dal"; import { TSuperAdminDALFactory } from "./super-admin-dal"; -import { TAdminSignUpDTO, TUpdateServerCfgDTO } from "./super-admin-types"; +import { TAdminSignUpDTO } from "./super-admin-types"; type TSuperAdminServiceFactoryDep = { serverCfgDAL: TSuperAdminDALFactory; - orgDAL: Pick; userDAL: TUserDALFactory; authService: Pick; orgService: Pick; @@ -36,7 +33,6 @@ const ADMIN_CONFIG_DB_UUID = "00000000-0000-0000-0000-000000000000"; export const superAdminServiceFactory = ({ serverCfgDAL, - orgDAL, userDAL, authService, orgService, @@ -76,33 +72,11 @@ export const superAdminServiceFactory = ({ return newCfg; }; - const updateServerCfg = async (data: TUpdateServerCfgDTO) => { - let organization: TOrganizations | undefined; - if (data.defaultAuthOrgSlug) { - organization = await orgDAL.findOne({ - slug: data.defaultAuthOrgSlug - }); - - if (!organization) { - throw new BadRequestError({ - name: "Update server config", - message: "Failed to find default organization" - }); - } - } - - const updatedServerCfg = await serverCfgDAL.updateById(ADMIN_CONFIG_DB_UUID, { - ...omit(data, ["defaultAuthOrgSlug"]), - defaultAuthOrgId: organization?.id || null - }); - - const result = { - ...updatedServerCfg, - defaultAuthOrgSlug: organization?.slug || null - }; + const updateServerCfg = async (data: TSuperAdminUpdate) => { + const updatedServerCfg = await serverCfgDAL.updateById(ADMIN_CONFIG_DB_UUID, data); - await keyStore.setItemWithExpiry(ADMIN_CONFIG_KEY, ADMIN_CONFIG_KEY_EXP, JSON.stringify(result)); - return result; + await keyStore.setItemWithExpiry(ADMIN_CONFIG_KEY, ADMIN_CONFIG_KEY_EXP, JSON.stringify(updatedServerCfg)); + return updatedServerCfg; }; const adminSignUp = async ({ diff --git a/backend/src/services/super-admin/super-admin-types.ts b/backend/src/services/super-admin/super-admin-types.ts index 94742751c9..e444c8843a 100644 --- a/backend/src/services/super-admin/super-admin-types.ts +++ b/backend/src/services/super-admin/super-admin-types.ts @@ -1,5 +1,3 @@ -import { TSuperAdminUpdate } from "@app/db/schemas"; - export type TAdminSignUpDTO = { email: string; password: string; @@ -17,7 +15,3 @@ export type TAdminSignUpDTO = { ip: string; userAgent: string; }; - -export type TUpdateServerCfgDTO = Omit & { - defaultAuthOrgSlug?: string | null; -}; diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 5b7baf26c6..c53bef98d3 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -21,7 +21,7 @@ import { Tabs } from "@app/components/v2"; import { useOrganization, useServerConfig, useUser } from "@app/context"; -import { useUpdateServerConfig } from "@app/hooks/api"; +import { useGetOrganizations, useUpdateServerConfig } from "@app/hooks/api"; import { RateLimitPanel } from "./RateLimitPanel"; @@ -40,7 +40,7 @@ const formSchema = z.object({ allowedSignUpDomain: z.string().optional().nullable(), trustSamlEmails: z.boolean(), trustLdapEmails: z.boolean(), - defaultAuthOrgSlug: z.string().optional().nullable() + defaultAuthOrgId: z.string() }); type TDashboardForm = z.infer; @@ -62,7 +62,7 @@ export const AdminDashboardPage = () => { allowedSignUpDomain: config.allowedSignUpDomain, trustSamlEmails: config.trustSamlEmails, trustLdapEmails: config.trustLdapEmails, - defaultAuthOrgSlug: config.defaultAuthOrgSlug + defaultAuthOrgId: config.defaultAuthOrgId ?? "" } }); @@ -72,6 +72,8 @@ export const AdminDashboardPage = () => { const { orgs } = useOrganization(); const { mutateAsync: updateServerConfig } = useUpdateServerConfig(); + const organizations = useGetOrganizations(); + const isNotAllowed = !user?.superAdmin; // TODO(akhilmhdh): on nextjs 14 roadmap this will be properly addressed with context split @@ -91,11 +93,11 @@ export const AdminDashboardPage = () => { allowedSignUpDomain, trustSamlEmails, trustLdapEmails, - defaultAuthOrgSlug + defaultAuthOrgId } = formData; await updateServerConfig({ - defaultAuthOrgSlug, + defaultAuthOrgId: defaultAuthOrgId || null, allowSignUp: signUpMode !== SignUpModes.Disabled, allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : null, trustSamlEmails, @@ -151,13 +153,13 @@ export const AdminDashboardPage = () => { name="signUpMode" render={({ field: { onChange, ...field }, fieldState: { error } }) => ( + )} />