@webiny/api-mailer 6.4.0-beta.3 → 6.4.0-beta.5

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.
Files changed (44) hide show
  1. package/domain/MailTransport/abstractions.d.ts +1 -7
  2. package/domain/MailTransport/abstractions.js +1 -2
  3. package/domain/MailTransport/abstractions.js.map +1 -1
  4. package/domain/MailerService/abstractions.d.ts +2 -2
  5. package/domain/MailerService/abstractions.js.map +1 -1
  6. package/domain/MailerService/errors.d.ts +4 -0
  7. package/domain/MailerService/errors.js +8 -1
  8. package/domain/MailerService/errors.js.map +1 -1
  9. package/features/DummyTransport/DummyMailTransportFactory.d.ts +1 -0
  10. package/features/DummyTransport/DummyMailTransportFactory.js +3 -0
  11. package/features/DummyTransport/DummyMailTransportFactory.js.map +1 -1
  12. package/features/GetSettings/GetSettingsRepository.js +4 -2
  13. package/features/GetSettings/GetSettingsRepository.js.map +1 -1
  14. package/features/MailerService/MailerService.d.ts +3 -4
  15. package/features/MailerService/MailerService.js +26 -16
  16. package/features/MailerService/MailerService.js.map +1 -1
  17. package/features/MailerService/feature.js +0 -2
  18. package/features/MailerService/feature.js.map +1 -1
  19. package/features/SaveSettings/SaveSettingsRepository.js +6 -4
  20. package/features/SaveSettings/SaveSettingsRepository.js.map +1 -1
  21. package/features/SaveSettings/SaveSettingsUseCase.d.ts +4 -4
  22. package/features/SaveSettings/SaveSettingsUseCase.js +11 -6
  23. package/features/SaveSettings/SaveSettingsUseCase.js.map +1 -1
  24. package/features/SaveSettings/abstractions.d.ts +1 -0
  25. package/features/SaveSettings/abstractions.js.map +1 -1
  26. package/features/SaveSettings/validation.d.ts +1 -0
  27. package/features/SaveSettings/validation.js +1 -0
  28. package/features/SaveSettings/validation.js.map +1 -1
  29. package/features/SendMail/SendMailUseCase.d.ts +1 -1
  30. package/features/SmtpTransport/SmtpConfig.js +1 -0
  31. package/features/SmtpTransport/SmtpConfig.js.map +1 -1
  32. package/features/SmtpTransport/SmtpMailTransportFactory.d.ts +1 -0
  33. package/features/SmtpTransport/SmtpMailTransportFactory.js +3 -0
  34. package/features/SmtpTransport/SmtpMailTransportFactory.js.map +1 -1
  35. package/graphql/settings.js +4 -8
  36. package/graphql/settings.js.map +1 -1
  37. package/index.d.ts +1 -1
  38. package/index.js +2 -2
  39. package/index.js.map +1 -1
  40. package/package.json +20 -18
  41. package/types.d.ts +1 -0
  42. package/features/MailerService/ActiveTransport.d.ts +0 -10
  43. package/features/MailerService/ActiveTransport.js +0 -24
  44. package/features/MailerService/ActiveTransport.js.map +0 -1
@@ -10,6 +10,7 @@ export declare namespace MailTransport {
10
10
  }
11
11
  export interface IMailTransportFactory {
12
12
  name: string;
13
+ canUse(settings: TransportSettings | null): boolean;
13
14
  createTransport(settings: TransportSettings): Promise<IMailTransport>;
14
15
  }
15
16
  export declare const MailTransportFactory: import("@webiny/di").Abstraction<IMailTransportFactory>;
@@ -17,10 +18,3 @@ export declare namespace MailTransportFactory {
17
18
  type Interface = IMailTransportFactory;
18
19
  type Return = Promise<IMailTransport>;
19
20
  }
20
- export interface IActiveTransport {
21
- name(): string | null;
22
- }
23
- export declare const ActiveTransport: import("@webiny/di").Abstraction<IActiveTransport>;
24
- export declare namespace ActiveTransport {
25
- type Interface = IActiveTransport;
26
- }
@@ -1,7 +1,6 @@
1
1
  import { createAbstraction } from "@webiny/feature/api";
2
2
  const MailTransport = createAbstraction("MailTransport");
3
3
  const MailTransportFactory = createAbstraction("MailTransportFactory");
4
- const ActiveTransport = createAbstraction("ActiveTransport");
5
- export { ActiveTransport, MailTransport, MailTransportFactory };
4
+ export { MailTransport, MailTransportFactory };
6
5
 
7
6
  //# sourceMappingURL=abstractions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"domain/MailTransport/abstractions.js","sources":["../../../src/domain/MailTransport/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse, TransportSettings } from \"~/types.js\";\n\nexport interface IMailTransport {\n name: string;\n send(params: TransportSendData): Promise<TransportSendResponse>;\n}\n\nexport const MailTransport = createAbstraction<IMailTransport>(\"MailTransport\");\n\nexport namespace MailTransport {\n export type Interface = IMailTransport;\n export type SendParams = TransportSendData;\n}\n\nexport interface IMailTransportFactory {\n name: string;\n createTransport(settings: TransportSettings): Promise<IMailTransport>;\n}\n\nexport const MailTransportFactory =\n createAbstraction<IMailTransportFactory>(\"MailTransportFactory\");\n\nexport namespace MailTransportFactory {\n export type Interface = IMailTransportFactory;\n export type Return = Promise<IMailTransport>;\n}\n\nexport interface IActiveTransport {\n name(): string | null;\n}\n\nexport const ActiveTransport = createAbstraction<IActiveTransport>(\"ActiveTransport\");\n\nexport namespace ActiveTransport {\n export type Interface = IActiveTransport;\n}\n"],"names":["MailTransport","createAbstraction","MailTransportFactory","ActiveTransport"],"mappings":";AAQO,MAAMA,gBAAgBC,kBAAkC;AAYxD,MAAMC,uBACTD,kBAAyC;AAWtC,MAAME,kBAAkBF,kBAAoC"}
1
+ {"version":3,"file":"domain/MailTransport/abstractions.js","sources":["../../../src/domain/MailTransport/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse, TransportSettings } from \"~/types.js\";\n\nexport interface IMailTransport {\n name: string;\n send(params: TransportSendData): Promise<TransportSendResponse>;\n}\n\nexport const MailTransport = createAbstraction<IMailTransport>(\"MailTransport\");\n\nexport namespace MailTransport {\n export type Interface = IMailTransport;\n export type SendParams = TransportSendData;\n}\n\nexport interface IMailTransportFactory {\n name: string;\n canUse(settings: TransportSettings | null): boolean;\n createTransport(settings: TransportSettings): Promise<IMailTransport>;\n}\n\nexport const MailTransportFactory =\n createAbstraction<IMailTransportFactory>(\"MailTransportFactory\");\n\nexport namespace MailTransportFactory {\n export type Interface = IMailTransportFactory;\n export type Return = Promise<IMailTransport>;\n}\n"],"names":["MailTransport","createAbstraction","MailTransportFactory"],"mappings":";AAQO,MAAMA,gBAAgBC,kBAAkC;AAaxD,MAAMC,uBACTD,kBAAyC"}
@@ -1,9 +1,9 @@
1
1
  import { Result } from "@webiny/feature/api";
2
2
  import type { TransportSendData, TransportSendResponse } from "../../types.js";
3
- import { NoTransportAvailableError, NoSettingsConfiguredError, TransportSendError } from "./errors.js";
3
+ import { NoTransportAvailableError, TransportCreateError, TransportSendError } from "./errors.js";
4
4
  export interface IMailerServiceErrors {
5
5
  noTransport: NoTransportAvailableError;
6
- noSettings: NoSettingsConfiguredError;
6
+ transportCreate: TransportCreateError;
7
7
  transportSend: TransportSendError;
8
8
  }
9
9
  type MailerServiceError = IMailerServiceErrors[keyof IMailerServiceErrors];
@@ -1 +1 @@
1
- {"version":3,"file":"domain/MailerService/abstractions.js","sources":["../../../src/domain/MailerService/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse } from \"~/types.js\";\nimport {\n NoTransportAvailableError,\n NoSettingsConfiguredError,\n TransportSendError\n} from \"./errors.js\";\n\nexport interface IMailerServiceErrors {\n noTransport: NoTransportAvailableError;\n noSettings: NoSettingsConfiguredError;\n transportSend: TransportSendError;\n}\n\ntype MailerServiceError = IMailerServiceErrors[keyof IMailerServiceErrors];\n\nexport interface IMailerService {\n sendMail<T = any>(\n data: TransportSendData\n ): Promise<Result<TransportSendResponse<T>, MailerServiceError>>;\n}\n\nexport const MailerService = createAbstraction<IMailerService>(\"MailerService\");\n\nexport namespace MailerService {\n export type Interface = IMailerService;\n export type Return<T = any> = Promise<Result<TransportSendResponse<T>, MailerServiceError>>;\n export type Error = MailerServiceError;\n}\n"],"names":["MailerService","createAbstraction"],"mappings":";AAuBO,MAAMA,gBAAgBC,kBAAkC"}
1
+ {"version":3,"file":"domain/MailerService/abstractions.js","sources":["../../../src/domain/MailerService/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { TransportSendData, TransportSendResponse } from \"~/types.js\";\nimport { NoTransportAvailableError, TransportCreateError, TransportSendError } from \"./errors.js\";\n\nexport interface IMailerServiceErrors {\n noTransport: NoTransportAvailableError;\n transportCreate: TransportCreateError;\n transportSend: TransportSendError;\n}\n\ntype MailerServiceError = IMailerServiceErrors[keyof IMailerServiceErrors];\n\nexport interface IMailerService {\n sendMail<T = any>(\n data: TransportSendData\n ): Promise<Result<TransportSendResponse<T>, MailerServiceError>>;\n}\n\nexport const MailerService = createAbstraction<IMailerService>(\"MailerService\");\n\nexport namespace MailerService {\n export type Interface = IMailerService;\n export type Return<T = any> = Promise<Result<TransportSendResponse<T>, MailerServiceError>>;\n export type Error = MailerServiceError;\n}\n"],"names":["MailerService","createAbstraction"],"mappings":";AAmBO,MAAMA,gBAAgBC,kBAAkC"}
@@ -8,6 +8,10 @@ export declare class NoSettingsConfiguredError extends BaseError {
8
8
  readonly code: "Mailer/MailerService/NoSettingsConfigured";
9
9
  constructor();
10
10
  }
11
+ export declare class TransportCreateError extends BaseError {
12
+ readonly code: "Mailer/MailerService/TransportCreateError";
13
+ constructor(error: unknown);
14
+ }
11
15
  export declare class TransportSendError extends BaseError<{
12
16
  error: TransportSendResponse["error"];
13
17
  }> {
@@ -13,6 +13,13 @@ class NoSettingsConfiguredError extends BaseError {
13
13
  }), this.code = "Mailer/MailerService/NoSettingsConfigured";
14
14
  }
15
15
  }
