From 92f2f16656af244cd56a7e5d2dae75f8cd8ff6f4 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 19 Jun 2024 13:46:17 +0800 Subject: [PATCH] misc: added option for trusting OIDC emails by default --- .../20240617041053_add-oidc-auth.ts | 16 +++++++++ backend/src/db/schemas/super-admin.ts | 3 +- .../ee/services/oidc/oidc-config-service.ts | 18 ++++++++-- backend/src/server/routes/v1/admin-router.ts | 3 +- frontend/src/hooks/api/admin/types.ts | 1 + .../admin/DashboardPage/DashboardPage.tsx | 35 +++++++++++++++---- 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/backend/src/db/migrations/20240617041053_add-oidc-auth.ts b/backend/src/db/migrations/20240617041053_add-oidc-auth.ts index 8ef34854b..b74f0040a 100644 --- a/backend/src/db/migrations/20240617041053_add-oidc-auth.ts +++ b/backend/src/db/migrations/20240617041053_add-oidc-auth.ts @@ -24,8 +24,24 @@ export async function up(knex: Knex): Promise { tb.foreign("orgId").references("id").inTable(TableName.Organization); }); } + + if (await knex.schema.hasTable(TableName.SuperAdmin)) { + if (!(await knex.schema.hasColumn(TableName.SuperAdmin, "trustOidcEmails"))) { + await knex.schema.alterTable(TableName.SuperAdmin, (tb) => { + tb.boolean("trustOidcEmails").defaultTo(false); + }); + } + } } export async function down(knex: Knex): Promise { await knex.schema.dropTableIfExists(TableName.OidcConfig); + + if (await knex.schema.hasTable(TableName.SuperAdmin)) { + if (await knex.schema.hasColumn(TableName.SuperAdmin, "trustOidcEmails")) { + await knex.schema.alterTable(TableName.SuperAdmin, (t) => { + t.dropColumn("trustOidcEmails"); + }); + } + } } diff --git a/backend/src/db/schemas/super-admin.ts b/backend/src/db/schemas/super-admin.ts index 417d4e05e..87ba35c83 100644 --- a/backend/src/db/schemas/super-admin.ts +++ b/backend/src/db/schemas/super-admin.ts @@ -16,7 +16,8 @@ export const SuperAdminSchema = z.object({ allowedSignUpDomain: z.string().nullable().optional(), instanceId: z.string().uuid().default("00000000-0000-0000-0000-000000000000"), trustSamlEmails: z.boolean().default(false).nullable().optional(), - trustLdapEmails: z.boolean().default(false).nullable().optional() + trustLdapEmails: z.boolean().default(false).nullable().optional(), + trustOidcEmails: z.boolean().default(false).nullable().optional() }); export type TSuperAdmin = z.infer; diff --git a/backend/src/ee/services/oidc/oidc-config-service.ts b/backend/src/ee/services/oidc/oidc-config-service.ts index 3f58036b6..546de7d9d 100644 --- a/backend/src/ee/services/oidc/oidc-config-service.ts +++ b/backend/src/ee/services/oidc/oidc-config-service.ts @@ -25,6 +25,7 @@ import { TOrgBotDALFactory } from "@app/services/org/org-bot-dal"; import { TOrgDALFactory } from "@app/services/org/org-dal"; import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal"; import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service"; +import { getServerCfg } from "@app/services/super-admin/super-admin-service"; import { TUserDALFactory } from "@app/services/user/user-dal"; import { normalizeUsername } from "@app/services/user/user-fns"; import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal"; @@ -144,6 +145,7 @@ export const oidcConfigServiceFactory = ({ }; const oidcLogin = async ({ externalId, email, firstName, lastName, orgId, callbackPort }: TOidcLoginDTO) => { + const serverCfg = await getServerCfg(); const appCfg = getConfig(); const userAlias = await userAliasDAL.findOne({ externalId, @@ -192,14 +194,25 @@ export const oidcConfigServiceFactory = ({ } else { user = await userDAL.transaction(async (tx) => { let newUser: TUsers | undefined; + + if (serverCfg.trustOidcEmails) { + newUser = await userDAL.findOne( + { + email, + isEmailVerified: true + }, + tx + ); + } + if (!newUser) { const uniqueUsername = await normalizeUsername(externalId, userDAL); newUser = await userDAL.create( { email, firstName, - isEmailVerified: false, - username: uniqueUsername, + isEmailVerified: serverCfg.trustOidcEmails, + username: serverCfg.trustOidcEmails ? email : uniqueUsername, lastName, authMethods: [], isGhost: false @@ -252,6 +265,7 @@ export const oidcConfigServiceFactory = ({ return newUser; }); } + await licenseService.updateSubscriptionOrgMemberCount(organization.id); const isUserCompleted = Boolean(user.isAccepted); diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index 572409d9b..d8f64b86f 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -51,7 +51,8 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { allowSignUp: z.boolean().optional(), allowedSignUpDomain: z.string().optional().nullable(), trustSamlEmails: z.boolean().optional(), - trustLdapEmails: z.boolean().optional() + trustLdapEmails: z.boolean().optional(), + trustOidcEmails: z.boolean().optional() }), response: { 200: z.object({ diff --git a/frontend/src/hooks/api/admin/types.ts b/frontend/src/hooks/api/admin/types.ts index 6a42e6ed0..80025ab8f 100644 --- a/frontend/src/hooks/api/admin/types.ts +++ b/frontend/src/hooks/api/admin/types.ts @@ -5,6 +5,7 @@ export type TServerConfig = { isMigrationModeOn?: boolean; trustSamlEmails: boolean; trustLdapEmails: boolean; + trustOidcEmails: boolean; isSecretScanningDisabled: boolean; }; diff --git a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx index 52fddb22c..c5f7db906 100644 --- a/frontend/src/views/admin/DashboardPage/DashboardPage.tsx +++ b/frontend/src/views/admin/DashboardPage/DashboardPage.tsx @@ -39,7 +39,8 @@ const formSchema = z.object({ signUpMode: z.nativeEnum(SignUpModes), allowedSignUpDomain: z.string().optional().nullable(), trustSamlEmails: z.boolean(), - trustLdapEmails: z.boolean() + trustLdapEmails: z.boolean(), + trustOidcEmails: z.boolean() }); type TDashboardForm = z.infer; @@ -60,7 +61,8 @@ export const AdminDashboardPage = () => { signUpMode: config.allowSignUp ? SignUpModes.Anyone : SignUpModes.Disabled, allowedSignUpDomain: config.allowedSignUpDomain, trustSamlEmails: config.trustSamlEmails, - trustLdapEmails: config.trustLdapEmails + trustLdapEmails: config.trustLdapEmails, + trustOidcEmails: config.trustOidcEmails } }); @@ -84,13 +86,15 @@ export const AdminDashboardPage = () => { const onFormSubmit = async (formData: TDashboardForm) => { try { - const { signUpMode, allowedSignUpDomain, trustSamlEmails, trustLdapEmails } = formData; + const { signUpMode, allowedSignUpDomain, trustSamlEmails, trustLdapEmails, trustOidcEmails } = + formData; await updateServerConfig({ allowSignUp: signUpMode !== SignUpModes.Disabled, allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : null, trustSamlEmails, - trustLdapEmails + trustLdapEmails, + trustOidcEmails }); createNotification({ text: "Successfully changed sign up setting.", @@ -190,9 +194,9 @@ export const AdminDashboardPage = () => {
Trust emails
- Select if you want Infisical to trust external emails from SAML/LDAP identity - providers. If set to false, then Infisical will prompt SAML/LDAP provisioned - users to verify their email upon their first login. + Select if you want Infisical to trust external emails from SAML/LDAP/OIDC + identity providers. If set to false, then Infisical will prompt SAML/LDAP + provisioned users to verify their email upon their first login.
{ ); }} /> + { + return ( + + field.onChange(value)} + isChecked={field.value} + > +

Trust OIDC emails

+
+
+ ); + }} + />