@oneuptime/common 9.3.11 → 9.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/ProjectSmtpConfig.ts +202 -0
- package/Models/DatabaseModels/Service.ts +1 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1767896933148-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1768216593272-IncreaseClientSecretLength.ts +24 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1768217403078-AddOAuthProviderType.ts +21 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Services/AlertService.ts +1 -1
- package/Server/Services/IncidentService.ts +1 -1
- package/Server/Services/ProjectSmtpConfigService.ts +52 -5
- package/Types/Email/EmailServer.ts +11 -0
- package/Types/Email/OAuthProviderType.ts +28 -0
- package/Types/Email/SMTPAuthenticationType.ts +8 -0
- package/Types/Icon/IconProp.ts +3 -0
- package/UI/Components/Icon/Icon.tsx +41 -3
- package/build/dist/Models/DatabaseModels/ProjectSmtpConfig.js +206 -0
- package/build/dist/Models/DatabaseModels/ProjectSmtpConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Service.js +1 -0
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1767896933148-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1767896933148-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768216593272-IncreaseClientSecretLength.js +17 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768216593272-IncreaseClientSecretLength.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768217403078-AddOAuthProviderType.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1768217403078-AddOAuthProviderType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +1 -1
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +1 -1
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/ProjectSmtpConfigService.js +36 -4
- package/build/dist/Server/Services/ProjectSmtpConfigService.js.map +1 -1
- package/build/dist/Types/Email/OAuthProviderType.js +28 -0
- package/build/dist/Types/Email/OAuthProviderType.js.map +1 -0
- package/build/dist/Types/Email/SMTPAuthenticationType.js +9 -0
- package/build/dist/Types/Email/SMTPAuthenticationType.js.map +1 -0
- package/build/dist/Types/Icon/IconProp.js +3 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +22 -2
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,6 +17,8 @@ import TableMetadata from "../../Types/Database/TableMetadata";
|
|
|
17
17
|
import TenantColumn from "../../Types/Database/TenantColumn";
|
|
18
18
|
import UniqueColumnBy from "../../Types/Database/UniqueColumnBy";
|
|
19
19
|
import Email from "../../Types/Email";
|
|
20
|
+
import OAuthProviderType from "../../Types/Email/OAuthProviderType";
|
|
21
|
+
import SMTPAuthenticationType from "../../Types/Email/SMTPAuthenticationType";
|
|
20
22
|
import IconProp from "../../Types/Icon/IconProp";
|
|
21
23
|
import ObjectID from "../../Types/ObjectID";
|
|
22
24
|
import Permission from "../../Types/Permission";
|
|
@@ -561,4 +563,204 @@ export default class ProjectSmtpConfig extends BaseModel {
|
|
|
561
563
|
default: true,
|
|
562
564
|
})
|
|
563
565
|
public secure?: boolean = undefined;
|
|
566
|
+
|
|
567
|
+
// OAuth 2.0 Configuration Fields
|
|
568
|
+
|
|
569
|
+
@ColumnAccessControl({
|
|
570
|
+
create: [
|
|
571
|
+
Permission.ProjectOwner,
|
|
572
|
+
Permission.ProjectAdmin,
|
|
573
|
+
Permission.CreateProjectSMTPConfig,
|
|
574
|
+
],
|
|
575
|
+
read: [
|
|
576
|
+
Permission.ProjectOwner,
|
|
577
|
+
Permission.ProjectAdmin,
|
|
578
|
+
Permission.ProjectMember,
|
|
579
|
+
Permission.ReadProjectSMTPConfig,
|
|
580
|
+
],
|
|
581
|
+
update: [
|
|
582
|
+
Permission.ProjectOwner,
|
|
583
|
+
Permission.ProjectAdmin,
|
|
584
|
+
Permission.EditProjectSMTPConfig,
|
|
585
|
+
],
|
|
586
|
+
})
|
|
587
|
+
@TableColumn({
|
|
588
|
+
required: true,
|
|
589
|
+
type: TableColumnType.ShortText,
|
|
590
|
+
title: "Authentication Type",
|
|
591
|
+
description:
|
|
592
|
+
"The type of authentication to use for this SMTP server. Options: Username and Password, OAuth, or None.",
|
|
593
|
+
defaultValue: SMTPAuthenticationType.UsernamePassword,
|
|
594
|
+
example: "Username and Password",
|
|
595
|
+
})
|
|
596
|
+
@Column({
|
|
597
|
+
nullable: false,
|
|
598
|
+
type: ColumnType.ShortText,
|
|
599
|
+
length: ColumnLength.ShortText,
|
|
600
|
+
default: SMTPAuthenticationType.UsernamePassword,
|
|
601
|
+
})
|
|
602
|
+
public authType?: SMTPAuthenticationType = undefined;
|
|
603
|
+
|
|
604
|
+
@ColumnAccessControl({
|
|
605
|
+
create: [
|
|
606
|
+
Permission.ProjectOwner,
|
|
607
|
+
Permission.ProjectAdmin,
|
|
608
|
+
Permission.CreateProjectSMTPConfig,
|
|
609
|
+
],
|
|
610
|
+
read: [
|
|
611
|
+
Permission.ProjectOwner,
|
|
612
|
+
Permission.ProjectAdmin,
|
|
613
|
+
Permission.ProjectMember,
|
|
614
|
+
Permission.ReadProjectSMTPConfig,
|
|
615
|
+
],
|
|
616
|
+
update: [
|
|
617
|
+
Permission.ProjectOwner,
|
|
618
|
+
Permission.ProjectAdmin,
|
|
619
|
+
Permission.EditProjectSMTPConfig,
|
|
620
|
+
],
|
|
621
|
+
})
|
|
622
|
+
@TableColumn({
|
|
623
|
+
required: false,
|
|
624
|
+
type: TableColumnType.ShortText,
|
|
625
|
+
title: "OAuth Client ID",
|
|
626
|
+
description:
|
|
627
|
+
"The Client ID from your OAuth application registration. Required for OAuth authentication.",
|
|
628
|
+
example: "12345678-1234-1234-1234-123456789012",
|
|
629
|
+
})
|
|
630
|
+
@Column({
|
|
631
|
+
nullable: true,
|
|
632
|
+
type: ColumnType.ShortText,
|
|
633
|
+
length: ColumnLength.ShortText,
|
|
634
|
+
})
|
|
635
|
+
public clientId?: string = undefined;
|
|
636
|
+
|
|
637
|
+
@ColumnAccessControl({
|
|
638
|
+
create: [
|
|
639
|
+
Permission.ProjectOwner,
|
|
640
|
+
Permission.ProjectAdmin,
|
|
641
|
+
Permission.CreateProjectSMTPConfig,
|
|
642
|
+
],
|
|
643
|
+
read: [
|
|
644
|
+
Permission.ProjectOwner,
|
|
645
|
+
Permission.ProjectAdmin,
|
|
646
|
+
Permission.ReadProjectSMTPConfig,
|
|
647
|
+
],
|
|
648
|
+
update: [
|
|
649
|
+
Permission.ProjectOwner,
|
|
650
|
+
Permission.ProjectAdmin,
|
|
651
|
+
Permission.EditProjectSMTPConfig,
|
|
652
|
+
],
|
|
653
|
+
})
|
|
654
|
+
@TableColumn({
|
|
655
|
+
required: false,
|
|
656
|
+
type: TableColumnType.VeryLongText,
|
|
657
|
+
title: "OAuth Client Secret",
|
|
658
|
+
description:
|
|
659
|
+
"The Client Secret from your OAuth application registration. Required for OAuth authentication. For Google service accounts, this is the private key from the JSON key file.",
|
|
660
|
+
example: "your-client-secret",
|
|
661
|
+
})
|
|
662
|
+
@Column({
|
|
663
|
+
nullable: true,
|
|
664
|
+
type: ColumnType.VeryLongText,
|
|
665
|
+
})
|
|
666
|
+
public clientSecret?: string = undefined;
|
|
667
|
+
|
|
668
|
+
@ColumnAccessControl({
|
|
669
|
+
create: [
|
|
670
|
+
Permission.ProjectOwner,
|
|
671
|
+
Permission.ProjectAdmin,
|
|
672
|
+
Permission.CreateProjectSMTPConfig,
|
|
673
|
+
],
|
|
674
|
+
read: [
|
|
675
|
+
Permission.ProjectOwner,
|
|
676
|
+
Permission.ProjectAdmin,
|
|
677
|
+
Permission.ProjectMember,
|
|
678
|
+
Permission.ReadProjectSMTPConfig,
|
|
679
|
+
],
|
|
680
|
+
update: [
|
|
681
|
+
Permission.ProjectOwner,
|
|
682
|
+
Permission.ProjectAdmin,
|
|
683
|
+
Permission.EditProjectSMTPConfig,
|
|
684
|
+
],
|
|
685
|
+
})
|
|
686
|
+
@TableColumn({
|
|
687
|
+
required: false,
|
|
688
|
+
type: TableColumnType.LongURL,
|
|
689
|
+
title: "OAuth Token URL",
|
|
690
|
+
description:
|
|
691
|
+
"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",
|
|
692
|
+
example:
|
|
693
|
+
"https://login.microsoftonline.com/your-tenant-id/oauth2/v2.0/token",
|
|
694
|
+
})
|
|
695
|
+
@Column({
|
|
696
|
+
nullable: true,
|
|
697
|
+
type: ColumnType.LongURL,
|
|
698
|
+
})
|
|
699
|
+
public tokenUrl?: string = undefined;
|
|
700
|
+
|
|
701
|
+
@ColumnAccessControl({
|
|
702
|
+
create: [
|
|
703
|
+
Permission.ProjectOwner,
|
|
704
|
+
Permission.ProjectAdmin,
|
|
705
|
+
Permission.CreateProjectSMTPConfig,
|
|
706
|
+
],
|
|
707
|
+
read: [
|
|
708
|
+
Permission.ProjectOwner,
|
|
709
|
+
Permission.ProjectAdmin,
|
|
710
|
+
Permission.ProjectMember,
|
|
711
|
+
Permission.ReadProjectSMTPConfig,
|
|
712
|
+
],
|
|
713
|
+
update: [
|
|
714
|
+
Permission.ProjectOwner,
|
|
715
|
+
Permission.ProjectAdmin,
|
|
716
|
+
Permission.EditProjectSMTPConfig,
|
|
717
|
+
],
|
|
718
|
+
})
|
|
719
|
+
@TableColumn({
|
|
720
|
+
required: false,
|
|
721
|
+
type: TableColumnType.LongText,
|
|
722
|
+
title: "OAuth Scope",
|
|
723
|
+
description:
|
|
724
|
+
"The OAuth scope(s) required for SMTP access. For Microsoft 365: https://outlook.office365.com/.default. For Google: https://mail.google.com/",
|
|
725
|
+
example: "https://outlook.office365.com/.default",
|
|
726
|
+
})
|
|
727
|
+
@Column({
|
|
728
|
+
nullable: true,
|
|
729
|
+
type: ColumnType.LongText,
|
|
730
|
+
length: ColumnLength.LongText,
|
|
731
|
+
})
|
|
732
|
+
public scope?: string = undefined;
|
|
733
|
+
|
|
734
|
+
@ColumnAccessControl({
|
|
735
|
+
create: [
|
|
736
|
+
Permission.ProjectOwner,
|
|
737
|
+
Permission.ProjectAdmin,
|
|
738
|
+
Permission.CreateProjectSMTPConfig,
|
|
739
|
+
],
|
|
740
|
+
read: [
|
|
741
|
+
Permission.ProjectOwner,
|
|
742
|
+
Permission.ProjectAdmin,
|
|
743
|
+
Permission.ProjectMember,
|
|
744
|
+
Permission.ReadProjectSMTPConfig,
|
|
745
|
+
],
|
|
746
|
+
update: [
|
|
747
|
+
Permission.ProjectOwner,
|
|
748
|
+
Permission.ProjectAdmin,
|
|
749
|
+
Permission.EditProjectSMTPConfig,
|
|
750
|
+
],
|
|
751
|
+
})
|
|
752
|
+
@TableColumn({
|
|
753
|
+
required: false,
|
|
754
|
+
type: TableColumnType.ShortText,
|
|
755
|
+
title: "OAuth Provider Type",
|
|
756
|
+
description:
|
|
757
|
+
"The OAuth grant type to use. 'Client Credentials' for Microsoft 365 and most providers. 'JWT Bearer' for Google Workspace service accounts.",
|
|
758
|
+
example: "Client Credentials",
|
|
759
|
+
})
|
|
760
|
+
@Column({
|
|
761
|
+
nullable: true,
|
|
762
|
+
type: ColumnType.ShortText,
|
|
763
|
+
length: ColumnLength.ShortText,
|
|
764
|
+
})
|
|
765
|
+
public oauthProviderType?: OAuthProviderType = undefined;
|
|
564
766
|
}
|
|
@@ -239,6 +239,7 @@ export default class Service extends BaseModel {
|
|
|
239
239
|
@TableColumn({
|
|
240
240
|
required: false,
|
|
241
241
|
type: TableColumnType.LongText,
|
|
242
|
+
canReadOnRelationQuery: true,
|
|
242
243
|
title: "Description",
|
|
243
244
|
description: "Friendly description that will help you remember",
|
|
244
245
|
example:
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1767896933148 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1767896933148";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "ProjectSMTPConfig" ADD "authType" character varying(100) NOT NULL DEFAULT 'Username and Password'`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "ProjectSMTPConfig" ADD "clientId" character varying(100)`,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "ProjectSMTPConfig" ADD "clientSecret" character varying(500)`,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "ProjectSMTPConfig" ADD "tokenUrl" text`,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "ProjectSMTPConfig" ADD "scope" character varying(500)`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "scope"`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "tokenUrl"`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "clientSecret"`,
|
|
33
|
+
);
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "clientId"`,
|
|
36
|
+
);
|
|
37
|
+
await queryRunner.query(
|
|
38
|
+
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "authType"`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
package/Server/Infrastructure/Postgres/SchemaMigrations/1768216593272-IncreaseClientSecretLength.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class IncreaseClientSecretLength1768216593272
|
|
4
|
+
implements MigrationInterface
|
|
5
|
+
{
|
|
6
|
+
public name = "IncreaseClientSecretLength1768216593272";
|
|
7
|
+
|
|
8
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
9
|
+
/*
|
|
10
|
+
* Change clientSecret from varchar(500) to text to support longer OAuth secrets
|
|
11
|
+
* (e.g., Google service account private keys which are ~1700+ characters)
|
|
12
|
+
*/
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "ProjectSMTPConfig" ALTER COLUMN "clientSecret" TYPE text`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
19
|
+
// Revert back to varchar(500)
|
|
20
|
+
await queryRunner.query(
|
|
21
|
+
`ALTER TABLE "ProjectSMTPConfig" ALTER COLUMN "clientSecret" TYPE character varying(500)`,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class AddOAuthProviderType1768217403078 implements MigrationInterface {
|
|
4
|
+
public name = "AddOAuthProviderType1768217403078";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
/*
|
|
8
|
+
* Add oauthProviderType column to ProjectSMTPConfig table
|
|
9
|
+
* Values: 'Client Credentials' (for Microsoft 365, etc.) or 'JWT Bearer' (for Google Workspace)
|
|
10
|
+
*/
|
|
11
|
+
await queryRunner.query(
|
|
12
|
+
`ALTER TABLE "ProjectSMTPConfig" ADD "oauthProviderType" character varying(100)`,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
17
|
+
await queryRunner.query(
|
|
18
|
+
`ALTER TABLE "ProjectSMTPConfig" DROP COLUMN "oauthProviderType"`,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -213,9 +213,12 @@ import { AddAIAgentIsDefault1766918848434 } from "./1766918848434-AddAIAgentIsDe
|
|
|
213
213
|
import { MigrationName1766923324521 } from "./1766923324521-MigrationName";
|
|
214
214
|
import { AddGitHubAppInstallationIdToProject1766958924188 } from "./1766958924188-AddGitHubAppInstallationIdToProject";
|
|
215
215
|
import { MigrationName1767009661768 } from "./1767009661768-MigrationName";
|
|
216
|
+
import { MigrationName1767896933148 } from "./1767896933148-MigrationName";
|
|
216
217
|
import { RenameServiceCatalogToService1767966850199 } from "./1767966850199-RenameServiceCatalogToService";
|
|
217
218
|
import { MigrationName1767979055522 } from "./1767979055522-MigrationName";
|
|
218
219
|
import { MigrationName1767979448478 } from "./1767979448478-MigrationName";
|
|
220
|
+
import { IncreaseClientSecretLength1768216593272 } from "./1768216593272-IncreaseClientSecretLength";
|
|
221
|
+
import { AddOAuthProviderType1768217403078 } from "./1768217403078-AddOAuthProviderType";
|
|
219
222
|
|
|
220
223
|
export default [
|
|
221
224
|
InitialMigration,
|
|
@@ -436,4 +439,7 @@ export default [
|
|
|
436
439
|
RenameServiceCatalogToService1767966850199,
|
|
437
440
|
MigrationName1767979055522,
|
|
438
441
|
MigrationName1767979448478,
|
|
442
|
+
MigrationName1767896933148,
|
|
443
|
+
IncreaseClientSecretLength1768216593272,
|
|
444
|
+
AddOAuthProviderType1768217403078,
|
|
439
445
|
];
|
|
@@ -1171,7 +1171,7 @@ ${alertSeverity.name}
|
|
|
1171
1171
|
metricType.name = alertCountMetric.name;
|
|
1172
1172
|
metricType.description = "Number of alerts created";
|
|
1173
1173
|
metricType.unit = "";
|
|
1174
|
-
metricType.
|
|
1174
|
+
metricType.services = [];
|
|
1175
1175
|
metricTypesMap[alertCountMetric.name] = metricType;
|
|
1176
1176
|
|
|
1177
1177
|
// is the alert acknowledged?
|
|
@@ -2084,7 +2084,7 @@ ${incidentSeverity.name}
|
|
|
2084
2084
|
metricType.name = incidentCountMetric.name;
|
|
2085
2085
|
metricType.description = "Number of incidents created";
|
|
2086
2086
|
metricType.unit = "";
|
|
2087
|
-
metricType.
|
|
2087
|
+
metricType.services = [];
|
|
2088
2088
|
|
|
2089
2089
|
// add to map.
|
|
2090
2090
|
metricTypesMap[incidentCountMetric.name] = metricType;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import DatabaseService from "./DatabaseService";
|
|
2
2
|
import EmailServer from "../../Types/Email/EmailServer";
|
|
3
|
+
import SMTPAuthenticationType from "../../Types/Email/SMTPAuthenticationType";
|
|
3
4
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
5
|
+
import URL from "../../Types/API/URL";
|
|
4
6
|
import Model from "../../Models/DatabaseModels/ProjectSmtpConfig";
|
|
5
7
|
|
|
6
8
|
export class Service extends DatabaseService<Model> {
|
|
@@ -27,13 +29,51 @@ export class Service extends DatabaseService<Model> {
|
|
|
27
29
|
throw new BadDataException("Project SMTP config port is not set");
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
// Get auth type, default to UsernamePassword for backward compatibility
|
|
33
|
+
const authType: SMTPAuthenticationType =
|
|
34
|
+
projectSmtpConfig.authType || SMTPAuthenticationType.UsernamePassword;
|
|
35
|
+
|
|
36
|
+
// Validate based on auth type
|
|
37
|
+
if (authType === SMTPAuthenticationType.UsernamePassword) {
|
|
38
|
+
if (!projectSmtpConfig.username) {
|
|
39
|
+
throw new BadDataException("Project SMTP config username is not set");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!projectSmtpConfig.password) {
|
|
43
|
+
throw new BadDataException("Project SMTP config password is not set");
|
|
44
|
+
}
|
|
45
|
+
} else if (authType === SMTPAuthenticationType.OAuth) {
|
|
46
|
+
if (!projectSmtpConfig.username) {
|
|
47
|
+
throw new BadDataException(
|
|
48
|
+
"Project SMTP config username (email address) is not set for OAuth",
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!projectSmtpConfig.clientId) {
|
|
53
|
+
throw new BadDataException(
|
|
54
|
+
"Project SMTP config OAuth Client ID is not set",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!projectSmtpConfig.clientSecret) {
|
|
59
|
+
throw new BadDataException(
|
|
60
|
+
"Project SMTP config OAuth Client Secret is not set",
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!projectSmtpConfig.tokenUrl) {
|
|
65
|
+
throw new BadDataException(
|
|
66
|
+
"Project SMTP config OAuth Token URL is not set",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
33
69
|
|
|
34
|
-
|
|
35
|
-
|
|
70
|
+
if (!projectSmtpConfig.scope) {
|
|
71
|
+
throw new BadDataException(
|
|
72
|
+
"Project SMTP config OAuth Scope is not set",
|
|
73
|
+
);
|
|
74
|
+
}
|
|
36
75
|
}
|
|
76
|
+
// For SMTPAuthenticationType.None, no credentials are required
|
|
37
77
|
|
|
38
78
|
if (!projectSmtpConfig.fromEmail) {
|
|
39
79
|
throw new BadDataException("Project SMTP config from email is not set");
|
|
@@ -52,6 +92,13 @@ export class Service extends DatabaseService<Model> {
|
|
|
52
92
|
fromEmail: projectSmtpConfig.fromEmail,
|
|
53
93
|
fromName: projectSmtpConfig.fromName,
|
|
54
94
|
secure: Boolean(projectSmtpConfig.secure),
|
|
95
|
+
authType: authType,
|
|
96
|
+
clientId: projectSmtpConfig.clientId,
|
|
97
|
+
clientSecret: projectSmtpConfig.clientSecret,
|
|
98
|
+
tokenUrl: projectSmtpConfig.tokenUrl
|
|
99
|
+
? URL.fromString(projectSmtpConfig.tokenUrl)
|
|
100
|
+
: undefined,
|
|
101
|
+
scope: projectSmtpConfig.scope,
|
|
55
102
|
};
|
|
56
103
|
}
|
|
57
104
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import Hostname from "../API/Hostname";
|
|
2
|
+
import URL from "../API/URL";
|
|
2
3
|
import Email from "../Email";
|
|
3
4
|
import ObjectID from "../ObjectID";
|
|
4
5
|
import Port from "../Port";
|
|
6
|
+
import OAuthProviderType from "./OAuthProviderType";
|
|
7
|
+
import SMTPAuthenticationType from "./SMTPAuthenticationType";
|
|
5
8
|
|
|
6
9
|
export default interface EmailServer {
|
|
7
10
|
id?: ObjectID | undefined; // If this is custom SMTP, this is the ID of the SMTP config. Otherwise, it's undefined
|
|
@@ -12,4 +15,12 @@ export default interface EmailServer {
|
|
|
12
15
|
secure: boolean;
|
|
13
16
|
fromEmail: Email;
|
|
14
17
|
fromName: string;
|
|
18
|
+
|
|
19
|
+
// OAuth 2.0 fields for any OAuth-enabled SMTP server
|
|
20
|
+
authType?: SMTPAuthenticationType | undefined;
|
|
21
|
+
clientId?: string | undefined; // OAuth Application Client ID
|
|
22
|
+
clientSecret?: string | undefined; // OAuth Application Client Secret
|
|
23
|
+
tokenUrl?: URL | undefined; // OAuth token endpoint URL (e.g., https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token)
|
|
24
|
+
scope?: string | undefined; // OAuth scope(s), space-separated (e.g., https://outlook.office365.com/.default)
|
|
25
|
+
oauthProviderType?: OAuthProviderType | undefined; // OAuth grant type: Client Credentials or JWT Bearer
|
|
15
26
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Provider Types for SMTP authentication.
|
|
3
|
+
* Different providers use different OAuth 2.0 grant types.
|
|
4
|
+
*/
|
|
5
|
+
enum OAuthProviderType {
|
|
6
|
+
/**
|
|
7
|
+
* Client Credentials Grant (RFC 6749)
|
|
8
|
+
* Used by: Microsoft 365, Azure AD, and most OAuth 2.0 providers
|
|
9
|
+
*
|
|
10
|
+
* Required fields: Client ID, Client Secret, Token URL, Scope
|
|
11
|
+
*/
|
|
12
|
+
ClientCredentials = "Client Credentials",
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* JWT Bearer Assertion Grant (RFC 7523)
|
|
16
|
+
* Used by: Google Workspace service accounts
|
|
17
|
+
*
|
|
18
|
+
* Required fields:
|
|
19
|
+
* - Client ID: Service account email (client_email from JSON key)
|
|
20
|
+
* - Client Secret: Private key (private_key from JSON key)
|
|
21
|
+
* - Token URL: OAuth token endpoint
|
|
22
|
+
* - Scope: Required scopes
|
|
23
|
+
* - Username: Email address to impersonate
|
|
24
|
+
*/
|
|
25
|
+
JWTBearer = "JWT Bearer",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default OAuthProviderType;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Authentication types for SMTP servers
|
|
2
|
+
enum SMTPAuthenticationType {
|
|
3
|
+
UsernamePassword = "Username and Password", // Traditional SMTP authentication
|
|
4
|
+
OAuth = "OAuth", // OAuth 2.0 authentication (for Microsoft 365, etc.)
|
|
5
|
+
None = "None", // No authentication (for relay servers)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default SMTPAuthenticationType;
|
package/Types/Icon/IconProp.ts
CHANGED
|
@@ -1307,9 +1307,9 @@ const Icon: FunctionComponent<ComponentProps> = ({
|
|
|
1307
1307
|
/>,
|
|
1308
1308
|
);
|
|
1309
1309
|
} else if (icon === IconProp.FlowDiagram) {
|
|
1310
|
-
// Flow diagram icon matching home page workflows - two boxes at top, one at bottom, connected
|
|
1310
|
+
// Flow diagram icon matching home page workflows - two boxes at top, one at bottom, connected (rotated 180°)
|
|
1311
1311
|
return getSvgWrapper(
|
|
1312
|
-
|
|
1312
|
+
<g style={{ transform: "rotate(180deg)", transformOrigin: "center" }}>
|
|
1313
1313
|
<rect x="3" y="3" width="6" height="4" rx="1" strokeWidth="1.5" />
|
|
1314
1314
|
<rect x="15" y="3" width="6" height="4" rx="1" strokeWidth="1.5" />
|
|
1315
1315
|
<rect x="9" y="17" width="6" height="4" rx="1" strokeWidth="1.5" />
|
|
@@ -1317,7 +1317,7 @@ const Icon: FunctionComponent<ComponentProps> = ({
|
|
|
1317
1317
|
strokeLinecap="round"
|
|
1318
1318
|
d="M6 7v3a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7M12 12v5"
|
|
1319
1319
|
/>
|
|
1320
|
-
|
|
1320
|
+
</g>,
|
|
1321
1321
|
);
|
|
1322
1322
|
} else if (icon === IconProp.Bug) {
|
|
1323
1323
|
// Bug icon for exceptions - matching home page
|
|
@@ -1330,6 +1330,44 @@ const Icon: FunctionComponent<ComponentProps> = ({
|
|
|
1330
1330
|
/>
|
|
1331
1331
|
</>,
|
|
1332
1332
|
);
|
|
1333
|
+
} else if (icon === IconProp.ChartPie) {
|
|
1334
|
+
// Pie chart icon for dashboards - matching home page
|
|
1335
|
+
return getSvgWrapper(
|
|
1336
|
+
<>
|
|
1337
|
+
<path
|
|
1338
|
+
strokeLinecap="round"
|
|
1339
|
+
strokeLinejoin="round"
|
|
1340
|
+
d="M10.5 6a7.5 7.5 0 107.5 7.5h-7.5V6z"
|
|
1341
|
+
/>
|
|
1342
|
+
<path
|
|
1343
|
+
strokeLinecap="round"
|
|
1344
|
+
strokeLinejoin="round"
|
|
1345
|
+
d="M13.5 10.5H21A7.5 7.5 0 0013.5 3v7.5z"
|
|
1346
|
+
/>
|
|
1347
|
+
</>,
|
|
1348
|
+
);
|
|
1349
|
+
} else if (icon === IconProp.Heartbeat) {
|
|
1350
|
+
// Heartbeat/line chart icon for metrics - matching home page
|
|
1351
|
+
return getSvgWrapper(
|
|
1352
|
+
<>
|
|
1353
|
+
<path
|
|
1354
|
+
strokeLinecap="round"
|
|
1355
|
+
strokeLinejoin="round"
|
|
1356
|
+
d="M2 12h3l2-4 3 8 3-6 2 4h7"
|
|
1357
|
+
/>
|
|
1358
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M2 20h20" />
|
|
1359
|
+
</>,
|
|
1360
|
+
);
|
|
1361
|
+
} else if (icon === IconProp.Waterfall) {
|
|
1362
|
+
// Waterfall/span diagram icon for traces - matching home page
|
|
1363
|
+
return getSvgWrapper(
|
|
1364
|
+
<>
|
|
1365
|
+
<rect x="2" y="3" width="20" height="4" rx="0.5" />
|
|
1366
|
+
<rect x="2" y="10" width="10" height="4" rx="0.5" />
|
|
1367
|
+
<rect x="2" y="17" width="5" height="4" rx="0.5" />
|
|
1368
|
+
<rect x="17" y="17" width="5" height="4" rx="0.5" />
|
|
1369
|
+
</>,
|
|
1370
|
+
);
|
|
1333
1371
|
}
|
|
1334
1372
|
|
|
1335
1373
|
return <></>;
|