From 8a14914bc324c9918da1ee9b4b87c4dfa0091b7b Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Fri, 8 Nov 2024 21:43:25 +0800 Subject: [PATCH 1/4] misc: added more error handling --- .../ee/services/oidc/oidc-config-service.ts | 48 +++++++++++++++---- backend/src/lib/errors/index.ts | 12 +++++ backend/src/server/boot-strap-check.ts | 4 +- backend/src/server/plugins/error-handler.ts | 6 ++- backend/src/services/smtp/smtp-service.ts | 18 ++++++- 5 files changed, 74 insertions(+), 14 deletions(-) diff --git a/backend/src/ee/services/oidc/oidc-config-service.ts b/backend/src/ee/services/oidc/oidc-config-service.ts index 17c1ddaaf2..c7d9ac8c67 100644 --- a/backend/src/ee/services/oidc/oidc-config-service.ts +++ b/backend/src/ee/services/oidc/oidc-config-service.ts @@ -17,7 +17,7 @@ import { infisicalSymmetricDecrypt, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; -import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; +import { BadRequestError, ForbiddenRequestError, NotFoundError, OidcAuthError } from "@app/lib/errors"; import { AuthMethod, AuthTokenType } from "@app/services/auth/auth-type"; import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service"; import { TokenType } from "@app/services/auth-token/auth-token-types"; @@ -56,7 +56,7 @@ type TOidcConfigServiceFactoryDep = { orgBotDAL: Pick; licenseService: Pick; tokenService: Pick; - smtpService: Pick; + smtpService: Pick; permissionService: Pick; oidcConfigDAL: Pick; }; @@ -223,6 +223,7 @@ export const oidcConfigServiceFactory = ({ let newUser: TUsers | undefined; if (serverCfg.trustOidcEmails) { + // we prioritize getting the most complete user to create the new alias under newUser = await userDAL.findOne( { email, @@ -230,6 +231,16 @@ export const oidcConfigServiceFactory = ({ }, tx ); + + if (!newUser) { + // this fetches user entries created via invites + newUser = await userDAL.findOne( + { + username: email + }, + tx + ); + } } if (!newUser) { @@ -332,14 +343,20 @@ export const oidcConfigServiceFactory = ({ userId: user.id }); - await smtpService.sendMail({ - template: SmtpTemplates.EmailVerification, - subjectLine: "Infisical confirmation code", - recipients: [user.email], - substitutions: { - code: token - } - }); + await smtpService + .sendMail({ + template: SmtpTemplates.EmailVerification, + subjectLine: "Infisical confirmation code", + recipients: [user.email], + substitutions: { + code: token + } + }) + .catch((err: Error) => { + throw new OidcAuthError({ + message: `Error with SMTP configuration - contact the Infisical instance admin. ${err.message}` + }); + }); } return { isUserCompleted, providerAuthToken }; @@ -395,6 +412,17 @@ export const oidcConfigServiceFactory = ({ message: `Organization bot for organization with ID '${org.id}' not found`, name: "OrgBotNotFound" }); + + const serverCfg = await getServerCfg(); + if (isActive && !serverCfg.trustOidcEmails) { + const isSmtpConnected = await smtpService.verify(); + if (!isSmtpConnected) { + throw new BadRequestError({ + message: "Cannot enable OIDC when there are issues with the instance's SMTP configuration" + }); + } + } + const key = infisicalSymmetricDecrypt({ ciphertext: orgBot.encryptedSymmetricKey, iv: orgBot.symmetricKeyIV, diff --git a/backend/src/lib/errors/index.ts b/backend/src/lib/errors/index.ts index 0818cfe7d9..cc1c1d66b4 100644 --- a/backend/src/lib/errors/index.ts +++ b/backend/src/lib/errors/index.ts @@ -133,3 +133,15 @@ export class ScimRequestError extends Error { this.status = status; } } + +export class OidcAuthError extends Error { + name: string; + + error: unknown; + + constructor({ name, error, message }: { message?: string; name?: string; error?: unknown }) { + super(message || "Something went wrong"); + this.name = name || "OidcAuthError"; + this.error = error; + } +} diff --git a/backend/src/server/boot-strap-check.ts b/backend/src/server/boot-strap-check.ts index ceaef59e7f..696abb8e04 100644 --- a/backend/src/server/boot-strap-check.ts +++ b/backend/src/server/boot-strap-check.ts @@ -48,8 +48,8 @@ export const bootstrapCheck = async ({ db }: BootstrapOpt) => { .then(async () => { console.info("SMTP successfully connected"); }) - .catch((err) => { - console.error(`SMTP - Failed to connect to ${appCfg.SMTP_HOST}:${appCfg.SMTP_PORT}`); + .catch((err: Error) => { + console.error(`SMTP - Failed to connect to ${appCfg.SMTP_HOST}:${appCfg.SMTP_PORT} - ${err.message}`); logger.error(err); }); diff --git a/backend/src/server/plugins/error-handler.ts b/backend/src/server/plugins/error-handler.ts index 007902a176..c08b2fe4c7 100644 --- a/backend/src/server/plugins/error-handler.ts +++ b/backend/src/server/plugins/error-handler.ts @@ -10,6 +10,7 @@ import { GatewayTimeoutError, InternalServerError, NotFoundError, + OidcAuthError, RateLimitError, ScimRequestError, UnauthorizedError @@ -83,7 +84,10 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider status: error.status, detail: error.detail }); - // Handle JWT errors and make them more human-readable for the end-user. + } else if (error instanceof OidcAuthError) { + void res + .status(HttpStatusCodes.InternalServerError) + .send({ statusCode: HttpStatusCodes.InternalServerError, message: error.message, error: error.name }); } else if (error instanceof jwt.JsonWebTokenError) { const message = (() => { if (error.message === JWTErrors.JwtExpired) { diff --git a/backend/src/services/smtp/smtp-service.ts b/backend/src/services/smtp/smtp-service.ts index 1f38babb37..bdf2fe18c5 100644 --- a/backend/src/services/smtp/smtp-service.ts +++ b/backend/src/services/smtp/smtp-service.ts @@ -77,5 +77,21 @@ export const smtpServiceFactory = (cfg: TSmtpConfig) => { } }; - return { sendMail }; + const verify = async () => { + const isConnected = smtp + .verify() + .then(async () => { + logger.info("SMTP connected"); + return true; + }) + .catch((err: Error) => { + logger.error("SMTP error"); + logger.error(err); + return false; + }); + + return isConnected; + }; + + return { sendMail, verify }; }; From 9e4b66e2158267ee6ee3250b69214070b3c4765f Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Sat, 9 Nov 2024 00:38:45 +0800 Subject: [PATCH 2/4] misc: made users automatically verified --- backend/e2e-test/mocks/smtp.ts | 3 +++ backend/src/ee/services/oidc/oidc-config-service.ts | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/backend/e2e-test/mocks/smtp.ts b/backend/e2e-test/mocks/smtp.ts index 9f83f7134a..4ba42e8389 100644 --- a/backend/e2e-test/mocks/smtp.ts +++ b/backend/e2e-test/mocks/smtp.ts @@ -5,6 +5,9 @@ export const mockSmtpServer = (): TSmtpService => { return { sendMail: async (data) => { storage.push(data); + }, + verify: async () => { + return true; } }; }; diff --git a/backend/src/ee/services/oidc/oidc-config-service.ts b/backend/src/ee/services/oidc/oidc-config-service.ts index c7d9ac8c67..085cba8988 100644 --- a/backend/src/ee/services/oidc/oidc-config-service.ts +++ b/backend/src/ee/services/oidc/oidc-config-service.ts @@ -240,6 +240,13 @@ export const oidcConfigServiceFactory = ({ }, tx ); + + if (newUser && !newUser.isEmailVerified) { + // we automatically mark it as email-verified because we've configured trust for OIDC emails + newUser = await userDAL.updateById(newUser.id, { + isEmailVerified: true + }); + } } } From 3f6a0c77f1892ef4a3d27b5d609a8c27c1611fff Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Sat, 9 Nov 2024 01:51:11 +0800 Subject: [PATCH 3/4] misc: finalized user messages --- backend/src/ee/services/oidc/oidc-config-service.ts | 2 +- backend/src/server/boot-strap-check.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/ee/services/oidc/oidc-config-service.ts b/backend/src/ee/services/oidc/oidc-config-service.ts index 085cba8988..4e0e7ba1ed 100644 --- a/backend/src/ee/services/oidc/oidc-config-service.ts +++ b/backend/src/ee/services/oidc/oidc-config-service.ts @@ -361,7 +361,7 @@ export const oidcConfigServiceFactory = ({ }) .catch((err: Error) => { throw new OidcAuthError({ - message: `Error with SMTP configuration - contact the Infisical instance admin. ${err.message}` + message: `Error sending email confirmation code for user registration - contact the Infisical instance admin. ${err.message}` }); }); } diff --git a/backend/src/server/boot-strap-check.ts b/backend/src/server/boot-strap-check.ts index 696abb8e04..7db2a71e82 100644 --- a/backend/src/server/boot-strap-check.ts +++ b/backend/src/server/boot-strap-check.ts @@ -46,7 +46,7 @@ export const bootstrapCheck = async ({ db }: BootstrapOpt) => { await createTransport(smtpCfg) .verify() .then(async () => { - console.info("SMTP successfully connected"); + console.info(`SMTP - Verified connection to ${appCfg.SMTP_HOST}:${appCfg.SMTP_PORT}`); }) .catch((err: Error) => { console.error(`SMTP - Failed to connect to ${appCfg.SMTP_HOST}:${appCfg.SMTP_PORT} - ${err.message}`); From 089a7e880b15589c20aad0297ae0cdd8902fd2dd Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Mon, 18 Nov 2024 17:29:01 +0800 Subject: [PATCH 4/4] misc: added message for bypass --- backend/src/ee/services/oidc/oidc-config-service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/ee/services/oidc/oidc-config-service.ts b/backend/src/ee/services/oidc/oidc-config-service.ts index 4e0e7ba1ed..45a58bd1ea 100644 --- a/backend/src/ee/services/oidc/oidc-config-service.ts +++ b/backend/src/ee/services/oidc/oidc-config-service.ts @@ -425,7 +425,8 @@ export const oidcConfigServiceFactory = ({ const isSmtpConnected = await smtpService.verify(); if (!isSmtpConnected) { throw new BadRequestError({ - message: "Cannot enable OIDC when there are issues with the instance's SMTP configuration" + message: + "Cannot enable OIDC when there are issues with the instance's SMTP configuration. Bypass this by turning on trust for OIDC emails in the server admin console." }); } }