refactor: Improve code formatting and readability across multiple files

This commit is contained in:
Nawaz Dhandala
2026-01-12 12:11:57 +00:00
parent 3f3be46789
commit f59c215d1f
9 changed files with 98 additions and 61 deletions

View File

@@ -104,7 +104,9 @@ router.post(
clientSecret: config.clientSecret,
tokenUrl: config.tokenUrl ? URL.fromString(config.tokenUrl) : undefined,
scope: config.scope,
oauthProviderType: config.oauthProviderType as OAuthProviderType | undefined,
oauthProviderType: config.oauthProviderType as
| OAuthProviderType
| undefined,
};
try {

View File

@@ -84,8 +84,10 @@ class TransporterPool {
emailServer: EmailServer,
options: { timeout?: number | undefined },
): Promise<Transporter> {
// For OAuth, we need to create a new transporter each time to get fresh tokens
// The access token has a limited lifetime and needs to be refreshed
/*
* For OAuth, we need to create a new transporter each time to get fresh tokens
* The access token has a limited lifetime and needs to be refreshed
*/
if (emailServer.authType === SMTPAuthenticationType.OAuth) {
return await this.createOAuthTransporter(emailServer, options);
}
@@ -136,15 +138,18 @@ class TransporterPool {
);
}
// Get the access token using the generic OAuth service
// Provider type determines which grant flow to use (Client Credentials vs JWT Bearer)
/*
* Get the access token using the generic OAuth service
* Provider type determines which grant flow to use (Client Credentials vs JWT Bearer)
*/
const accessToken: string = await SMTPOAuthService.getAccessToken({
clientId: emailServer.clientId,
clientSecret: emailServer.clientSecret,
tokenUrl: emailServer.tokenUrl,
scope: emailServer.scope,
username: emailServer.username, // Required for JWT Bearer (user to impersonate)
providerType: emailServer.oauthProviderType || OAuthProviderType.ClientCredentials,
providerType:
emailServer.oauthProviderType || OAuthProviderType.ClientCredentials,
});
logger.debug("Creating OAuth transporter for SMTP");

View File

@@ -80,11 +80,10 @@ export default class SMTPOAuthService {
// Try to get cached token from Redis
try {
const cachedToken: CachedToken | null =
(await GlobalCache.getJSONObject(
this.TOKEN_CACHE_NAMESPACE,
cacheKey,
)) as CachedToken | null;
const cachedToken: CachedToken | null = (await GlobalCache.getJSONObject(
this.TOKEN_CACHE_NAMESPACE,
cacheKey,
)) as CachedToken | null;
if (cachedToken && cachedToken.expiresAt > Date.now()) {
logger.debug("Using cached OAuth token from Redis");

View File

@@ -689,7 +689,8 @@ export default class ProjectSmtpConfig extends BaseModel {
title: "OAuth Token URL",
description:
"The OAuth token endpoint URL. For Microsoft 365: https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token. For Google: https://oauth2.googleapis.com/token",
example: "https://login.microsoftonline.com/your-tenant-id/oauth2/v2.0/token",
example:
"https://login.microsoftonline.com/your-tenant-id/oauth2/v2.0/token",
})
@Column({
nullable: true,

View File

@@ -1,22 +1,41 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class MigrationName1767896933148 implements MigrationInterface {
name = 'MigrationName1767896933148'
name = "MigrationName1767896933148";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ADD "authType" character varying(100) NOT NULL DEFAULT 'Username and Password'`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ADD "clientId" character varying(100)`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ADD "clientSecret" character varying(500)`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ADD "tokenUrl" text`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ADD "scope" character varying(500)`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "scope"`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "tokenUrl"`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "clientSecret"`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "clientId"`);
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "authType"`);
}
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ADD "authType" character varying(100) NOT NULL DEFAULT 'Username and Password'`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ADD "clientId" character varying(100)`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ADD "clientSecret" character varying(500)`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ADD "tokenUrl" text`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ADD "scope" character varying(500)`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "scope"`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "tokenUrl"`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "clientSecret"`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "clientId"`,
);
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "authType"`,
);
}
}

View File

@@ -1,17 +1,24 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class IncreaseClientSecretLength1768216593272 implements MigrationInterface {
name = 'IncreaseClientSecretLength1768216593272'
export class IncreaseClientSecretLength1768216593272
implements MigrationInterface
{
name = "IncreaseClientSecretLength1768216593272";
public async up(queryRunner: QueryRunner): Promise<void> {
// Change clientSecret from varchar(500) to text to support longer OAuth secrets
// (e.g., Google service account private keys which are ~1700+ characters)
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ALTER COLUMN "clientSecret" TYPE text`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
// Revert back to varchar(500)
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ALTER COLUMN "clientSecret" TYPE character varying(500)`);
}
public async up(queryRunner: QueryRunner): Promise<void> {
/*
* Change clientSecret from varchar(500) to text to support longer OAuth secrets
* (e.g., Google service account private keys which are ~1700+ characters)
*/
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ALTER COLUMN "clientSecret" TYPE text`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
// Revert back to varchar(500)
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ALTER COLUMN "clientSecret" TYPE character varying(500)`,
);
}
}

