@webiny/api-mailer 0.0.0-unstable.496cf268ac → 0.0.0-unstable.606fc9c866

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"}
@@ -8,17 +8,17 @@ export declare const createValidation: zod.ZodObject<{
8
8
  user: zod.ZodString;
9
9
  }, "strip", zod.ZodTypeAny, {
10
10
  from: string;
11
+ host: string;
12
+ port: number | null;
11
13
  replyTo: string;
12
14
  password: string;
13
- port: number | null;
14
- host: string;
15
15
  user: string;
16
16
  }, {
17
17
  from: string;
18
+ host: string;
19
+ port: number | null;
18
20
  replyTo: string;
19
21
  password: string;
20
- port: number | null;
21
- host: string;
22
22
  user: string;
23
23
  }>;
24
24
  export declare const updateValidation: zod.ZodObject<{
@@ -30,16 +30,16 @@ export declare const updateValidation: zod.ZodObject<{
30
30
  user: zod.ZodString;
31
31
  }, "strip", zod.ZodTypeAny, {
32
32
  from: string;
33
+ host: string;
34
+ port: number | null;
33
35
  replyTo: string;
34
36
  password: string | null;
35
- port: number | null;
36
- host: string;
37
37
  user: string;
38
38
  }, {
39
39
  from: string;
40
+ host: string;
41
+ port: number | null;
40
42
  replyTo: string;
41
43
  password: string | null;
42
- port: number | null;
43
- host: string;
44
44
  user: string;
45
45
  }>;
@@ -45,19 +45,18 @@ const createSettingsCrud = async context => {
45
45
  secret = (0, _secret.getSecret)();
46
46
  } catch (ex) {}
47
47
  const getModel = async () => {
48
- try {
49
- context.security.disableAuthorization();
50
- const model = await context.cms.getModel(_model.SETTINGS_MODEL_ID);
51
- if (model) {
52
- 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);
53
56
  }
54
- } catch (ex) {
55
- throw new _error.default(ex.message, ex.code, ex.data);
56
- } finally {
57
- context.security.enableAuthorization();
58
- }
59
- throw new _error.default(`Missing CMS Model "${_model.SETTINGS_MODEL_ID}".`, "CMS_MODEL_MISSING", {
60
- 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
+ });
61
60
  });
62
61
  };
63
62
 
@@ -95,44 +94,43 @@ const createSettingsCrud = async context => {
95
94
  checkSecret();
96
95
  const model = await getModel();
97
96
  const tenant = getTenant();
98
- try {
99
- context.security.disableAuthorization();
100
- await onSettingsBeforeGet.publish({
101
- tenant
102
- });
103
- /**
104
- * We always list because we have no id or something like that to query by.
105
- * This should return one setting anyway.
106
- */
107
- const [entries] = await context.cms.listLatestEntries(model, {
108
- limit: 1,
109
- sort: ["createdOn_DESC"]
110
- });
111
- const [entry] = entries;
112
- if (!entry) {
113
- 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
+ });
114
131
  }
115
- const settings = (0, _transform.transformValuesFromEntry)({
116
- entry: entry,
117
- secret
118
- });
119
- const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
120
- password: ""
121
- });
122
- await onSettingsAfterGet.publish({
123
- tenant,
124
- settings: passwordlessSettings
125
- });
126
- return settings;
127
- } catch (ex) {
128
- await onSettingsGetError.publish({
129
- tenant,
130
- error: ex
131
- });
132
- } finally {
133
- context.security.enableAuthorization();
134
- }
135
- return null;
132
+ return null;
133
+ });
136
134
  },
