diff --git a/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts b/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts index b65e5aefe..ddd0f55c1 100644 --- a/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts +++ b/packages/hoppscotch-backend/src/infra-config/infra-config.service.ts @@ -16,7 +16,7 @@ import { INFRA_CONFIG_RESET_FAILED, INFRA_CONFIG_UPDATE_FAILED, } from 'src/errors'; -import { throwErr, validateUrl } from 'src/utils'; +import { throwErr, validateSMTPUrl } from 'src/utils'; import { ConfigService } from '@nestjs/config'; import { AuthProviderStatus, stopApp } from './helper'; import { EnableAndDisableSSOArgs, InfraConfigArgs } from './input-args'; @@ -302,7 +302,7 @@ export class InfraConfigService implements OnModuleInit { ) { for (let i = 0; i < infraConfigs.length; i++) { if (infraConfigs[i].name === InfraConfigEnumForClient.MAILER_SMTP_URL) { - const isValidUrl = validateUrl(infraConfigs[i].value); + const isValidUrl = validateSMTPUrl(infraConfigs[i].value); if (!isValidUrl) return E.left(INFRA_CONFIG_INVALID_INPUT); } } diff --git a/packages/hoppscotch-backend/src/utils.ts b/packages/hoppscotch-backend/src/utils.ts index 346e4b214..cc74c30f2 100644 --- a/packages/hoppscotch-backend/src/utils.ts +++ b/packages/hoppscotch-backend/src/utils.ts @@ -136,33 +136,18 @@ export const validateEmail = (email: string) => { * @param url The URL to validate * @returns boolean */ -export const validateUrl = (url: string) => { - /** - * RegExps. - * A URL must match #1 and then at least one of #2/#3. - * Use two levels of REs to avoid REDOS. - */ - const protocolAndDomainRE = /^(?:\w+:)?\/\/(\S+)$/; - const localhostDomainRE = /^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/; - const nonLocalhostDomainRE = /^[^\s\.]+\.\S{2,}$/; +export const validateSMTPUrl = (url: string) => { + // Possible valid formats + // smtp(s)://mail.example.com + // smtp(s)://user:pass@mail.example.com + // smtp(s)://mail.example.com:587 + // smtp(s)://user:pass@mail.example.com:587 - const match = url.match(protocolAndDomainRE); - if (!match) { - return false; - } - - const everythingAfterProtocol = match[1]; - if (!everythingAfterProtocol) { - return false; - } - - if ( - localhostDomainRE.test(everythingAfterProtocol) || - nonLocalhostDomainRE.test(everythingAfterProtocol) - ) { - return true; - } + if (!url || url.length === 0) return false; + const regex = + /^(smtp|smtps):\/\/(?:([^:]+):([^@]+)@)?((?!\.)[^:]+)(?::(\d+))?$/; + if (regex.test(url)) return true; return false; };