16
+ class TransportCreateError extends BaseError {
17
+ constructor(error){
18
+ super({
19
+ message: error instanceof Error ? error.message : String(error)
20
+ }), this.code = "Mailer/MailerService/TransportCreateError";
21
+ }
22
+ }
16
23
  class TransportSendError extends BaseError {
17
24
  constructor(error){
18
25
  super({
@@ -23,6 +30,6 @@ class TransportSendError extends BaseError {
23
30
  }), this.code = "Mailer/MailerService/TransportSendError";
24
31
  }
25
32
  }
26
- export { NoSettingsConfiguredError, NoTransportAvailableError, TransportSendError };
33
+ export { NoSettingsConfiguredError, NoTransportAvailableError, TransportCreateError, TransportSendError };
27
34
 
28
35
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"domain/MailerService/errors.js","sources":["../../../src/domain/MailerService/errors.ts"],"sourcesContent":["import { BaseError } from \"@webiny/feature/api\";\nimport type { TransportSendResponse } from \"~/types.js\";\n\nexport class NoTransportAvailableError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoTransportAvailable\" as const;\n\n constructor() {\n super({\n message: \"There is no transport available.\"\n });\n }\n}\n\nexport class NoSettingsConfiguredError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoSettingsConfigured\" as const;\n\n constructor() {\n super({\n message: \"No mailer settings are configured and no environment variables are set.\"\n });\n }\n}\n\nexport class TransportSendError extends BaseError<{ error: TransportSendResponse[\"error\"] }> {\n override readonly code = \"Mailer/MailerService/TransportSendError\" as const;\n\n constructor(error: NonNullable<TransportSendResponse[\"error\"]>) {\n super({\n message: error.message,\n data: {\n error\n }\n });\n }\n}\n"],"names":["NoTransportAvailableError","BaseError","NoSettingsConfiguredError","TransportSendError","error"],"mappings":";AAGO,MAAMA,kCAAkCC;IAG3C,aAAc;QACV,KAAK,CAAC;YACF,SAAS;QACb,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAMC,kCAAkCD;IAG3C,aAAc;QACV,KAAK,CAAC;YACF,SAAS;QACb,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAME,2BAA2BF;IAGpC,YAAYG,KAAkD,CAAE;QAC5D,KAAK,CAAC;YACF,SAASA,MAAM,OAAO;YACtB,MAAM;gBACFA;YACJ;QACJ,SARc,IAAI,GAAG;IASzB;AACJ"}
1
+ {"version":3,"file":"domain/MailerService/errors.js","sources":["../../../src/domain/MailerService/errors.ts"],"sourcesContent":["import { BaseError } from \"@webiny/feature/api\";\nimport type { TransportSendResponse } from \"~/types.js\";\n\nexport class NoTransportAvailableError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoTransportAvailable\" as const;\n\n constructor() {\n super({\n message: \"There is no transport available.\"\n });\n }\n}\n\nexport class NoSettingsConfiguredError extends BaseError {\n override readonly code = \"Mailer/MailerService/NoSettingsConfigured\" as const;\n\n constructor() {\n super({\n message: \"No mailer settings are configured and no environment variables are set.\"\n });\n }\n}\n\nexport class TransportCreateError extends BaseError {\n override readonly code = \"Mailer/MailerService/TransportCreateError\" as const;\n\n constructor(error: unknown) {\n super({\n message: error instanceof Error ? error.message : String(error)\n });\n }\n}\n\nexport class TransportSendError extends BaseError<{ error: TransportSendResponse[\"error\"] }> {\n override readonly code = \"Mailer/MailerService/TransportSendError\" as const;\n\n constructor(error: NonNullable<TransportSendResponse[\"error\"]>) {\n super({\n message: error.message,\n data: {\n error\n }\n });\n }\n}\n"],"names":["NoTransportAvailableError","BaseError","NoSettingsConfiguredError","TransportCreateError","error","Error","String","TransportSendError"],"mappings":";AAGO,MAAMA,kCAAkCC;IAG3C,aAAc;QACV,KAAK,CAAC;YACF,SAAS;QACb,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAMC,kCAAkCD;IAG3C,aAAc;QACV,KAAK,CAAC;YACF,SAAS;QACb,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAME,6BAA6BF;IAGtC,YAAYG,KAAc,CAAE;QACxB,KAAK,CAAC;YACF,SAASA,iBAAiBC,QAAQD,MAAM,OAAO,GAAGE,OAAOF;QAC7D,SALc,IAAI,GAAG;IAMzB;AACJ;AAEO,MAAMG,2BAA2BN;IAGpC,YAAYG,KAAkD,CAAE;QAC5D,KAAK,CAAC;YACF,SAASA,MAAM,OAAO;YACtB,MAAM;gBACFA;YACJ;QACJ,SARc,IAAI,GAAG;IASzB;AACJ"}
@@ -1,6 +1,7 @@
1
1
  import { type IMailTransport, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
2
2
  declare class DummyMailTransportFactoryImpl implements MailTransportFactory.Interface {
3
3
  readonly name = "Mailer/DummyTransport";
4
+ canUse(): boolean;
4
5
  createTransport(): Promise<IMailTransport>;
5
6
  }
6
7
  export declare const DummyMailTransportFactory: typeof DummyMailTransportFactoryImpl & {
@@ -1,6 +1,9 @@
1
1
  import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
2
2
  import { DummyMailTransport } from "./DummyMailTransport.js";
3
3
  class DummyMailTransportFactoryImpl {
4
+ canUse() {
5
+ return true;
6
+ }
4
7
  async createTransport() {
5
8
  return new DummyMailTransport();
6
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"features/DummyTransport/DummyMailTransportFactory.js","sources":["../../../src/features/DummyTransport/DummyMailTransportFactory.ts"],"sourcesContent":["import { type IMailTransport, MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport { DummyMailTransport } from \"./DummyMailTransport.js\";\n\nclass DummyMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/DummyTransport\";\n\n async createTransport(): Promise<IMailTransport> {\n return new DummyMailTransport();\n }\n}\n\nexport const DummyMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: DummyMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["DummyMailTransportFactoryImpl","DummyMailTransport","DummyMailTransportFactory","MailTransportFactory"],"mappings":";;AAGA,MAAMA;IAGF,MAAM,kBAA2C;QAC7C,OAAO,IAAIC;IACf;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMC,4BAA4BC,qBAAqB,oBAAoB,CAAC;IAC/E,gBAAgBH;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"features/DummyTransport/DummyMailTransportFactory.js","sources":["../../../src/features/DummyTransport/DummyMailTransportFactory.ts"],"sourcesContent":["import { type IMailTransport, MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport { DummyMailTransport } from \"./DummyMailTransport.js\";\n\nclass DummyMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/DummyTransport\";\n\n canUse(): boolean {\n return true;\n }\n\n async createTransport(): Promise<IMailTransport> {\n return new DummyMailTransport();\n }\n}\n\nexport const DummyMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: DummyMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["DummyMailTransportFactoryImpl","DummyMailTransport","DummyMailTransportFactory","MailTransportFactory"],"mappings":";;AAGA,MAAMA;IAGF,SAAkB;QACd,OAAO;IACX;IAEA,MAAM,kBAA2C;QAC7C,OAAO,IAAIC;IACf;;aARgB,IAAI,GAAG;;AAS3B;AAEO,MAAMC,4BAA4BC,qBAAqB,oBAAoB,CAAC;IAC/E,gBAAgBH;IAChB,cAAc,EAAE;AACpB"}
@@ -26,10 +26,12 @@ class GetSettingsRepositoryImpl {
26
26
  settings: null,
27
27
  source: null
28
28
  });
29
- const password = settings.password ? this.encryption.decrypt(String(settings.password)) : "";
29
+ const password = settings.password ? await this.encryption.decrypt(String(settings.password)) : "";
30
+ const port = Number(settings.port || 587);
30
31
  const transportSettings = {
31
32
  host: String(settings.host || ""),
32
- port: Number(settings.port || 25),
33
+ port,
34
+ secure: settings.secure ?? 465 === port,
33
35
  user: String(settings.user || ""),
34
36
  password,
35
37
  from: String(settings.from || ""),
@@ -1 +1 @@
1
- {"version":3,"file":"features/GetSettings/GetSettingsRepository.js","sources":["../../../src/features/GetSettings/GetSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { GetSettingsRepository, type ISettingsWithSource } from \"./abstractions.js\";\nimport { CodeMailerSettings } from \"~/domain/CodeMailerSettings/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nclass GetSettingsRepositoryImpl implements GetSettingsRepository.Interface {\n constructor(\n private keyValueStore: KeyValueStore.Interface,\n private encryption: Encryption.Interface,\n private codeSettings: CodeMailerSettings.Interface\n ) {}\n\n async get(transportName: string): Promise<Result<ISettingsWithSource>> {\n // Code-defined settings win over the KV store.\n const codeSettingsValue = this.codeSettings.get(transportName);\n if (codeSettingsValue !== null) {\n return Result.ok({\n settings: codeSettingsValue,\n source: \"code\"\n });\n }\n\n const result = await this.keyValueStore.get<TransportSettings>(MAILER_TRANSPORT_SETTINGS);\n\n if (result.isFail()) {\n return Result.ok({ settings: null, source: null });\n }\n\n const settings = result.value;\n if (!settings) {\n return Result.ok({ settings: null, source: null });\n }\n\n // Decrypt password if present.\n const password = settings.password\n ? this.encryption.decrypt(String(settings.password))\n : \"\";\n\n const transportSettings: TransportSettings = {\n host: String(settings.host || \"\"),\n port: Number(settings.port || 25),\n user: String(settings.user || \"\"),\n password,\n from: String(settings.from || \"\"),\n replyTo: settings.replyTo ? String(settings.replyTo) : undefined\n };\n\n return Result.ok({ settings: transportSettings, source: \"storage\" });\n }\n}\n\nexport const GetSettingsRepositoryImplementation = GetSettingsRepository.createImplementation({\n implementation: GetSettingsRepositoryImpl,\n dependencies: [KeyValueStore, Encryption, CodeMailerSettings]\n});\n"],"names":["GetSettingsRepositoryImpl","keyValueStore","encryption","codeSettings","transportName","codeSettingsValue","Result","result","MAILER_TRANSPORT_SETTINGS","settings","password","String","transportSettings","Number","undefined","GetSettingsRepositoryImplementation","GetSettingsRepository","KeyValueStore","Encryption","CodeMailerSettings"],"mappings":";;;;;;AAQA,MAAMA;IACF,YACYC,aAAsC,EACtCC,UAAgC,EAChCC,YAA0C,CACpD;aAHUF,aAAa,GAAbA;aACAC,UAAU,GAAVA;aACAC,YAAY,GAAZA;IACT;IAEH,MAAM,IAAIC,aAAqB,EAAwC;QAEnE,MAAMC,oBAAoB,IAAI,CAAC,YAAY,CAAC,GAAG,CAACD;QAChD,IAAIC,AAAsB,SAAtBA,mBACA,OAAOC,OAAO,EAAE,CAAC;YACb,UAAUD;YACV,QAAQ;QACZ;QAGJ,MAAME,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAoBC;QAE/D,IAAID,OAAO,MAAM,IACb,OAAOD,OAAO,EAAE,CAAC;YAAE,UAAU;YAAM,QAAQ;QAAK;QAGpD,MAAMG,WAAWF,OAAO,KAAK;QAC7B,IAAI,CAACE,UACD,OAAOH,OAAO,EAAE,CAAC;YAAE,UAAU;YAAM,QAAQ;QAAK;QAIpD,MAAMI,WAAWD,SAAS,QAAQ,GAC5B,IAAI,CAAC,UAAU,CAAC,OAAO,CAACE,OAAOF,SAAS,QAAQ,KAChD;QAEN,MAAMG,oBAAuC;YACzC,MAAMD,OAAOF,SAAS,IAAI,IAAI;YAC9B,MAAMI,OAAOJ,SAAS,IAAI,IAAI;YAC9B,MAAME,OAAOF,SAAS,IAAI,IAAI;YAC9BC;YACA,MAAMC,OAAOF,SAAS,IAAI,IAAI;YAC9B,SAASA,SAAS,OAAO,GAAGE,OAAOF,SAAS,OAAO,IAAIK;QAC3D;QAEA,OAAOR,OAAO,EAAE,CAAC;YAAE,UAAUM;YAAmB,QAAQ;QAAU;IACtE;AACJ;AAEO,MAAMG,sCAAsCC,sBAAsB,oBAAoB,CAAC;IAC1F,gBAAgBhB;IAChB,cAAc;QAACiB;QAAeC;QAAYC;KAAmB;AACjE"}
1
+ {"version":3,"file":"features/GetSettings/GetSettingsRepository.js","sources":["../../../src/features/GetSettings/GetSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { GetSettingsRepository, type ISettingsWithSource } from \"./abstractions.js\";\nimport { CodeMailerSettings } from \"~/domain/CodeMailerSettings/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nclass GetSettingsRepositoryImpl implements GetSettingsRepository.Interface {\n constructor(\n private keyValueStore: KeyValueStore.Interface,\n private encryption: Encryption.Interface,\n private codeSettings: CodeMailerSettings.Interface\n ) {}\n\n async get(transportName: string): Promise<Result<ISettingsWithSource>> {\n // Code-defined settings win over the KV store.\n const codeSettingsValue = this.codeSettings.get(transportName);\n if (codeSettingsValue !== null) {\n return Result.ok({\n settings: codeSettingsValue,\n source: \"code\"\n });\n }\n\n const result = await this.keyValueStore.get<TransportSettings>(MAILER_TRANSPORT_SETTINGS);\n\n if (result.isFail()) {\n return Result.ok({ settings: null, source: null });\n }\n\n const settings = result.value;\n if (!settings) {\n return Result.ok({ settings: null, source: null });\n }\n\n // Decrypt password if present.\n const password = settings.password\n ? await this.encryption.decrypt(String(settings.password))\n : \"\";\n\n const port = Number(settings.port || 587);\n\n const transportSettings: TransportSettings = {\n host: String(settings.host || \"\"),\n port,\n secure: settings.secure ?? port === 465,\n user: String(settings.user || \"\"),\n password,\n from: String(settings.from || \"\"),\n replyTo: settings.replyTo ? String(settings.replyTo) : undefined\n };\n\n return Result.ok({ settings: transportSettings, source: \"storage\" });\n }\n}\n\nexport const GetSettingsRepositoryImplementation = GetSettingsRepository.createImplementation({\n implementation: GetSettingsRepositoryImpl,\n dependencies: [KeyValueStore, Encryption, CodeMailerSettings]\n});\n"],"names":["GetSettingsRepositoryImpl","keyValueStore","encryption","codeSettings","transportName","codeSettingsValue","Result","result","MAILER_TRANSPORT_SETTINGS","settings","password","String","port","Number","transportSettings","undefined","GetSettingsRepositoryImplementation","GetSettingsRepository","KeyValueStore","Encryption","CodeMailerSettings"],"mappings":";;;;;;AAQA,MAAMA;IACF,YACYC,aAAsC,EACtCC,UAAgC,EAChCC,YAA0C,CACpD;aAHUF,aAAa,GAAbA;aACAC,UAAU,GAAVA;aACAC,YAAY,GAAZA;IACT;IAEH,MAAM,IAAIC,aAAqB,EAAwC;QAEnE,MAAMC,oBAAoB,IAAI,CAAC,YAAY,CAAC,GAAG,CAACD;QAChD,IAAIC,AAAsB,SAAtBA,mBACA,OAAOC,OAAO,EAAE,CAAC;YACb,UAAUD;YACV,QAAQ;QACZ;QAGJ,MAAME,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAoBC;QAE/D,IAAID,OAAO,MAAM,IACb,OAAOD,OAAO,EAAE,CAAC;YAAE,UAAU;YAAM,QAAQ;QAAK;QAGpD,MAAMG,WAAWF,OAAO,KAAK;QAC7B,IAAI,CAACE,UACD,OAAOH,OAAO,EAAE,CAAC;YAAE,UAAU;YAAM,QAAQ;QAAK;QAIpD,MAAMI,WAAWD,SAAS,QAAQ,GAC5B,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACE,OAAOF,SAAS,QAAQ,KACtD;QAEN,MAAMG,OAAOC,OAAOJ,SAAS,IAAI,IAAI;QAErC,MAAMK,oBAAuC;YACzC,MAAMH,OAAOF,SAAS,IAAI,IAAI;YAC9BG;YACA,QAAQH,SAAS,MAAM,IAAIG,AAAS,QAATA;YAC3B,MAAMD,OAAOF,SAAS,IAAI,IAAI;YAC9BC;YACA,MAAMC,OAAOF,SAAS,IAAI,IAAI;YAC9B,SAASA,SAAS,OAAO,GAAGE,OAAOF,SAAS,OAAO,IAAIM;QAC3D;QAEA,OAAOT,OAAO,EAAE,CAAC;YAAE,UAAUQ;YAAmB,QAAQ;QAAU;IACtE;AACJ;AAEO,MAAME,sCAAsCC,sBAAsB,oBAAoB,CAAC;IAC1F,gBAAgBjB;IAChB,cAAc;QAACkB;QAAeC;QAAYC;KAAmB;AACjE"}
@@ -1,14 +1,13 @@
1
1
  import { MailerService as Abstraction } from "../../domain/MailerService/abstractions.js";
2
- import { ActiveTransport, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
2
+ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
3
3
  import { GetSettingsRepository } from "../GetSettings/abstractions.js";
4
4
  import type { TransportSendData } from "../../types.js";
5
5
  declare class MailerServiceImpl implements Abstraction.Interface {
6
6
  private getSettingsRepository;
7
- private activeTransport;
8
7
  private transportFactories;
9
- constructor(getSettingsRepository: GetSettingsRepository.Interface, activeTransport: ActiveTransport.Interface, transportFactories: MailTransportFactory.Interface[]);
8
+ constructor(getSettingsRepository: GetSettingsRepository.Interface, transportFactories: MailTransportFactory.Interface[]);
10
9
  sendMail<T = any>(data: TransportSendData): Abstraction.Return<T>;
11
- private getTransport;
10
+ private resolveTransport;
12
11
  }
13
12
  export declare const MailerService: typeof MailerServiceImpl & {
14
13
  __abstraction: import("@webiny/di").Abstraction<import("~/domain/MailerService/abstractions.js").IMailerService>;
@@ -1,22 +1,16 @@
1
1
  import { Result } from "@webiny/feature/api";
2
2
  import { MailerService } from "../../domain/MailerService/abstractions.js";
3
- import { NoSettingsConfiguredError, NoTransportAvailableError, TransportSendError } from "../../domain/MailerService/errors.js";
4
- import { ActiveTransport, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
3
+ import { NoTransportAvailableError, TransportCreateError, TransportSendError } from "../../domain/MailerService/errors.js";
4
+ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
5
5
  import { GetSettingsRepository } from "../GetSettings/abstractions.js";
6
6
  class MailerServiceImpl {
7
- constructor(getSettingsRepository, activeTransport, transportFactories){
7
+ constructor(getSettingsRepository, transportFactories){
8
8
  this.getSettingsRepository = getSettingsRepository;
9
- this.activeTransport = activeTransport;
10
9
  this.transportFactories = transportFactories;
11
10
  }
12
11
  async sendMail(data) {
13
- const transportName = this.activeTransport.name();
14
- if (!transportName) return Result.fail(new NoTransportAvailableError());
15
- const result = await this.getSettingsRepository.get(transportName);
16
- const { settings } = result.value;
17
- if (!settings) return Result.fail(new NoSettingsConfiguredError());
18
- const transport = await this.getTransport(transportName, settings);
19
- if (!transport) return Result.fail(new NoTransportAvailableError());
12
+ const { factory, transport } = await this.resolveTransport();
13
+ if (!factory || !transport) return Result.fail(new NoTransportAvailableError());
20
14
  try {
21
15
  const response = await transport.send(data);
22
16
  if (response.error) return Result.fail(new TransportSendError(response.error));
@@ -25,17 +19,33 @@ class MailerServiceImpl {
25
19
  return Result.fail(new TransportSendError(error));
26
20
  }
27
21
  }
28
- async getTransport(transportName, settings) {
29
- const factory = this.transportFactories.find((f)=>f.name === transportName);
30
- if (!factory) return null;
31
- return factory.createTransport(settings);
22
+ async resolveTransport() {
23
+ const factories = [
24
+ ...this.transportFactories
25
+ ].reverse();
26
+ for (const factory of factories){
27
+ const result = await this.getSettingsRepository.get(factory.name);
28
+ const { settings } = result.value;
29
+ if (factory.canUse(settings)) try {
30
+ const transport = await factory.createTransport(settings);
31
+ return {
32
+ factory,
33
+ transport
34
+ };
35
+ } catch (error) {
36
+ throw new TransportCreateError(error);
37
+ }
38
+ }
39
+ return {
40
+ factory: null,
41
+ transport: null
42
+ };
32
43
  }
33
44
  }
34
45
  const MailerService_MailerService = MailerService.createImplementation({
35
46
  implementation: MailerServiceImpl,
36
47
  dependencies: [
37
48
  GetSettingsRepository,
38
- ActiveTransport,
39
49
  [
40
50
  MailTransportFactory,
41
51
  {
@@ -1 +1 @@
1
- {"version":3,"file":"features/MailerService/MailerService.js","sources":["../../../src/features/MailerService/MailerService.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { MailerService as Abstraction } from \"~/domain/MailerService/abstractions.js\";\nimport {\n NoTransportAvailableError,\n NoSettingsConfiguredError,\n TransportSendError\n} from \"~/domain/MailerService/errors.js\";\nimport {\n ActiveTransport,\n MailTransport,\n MailTransportFactory\n} from \"~/domain/MailTransport/abstractions.js\";\nimport { GetSettingsRepository } from \"../GetSettings/abstractions.js\";\nimport type { TransportSettings, TransportSendData } from \"~/types.js\";\n\nclass MailerServiceImpl implements Abstraction.Interface {\n constructor(\n private getSettingsRepository: GetSettingsRepository.Interface,\n private activeTransport: ActiveTransport.Interface,\n private transportFactories: MailTransportFactory.Interface[]\n ) {}\n\n async sendMail<T = any>(data: TransportSendData): Abstraction.Return<T> {\n const transportName = this.activeTransport.name();\n\n if (!transportName) {\n return Result.fail(new NoTransportAvailableError());\n }\n\n const result = await this.getSettingsRepository.get(transportName);\n const { settings } = result.value;\n\n if (!settings) {\n return Result.fail(new NoSettingsConfiguredError());\n }\n\n const transport = await this.getTransport(transportName, settings);\n\n if (!transport) {\n return Result.fail(new NoTransportAvailableError());\n }\n\n try {\n const response = await transport.send(data);\n\n if (response.error) {\n return Result.fail(new TransportSendError(response.error));\n }\n\n return Result.ok(response);\n } catch (error) {\n return Result.fail(new TransportSendError(error));\n }\n }\n\n private async getTransport(\n transportName: string,\n settings: TransportSettings\n ): Promise<MailTransport.Interface | null> {\n const factory = this.transportFactories.find(f => f.name === transportName);\n if (!factory) {\n return null;\n }\n return factory.createTransport(settings);\n }\n}\n\nexport const MailerService = Abstraction.createImplementation({\n implementation: MailerServiceImpl,\n dependencies: [\n GetSettingsRepository,\n ActiveTransport,\n [MailTransportFactory, { multiple: true }]\n ]\n});\n"],"names":["MailerServiceImpl","getSettingsRepository","activeTransport","transportFactories","data","transportName","Result","NoTransportAvailableError","result","settings","NoSettingsConfiguredError","transport","response","TransportSendError","error","factory","f","MailerService","Abstraction","GetSettingsRepository","ActiveTransport","MailTransportFactory"],"mappings":";;;;;AAeA,MAAMA;IACF,YACYC,qBAAsD,EACtDC,eAA0C,EAC1CC,kBAAoD,CAC9D;aAHUF,qBAAqB,GAArBA;aACAC,eAAe,GAAfA;aACAC,kBAAkB,GAAlBA;IACT;IAEH,MAAM,SAAkBC,IAAuB,EAAyB;QACpE,MAAMC,gBAAgB,IAAI,CAAC,eAAe,CAAC,IAAI;QAE/C,IAAI,CAACA,eACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAG3B,MAAMC,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAACH;QACpD,MAAM,EAAEI,QAAQ,EAAE,GAAGD,OAAO,KAAK;QAEjC,IAAI,CAACC,UACD,OAAOH,OAAO,IAAI,CAAC,IAAII;QAG3B,MAAMC,YAAY,MAAM,IAAI,CAAC,YAAY,CAACN,eAAeI;QAEzD,IAAI,CAACE,WACD,OAAOL,OAAO,IAAI,CAAC,IAAIC;QAG3B,IAAI;YACA,MAAMK,WAAW,MAAMD,UAAU,IAAI,CAACP;YAEtC,IAAIQ,SAAS,KAAK,EACd,OAAON,OAAO,IAAI,CAAC,IAAIO,mBAAmBD,SAAS,KAAK;YAG5D,OAAON,OAAO,EAAE,CAACM;QACrB,EAAE,OAAOE,OAAO;YACZ,OAAOR,OAAO,IAAI,CAAC,IAAIO,mBAAmBC;QAC9C;IACJ;IAEA,MAAc,aACVT,aAAqB,EACrBI,QAA2B,EACY;QACvC,MAAMM,UAAU,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAACC,CAAAA,IAAKA,EAAE,IAAI,KAAKX;QAC7D,IAAI,CAACU,SACD,OAAO;QAEX,OAAOA,QAAQ,eAAe,CAACN;IACnC;AACJ;AAEO,MAAMQ,8BAAgBC,cAAAA,oBAAgC,CAAC;IAC1D,gBAAgBlB;IAChB,cAAc;QACVmB;QACAC;QACA;YAACC;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAC7C;AACL"}
1
+ {"version":3,"file":"features/MailerService/MailerService.js","sources":["../../../src/features/MailerService/MailerService.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { MailerService as Abstraction } from \"~/domain/MailerService/abstractions.js\";\nimport {\n NoTransportAvailableError,\n TransportCreateError,\n TransportSendError\n} from \"~/domain/MailerService/errors.js\";\nimport { MailTransport, MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport { GetSettingsRepository } from \"../GetSettings/abstractions.js\";\nimport type { TransportSendData } from \"~/types.js\";\n\nclass MailerServiceImpl implements Abstraction.Interface {\n constructor(\n private getSettingsRepository: GetSettingsRepository.Interface,\n private transportFactories: MailTransportFactory.Interface[]\n ) {}\n\n async sendMail<T = any>(data: TransportSendData): Abstraction.Return<T> {\n const { factory, transport } = await this.resolveTransport();\n\n if (!factory || !transport) {\n return Result.fail(new NoTransportAvailableError());\n }\n\n try {\n const response = await transport.send(data);\n\n if (response.error) {\n return Result.fail(new TransportSendError(response.error));\n }\n\n return Result.ok(response);\n } catch (error) {\n return Result.fail(new TransportSendError(error));\n }\n }\n\n private async resolveTransport(): Promise<{\n factory: MailTransportFactory.Interface | null;\n transport: MailTransport.Interface | null;\n }> {\n const factories = [...this.transportFactories].reverse();\n\n for (const factory of factories) {\n const result = await this.getSettingsRepository.get(factory.name);\n const { settings } = result.value;\n\n if (!factory.canUse(settings)) {\n continue;\n }\n\n try {\n const transport = await factory.createTransport(settings!);\n return { factory, transport };\n } catch (error) {\n throw new TransportCreateError(error);\n }\n }\n\n return { factory: null, transport: null };\n }\n}\n\nexport const MailerService = Abstraction.createImplementation({\n implementation: MailerServiceImpl,\n dependencies: [GetSettingsRepository, [MailTransportFactory, { multiple: true }]]\n});\n"],"names":["MailerServiceImpl","getSettingsRepository","transportFactories","data","factory","transport","Result","NoTransportAvailableError","response","TransportSendError","error","factories","result","settings","TransportCreateError","MailerService","Abstraction","GetSettingsRepository","MailTransportFactory"],"mappings":";;;;;AAWA,MAAMA;IACF,YACYC,qBAAsD,EACtDC,kBAAoD,CAC9D;aAFUD,qBAAqB,GAArBA;aACAC,kBAAkB,GAAlBA;IACT;IAEH,MAAM,SAAkBC,IAAuB,EAAyB;QACpE,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB;QAE1D,IAAI,CAACD,WAAW,CAACC,WACb,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAG3B,IAAI;YACA,MAAMC,WAAW,MAAMH,UAAU,IAAI,CAACF;YAEtC,IAAIK,SAAS,KAAK,EACd,OAAOF,OAAO,IAAI,CAAC,IAAIG,mBAAmBD,SAAS,KAAK;YAG5D,OAAOF,OAAO,EAAE,CAACE;QACrB,EAAE,OAAOE,OAAO;YACZ,OAAOJ,OAAO,IAAI,CAAC,IAAIG,mBAAmBC;QAC9C;IACJ;IAEA,MAAc,mBAGX;QACC,MAAMC,YAAY;eAAI,IAAI,CAAC,kBAAkB;SAAC,CAAC,OAAO;QAEtD,KAAK,MAAMP,WAAWO,UAAW;YAC7B,MAAMC,SAAS,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAACR,QAAQ,IAAI;YAChE,MAAM,EAAES,QAAQ,EAAE,GAAGD,OAAO,KAAK;YAEjC,IAAKR,QAAQ,MAAM,CAACS,WAIpB,IAAI;gBACA,MAAMR,YAAY,MAAMD,QAAQ,eAAe,CAACS;gBAChD,OAAO;oBAAET;oBAASC;gBAAU;YAChC,EAAE,OAAOK,OAAO;gBACZ,MAAM,IAAII,qBAAqBJ;YACnC;QACJ;QAEA,OAAO;YAAE,SAAS;YAAM,WAAW;QAAK;IAC5C;AACJ;AAEO,MAAMK,8BAAgBC,cAAAA,oBAAgC,CAAC;IAC1D,gBAAgBhB;IAChB,cAAc;QAACiB;QAAuB;YAACC;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAAC;AACrF"}
@@ -1,10 +1,8 @@
1
1
  import { createFeature } from "@webiny/feature/api";
2
2
  import { MailerService } from "./MailerService.js";
3
- import { ActiveTransport } from "./ActiveTransport.js";
4
3
  const MailerServiceFeature = createFeature({
5
4
  name: "Mailer/MailerService",
6
5
  register (container) {
7
- container.register(ActiveTransport).inSingletonScope();
8
6
  container.register(MailerService).inSingletonScope();
9
7
  }
10
8
  });
@@ -1 +1 @@
1
- {"version":3,"file":"features/MailerService/feature.js","sources":["../../../src/features/MailerService/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { MailerService } from \"./MailerService.js\";\nimport { ActiveTransport } from \"./ActiveTransport.js\";\n\nexport const MailerServiceFeature = createFeature({\n name: \"Mailer/MailerService\",\n register(container) {\n container.register(ActiveTransport).inSingletonScope();\n container.register(MailerService).inSingletonScope();\n }\n});\n"],"names":["MailerServiceFeature","createFeature","container","ActiveTransport","MailerService"],"mappings":";;;AAIO,MAAMA,uBAAuBC,cAAc;IAC9C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,iBAAiB,gBAAgB;QACpDD,UAAU,QAAQ,CAACE,eAAe,gBAAgB;IACtD;AACJ"}
1
+ {"version":3,"file":"features/MailerService/feature.js","sources":["../../../src/features/MailerService/feature.ts"],"sourcesContent":["import { createFeature } from \"@webiny/feature/api\";\nimport { MailerService } from \"./MailerService.js\";\n\nexport const MailerServiceFeature = createFeature({\n name: \"Mailer/MailerService\",\n register(container) {\n container.register(MailerService).inSingletonScope();\n }\n});\n"],"names":["MailerServiceFeature","createFeature","container","MailerService"],"mappings":";;AAGO,MAAMA,uBAAuBC,cAAc;IAC9C,MAAM;IACN,UAASC,SAAS;QACdA,UAAU,QAAQ,CAACC,eAAe,gBAAgB;IACtD;AACJ"}
@@ -4,7 +4,7 @@ import { SaveSettingsRepository } from "./abstractions.js";
4
4
  import { SettingsPersistenceError } from "../../domain/errors.js";
5
5
  import { KeyValueStore } from "@webiny/api-core/features/keyValueStore/index.js";
6
6
  import { MAILER_TRANSPORT_SETTINGS } from "../../constants.js";
7
- const DEFAULT_PORT = 25;
7
+ const DEFAULT_PORT = 587;
8
8
  class SaveSettingsRepositoryImpl {
9
9
  constructor(keyValueStore, encryption){
10
10
  this.keyValueStore = keyValueStore;
@@ -15,11 +15,13 @@ class SaveSettingsRepositoryImpl {
15
15
  const existingSettings = existingResult.isOk() ? existingResult.value : null;
16
16
  const transportSettings = existingSettings ?? {};
17
17
  let passwordToStore = input.password || "";
18
- if (!input.password && existingSettings) passwordToStore = this.encryption.decrypt(transportSettings.password || "");
19
- const encryptedPassword = this.encryption.encrypt(passwordToStore);
18
+ if (!input.password && existingSettings) passwordToStore = await this.encryption.decrypt(transportSettings.password || "");
19
+ const encryptedPassword = await this.encryption.encrypt(passwordToStore);
20
+ const port = input.port ?? transportSettings.port ?? DEFAULT_PORT;
20
21
  const data = {
21
22
  host: input.host ?? transportSettings.host,
22
- port: input.port ?? transportSettings.port ?? DEFAULT_PORT,
23
+ port,
24
+ secure: input.secure ?? transportSettings.secure ?? 465 === port,
23
25
  user: input.user ?? transportSettings.user,
24
26
  password: encryptedPassword,
25
27
  from: input.from ?? transportSettings.from,
@@ -1 +1 @@
1
- {"version":3,"file":"features/SaveSettings/SaveSettingsRepository.js","sources":["../../../src/features/SaveSettings/SaveSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { SaveSettingsRepository, type SaveSettingsInput } from \"./abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SettingsPersistenceError } from \"~/domain/errors.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nconst DEFAULT_PORT = 25;\n\nclass SaveSettingsRepositoryImpl implements SaveSettingsRepository.Interface {\n constructor(\n private keyValueStore: KeyValueStore.Interface,\n private encryption: Encryption.Interface\n ) {}\n\n async execute(input: SaveSettingsInput): SaveSettingsRepository.Return {\n // Check if settings exist\n const existingResult =\n await this.keyValueStore.get<TransportSettings>(MAILER_TRANSPORT_SETTINGS);\n const existingSettings = existingResult.isOk() ? existingResult.value : null;\n const transportSettings: Partial<TransportSettings> = existingSettings ?? {};\n\n // If updating and no password provided, keep the existing password\n let passwordToStore = input.password || \"\";\n if (!input.password && existingSettings) {\n passwordToStore = this.encryption.decrypt(transportSettings.password || \"\");\n }\n\n // Encrypt password\n const encryptedPassword = this.encryption.encrypt(passwordToStore);\n\n // Prepare data\n const data = {\n host: input.host ?? transportSettings.host,\n port: input.port ?? transportSettings.port ?? DEFAULT_PORT,\n user: input.user ?? transportSettings.user,\n password: encryptedPassword,\n from: input.from ?? transportSettings.from,\n replyTo: input.replyTo ?? transportSettings.replyTo\n };\n\n // Save settings.\n const result = await this.keyValueStore.set(MAILER_TRANSPORT_SETTINGS, data);\n\n if (result.isFail()) {\n return Result.fail(new SettingsPersistenceError(result.error));\n }\n\n // Return the stored state without the password. Callers that need the\n // plaintext password go through GetSettingsRepository.get(transportName).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _password, ...savedSettings } = data as TransportSettings;\n return Result.ok(savedSettings);\n }\n}\n\nexport const SaveSettingsRepositoryImplementation = SaveSettingsRepository.createImplementation({\n implementation: SaveSettingsRepositoryImpl,\n dependencies: [KeyValueStore, Encryption]\n});\n"],"names":["DEFAULT_PORT","SaveSettingsRepositoryImpl","keyValueStore","encryption","input","existingResult","MAILER_TRANSPORT_SETTINGS","existingSettings","transportSettings","passwordToStore","encryptedPassword","data","result","Result","SettingsPersistenceError","_password","savedSettings","SaveSettingsRepositoryImplementation","SaveSettingsRepository","KeyValueStore","Encryption"],"mappings":";;;;;;AAQA,MAAMA,eAAe;AAErB,MAAMC;IACF,YACYC,aAAsC,EACtCC,UAAgC,CAC1C;aAFUD,aAAa,GAAbA;aACAC,UAAU,GAAVA;IACT;IAEH,MAAM,QAAQC,KAAwB,EAAiC;QAEnE,MAAMC,iBACF,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAoBC;QACpD,MAAMC,mBAAmBF,eAAe,IAAI,KAAKA,eAAe,KAAK,GAAG;QACxE,MAAMG,oBAAgDD,oBAAoB,CAAC;QAG3E,IAAIE,kBAAkBL,MAAM,QAAQ,IAAI;QACxC,IAAI,CAACA,MAAM,QAAQ,IAAIG,kBACnBE,kBAAkB,IAAI,CAAC,UAAU,CAAC,OAAO,CAACD,kBAAkB,QAAQ,IAAI;QAI5E,MAAME,oBAAoB,IAAI,CAAC,UAAU,CAAC,OAAO,CAACD;QAGlD,MAAME,OAAO;YACT,MAAMP,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1C,MAAMJ,MAAM,IAAI,IAAII,kBAAkB,IAAI,IAAIR;YAC9C,MAAMI,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1C,UAAUE;YACV,MAAMN,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1C,SAASJ,MAAM,OAAO,IAAII,kBAAkB,OAAO;QACvD;QAGA,MAAMI,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAACN,2BAA2BK;QAEvE,IAAIC,OAAO,MAAM,IACb,OAAOC,OAAO,IAAI,CAAC,IAAIC,yBAAyBF,OAAO,KAAK;QAMhE,MAAM,EAAE,UAAUG,SAAS,EAAE,GAAGC,eAAe,GAAGL;QAClD,OAAOE,OAAO,EAAE,CAACG;IACrB;AACJ;AAEO,MAAMC,uCAAuCC,uBAAuB,oBAAoB,CAAC;IAC5F,gBAAgBjB;IAChB,cAAc;QAACkB;QAAeC;KAAW;AAC7C"}
1
+ {"version":3,"file":"features/SaveSettings/SaveSettingsRepository.js","sources":["../../../src/features/SaveSettings/SaveSettingsRepository.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { Encryption } from \"@webiny/api-core/features/encryption/index.js\";\nimport { SaveSettingsRepository, type SaveSettingsInput } from \"./abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SettingsPersistenceError } from \"~/domain/errors.js\";\nimport { KeyValueStore } from \"@webiny/api-core/features/keyValueStore/index.js\";\nimport { MAILER_TRANSPORT_SETTINGS } from \"~/constants.js\";\n\nconst DEFAULT_PORT = 587;\n\nclass SaveSettingsRepositoryImpl implements SaveSettingsRepository.Interface {\n constructor(\n private keyValueStore: KeyValueStore.Interface,\n private encryption: Encryption.Interface\n ) {}\n\n async execute(input: SaveSettingsInput): SaveSettingsRepository.Return {\n // Check if settings exist\n const existingResult =\n await this.keyValueStore.get<TransportSettings>(MAILER_TRANSPORT_SETTINGS);\n const existingSettings = existingResult.isOk() ? existingResult.value : null;\n const transportSettings: Partial<TransportSettings> = existingSettings ?? {};\n\n // If updating and no password provided, keep the existing password\n let passwordToStore = input.password || \"\";\n if (!input.password && existingSettings) {\n passwordToStore = await this.encryption.decrypt(transportSettings.password || \"\");\n }\n\n // Encrypt password\n const encryptedPassword = await this.encryption.encrypt(passwordToStore);\n\n // Prepare data\n const port = input.port ?? transportSettings.port ?? DEFAULT_PORT;\n\n const data = {\n host: input.host ?? transportSettings.host,\n port,\n secure: input.secure ?? transportSettings.secure ?? port === 465,\n user: input.user ?? transportSettings.user,\n password: encryptedPassword,\n from: input.from ?? transportSettings.from,\n replyTo: input.replyTo ?? transportSettings.replyTo\n };\n\n // Save settings.\n const result = await this.keyValueStore.set(MAILER_TRANSPORT_SETTINGS, data);\n\n if (result.isFail()) {\n return Result.fail(new SettingsPersistenceError(result.error));\n }\n\n // Return the stored state without the password. Callers that need the\n // plaintext password go through GetSettingsRepository.get(transportName).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _password, ...savedSettings } = data as TransportSettings;\n return Result.ok(savedSettings);\n }\n}\n\nexport const SaveSettingsRepositoryImplementation = SaveSettingsRepository.createImplementation({\n implementation: SaveSettingsRepositoryImpl,\n dependencies: [KeyValueStore, Encryption]\n});\n"],"names":["DEFAULT_PORT","SaveSettingsRepositoryImpl","keyValueStore","encryption","input","existingResult","MAILER_TRANSPORT_SETTINGS","existingSettings","transportSettings","passwordToStore","encryptedPassword","port","data","result","Result","SettingsPersistenceError","_password","savedSettings","SaveSettingsRepositoryImplementation","SaveSettingsRepository","KeyValueStore","Encryption"],"mappings":";;;;;;AAQA,MAAMA,eAAe;AAErB,MAAMC;IACF,YACYC,aAAsC,EACtCC,UAAgC,CAC1C;aAFUD,aAAa,GAAbA;aACAC,UAAU,GAAVA;IACT;IAEH,MAAM,QAAQC,KAAwB,EAAiC;QAEnE,MAAMC,iBACF,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAoBC;QACpD,MAAMC,mBAAmBF,eAAe,IAAI,KAAKA,eAAe,KAAK,GAAG;QACxE,MAAMG,oBAAgDD,oBAAoB,CAAC;QAG3E,IAAIE,kBAAkBL,MAAM,QAAQ,IAAI;QACxC,IAAI,CAACA,MAAM,QAAQ,IAAIG,kBACnBE,kBAAkB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACD,kBAAkB,QAAQ,IAAI;QAIlF,MAAME,oBAAoB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACD;QAGxD,MAAME,OAAOP,MAAM,IAAI,IAAII,kBAAkB,IAAI,IAAIR;QAErD,MAAMY,OAAO;YACT,MAAMR,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1CG;YACA,QAAQP,MAAM,MAAM,IAAII,kBAAkB,MAAM,IAAIG,AAAS,QAATA;YACpD,MAAMP,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1C,UAAUE;YACV,MAAMN,MAAM,IAAI,IAAII,kBAAkB,IAAI;YAC1C,SAASJ,MAAM,OAAO,IAAII,kBAAkB,OAAO;QACvD;QAGA,MAAMK,SAAS,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAACP,2BAA2BM;QAEvE,IAAIC,OAAO,MAAM,IACb,OAAOC,OAAO,IAAI,CAAC,IAAIC,yBAAyBF,OAAO,KAAK;QAMhE,MAAM,EAAE,UAAUG,SAAS,EAAE,GAAGC,eAAe,GAAGL;QAClD,OAAOE,OAAO,EAAE,CAACG;IACrB;AACJ;AAEO,MAAMC,uCAAuCC,uBAAuB,oBAAoB,CAAC;IAC5F,gBAAgBlB;IAChB,cAAc;QAACmB;QAAeC;KAAW;AAC7C"}
@@ -1,15 +1,15 @@
1
- import { EventPublisher as EventPublisherAbstraction } from "@webiny/api-core/features/eventPublisher/index.js";
1
+ import { EventPublisher } from "@webiny/api-core/features/eventPublisher/index.js";
2
2
  import { SaveSettingsUseCase, SaveSettingsRepository, type SaveSettingsInput } from "./abstractions.js";
3
3
  import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
4
4
  import { CodeMailerSettings } from "../../domain/CodeMailerSettings/abstractions.js";
5
- import { ActiveTransport } from "../../domain/MailTransport/abstractions.js";
5
+ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
6
6
  declare class SaveSettingsUseCaseImpl implements SaveSettingsUseCase.Interface {
7
7
  private identityContext;
8
8
  private eventPublisher;
9
9
  private repository;
10
10
  private codeSettings;
11
- private activeTransport;
12
- constructor(identityContext: IdentityContext.Interface, eventPublisher: EventPublisherAbstraction.Interface, repository: SaveSettingsRepository.Interface, codeSettings: CodeMailerSettings.Interface, activeTransport: ActiveTransport.Interface);
11
+ private transportFactories;
12
+ constructor(identityContext: IdentityContext.Interface, eventPublisher: EventPublisher.Interface, repository: SaveSettingsRepository.Interface, codeSettings: CodeMailerSettings.Interface, transportFactories: MailTransportFactory.Interface[]);
13
13
  execute(input: SaveSettingsInput): SaveSettingsUseCase.Return;
14
14
  }
15
15
  export declare const SaveSettingsUseCaseImplementation: typeof SaveSettingsUseCaseImpl & {
@@ -6,22 +6,22 @@ import { saveValidation } from "./validation.js";
6
6
  import { SettingsLockedByCode, SettingsNotAuthorized, SettingsPersistenceError, SettingsValidationError } from "../../domain/errors.js";
7
7
  import { IdentityContext } from "@webiny/api-core/features/security/IdentityContext/index.js";
8
8
  import { CodeMailerSettings } from "../../domain/CodeMailerSettings/abstractions.js";
9
- import { ActiveTransport } from "../../domain/MailTransport/abstractions.js";
9
+ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
10
10
  class SaveSettingsUseCaseImpl {
11
- constructor(identityContext, eventPublisher, repository, codeSettings, activeTransport){
11
+ constructor(identityContext, eventPublisher, repository, codeSettings, transportFactories){
12
12
  this.identityContext = identityContext;
13
13
  this.eventPublisher = eventPublisher;
14
14
  this.repository = repository;
15
15
  this.codeSettings = codeSettings;
16
- this.activeTransport = activeTransport;
16
+ this.transportFactories = transportFactories;
17
17
  }
18
18
  async execute(input) {
19
19
  const permission = await this.identityContext.getPermission("mailer.settings");
20
20
  if (!permission) return Result.fail(new SettingsNotAuthorized());
21
21
  const validationResult = saveValidation.safeParse(input);
22
22
  if (!validationResult.success) return Result.fail(new SettingsValidationError(validationResult.error.issues));
23
- const transportName = this.activeTransport.name();
24
- if (transportName && null !== this.codeSettings.get(transportName)) return Result.fail(new SettingsLockedByCode());
23
+ const isLockedByCode = this.transportFactories.some((f)=>null !== this.codeSettings.get(f.name));
24
+ if (isLockedByCode) return Result.fail(new SettingsLockedByCode());
25
25
  const { password: _beforePassword, ...inputForEvent } = input;
26
26
  const beforeSaveEvent = new MailerSettingsBeforeSaveEvent({
27
27
  input: inputForEvent
@@ -43,7 +43,12 @@ const SaveSettingsUseCaseImplementation = SaveSettingsUseCase.createImplementati
43
43
  EventPublisher,
44
44
  SaveSettingsRepository,
45
45
  CodeMailerSettings,
46
- ActiveTransport
46
+ [
47
+ MailTransportFactory,
48
+ {
49
+ multiple: true
50
+ }
51
+ ]
47
52
  ]
48
53
  });
49
54
  export { SaveSettingsUseCaseImplementation };
@@ -1 +1 @@
1
- {"version":3,"file":"features/SaveSettings/SaveSettingsUseCase.js","sources":["../../../src/features/SaveSettings/SaveSettingsUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport {\n EventPublisher,\n EventPublisher as EventPublisherAbstraction\n} from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport {\n SaveSettingsUseCase,\n SaveSettingsRepository,\n type SaveSettingsInput\n} from \"./abstractions.js\";\nimport { MailerSettingsBeforeSaveEvent, MailerSettingsAfterSaveEvent } from \"./events.js\";\nimport { saveValidation } from \"./validation.js\";\nimport {\n SettingsValidationError,\n SettingsPersistenceError,\n SettingsNotAuthorized,\n SettingsLockedByCode\n} from \"~/domain/errors.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { CodeMailerSettings } from \"~/domain/CodeMailerSettings/abstractions.js\";\nimport { ActiveTransport } from \"~/domain/MailTransport/abstractions.js\";\n\nclass SaveSettingsUseCaseImpl implements SaveSettingsUseCase.Interface {\n constructor(\n private identityContext: IdentityContext.Interface,\n private eventPublisher: EventPublisherAbstraction.Interface,\n private repository: SaveSettingsRepository.Interface,\n private codeSettings: CodeMailerSettings.Interface,\n private activeTransport: ActiveTransport.Interface\n ) {}\n\n async execute(input: SaveSettingsInput): SaveSettingsUseCase.Return {\n const permission = await this.identityContext.getPermission(\"mailer.settings\");\n\n if (!permission) {\n return Result.fail(new SettingsNotAuthorized());\n }\n\n // Validate input.\n const validationResult = saveValidation.safeParse(input);\n if (!validationResult.success) {\n return Result.fail(new SettingsValidationError(validationResult.error.issues));\n }\n\n // Refuse when settings are defined via code.\n const transportName = this.activeTransport.name();\n if (transportName && this.codeSettings.get(transportName) !== null) {\n return Result.fail(new SettingsLockedByCode());\n }\n\n // Publish before save event. Strip the password — subscribers (audit\n // logs, telemetry) must never see the plaintext value from the input.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _beforePassword, ...inputForEvent } = input;\n const beforeSaveEvent = new MailerSettingsBeforeSaveEvent({ input: inputForEvent });\n await this.eventPublisher.publish(beforeSaveEvent);\n\n // Save settings.\n const result = await this.repository.execute(input);\n\n if (result.isFail()) {\n return Result.fail(new SettingsPersistenceError(result.error));\n }\n\n // Publish after save event. The repository return is already password-free\n // (its type is Omit<TransportSettings, \"password\">), so no runtime strip\n // is needed here.\n const afterSaveEvent = new MailerSettingsAfterSaveEvent({ settings: result.value });\n await this.eventPublisher.publish(afterSaveEvent);\n\n return result;\n }\n}\n\nexport const SaveSettingsUseCaseImplementation = SaveSettingsUseCase.createImplementation({\n implementation: SaveSettingsUseCaseImpl,\n dependencies: [\n IdentityContext,\n EventPublisher,\n SaveSettingsRepository,\n CodeMailerSettings,\n ActiveTransport\n ]\n});\n"],"names":["SaveSettingsUseCaseImpl","identityContext","eventPublisher","repository","codeSettings","activeTransport","input","permission","Result","SettingsNotAuthorized","validationResult","saveValidation","SettingsValidationError","transportName","SettingsLockedByCode","_beforePassword","inputForEvent","beforeSaveEvent","MailerSettingsBeforeSaveEvent","result","SettingsPersistenceError","afterSaveEvent","MailerSettingsAfterSaveEvent","SaveSettingsUseCaseImplementation","SaveSettingsUseCase","IdentityContext","EventPublisher","SaveSettingsRepository","CodeMailerSettings","ActiveTransport"],"mappings":";;;;;;;;;AAsBA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,cAAmD,EACnDC,UAA4C,EAC5CC,YAA0C,EAC1CC,eAA0C,CACpD;aALUJ,eAAe,GAAfA;aACAC,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,YAAY,GAAZA;aACAC,eAAe,GAAfA;IACT;IAEH,MAAM,QAAQC,KAAwB,EAA8B;QAChE,MAAMC,aAAa,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC;QAE5D,IAAI,CAACA,YACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAI3B,MAAMC,mBAAmBC,eAAe,SAAS,CAACL;QAClD,IAAI,CAACI,iBAAiB,OAAO,EACzB,OAAOF,OAAO,IAAI,CAAC,IAAII,wBAAwBF,iBAAiB,KAAK,CAAC,MAAM;QAIhF,MAAMG,gBAAgB,IAAI,CAAC,eAAe,CAAC,IAAI;QAC/C,IAAIA,iBAAiB,AAAyC,SAAzC,IAAI,CAAC,YAAY,CAAC,GAAG,CAACA,gBACvC,OAAOL,OAAO,IAAI,CAAC,IAAIM;QAM3B,MAAM,EAAE,UAAUC,eAAe,EAAE,GAAGC,eAAe,GAAGV;QACxD,MAAMW,kBAAkB,IAAIC,8BAA8B;YAAE,OAAOF;QAAc;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAACC;QAGlC,MAAME,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACb;QAE7C,IAAIa,OAAO,MAAM,IACb,OAAOX,OAAO,IAAI,CAAC,IAAIY,yBAAyBD,OAAO,KAAK;QAMhE,MAAME,iBAAiB,IAAIC,6BAA6B;YAAE,UAAUH,OAAO,KAAK;QAAC;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAACE;QAElC,OAAOF;IACX;AACJ;AAEO,MAAMI,oCAAoCC,oBAAoB,oBAAoB,CAAC;IACtF,gBAAgBxB;IAChB,cAAc;QACVyB;QACAC;QACAC;QACAC;QACAC;KACH;AACL"}
1
+ {"version":3,"file":"features/SaveSettings/SaveSettingsUseCase.js","sources":["../../../src/features/SaveSettings/SaveSettingsUseCase.ts"],"sourcesContent":["import { Result } from \"@webiny/feature/api\";\nimport { EventPublisher } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport {\n SaveSettingsUseCase,\n SaveSettingsRepository,\n type SaveSettingsInput\n} from \"./abstractions.js\";\nimport { MailerSettingsBeforeSaveEvent, MailerSettingsAfterSaveEvent } from \"./events.js\";\nimport { saveValidation } from \"./validation.js\";\nimport {\n SettingsValidationError,\n SettingsPersistenceError,\n SettingsNotAuthorized,\n SettingsLockedByCode\n} from \"~/domain/errors.js\";\nimport { IdentityContext } from \"@webiny/api-core/features/security/IdentityContext/index.js\";\nimport { CodeMailerSettings } from \"~/domain/CodeMailerSettings/abstractions.js\";\nimport { MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\n\nclass SaveSettingsUseCaseImpl implements SaveSettingsUseCase.Interface {\n constructor(\n private identityContext: IdentityContext.Interface,\n private eventPublisher: EventPublisher.Interface,\n private repository: SaveSettingsRepository.Interface,\n private codeSettings: CodeMailerSettings.Interface,\n private transportFactories: MailTransportFactory.Interface[]\n ) {}\n\n async execute(input: SaveSettingsInput): SaveSettingsUseCase.Return {\n const permission = await this.identityContext.getPermission(\"mailer.settings\");\n\n if (!permission) {\n return Result.fail(new SettingsNotAuthorized());\n }\n\n const validationResult = saveValidation.safeParse(input);\n if (!validationResult.success) {\n return Result.fail(new SettingsValidationError(validationResult.error.issues));\n }\n\n /* Refuse when any registered transport has code-defined settings. */\n const isLockedByCode = this.transportFactories.some(\n f => this.codeSettings.get(f.name) !== null\n );\n\n if (isLockedByCode) {\n return Result.fail(new SettingsLockedByCode());\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _beforePassword, ...inputForEvent } = input;\n const beforeSaveEvent = new MailerSettingsBeforeSaveEvent({ input: inputForEvent });\n await this.eventPublisher.publish(beforeSaveEvent);\n\n const result = await this.repository.execute(input);\n\n if (result.isFail()) {\n return Result.fail(new SettingsPersistenceError(result.error));\n }\n\n const afterSaveEvent = new MailerSettingsAfterSaveEvent({ settings: result.value });\n await this.eventPublisher.publish(afterSaveEvent);\n\n return result;\n }\n}\n\nexport const SaveSettingsUseCaseImplementation = SaveSettingsUseCase.createImplementation({\n implementation: SaveSettingsUseCaseImpl,\n dependencies: [\n IdentityContext,\n EventPublisher,\n SaveSettingsRepository,\n CodeMailerSettings,\n [MailTransportFactory, { multiple: true }]\n ]\n});\n"],"names":["SaveSettingsUseCaseImpl","identityContext","eventPublisher","repository","codeSettings","transportFactories","input","permission","Result","SettingsNotAuthorized","validationResult","saveValidation","SettingsValidationError","isLockedByCode","f","SettingsLockedByCode","_beforePassword","inputForEvent","beforeSaveEvent","MailerSettingsBeforeSaveEvent","result","SettingsPersistenceError","afterSaveEvent","MailerSettingsAfterSaveEvent","SaveSettingsUseCaseImplementation","SaveSettingsUseCase","IdentityContext","EventPublisher","SaveSettingsRepository","CodeMailerSettings","MailTransportFactory"],"mappings":";;;;;;;;;AAmBA,MAAMA;IACF,YACYC,eAA0C,EAC1CC,cAAwC,EACxCC,UAA4C,EAC5CC,YAA0C,EAC1CC,kBAAoD,CAC9D;aALUJ,eAAe,GAAfA;aACAC,cAAc,GAAdA;aACAC,UAAU,GAAVA;aACAC,YAAY,GAAZA;aACAC,kBAAkB,GAAlBA;IACT;IAEH,MAAM,QAAQC,KAAwB,EAA8B;QAChE,MAAMC,aAAa,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC;QAE5D,IAAI,CAACA,YACD,OAAOC,OAAO,IAAI,CAAC,IAAIC;QAG3B,MAAMC,mBAAmBC,eAAe,SAAS,CAACL;QAClD,IAAI,CAACI,iBAAiB,OAAO,EACzB,OAAOF,OAAO,IAAI,CAAC,IAAII,wBAAwBF,iBAAiB,KAAK,CAAC,MAAM;QAIhF,MAAMG,iBAAiB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC/CC,CAAAA,IAAK,AAAkC,SAAlC,IAAI,CAAC,YAAY,CAAC,GAAG,CAACA,EAAE,IAAI;QAGrC,IAAID,gBACA,OAAOL,OAAO,IAAI,CAAC,IAAIO;QAI3B,MAAM,EAAE,UAAUC,eAAe,EAAE,GAAGC,eAAe,GAAGX;QACxD,MAAMY,kBAAkB,IAAIC,8BAA8B;YAAE,OAAOF;QAAc;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAACC;QAElC,MAAME,SAAS,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAACd;QAE7C,IAAIc,OAAO,MAAM,IACb,OAAOZ,OAAO,IAAI,CAAC,IAAIa,yBAAyBD,OAAO,KAAK;QAGhE,MAAME,iBAAiB,IAAIC,6BAA6B;YAAE,UAAUH,OAAO,KAAK;QAAC;QACjF,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAACE;QAElC,OAAOF;IACX;AACJ;AAEO,MAAMI,oCAAoCC,oBAAoB,oBAAoB,CAAC;IACtF,gBAAgBzB;IAChB,cAAc;QACV0B;QACAC;QACAC;QACAC;QACA;YAACC;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAC7C;AACL"}
@@ -5,6 +5,7 @@ import { SettingsValidationError, SettingsPersistenceError, SettingsNotAuthorize
5
5
  export interface SaveSettingsInput {
6
6
  host: string;
7
7
  port?: number;
8
+ secure?: boolean;
8
9
  user: string;
9
10
  password?: string;
10
11
  from: string;
@@ -1 +1 @@
1
- {"version":3,"file":"features/SaveSettings/abstractions.js","sources":["../../../src/features/SaveSettings/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { DomainEvent, IEventHandler } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport {\n SettingsValidationError,\n SettingsPersistenceError,\n SettingsNotAuthorized,\n SettingsLockedByCode\n} from \"~/domain/errors.js\";\n\nexport interface SaveSettingsInput {\n host: string;\n port?: number;\n user: string;\n password?: string;\n from: string;\n replyTo?: string;\n}\n\nexport interface ISaveSettingsErrors {\n validation: SettingsValidationError;\n persistence: SettingsPersistenceError;\n notAuthorized: SettingsNotAuthorized;\n lockedByCode: SettingsLockedByCode;\n}\n\ntype SaveSettingsError = ISaveSettingsErrors[keyof ISaveSettingsErrors];\n\n/**\n * Save-side returns are password-free. The only path that exposes the password\n * to in-process callers is GetSettingsRepository.get / GetSettingsUseCase.execute\n * (used by MailerService to authenticate SMTP). Everything else — events,\n * GraphQL responses, logs, audit trails — must use this Omit shape.\n */\nexport type SavedTransportSettings = Omit<TransportSettings, \"password\">;\n\nexport interface ISaveSettingsRepository {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsRepository =\n createAbstraction<ISaveSettingsRepository>(\"SaveSettingsRepository\");\n\nexport namespace SaveSettingsRepository {\n export type Interface = ISaveSettingsRepository;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\nexport interface ISaveSettings {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsUseCase = createAbstraction<ISaveSettings>(\"SaveSettingsUseCase\");\n\nexport namespace SaveSettingsUseCase {\n export type Interface = ISaveSettings;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\n// Domain Events. Both payloads exclude `password` so subscribers (audit logs,\n// telemetry, etc.) cannot accidentally persist plaintext or ciphertext secrets.\nexport interface MailerSettingsBeforeSavePayload {\n input: Omit<SaveSettingsInput, \"password\">;\n}\n\nexport interface MailerSettingsAfterSavePayload {\n settings: Omit<TransportSettings, \"password\">;\n}\n\n// Event Handler Abstractions\nexport const MailerSettingsBeforeSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>\n>(\"MailerSettingsBeforeSaveEventHandler\");\n\nexport namespace MailerSettingsBeforeSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>;\n export type Event = DomainEvent<MailerSettingsBeforeSavePayload>;\n}\n\nexport const MailerSettingsAfterSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>\n>(\"MailerSettingsAfterSaveEventHandler\");\n\nexport namespace MailerSettingsAfterSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>;\n export type Event = DomainEvent<MailerSettingsAfterSavePayload>;\n}\n"],"names":["SaveSettingsRepository","createAbstraction","SaveSettingsUseCase","MailerSettingsBeforeSaveEventHandler","MailerSettingsAfterSaveEventHandler"],"mappings":";AAyCO,MAAMA,yBACTC,kBAA2C;AAYxC,MAAMC,sBAAsBD,kBAAiC;AAmB7D,MAAME,uCAAuCF,kBAElD;AAOK,MAAMG,sCAAsCH,kBAEjD"}
1
+ {"version":3,"file":"features/SaveSettings/abstractions.js","sources":["../../../src/features/SaveSettings/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport { Result } from \"@webiny/feature/api\";\nimport type { DomainEvent, IEventHandler } from \"@webiny/api-core/features/eventPublisher/index.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport {\n SettingsValidationError,\n SettingsPersistenceError,\n SettingsNotAuthorized,\n SettingsLockedByCode\n} from \"~/domain/errors.js\";\n\nexport interface SaveSettingsInput {\n host: string;\n port?: number;\n secure?: boolean;\n user: string;\n password?: string;\n from: string;\n replyTo?: string;\n}\n\nexport interface ISaveSettingsErrors {\n validation: SettingsValidationError;\n persistence: SettingsPersistenceError;\n notAuthorized: SettingsNotAuthorized;\n lockedByCode: SettingsLockedByCode;\n}\n\ntype SaveSettingsError = ISaveSettingsErrors[keyof ISaveSettingsErrors];\n\n/**\n * Save-side returns are password-free. The only path that exposes the password\n * to in-process callers is GetSettingsRepository.get / GetSettingsUseCase.execute\n * (used by MailerService to authenticate SMTP). Everything else — events,\n * GraphQL responses, logs, audit trails — must use this Omit shape.\n */\nexport type SavedTransportSettings = Omit<TransportSettings, \"password\">;\n\nexport interface ISaveSettingsRepository {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsRepository =\n createAbstraction<ISaveSettingsRepository>(\"SaveSettingsRepository\");\n\nexport namespace SaveSettingsRepository {\n export type Interface = ISaveSettingsRepository;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\nexport interface ISaveSettings {\n execute(input: SaveSettingsInput): Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n}\n\nexport const SaveSettingsUseCase = createAbstraction<ISaveSettings>(\"SaveSettingsUseCase\");\n\nexport namespace SaveSettingsUseCase {\n export type Interface = ISaveSettings;\n export type Return = Promise<Result<SavedTransportSettings, SaveSettingsError>>;\n export type Error = SaveSettingsError;\n}\n\n// Domain Events. Both payloads exclude `password` so subscribers (audit logs,\n// telemetry, etc.) cannot accidentally persist plaintext or ciphertext secrets.\nexport interface MailerSettingsBeforeSavePayload {\n input: Omit<SaveSettingsInput, \"password\">;\n}\n\nexport interface MailerSettingsAfterSavePayload {\n settings: Omit<TransportSettings, \"password\">;\n}\n\n// Event Handler Abstractions\nexport const MailerSettingsBeforeSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>\n>(\"MailerSettingsBeforeSaveEventHandler\");\n\nexport namespace MailerSettingsBeforeSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsBeforeSavePayload>>;\n export type Event = DomainEvent<MailerSettingsBeforeSavePayload>;\n}\n\nexport const MailerSettingsAfterSaveEventHandler = createAbstraction<\n IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>\n>(\"MailerSettingsAfterSaveEventHandler\");\n\nexport namespace MailerSettingsAfterSaveEventHandler {\n export type Interface = IEventHandler<DomainEvent<MailerSettingsAfterSavePayload>>;\n export type Event = DomainEvent<MailerSettingsAfterSavePayload>;\n}\n"],"names":["SaveSettingsRepository","createAbstraction","SaveSettingsUseCase","MailerSettingsBeforeSaveEventHandler","MailerSettingsAfterSaveEventHandler"],"mappings":";AA0CO,MAAMA,yBACTC,kBAA2C;AAYxC,MAAMC,sBAAsBD,kBAAiC;AAmB7D,MAAME,uCAAuCF,kBAElD;AAOK,MAAMG,sCAAsCH,kBAEjD"}
@@ -1,5 +1,6 @@
1
1
  import zod from "zod";
2
2
  export declare const saveValidation: zod.ZodObject<{
3
+ secure: zod.ZodOptional<zod.ZodBoolean>;
3
4
  password: zod.ZodPipe<zod.ZodOptional<zod.ZodOptional<zod.ZodNullable<zod.ZodString>>>, zod.ZodTransform<string | null, string | null | undefined>>;
4
5
  from: zod.ZodString;
5
6
  port: zod.ZodOptional<zod.ZodNullable<zod.ZodOptional<zod.ZodNumber>>>;
@@ -13,6 +13,7 @@ const common = {
13
13
  };
14
14
  const saveValidation = zod.object({
15
15
  ...common,
16
+ secure: zod.boolean().optional().describe("Use TLS/SSL"),
16
17
  password: validation_password.nullish().optional().transform((value)=>void 0 === value ? null : value)
17
18
  });
18
19
  export { saveValidation };
@@ -1 +1 @@
1
- {"version":3,"file":"features/SaveSettings/validation.js","sources":["../../../src/features/SaveSettings/validation.ts"],"sourcesContent":["import zod from \"zod\";\nimport { isMailboxAddress } from \"~/utils/isMailboxAddress.js\";\n\nconst password = zod.string().describe(\"Password\");\n\nconst mailboxAddress = zod.string().refine(isMailboxAddress, { message: \"Invalid email address.\" });\n\nconst common = {\n from: mailboxAddress.describe(\"Mail from\"),\n port: zod.number().optional().nullish().describe(\"Port\"),\n replyTo: zod\n .preprocess(\n // We need to set empty strings to `null` before address validation kicks in.\n value => (value === \"\" ? null : value),\n mailboxAddress.optional().nullish()\n )\n .describe(\"Mail reply-to\"),\n host: zod.string().describe(\"Hostname\"),\n user: zod.string().describe(\"User\")\n};\n\nexport const saveValidation = zod.object({\n ...common,\n password: password\n .nullish()\n .optional()\n .transform(value => {\n return value === undefined ? null : value;\n })\n});\n"],"names":["password","zod","mailboxAddress","isMailboxAddress","common","value","saveValidation","undefined"],"mappings":";;AAGA,MAAMA,sBAAWC,IAAI,MAAM,GAAG,QAAQ,CAAC;AAEvC,MAAMC,iBAAiBD,IAAI,MAAM,GAAG,MAAM,CAACE,kBAAkB;IAAE,SAAS;AAAyB;AAEjG,MAAMC,SAAS;IACX,MAAMF,eAAe,QAAQ,CAAC;IAC9B,MAAMD,IAAI,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACjD,SAASA,IAAAA,UACM,CAEPI,CAAAA,QAAUA,AAAU,OAAVA,QAAe,OAAOA,OAChCH,eAAe,QAAQ,GAAG,OAAO,IAEpC,QAAQ,CAAC;IACd,MAAMD,IAAI,MAAM,GAAG,QAAQ,CAAC;IAC5B,MAAMA,IAAI,MAAM,GAAG,QAAQ,CAAC;AAChC;AAEO,MAAMK,iBAAiBL,IAAI,MAAM,CAAC;IACrC,GAAGG,MAAM;IACT,UAAUJ,oBACL,OAAO,GACP,QAAQ,GACR,SAAS,CAACK,CAAAA,QACAA,AAAUE,WAAVF,QAAsB,OAAOA;AAEhD"}
1
+ {"version":3,"file":"features/SaveSettings/validation.js","sources":["../../../src/features/SaveSettings/validation.ts"],"sourcesContent":["import zod from \"zod\";\nimport { isMailboxAddress } from \"~/utils/isMailboxAddress.js\";\n\nconst password = zod.string().describe(\"Password\");\n\nconst mailboxAddress = zod.string().refine(isMailboxAddress, { message: \"Invalid email address.\" });\n\nconst common = {\n from: mailboxAddress.describe(\"Mail from\"),\n port: zod.number().optional().nullish().describe(\"Port\"),\n replyTo: zod\n .preprocess(\n // We need to set empty strings to `null` before address validation kicks in.\n value => (value === \"\" ? null : value),\n mailboxAddress.optional().nullish()\n )\n .describe(\"Mail reply-to\"),\n host: zod.string().describe(\"Hostname\"),\n user: zod.string().describe(\"User\")\n};\n\nexport const saveValidation = zod.object({\n ...common,\n secure: zod.boolean().optional().describe(\"Use TLS/SSL\"),\n password: password\n .nullish()\n .optional()\n .transform(value => {\n return value === undefined ? null : value;\n })\n});\n"],"names":["password","zod","mailboxAddress","isMailboxAddress","common","value","saveValidation","undefined"],"mappings":";;AAGA,MAAMA,sBAAWC,IAAI,MAAM,GAAG,QAAQ,CAAC;AAEvC,MAAMC,iBAAiBD,IAAI,MAAM,GAAG,MAAM,CAACE,kBAAkB;IAAE,SAAS;AAAyB;AAEjG,MAAMC,SAAS;IACX,MAAMF,eAAe,QAAQ,CAAC;IAC9B,MAAMD,IAAI,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACjD,SAASA,IAAAA,UACM,CAEPI,CAAAA,QAAUA,AAAU,OAAVA,QAAe,OAAOA,OAChCH,eAAe,QAAQ,GAAG,OAAO,IAEpC,QAAQ,CAAC;IACd,MAAMD,IAAI,MAAM,GAAG,QAAQ,CAAC;IAC5B,MAAMA,IAAI,MAAM,GAAG,QAAQ,CAAC;AAChC;AAEO,MAAMK,iBAAiBL,IAAI,MAAM,CAAC;IACrC,GAAGG,MAAM;IACT,QAAQH,IAAI,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAUD,oBACL,OAAO,GACP,QAAQ,GACR,SAAS,CAACK,CAAAA,QACAA,AAAUE,WAAVF,QAAsB,OAAOA;AAEhD"}
@@ -8,7 +8,7 @@ declare class SendMailUseCaseImpl implements SendMailUseCase.Interface {
8
8
  private mailerService;
9
9
  private eventPublisher;
10
10
  constructor(mailerService: MailerService.Interface, eventPublisher: EventPublisherAbstraction.Interface);
11
- execute(data: TransportSendData): Promise<Result<never, MailValidationError> | Result<import("~/types.js").TransportSendResponse<any>, import("../../domain/MailerService/errors.js").NoTransportAvailableError | import("../../domain/MailerService/errors.js").NoSettingsConfiguredError | import("../../domain/MailerService/errors.js").TransportSendError>>;
11
+ execute(data: TransportSendData): Promise<Result<never, MailValidationError> | Result<import("~/types.js").TransportSendResponse<any>, import("../../domain/MailerService/errors.js").NoTransportAvailableError | import("../../domain/MailerService/errors.js").TransportCreateError | import("../../domain/MailerService/errors.js").TransportSendError>>;
12
12
  }
13
13
  export declare const SendMailUseCaseImplementation: typeof SendMailUseCaseImpl & {
14
14
  __abstraction: import("@webiny/di").Abstraction<import("./abstractions.js").ISendMailUseCase>;
@@ -8,6 +8,7 @@ class SmtpConfig {
8
8
  const baseConfig = {
9
9
  host: settings.host,
10
10
  port: settings.port,
11
+ secure: settings.secure,
11
12
  auth: {
12
13
  user: settings.user,
13
14
  pass: settings.password
@@ -1 +1 @@
1
- {"version":3,"file":"features/SmtpTransport/SmtpConfig.js","sources":["../../../src/features/SmtpTransport/SmtpConfig.ts"],"sourcesContent":["import type { TransportSettings } from \"~/types.js\";\nimport type SMTPTransport from \"nodemailer/lib/smtp-transport\";\n\nexport type SmtpTransportConfig = SMTPTransport.Options;\n\nconst configDefaults: Partial<SmtpTransportConfig> = {\n socketTimeout: 15000,\n connectionTimeout: 15000,\n greetingTimeout: 15000\n};\n\nexport class SmtpConfig {\n static fromTransportSettings(settings: TransportSettings): SmtpTransportConfig {\n const baseConfig: SmtpTransportConfig = {\n host: settings.host,\n port: settings.port,\n auth: {\n user: settings.user,\n pass: settings.password\n }\n };\n\n // Apply defaults\n return Object.keys(configDefaults).reduce<SmtpTransportConfig>((config, key) => {\n const configKey = key as keyof SmtpTransportConfig;\n if (config[configKey] === undefined || config[configKey] === null) {\n // @ts-expect-error\n config[configKey] = configDefaults[configKey];\n }\n return config;\n }, baseConfig);\n }\n}\n"],"names":["configDefaults","SmtpConfig","settings","baseConfig","Object","config","key","configKey","undefined"],"mappings":"AAKA,MAAMA,iBAA+C;IACjD,eAAe;IACf,mBAAmB;IACnB,iBAAiB;AACrB;AAEO,MAAMC;IACT,OAAO,sBAAsBC,QAA2B,EAAuB;QAC3E,MAAMC,aAAkC;YACpC,MAAMD,SAAS,IAAI;YACnB,MAAMA,SAAS,IAAI;YACnB,MAAM;gBACF,MAAMA,SAAS,IAAI;gBACnB,MAAMA,SAAS,QAAQ;YAC3B;QACJ;QAGA,OAAOE,OAAO,IAAI,CAACJ,gBAAgB,MAAM,CAAsB,CAACK,QAAQC;YACpE,MAAMC,YAAYD;YAClB,IAAID,AAAsBG,WAAtBH,MAAM,CAACE,UAAU,IAAkBF,AAAsB,SAAtBA,MAAM,CAACE,UAAU,EAEpDF,MAAM,CAACE,UAAU,GAAGP,cAAc,CAACO,UAAU;YAEjD,OAAOF;QACX,GAAGF;IACP;AACJ"}
1
+ {"version":3,"file":"features/SmtpTransport/SmtpConfig.js","sources":["../../../src/features/SmtpTransport/SmtpConfig.ts"],"sourcesContent":["import type { TransportSettings } from \"~/types.js\";\nimport type SMTPTransport from \"nodemailer/lib/smtp-transport\";\n\nexport type SmtpTransportConfig = SMTPTransport.Options;\n\nconst configDefaults: Partial<SmtpTransportConfig> = {\n socketTimeout: 15000,\n connectionTimeout: 15000,\n greetingTimeout: 15000\n};\n\nexport class SmtpConfig {\n static fromTransportSettings(settings: TransportSettings): SmtpTransportConfig {\n const baseConfig: SmtpTransportConfig = {\n host: settings.host,\n port: settings.port,\n secure: settings.secure,\n auth: {\n user: settings.user,\n pass: settings.password\n }\n };\n\n // Apply defaults\n return Object.keys(configDefaults).reduce<SmtpTransportConfig>((config, key) => {\n const configKey = key as keyof SmtpTransportConfig;\n if (config[configKey] === undefined || config[configKey] === null) {\n // @ts-expect-error\n config[configKey] = configDefaults[configKey];\n }\n return config;\n }, baseConfig);\n }\n}\n"],"names":["configDefaults","SmtpConfig","settings","baseConfig","Object","config","key","configKey","undefined"],"mappings":"AAKA,MAAMA,iBAA+C;IACjD,eAAe;IACf,mBAAmB;IACnB,iBAAiB;AACrB;AAEO,MAAMC;IACT,OAAO,sBAAsBC,QAA2B,EAAuB;QAC3E,MAAMC,aAAkC;YACpC,MAAMD,SAAS,IAAI;YACnB,MAAMA,SAAS,IAAI;YACnB,QAAQA,SAAS,MAAM;YACvB,MAAM;gBACF,MAAMA,SAAS,IAAI;gBACnB,MAAMA,SAAS,QAAQ;YAC3B;QACJ;QAGA,OAAOE,OAAO,IAAI,CAACJ,gBAAgB,MAAM,CAAsB,CAACK,QAAQC;YACpE,MAAMC,YAAYD;YAClB,IAAID,AAAsBG,WAAtBH,MAAM,CAACE,UAAU,IAAkBF,AAAsB,SAAtBA,MAAM,CAACE,UAAU,EAEpDF,MAAM,CAACE,UAAU,GAAGP,cAAc,CAACO,UAAU;YAEjD,OAAOF;QACX,GAAGF;IACP;AACJ"}
@@ -2,6 +2,7 @@ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js
2
2
  import type { TransportSettings } from "../../types.js";
3
3
  declare class SmtpMailTransportFactoryImpl implements MailTransportFactory.Interface {
4
4
  readonly name = "Mailer/SmtpTransport";
5
+ canUse(settings: TransportSettings | null): boolean;
5
6
  createTransport(settings: TransportSettings): MailTransportFactory.Return;
6
7
  }
7
8
  export declare const SmtpMailTransportFactory: typeof SmtpMailTransportFactoryImpl & {
@@ -2,6 +2,9 @@ import { MailTransportFactory } from "../../domain/MailTransport/abstractions.js
2
2
  import { SmtpMailTransport } from "./SmtpMailTransport.js";
3
3
  import { SmtpConfig } from "./SmtpConfig.js";
4
4
  class SmtpMailTransportFactoryImpl {
5
+ canUse(settings) {
6
+ return null !== settings;
7
+ }
5
8
  async createTransport(settings) {
6
9
  return new SmtpMailTransport(SmtpConfig.fromTransportSettings(settings));
7
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"features/SmtpTransport/SmtpMailTransportFactory.js","sources":["../../../src/features/SmtpTransport/SmtpMailTransportFactory.ts"],"sourcesContent":["import { MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SmtpMailTransport } from \"~/features/SmtpTransport/SmtpMailTransport.js\";\nimport { SmtpConfig } from \"~/features/SmtpTransport/SmtpConfig.js\";\n\nclass SmtpMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/SmtpTransport\";\n\n async createTransport(settings: TransportSettings): MailTransportFactory.Return {\n return new SmtpMailTransport(SmtpConfig.fromTransportSettings(settings));\n }\n}\n\nexport const SmtpMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: SmtpMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["SmtpMailTransportFactoryImpl","settings","SmtpMailTransport","SmtpConfig","SmtpMailTransportFactory","MailTransportFactory"],"mappings":";;;AAKA,MAAMA;IAGF,MAAM,gBAAgBC,QAA2B,EAA+B;QAC5E,OAAO,IAAIC,kBAAkBC,WAAW,qBAAqB,CAACF;IAClE;;aAJgB,IAAI,GAAG;;AAK3B;AAEO,MAAMG,2BAA2BC,qBAAqB,oBAAoB,CAAC;IAC9E,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
1
+ {"version":3,"file":"features/SmtpTransport/SmtpMailTransportFactory.js","sources":["../../../src/features/SmtpTransport/SmtpMailTransportFactory.ts"],"sourcesContent":["import { MailTransportFactory } from \"~/domain/MailTransport/abstractions.js\";\nimport type { TransportSettings } from \"~/types.js\";\nimport { SmtpMailTransport } from \"~/features/SmtpTransport/SmtpMailTransport.js\";\nimport { SmtpConfig } from \"~/features/SmtpTransport/SmtpConfig.js\";\n\nclass SmtpMailTransportFactoryImpl implements MailTransportFactory.Interface {\n public readonly name = \"Mailer/SmtpTransport\";\n\n canUse(settings: TransportSettings | null): boolean {\n return settings !== null;\n }\n\n async createTransport(settings: TransportSettings): MailTransportFactory.Return {\n return new SmtpMailTransport(SmtpConfig.fromTransportSettings(settings));\n }\n}\n\nexport const SmtpMailTransportFactory = MailTransportFactory.createImplementation({\n implementation: SmtpMailTransportFactoryImpl,\n dependencies: []\n});\n"],"names":["SmtpMailTransportFactoryImpl","settings","SmtpMailTransport","SmtpConfig","SmtpMailTransportFactory","MailTransportFactory"],"mappings":";;;AAKA,MAAMA;IAGF,OAAOC,QAAkC,EAAW;QAChD,OAAOA,AAAa,SAAbA;IACX;IAEA,MAAM,gBAAgBA,QAA2B,EAA+B;QAC5E,OAAO,IAAIC,kBAAkBC,WAAW,qBAAqB,CAACF;IAClE;;aARgB,IAAI,GAAG;;AAS3B;AAEO,MAAMG,2BAA2BC,qBAAqB,oBAAoB,CAAC;IAC9E,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
@@ -1,7 +1,7 @@
1
1
  import { ErrorResponse, GraphQLSchemaPlugin } from "@webiny/handler-graphql";
2
2
  import { GetSettingsUseCase } from "../features/GetSettings/abstractions.js";
3
3
  import { SaveSettingsUseCase } from "../features/SaveSettings/abstractions.js";
4
- import { ActiveTransport } from "../domain/MailTransport/abstractions.js";
4
+ const SMTP_TRANSPORT_NAME = "Mailer/SmtpTransport";
5
5
  const emptyResolver = ()=>({});
6
6
  const toPublicSettings = (settings, source)=>{
7
7
  if (!settings) return null;
@@ -22,6 +22,7 @@ const createSettingsGraphQL = ()=>new GraphQLSchemaPlugin({
22
22
  type MailerTransportSettings {
23
23
  host: String
24
24
  port: Number
25
+ secure: Boolean
25
26
  user: String
26
27
  from: String
27
28
  replyTo: String
@@ -40,6 +41,7 @@ const createSettingsGraphQL = ()=>new GraphQLSchemaPlugin({
40
41
  input MailerTransportSettingsInput {
41
42
  host: String!
42
43
  port: Number
44
+ secure: Boolean
43
45
  user: String!
44
46
  password: String
45
47
  from: String!
@@ -64,14 +66,8 @@ const createSettingsGraphQL = ()=>new GraphQLSchemaPlugin({
64
66
  MailerQuery: {
65
67
  getSettings: async (_, __, context)=>{
66
68
  try {
67
- const activeTransport = context.container.resolve(ActiveTransport);
68
- const transportName = activeTransport.name();
69
- if (!transportName) return {
70
- data: null,
71
- error: null
72
- };
73
69
  const getSettings = context.container.resolve(GetSettingsUseCase);
74
- const result = await getSettings.execute(transportName);
70
+ const result = await getSettings.execute(SMTP_TRANSPORT_NAME);
75
71
  const { settings, source } = result.value;
76
72
  return {
77
73
  data: toPublicSettings(settings, source),
@@ -1 +1 @@
1
- {"version":3,"file":"graphql/settings.js","sources":["../../src/graphql/settings.ts"],"sourcesContent":["import { ErrorResponse, GraphQLSchemaPlugin } from \"@webiny/handler-graphql\";\nimport { GetSettingsUseCase } from \"~/features/GetSettings/abstractions.js\";\nimport { SaveSettingsUseCase } from \"~/features/SaveSettings/abstractions.js\";\nimport { ActiveTransport } from \"~/domain/MailTransport/abstractions.js\";\nimport type { MailerSettingsSource } from \"~/features/GetSettings/abstractions.js\";\nimport type { Context } from \"@webiny/api/types.js\";\nimport type { TransportSettings } from \"~/types.js\";\n\nconst emptyResolver = () => ({});\n\n// Strip `password` before the settings leave the server and tack on `source`\n// so the admin UI can branch on code-vs-storage. Accepts both the full\n// `TransportSettings` (from getSettings) and the already-stripped\n// `Omit<TransportSettings, \"password\">` (from saveSettings) — defense in depth\n// even when the input type carries no password to begin with.\nconst toPublicSettings = (\n settings: TransportSettings | Omit<TransportSettings, \"password\"> | null,\n source: MailerSettingsSource\n): (Omit<TransportSettings, \"password\"> & { source: MailerSettingsSource }) | null => {\n if (!settings) {\n return null;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _password, ...publicSettings } = settings as TransportSettings;\n return { ...publicSettings, source };\n};\n\nexport const createSettingsGraphQL = () => {\n return new GraphQLSchemaPlugin<Context>({\n typeDefs: `\n type MailerTransportSettingsError {\n message: String!\n code: String\n data: JSON\n }\n\n type MailerTransportSettings {\n host: String\n port: Number\n user: String\n from: String\n replyTo: String\n source: String\n }\n\n type MailerTransportSettingsResponse {\n data: MailerTransportSettings\n error: MailerTransportSettingsError\n }\n\n type MailerQuery {\n getSettings: MailerTransportSettingsResponse!\n }\n\n input MailerTransportSettingsInput {\n host: String!\n port: Number\n user: String!\n password: String\n from: String!\n replyTo: String\n }\n\n type MailerMutation {\n saveSettings(data: MailerTransportSettingsInput!): MailerTransportSettingsResponse!\n }\n\n extend type Query {\n mailer: MailerQuery\n }\n extend type Mutation {\n mailer: MailerMutation\n }\n `,\n resolvers: {\n Query: {\n mailer: emptyResolver\n },\n MailerQuery: {\n getSettings: async (_, __, context) => {\n try {\n const activeTransport = context.container.resolve(ActiveTransport);\n const transportName = activeTransport.name();\n\n if (!transportName) {\n return { data: null, error: null };\n }\n\n const getSettings = context.container.resolve(GetSettingsUseCase);\n const result = await getSettings.execute(transportName);\n\n const { settings, source } = result.value;\n\n return {\n data: toPublicSettings(settings, source),\n error: null\n };\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n },\n Mutation: {\n mailer: emptyResolver\n },\n MailerMutation: {\n saveSettings: async (_, args: any, context) => {\n try {\n const saveSettings = context.container.resolve(SaveSettingsUseCase);\n const result = await saveSettings.execute(args.data);\n\n if (result.isFail()) {\n return new ErrorResponse(result.error);\n }\n\n return {\n data: toPublicSettings(result.value, \"storage\"),\n error: null\n };\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n }\n }\n });\n};\n"],"names":["emptyResolver","toPublicSettings","settings","source","_password","publicSettings","createSettingsGraphQL","GraphQLSchemaPlugin","_","__","context","activeTransport","ActiveTransport","transportName","getSettings","GetSettingsUseCase","result","ex","ErrorResponse","args","saveSettings","SaveSettingsUseCase"],"mappings":";;;;AAQA,MAAMA,gBAAgB,IAAO,EAAC;AAO9B,MAAMC,mBAAmB,CACrBC,UACAC;IAEA,IAAI,CAACD,UACD,OAAO;IAGX,MAAM,EAAE,UAAUE,SAAS,EAAE,GAAGC,gBAAgB,GAAGH;IACnD,OAAO;QAAE,GAAGG,cAAc;QAAEF;IAAO;AACvC;AAEO,MAAMG,wBAAwB,IAC1B,IAAIC,oBAA6B;QACpC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4CX,CAAC;QACD,WAAW;YACP,OAAO;gBACH,QAAQP;YACZ;YACA,aAAa;gBACT,aAAa,OAAOQ,GAAGC,IAAIC;oBACvB,IAAI;wBACA,MAAMC,kBAAkBD,QAAQ,SAAS,CAAC,OAAO,CAACE;wBAClD,MAAMC,gBAAgBF,gBAAgB,IAAI;wBAE1C,IAAI,CAACE,eACD,OAAO;4BAAE,MAAM;4BAAM,OAAO;wBAAK;wBAGrC,MAAMC,cAAcJ,QAAQ,SAAS,CAAC,OAAO,CAACK;wBAC9C,MAAMC,SAAS,MAAMF,YAAY,OAAO,CAACD;wBAEzC,MAAM,EAAEX,QAAQ,EAAEC,MAAM,EAAE,GAAGa,OAAO,KAAK;wBAEzC,OAAO;4BACH,MAAMf,iBAAiBC,UAAUC;4BACjC,OAAO;wBACX;oBACJ,EAAE,OAAOc,IAAI;wBACT,OAAO,IAAIC,cAAcD;oBAC7B;gBACJ;YACJ;YACA,UAAU;gBACN,QAAQjB;YACZ;YACA,gBAAgB;gBACZ,cAAc,OAAOQ,GAAGW,MAAWT;oBAC/B,IAAI;wBACA,MAAMU,eAAeV,QAAQ,SAAS,CAAC,OAAO,CAACW;wBAC/C,MAAML,SAAS,MAAMI,aAAa,OAAO,CAACD,KAAK,IAAI;wBAEnD,IAAIH,OAAO,MAAM,IACb,OAAO,IAAIE,cAAcF,OAAO,KAAK;wBAGzC,OAAO;4BACH,MAAMf,iBAAiBe,OAAO,KAAK,EAAE;4BACrC,OAAO;wBACX;oBACJ,EAAE,OAAOC,IAAI;wBACT,OAAO,IAAIC,cAAcD;oBAC7B;gBACJ;YACJ;QACJ;IACJ"}
1
+ {"version":3,"file":"graphql/settings.js","sources":["../../src/graphql/settings.ts"],"sourcesContent":["import { ErrorResponse, GraphQLSchemaPlugin } from \"@webiny/handler-graphql\";\nimport { GetSettingsUseCase } from \"~/features/GetSettings/abstractions.js\";\nimport { SaveSettingsUseCase } from \"~/features/SaveSettings/abstractions.js\";\nimport type { MailerSettingsSource } from \"~/features/GetSettings/abstractions.js\";\nimport type { Context } from \"@webiny/api/types.js\";\nimport type { TransportSettings } from \"~/types.js\";\n\nconst SMTP_TRANSPORT_NAME = \"Mailer/SmtpTransport\";\n\nconst emptyResolver = () => ({});\n\n// Strip `password` before the settings leave the server and tack on `source`\n// so the admin UI can branch on code-vs-storage. Accepts both the full\n// `TransportSettings` (from getSettings) and the already-stripped\n// `Omit<TransportSettings, \"password\">` (from saveSettings) — defense in depth\n// even when the input type carries no password to begin with.\nconst toPublicSettings = (\n settings: TransportSettings | Omit<TransportSettings, \"password\"> | null,\n source: MailerSettingsSource\n): (Omit<TransportSettings, \"password\"> & { source: MailerSettingsSource }) | null => {\n if (!settings) {\n return null;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { password: _password, ...publicSettings } = settings as TransportSettings;\n return { ...publicSettings, source };\n};\n\nexport const createSettingsGraphQL = () => {\n return new GraphQLSchemaPlugin<Context>({\n typeDefs: `\n type MailerTransportSettingsError {\n message: String!\n code: String\n data: JSON\n }\n\n type MailerTransportSettings {\n host: String\n port: Number\n secure: Boolean\n user: String\n from: String\n replyTo: String\n source: String\n }\n\n type MailerTransportSettingsResponse {\n data: MailerTransportSettings\n error: MailerTransportSettingsError\n }\n\n type MailerQuery {\n getSettings: MailerTransportSettingsResponse!\n }\n\n input MailerTransportSettingsInput {\n host: String!\n port: Number\n secure: Boolean\n user: String!\n password: String\n from: String!\n replyTo: String\n }\n\n type MailerMutation {\n saveSettings(data: MailerTransportSettingsInput!): MailerTransportSettingsResponse!\n }\n\n extend type Query {\n mailer: MailerQuery\n }\n extend type Mutation {\n mailer: MailerMutation\n }\n `,\n resolvers: {\n Query: {\n mailer: emptyResolver\n },\n MailerQuery: {\n getSettings: async (_, __, context) => {\n try {\n const getSettings = context.container.resolve(GetSettingsUseCase);\n const result = await getSettings.execute(SMTP_TRANSPORT_NAME);\n\n const { settings, source } = result.value;\n\n return {\n data: toPublicSettings(settings, source),\n error: null\n };\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n },\n Mutation: {\n mailer: emptyResolver\n },\n MailerMutation: {\n saveSettings: async (_, args: any, context) => {\n try {\n const saveSettings = context.container.resolve(SaveSettingsUseCase);\n const result = await saveSettings.execute(args.data);\n\n if (result.isFail()) {\n return new ErrorResponse(result.error);\n }\n\n return {\n data: toPublicSettings(result.value, \"storage\"),\n error: null\n };\n } catch (ex) {\n return new ErrorResponse(ex);\n }\n }\n }\n }\n });\n};\n"],"names":["SMTP_TRANSPORT_NAME","emptyResolver","toPublicSettings","settings","source","_password","publicSettings","createSettingsGraphQL","GraphQLSchemaPlugin","_","__","context","getSettings","GetSettingsUseCase","result","ex","ErrorResponse","args","saveSettings","SaveSettingsUseCase"],"mappings":";;;AAOA,MAAMA,sBAAsB;AAE5B,MAAMC,gBAAgB,IAAO,EAAC;AAO9B,MAAMC,mBAAmB,CACrBC,UACAC;IAEA,IAAI,CAACD,UACD,OAAO;IAGX,MAAM,EAAE,UAAUE,SAAS,EAAE,GAAGC,gBAAgB,GAAGH;IACnD,OAAO;QAAE,GAAGG,cAAc;QAAEF;IAAO;AACvC;AAEO,MAAMG,wBAAwB,IAC1B,IAAIC,oBAA6B;QACpC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8CX,CAAC;QACD,WAAW;YACP,OAAO;gBACH,QAAQP;YACZ;YACA,aAAa;gBACT,aAAa,OAAOQ,GAAGC,IAAIC;oBACvB,IAAI;wBACA,MAAMC,cAAcD,QAAQ,SAAS,CAAC,OAAO,CAACE;wBAC9C,MAAMC,SAAS,MAAMF,YAAY,OAAO,CAACZ;wBAEzC,MAAM,EAAEG,QAAQ,EAAEC,MAAM,EAAE,GAAGU,OAAO,KAAK;wBAEzC,OAAO;4BACH,MAAMZ,iBAAiBC,UAAUC;4BACjC,OAAO;wBACX;oBACJ,EAAE,OAAOW,IAAI;wBACT,OAAO,IAAIC,cAAcD;oBAC7B;gBACJ;YACJ;YACA,UAAU;gBACN,QAAQd;YACZ;YACA,gBAAgB;gBACZ,cAAc,OAAOQ,GAAGQ,MAAWN;oBAC/B,IAAI;wBACA,MAAMO,eAAeP,QAAQ,SAAS,CAAC,OAAO,CAACQ;wBAC/C,MAAML,SAAS,MAAMI,aAAa,OAAO,CAACD,KAAK,IAAI;wBAEnD,IAAIH,OAAO,MAAM,IACb,OAAO,IAAIE,cAAcF,OAAO,KAAK;wBAGzC,OAAO;4BACH,MAAMZ,iBAAiBY,OAAO,KAAK,EAAE;4BACrC,OAAO;wBACX;oBACJ,EAAE,OAAOC,IAAI;wBACT,OAAO,IAAIC,cAAcD;oBAC7B;gBACJ;YACJ;QACJ;IACJ"}
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { MailerService } from "./domain/MailerService/abstractions.js";
2
2
  export type { IMailerService, IMailerServiceErrors } from "./domain/MailerService/abstractions.js";
3
- export declare const createMailerContext: () => import("@webiny/api").ContextPlugin<import("@webiny/api/types.js").Context>;
3
+ export declare const createMailerContext: () => import("@webiny/handler").RegisterExtensionPlugin<import("@webiny/handler/types.js").Context>;
4
4
  export declare const createMailerGraphQL: () => import("@webiny/handler-graphql/index.js").GraphQLSchemaPlugin<import("@webiny/api/types.js").Context>;
package/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import { createContextPlugin } from "@webiny/api";
2
1
  import { CodeMailerSettingsFeature } from "./features/CodeMailerSettings/feature.js";
3
2
  import { GetSettingsFeature } from "./features/GetSettings/feature.js";
4
3
  import { SaveSettingsFeature } from "./features/SaveSettings/feature.js";
@@ -7,7 +6,8 @@ import { SmtpTransportFeature } from "./features/SmtpTransport/feature.js";
7
6
  import { MailerServiceFeature } from "./features/MailerService/feature.js";
8
7
  import { SendMailFeature } from "./features/SendMail/feature.js";
9
8
  import { createSettingsGraphQL } from "./graphql/settings.js";
10
- const createMailerContext = ()=>createContextPlugin((context)=>{
9
+ import { createRegisterExtensionPlugin } from "@webiny/handler";
10
+ const createMailerContext = ()=>createRegisterExtensionPlugin((context)=>{
11
11
  CodeMailerSettingsFeature.register(context.container);
12
12
  DummyTransportFeature.register(context.container);
13
13
  SmtpTransportFeature.register(context.container);
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { createContextPlugin } from \"@webiny/api\";\nimport { CodeMailerSettingsFeature } from \"~/features/CodeMailerSettings/feature.js\";\nimport { GetSettingsFeature } from \"~/features/GetSettings/feature.js\";\nimport { SaveSettingsFeature } from \"~/features/SaveSettings/feature.js\";\nimport { DummyTransportFeature } from \"~/features/DummyTransport/feature.js\";\nimport { SmtpTransportFeature } from \"~/features/SmtpTransport/feature.js\";\nimport { MailerServiceFeature } from \"~/features/MailerService/feature.js\";\nimport { SendMailFeature } from \"~/features/SendMail/feature.js\";\nimport { createSettingsGraphQL } from \"~/graphql/settings.js\";\n\nexport { MailerService } from \"./domain/MailerService/abstractions.js\";\nexport type { IMailerService, IMailerServiceErrors } from \"./domain/MailerService/abstractions.js\";\n\nexport const createMailerContext = () => {\n return createContextPlugin(context => {\n // Register all features.\n CodeMailerSettingsFeature.register(context.container);\n DummyTransportFeature.register(context.container);\n SmtpTransportFeature.register(context.container);\n GetSettingsFeature.register(context.container);\n SaveSettingsFeature.register(context.container);\n MailerServiceFeature.register(context.container);\n SendMailFeature.register(context.container);\n });\n};\n\nexport const createMailerGraphQL = () => {\n return createSettingsGraphQL();\n};\n"],"names":["createMailerContext","createContextPlugin","context","CodeMailerSettingsFeature","DummyTransportFeature","SmtpTransportFeature","GetSettingsFeature","SaveSettingsFeature","MailerServiceFeature","SendMailFeature","createMailerGraphQL","createSettingsGraphQL"],"mappings":";;;;;;;;;AAaO,MAAMA,sBAAsB,IACxBC,oBAAoBC,CAAAA;QAEvBC,0BAA0B,QAAQ,CAACD,QAAQ,SAAS;QACpDE,sBAAsB,QAAQ,CAACF,QAAQ,SAAS;QAChDG,qBAAqB,QAAQ,CAACH,QAAQ,SAAS;QAC/CI,mBAAmB,QAAQ,CAACJ,QAAQ,SAAS;QAC7CK,oBAAoB,QAAQ,CAACL,QAAQ,SAAS;QAC9CM,qBAAqB,QAAQ,CAACN,QAAQ,SAAS;QAC/CO,gBAAgB,QAAQ,CAACP,QAAQ,SAAS;IAC9C;AAGG,MAAMQ,sBAAsB,IACxBC"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { CodeMailerSettingsFeature } from \"~/features/CodeMailerSettings/feature.js\";\nimport { GetSettingsFeature } from \"~/features/GetSettings/feature.js\";\nimport { SaveSettingsFeature } from \"~/features/SaveSettings/feature.js\";\nimport { DummyTransportFeature } from \"~/features/DummyTransport/feature.js\";\nimport { SmtpTransportFeature } from \"~/features/SmtpTransport/feature.js\";\nimport { MailerServiceFeature } from \"~/features/MailerService/feature.js\";\nimport { SendMailFeature } from \"~/features/SendMail/feature.js\";\nimport { createSettingsGraphQL } from \"~/graphql/settings.js\";\nimport { createRegisterExtensionPlugin } from \"@webiny/handler\";\n\nexport { MailerService } from \"./domain/MailerService/abstractions.js\";\nexport type { IMailerService, IMailerServiceErrors } from \"./domain/MailerService/abstractions.js\";\n\nexport const createMailerContext = () => {\n return createRegisterExtensionPlugin(context => {\n // Register all features.\n CodeMailerSettingsFeature.register(context.container);\n DummyTransportFeature.register(context.container);\n SmtpTransportFeature.register(context.container);\n GetSettingsFeature.register(context.container);\n SaveSettingsFeature.register(context.container);\n MailerServiceFeature.register(context.container);\n SendMailFeature.register(context.container);\n });\n};\n\nexport const createMailerGraphQL = () => {\n return createSettingsGraphQL();\n};\n"],"names":["createMailerContext","createRegisterExtensionPlugin","context","CodeMailerSettingsFeature","DummyTransportFeature","SmtpTransportFeature","GetSettingsFeature","SaveSettingsFeature","MailerServiceFeature","SendMailFeature","createMailerGraphQL","createSettingsGraphQL"],"mappings":";;;;;;;;;AAaO,MAAMA,sBAAsB,IACxBC,8BAA8BC,CAAAA;QAEjCC,0BAA0B,QAAQ,CAACD,QAAQ,SAAS;QACpDE,sBAAsB,QAAQ,CAACF,QAAQ,SAAS;QAChDG,qBAAqB,QAAQ,CAACH,QAAQ,SAAS;QAC/CI,mBAAmB,QAAQ,CAACJ,QAAQ,SAAS;QAC7CK,oBAAoB,QAAQ,CAACL,QAAQ,SAAS;QAC9CM,qBAAqB,QAAQ,CAACN,QAAQ,SAAS;QAC/CO,gBAAgB,QAAQ,CAACP,QAAQ,SAAS;IAC9C;AAGG,MAAMQ,sBAAsB,IACxBC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-mailer",
3
- "version": "6.4.0-beta.3",
3
+ "version": "6.4.0-beta.5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -18,33 +18,35 @@
18
18
  "description": "The API to send e-mails.",
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
- "@webiny/api": "6.4.0-beta.3",
22
- "@webiny/api-headless-cms": "6.4.0-beta.3",
23
- "@webiny/feature": "6.4.0-beta.3",
24
- "@webiny/handler-graphql": "6.4.0-beta.3",
25
- "@webiny/plugins": "6.4.0-beta.3",
21
+ "@webiny/api": "6.4.0-beta.5",
22
+ "@webiny/api-headless-cms": "6.4.0-beta.5",
23
+ "@webiny/feature": "6.4.0-beta.5",
24
+ "@webiny/handler-graphql": "6.4.0-beta.5",
25
+ "@webiny/plugins": "6.4.0-beta.5",
26
26
  "email-addresses": "5.0.0",
27
- "nodemailer": "8.0.7",
27
+ "nodemailer": "8.0.8",
28
28
  "zod": "4.4.3"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/nodemailer": "8.0.0",
32
- "@webiny/api-core": "6.4.0-beta.3",
33
- "@webiny/build-tools": "6.4.0-beta.3",
34
- "@webiny/db-dynamodb": "6.4.0-beta.3",
35
- "@webiny/handler": "6.4.0-beta.3",
36
- "@webiny/handler-aws": "6.4.0-beta.3",
37
- "@webiny/handler-db": "6.4.0-beta.3",
38
- "@webiny/project-utils": "6.4.0-beta.3",
32
+ "@webiny/api-core": "6.4.0-beta.5",
33
+ "@webiny/build-tools": "6.4.0-beta.5",
34
+ "@webiny/db-dynamodb": "6.4.0-beta.5",
35
+ "@webiny/handler": "6.4.0-beta.5",
36
+ "@webiny/handler-aws": "6.4.0-beta.5",
37
+ "@webiny/handler-db": "6.4.0-beta.5",
38
+ "@webiny/project-utils": "6.4.0-beta.5",
39
39
  "graphql": "16.14.0",
40
40
  "jest-dynalite": "3.6.1",
41
41
  "rimraf": "6.1.3",
42
42
  "typescript": "6.0.3",
43
- "vitest": "4.1.6"
43
+ "vitest": "4.1.7"
44
44
  },
45
45
  "publishConfig": {
46
- "access": "public",
47
- "directory": "dist"
46
+ "access": "public"
48
47
  },
49
- "gitHead": "2e58681d4344024bfb60e6180338e2f154ec87f0"
48
+ "gitHead": "8476da73b653c89cc1474d968baf55c1b0ae0e5f",
49
+ "webiny": {
50
+ "publishFrom": "dist"
51
+ }
50
52
  }
package/types.d.ts CHANGED
@@ -34,6 +34,7 @@ export type TransportSendData = BaseTransportSendData & (TransportSendToData | T
34
34
  export interface TransportSettings {
35
35
  host: string;
36
36
  port: number;
37
+ secure: boolean;
37
38
  user: string;
38
39
  password: string;
39
40
  from: string;
@@ -1,10 +0,0 @@
1
- import { ActiveTransport as ActiveTransportAbstraction, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
2
- declare class ActiveTransportImpl implements ActiveTransportAbstraction.Interface {
3
- private transportFactories;
4
- constructor(transportFactories: MailTransportFactory.Interface[]);
5
- name(): string | null;
6
- }
7
- export declare const ActiveTransport: typeof ActiveTransportImpl & {
8
- __abstraction: import("@webiny/di").Abstraction<import("~/domain/MailTransport/abstractions.js").IActiveTransport>;
9
- };
10
- export {};
@@ -1,24 +0,0 @@
1
- import { ActiveTransport, MailTransportFactory } from "../../domain/MailTransport/abstractions.js";
2
- class ActiveTransportImpl {
3
- constructor(transportFactories){
4
- this.transportFactories = transportFactories;
5
- }
6
- name() {
7
- if (0 === this.transportFactories.length) return null;
8
- return this.transportFactories[this.transportFactories.length - 1].name;
9
- }
10
- }
11
- const ActiveTransport_ActiveTransport = ActiveTransport.createImplementation({
12
- implementation: ActiveTransportImpl,
13
- dependencies: [
14
- [
15
- MailTransportFactory,
16
- {
17
- multiple: true
18
- }
19
- ]
20
- ]
21
- });
22
- export { ActiveTransport_ActiveTransport as ActiveTransport };
23
-
24
- //# sourceMappingURL=ActiveTransport.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"features/MailerService/ActiveTransport.js","sources":["../../../src/features/MailerService/ActiveTransport.ts"],"sourcesContent":["import {\n ActiveTransport as ActiveTransportAbstraction,\n MailTransportFactory\n} from \"~/domain/MailTransport/abstractions.js\";\n\nclass ActiveTransportImpl implements ActiveTransportAbstraction.Interface {\n constructor(private transportFactories: MailTransportFactory.Interface[]) {}\n\n name(): string | null {\n if (this.transportFactories.length === 0) {\n return null;\n }\n return this.transportFactories[this.transportFactories.length - 1].name;\n }\n}\n\nexport const ActiveTransport = ActiveTransportAbstraction.createImplementation({\n implementation: ActiveTransportImpl,\n dependencies: [[MailTransportFactory, { multiple: true }]]\n});\n"],"names":["ActiveTransportImpl","transportFactories","ActiveTransport","ActiveTransportAbstraction","MailTransportFactory"],"mappings":";AAKA,MAAMA;IACF,YAAoBC,kBAAoD,CAAE;aAAtDA,kBAAkB,GAAlBA;IAAuD;IAE3E,OAAsB;QAClB,IAAI,AAAmC,MAAnC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAC9B,OAAO;QAEX,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI;IAC3E;AACJ;AAEO,MAAMC,kCAAkBC,gBAAAA,oBAA+C,CAAC;IAC3E,gBAAgBH;IAChB,cAAc;QAAC;YAACI;YAAsB;gBAAE,UAAU;YAAK;SAAE;KAAC;AAC9D"}