@webiny/api-mailer 0.0.0-unstable.990c3ab1b6 → 0.0.0-unstable.aa00eecd97

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.
@@ -72,7 +72,8 @@ const createSettingsModel = group => {
72
72
  layout: [["host", "port", "user", "password", "from", "replyTo"]],
73
73
  description: "Mailer Settings",
74
74
  titleFieldId: "",
75
- isPrivate: true
75
+ isPrivate: true,
76
+ noValidate: true
76
77
  });
77
78
  };
78
79
  exports.createSettingsModel = createSettingsModel;
@@ -1 +1 @@
1
- {"version":3,"names":["SETTINGS_MODEL_ID","createField","params","label","required","type","id","lodashCamelCase","validation","push","message","name","settings","fieldId","storageId","createTextField","createNumberField","createSettingsModel","group","createCmsModel","modelId","contentModelGroup","fields","layout","description","titleFieldId","isPrivate"],"sources":["model.ts"],"sourcesContent":["import { createCmsModel, CmsGroupPlugin } from \"@webiny/api-headless-cms\";\nimport { CmsModelField, CmsModelFieldValidation } from \"@webiny/api-headless-cms/types\";\nimport lodashCamelCase from \"lodash/camelCase\";\n\nexport const SETTINGS_MODEL_ID = \"mailerSettings\";\n\ninterface CreateFieldParams {\n type: string;\n label: string;\n required?: boolean;\n}\nconst createField = (params: CreateFieldParams): CmsModelField => {\n const { label, required, type } = params;\n const id = lodashCamelCase(label);\n\n const validation: CmsModelFieldValidation[] = [];\n if (required) {\n validation.push({\n message: `Field \"${label}\" is required!`,\n name: \"required\",\n settings: {}\n });\n }\n return {\n label,\n id,\n fieldId: id,\n storageId: id,\n type,\n validation\n };\n};\n\nconst createTextField = (params: Omit<CreateFieldParams, \"type\">) => {\n return createField({\n ...params,\n type: \"text\"\n });\n};\nconst createNumberField = (params: Omit<CreateFieldParams, \"type\">) => {\n return createField({\n ...params,\n type: \"number\"\n });\n};\n\nexport const createSettingsModel = (group: CmsGroupPlugin) => {\n return createCmsModel({\n modelId: SETTINGS_MODEL_ID,\n name: \"Mailer Settings\",\n group: {\n id: group.contentModelGroup.id,\n name: group.contentModelGroup.name\n },\n fields: [\n createTextField({\n label: \"Host\",\n required: true\n }),\n createNumberField({\n label: \"Port\"\n }),\n createTextField({\n label: \"User\",\n required: true\n }),\n createTextField({\n label: \"Password\",\n required: true\n }),\n createTextField({\n label: \"From\",\n required: true\n }),\n createTextField({\n label: \"Reply-To\"\n })\n ],\n layout: [[\"host\", \"port\", \"user\", \"password\", \"from\", \"replyTo\"]],\n description: \"Mailer Settings\",\n titleFieldId: \"\",\n isPrivate: true\n });\n};\n"],"mappings":";;;;;;;;AAAA;AAEA;AAEO,MAAMA,iBAAiB,GAAG,gBAAgB;AAAC;AAOlD,MAAMC,WAAW,GAAIC,MAAyB,IAAoB;EAC9D,MAAM;IAAEC,KAAK;IAAEC,QAAQ;IAAEC;EAAK,CAAC,GAAGH,MAAM;EACxC,MAAMI,EAAE,GAAG,IAAAC,kBAAe,EAACJ,KAAK,CAAC;EAEjC,MAAMK,UAAqC,GAAG,EAAE;EAChD,IAAIJ,QAAQ,EAAE;IACVI,UAAU,CAACC,IAAI,CAAC;MACZC,OAAO,EAAG,UAASP,KAAM,gBAAe;MACxCQ,IAAI,EAAE,UAAU;MAChBC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC;EACN;EACA,OAAO;IACHT,KAAK;IACLG,EAAE;IACFO,OAAO,EAAEP,EAAE;IACXQ,SAAS,EAAER,EAAE;IACbD,IAAI;IACJG;EACJ,CAAC;AACL,CAAC;AAED,MAAMO,eAAe,GAAIb,MAAuC,IAAK;EACjE,OAAOD,WAAW,6DACXC,MAAM;IACTG,IAAI,EAAE;EAAM,GACd;AACN,CAAC;AACD,MAAMW,iBAAiB,GAAId,MAAuC,IAAK;EACnE,OAAOD,WAAW,6DACXC,MAAM;IACTG,IAAI,EAAE;EAAQ,GAChB;AACN,CAAC;AAEM,MAAMY,mBAAmB,GAAIC,KAAqB,IAAK;EAC1D,OAAO,IAAAC,8BAAc,EAAC;IAClBC,OAAO,EAAEpB,iBAAiB;IAC1BW,IAAI,EAAE,iBAAiB;IACvBO,KAAK,EAAE;MACHZ,EAAE,EAAEY,KAAK,CAACG,iBAAiB,CAACf,EAAE;MAC9BK,IAAI,EAAEO,KAAK,CAACG,iBAAiB,CAACV;IAClC,CAAC;IACDW,MAAM,EAAE,CACJP,eAAe,CAAC;MACZZ,KAAK,EAAE,MAAM;MACbC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFY,iBAAiB,CAAC;MACdb,KAAK,EAAE;IACX,CAAC,CAAC,EACFY,eAAe,CAAC;MACZZ,KAAK,EAAE,MAAM;MACbC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFW,eAAe,CAAC;MACZZ,KAAK,EAAE,UAAU;MACjBC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFW,eAAe,CAAC;MACZZ,KAAK,EAAE,MAAM;MACbC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFW,eAAe,CAAC;MACZZ,KAAK,EAAE;IACX,CAAC,CAAC,CACL;IACDoB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACjEC,WAAW,EAAE,iBAAiB;IAC9BC,YAAY,EAAE,EAAE;IAChBC,SAAS,EAAE;EACf,CAAC,CAAC;AACN,CAAC;AAAC"}
1
+ {"version":3,"names":["SETTINGS_MODEL_ID","createField","params","label","required","type","id","lodashCamelCase","validation","push","message","name","settings","fieldId","storageId","createTextField","createNumberField","createSettingsModel","group","createCmsModel","modelId","contentModelGroup","fields","layout","description","titleFieldId","isPrivate","noValidate"],"sources":["model.ts"],"sourcesContent":["import { createCmsModel, CmsGroupPlugin } from \"@webiny/api-headless-cms\";\nimport { CmsModelField, CmsModelFieldValidation } from \"@webiny/api-headless-cms/types\";\nimport lodashCamelCase from \"lodash/camelCase\";\n\nexport const SETTINGS_MODEL_ID = \"mailerSettings\";\n\ninterface CreateFieldParams {\n type: string;\n label: string;\n required?: boolean;\n}\nconst createField = (params: CreateFieldParams): CmsModelField => {\n const { label, required, type } = params;\n const id = lodashCamelCase(label);\n\n const validation: CmsModelFieldValidation[] = [];\n if (required) {\n validation.push({\n message: `Field \"${label}\" is required!`,\n name: \"required\",\n settings: {}\n });\n }\n return {\n label,\n id,\n fieldId: id,\n storageId: id,\n type,\n validation\n };\n};\n\nconst createTextField = (params: Omit<CreateFieldParams, \"type\">) => {\n return createField({\n ...params,\n type: \"text\"\n });\n};\nconst createNumberField = (params: Omit<CreateFieldParams, \"type\">) => {\n return createField({\n ...params,\n type: \"number\"\n });\n};\n\nexport const createSettingsModel = (group: CmsGroupPlugin) => {\n return createCmsModel({\n modelId: SETTINGS_MODEL_ID,\n name: \"Mailer Settings\",\n group: {\n id: group.contentModelGroup.id,\n name: group.contentModelGroup.name\n },\n fields: [\n createTextField({\n label: \"Host\",\n required: true\n }),\n createNumberField({\n label: \"Port\"\n }),\n createTextField({\n label: \"User\",\n required: true\n }),\n createTextField({\n label: \"Password\",\n required: true\n }),\n createTextField({\n label: \"From\",\n required: true\n }),\n createTextField({\n label: \"Reply-To\"\n })\n ],\n layout: [[\"host\", \"port\", \"user\", \"password\", \"from\", \"replyTo\"]],\n description: \"Mailer Settings\",\n titleFieldId: \"\",\n isPrivate: true,\n noValidate: true\n });\n};\n"],"mappings":";;;;;;;;AAAA;AAEA;AAEO,MAAMA,iBAAiB,GAAG,gBAAgB;AAAC;AAOlD,MAAMC,WAAW,GAAIC,MAAyB,IAAoB;EAC9D,MAAM;IAAEC,KAAK;IAAEC,QAAQ;IAAEC;EAAK,CAAC,GAAGH,MAAM;EACxC,MAAMI,EAAE,GAAG,IAAAC,kBAAe,EAACJ,KAAK,CAAC;EAEjC,MAAMK,UAAqC,GAAG,EAAE;EAChD,IAAIJ,QAAQ,EAAE;IACVI,UAAU,CAACC,IAAI,CAAC;MACZC,OAAO,EAAG,UAASP,KAAM,gBAAe;MACxCQ,IAAI,EAAE,UAAU;MAChBC,QAAQ,EAAE,CAAC;IACf,CAAC,CAAC;EACN;EACA,OAAO;IACHT,KAAK;IACLG,EAAE;IACFO,OAAO,EAAEP,EAAE;IACXQ,SAAS,EAAER,EAAE;IACbD,IAAI;IACJG;EACJ,CAAC;AACL,CAAC;AAED,MAAMO,eAAe,GAAIb,MAAuC,IAAK;EACjE,OAAOD,WAAW,6DACXC,MAAM;IACTG,IAAI,EAAE;EAAM,GACd;AACN,CAAC;AACD,MAAMW,iBAAiB,GAAId,MAAuC,IAAK;EACnE,OAAOD,WAAW,6DACXC,MAAM;IACTG,IAAI,EAAE;EAAQ,GAChB;AACN,CAAC;AAEM,MAAMY,mBAAmB,GAAIC,KAAqB,IAAK;EAC1D,OAAO,IAAAC,8BAAc,EAAC;IAClBC,OAAO,EAAEpB,iBAAiB;IAC1BW,IAAI,EAAE,iBAAiB;IACvBO,KAAK,EAAE;MACHZ,EAAE,EAAEY,KAAK,CAACG,iBAAiB,CAACf,EAAE;MAC9BK,IAAI,EAAEO,KAAK,CAACG,iBAAiB,CAACV;IAClC,CAAC;IACDW,MAAM,EAAE,CACJP,eAAe,CAAC;MACZZ,KAAK,EAAE,MAAM;MACbC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFY,iBAAiB,CAAC;MACdb,KAAK,EAAE;IACX,CAAC,CAAC,EACFY,eAAe,CAAC;MACZZ,KAAK,EAAE,MAAM;MACbC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFW,eAAe,CAAC;MACZZ,KAAK,EAAE,UAAU;MACjBC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFW,eAAe,CAAC;MACZZ,KAAK,EAAE,MAAM;MACbC,QAAQ,EAAE;IACd,CAAC,CAAC,EACFW,eAAe,CAAC;MACZZ,KAAK,EAAE;IACX,CAAC,CAAC,CACL;IACDoB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACjEC,WAAW,EAAE,iBAAiB;IAC9BC,YAAY,EAAE,EAAE;IAChBC,SAAS,EAAE,IAAI;IACfC,UAAU,EAAE;EAChB,CAAC,CAAC;AACN,CAAC;AAAC"}
@@ -1,4 +1,45 @@
1
- import joi from "joi";
2
- import { TransportSettings } from "../../types";
3
- export declare const createValidation: joi.ObjectSchema<TransportSettings>;
4
- export declare const updateValidation: joi.ObjectSchema<TransportSettings>;
1
+ import zod from "zod";
2
+ export declare const createValidation: zod.ZodObject<{
3
+ password: zod.ZodString;
4
+ from: zod.ZodString;
5
+ port: zod.ZodNullable<zod.ZodNumber>;
6
+ replyTo: zod.ZodString;
7
+ host: zod.ZodString;
8
+ user: zod.ZodString;
9
+ }, "strip", zod.ZodTypeAny, {
10
+ from: string;
11
+ host: string;
12
+ port: number | null;
13
+ replyTo: string;
14
+ password: string;
15
+ user: string;
16
+ }, {
17
+ from: string;
18
+ host: string;
19
+ port: number | null;
20
+ replyTo: string;
21
+ password: string;
22
+ user: string;
23
+ }>;
24
+ export declare const updateValidation: zod.ZodObject<{
25
+ password: zod.ZodNullable<zod.ZodString>;
26
+ from: zod.ZodString;
27
+ port: zod.ZodNullable<zod.ZodNumber>;
28
+ replyTo: zod.ZodString;
29
+ host: zod.ZodString;
30
+ user: zod.ZodString;
31
+ }, "strip", zod.ZodTypeAny, {
32
+ from: string;
33
+ host: string;
34
+ port: number | null;
35
+ replyTo: string;
36
+ password: string | null;
37
+ user: string;
38
+ }, {
39
+ from: string;
40
+ host: string;
41
+ port: number | null;
42
+ replyTo: string;
43
+ password: string | null;
44
+ user: string;
45
+ }>;
@@ -6,23 +6,20 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.updateValidation = exports.createValidation = void 0;
8
8
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
9
- var _joi = _interopRequireDefault(require("joi"));
10
- const options = {
11
- tlds: false
12
- };
13
- const password = _joi.default.string().label("Password");
9
+ var _zod = _interopRequireDefault(require("zod"));
10
+ const password = _zod.default.string().describe("Password");
14
11
  const common = {
15
- from: _joi.default.string().email(options).required().label("Mail from"),
16
- port: _joi.default.number().label("Port").default(25),
17
- replyTo: _joi.default.string().email(options).optional().label("Mail reply-to"),
18
- host: _joi.default.string().required().label("Hostname"),
19
- user: _joi.default.string().required().label("User")
12
+ from: _zod.default.string().email().describe("Mail from"),
13
+ port: _zod.default.number().optional().nullish().describe("Port"),
14
+ replyTo: _zod.default.string().email().optional().describe("Mail reply-to"),
15
+ host: _zod.default.string().describe("Hostname"),
16
+ user: _zod.default.string().describe("User")
20
17
  };