137
135
  /**
138
136
  * Method should not be used outside of mailer
@@ -160,30 +158,29 @@ const createSettingsCrud = async context => {
160
158
  port: settings.port || defaultPort,
161
159
  password: ""
162
160
  });
163
- try {
164
- context.security.disableAuthorization();
165
- await onSettingsBeforeCreate.publish({
166
- settings: passwordlessSettings
167
- });
168
- await context.cms.createEntry(model, (0, _transform.transformInputToEntryValues)({
169
- values: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, passwordlessSettings), {}, {
170
- password
171
- }),
172
- secret
173
- }));
174
- await onSettingsAfterCreate.publish({
175
- settings: passwordlessSettings
176
- });
177
- return passwordlessSettings;
178
- } catch (ex) {
179
- await onSettingsCreateError.publish({
180
- settings: passwordlessSettings,
181
- error: ex
182
- });
183
- throw new _error.default(ex.message, ex.code, ex.data);
184
- } finally {
185
- context.security.enableAuthorization();
186
- }
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
+ });
187
184
  },
188
185
  /**
189
186
  * Method should not be used outside of mailer
@@ -203,12 +200,13 @@ const createSettingsCrud = async context => {
203
200
  errors: result.error.errors
204
201
  });
205
202
  }
206
- let original = initialOriginal;
203
+ let dbOriginal = null;
204
+ if (!initialOriginal) {
205
+ dbOriginal = await this.getSettings();
206
+ }
207
+ const original = initialOriginal || dbOriginal;
207
208
  if (!original) {
208
- original = await this.getSettings();
209
- if (!original) {
210
- throw new _error.default(`You are trying to update settings, but there is no existing record. Create it first!`, "NOT_FOUND");
211
- }
209
+ throw new _error.default(`You are trying to update settings, but there is no existing record. Create it first!`, "NOT_FOUND");
212
210
  }
213
211
  const _result$data2 = result.data,
214
212
  {
@@ -219,37 +217,36 @@ const createSettingsCrud = async context => {
219
217
  port: settings.port || original.port || defaultPort,
220
218
  password: ""
221
219
  });
222
- try {
223
- context.security.disableAuthorization();
224
- await onSettingsBeforeUpdate.publish({
225
- settings: passwordlessSettings,
226
- original
227
- });
228
- const transformedInput = (0, _transform.transformInputToEntryValues)({
229
- values: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, passwordlessSettings), {}, {
230
- password: password || original.password
231
- }),
232
- secret
233
- });
234
- /**
235
- * We want to make sure that old password gets stored again in case no password was sent in update input.
236
- */
237
- await context.cms.updateEntry(model, original.id, transformedInput);
238
- await onSettingsAfterUpdate.publish({
239
- settings: passwordlessSettings,
240
- original
241
- });
242
- return passwordlessSettings;
243
- } catch (ex) {
244
- await onSettingsUpdateError.publish({
245
- original,
246
- settings: passwordlessSettings,
247
- error: ex
248
- });
249
- throw new _error.default(ex.message, ex.code, ex.data);
250
- } finally {
251
- context.security.enableAuthorization();
252
- }
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
+ });
253
250
  },
