@webiny/api-mailer 5.34.8 → 5.35.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/context.js +0 -7
- package/context.js.map +1 -1
- package/crud/group.js +0 -3
- package/crud/group.js.map +1 -1
- package/crud/settings/hooks.js +3 -15
- package/crud/settings/hooks.js.map +1 -1
- package/crud/settings/model.js +2 -13
- package/crud/settings/model.js.map +1 -1
- package/crud/settings/password.js +0 -18
- package/crud/settings/password.js.map +1 -1
- package/crud/settings/secret.js +0 -6
- package/crud/settings/secret.js.map +1 -1
- package/crud/settings/transform.js +0 -12
- package/crud/settings/transform.js.map +1 -1
- package/crud/settings/validation.d.ts +45 -4
- package/crud/settings/validation.js +11 -24
- package/crud/settings/validation.js.map +1 -1
- package/crud/settings.crud.js +132 -195
- package/crud/settings.crud.js.map +1 -1
- package/crud/transport/onTransportBeforeSend.js +28 -37
- package/crud/transport/onTransportBeforeSend.js.map +1 -1
- package/crud/transporter.crud.js +3 -40
- package/crud/transporter.crud.js.map +1 -1
- package/graphql/index.js +0 -3
- package/graphql/index.js.map +1 -1
- package/graphql/settings.js +0 -8
- package/graphql/settings.js.map +1 -1
- package/index.d.ts +2 -5
- package/index.js +29 -35
- package/index.js.map +1 -1
- package/package.json +24 -24
- package/plugins/CreateTransportPlugin.js +0 -9
- package/plugins/CreateTransportPlugin.js.map +1 -1
- package/plugins/index.js +0 -2
- package/plugins/index.js.map +1 -1
- package/transports/createDummyTransport.js +1 -3
- package/transports/createDummyTransport.js.map +1 -1
- package/transports/createSmtpTransport.js +1 -16
- package/transports/createSmtpTransport.js.map +1 -1
- package/transports/index.d.ts +2 -0
- package/transports/index.js +27 -0
- package/transports/index.js.map +1 -0
- package/types.d.ts +1 -1
- package/types.js.map +1 -1
package/crud/settings.crud.js
CHANGED
|
@@ -1,35 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.createSettingsCrud = void 0;
|
|
9
|
-
|
|
10
8
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
11
|
-
|
|
12
9
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
13
|
-
|
|
14
10
|
var _error = _interopRequireDefault(require("@webiny/error"));
|
|
15
|
-
|
|
16
11
|
var _pubsub = require("@webiny/pubsub");
|
|
17
|
-
|
|
18
12
|
var _model = require("./settings/model");
|
|
19
|
-
|
|
20
13
|
var _transform = require("./settings/transform");
|
|
21
|
-
|
|
22
14
|
var _secret = require("./settings/secret");
|
|
23
|
-
|
|
24
15
|
var _validation = require("./settings/validation");
|
|
25
|
-
|
|
26
16
|
var _hooks = require("./settings/hooks");
|
|
27
|
-
|
|
28
17
|
var _apiSecurity = require("@webiny/api-security");
|
|
29
|
-
|
|
30
18
|
const _excluded = ["password"],
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
_excluded2 = ["password"];
|
|
20
|
+
const defaultPort = 25;
|
|
33
21
|
/**
|
|
34
22
|
* Note that settings cannot be used if there is no secret defined.
|
|
35
23
|
*/
|
|
@@ -38,73 +26,60 @@ const createSettingsCrud = async context => {
|
|
|
38
26
|
* We need to remove password from all references on create and update in the CMS.
|
|
39
27
|
*/
|
|
40
28
|
(0, _hooks.attachPasswordObfuscatingHooks)(context);
|
|
41
|
-
|
|
42
29
|
const getTenant = () => {
|
|
43
30
|
return context.tenancy.getCurrentTenant().id;
|
|
44
31
|
};
|
|
45
|
-
|
|
46
32
|
const validateAccess = async () => {
|
|
47
33
|
const permission = await context.security.getPermission("mailer.settings");
|
|
48
|
-
|
|
49
34
|
if (permission) {
|
|
50
35
|
return;
|
|
51
36
|
}
|
|
52
|
-
|
|
53
37
|
throw new _apiSecurity.NotAuthorizedError({
|
|
54
38
|
data: {
|
|
55
39
|
reason: `Not allowed to update the mailer settings.`
|
|
56
40
|
}
|
|
57
41
|
});
|
|
58
42
|
};
|
|
59
|
-
|
|
60
43
|
let secret = null;
|
|
61
|
-
|
|
62
44
|
try {
|
|
63
45
|
secret = (0, _secret.getSecret)();
|
|
64
46
|
} catch (ex) {}
|
|
65
|
-
|
|
66
47
|
const getModel = async () => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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);
|
|
73
56
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
context.security.enableAuthorization();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
throw new _error.default(`Missing CMS Model "${_model.SETTINGS_MODEL_ID}".`, "CMS_MODEL_MISSING", {
|
|
81
|
-
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
|
+
});
|
|
82
60
|
});
|
|
83
|
-
};
|
|
84
|
-
|
|
61
|
+
};
|
|
85
62
|
|
|
63
|
+
// get
|
|
86
64
|
const onSettingsBeforeGet = (0, _pubsub.createTopic)("mailer.onSettingsBeforeGet");
|
|
87
65
|
const onSettingsAfterGet = (0, _pubsub.createTopic)("mailer.onSettingsAfterGet");
|
|
88
|
-
const onSettingsGetError = (0, _pubsub.createTopic)("mailer.onSettingsCreateError");
|
|
89
|
-
|
|
66
|
+
const onSettingsGetError = (0, _pubsub.createTopic)("mailer.onSettingsCreateError");
|
|
67
|
+
// create
|
|
90
68
|
const onSettingsBeforeCreate = (0, _pubsub.createTopic)("mailer.onSettingsBeforeCreate");
|
|
91
69
|
const onSettingsAfterCreate = (0, _pubsub.createTopic)("mailer.onSettingsAfterCreate");
|
|
92
|
-
const onSettingsCreateError = (0, _pubsub.createTopic)("mailer.onSettingsCreateError");
|
|
93
|
-
|
|
70
|
+
const onSettingsCreateError = (0, _pubsub.createTopic)("mailer.onSettingsCreateError");
|
|
71
|
+
// update
|
|
94
72
|
const onSettingsBeforeUpdate = (0, _pubsub.createTopic)("mailer.onSettingsBeforeUpdate");
|
|
95
73
|
const onSettingsAfterUpdate = (0, _pubsub.createTopic)("mailer.onSettingsAfterUpdate");
|
|
96
74
|
const onSettingsUpdateError = (0, _pubsub.createTopic)("mailer.onSettingsUpdateError");
|
|
97
|
-
|
|
98
75
|
const checkSecret = () => {
|
|
99
76
|
if (secret) {
|
|
100
77
|
return;
|
|
101
78
|
}
|
|
102
|
-
|
|
103
79
|
throw new _error.default("There must be a password secret defined!", "PASSWORD_SECRET_ERROR", {
|
|
104
80
|
description: "To store the Mailer settings, you must have a password secret environment variable defined."
|
|
105
81
|
});
|
|
106
82
|
};
|
|
107
|
-
|
|
108
83
|
return {
|
|
109
84
|
onSettingsAfterGet,
|
|
110
85
|
onSettingsBeforeGet,
|
|
@@ -119,51 +94,44 @@ const createSettingsCrud = async context => {
|
|
|
119
94
|
checkSecret();
|
|
120
95
|
const model = await getModel();
|
|
121
96
|
const tenant = getTenant();
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
+
});
|
|
141
131
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
entry: entry,
|
|
145
|
-
secret
|
|
146
|
-
});
|
|
147
|
-
const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
|
|
148
|
-
password: ""
|
|
149
|
-
});
|
|
150
|
-
await onSettingsAfterGet.publish({
|
|
151
|
-
tenant,
|
|
152
|
-
settings: passwordlessSettings
|
|
153
|
-
});
|
|
154
|
-
return settings;
|
|
155
|
-
} catch (ex) {
|
|
156
|
-
await onSettingsGetError.publish({
|
|
157
|
-
tenant,
|
|
158
|
-
error: ex
|
|
159
|
-
});
|
|
160
|
-
} finally {
|
|
161
|
-
context.security.enableAuthorization();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return null;
|
|
132
|
+
return null;
|
|
133
|
+
});
|
|
165
134
|
},
|
|
166
|
-
|
|
167
135
|
/**
|
|
168
136
|
* Method should not be used outside of mailer
|
|
169
137
|
* @internal
|
|
@@ -175,57 +143,45 @@ const createSettingsCrud = async context => {
|
|
|
175
143
|
input
|
|
176
144
|
} = params;
|
|
177
145
|
const model = await getModel();
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const error = result.error;
|
|
182
|
-
|
|
183
|
-
if (error) {
|
|
146
|
+
const result = _validation.createValidation.safeParse(input);
|
|
147
|
+
if (!result.success) {
|
|
184
148
|
throw new _error.default("Validation failed!", "VALIDATION_ERROR", {
|
|
185
|
-
errors: error.
|
|
149
|
+
errors: result.error.errors
|
|
186
150
|
});
|
|
187
151
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
settings = (0, _objectWithoutProperties2.default)(_result$value, _excluded);
|
|
194
|
-
|
|
195
|
-
if (!settings.port) {
|
|
196
|
-
settings.port = 25;
|
|
197
|
-
}
|
|
198
|
-
|
|
152
|
+
const _result$data = result.data,
|
|
153
|
+
{
|
|
154
|
+
password
|
|
155
|
+
} = _result$data,
|
|
156
|
+
settings = (0, _objectWithoutProperties2.default)(_result$data, _excluded);
|
|
199
157
|
const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
|
|
158
|
+
port: settings.port || defaultPort,
|
|
200
159
|
password: ""
|
|
201
160
|
});
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
context.security.enableAuthorization();
|
|
226
|
-
}
|
|
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
|
+
});
|
|
227
184
|
},
|
|
228
|
-
|
|
229
185
|
/**
|
|
230
186
|
* Method should not be used outside of mailer
|
|
231
187
|
* @internal
|
|
@@ -238,94 +194,75 @@ const createSettingsCrud = async context => {
|
|
|
238
194
|
original: initialOriginal
|
|
239
195
|
} = params;
|
|
240
196
|
const model = await getModel();
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const error = result.error;
|
|
245
|
-
|
|
246
|
-
if (error) {
|
|
197
|
+
const result = _validation.updateValidation.safeParse(input);
|
|
198
|
+
if (!result.success) {
|
|
247
199
|
throw new _error.default("Validation failed!", "VALIDATION_ERROR", {
|
|
248
|
-
errors: error.
|
|
200
|
+
errors: result.error.errors
|
|
249
201
|
});
|
|
250
202
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (!original) {
|
|
255
|
-
original = await this.getSettings();
|
|
256
|
-
|
|
257
|
-
if (!original) {
|
|
258
|
-
throw new _error.default(`You are trying to update settings, but there is no existing record. Create it first!`, "NOT_FOUND");
|
|
259
|
-
}
|
|
203
|
+
let dbOriginal = null;
|
|
204
|
+
if (!initialOriginal) {
|
|
205
|
+
dbOriginal = await this.getSettings();
|
|
260
206
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
password
|
|
265
|
-
} = _result$value2,
|
|
266
|
-
settings = (0, _objectWithoutProperties2.default)(_result$value2, _excluded2);
|
|
267
|
-
|
|
268
|
-
if (!settings.port) {
|
|
269
|
-
settings.port = original.port || 25;
|
|
207
|
+
const original = initialOriginal || dbOriginal;
|
|
208
|
+
if (!original) {
|
|
209
|
+
throw new _error.default(`You are trying to update settings, but there is no existing record. Create it first!`, "NOT_FOUND");
|
|
270
210
|
}
|
|
271
|
-
|
|
211
|
+
const _result$data2 = result.data,
|
|
212
|
+
{
|
|
213
|
+
password
|
|
214
|
+
} = _result$data2,
|
|
215
|
+
settings = (0, _objectWithoutProperties2.default)(_result$data2, _excluded2);
|
|
272
216
|
const passwordlessSettings = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, settings), {}, {
|
|
217
|
+
port: settings.port || original.port || defaultPort,
|
|
273
218
|
password: ""
|
|
274
219
|
});
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
} finally {
|
|
306
|
-
context.security.enableAuthorization();
|
|
307
|
-
}
|
|
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
|
+
});
|
|
308
250
|
},
|
|
309
|
-
|
|
310
251
|
async saveSettings(params) {
|
|
311
252
|
const {
|
|
312
253
|
input
|
|
313
254
|
} = params;
|
|
314
255
|
const original = await this.getSettings();
|
|
315
|
-
|
|
316
256
|
if (!original) {
|
|
317
257
|
return this.createSettings({
|
|
318
258
|
input
|
|
319
259
|
});
|
|
320
260
|
}
|
|
321
|
-
|
|
322
261
|
return this.updateSettings({
|
|
323
262
|
input,
|
|
324
263
|
original
|
|
325
264
|
});
|
|
326
265
|
}
|
|
327
|
-
|
|
328
266
|
};
|
|
329
267
|
};
|
|
330
|
-
|
|
331
268
|
exports.createSettingsCrud = createSettingsCrud;
|
|
@@ -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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"}
|
|
@@ -1,37 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.attachOnTransportBeforeSend = void 0;
|
|
9
|
-
|
|
10
|
-
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
11
|
-
|
|
12
|
-
var _joi = _interopRequireDefault(require("joi"));
|
|
13
|
-
|
|
14
8
|
var _error = _interopRequireDefault(require("@webiny/error"));
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
replyTo: _joi.default.string().email(options),
|
|
31
|
-
text: requiredString.min(10),
|
|
32
|
-
html: _joi.default.string()
|
|
33
|
-
});
|
|
34
|
-
|
|
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.");
|
|
35
24
|
const attachOnTransportBeforeSend = params => {
|
|
36
25
|
const {
|
|
37
26
|
onTransportBeforeSend
|
|
@@ -40,14 +29,23 @@ const attachOnTransportBeforeSend = params => {
|
|
|
40
29
|
data: input
|
|
41
30
|
}) => {
|
|
42
31
|
let result;
|
|
43
|
-
|
|
44
32
|
try {
|
|
45
|
-
result =
|
|
46
|
-
|
|
47
|
-
if (!result.error) {
|
|
33
|
+
result = schema.safeParse(input);
|
|
34
|
+
if (result.success) {
|
|
48
35
|
return;
|
|
49
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
|
+
});
|
|
50
45
|
} catch (ex) {
|
|
46
|
+
if (ex instanceof _error.default) {
|
|
47
|
+
throw ex;
|
|
48
|
+
}
|
|
51
49
|
throw new _error.default({
|
|
52
50
|
message: "Error while validating e-mail params.",
|
|
53
51
|
code: "VALIDATION_ERROR",
|
|
@@ -57,13 +55,6 @@ const attachOnTransportBeforeSend = params => {
|
|
|
57
55
|
}
|
|
58
56
|
});
|
|
59
57
|
}
|
|
60
|
-
|
|
61
|
-
throw new _error.default({
|
|
62
|
-
message: "Error while validating e-mail params.",
|
|
63
|
-
code: "VALIDATION_ERROR",
|
|
64
|
-
data: (0, _objectSpread2.default)({}, result.error)
|
|
65
|
-
});
|
|
66
58
|
});
|
|
67
59
|
};
|
|
68
|
-
|
|
69
60
|
exports.attachOnTransportBeforeSend = attachOnTransportBeforeSend;
|