21
- const createValidation = _joi.default.object((0, _objectSpread2.default)((0, _objectSpread2.default)({}, common), {}, {
22
- password: password.required()
18
+ const createValidation = _zod.default.object((0, _objectSpread2.default)((0, _objectSpread2.default)({}, common), {}, {
19
+ password
23
20
  })).required();
24
21
  exports.createValidation = createValidation;
25
- const updateValidation = _joi.default.object((0, _objectSpread2.default)((0, _objectSpread2.default)({}, common), {}, {
26
- password
22
+ const updateValidation = _zod.default.object((0, _objectSpread2.default)((0, _objectSpread2.default)({}, common), {}, {
23
+ password: password.nullish().optional()
27
24
  })).required();
28
25
  exports.updateValidation = updateValidation;
@@ -1 +1 @@
1
- {"version":3,"names":["options","tlds","password","joi","string","label","common","from","email","required","port","number","default","replyTo","optional","host","user","createValidation","object","updateValidation"],"sources":["validation.ts"],"sourcesContent":["import joi, { EmailOptions } from \"joi\";\nimport { TransportSettings } from \"~/types\";\n\nconst options: EmailOptions = {\n tlds: false\n};\n\nconst password = joi.string().label(\"Password\");\nconst common = {\n from: joi.string().email(options).required().label(\"Mail from\"),\n port: joi.number().label(\"Port\").default(25),\n replyTo: joi.string().email(options).optional().label(\"Mail reply-to\"),\n host: joi.string().required().label(\"Hostname\"),\n user: joi.string().required().label(\"User\")\n};\n\nexport const createValidation = joi\n .object<TransportSettings>({\n ...common,\n password: password.required()\n })\n .required();\n\nexport const updateValidation = joi\n .object<TransportSettings>({\n ...common,\n password\n })\n .required();\n"],"mappings":";;;;;;;;AAAA;AAGA,MAAMA,OAAqB,GAAG;EAC1BC,IAAI,EAAE;AACV,CAAC;AAED,MAAMC,QAAQ,GAAGC,YAAG,CAACC,MAAM,EAAE,CAACC,KAAK,CAAC,UAAU,CAAC;AAC/C,MAAMC,MAAM,GAAG;EACXC,IAAI,EAAEJ,YAAG,CAACC,MAAM,EAAE,CAACI,KAAK,CAACR,OAAO,CAAC,CAACS,QAAQ,EAAE,CAACJ,KAAK,CAAC,WAAW,CAAC;EAC/DK,IAAI,EAAEP,YAAG,CAACQ,MAAM,EAAE,CAACN,KAAK,CAAC,MAAM,CAAC,CAACO,OAAO,CAAC,EAAE,CAAC;EAC5CC,OAAO,EAAEV,YAAG,CAACC,MAAM,EAAE,CAACI,KAAK,CAACR,OAAO,CAAC,CAACc,QAAQ,EAAE,CAACT,KAAK,CAAC,eAAe,CAAC;EACtEU,IAAI,EAAEZ,YAAG,CAACC,MAAM,EAAE,CAACK,QAAQ,EAAE,CAACJ,KAAK,CAAC,UAAU,CAAC;EAC/CW,IAAI,EAAEb,YAAG,CAACC,MAAM,EAAE,CAACK,QAAQ,EAAE,CAACJ,KAAK,CAAC,MAAM;AAC9C,CAAC;AAEM,MAAMY,gBAAgB,GAAGd,YAAG,CAC9Be,MAAM,6DACAZ,MAAM;EACTJ,QAAQ,EAAEA,QAAQ,CAACO,QAAQ;AAAE,GAC/B,CACDA,QAAQ,EAAE;AAAC;AAET,MAAMU,gBAAgB,GAAGhB,YAAG,CAC9Be,MAAM,6DACAZ,MAAM;EACTJ;AAAQ,GACV,CACDO,QAAQ,EAAE;AAAC"}
1
+ {"version":3,"names":["password","zod","string","describe","common","from","email","port","number","optional","nullish","replyTo","host","user","createValidation","object","required","updateValidation"],"sources":["validation.ts"],"sourcesContent":["import zod from \"zod\";\n\nconst password = zod.string().describe(\"Password\");\n\nconst common = {\n from: zod.string().email().describe(\"Mail from\"),\n port: zod.number().optional().nullish().describe(\"Port\"),\n replyTo: zod.string().email().optional().describe(\"Mail reply-to\"),\n host: zod.string().describe(\"Hostname\"),\n user: zod.string().describe(\"User\")\n};\n\nexport const createValidation = zod\n .object({\n ...common,\n password\n })\n .required();\n\nexport const updateValidation = zod\n .object({\n ...common,\n password: password.nullish().optional()\n })\n .required();\n"],"mappings":";;;;;;;;AAAA;AAEA,MAAMA,QAAQ,GAAGC,YAAG,CAACC,MAAM,EAAE,CAACC,QAAQ,CAAC,UAAU,CAAC;AAElD,MAAMC,MAAM,GAAG;EACXC,IAAI,EAAEJ,YAAG,CAACC,MAAM,EAAE,CAACI,KAAK,EAAE,CAACH,QAAQ,CAAC,WAAW,CAAC;EAChDI,IAAI,EAAEN,YAAG,CAACO,MAAM,EAAE,CAACC,QAAQ,EAAE,CAACC,OAAO,EAAE,CAACP,QAAQ,CAAC,MAAM,CAAC;EACxDQ,OAAO,EAAEV,YAAG,CAACC,MAAM,EAAE,CAACI,KAAK,EAAE,CAACG,QAAQ,EAAE,CAACN,QAAQ,CAAC,eAAe,CAAC;EAClES,IAAI,EAAEX,YAAG,CAACC,MAAM,EAAE,CAACC,QAAQ,CAAC,UAAU,CAAC;EACvCU,IAAI,EAAEZ,YAAG,CAACC,MAAM,EAAE,CAACC,QAAQ,CAAC,MAAM;AACtC,CAAC;AAEM,MAAMW,gBAAgB,GAAGb,YAAG,CAC9Bc,MAAM,6DACAX,MAAM;EACTJ;AAAQ,GACV,CACDgB,QAAQ,EAAE;AAAC;AAET,MAAMC,gBAAgB,GAAGhB,YAAG,CAC9Bc,MAAM,6DACAX,MAAM;EACTJ,QAAQ,EAAEA,QAAQ,CAACU,OAAO,EAAE,CAACD,QAAQ;AAAE,GACzC,CACDO,QAAQ,EAAE;AAAC"}
@@ -17,6 +17,7 @@ var _hooks = require("./settings/hooks");
17
17
  var _apiSecurity = require("@webiny/api-security");
18
18
  const _excluded = ["password"],
19
19
  _excluded2 = ["password"];
20
+ const defaultPort = 25;
20
21
  /**
21
22
  * Note that settings cannot be used if there is no secret defined.
22
23
  */
@@ -44,19 +45,18 @@ const createSettingsCrud = async context => {
44
45
  secret = (0, _secret.getSecret)();
45
46
  } catch (ex) {}
46
47
  const getModel = async () => {
47
- try {
48
- context.security.disableAuthorization();
49
- const model = await context.cms.getModel(_model.SETTINGS_MODEL_ID);
50
- if (model) {
51
- return model;
48
+ return context.security.withoutAuthorization(async () => {
49
+ try {
50
+ const model = await context.cms.getModel(_model.SETTINGS_MODEL_ID);
51
+ if (model) {
52
+ return model;
53
+ }
54
+ } catch (ex) {
55
+ throw new _error.default(ex.message, ex.code, ex.data);
52
56
  }
53
- } catch (ex) {
54
- throw new _error.default(ex.message, ex.code, ex.data);
55
- } finally {
56
- context.security.enableAuthorization();
57
- }
58
- throw new _error.default(`Missing CMS Model "${_model.SETTINGS_MODEL_ID}".`, "CMS_MODEL_MISSING", {
59
- modelId: _model.SETTINGS_MODEL_ID
57
+ throw new _error.default(`Missing CMS Model "${_model.SETTINGS_MODEL_ID}".`, "CMS_MODEL_MISSING", {
58
+ modelId: _model.SETTINGS_MODEL_ID
59
+ });
60
60
  });
61
61
  };
62
62
 
@@ -94,44 +94,43 @@ const createSettingsCrud = async context => {
94
94
  checkSecret();
95
95
  const model = await getModel();
96
96
  const tenant = getTenant();
97
- try {
98
- context.security.disableAuthorization();
99
- await onSettingsBeforeGet.publish({
100
- tenant
101
- });
102
- /**
103
- * We always list because we have no id or something like that to query by.
104
- * This should return one setting anyway.
105
- */
106
- const [entries] = await context.cms.listLatestEntries(model, {
107
- limit: 1,
108
- sort: ["createdOn_DESC"]
109
- });
110
- const [entry] = entries;
111
- if (!entry) {
112
- return null;
97
+ return await context.security.withoutAuthorization(async () => {
98
+ try {
99
+ await onSettingsBeforeGet.publish({
100
+ tenant
101
+ });
102
+ /**
103
+ * We always list because we have no id or something like that to query by.
104
+ * This should return one setting anyway.
105
+ */
106
+ const [entries] = await context.cms.listLatestEntries(model, {
107
+ limit: 1,
108
+ sort: ["createdOn_DESC"]
109
+ });
110
+ const [entry] = entries;
111
+ if (!entry) {
112
+ return null;
113
+ }
114
+ const settings = (0, _transform.transformValuesFromEntry)({
115
+ entry: entry,
116
+ secret
117
+ });
118
+ const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
119
+ password: ""
120
+ });
121
+ await onSettingsAfterGet.publish({
122
+ tenant,
123
+ settings: passwordlessSettings
124
+ });
125
+ return settings;
126
+ } catch (ex) {
127
+ await onSettingsGetError.publish({
128
+ tenant,
129
+ error: ex
130
+ });
113
131
  }
114
- const settings = (0, _transform.transformValuesFromEntry)({
115
- entry: entry,
116
- secret
117
- });
118
- const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
119
- password: ""
120
- });
121
- await onSettingsAfterGet.publish({
122
- tenant,
123
- settings: passwordlessSettings
124
- });
125
- return settings;
126
- } catch (ex) {
127
- await onSettingsGetError.publish({
128
- tenant,
129
- error: ex
130
- });
131
- } finally {
132
- context.security.enableAuthorization();
133
- }
134
- return null;
132
+ return null;
133
+ });
135
134
  },
136
135
  /**
137
136
  * Method should not be used outside of mailer
@@ -144,48 +143,44 @@ const createSettingsCrud = async context => {
144
143
  input
145
144
  } = params;
146
145
  const model = await getModel();
147
- const result = _validation.createValidation.validate(input);
148
- const error = result.error;
149
- if (error) {
146
+ const result = _validation.createValidation.safeParse(input);
147
+ if (!result.success) {
150
148
  throw new _error.default("Validation failed!", "VALIDATION_ERROR", {
151
- errors: error.details
149
+ errors: result.error.errors
152
150
  });
153
151
  }
154
- const _result$value = result.value,
152
+ const _result$data = result.data,
155
153
  {
156
154
  password
157
- } = _result$value,
158
- settings = (0, _objectWithoutProperties2.default)(_result$value, _excluded);
159
- if (!settings.port) {
160
- settings.port = 25;
161
- }
155
+ } = _result$data,
156
+ settings = (0, _objectWithoutProperties2.default)(_result$data, _excluded);
162
157
  const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
158
+ port: settings.port || defaultPort,
163
159
  password: ""
164
160
  });
165
- try {
166
- context.security.disableAuthorization();
167
- await onSettingsBeforeCreate.publish({
168
- settings: passwordlessSettings
169
- });
170
- await context.cms.createEntry(model, (0, _transform.transformInputToEntryValues)({
171
- values: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
172
- password
173
- }),
174
- secret
175
- }));
176
- await onSettingsAfterCreate.publish({
177
- settings: passwordlessSettings
178
- });
179
- return passwordlessSettings;
180
- } catch (ex) {
181
- await onSettingsCreateError.publish({
182
- settings: passwordlessSettings,
183
- error: ex
184
- });
185
- throw new _error.default(ex.message, ex.code, ex.data);
186
- } finally {
187
- context.security.enableAuthorization();
188
- }
161
+ return await context.security.withoutAuthorization(async () => {
162
+ try {
163
+ await onSettingsBeforeCreate.publish({
164
+ settings: passwordlessSettings
165
+ });
166
+ await context.cms.createEntry(model, (0, _transform.transformInputToEntryValues)({
167
+ values: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, passwordlessSettings), {}, {
168
+ password
169
+ }),
170
+ secret
171
+ }));
172
+ await onSettingsAfterCreate.publish({
173
+ settings: passwordlessSettings
174
+ });
175
+ return passwordlessSettings;
176
+ } catch (ex) {
177
+ await onSettingsCreateError.publish({
178
+ settings: passwordlessSettings,
179
+ error: ex
180
+ });
181
+ throw new _error.default(ex.message, ex.code, ex.data);
182
+ }
183
+ });
189
184
  },
190
185
  /**
191
186
  * Method should not be used outside of mailer
@@ -199,62 +194,59 @@ const createSettingsCrud = async context => {
199
194
  original: initialOriginal
200
195
  } = params;
201
196
  const model = await getModel();
202
- const result = _validation.updateValidation.validate(input);
203
- const error = result.error;
204
- if (error) {
197
+ const result = _validation.updateValidation.safeParse(input);
198
+ if (!result.success) {
205
199
  throw new _error.default("Validation failed!", "VALIDATION_ERROR", {
206
- errors: error.details
200
+ errors: result.error.errors
207
201
  });
208
202
  }
209
- let original = initialOriginal;
203
+ let dbOriginal = null;
204
+ if (!initialOriginal) {
205
+ dbOriginal = await this.getSettings();
206
+ }
207
+ const original = initialOriginal || dbOriginal;
210
208
  if (!original) {
211
- original = await this.getSettings();
212
- if (!original) {
213
- throw new _error.default(`You are trying to update settings, but there is no existing record. Create it first!`, "NOT_FOUND");
214
- }
209
+ throw new _error.default(`You are trying to update settings, but there is no existing record. Create it first!`, "NOT_FOUND");
215
210
  }
216
- const _result$value2 = result.value,
211
+ const _result$data2 = result.data,
217
212
  {
218
213
  password
219
- } = _result$value2,
220
- settings = (0, _objectWithoutProperties2.default)(_result$value2, _excluded2);
221
- if (!settings.port) {
222
- settings.port = original.port || 25;
223
- }
214
+ } = _result$data2,
215
+ settings = (0, _objectWithoutProperties2.default)(_result$data2, _excluded2);
224
216
  const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
217
+ port: settings.port || original.port || defaultPort,
225
218
  password: ""
226
219
  });
227
- try {
228
- context.security.disableAuthorization();
229
- await onSettingsBeforeUpdate.publish({
230
- settings: passwordlessSettings,
231
- original
232
- });
233
- const transformedInput = (0, _transform.transformInputToEntryValues)({
234
- values: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
235
- password: password || original.password
236
- }),
237
- secret
238
- });
239
- /**
240
- * We want to make sure that old password gets stored again in case no password was sent in update input.
241
- */
242
- await context.cms.updateEntry(model, original.id, transformedInput);
243
- await onSettingsAfterUpdate.publish({
244
- settings: passwordlessSettings,
245
- original
246
- });
247
- return passwordlessSettings;
248
- } catch (ex) {
249
- await onSettingsUpdateError.publish({
250
- original,
251
- settings: passwordlessSettings,
252
- error: ex
253
- });
254
- throw new _error.default(ex.message, ex.code, ex.data);
255
- } finally {
256
- context.security.enableAuthorization();
257
- }
220
+ return await context.security.withoutAuthorization(async () => {
221
+ try {
222
+ await onSettingsBeforeUpdate.publish({
223
+ settings: passwordlessSettings,
224
+ original: original
225
+ });
226
+ const transformedInput = (0, _transform.transformInputToEntryValues)({
227
+ values: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, passwordlessSettings), {}, {
228
+ password: password || original.password
229
+ }),
230
+ secret
231
+ });
232
+ /**
233
+ * We want to make sure that old password gets stored again in case no password was sent in update input.
234
+ */
235
+ await context.cms.updateEntry(model, original.id, transformedInput);
236
+ await onSettingsAfterUpdate.publish({
237
+ settings: passwordlessSettings,
238
+ original
239
+ });
240
+ return passwordlessSettings;
241
+ } catch (ex) {
242
+ await onSettingsUpdateError.publish({
243
+ original,
244
+ settings: passwordlessSettings,
245
+ error: ex
246
+ });
247
+ throw new _error.default(ex.message, ex.code, ex.data);
248
+ }
249
+ });
258
250
  },
259
251
  async saveSettings(params) {
260
252
  const {
@@ -1 +1 @@
1
- {"version":3,"names":["createSettingsCrud","context","attachPasswordObfuscatingHooks","getTenant","tenancy","getCurrentTenant","id","validateAccess","permission","security","getPermission","NotAuthorizedError","data","reason","secret","getSecret","ex","getModel","disableAuthorization","model","cms","SETTINGS_MODEL_ID","WebinyError","message","code","enableAuthorization","modelId","onSettingsBeforeGet","createTopic","onSettingsAfterGet","onSettingsGetError","onSettingsBeforeCreate","onSettingsAfterCreate","onSettingsCreateError","onSettingsBeforeUpdate","onSettingsAfterUpdate","onSettingsUpdateError","checkSecret","description","getSettings","tenant","publish","entries","listLatestEntries","limit","sort","entry","settings","transformValuesFromEntry","passwordlessSettings","password","error","createSettings","params","input","result","createValidation","validate","errors","details","value","port","createEntry","transformInputToEntryValues","values","updateSettings","original","initialOriginal","updateValidation","transformedInput","updateEntry","saveSettings"],"sources":["settings.crud.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport {\n MailerContext,\n MailerContextObject,\n MailerSettingsContext,\n OnSettingsAfterCreateTopicParams,\n OnSettingsAfterGetTopicParams,\n OnSettingsAfterUpdateTopicParams,\n OnSettingsBeforeCreateTopicParams,\n OnSettingsBeforeGetTopicParams,\n OnSettingsBeforeUpdateTopicParams,\n OnSettingsCreateErrorTopicParams,\n OnSettingsGetErrorTopicParams,\n OnSettingsUpdateErrorTopicParams,\n TransportSettings\n} from \"~/types\";\nimport { createTopic } from \"@webiny/pubsub\";\nimport { SETTINGS_MODEL_ID } from \"./settings/model\";\nimport { transformValuesFromEntry, transformInputToEntryValues } from \"~/crud/settings/transform\";\nimport { getSecret } from \"~/crud/settings/secret\";\nimport { createValidation, updateValidation } from \"~/crud/settings/validation\";\nimport { CmsEntry, CmsModel } from \"@webiny/api-headless-cms/types\";\nimport { attachPasswordObfuscatingHooks } from \"~/crud/settings/hooks\";\nimport { NotAuthorizedError } from \"@webiny/api-security\";\n\n/**\n * Note that settings cannot be used if there is no secret defined.\n */\nexport const createSettingsCrud = async (\n context: MailerContext\n): Promise<MailerSettingsContext> => {\n /**\n * We need to remove password from all references on create and update in the CMS.\n */\n attachPasswordObfuscatingHooks(context);\n\n const getTenant = () => {\n return context.tenancy.getCurrentTenant().id;\n };\n\n const validateAccess = async () => {\n const permission = await context.security.getPermission(\"mailer.settings\");\n\n if (permission) {\n return;\n }\n throw new NotAuthorizedError({\n data: {\n reason: `Not allowed to update the mailer settings.`\n }\n });\n };\n\n let secret: string | null = null;\n try {\n secret = getSecret();\n } catch (ex) {}\n\n const getModel = async (): Promise<CmsModel> => {\n try {\n context.security.disableAuthorization();\n const model = await context.cms.getModel(SETTINGS_MODEL_ID);\n if (model) {\n return model;\n }\n } catch (ex) {\n throw new WebinyError(ex.message, ex.code, ex.data);\n } finally {\n context.security.enableAuthorization();\n }\n throw new WebinyError(`Missing CMS Model \"${SETTINGS_MODEL_ID}\".`, \"CMS_MODEL_MISSING\", {\n modelId: SETTINGS_MODEL_ID\n });\n };\n\n // get\n const onSettingsBeforeGet = createTopic<OnSettingsBeforeGetTopicParams>(\n \"mailer.onSettingsBeforeGet\"\n );\n const onSettingsAfterGet = createTopic<OnSettingsAfterGetTopicParams>(\n \"mailer.onSettingsAfterGet\"\n );\n const onSettingsGetError = createTopic<OnSettingsGetErrorTopicParams>(\n \"mailer.onSettingsCreateError\"\n );\n // create\n const onSettingsBeforeCreate = createTopic<OnSettingsBeforeCreateTopicParams>(\n \"mailer.onSettingsBeforeCreate\"\n );\n const onSettingsAfterCreate = createTopic<OnSettingsAfterCreateTopicParams>(\n \"mailer.onSettingsAfterCreate\"\n );\n const onSettingsCreateError = createTopic<OnSettingsCreateErrorTopicParams>(\n \"mailer.onSettingsCreateError\"\n );\n // update\n const onSettingsBeforeUpdate = createTopic<OnSettingsBeforeUpdateTopicParams>(\n \"mailer.onSettingsBeforeUpdate\"\n );\n const onSettingsAfterUpdate = createTopic<OnSettingsAfterUpdateTopicParams>(\n \"mailer.onSettingsAfterUpdate\"\n );\n const onSettingsUpdateError = createTopic<OnSettingsUpdateErrorTopicParams>(\n \"mailer.onSettingsUpdateError\"\n );\n\n const checkSecret = (): void => {\n if (secret) {\n return;\n }\n throw new WebinyError(\"There must be a password secret defined!\", \"PASSWORD_SECRET_ERROR\", {\n description:\n \"To store the Mailer settings, you must have a password secret environment variable defined.\"\n });\n };\n\n return {\n onSettingsAfterGet,\n onSettingsBeforeGet,\n onSettingsGetError,\n onSettingsBeforeCreate,\n onSettingsAfterCreate,\n onSettingsCreateError,\n onSettingsBeforeUpdate,\n onSettingsAfterUpdate,\n onSettingsUpdateError,\n getSettings: async () => {\n checkSecret();\n\n const model = await getModel();\n\n const tenant = getTenant();\n try {\n context.security.disableAuthorization();\n await onSettingsBeforeGet.publish({\n tenant\n });\n /**\n * We always list because we have no id or something like that to query by.\n * This should return one setting anyway.\n */\n const [entries] = await context.cms.listLatestEntries(model, {\n limit: 1,\n sort: [\"createdOn_DESC\"]\n });\n const [entry] = entries;\n if (!entry) {\n return null;\n }\n const settings = transformValuesFromEntry({\n entry: entry as CmsEntry<TransportSettings>,\n secret\n });\n\n const passwordlessSettings: TransportSettings = {\n ...settings,\n password: \"\"\n };\n\n await onSettingsAfterGet.publish({\n tenant,\n settings: passwordlessSettings\n });\n\n return settings;\n } catch (ex) {\n await onSettingsGetError.publish({\n tenant,\n error: ex\n });\n } finally {\n context.security.enableAuthorization();\n }\n return null;\n },\n /**\n * Method should not be used outside of mailer\n * @internal\n */\n async createSettings(this: MailerContextObject, params) {\n checkSecret();\n await validateAccess();\n\n const { input } = params;\n\n const model = await getModel();\n\n const result = createValidation.validate(input);\n\n const error = result.error;\n if (error) {\n throw new WebinyError(\"Validation failed!\", \"VALIDATION_ERROR\", {\n errors: error.details\n });\n }\n\n const { password, ...settings } = result.value;\n\n if (!settings.port) {\n settings.port = 25;\n }\n\n const passwordlessSettings: TransportSettings = {\n ...settings,\n password: \"\"\n };\n\n try {\n context.security.disableAuthorization();\n\n await onSettingsBeforeCreate.publish({\n settings: passwordlessSettings\n });\n\n await context.cms.createEntry(\n model,\n transformInputToEntryValues({\n values: {\n ...settings,\n password\n },\n secret\n })\n );\n\n await onSettingsAfterCreate.publish({\n settings: passwordlessSettings\n });\n return passwordlessSettings;\n } catch (ex) {\n await onSettingsCreateError.publish({\n settings: passwordlessSettings,\n error: ex\n });\n throw new WebinyError(ex.message, ex.code, ex.data);\n } finally {\n context.security.enableAuthorization();\n }\n },\n /**\n * Method should not be used outside of mailer\n * @internal\n */\n async updateSettings(this: MailerContextObject, params) {\n checkSecret();\n await validateAccess();\n\n const { input, original: initialOriginal } = params;\n\n const model = await getModel();\n\n const result = updateValidation.validate(input);\n\n const error = result.error;\n if (error) {\n throw new WebinyError(\"Validation failed!\", \"VALIDATION_ERROR\", {\n errors: error.details\n });\n }\n let original = initialOriginal;\n if (!original) {\n original = await this.getSettings();\n if (!original) {\n throw new WebinyError(\n `You are trying to update settings, but there is no existing record. Create it first!`,\n \"NOT_FOUND\"\n );\n }\n }\n\n const { password, ...settings } = result.value;\n\n if (!settings.port) {\n settings.port = original.port || 25;\n }\n\n const passwordlessSettings: TransportSettings = {\n ...settings,\n password: \"\"\n };\n try {\n context.security.disableAuthorization();\n\n await onSettingsBeforeUpdate.publish({\n settings: passwordlessSettings,\n original\n });\n\n const transformedInput = transformInputToEntryValues({\n values: {\n ...settings,\n password: password || original.password\n },\n secret\n });\n /**\n * We want to make sure that old password gets stored again in case no password was sent in update input.\n */\n await context.cms.updateEntry(model, original.id, transformedInput);\n\n await onSettingsAfterUpdate.publish({\n settings: passwordlessSettings,\n original\n });\n return passwordlessSettings;\n } catch (ex) {\n await onSettingsUpdateError.publish({\n original,\n settings: passwordlessSettings,\n error: ex\n });\n throw new WebinyError(ex.message, ex.code, ex.data);\n } finally {\n context.security.enableAuthorization();\n }\n },\n async saveSettings(this: MailerContextObject, params) {\n const { input } = params;\n\n const original = await this.getSettings();\n if (!original) {\n return this.createSettings({\n input\n });\n }\n return this.updateSettings({\n input,\n original\n });\n }\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["defaultPort","createSettingsCrud","context","attachPasswordObfuscatingHooks","getTenant","tenancy","getCurrentTenant","id","validateAccess","permission","security","getPermission","NotAuthorizedError","data","reason","secret","getSecret","ex","getModel","withoutAuthorization","model","cms","SETTINGS_MODEL_ID","WebinyError","message","code","modelId","onSettingsBeforeGet","createTopic","onSettingsAfterGet","onSettingsGetError","onSettingsBeforeCreate","onSettingsAfterCreate","onSettingsCreateError","onSettingsBeforeUpdate","onSettingsAfterUpdate","onSettingsUpdateError","checkSecret","description","getSettings","tenant","publish","entries","listLatestEntries","limit","sort","entry","settings","transformValuesFromEntry","passwordlessSettings","password","error","createSettings","params","input","result","createValidation","safeParse","success","errors","port","createEntry","transformInputToEntryValues","values","updateSettings","original","initialOriginal","updateValidation","dbOriginal","transformedInput","updateEntry","saveSettings"],"sources":["settings.crud.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport {\n ExtendedTransportSettings,\n MailerContext,\n MailerContextObject,\n MailerSettingsContext,\n OnSettingsAfterCreateTopicParams,\n OnSettingsAfterGetTopicParams,\n OnSettingsAfterUpdateTopicParams,\n OnSettingsBeforeCreateTopicParams,\n OnSettingsBeforeGetTopicParams,\n OnSettingsBeforeUpdateTopicParams,\n OnSettingsCreateErrorTopicParams,\n OnSettingsGetErrorTopicParams,\n OnSettingsUpdateErrorTopicParams,\n TransportSettings\n} from \"~/types\";\nimport { createTopic } from \"@webiny/pubsub\";\nimport { SETTINGS_MODEL_ID } from \"./settings/model\";\nimport { transformInputToEntryValues, transformValuesFromEntry } from \"~/crud/settings/transform\";\nimport { getSecret } from \"~/crud/settings/secret\";\nimport { createValidation, updateValidation } from \"~/crud/settings/validation\";\nimport { CmsEntry, CmsModel } from \"@webiny/api-headless-cms/types\";\nimport { attachPasswordObfuscatingHooks } from \"~/crud/settings/hooks\";\nimport { NotAuthorizedError } from \"@webiny/api-security\";\n\nconst defaultPort = 25;\n/**\n * Note that settings cannot be used if there is no secret defined.\n */\nexport const createSettingsCrud = async (\n context: MailerContext\n): Promise<MailerSettingsContext> => {\n /**\n * We need to remove password from all references on create and update in the CMS.\n */\n attachPasswordObfuscatingHooks(context);\n\n const getTenant = () => {\n return context.tenancy.getCurrentTenant().id;\n };\n\n const validateAccess = async () => {\n const permission = await context.security.getPermission(\"mailer.settings\");\n\n if (permission) {\n return;\n }\n throw new NotAuthorizedError({\n data: {\n reason: `Not allowed to update the mailer settings.`\n }\n });\n };\n\n let secret: string | null = null;\n try {\n secret = getSecret();\n } catch (ex) {}\n\n const getModel = async (): Promise<CmsModel> => {\n return context.security.withoutAuthorization(async () => {\n try {\n const model = await context.cms.getModel(SETTINGS_MODEL_ID);\n if (model) {\n return model;\n }\n } catch (ex) {\n throw new WebinyError(ex.message, ex.code, ex.data);\n }\n throw new WebinyError(\n `Missing CMS Model \"${SETTINGS_MODEL_ID}\".`,\n \"CMS_MODEL_MISSING\",\n {\n modelId: SETTINGS_MODEL_ID\n }\n );\n });\n };\n\n // get\n const onSettingsBeforeGet = createTopic<OnSettingsBeforeGetTopicParams>(\n \"mailer.onSettingsBeforeGet\"\n );\n const onSettingsAfterGet = createTopic<OnSettingsAfterGetTopicParams>(\n \"mailer.onSettingsAfterGet\"\n );\n const onSettingsGetError = createTopic<OnSettingsGetErrorTopicParams>(\n \"mailer.onSettingsCreateError\"\n );\n // create\n const onSettingsBeforeCreate = createTopic<OnSettingsBeforeCreateTopicParams>(\n \"mailer.onSettingsBeforeCreate\"\n );\n const onSettingsAfterCreate = createTopic<OnSettingsAfterCreateTopicParams>(\n \"mailer.onSettingsAfterCreate\"\n );\n const onSettingsCreateError = createTopic<OnSettingsCreateErrorTopicParams>(\n \"mailer.onSettingsCreateError\"\n );\n // update\n const onSettingsBeforeUpdate = createTopic<OnSettingsBeforeUpdateTopicParams>(\n \"mailer.onSettingsBeforeUpdate\"\n );\n const onSettingsAfterUpdate = createTopic<OnSettingsAfterUpdateTopicParams>(\n \"mailer.onSettingsAfterUpdate\"\n );\n const onSettingsUpdateError = createTopic<OnSettingsUpdateErrorTopicParams>(\n \"mailer.onSettingsUpdateError\"\n );\n\n const checkSecret = (): void => {\n if (secret) {\n return;\n }\n throw new WebinyError(\"There must be a password secret defined!\", \"PASSWORD_SECRET_ERROR\", {\n description:\n \"To store the Mailer settings, you must have a password secret environment variable defined.\"\n });\n };\n\n return {\n onSettingsAfterGet,\n onSettingsBeforeGet,\n onSettingsGetError,\n onSettingsBeforeCreate,\n onSettingsAfterCreate,\n onSettingsCreateError,\n onSettingsBeforeUpdate,\n onSettingsAfterUpdate,\n onSettingsUpdateError,\n getSettings: async () => {\n checkSecret();\n\n const model = await getModel();\n\n const tenant = getTenant();\n return await context.security.withoutAuthorization(async () => {\n try {\n await onSettingsBeforeGet.publish({\n tenant\n });\n /**\n * We always list because we have no id or something like that to query by.\n * This should return one setting anyway.\n */\n const [entries] = await context.cms.listLatestEntries(model, {\n limit: 1,\n sort: [\"createdOn_DESC\"]\n });\n const [entry] = entries;\n if (!entry) {\n return null;\n }\n const settings = transformValuesFromEntry({\n entry: entry as CmsEntry<TransportSettings>,\n secret\n });\n\n const passwordlessSettings: TransportSettings = {\n ...settings,\n password: \"\"\n };\n\n await onSettingsAfterGet.publish({\n tenant,\n settings: passwordlessSettings\n });\n\n return settings;\n } catch (ex) {\n await onSettingsGetError.publish({\n tenant,\n error: ex\n });\n }\n return null;\n });\n },\n /**\n * Method should not be used outside of mailer\n * @internal\n */\n async createSettings(this: MailerContextObject, params) {\n checkSecret();\n await validateAccess();\n\n const { input } = params;\n\n const model = await getModel();\n\n const result = createValidation.safeParse(input);\n\n if (!result.success) {\n throw new WebinyError(\"Validation failed!\", \"VALIDATION_ERROR\", {\n errors: result.error.errors\n });\n }\n\n const { password, ...settings } = result.data;\n\n const passwordlessSettings: TransportSettings = {\n ...settings,\n port: settings.port || defaultPort,\n password: \"\"\n };\n\n return await context.security.withoutAuthorization(async () => {\n try {\n await onSettingsBeforeCreate.publish({\n settings: passwordlessSettings\n });\n\n await context.cms.createEntry(\n model,\n transformInputToEntryValues({\n values: {\n ...passwordlessSettings,\n password\n },\n secret\n })\n );\n\n await onSettingsAfterCreate.publish({\n settings: passwordlessSettings\n });\n return passwordlessSettings;\n } catch (ex) {\n await onSettingsCreateError.publish({\n settings: passwordlessSettings,\n error: ex\n });\n throw new WebinyError(ex.message, ex.code, ex.data);\n }\n });\n },\n /**\n * Method should not be used outside of mailer\n * @internal\n */\n async updateSettings(this: MailerContextObject, params) {\n checkSecret();\n await validateAccess();\n\n const { input, original: initialOriginal } = params;\n\n const model = await getModel();\n\n const result = updateValidation.safeParse(input);\n\n if (!result.success) {\n throw new WebinyError(\"Validation failed!\", \"VALIDATION_ERROR\", {\n errors: result.error.errors\n });\n }\n\n let dbOriginal: ExtendedTransportSettings | null = null;\n if (!initialOriginal) {\n dbOriginal = await this.getSettings();\n }\n const original = initialOriginal || dbOriginal;\n if (!original) {\n throw new WebinyError(\n `You are trying to update settings, but there is no existing record. Create it first!`,\n \"NOT_FOUND\"\n );\n }\n\n const { password, ...settings } = result.data;\n\n const passwordlessSettings: TransportSettings = {\n ...settings,\n port: settings.port || original.port || defaultPort,\n password: \"\"\n };\n return await context.security.withoutAuthorization(async () => {\n try {\n await onSettingsBeforeUpdate.publish({\n settings: passwordlessSettings,\n original: original\n });\n\n const transformedInput = transformInputToEntryValues({\n values: {\n ...passwordlessSettings,\n password: password || original.password\n },\n secret\n });\n /**\n * We want to make sure that old password gets stored again in case no password was sent in update input.\n */\n await context.cms.updateEntry(model, original.id, transformedInput);\n\n await onSettingsAfterUpdate.publish({\n settings: passwordlessSettings,\n original\n });\n return passwordlessSettings;\n } catch (ex) {\n await onSettingsUpdateError.publish({\n original,\n settings: passwordlessSettings,\n error: ex\n });\n throw new WebinyError(ex.message, ex.code, ex.data);\n }\n });\n },\n async saveSettings(this: MailerContextObject, params) {\n const { input } = params;\n\n const original = await this.getSettings();\n if (!original) {\n return this.createSettings({\n input\n });\n }\n return this.updateSettings({\n input,\n original\n });\n }\n };\n};\n"],"mappings":"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"}
@@ -5,24 +5,22 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.attachOnTransportBeforeSend = void 0;
8
- var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
9
- var _joi = _interopRequireDefault(require("joi"));
10
8
  var _error = _interopRequireDefault(require("@webiny/error"));
11
- const options = {
12
- tlds: false
13
- };
14
- const requiredString = _joi.default.string().required();
15
- const requiredEmail = requiredString.email(options);
16
- const schema = _joi.default.object({
17
- to: _joi.default.array().items(requiredEmail),
18
- from: _joi.default.string().email(options),
19
- subject: requiredString.max(1024),
20
- cc: _joi.default.array().items(requiredEmail),
21
- bcc: _joi.default.array().items(requiredEmail),
22
- replyTo: _joi.default.string().email(options),
23
- text: requiredString.min(10),
24
- html: _joi.default.string()
25
- });
9
+ var _zod = _interopRequireDefault(require("zod"));
10
+ const requiredString = _zod.default.string();
11
+ const requiredEmail = requiredString.email();
12
+ const schema = _zod.default.object({
13
+ to: _zod.default.array(requiredEmail).optional(),
14
+ from: _zod.default.string().email().optional(),
15
+ subject: requiredString.max(1024).min(2),
16
+ cc: _zod.default.array(requiredEmail).optional(),
17
+ bcc: _zod.default.array(requiredEmail).optional(),
18
+ replyTo: _zod.default.string().email().optional(),
19
+ text: _zod.default.string().optional(),
20
+ html: _zod.default.string().optional()
21
+ }).refine(data => {
22
+ return !!data.text || !!data.html;
23
+ }, "Either text or html is required.");
26
24
  const attachOnTransportBeforeSend = params => {
27
25
  const {
28
26
  onTransportBeforeSend
@@ -32,11 +30,22 @@ const attachOnTransportBeforeSend = params => {
32
30
  }) => {
33
31
  let result;
34
32
  try {
35
- result = await schema.validate(input);
36
- if (!result.error) {
33
+ result = schema.safeParse(input);
34
+ if (result.success) {
37
35
  return;
38
36
  }
37
+ throw new _error.default({
38
+ message: "Error while validating e-mail params.",
39
+ code: "VALIDATION_ERROR",
40
+ data: {
41
+ error: result.error,
42
+ input
43
+ }
44
+ });
39
45
  } catch (ex) {
46
+ if (ex instanceof _error.default) {
47
+ throw ex;
48
+ }
40
49
  throw new _error.default({
41
50
  message: "Error while validating e-mail params.",
42
51
  code: "VALIDATION_ERROR",
@@ -46,11 +55,6 @@ const attachOnTransportBeforeSend = params => {
46
55
  }
47
56
  });
48
57
  }
49
- throw new _error.default({
50
- message: "Error while validating e-mail params.",
51
- code: "VALIDATION_ERROR",
52
- data: (0, _objectSpread2.default)({}, result.error)
53
- });
54
58
  });
55
59
  };
56
60
  exports.attachOnTransportBeforeSend = attachOnTransportBeforeSend;