254
251
  async saveSettings(params) {
255
252
  const {
@@ -1 +1 @@
1
- {"version":3,"names":["defaultPort","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","safeParse","success","errors","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\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 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.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 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 ...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 } 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.safeParse(input);\n\n if (!result.success) {\n throw new WebinyError(\"Validation failed!\", \"VALIDATION_ERROR\", {\n errors: result.error.errors\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.data;\n\n const passwordlessSettings: TransportSettings = {\n ...settings,\n port: settings.port || original.port || defaultPort,\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 ...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 } 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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-mailer",
3
- "version": "0.0.0-unstable.496cf268ac",
3
+ "version": "0.0.0-unstable.606fc9c866",
4
4
  "main": "index.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,12 +15,12 @@
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
17
  "@babel/runtime": "7.20.13",
18
- "@webiny/api": "0.0.0-unstable.496cf268ac",
19
- "@webiny/api-headless-cms": "0.0.0-unstable.496cf268ac",
20
- "@webiny/error": "0.0.0-unstable.496cf268ac",
21
- "@webiny/handler-graphql": "0.0.0-unstable.496cf268ac",
22
- "@webiny/plugins": "0.0.0-unstable.496cf268ac",
23
- "@webiny/pubsub": "0.0.0-unstable.496cf268ac",
18
+ "@webiny/api": "0.0.0-unstable.606fc9c866",
19
+ "@webiny/api-headless-cms": "0.0.0-unstable.606fc9c866",
20
+ "@webiny/error": "0.0.0-unstable.606fc9c866",
21
+ "@webiny/handler-graphql": "0.0.0-unstable.606fc9c866",
22
+ "@webiny/plugins": "0.0.0-unstable.606fc9c866",
23
+ "@webiny/pubsub": "0.0.0-unstable.606fc9c866",
24
24
  "crypto-js": "4.1.1",
25
25
  "lodash": "4.17.21",
26
26
  "nodemailer": "6.9.1",
@@ -33,19 +33,19 @@
33
33
  "@babel/preset-typescript": "^7.18.6",
34
34
  "@types/crypto-js": "^4.1.1",
35
35
  "@types/nodemailer": "^6.4.4",
36
- "@webiny/api-headless-cms-ddb": "^0.0.0-unstable.496cf268ac",
37
- "@webiny/api-i18n": "^0.0.0-unstable.496cf268ac",
38
- "@webiny/api-i18n-ddb": "^0.0.0-unstable.496cf268ac",
39
- "@webiny/api-security": "^0.0.0-unstable.496cf268ac",
40
- "@webiny/api-security-so-ddb": "^0.0.0-unstable.496cf268ac",
41
- "@webiny/api-tenancy": "^0.0.0-unstable.496cf268ac",
42
- "@webiny/api-tenancy-so-ddb": "^0.0.0-unstable.496cf268ac",
43
- "@webiny/cli": "^0.0.0-unstable.496cf268ac",
44
- "@webiny/db-dynamodb": "^0.0.0-unstable.496cf268ac",
45
- "@webiny/handler": "^0.0.0-unstable.496cf268ac",
46
- "@webiny/handler-aws": "^0.0.0-unstable.496cf268ac",
47
- "@webiny/handler-db": "^0.0.0-unstable.496cf268ac",
48
- "@webiny/project-utils": "^0.0.0-unstable.496cf268ac",
36
+ "@webiny/api-headless-cms-ddb": "^0.0.0-unstable.606fc9c866",
37
+ "@webiny/api-i18n": "^0.0.0-unstable.606fc9c866",
38
+ "@webiny/api-i18n-ddb": "^0.0.0-unstable.606fc9c866",
39
+ "@webiny/api-security": "^0.0.0-unstable.606fc9c866",
40
+ "@webiny/api-security-so-ddb": "^0.0.0-unstable.606fc9c866",
41
+ "@webiny/api-tenancy": "^0.0.0-unstable.606fc9c866",
42
+ "@webiny/api-tenancy-so-ddb": "^0.0.0-unstable.606fc9c866",
43
+ "@webiny/cli": "^0.0.0-unstable.606fc9c866",
44
+ "@webiny/db-dynamodb": "^0.0.0-unstable.606fc9c866",
45
+ "@webiny/handler": "^0.0.0-unstable.606fc9c866",
46
+ "@webiny/handler-aws": "^0.0.0-unstable.606fc9c866",
47
+ "@webiny/handler-db": "^0.0.0-unstable.606fc9c866",
48
+ "@webiny/project-utils": "^0.0.0-unstable.606fc9c866",
49
49
  "graphql": "^15.7.2",
50
50
  "jest": "^28.1.0",
51
51
  "jest-dynalite": "^3.6.1",
@@ -61,5 +61,5 @@
61
61
  "build": "yarn webiny run build",
62
62
  "watch": "yarn webiny run watch"
63
63
  },
64
- "gitHead": "496cf268acd5b092c860b62d75c7d765c9472043"
64
+ "gitHead": "606fc9c866aec436f24983abc9bdaf02af2b8746"
65
65
  }