mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 21:26:17 +00:00
Fix: Requested changes
This commit is contained in:
@@ -458,7 +458,6 @@ export const registerRoutes = async (
|
|||||||
userDAL,
|
userDAL,
|
||||||
authService: loginService,
|
authService: loginService,
|
||||||
serverCfgDAL: superAdminDAL,
|
serverCfgDAL: superAdminDAL,
|
||||||
orgDAL,
|
|
||||||
orgService,
|
orgService,
|
||||||
keyStore
|
keyStore
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
|
|||||||
trustSamlEmails: z.boolean().optional(),
|
trustSamlEmails: z.boolean().optional(),
|
||||||
trustLdapEmails: z.boolean().optional(),
|
trustLdapEmails: z.boolean().optional(),
|
||||||
trustOidcEmails: z.boolean().optional(),
|
trustOidcEmails: z.boolean().optional(),
|
||||||
defaultAuthOrgSlug: z.string().optional().nullable()
|
defaultAuthOrgId: z.string().optional().nullable()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import { TDbClient } from "@app/db";
|
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";
|
import { ormify } from "@app/lib/knex";
|
||||||
|
|
||||||
export type TSuperAdminDALFactory = ReturnType<typeof superAdminDALFactory>;
|
export type TSuperAdminDALFactory = ReturnType<typeof superAdminDALFactory>;
|
||||||
|
|
||||||
export const superAdminDALFactory = (db: TDbClient) => {
|
export const superAdminDALFactory = (db: TDbClient) => {
|
||||||
const orm = ormify(db, TableName.SuperAdmin);
|
const superAdminOrm = ormify(db, TableName.SuperAdmin);
|
||||||
|
|
||||||
const findById = async (id: string) => {
|
const findById = async (id: string, tx?: Knex) => {
|
||||||
const config = await db(TableName.SuperAdmin)
|
const config = await (tx || db)(TableName.SuperAdmin)
|
||||||
.where(`${TableName.SuperAdmin}.id`, id)
|
.where(`${TableName.SuperAdmin}.id`, id)
|
||||||
.leftJoin(TableName.Organization, `${TableName.SuperAdmin}.defaultAuthOrgId`, `${TableName.Organization}.id`)
|
.leftJoin(TableName.Organization, `${TableName.SuperAdmin}.defaultAuthOrgId`, `${TableName.Organization}.id`)
|
||||||
.select(
|
.select(
|
||||||
@@ -23,8 +25,20 @@ export const superAdminDALFactory = (db: TDbClient) => {
|
|||||||
} as TSuperAdmin & { defaultAuthOrgSlug: string | null };
|
} 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 {
|
return {
|
||||||
...orm,
|
...superAdminOrm,
|
||||||
findById
|
findById,
|
||||||
|
updateById
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
import bcrypt from "bcrypt";
|
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 { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
||||||
import { getUserPrivateKey } from "@app/lib/crypto/srp";
|
import { getUserPrivateKey } from "@app/lib/crypto/srp";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
import { omit } from "@app/lib/fn";
|
|
||||||
|
|
||||||
import { TAuthLoginFactory } from "../auth/auth-login-service";
|
import { TAuthLoginFactory } from "../auth/auth-login-service";
|
||||||
import { AuthMethod } from "../auth/auth-type";
|
import { AuthMethod } from "../auth/auth-type";
|
||||||
import { TOrgDALFactory } from "../org/org-dal";
|
|
||||||
import { TOrgServiceFactory } from "../org/org-service";
|
import { TOrgServiceFactory } from "../org/org-service";
|
||||||
import { TUserDALFactory } from "../user/user-dal";
|
import { TUserDALFactory } from "../user/user-dal";
|
||||||
import { TSuperAdminDALFactory } from "./super-admin-dal";
|
import { TSuperAdminDALFactory } from "./super-admin-dal";
|
||||||
import { TAdminSignUpDTO, TUpdateServerCfgDTO } from "./super-admin-types";
|
import { TAdminSignUpDTO } from "./super-admin-types";
|
||||||
|
|
||||||
type TSuperAdminServiceFactoryDep = {
|
type TSuperAdminServiceFactoryDep = {
|
||||||
serverCfgDAL: TSuperAdminDALFactory;
|
serverCfgDAL: TSuperAdminDALFactory;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findOne">;
|
|
||||||
userDAL: TUserDALFactory;
|
userDAL: TUserDALFactory;
|
||||||
authService: Pick<TAuthLoginFactory, "generateUserTokens">;
|
authService: Pick<TAuthLoginFactory, "generateUserTokens">;
|
||||||
orgService: Pick<TOrgServiceFactory, "createOrganization">;
|
orgService: Pick<TOrgServiceFactory, "createOrganization">;
|
||||||
@@ -36,7 +33,6 @@ const ADMIN_CONFIG_DB_UUID = "00000000-0000-0000-0000-000000000000";
|
|||||||
|
|
||||||
export const superAdminServiceFactory = ({
|
export const superAdminServiceFactory = ({
|
||||||
serverCfgDAL,
|
serverCfgDAL,
|
||||||
orgDAL,
|
|
||||||
userDAL,
|
userDAL,
|
||||||
authService,
|
authService,
|
||||||
orgService,
|
orgService,
|
||||||
@@ -76,33 +72,11 @@ export const superAdminServiceFactory = ({
|
|||||||
return newCfg;
|
return newCfg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateServerCfg = async (data: TUpdateServerCfgDTO) => {
|
const updateServerCfg = async (data: TSuperAdminUpdate) => {
|
||||||
let organization: TOrganizations | undefined;
|
const updatedServerCfg = await serverCfgDAL.updateById(ADMIN_CONFIG_DB_UUID, data);
|
||||||
if (data.defaultAuthOrgSlug) {
|
|
||||||
organization = await orgDAL.findOne({
|
|
||||||
slug: data.defaultAuthOrgSlug
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!organization) {
|
await keyStore.setItemWithExpiry(ADMIN_CONFIG_KEY, ADMIN_CONFIG_KEY_EXP, JSON.stringify(updatedServerCfg));
|
||||||
throw new BadRequestError({
|
return updatedServerCfg;
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
await keyStore.setItemWithExpiry(ADMIN_CONFIG_KEY, ADMIN_CONFIG_KEY_EXP, JSON.stringify(result));
|
|
||||||
return result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const adminSignUp = async ({
|
const adminSignUp = async ({
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { TSuperAdminUpdate } from "@app/db/schemas";
|
|
||||||
|
|
||||||
export type TAdminSignUpDTO = {
|
export type TAdminSignUpDTO = {
|
||||||
email: string;
|
email: string;
|
||||||
password: string;
|
password: string;
|
||||||
@@ -17,7 +15,3 @@ export type TAdminSignUpDTO = {
|
|||||||
ip: string;
|
ip: string;
|
||||||
userAgent: string;
|
userAgent: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TUpdateServerCfgDTO = Omit<TSuperAdminUpdate, "defaultAuthOrgId"> & {
|
|
||||||
defaultAuthOrgSlug?: string | null;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
Tabs
|
Tabs
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { useOrganization, useServerConfig, useUser } from "@app/context";
|
import { useOrganization, useServerConfig, useUser } from "@app/context";
|
||||||
import { useUpdateServerConfig } from "@app/hooks/api";
|
import { useGetOrganizations, useUpdateServerConfig } from "@app/hooks/api";
|
||||||
|
|
||||||
import { RateLimitPanel } from "./RateLimitPanel";
|
import { RateLimitPanel } from "./RateLimitPanel";
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ const formSchema = z.object({
|
|||||||
trustSamlEmails: z.boolean(),
|
trustSamlEmails: z.boolean(),
|
||||||
trustLdapEmails: z.boolean(),
|
trustLdapEmails: z.boolean(),
|
||||||
trustOidcEmails: z.boolean(),
|
trustOidcEmails: z.boolean(),
|
||||||
defaultAuthOrgSlug: z.string().optional().nullable()
|
defaultAuthOrgId: z.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
type TDashboardForm = z.infer<typeof formSchema>;
|
type TDashboardForm = z.infer<typeof formSchema>;
|
||||||
@@ -64,7 +64,7 @@ export const AdminDashboardPage = () => {
|
|||||||
trustSamlEmails: config.trustSamlEmails,
|
trustSamlEmails: config.trustSamlEmails,
|
||||||
trustLdapEmails: config.trustLdapEmails,
|
trustLdapEmails: config.trustLdapEmails,
|
||||||
trustOidcEmails: config.trustOidcEmails,
|
trustOidcEmails: config.trustOidcEmails,
|
||||||
defaultAuthOrgSlug: config.defaultAuthOrgSlug
|
defaultAuthOrgId: config.defaultAuthOrgId ?? ""
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -74,6 +74,8 @@ export const AdminDashboardPage = () => {
|
|||||||
const { orgs } = useOrganization();
|
const { orgs } = useOrganization();
|
||||||
const { mutateAsync: updateServerConfig } = useUpdateServerConfig();
|
const { mutateAsync: updateServerConfig } = useUpdateServerConfig();
|
||||||
|
|
||||||
|
const organizations = useGetOrganizations();
|
||||||
|
|
||||||
const isNotAllowed = !user?.superAdmin;
|
const isNotAllowed = !user?.superAdmin;
|
||||||
|
|
||||||
// TODO(akhilmhdh): on nextjs 14 roadmap this will be properly addressed with context split
|
// TODO(akhilmhdh): on nextjs 14 roadmap this will be properly addressed with context split
|
||||||
@@ -94,11 +96,11 @@ export const AdminDashboardPage = () => {
|
|||||||
trustSamlEmails,
|
trustSamlEmails,
|
||||||
trustLdapEmails,
|
trustLdapEmails,
|
||||||
trustOidcEmails,
|
trustOidcEmails,
|
||||||
defaultAuthOrgSlug
|
defaultAuthOrgId
|
||||||
} = formData;
|
} = formData;
|
||||||
|
|
||||||
await updateServerConfig({
|
await updateServerConfig({
|
||||||
defaultAuthOrgSlug,
|
defaultAuthOrgId: defaultAuthOrgId || null,
|
||||||
allowSignUp: signUpMode !== SignUpModes.Disabled,
|
allowSignUp: signUpMode !== SignUpModes.Disabled,
|
||||||
allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : null,
|
allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : null,
|
||||||
trustSamlEmails,
|
trustSamlEmails,
|
||||||
@@ -155,13 +157,13 @@ export const AdminDashboardPage = () => {
|
|||||||
name="signUpMode"
|
name="signUpMode"
|
||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
className="max-w-72 w-72"
|
className="max-w-sm"
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
className="w-72 bg-mineshaft-700"
|
className="w-full bg-mineshaft-700"
|
||||||
dropdownContainerClassName="bg-mineshaft-700"
|
dropdownContainerClassName="bg-mineshaft-800"
|
||||||
defaultValue={field.value}
|
defaultValue={field.value}
|
||||||
onValueChange={(e) => onChange(e)}
|
onValueChange={(e) => onChange(e)}
|
||||||
{...field}
|
{...field}
|
||||||
@@ -203,7 +205,7 @@ export const AdminDashboardPage = () => {
|
|||||||
|
|
||||||
<div className="flex flex-col justify-start">
|
<div className="flex flex-col justify-start">
|
||||||
<div className="mb-2 text-xl font-semibold text-mineshaft-100">
|
<div className="mb-2 text-xl font-semibold text-mineshaft-100">
|
||||||
Default organization slug
|
Default organization
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4 max-w-sm text-sm text-mineshaft-400">
|
<div className="mb-4 max-w-sm text-sm text-mineshaft-400">
|
||||||
Select the slug of the organization you want to set as default for SAML/LDAP
|
Select the slug of the organization you want to set as default for SAML/LDAP
|
||||||
@@ -212,16 +214,33 @@ export const AdminDashboardPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue=""
|
name="defaultAuthOrgId"
|
||||||
name="defaultAuthOrgSlug"
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
render={({ field, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Default organization slug"
|
className="max-w-sm"
|
||||||
className="w-72"
|
|
||||||
isError={Boolean(error)}
|
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
|
isError={Boolean(error)}
|
||||||
>
|
>
|
||||||
<Input {...field} value={field.value || ""} placeholder="acme-corp" />
|
<Select
|
||||||
|
className="w-full bg-mineshaft-700"
|
||||||
|
dropdownContainerClassName="bg-mineshaft-800"
|
||||||
|
defaultValue={field.value ?? " "}
|
||||||
|
onValueChange={(e) => {
|
||||||
|
if (e === " ") {
|
||||||
|
onChange(null);
|
||||||
|
} else {
|
||||||
|
onChange(e);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{...field}
|
||||||
|
>
|
||||||
|
<SelectItem value=" ">Select organization...</SelectItem>
|
||||||
|
{organizations.data?.map((org) => (
|
||||||
|
<SelectItem key={org.id} value={org.id}>
|
||||||
|
{org.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user