View File

@@ -1,16 +1,21 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class AddOAuthProviderType1768217403078 implements MigrationInterface {
name = 'AddOAuthProviderType1768217403078'
name = "AddOAuthProviderType1768217403078";
public async up(queryRunner: QueryRunner): Promise<void> {
// Add oauthProviderType column to ProjectSMTPConfig table
// Values: 'Client Credentials' (for Microsoft 365, etc.) or 'JWT Bearer' (for Google Workspace)
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" ADD "oauthProviderType" character varying(100)`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "oauthProviderType"`);
}
public async up(queryRunner: QueryRunner): Promise<void> {
/*
* Add oauthProviderType column to ProjectSMTPConfig table
* Values: 'Client Credentials' (for Microsoft 365, etc.) or 'JWT Bearer' (for Google Workspace)
*/
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" ADD "oauthProviderType" character varying(100)`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "oauthProviderType"`,
);
}
}

View File

@@ -1355,11 +1355,7 @@ const Icon: FunctionComponent<ComponentProps> = ({
strokeLinejoin="round"
d="M2 12h3l2-4 3 8 3-6 2 4h7"
/>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M2 20h20"
/>
<path strokeLinecap="round" strokeLinejoin="round" d="M2 20h20" />
</>,
);
} else if (icon === IconProp.Waterfall) {

View File

@@ -163,7 +163,8 @@ const CustomSMTPTable: FunctionComponent = (): ReactElement => {
title: "Use SSL / TLS",
stepId: "server-info",
fieldType: FormFieldSchemaType.Toggle,
description: "Enable secure email communication. Recommended for most providers.",
description:
"Enable secure email communication. Recommended for most providers.",
},
{
field: {
@@ -172,8 +173,9 @@ const CustomSMTPTable: FunctionComponent = (): ReactElement => {
title: "Authentication Type",
stepId: "authentication",
fieldType: FormFieldSchemaType.Dropdown,
dropdownOptions:
DropdownUtil.getDropdownOptionsFromEnum(SMTPAuthenticationType),
dropdownOptions: DropdownUtil.getDropdownOptionsFromEnum(
SMTPAuthenticationType,
),
required: true,
defaultValue: SMTPAuthenticationType.UsernamePassword,
description:
@@ -206,8 +208,8 @@ const CustomSMTPTable: FunctionComponent = (): ReactElement => {
disableSpellCheck: true,
showIf: (values: FormValues<ProjectSmtpConfig>): boolean => {
return (
values["authType"] === SMTPAuthenticationType.UsernamePassword ||
!values["authType"]
values["authType"] ===
SMTPAuthenticationType.UsernamePassword || !values["authType"]
);
},
},
@@ -268,7 +270,8 @@ const CustomSMTPTable: FunctionComponent = (): ReactElement => {
stepId: "oauth-info",
fieldType: FormFieldSchemaType.URL,
required: true,
placeholder: "https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token",
placeholder:
"https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token",
description:
"The OAuth token endpoint URL. For Microsoft 365: https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token. For Google: https://oauth2.googleapis.com/token",
disableSpellCheck: true,