idea-aws 3.6.2 → 3.7.2
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/.eslintrc.js +14 -138
- package/dist/index.d.ts +11 -10
- package/dist/index.js +14 -2018
- package/dist/{attachments.d.ts → src/attachments.d.ts} +0 -0
- package/dist/src/attachments.js +45 -0
- package/dist/{cognito.d.ts → src/cognito.d.ts} +16 -11
- package/dist/src/cognito.js +251 -0
- package/dist/{comprehend.d.ts → src/comprehend.d.ts} +0 -0
- package/dist/src/comprehend.js +28 -0
- package/dist/{dynamoDB.d.ts → src/dynamoDB.d.ts} +16 -19
- package/dist/src/dynamoDB.js +308 -0
- package/dist/{genericController.d.ts → src/genericController.d.ts} +0 -0
- package/dist/src/genericController.js +112 -0
- package/dist/{resourceController.d.ts → src/resourceController.d.ts} +8 -4
- package/dist/src/resourceController.js +369 -0
- package/dist/{s3.d.ts → src/s3.d.ts} +1 -1
- package/dist/src/s3.js +144 -0
- package/dist/{ses.d.ts → src/ses.d.ts} +2 -1
- package/dist/src/ses.js +89 -0
- package/dist/{sns.d.ts → src/sns.d.ts} +1 -1
- package/dist/src/sns.js +70 -0
- package/dist/{streamController.d.ts → src/streamController.d.ts} +0 -0
- package/dist/src/streamController.js +16 -0
- package/dist/{translate.d.ts → src/translate.d.ts} +3 -0
- package/dist/src/translate.js +128 -0
- package/index.ts +12 -0
- package/package.json +19 -25
- package/webpack.config.js +0 -18
package/dist/index.js
CHANGED
|
@@ -1,974 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
-
module.exports = factory();
|
|
4
|
-
else if(typeof define === 'function' && define.amd)
|
|
5
|
-
define([], factory);
|
|
6
|
-
else {
|
|
7
|
-
var a = factory();
|
|
8
|
-
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
|
|
9
|
-
}
|
|
10
|
-
})(global, function() {
|
|
11
|
-
return /******/ (() => { // webpackBootstrap
|
|
12
|
-
/******/ "use strict";
|
|
13
|
-
/******/ var __webpack_modules__ = ({
|
|
14
|
-
|
|
15
|
-
/***/ 490:
|
|
16
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
20
|
-
exports.Attachments = void 0;
|
|
21
|
-
const dynamoDB_1 = __webpack_require__(823);
|
|
22
|
-
const s3_1 = __webpack_require__(216);
|
|
23
|
-
/**
|
|
24
|
-
* A custom class that takes advantage of DynamoDB and S3 to easily manage attachments.
|
|
25
|
-
*/
|
|
26
|
-
class Attachments {
|
|
27
|
-
constructor() {
|
|
28
|
-
/**
|
|
29
|
-
* The bucket where from to retrieve the attachments. Fallback to IDEA's default one.
|
|
30
|
-
*/
|
|
31
|
-
this.S3_ATTACHMENTS_BUCKET = process.env['S3_ATTACHMENTS_BUCKET'] || 'idea-attachments';
|
|
32
|
-
this.IUID_ATTACHMENTS_PREFIX = process.env['IUID_ATTACHMENTS_PREFIX'] || 'ATT';
|
|
33
|
-
this.dynamo = new dynamoDB_1.DynamoDB();
|
|
34
|
-
this.s3 = new s3_1.S3();
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Get a signedURL to put an attachment.
|
|
38
|
-
*/
|
|
39
|
-
put(project, teamId) {
|
|
40
|
-
return new Promise((resolve, reject) => {
|
|
41
|
-
this.dynamo
|
|
42
|
-
.IUID(this.IUID_ATTACHMENTS_PREFIX.concat('_').concat(project).concat('_').concat(teamId))
|
|
43
|
-
.then(attachmentId => {
|
|
44
|
-
const signedURL = this.s3.signedURLPut(this.S3_ATTACHMENTS_BUCKET, attachmentId);
|
|
45
|
-
signedURL.id = attachmentId;
|
|
46
|
-
resolve(signedURL);
|
|
47
|
-
})
|
|
48
|
-
.catch(err => reject(err));
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Get a signedURL to retrieve an attachment.
|
|
53
|
-
*/
|
|
54
|
-
get(attachmentId) {
|
|
55
|
-
const signedURL = this.s3.signedURLGet(this.S3_ATTACHMENTS_BUCKET, attachmentId);
|
|
56
|
-
signedURL.id = attachmentId;
|
|
57
|
-
return signedURL;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
exports.Attachments = Attachments;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
/***/ }),
|
|
64
|
-
|
|
65
|
-
/***/ 920:
|
|
66
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
70
|
-
exports.Cognito = void 0;
|
|
71
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
72
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
73
|
-
/**
|
|
74
|
-
* A wrapper for AWS Cognito.
|
|
75
|
-
*/
|
|
76
|
-
class Cognito {
|
|
77
|
-
constructor() {
|
|
78
|
-
this.cognito = new aws_sdk_1.CognitoIdentityServiceProvider({ apiVersion: '2016-04-18' });
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Change the region in which to find the user pool.
|
|
82
|
-
* Default: the runner's (e.g. Lambda function) region.
|
|
83
|
-
*/
|
|
84
|
-
setRegion(region) {
|
|
85
|
-
// there is no quick way to change the region without re-creating the object
|
|
86
|
-
this.cognito = new aws_sdk_1.CognitoIdentityServiceProvider({ apiVersion: this.cognito.config.apiVersion, region });
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Get the attributes of the user, from the authorizer claims.
|
|
90
|
-
* @param claims authorizer claims
|
|
91
|
-
* @return user's data
|
|
92
|
-
*/
|
|
93
|
-
getUserByClaims(claims) {
|
|
94
|
-
if (!claims)
|
|
95
|
-
return null;
|
|
96
|
-
const user = {};
|
|
97
|
-
// add any additional cognito attribute available in cognito
|
|
98
|
-
for (const p in claims)
|
|
99
|
-
if (p.startsWith('cognito:'))
|
|
100
|
-
user[p.slice(8)] = claims[p];
|
|
101
|
-
// map the important attributes with reserved names
|
|
102
|
-
user.userId = claims.sub;
|
|
103
|
-
user.email = claims.email;
|
|
104
|
-
return user;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Identify a user by its email address, returning its attributes.
|
|
108
|
-
*/
|
|
109
|
-
getUserByEmail(email, cognitoUserPoolId) {
|
|
110
|
-
return new Promise((resolve, reject) => {
|
|
111
|
-
// find the user by the email
|
|
112
|
-
this.cognito.adminGetUser({ UserPoolId: cognitoUserPoolId, Username: email }, (err, data) => {
|
|
113
|
-
if (err || !data)
|
|
114
|
-
reject(err);
|
|
115
|
-
else {
|
|
116
|
-
// convert and return the attributes
|
|
117
|
-
const userAttributes = {};
|
|
118
|
-
data.UserAttributes.forEach((a) => (userAttributes[a.Name] = a.Value));
|
|
119
|
-
resolve(userAttributes);
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Identify a user by its userId (sub), returning its attributes.
|
|
126
|
-
*/
|
|
127
|
-
getUserBySub(sub, cognitoUserPoolId) {
|
|
128
|
-
return new Promise((resolve, reject) => {
|
|
129
|
-
// find the user by the sub
|
|
130
|
-
this.cognito.listUsers({ UserPoolId: cognitoUserPoolId, Filter: `sub = "${sub}"`, Limit: 1 }, (err, data) => {
|
|
131
|
-
if (err || !data || !data.Users || !data.Users[0])
|
|
132
|
-
reject(err);
|
|
133
|
-
else {
|
|
134
|
-
// convert and return the attributes
|
|
135
|
-
const userAttributes = {};
|
|
136
|
-
data.Users[0].Attributes.forEach((a) => (userAttributes[a.Name] = a.Value));
|
|
137
|
-
resolve(userAttributes);
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Create a new user (by its email) in the pool specified.
|
|
144
|
-
* @return userId of the new user
|
|
145
|
-
*/
|
|
146
|
-
createUser(email, cognitoUserPoolId, options) {
|
|
147
|
-
return new Promise((resolve, reject) => {
|
|
148
|
-
options = options || {};
|
|
149
|
-
if (idea_toolbox_1.isEmpty(email, 'email'))
|
|
150
|
-
return reject(new Error('INVALID_EMAIL'));
|
|
151
|
-
const attributes = [
|
|
152
|
-
{ Name: 'email', Value: email },
|
|
153
|
-
{ Name: 'email_verified', Value: 'true' }
|
|
154
|
-
];
|
|
155
|
-
const params = {
|
|
156
|
-
UserPoolId: cognitoUserPoolId,
|
|
157
|
-
Username: email,
|
|
158
|
-
UserAttributes: attributes
|
|
159
|
-
};
|
|
160
|
-
if (options.skipNotification)
|
|
161
|
-
params.MessageAction = 'SUPPRESS';
|
|
162
|
-
if (options.temporaryPassword)
|
|
163
|
-
params.TemporaryPassword = options.temporaryPassword;
|
|
164
|
-
this.cognito.adminCreateUser(params, (err, data) => {
|
|
165
|
-
idea_toolbox_1.logger('COGNITO CREATE USER', err);
|
|
166
|
-
if (err)
|
|
167
|
-
switch (err.name) {
|
|
168
|
-
case 'UsernameExistsException':
|
|
169
|
-
return reject(new Error('USERNAME_ALREADY_EXISTS'));
|
|
170
|
-
case 'InvalidPasswordException':
|
|
171
|
-
return reject(new Error('INVALID_PASSWORD'));
|
|
172
|
-
default:
|
|
173
|
-
return reject(err);
|
|
174
|
-
}
|
|
175
|
-
const userId = data.User.Attributes.find((attr) => attr.Name === 'sub').Value || null;
|
|
176
|
-
if (userId)
|
|
177
|
-
resolve(userId);
|
|
178
|
-
else
|
|
179
|
-
reject(new Error('CREATION_FAILED'));
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Resend the password to a user who never logged in.
|
|
185
|
-
*/
|
|
186
|
-
resendPassword(email, cognitoUserPoolId, options) {
|
|
187
|
-
return new Promise((resolve, reject) => {
|
|
188
|
-
options = options || {};
|
|
189
|
-
if (idea_toolbox_1.isEmpty(email, 'email'))
|
|
190
|
-
return reject(new Error('INVALID_EMAIL'));
|
|
191
|
-
const params = {
|
|
192
|
-
UserPoolId: cognitoUserPoolId,
|
|
193
|
-
Username: email,
|
|
194
|
-
MessageAction: 'RESEND'
|
|
195
|
-
};
|
|
196
|
-
if (options.temporaryPassword)
|
|
197
|
-
params.TemporaryPassword = options.temporaryPassword;
|
|
198
|
-
this.cognito.adminCreateUser(params, (err) => {
|
|
199
|
-
idea_toolbox_1.logger('COGNITO RESEND PASSWORD', err);
|
|
200
|
-
if (err)
|
|
201
|
-
switch (err.name) {
|
|
202
|
-
case 'UnsupportedUserStateException':
|
|
203
|
-
return reject(new Error('USER_ALREADY_CONFIRMED_PASSWORD'));
|
|
204
|
-
default:
|
|
205
|
-
return reject(err);
|
|
206
|
-
}
|
|
207
|
-
else
|
|
208
|
-
resolve();
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Delete a user by its email (username), in the pool specified.
|
|
214
|
-
*/
|
|
215
|
-
deleteUser(email, cognitoUserPoolId) {
|
|
216
|
-
return new Promise((resolve, reject) => {
|
|
217
|
-
if (idea_toolbox_1.isEmpty(email, 'email'))
|
|
218
|
-
return reject(new Error('INVALID_EMAIL'));
|
|
219
|
-
this.cognito.adminDeleteUser({ UserPoolId: cognitoUserPoolId, Username: email }, (err) => {
|
|
220
|
-
idea_toolbox_1.logger('COGNITO DELETE USER', err);
|
|
221
|
-
if (err)
|
|
222
|
-
reject(new Error('DELETION_FAILED'));
|
|
223
|
-
else
|
|
224
|
-
resolve();
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Sign in a user of a specific pool through username and password.
|
|
230
|
-
*/
|
|
231
|
-
signIn(email, password, cognitoUserPoolId, cognitoUserPoolClientId) {
|
|
232
|
-
return new Promise((resolve, reject) => {
|
|
233
|
-
this.cognito.adminInitiateAuth({
|
|
234
|
-
UserPoolId: cognitoUserPoolId,
|
|
235
|
-
ClientId: cognitoUserPoolClientId,
|
|
236
|
-
AuthFlow: 'ADMIN_NO_SRP_AUTH',
|
|
237
|
-
AuthParameters: { USERNAME: email, PASSWORD: password }
|
|
238
|
-
}, (err, data) => {
|
|
239
|
-
idea_toolbox_1.logger('COGNITO SIGN IN', err);
|
|
240
|
-
if (err || !data.AuthenticationResult)
|
|
241
|
-
reject(err);
|
|
242
|
-
else
|
|
243
|
-
resolve(data.AuthenticationResult);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Given a username and a refresh token (and pool data), refresh the session and return the new tokens.
|
|
249
|
-
*/
|
|
250
|
-
refreshSession(email, refreshToken, cognitoUserPoolId, cognitoUserPoolClientId) {
|
|
251
|
-
return new Promise((resolve, reject) => {
|
|
252
|
-
this.cognito.adminInitiateAuth({
|
|
253
|
-
UserPoolId: cognitoUserPoolId,
|
|
254
|
-
ClientId: cognitoUserPoolClientId,
|
|
255
|
-
AuthFlow: 'REFRESH_TOKEN_AUTH',
|
|
256
|
-
AuthParameters: { USERNAME: email, REFRESH_TOKEN: refreshToken }
|
|
257
|
-
}, (err, data) => {
|
|
258
|
-
idea_toolbox_1.logger('COGNITO REFRESH TOKEN', err);
|
|
259
|
-
if (err || !data.AuthenticationResult)
|
|
260
|
-
reject(err);
|
|
261
|
-
else
|
|
262
|
-
resolve(data.AuthenticationResult);
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Change the email address (== username) associated to a user.
|
|
268
|
-
*/
|
|
269
|
-
updateEmail(email, newEmail, cognitoUserPoolId) {
|
|
270
|
-
return new Promise((resolve, reject) => {
|
|
271
|
-
if (idea_toolbox_1.isEmpty(newEmail, 'email'))
|
|
272
|
-
return reject(new Error('INVALID_NEW_EMAIL'));
|
|
273
|
-
this.cognito.adminUpdateUserAttributes({
|
|
274
|
-
UserPoolId: cognitoUserPoolId,
|
|
275
|
-
Username: email,
|
|
276
|
-
UserAttributes: [
|
|
277
|
-
{ Name: 'email', Value: newEmail },
|
|
278
|
-
{ Name: 'email_verified', Value: 'true' }
|
|
279
|
-
]
|
|
280
|
-
}, (err) => {
|
|
281
|
-
idea_toolbox_1.logger('COGNITO UPDATE EMAIL', err);
|
|
282
|
-
if (err)
|
|
283
|
-
reject(err);
|
|
284
|
-
// sign out the user from all its devices and resolve
|
|
285
|
-
else
|
|
286
|
-
this.globalSignOut(newEmail, cognitoUserPoolId)
|
|
287
|
-
.then(() => resolve())
|
|
288
|
-
.catch(e => reject(e));
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Change the password to sign in for a user.
|
|
294
|
-
*/
|
|
295
|
-
updatePassword(email, oldPassword, newPassword, cognitoUserPoolId, cognitoUserPoolClientId) {
|
|
296
|
-
return new Promise((resolve, reject) => {
|
|
297
|
-
if (newPassword.length < 8)
|
|
298
|
-
return reject(new Error('INVALID_NEW_PASSWORD'));
|
|
299
|
-
// get a token to run the password change
|
|
300
|
-
this.signIn(email, oldPassword, cognitoUserPoolId, cognitoUserPoolClientId)
|
|
301
|
-
.then((data) => {
|
|
302
|
-
// request the password change
|
|
303
|
-
this.cognito.changePassword({
|
|
304
|
-
AccessToken: data.AccessToken,
|
|
305
|
-
PreviousPassword: oldPassword,
|
|
306
|
-
ProposedPassword: newPassword
|
|
307
|
-
}, (err) => {
|
|
308
|
-
idea_toolbox_1.logger('COGNITO UPDATE PASSWORD', err);
|
|
309
|
-
if (err)
|
|
310
|
-
reject(err);
|
|
311
|
-
else
|
|
312
|
-
resolve();
|
|
313
|
-
});
|
|
314
|
-
})
|
|
315
|
-
.catch(err => reject(err));
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Sign out the user from all devices.
|
|
320
|
-
*/
|
|
321
|
-
globalSignOut(email, cognitoUserPoolId) {
|
|
322
|
-
return new Promise((resolve, reject) => {
|
|
323
|
-
this.cognito.adminUserGlobalSignOut({ Username: email, UserPoolId: cognitoUserPoolId }, (err) => {
|
|
324
|
-
idea_toolbox_1.logger('COGNITO GLOBAL SIGN OUT', err);
|
|
325
|
-
if (err)
|
|
326
|
-
reject(err);
|
|
327
|
-
else
|
|
328
|
-
resolve();
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Confirm and conclude a registration, usign a confirmation code.
|
|
334
|
-
*/
|
|
335
|
-
confirmSignUp(email, confirmationCode, cognitoUserPoolClientId) {
|
|
336
|
-
return new Promise((resolve, reject) => {
|
|
337
|
-
if (!email)
|
|
338
|
-
return reject(new Error('INVALID_EMAIL'));
|
|
339
|
-
if (!confirmationCode)
|
|
340
|
-
return reject(new Error('INVALID_CONFIRMATION_CODE'));
|
|
341
|
-
if (!cognitoUserPoolClientId)
|
|
342
|
-
return reject(new Error('INVALID_CLIENT_ID'));
|
|
343
|
-
// conclude the registration (sign-up) flow, using a provided confirmation code
|
|
344
|
-
this.cognito.confirmSignUp({ Username: email, ConfirmationCode: confirmationCode, ClientId: cognitoUserPoolClientId }, (err) => {
|
|
345
|
-
idea_toolbox_1.logger('COGNITO CONFIRM SIGN UP', err);
|
|
346
|
-
if (err)
|
|
347
|
-
reject(err);
|
|
348
|
-
else
|
|
349
|
-
resolve();
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* List the groups of the user pool.
|
|
355
|
-
*/
|
|
356
|
-
listGroups(cognitoUserPoolId) {
|
|
357
|
-
return new Promise((resolve, reject) => {
|
|
358
|
-
this.cognito.listGroups({ UserPoolId: cognitoUserPoolId }, (err, data) => {
|
|
359
|
-
idea_toolbox_1.logger('COGNITO LIST GROUPS', err);
|
|
360
|
-
if (err)
|
|
361
|
-
return reject(err);
|
|
362
|
-
const groups = data.Groups.map(g => ({ name: g.GroupName, description: g.Description }));
|
|
363
|
-
resolve(groups);
|
|
364
|
-
});
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* List the users part of a group in the user pool.
|
|
369
|
-
*/
|
|
370
|
-
listUsersInGroup(group, cognitoUserPoolId) {
|
|
371
|
-
return new Promise((resolve, reject) => {
|
|
372
|
-
this.cognito.listUsersInGroup({ UserPoolId: cognitoUserPoolId, GroupName: group }, (err, data) => {
|
|
373
|
-
idea_toolbox_1.logger('COGNITO LIST USERS IN GROUP', err);
|
|
374
|
-
if (err)
|
|
375
|
-
return reject(err);
|
|
376
|
-
// convert the Cognito Users into the IDEA Users format
|
|
377
|
-
const users = data.Users.map(u => {
|
|
378
|
-
const userAttributes = {};
|
|
379
|
-
u.Attributes.forEach((a) => (userAttributes[a.Name] = a.Value));
|
|
380
|
-
return new idea_toolbox_1.User({ userId: userAttributes.sub, email: userAttributes.email, createdAt: u.UserCreateDate });
|
|
381
|
-
});
|
|
382
|
-
resolve(users);
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Add a user (by email) to a group in the user pool.
|
|
388
|
-
*/
|
|
389
|
-
addUserToGroup(email, group, cognitoUserPoolId) {
|
|
390
|
-
return new Promise((resolve, reject) => {
|
|
391
|
-
this.getUserByEmail(email, cognitoUserPoolId).then(userData => {
|
|
392
|
-
const user = new idea_toolbox_1.User({ userId: userData.sub, email: userData.email });
|
|
393
|
-
this.cognito.adminAddUserToGroup({ UserPoolId: cognitoUserPoolId, GroupName: group, Username: user.userId }, err => {
|
|
394
|
-
idea_toolbox_1.logger('COGNITO ADD USER TO GROUP', err);
|
|
395
|
-
if (err)
|
|
396
|
-
reject(err);
|
|
397
|
-
else
|
|
398
|
-
resolve(user);
|
|
399
|
-
});
|
|
400
|
-
});
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* Remove a user (by email) from a group in the user pool.
|
|
405
|
-
*/
|
|
406
|
-
removeUserFromGroup(email, group, cognitoUserPoolId) {
|
|
407
|
-
return new Promise((resolve, reject) => {
|
|
408
|
-
this.getUserByEmail(email, cognitoUserPoolId).then(userData => {
|
|
409
|
-
const user = new idea_toolbox_1.User({ userId: userData.sub, email: userData.email });
|
|
410
|
-
this.cognito.adminRemoveUserFromGroup({ UserPoolId: cognitoUserPoolId, GroupName: group, Username: user.userId }, err => {
|
|
411
|
-
idea_toolbox_1.logger('COGNITO REMOVE USER FROM GROUP', err);
|
|
412
|
-
if (err)
|
|
413
|
-
reject(err);
|
|
414
|
-
else
|
|
415
|
-
resolve(user);
|
|
416
|
-
});
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
exports.Cognito = Cognito;
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
/***/ }),
|
|
425
|
-
|
|
426
|
-
/***/ 132:
|
|
427
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
431
|
-
exports.Comprehend = void 0;
|
|
432
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
433
|
-
/**
|
|
434
|
-
* A wrapper for Amazon Comprehend.
|
|
435
|
-
*/
|
|
436
|
-
class Comprehend {
|
|
437
|
-
constructor() {
|
|
438
|
-
this.comprehend = new aws_sdk_1.Comprehend({ apiVersion: '2017-11-27' });
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* Inspects text and returns an inference of the prevailing sentiment (POSITIVE, NEUTRAL, MIXED, or NEGATIVE).
|
|
442
|
-
*/
|
|
443
|
-
detectSentiment(params) {
|
|
444
|
-
return new Promise((resolve, reject) => {
|
|
445
|
-
// check for obligatory params
|
|
446
|
-
if (!params.language || !params.text)
|
|
447
|
-
return reject(new Error('MISSING_PARAMETERS'));
|
|
448
|
-
// execute the sentiment detection
|
|
449
|
-
this.comprehend.detectSentiment({ LanguageCode: params.language, Text: params.text }, (err, data) => {
|
|
450
|
-
if (err)
|
|
451
|
-
reject(err);
|
|
452
|
-
else
|
|
453
|
-
resolve(data.Sentiment);
|
|
454
|
-
});
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
exports.Comprehend = Comprehend;
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
/***/ }),
|
|
462
|
-
|
|
463
|
-
/***/ 823:
|
|
464
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
468
|
-
exports.DynamoDB = void 0;
|
|
469
|
-
const UUIDV4 = __webpack_require__(180);
|
|
470
|
-
const nanoid_1 = __webpack_require__(324);
|
|
471
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
472
|
-
const shortid_1 = __webpack_require__(942);
|
|
473
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
474
|
-
/**
|
|
475
|
-
* A wrapper for AWS DynamoDB.
|
|
476
|
-
*/
|
|
477
|
-
class DynamoDB {
|
|
478
|
-
/**
|
|
479
|
-
* Initialize a new DynamoDB helper object.
|
|
480
|
-
*/
|
|
481
|
-
constructor() {
|
|
482
|
-
this.dynamo = new aws_sdk_1.DynamoDB.DocumentClient();
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Convert a JSON object from dynamoDB format to simple JSON.
|
|
486
|
-
*/
|
|
487
|
-
unmarshall(data, options) {
|
|
488
|
-
return aws_sdk_1.DynamoDB.Converter.unmarshall(data, options);
|
|
489
|
-
}
|
|
490
|
-
/**
|
|
491
|
-
* Returns an IUID: IDEA's Unique IDentifier, which is an id unique through all IDEA's projects.
|
|
492
|
-
* Note: there's no need of an authorization check for extrernal uses: the permissions depend
|
|
493
|
-
* from the context in which it's executed.
|
|
494
|
-
* @deprecated use IUNID instead (nano version)
|
|
495
|
-
* @param project project code
|
|
496
|
-
* @return the IUID
|
|
497
|
-
*/
|
|
498
|
-
IUID(project) {
|
|
499
|
-
const MAX_ATTEMPTS = 3;
|
|
500
|
-
return new Promise((resolve, reject) => {
|
|
501
|
-
if (!project)
|
|
502
|
-
reject();
|
|
503
|
-
else
|
|
504
|
-
this.iuidHelper(project, 0, MAX_ATTEMPTS, resolve, reject);
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
iuidHelper(project, attempt, maxAttempts, resolve, reject) {
|
|
508
|
-
if (attempt > maxAttempts)
|
|
509
|
-
reject();
|
|
510
|
-
else {
|
|
511
|
-
const id = UUIDV4();
|
|
512
|
-
this.put({
|
|
513
|
-
TableName: 'idea_IUID',
|
|
514
|
-
Item: { project, id },
|
|
515
|
-
ConditionExpression: 'NOT (#p = :project AND #id = :id)',
|
|
516
|
-
ExpressionAttributeNames: { '#p': 'project', '#id': 'id' },
|
|
517
|
-
ExpressionAttributeValues: { ':project': project, ':id': id }
|
|
518
|
-
})
|
|
519
|
-
.then(() => resolve(`${project}_${id}`))
|
|
520
|
-
.catch(() =>
|
|
521
|
-
// ID exists, try again
|
|
522
|
-
this.iuidHelper(project, attempt + 1, maxAttempts, resolve, reject));
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Returns an IUNID: IDEA's Unique Nano IDentifier, which is an id unique through all IDEA's projects.
|
|
527
|
-
* Note: no need of an auth check for external uses: the permissions depend from the context in which it's executed.
|
|
528
|
-
* @param project project code
|
|
529
|
-
* @return the IUNID
|
|
530
|
-
*/
|
|
531
|
-
IUNID(project) {
|
|
532
|
-
const MAX_ATTEMPTS = 3;
|
|
533
|
-
return new Promise((resolve, reject) => {
|
|
534
|
-
if (!project)
|
|
535
|
-
reject();
|
|
536
|
-
else
|
|
537
|
-
this.iunidHelper(project, 0, MAX_ATTEMPTS, resolve, reject);
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
iunidHelper(project, attempt, maxAttempts, resolve, reject) {
|
|
541
|
-
if (attempt > maxAttempts)
|
|
542
|
-
reject();
|
|
543
|
-
else {
|
|
544
|
-
const id = nanoid_1.nanoid();
|
|
545
|
-
this.put({
|
|
546
|
-
TableName: 'idea_IUNID',
|
|
547
|
-
Item: { project, id },
|
|
548
|
-
ConditionExpression: 'NOT (#p = :project AND #id = :id)',
|
|
549
|
-
ExpressionAttributeNames: { '#p': 'project', '#id': 'id' },
|
|
550
|
-
ExpressionAttributeValues: { ':project': project, ':id': id }
|
|
551
|
-
})
|
|
552
|
-
.then(() => resolve(`${project}#${id}`))
|
|
553
|
-
.catch(() =>
|
|
554
|
-
// ID exists, try again
|
|
555
|
-
this.iunidHelper(project, attempt + 1, maxAttempts, resolve, reject));
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Returns an ISID: IDEA's Short IDentifier, which is a short, unique id through a single project.
|
|
560
|
-
* Note: there's no need of an authorization check for extrernal uses: the permissions depend
|
|
561
|
-
* from the context in which it's executed.
|
|
562
|
-
* @param project project code
|
|
563
|
-
* @return the ISID
|
|
564
|
-
*/
|
|
565
|
-
ISID(project) {
|
|
566
|
-
const MAX_ATTEMPTS = 3;
|
|
567
|
-
// avoid _ characters (to avoid concatenation problems with ids) -- it must be anyway 64 chars-long
|
|
568
|
-
shortid_1.characters('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-@');
|
|
569
|
-
return new Promise((resolve, reject) => {
|
|
570
|
-
if (!project)
|
|
571
|
-
reject();
|
|
572
|
-
else
|
|
573
|
-
this.isidHelper(project, 0, MAX_ATTEMPTS, resolve, reject);
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
isidHelper(project, attempt, maxAttempts, resolve, reject) {
|
|
577
|
-
if (attempt > maxAttempts)
|
|
578
|
-
reject();
|
|
579
|
-
else {
|
|
580
|
-
const id = shortid_1.generate();
|
|
581
|
-
this.put({
|
|
582
|
-
TableName: 'idea_ISID',
|
|
583
|
-
Item: { project, id },
|
|
584
|
-
ConditionExpression: 'NOT (#p = :project AND #id = :id)',
|
|
585
|
-
ExpressionAttributeNames: { '#p': 'project', '#id': 'id' },
|
|
586
|
-
ExpressionAttributeValues: { ':project': project, ':id': id }
|
|
587
|
-
})
|
|
588
|
-
.then(() => resolve(id))
|
|
589
|
-
.catch(() =>
|
|
590
|
-
// ID exists, try again
|
|
591
|
-
this.isidHelper(project, attempt + 1, maxAttempts, resolve, reject));
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Manage atomic counters (atomic autoincrement values) in IDEA's projects.
|
|
596
|
-
* They key of an atomic counter should be composed as the following: `DynamoDBTableName_uniqueKey`.
|
|
597
|
-
* @param key the key of the counter
|
|
598
|
-
*/
|
|
599
|
-
getAtomicCounterByKey(key) {
|
|
600
|
-
return new Promise((resolve, reject) => {
|
|
601
|
-
idea_toolbox_1.logger('GET ATOMIC COUNTER');
|
|
602
|
-
this.update({
|
|
603
|
-
TableName: 'idea_atomicCounters',
|
|
604
|
-
Key: { key },
|
|
605
|
-
UpdateExpression: 'ADD atomicCounter :increment',
|
|
606
|
-
ExpressionAttributeValues: { ':increment': 1 },
|
|
607
|
-
ReturnValues: 'UPDATED_NEW'
|
|
608
|
-
})
|
|
609
|
-
.then((data) => resolve(data.Attributes.atomicCounter))
|
|
610
|
-
.catch(err => reject(err));
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
/**
|
|
614
|
-
* Get an item of a DynamoDB table.
|
|
615
|
-
*/
|
|
616
|
-
get(params) {
|
|
617
|
-
return new Promise((resolve, reject) => {
|
|
618
|
-
this.dynamo.get(params, (err, data) => {
|
|
619
|
-
idea_toolbox_1.logger(`GET ${params.TableName}`, err);
|
|
620
|
-
if (err || !data.Item)
|
|
621
|
-
reject(err);
|
|
622
|
-
else
|
|
623
|
-
resolve(data.Item);
|
|
624
|
-
});
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
/**
|
|
628
|
-
* Put an item in a DynamoDB table.
|
|
629
|
-
*/
|
|
630
|
-
put(params) {
|
|
631
|
-
return new Promise((resolve, reject) => {
|
|
632
|
-
this.dynamo.put(params, (err, data) => {
|
|
633
|
-
idea_toolbox_1.logger(`PUT ${params.TableName}`, err);
|
|
634
|
-
if (err)
|
|
635
|
-
reject(err);
|
|
636
|
-
else
|
|
637
|
-
resolve(data);
|
|
638
|
-
});
|
|
639
|
-
});
|
|
640
|
-
}
|
|
641
|
-
/**
|
|
642
|
-
* Update an item of a DynamoDB table.
|
|
643
|
-
*/
|
|
644
|
-
update(params) {
|
|
645
|
-
return new Promise((resolve, reject) => {
|
|
646
|
-
this.dynamo.update(params, (err, data) => {
|
|
647
|
-
idea_toolbox_1.logger(`UPDATE ${params.TableName}`, err);
|
|
648
|
-
if (err)
|
|
649
|
-
reject(err);
|
|
650
|
-
else
|
|
651
|
-
resolve(data);
|
|
652
|
-
});
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
/**
|
|
656
|
-
* Delete an item of a DynamoDB table.
|
|
657
|
-
*/
|
|
658
|
-
delete(params) {
|
|
659
|
-
return new Promise((resolve, reject) => {
|
|
660
|
-
this.dynamo.delete(params, (err, data) => {
|
|
661
|
-
idea_toolbox_1.logger(`DELETE ${params.TableName}`, err);
|
|
662
|
-
if (err)
|
|
663
|
-
reject(err);
|
|
664
|
-
else
|
|
665
|
-
resolve(data);
|
|
666
|
-
});
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
/**
|
|
670
|
-
* Get group of items based on their keys from DynamoDb table, avoiding the limits of DynamoDB's BatchGetItem.
|
|
671
|
-
* @param ignoreErr if set, ignore the errors and continue the bulk op.
|
|
672
|
-
*/
|
|
673
|
-
batchGet(table, keys, ignoreErr) {
|
|
674
|
-
return new Promise((resolve, reject) => {
|
|
675
|
-
if (!keys.length) {
|
|
676
|
-
idea_toolbox_1.logger(`BATCH GET ${table}`, null, 'No elements to get');
|
|
677
|
-
resolve([]);
|
|
678
|
-
}
|
|
679
|
-
else
|
|
680
|
-
this.batchGetHelper(table, keys, [], Boolean(ignoreErr), 0, 100, resolve, reject);
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
batchGetHelper(t, keys, elements, iErr, curr, size, resolve, reject) {
|
|
684
|
-
// prepare the structure for the bulk operation
|
|
685
|
-
const batch = { RequestItems: {} };
|
|
686
|
-
batch.RequestItems[t] = { Keys: [] };
|
|
687
|
-
batch.RequestItems[t].Keys = keys.slice(curr, curr + size);
|
|
688
|
-
// execute the bulk operation
|
|
689
|
-
this.dynamo.batchGet(batch, (err, data) => {
|
|
690
|
-
idea_toolbox_1.logger(`BATCH GET ${t}`, err, `${curr} of ${keys.length}`);
|
|
691
|
-
if (err && !iErr)
|
|
692
|
-
return reject(err);
|
|
693
|
-
// concat the results
|
|
694
|
-
elements = elements.concat(data.Responses[t]);
|
|
695
|
-
// if there are still chunks to manage, go on recursively
|
|
696
|
-
if (curr + size < keys.length)
|
|
697
|
-
this.batchGetHelper(t, keys, elements, iErr, curr + size, size, resolve, reject);
|
|
698
|
-
// no more chunks to manage: we're done
|
|
699
|
-
else
|
|
700
|
-
resolve(elements);
|
|
701
|
-
});
|
|
702
|
-
}
|
|
703
|
-
/**
|
|
704
|
-
* Put an array of items in a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
|
|
705
|
-
* @param ignoreErr if true, ignore the errors and continue the bulk op
|
|
706
|
-
*/
|
|
707
|
-
batchPut(table, items, ignoreErr) {
|
|
708
|
-
return new Promise((resolve, reject) => {
|
|
709
|
-
if (!items.length) {
|
|
710
|
-
idea_toolbox_1.logger(`BATCH WRITE (PUT) ${table}`, null, 'No elements to write');
|
|
711
|
-
resolve();
|
|
712
|
-
}
|
|
713
|
-
else
|
|
714
|
-
this.batchWriteHelper(table, items, true, Boolean(ignoreErr), 0, 25, resolve, reject);
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
* Delete an array of items from a DynamoDb table, avoiding the limits of DynamoDB's BatchWriteItem.
|
|
719
|
-
* @param ignoreErr if true, ignore the errors and continue the bulk op.
|
|
720
|
-
*/
|
|
721
|
-
batchDelete(table, keys, ignoreErr) {
|
|
722
|
-
return new Promise((resolve, reject) => {
|
|
723
|
-
if (keys.length === 0) {
|
|
724
|
-
idea_toolbox_1.logger(`BATCH WRITE (DELETE) ${table}`, null, 'No elements to write');
|
|
725
|
-
resolve();
|
|
726
|
-
}
|
|
727
|
-
else
|
|
728
|
-
this.batchWriteHelper(table, keys, false, Boolean(ignoreErr), 0, 25, resolve, reject);
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
batchWriteHelper(t, items, isPut, iErr, curr, size, resolve, reject) {
|
|
732
|
-
// prepare the structure for the bulk operation
|
|
733
|
-
const batch = { RequestItems: {} };
|
|
734
|
-
if (isPut) {
|
|
735
|
-
batch.RequestItems[t] = items.slice(curr, curr + size).map(i => ({ PutRequest: { Item: i } }));
|
|
736
|
-
}
|
|
737
|
-
else {
|
|
738
|
-
// isDelete
|
|
739
|
-
batch.RequestItems[t] = items.slice(curr, curr + size).map(k => ({ DeleteRequest: { Key: k } }));
|
|
740
|
-
}
|
|
741
|
-
// execute the bulk operation
|
|
742
|
-
this.dynamo.batchWrite(batch, (err) => {
|
|
743
|
-
idea_toolbox_1.logger(`BATCH WRITE (${isPut ? 'PUT' : 'DELETE'}) ${t}`, err, `${curr} of ${items.length}`);
|
|
744
|
-
if (err && !iErr)
|
|
745
|
-
reject(err);
|
|
746
|
-
// if there are still chunks to manage, go on recursively
|
|
747
|
-
else if (curr + size < items.length)
|
|
748
|
-
this.batchWriteHelper(t, items, isPut, iErr, curr + size, size, resolve, reject);
|
|
749
|
-
// no more chunks to manage: we're done
|
|
750
|
-
else
|
|
751
|
-
resolve();
|
|
752
|
-
});
|
|
753
|
-
}
|
|
754
|
-
/**
|
|
755
|
-
* Query a DynamoDb table, avoiding the limits of DynamoDB's Query.
|
|
756
|
-
* @param params the params to apply to DynamoDB's function
|
|
757
|
-
*/
|
|
758
|
-
query(params) {
|
|
759
|
-
return new Promise((resolve, reject) => {
|
|
760
|
-
this.queryScanHelper(params, [], true, resolve, reject);
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
/**
|
|
764
|
-
* Scan a DynamoDb table, avoiding the limits of DynamoDB's Query.
|
|
765
|
-
* @param params the params to apply to DynamoDB's function
|
|
766
|
-
*/
|
|
767
|
-
scan(params) {
|
|
768
|
-
return new Promise((resolve, reject) => {
|
|
769
|
-
this.queryScanHelper(params, [], false, resolve, reject);
|
|
770
|
-
});
|
|
771
|
-
}
|
|
772
|
-
queryScanHelper(params, items, isQuery, resolve, reject) {
|
|
773
|
-
const f = isQuery ? 'query' : 'scan';
|
|
774
|
-
this.dynamo[f](params, (err, data) => {
|
|
775
|
-
if (err || !data || !data.Items) {
|
|
776
|
-
idea_toolbox_1.logger(`${f.toUpperCase()} ${params.TableName}`, err);
|
|
777
|
-
return reject(err);
|
|
778
|
-
}
|
|
779
|
-
items = items.concat(data.Items);
|
|
780
|
-
if (data.LastEvaluatedKey) {
|
|
781
|
-
params.ExclusiveStartKey = data.LastEvaluatedKey;
|
|
782
|
-
this.queryScanHelper(params, items, isQuery, resolve, reject);
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
idea_toolbox_1.logger(`${f.toUpperCase()} ${params.TableName}`, null, items.length);
|
|
786
|
-
resolve(items);
|
|
787
|
-
}
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Query a DynamoDb table in the traditional way (no pagination or data mapping).
|
|
792
|
-
* @param params the params to apply to DynamoDB's function
|
|
793
|
-
*/
|
|
794
|
-
queryClassic(params) {
|
|
795
|
-
return new Promise((resolve, reject) => {
|
|
796
|
-
this.queryScanClassicHelper(params, true, resolve, reject);
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
/**
|
|
800
|
-
* Scan a DynamoDb table in the traditional way (no pagination or data mapping).
|
|
801
|
-
* @param params the params to apply to DynamoDB's function
|
|
802
|
-
*/
|
|
803
|
-
scanClassic(params) {
|
|
804
|
-
return new Promise((resolve, reject) => {
|
|
805
|
-
this.queryScanClassicHelper(params, false, resolve, reject);
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
queryScanClassicHelper(params, isQuery, resolve, reject) {
|
|
809
|
-
const f = isQuery ? 'query' : 'scan';
|
|
810
|
-
this.dynamo[f](params, (err, data) => {
|
|
811
|
-
idea_toolbox_1.logger(`${f.toUpperCase()} classic ${params.TableName}`, err, data && data.Items ? data.Items.length : 0);
|
|
812
|
-
if (err || !data)
|
|
813
|
-
reject(err);
|
|
814
|
-
else
|
|
815
|
-
resolve(data);
|
|
816
|
-
});
|
|
817
|
-
}
|
|
818
|
-
/**
|
|
819
|
-
* Execute a series of max 10 write operations in a single transaction.
|
|
820
|
-
* @param ops the operations to execute in the transaction
|
|
821
|
-
*/
|
|
822
|
-
transactWrites(ops) {
|
|
823
|
-
return new Promise((resolve, reject) => {
|
|
824
|
-
if (!ops.length) {
|
|
825
|
-
idea_toolbox_1.logger('TRANSACTION WRITES', null, 'No elements to write');
|
|
826
|
-
resolve();
|
|
827
|
-
}
|
|
828
|
-
else
|
|
829
|
-
this.dynamo.transactWrite({ TransactItems: ops.slice(0, 10) }, (err) => {
|
|
830
|
-
idea_toolbox_1.logger('TRANSACTION WRITES', err);
|
|
831
|
-
if (err)
|
|
832
|
-
reject(err);
|
|
833
|
-
else
|
|
834
|
-
resolve();
|
|
835
|
-
});
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
|
-
* Creates a set of elements (DynamoDB format) inferring the type of set from the type of the first element.
|
|
840
|
-
*/
|
|
841
|
-
createSet(array, options) {
|
|
842
|
-
return this.dynamo.createSet(array, options);
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
exports.DynamoDB = DynamoDB;
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
/***/ }),
|
|
849
|
-
|
|
850
|
-
/***/ 838:
|
|
851
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
855
|
-
exports.GenericController = void 0;
|
|
856
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
857
|
-
const dynamoDB_1 = __webpack_require__(823);
|
|
858
|
-
const cognito_1 = __webpack_require__(920);
|
|
859
|
-
const s3_1 = __webpack_require__(216);
|
|
860
|
-
const ses_1 = __webpack_require__(887);
|
|
861
|
-
const sns_1 = __webpack_require__(187);
|
|
862
|
-
const translate_1 = __webpack_require__(580);
|
|
863
|
-
const comprehend_1 = __webpack_require__(132);
|
|
864
|
-
const attachments_1 = __webpack_require__(490);
|
|
865
|
-
/**
|
|
866
|
-
* An abstract class to inherit to manage some resources with an AWS Lambda function.
|
|
867
|
-
*/
|
|
868
|
-
class GenericController {
|
|
869
|
-
/**
|
|
870
|
-
* Initialize a new GenericController helper object.
|
|
871
|
-
* @param event the event that invoked the AWS lambda function
|
|
872
|
-
* @param callback the callback to resolve or reject the execution
|
|
873
|
-
*/
|
|
874
|
-
constructor(event, callback, options) {
|
|
875
|
-
options = options || {};
|
|
876
|
-
this.event = event;
|
|
877
|
-
this.callback = callback;
|
|
878
|
-
this.tables = options.tables || {};
|
|
879
|
-
// set the logs to print objects deeper
|
|
880
|
-
__webpack_require__(669).inspect.defaultOptions.depth = null;
|
|
881
|
-
}
|
|
882
|
-
/**
|
|
883
|
-
* Default callback for the Lambda.
|
|
884
|
-
*/
|
|
885
|
-
done(err, res) {
|
|
886
|
-
idea_toolbox_1.logger(err ? 'DONE WITH ERRORS' : 'DONE', err, res, true);
|
|
887
|
-
this.callback(err, res);
|
|
888
|
-
}
|
|
889
|
-
///
|
|
890
|
-
/// AWS SERVICES
|
|
891
|
-
///
|
|
892
|
-
get dynamoDB() {
|
|
893
|
-
if (!this._dynamoDB)
|
|
894
|
-
this._dynamoDB = new dynamoDB_1.DynamoDB();
|
|
895
|
-
return this._dynamoDB;
|
|
896
|
-
}
|
|
897
|
-
set dynamoDB(dynamoDB) {
|
|
898
|
-
this._dynamoDB = dynamoDB;
|
|
899
|
-
}
|
|
900
|
-
get cognito() {
|
|
901
|
-
if (!this._cognito)
|
|
902
|
-
this._cognito = new cognito_1.Cognito();
|
|
903
|
-
return this._cognito;
|
|
904
|
-
}
|
|
905
|
-
set cognito(cognito) {
|
|
906
|
-
this._cognito = cognito;
|
|
907
|
-
}
|
|
908
|
-
get s3() {
|
|
909
|
-
if (!this._s3)
|
|
910
|
-
this._s3 = new s3_1.S3();
|
|
911
|
-
return this._s3;
|
|
912
|
-
}
|
|
913
|
-
set s3(s3) {
|
|
914
|
-
this._s3 = s3;
|
|
915
|
-
}
|
|
916
|
-
get ses() {
|
|
917
|
-
if (!this._ses)
|
|
918
|
-
this._ses = new ses_1.SES();
|
|
919
|
-
return this._ses;
|
|
920
|
-
}
|
|
921
|
-
set ses(ses) {
|
|
922
|
-
this._ses = ses;
|
|
923
|
-
}
|
|
924
|
-
get sns() {
|
|
925
|
-
if (!this._sns)
|
|
926
|
-
this._sns = new sns_1.SNS();
|
|
927
|
-
return this._sns;
|
|
928
|
-
}
|
|
929
|
-
set sns(sns) {
|
|
930
|
-
this._sns = sns;
|
|
931
|
-
}
|
|
932
|
-
get translate() {
|
|
933
|
-
if (!this._translate)
|
|
934
|
-
this._translate = new translate_1.Translate();
|
|
935
|
-
return this._translate;
|
|
936
|
-
}
|
|
937
|
-
set translate(translate) {
|
|
938
|
-
this._translate = translate;
|
|
939
|
-
}
|
|
940
|
-
get comprehend() {
|
|
941
|
-
if (!this._comprehend)
|
|
942
|
-
this._comprehend = new comprehend_1.Comprehend();
|
|
943
|
-
return this._comprehend;
|
|
944
|
-
}
|
|
945
|
-
set comprehend(comprehend) {
|
|
946
|
-
this._comprehend = comprehend;
|
|
947
|
-
}
|
|
948
|
-
///
|
|
949
|
-
/// HELPERS
|
|
950
|
-
///
|
|
951
|
-
/**
|
|
952
|
-
* Manage attachments (through SignedURLs).
|
|
953
|
-
*/
|
|
954
|
-
get attachments() {
|
|
955
|
-
if (!this._attachments)
|
|
956
|
-
this._attachments = new attachments_1.Attachments();
|
|
957
|
-
return this._attachments;
|
|
958
|
-
}
|
|
959
|
-
set attachments(attachments) {
|
|
960
|
-
this._attachments = attachments;
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
exports.GenericController = GenericController;
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
/***/ }),
|
|
967
|
-
|
|
968
|
-
/***/ 341:
|
|
969
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
970
|
-
|
|
971
|
-
|
|
1
|
+
"use strict";
|
|
972
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
973
3
|
if (k2 === undefined) k2 = k;
|
|
974
4
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
@@ -977,1051 +7,17 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
977
7
|
o[k2] = m[k];
|
|
978
8
|
}));
|
|
979
9
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
980
|
-
for (var p in m) if (p !== "default" && !
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
981
11
|
};
|
|
982
|
-
Object.defineProperty(exports, "__esModule",
|
|
983
|
-
__exportStar(
|
|
984
|
-
__exportStar(
|
|
985
|
-
__exportStar(
|
|
986
|
-
__exportStar(
|
|
987
|
-
__exportStar(
|
|
988
|
-
__exportStar(
|
|
989
|
-
__exportStar(
|
|
990
|
-
__exportStar(
|
|
991
|
-
__exportStar(
|
|
992
|
-
__exportStar(
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
/***/ }),
|
|
996
|
-
|
|
997
|
-
/***/ 629:
|
|
998
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1002
|
-
exports.ResourceController = void 0;
|
|
1003
|
-
/* eslint-disable no-invalid-this */
|
|
1004
|
-
const fs_1 = __webpack_require__(747);
|
|
1005
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
1006
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
1007
|
-
const genericController_1 = __webpack_require__(838);
|
|
1008
|
-
/**
|
|
1009
|
-
* An abstract class to inherit to manage API requests (AWS API Gateway) in an AWS Lambda function.
|
|
1010
|
-
*/
|
|
1011
|
-
class ResourceController extends genericController_1.GenericController {
|
|
1012
|
-
constructor(event, callback, options) {
|
|
1013
|
-
var _a, _b, _c, _d, _e;
|
|
1014
|
-
super(event, callback, options);
|
|
1015
|
-
this.templateMatcher = /{{\s?([^{}\s]*)\s?}}/g;
|
|
1016
|
-
///
|
|
1017
|
-
/// REQUEST HANDLERS
|
|
1018
|
-
///
|
|
1019
|
-
this.handleRequest = () => {
|
|
1020
|
-
// check the authorizations and prepare the API request
|
|
1021
|
-
this.checkAuthBeforeRequest()
|
|
1022
|
-
.then(() => {
|
|
1023
|
-
let request;
|
|
1024
|
-
if (this.resourceId)
|
|
1025
|
-
switch (this.httpMethod) {
|
|
1026
|
-
// resource/{resourceId}
|
|
1027
|
-
case 'GET':
|
|
1028
|
-
request = this.getResource();
|
|
1029
|
-
break;
|
|
1030
|
-
case 'POST':
|
|
1031
|
-
request = this.postResource();
|
|
1032
|
-
break;
|
|
1033
|
-
case 'PUT':
|
|
1034
|
-
request = this.putResource();
|
|
1035
|
-
break;
|
|
1036
|
-
case 'DELETE':
|
|
1037
|
-
request = this.deleteResource();
|
|
1038
|
-
break;
|
|
1039
|
-
case 'PATCH':
|
|
1040
|
-
request = this.patchResource();
|
|
1041
|
-
break;
|
|
1042
|
-
case 'HEAD':
|
|
1043
|
-
request = this.headResource();
|
|
1044
|
-
break;
|
|
1045
|
-
default: /* nope */
|
|
1046
|
-
}
|
|
1047
|
-
else
|
|
1048
|
-
switch (this.httpMethod) {
|
|
1049
|
-
// resource
|
|
1050
|
-
case 'GET':
|
|
1051
|
-
request = this.getResources();
|
|
1052
|
-
break;
|
|
1053
|
-
case 'POST':
|
|
1054
|
-
request = this.postResources();
|
|
1055
|
-
break;
|
|
1056
|
-
case 'PUT':
|
|
1057
|
-
request = this.putResources();
|
|
1058
|
-
break;
|
|
1059
|
-
case 'DELETE':
|
|
1060
|
-
request = this.deleteResources();
|
|
1061
|
-
break;
|
|
1062
|
-
case 'PATCH':
|
|
1063
|
-
request = this.patchResources();
|
|
1064
|
-
break;
|
|
1065
|
-
case 'HEAD':
|
|
1066
|
-
request = this.headResources();
|
|
1067
|
-
break;
|
|
1068
|
-
default: /* nope */
|
|
1069
|
-
}
|
|
1070
|
-
// execute the API request
|
|
1071
|
-
if (!request)
|
|
1072
|
-
this.done(new Error('UNSUPPORTED_METHOD'));
|
|
1073
|
-
else {
|
|
1074
|
-
request.then((res) => this.done(null, res)).catch((err) => this.done(err));
|
|
1075
|
-
}
|
|
1076
|
-
})
|
|
1077
|
-
.catch(err => this.done(new Error(err && err.message ? err.message : 'FORBIDDEN')));
|
|
1078
|
-
};
|
|
1079
|
-
this.authorization = (_a = event.headers) === null || _a === void 0 ? void 0 : _a.Authorization;
|
|
1080
|
-
this.claims = (_c = (_b = event.requestContext) === null || _b === void 0 ? void 0 : _b.authorizer) === null || _c === void 0 ? void 0 : _c.claims;
|
|
1081
|
-
this.principalId = (_d = this.claims) === null || _d === void 0 ? void 0 : _d.sub;
|
|
1082
|
-
this.stage = (_e = event.requestContext) === null || _e === void 0 ? void 0 : _e.stage;
|
|
1083
|
-
this.httpMethod = event.httpMethod;
|
|
1084
|
-
this.resource = (event.resource || '').replace('+', ''); // {proxy+} -> {proxy}
|
|
1085
|
-
this.path = event.path || '';
|
|
1086
|
-
this.resourceId =
|
|
1087
|
-
event.pathParameters && event.pathParameters[options.resourceId || 'proxy']
|
|
1088
|
-
? decodeURIComponent(event.pathParameters[options.resourceId || 'proxy'])
|
|
1089
|
-
: '';
|
|
1090
|
-
this.queryParams = event.queryStringParameters || {};
|
|
1091
|
-
this.body = (event.body ? JSON.parse(event.body) : {}) || {};
|
|
1092
|
-
this.logRequestsWithKey = options.logRequestsWithKey;
|
|
1093
|
-
// acquire some info about the client, if available
|
|
1094
|
-
let version = '?', platform = '?';
|
|
1095
|
-
if (this.queryParams['_v']) {
|
|
1096
|
-
version = this.queryParams['_v'];
|
|
1097
|
-
delete this.queryParams['_v'];
|
|
1098
|
-
}
|
|
1099
|
-
if (this.queryParams['_p']) {
|
|
1100
|
-
platform = this.queryParams['_p'];
|
|
1101
|
-
delete this.queryParams['_p'];
|
|
1102
|
-
}
|
|
1103
|
-
// print the initial log
|
|
1104
|
-
const info = { principalId: this.principalId, queryParams: this.queryParams, body: this.body, version, platform };
|
|
1105
|
-
idea_toolbox_1.logger(`START: ${this.httpMethod} ${this.stage} ${this.path}`, null, info, true);
|
|
1106
|
-
}
|
|
1107
|
-
done(err, res) {
|
|
1108
|
-
idea_toolbox_1.logger(err ? 'DONE WITH ERRORS' : 'DONE', err, res, true);
|
|
1109
|
-
// if configured, store the log of the request
|
|
1110
|
-
if (this.logRequestsWithKey)
|
|
1111
|
-
this.storeLog(!err);
|
|
1112
|
-
// send the response
|
|
1113
|
-
this.callback(null, {
|
|
1114
|
-
statusCode: err ? '400' : '200',
|
|
1115
|
-
body: err ? JSON.stringify({ message: err.message }) : JSON.stringify(res || {}),
|
|
1116
|
-
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }
|
|
1117
|
-
});
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
* To @override
|
|
1121
|
-
*/
|
|
1122
|
-
checkAuthBeforeRequest() {
|
|
1123
|
-
return new Promise(resolve => resolve());
|
|
1124
|
-
}
|
|
1125
|
-
/**
|
|
1126
|
-
* To @override
|
|
1127
|
-
*/
|
|
1128
|
-
getResource() {
|
|
1129
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* To @override
|
|
1133
|
-
*/
|
|
1134
|
-
postResource() {
|
|
1135
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1136
|
-
}
|
|
1137
|
-
/**
|
|
1138
|
-
* To @override
|
|
1139
|
-
*/
|
|
1140
|
-
putResource() {
|
|
1141
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1142
|
-
}
|
|
1143
|
-
/**
|
|
1144
|
-
* To @override
|
|
1145
|
-
*/
|
|
1146
|
-
deleteResource() {
|
|
1147
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1148
|
-
}
|
|
1149
|
-
/**
|
|
1150
|
-
* To @override
|
|
1151
|
-
*/
|
|
1152
|
-
headResource() {
|
|
1153
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1154
|
-
}
|
|
1155
|
-
/**
|
|
1156
|
-
* To @override
|
|
1157
|
-
*/
|
|
1158
|
-
getResources() {
|
|
1159
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* To @override
|
|
1163
|
-
*/
|
|
1164
|
-
postResources() {
|
|
1165
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1166
|
-
}
|
|
1167
|
-
/**
|
|
1168
|
-
* To @override
|
|
1169
|
-
*/
|
|
1170
|
-
putResources() {
|
|
1171
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1172
|
-
}
|
|
1173
|
-
/**
|
|
1174
|
-
* To @override
|
|
1175
|
-
*/
|
|
1176
|
-
patchResource() {
|
|
1177
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1178
|
-
}
|
|
1179
|
-
/**
|
|
1180
|
-
* To @override
|
|
1181
|
-
*/
|
|
1182
|
-
patchResources() {
|
|
1183
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* To @override
|
|
1187
|
-
*/
|
|
1188
|
-
deleteResources() {
|
|
1189
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1190
|
-
}
|
|
1191
|
-
/**
|
|
1192
|
-
* To @override
|
|
1193
|
-
*/
|
|
1194
|
-
headResources() {
|
|
1195
|
-
return new Promise((_, reject) => reject(new Error('UNSUPPORTED_METHOD')));
|
|
1196
|
-
}
|
|
1197
|
-
///
|
|
1198
|
-
/// HELPERS
|
|
1199
|
-
///
|
|
1200
|
-
/**
|
|
1201
|
-
* Store the log associated to the request (no response/error handling).
|
|
1202
|
-
*/
|
|
1203
|
-
storeLog(succeeded) {
|
|
1204
|
-
// create the log
|
|
1205
|
-
const log = new idea_toolbox_1.APIRequestLog({
|
|
1206
|
-
logId: this.logRequestsWithKey,
|
|
1207
|
-
userId: this.principalId,
|
|
1208
|
-
resource: this.resource,
|
|
1209
|
-
path: this.path,
|
|
1210
|
-
resourceId: this.resourceId,
|
|
1211
|
-
method: this.httpMethod,
|
|
1212
|
-
succeeded
|
|
1213
|
-
});
|
|
1214
|
-
// optionally add a track of the action
|
|
1215
|
-
if (this.httpMethod === 'PATCH' && this.body && this.body.action)
|
|
1216
|
-
log.action = this.body.action;
|
|
1217
|
-
// insert the log and don't wait for response or errors
|
|
1218
|
-
this.dynamoDB.put({ TableName: 'idea_logs', Item: log }).catch(() => { });
|
|
1219
|
-
}
|
|
1220
|
-
/**
|
|
1221
|
-
* Check whether shared resource exists in the back-end (translation, template, etc.).
|
|
1222
|
-
*/
|
|
1223
|
-
sharedResourceExists(path) {
|
|
1224
|
-
return fs_1.existsSync(`assets/${path}`);
|
|
1225
|
-
}
|
|
1226
|
-
/**
|
|
1227
|
-
* Load a shared resource in the back-end (translation, template, etc.).
|
|
1228
|
-
* @param encoding default: `utf-8`
|
|
1229
|
-
*/
|
|
1230
|
-
loadSharedResource(path, encoding) {
|
|
1231
|
-
encoding = encoding || 'utf-8';
|
|
1232
|
-
return fs_1.readFileSync(`assets/${path}`, { encoding });
|
|
1233
|
-
}
|
|
1234
|
-
///
|
|
1235
|
-
/// MANAGE INTERNAL API REQUESTS (lambda invokes masked as API requests)
|
|
1236
|
-
///
|
|
1237
|
-
/**
|
|
1238
|
-
* Simulate an internal API request, invoking directly the lambda and therefore saving resources.
|
|
1239
|
-
* @return the body of the response
|
|
1240
|
-
*/
|
|
1241
|
-
invokeInternalAPIRequest(params) {
|
|
1242
|
-
return new Promise((resolve, reject) => {
|
|
1243
|
-
// create a copy of the event
|
|
1244
|
-
const event = JSON.parse(JSON.stringify(this.event));
|
|
1245
|
-
// change only the event attributes we need; e.g. the authorization is unchanged
|
|
1246
|
-
event.stage = params.stage || this.stage;
|
|
1247
|
-
event.httpMethod = params.httpMethod;
|
|
1248
|
-
event.resource = params.resource;
|
|
1249
|
-
event.pathParameters = params.pathParams || {};
|
|
1250
|
-
event.queryStringParameters = params.queryParams || {};
|
|
1251
|
-
event.body = JSON.stringify(params.body || {});
|
|
1252
|
-
// parse the path
|
|
1253
|
-
event.path = event.resource;
|
|
1254
|
-
for (const p in event.pathParameters)
|
|
1255
|
-
if (event.pathParameters[p])
|
|
1256
|
-
event.resource = event.resource.replace(`{${p}}`, event.pathParameters[p]);
|
|
1257
|
-
// set a flag to make the invoked to recognise that is an internal request
|
|
1258
|
-
event.internalAPIRequest = true;
|
|
1259
|
-
// invoke the lambda with the event prepaired, simulating an API request
|
|
1260
|
-
new aws_sdk_1.Lambda().invoke({
|
|
1261
|
-
FunctionName: params.lambda,
|
|
1262
|
-
Qualifier: event.stage,
|
|
1263
|
-
InvocationType: 'RequestResponse',
|
|
1264
|
-
Payload: JSON.stringify(event)
|
|
1265
|
-
}, (err, res) => {
|
|
1266
|
-
// reject in case of internal error
|
|
1267
|
-
if (err)
|
|
1268
|
-
reject(err);
|
|
1269
|
-
else {
|
|
1270
|
-
// parse the payload and the body
|
|
1271
|
-
const payload = JSON.parse(res.Payload);
|
|
1272
|
-
const body = JSON.parse(payload.body);
|
|
1273
|
-
// if the response is successfull, return the body
|
|
1274
|
-
if (Number(payload.statusCode) === 200)
|
|
1275
|
-
resolve(body);
|
|
1276
|
-
// otherwise, reject the controlled error
|
|
1277
|
-
else
|
|
1278
|
-
reject(new Error(body.message));
|
|
1279
|
-
}
|
|
1280
|
-
});
|
|
1281
|
-
});
|
|
1282
|
-
}
|
|
1283
|
-
/**
|
|
1284
|
-
* Whether the current request comes from an internal API request, i.e. it was invoked by another controller.
|
|
1285
|
-
*/
|
|
1286
|
-
comesFromInternalRequest() {
|
|
1287
|
-
return Boolean(this.event.internalAPIRequest);
|
|
1288
|
-
}
|
|
1289
|
-
//
|
|
1290
|
-
// TRANSLATIONS
|
|
1291
|
-
//
|
|
1292
|
-
/**
|
|
1293
|
-
* Load the translations from the shared resources and set them with a fallback language.
|
|
1294
|
-
*/
|
|
1295
|
-
loadTranslations(lang, defLang) {
|
|
1296
|
-
// check for the existance of the mandatory source file
|
|
1297
|
-
if (!this.sharedResourceExists(`i18n/${lang}.json`))
|
|
1298
|
-
return;
|
|
1299
|
-
// set the languages
|
|
1300
|
-
this.currentLang = lang;
|
|
1301
|
-
this.defaultLang = defLang || lang;
|
|
1302
|
-
this.translations = {};
|
|
1303
|
-
// load the translations in the chosen language
|
|
1304
|
-
this.translations[this.currentLang] = JSON.parse(this.loadSharedResource(`i18n/${this.currentLang}.json`).toString());
|
|
1305
|
-
// load the translations in the default language, if set and differ from the current
|
|
1306
|
-
if (this.defaultLang !== this.currentLang && this.sharedResourceExists(`i18n/${this.defaultLang}.json`))
|
|
1307
|
-
this.translations[this.defaultLang] = JSON.parse(this.loadSharedResource(`i18n/${this.defaultLang}.json`).toString());
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* Get a translated term by key, optionally interpolating variables (e.g. `{{user}}`).
|
|
1311
|
-
* If the term doesn't exist in the current language, it is searched in the default language.
|
|
1312
|
-
*/
|
|
1313
|
-
t(key, interpolateParams) {
|
|
1314
|
-
if (!this.translations || !this.currentLang)
|
|
1315
|
-
return;
|
|
1316
|
-
if (!this.isDefined(key) || !key.length)
|
|
1317
|
-
return;
|
|
1318
|
-
let res = this.interpolate(this.getValue(this.translations[this.currentLang], key), interpolateParams);
|
|
1319
|
-
if (res === undefined && this.defaultLang !== null && this.defaultLang !== this.currentLang)
|
|
1320
|
-
res = this.interpolate(this.getValue(this.translations[this.defaultLang], key), interpolateParams);
|
|
1321
|
-
return res;
|
|
1322
|
-
}
|
|
1323
|
-
/**
|
|
1324
|
-
* Interpolates a string to replace parameters.
|
|
1325
|
-
* "This is a {{ key }}" ==> "This is a value", with params = { key: "value" }
|
|
1326
|
-
*/
|
|
1327
|
-
interpolate(expr, params) {
|
|
1328
|
-
if (!params || !expr)
|
|
1329
|
-
return expr;
|
|
1330
|
-
return expr.replace(this.templateMatcher, (substring, b) => {
|
|
1331
|
-
const r = this.getValue(params, b);
|
|
1332
|
-
return this.isDefined(r) ? r : substring;
|
|
1333
|
-
});
|
|
1334
|
-
}
|
|
1335
|
-
/**
|
|
1336
|
-
* Gets a value from an object by composed key.
|
|
1337
|
-
* getValue({ key1: { keyA: 'valueI' }}, 'key1.keyA') ==> 'valueI'
|
|
1338
|
-
*/
|
|
1339
|
-
getValue(target, key) {
|
|
1340
|
-
const keys = typeof key === 'string' ? key.split('.') : [key];
|
|
1341
|
-
key = '';
|
|
1342
|
-
do {
|
|
1343
|
-
key += keys.shift();
|
|
1344
|
-
if (this.isDefined(target) && this.isDefined(target[key]) && (typeof target[key] === 'object' || !keys.length)) {
|
|
1345
|
-
target = target[key];
|
|
1346
|
-
key = '';
|
|
1347
|
-
}
|
|
1348
|
-
else if (!keys.length)
|
|
1349
|
-
target = undefined;
|
|
1350
|
-
else
|
|
1351
|
-
key += '.';
|
|
1352
|
-
} while (keys.length);
|
|
1353
|
-
return target;
|
|
1354
|
-
}
|
|
1355
|
-
/**
|
|
1356
|
-
* Helper to quicly check if the value is defined.
|
|
1357
|
-
*/
|
|
1358
|
-
isDefined(value) {
|
|
1359
|
-
return value !== undefined && value !== null;
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
exports.ResourceController = ResourceController;
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
/***/ }),
|
|
1366
|
-
|
|
1367
|
-
/***/ 216:
|
|
1368
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1372
|
-
exports.GetObjectTypes = exports.S3 = void 0;
|
|
1373
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
1374
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
1375
|
-
/**
|
|
1376
|
-
* A wrapper for AWS Simple Storage Service.
|
|
1377
|
-
*/
|
|
1378
|
-
class S3 {
|
|
1379
|
-
/**
|
|
1380
|
-
* Initialize a new S3 helper object.
|
|
1381
|
-
*/
|
|
1382
|
-
constructor() {
|
|
1383
|
-
this.DEFAULT_DOWNLOAD_BUCKET_PREFIX = 'common';
|
|
1384
|
-
this.DEFAULT_DOWNLOAD_BUCKET = 'idea-downloads';
|
|
1385
|
-
this.DEFAULT_DOWNLOAD_BUCKET_SEC_TO_EXP = 180;
|
|
1386
|
-
this.DEFAULT_UPLOAD_BUCKET_SEC_TO_EXP = 300;
|
|
1387
|
-
this.s3 = new aws_sdk_1.S3({ apiVersion: '2006-03-01', signatureVersion: 'v4' });
|
|
1388
|
-
}
|
|
1389
|
-
/**
|
|
1390
|
-
* Create a download link of a piece of data (through S3).
|
|
1391
|
-
* *Pratically*, it uploads the file on an S3 bucket, generating and returning a url to it.
|
|
1392
|
-
*/
|
|
1393
|
-
createDownloadURLFromData(data, options) {
|
|
1394
|
-
return new Promise((resolve, reject) => {
|
|
1395
|
-
// if needed, randomly generates the key
|
|
1396
|
-
if (!options.key)
|
|
1397
|
-
options.key = new Date().getTime().toString().concat(Math.random().toString(36).slice(2));
|
|
1398
|
-
// add the prefix to the key
|
|
1399
|
-
options.key = `${options.prefix || this.DEFAULT_DOWNLOAD_BUCKET_PREFIX}/${options.key}`;
|
|
1400
|
-
// set the other parameters
|
|
1401
|
-
options.bucket = options.bucket || this.DEFAULT_DOWNLOAD_BUCKET;
|
|
1402
|
-
options.secToExp = options.secToExp || this.DEFAULT_DOWNLOAD_BUCKET_SEC_TO_EXP;
|
|
1403
|
-
// upload the file to the downloads bucket
|
|
1404
|
-
this.s3.upload({
|
|
1405
|
-
Bucket: options.bucket,
|
|
1406
|
-
Key: options.key,
|
|
1407
|
-
Body: data,
|
|
1408
|
-
ContentType: options.contentType
|
|
1409
|
-
}, (err) => {
|
|
1410
|
-
idea_toolbox_1.logger('S3 UPLOAD', err);
|
|
1411
|
-
if (err)
|
|
1412
|
-
reject(err);
|
|
1413
|
-
else
|
|
1414
|
-
resolve(this.signedURLGet(options.bucket, options.key, options.secToExp));
|
|
1415
|
-
});
|
|
1416
|
-
});
|
|
1417
|
-
}
|
|
1418
|
-
/**
|
|
1419
|
-
* Get a signed URL to put a file on a S3 bucket.
|
|
1420
|
-
* @param expires seconds after which the signed URL expires
|
|
1421
|
-
*/
|
|
1422
|
-
signedURLPut(bucket, key, expires) {
|
|
1423
|
-
return new idea_toolbox_1.SignedURL({
|
|
1424
|
-
url: this.s3.getSignedUrl('putObject', {
|
|
1425
|
-
Bucket: bucket,
|
|
1426
|
-
Key: key,
|
|
1427
|
-
Expires: expires || this.DEFAULT_UPLOAD_BUCKET_SEC_TO_EXP
|
|
1428
|
-
})
|
|
1429
|
-
});
|
|
1430
|
-
}
|
|
1431
|
-
/**
|
|
1432
|
-
* Get a signed URL to get a file on a S3 bucket.
|
|
1433
|
-
* @param expires seconds after which the signed URL expires
|
|
1434
|
-
*/
|
|
1435
|
-
signedURLGet(bucket, key, expires) {
|
|
1436
|
-
return new idea_toolbox_1.SignedURL({
|
|
1437
|
-
url: this.s3.getSignedUrl('getObject', {
|
|
1438
|
-
Bucket: bucket,
|
|
1439
|
-
Key: key,
|
|
1440
|
-
Expires: expires || this.DEFAULT_DOWNLOAD_BUCKET_SEC_TO_EXP
|
|
1441
|
-
})
|
|
1442
|
-
});
|
|
1443
|
-
}
|
|
1444
|
-
/**
|
|
1445
|
-
* Make a copy of an object of the bucket.
|
|
1446
|
-
*/
|
|
1447
|
-
copyObject(options) {
|
|
1448
|
-
return new Promise((resolve, reject) => {
|
|
1449
|
-
this.s3.copyObject({ CopySource: options.copySource, Bucket: options.bucket, Key: options.key }, (err) => {
|
|
1450
|
-
idea_toolbox_1.logger('S3 COPY OBJECT', err, options.key);
|
|
1451
|
-
if (err)
|
|
1452
|
-
reject(err);
|
|
1453
|
-
else
|
|
1454
|
-
resolve();
|
|
1455
|
-
});
|
|
1456
|
-
});
|
|
1457
|
-
}
|
|
1458
|
-
/**
|
|
1459
|
-
* Get an object from a S3 bucket.
|
|
1460
|
-
*/
|
|
1461
|
-
getObject(options) {
|
|
1462
|
-
return new Promise((resolve, reject) => {
|
|
1463
|
-
this.s3.getObject({ Bucket: options.bucket, Key: options.key }, (err, d) => {
|
|
1464
|
-
idea_toolbox_1.logger('S3 GET OBJECT', err, options.type);
|
|
1465
|
-
if (err)
|
|
1466
|
-
reject(err);
|
|
1467
|
-
else
|
|
1468
|
-
switch (options.type) {
|
|
1469
|
-
case GetObjectTypes.JSON:
|
|
1470
|
-
resolve(JSON.parse(d.Body.toString('utf-8')));
|
|
1471
|
-
break;
|
|
1472
|
-
case GetObjectTypes.TEXT:
|
|
1473
|
-
resolve(d.Body.toString('utf-8'));
|
|
1474
|
-
break;
|
|
1475
|
-
default:
|
|
1476
|
-
resolve(d);
|
|
1477
|
-
}
|
|
1478
|
-
});
|
|
1479
|
-
});
|
|
1480
|
-
}
|
|
1481
|
-
/**
|
|
1482
|
-
* Put an object in a S3 bucket.
|
|
1483
|
-
*/
|
|
1484
|
-
putObject(options) {
|
|
1485
|
-
return new Promise((resolve, reject) => {
|
|
1486
|
-
const params = { Bucket: options.bucket, Key: options.key, Body: options.body };
|
|
1487
|
-
if (options.contentType)
|
|
1488
|
-
params.ContentType = options.contentType;
|
|
1489
|
-
if (options.acl)
|
|
1490
|
-
params.ACL = options.acl;
|
|
1491
|
-
if (options.metadata)
|
|
1492
|
-
params.Metadata = options.metadata;
|
|
1493
|
-
this.s3.putObject(params, (err, d) => {
|
|
1494
|
-
idea_toolbox_1.logger('S3 PUT OBJECT', err, options.key);
|
|
1495
|
-
if (err)
|
|
1496
|
-
reject(err);
|
|
1497
|
-
else
|
|
1498
|
-
resolve(d);
|
|
1499
|
-
});
|
|
1500
|
-
});
|
|
1501
|
-
}
|
|
1502
|
-
/**
|
|
1503
|
-
* Delete an object from an S3 bucket.
|
|
1504
|
-
*/
|
|
1505
|
-
deleteObject(options) {
|
|
1506
|
-
return new Promise((resolve, reject) => {
|
|
1507
|
-
this.s3.deleteObject({ Bucket: options.bucket, Key: options.key }, (err, o) => {
|
|
1508
|
-
idea_toolbox_1.logger('S3 DELETE OBJECT', err, options.key);
|
|
1509
|
-
if (err)
|
|
1510
|
-
reject(err);
|
|
1511
|
-
else
|
|
1512
|
-
resolve(o);
|
|
1513
|
-
});
|
|
1514
|
-
});
|
|
1515
|
-
}
|
|
1516
|
-
/**
|
|
1517
|
-
* List the objects of an S3 bucket.
|
|
1518
|
-
*/
|
|
1519
|
-
listObjects(options) {
|
|
1520
|
-
return new Promise((resolve, reject) => {
|
|
1521
|
-
this.s3.listObjects({ Bucket: options.bucket, Prefix: options.prefix }, (err, o) => {
|
|
1522
|
-
idea_toolbox_1.logger('S3 LIST OBJECTS', err, options.prefix);
|
|
1523
|
-
if (err)
|
|
1524
|
-
reject(err);
|
|
1525
|
-
else
|
|
1526
|
-
resolve(o);
|
|
1527
|
-
});
|
|
1528
|
-
});
|
|
1529
|
-
}
|
|
1530
|
-
/**
|
|
1531
|
-
* List the objects keys of an S3 bucket.
|
|
1532
|
-
*/
|
|
1533
|
-
listObjectsKeys(options) {
|
|
1534
|
-
return new Promise((resolve, reject) => {
|
|
1535
|
-
this.listObjects(options)
|
|
1536
|
-
.then(list => resolve(list.Contents.map(obj => obj.Key)))
|
|
1537
|
-
.catch(err => reject(err));
|
|
1538
|
-
});
|
|
1539
|
-
}
|
|
1540
|
-
/**
|
|
1541
|
-
* Check whether an object on an S3 bucket exists.
|
|
1542
|
-
*/
|
|
1543
|
-
doesObjectExist(options) {
|
|
1544
|
-
return new Promise(resolve => {
|
|
1545
|
-
this.s3.headObject({ Bucket: options.bucket, Key: options.key }, (err) => {
|
|
1546
|
-
idea_toolbox_1.logger('S3 HEAD OBJECT', err, options.key);
|
|
1547
|
-
if (err)
|
|
1548
|
-
resolve(false);
|
|
1549
|
-
else
|
|
1550
|
-
resolve(true);
|
|
1551
|
-
});
|
|
1552
|
-
});
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
exports.S3 = S3;
|
|
1556
|
-
/**
|
|
1557
|
-
* The managed types to convert objects coming from an S3 bucket.
|
|
1558
|
-
*/
|
|
1559
|
-
var GetObjectTypes;
|
|
1560
|
-
(function (GetObjectTypes) {
|
|
1561
|
-
GetObjectTypes["JSON"] = "JSON";
|
|
1562
|
-
GetObjectTypes["TEXT"] = "TEXT";
|
|
1563
|
-
})(GetObjectTypes = exports.GetObjectTypes || (exports.GetObjectTypes = {}));
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
/***/ }),
|
|
1567
|
-
|
|
1568
|
-
/***/ 887:
|
|
1569
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1573
|
-
exports.SES = void 0;
|
|
1574
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
1575
|
-
const nodemailer_1 = __webpack_require__(123);
|
|
1576
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
1577
|
-
const dynamoDB_1 = __webpack_require__(823);
|
|
1578
|
-
/**
|
|
1579
|
-
* A wrapper for AWS Simple Email Service.
|
|
1580
|
-
*/
|
|
1581
|
-
class SES {
|
|
1582
|
-
/**
|
|
1583
|
-
* Send an email through AWS Simple Email Service.
|
|
1584
|
-
*/
|
|
1585
|
-
sendEmail(emailData, sesParams) {
|
|
1586
|
-
return new Promise((resolve, reject) => {
|
|
1587
|
-
// if requested, check whether there is a custom SES configuration to apply for the team
|
|
1588
|
-
this.searchForCustomSESConfigByTeamId(sesParams.teamId).then(customSESConfig => {
|
|
1589
|
-
var _a;
|
|
1590
|
-
let promise;
|
|
1591
|
-
// if the email includes attachments, send with Nodemailer (to avoid size limitations)
|
|
1592
|
-
if ((_a = emailData.attachments) === null || _a === void 0 ? void 0 : _a.length)
|
|
1593
|
-
promise = this.sendEmailWithNodemailer(emailData, customSESConfig || sesParams);
|
|
1594
|
-
// otherwise, send with SES (more secure)
|
|
1595
|
-
else
|
|
1596
|
-
promise = this.sendEmailWithSES(emailData, customSESConfig || sesParams);
|
|
1597
|
-
promise.then(res => resolve(res)).catch(err => reject(err));
|
|
1598
|
-
});
|
|
1599
|
-
});
|
|
1600
|
-
}
|
|
1601
|
-
searchForCustomSESConfigByTeamId(teamId) {
|
|
1602
|
-
return new Promise(resolve => {
|
|
1603
|
-
if (!teamId)
|
|
1604
|
-
return resolve(null);
|
|
1605
|
-
new dynamoDB_1.DynamoDB()
|
|
1606
|
-
.get({ TableName: 'idea_teamsSES', Key: { teamId } })
|
|
1607
|
-
.then((customConfig) => resolve(customConfig))
|
|
1608
|
-
.catch(() => resolve(null));
|
|
1609
|
-
});
|
|
1610
|
-
}
|
|
1611
|
-
sendEmailWithSES(emailData, sesParams) {
|
|
1612
|
-
return new Promise((resolve, reject) => {
|
|
1613
|
-
// prepare SES email data
|
|
1614
|
-
const sesData = {};
|
|
1615
|
-
sesData.Destination = {};
|
|
1616
|
-
if (emailData.toAddresses)
|
|
1617
|
-
sesData.Destination.ToAddresses = emailData.toAddresses;
|
|
1618
|
-
if (emailData.ccAddresses)
|
|
1619
|
-
sesData.Destination.CcAddresses = emailData.ccAddresses;
|
|
1620
|
-
if (emailData.bccAddresses)
|
|
1621
|
-
sesData.Destination.BccAddresses = emailData.bccAddresses;
|
|
1622
|
-
if (emailData.replyToAddresses)
|
|
1623
|
-
sesData.ReplyToAddresses = emailData.replyToAddresses;
|
|
1624
|
-
sesData.Message = {};
|
|
1625
|
-
if (emailData.subject)
|
|
1626
|
-
sesData.Message.Subject = { Charset: 'UTF-8', Data: emailData.subject };
|
|
1627
|
-
sesData.Message.Body = {};
|
|
1628
|
-
if (emailData.html)
|
|
1629
|
-
sesData.Message.Body.Html = { Charset: 'UTF-8', Data: emailData.html };
|
|
1630
|
-
if (emailData.text)
|
|
1631
|
-
sesData.Message.Body.Text = { Charset: 'UTF-8', Data: emailData.text };
|
|
1632
|
-
if (!emailData.html && !emailData.text)
|
|
1633
|
-
sesData.Message.Body.Text = { Charset: 'UTF-8', Data: '' };
|
|
1634
|
-
sesData.Source = `${sesParams.sourceName} <${sesParams.source}>`;
|
|
1635
|
-
sesData.SourceArn = sesParams.sourceArn;
|
|
1636
|
-
// send email
|
|
1637
|
-
new aws_sdk_1.SES({ region: sesParams.region }).sendEmail(sesData, (err) => {
|
|
1638
|
-
idea_toolbox_1.logger('SES SEND EMAIL', err);
|
|
1639
|
-
if (err)
|
|
1640
|
-
reject(err);
|
|
1641
|
-
else
|
|
1642
|
-
resolve();
|
|
1643
|
-
});
|
|
1644
|
-
});
|
|
1645
|
-
}
|
|
1646
|
-
sendEmailWithNodemailer(emailData, sesParams) {
|
|
1647
|
-
return new Promise((resolve, reject) => {
|
|
1648
|
-
// set the mail options in Nodemailer's format
|
|
1649
|
-
const mailOptions = {};
|
|
1650
|
-
mailOptions.from = `${sesParams.sourceName} <${sesParams.source}>`;
|
|
1651
|
-
mailOptions.to = emailData.toAddresses.join(',');
|
|
1652
|
-
if (emailData.ccAddresses)
|
|
1653
|
-
mailOptions.cc = emailData.ccAddresses.join(',');
|
|
1654
|
-
if (emailData.bccAddresses)
|
|
1655
|
-
mailOptions.bcc = emailData.bccAddresses.join(',');
|
|
1656
|
-
if (emailData.replyToAddresses)
|
|
1657
|
-
mailOptions.replyTo = emailData.replyToAddresses.join(',');
|
|
1658
|
-
mailOptions.subject = emailData.subject;
|
|
1659
|
-
if (emailData.html)
|
|
1660
|
-
mailOptions.html = emailData.html;
|
|
1661
|
-
if (emailData.text)
|
|
1662
|
-
mailOptions.text = emailData.text;
|
|
1663
|
-
mailOptions.attachments = emailData.attachments;
|
|
1664
|
-
// create Nodemailer SES transporter and send the email
|
|
1665
|
-
nodemailer_1.createTransport({ SES: new aws_sdk_1.SES({ region: sesParams.region }) }).sendMail(mailOptions, (err) => {
|
|
1666
|
-
idea_toolbox_1.logger('SES SEND EMAIL (NODEMAILER)', err);
|
|
1667
|
-
if (err)
|
|
1668
|
-
reject(err);
|
|
1669
|
-
else
|
|
1670
|
-
resolve();
|
|
1671
|
-
});
|
|
1672
|
-
});
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
exports.SES = SES;
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
/***/ }),
|
|
1679
|
-
|
|
1680
|
-
/***/ 187:
|
|
1681
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1685
|
-
exports.SNS = void 0;
|
|
1686
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
1687
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
1688
|
-
/**
|
|
1689
|
-
* A wrapper for AWS Simple Notification Service.
|
|
1690
|
-
*/
|
|
1691
|
-
class SNS {
|
|
1692
|
-
/**
|
|
1693
|
-
* Create a new endpoint in the SNS platform specified.
|
|
1694
|
-
* @return platform endpoint ARN
|
|
1695
|
-
*/
|
|
1696
|
-
createPushPlatormEndpoint(platform, token, snsParams) {
|
|
1697
|
-
return new Promise((resolve, reject) => {
|
|
1698
|
-
let platformARN;
|
|
1699
|
-
// identify the platform ARN
|
|
1700
|
-
switch (platform) {
|
|
1701
|
-
case idea_toolbox_1.PushNotificationsPlatforms.APNS:
|
|
1702
|
-
platformARN = snsParams.appleArn;
|
|
1703
|
-
break;
|
|
1704
|
-
case idea_toolbox_1.PushNotificationsPlatforms.APNS_SANDBOX:
|
|
1705
|
-
platformARN = snsParams.appleDevArn;
|
|
1706
|
-
break;
|
|
1707
|
-
case idea_toolbox_1.PushNotificationsPlatforms.FCM:
|
|
1708
|
-
platformARN = snsParams.androidArn;
|
|
1709
|
-
break;
|
|
1710
|
-
default:
|
|
1711
|
-
return reject(new Error('UNSUPPORTED_PLATFORM'));
|
|
1712
|
-
}
|
|
1713
|
-
// create a new endpoint in the platform
|
|
1714
|
-
new aws_sdk_1.SNS({ apiVersion: '2010-03-31', region: snsParams.region }).createPlatformEndpoint({ PlatformApplicationArn: platformARN, Token: token }, (err, data) => {
|
|
1715
|
-
idea_toolbox_1.logger('SNS ADD PLATFORM ENDPOINT', err);
|
|
1716
|
-
if (err || !data.EndpointArn)
|
|
1717
|
-
reject(err);
|
|
1718
|
-
else
|
|
1719
|
-
resolve(data.EndpointArn);
|
|
1720
|
-
});
|
|
1721
|
-
});
|
|
1722
|
-
}
|
|
1723
|
-
/**
|
|
1724
|
-
* Publish a message to a SNS endpoint.
|
|
1725
|
-
*/
|
|
1726
|
-
publish(params) {
|
|
1727
|
-
return new Promise((resolve, reject) => {
|
|
1728
|
-
let structuredMessage;
|
|
1729
|
-
if (params.json)
|
|
1730
|
-
structuredMessage = { default: JSON.stringify(params.json) };
|
|
1731
|
-
else
|
|
1732
|
-
switch (params.platform) {
|
|
1733
|
-
case idea_toolbox_1.PushNotificationsPlatforms.APNS:
|
|
1734
|
-
structuredMessage = { APNS: JSON.stringify({ aps: { alert: params.message } }) };
|
|
1735
|
-
break;
|
|
1736
|
-
case idea_toolbox_1.PushNotificationsPlatforms.APNS_SANDBOX:
|
|
1737
|
-
structuredMessage = { APNS_SANDBOX: JSON.stringify({ aps: { alert: params.message } }) };
|
|
1738
|
-
break;
|
|
1739
|
-
case idea_toolbox_1.PushNotificationsPlatforms.FCM:
|
|
1740
|
-
structuredMessage = {
|
|
1741
|
-
GCM: JSON.stringify({ notification: { body: params.message, title: params.message } })
|
|
1742
|
-
};
|
|
1743
|
-
break;
|
|
1744
|
-
default:
|
|
1745
|
-
return reject(new Error('UNSUPPORTED_PLATFORM'));
|
|
1746
|
-
}
|
|
1747
|
-
new aws_sdk_1.SNS({ apiVersion: '2010-03-31', region: params.region }).publish({
|
|
1748
|
-
MessageStructure: 'json',
|
|
1749
|
-
Message: JSON.stringify(structuredMessage),
|
|
1750
|
-
TargetArn: params.endpoint
|
|
1751
|
-
}, (err, data) => {
|
|
1752
|
-
idea_toolbox_1.logger('SNS PUBLISH IN TOPIC', err);
|
|
1753
|
-
if (err)
|
|
1754
|
-
reject(err);
|
|
1755
|
-
else
|
|
1756
|
-
resolve(data);
|
|
1757
|
-
});
|
|
1758
|
-
});
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
exports.SNS = SNS;
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
/***/ }),
|
|
1765
|
-
|
|
1766
|
-
/***/ 296:
|
|
1767
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1771
|
-
exports.StreamController = void 0;
|
|
1772
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
1773
|
-
const genericController_1 = __webpack_require__(838);
|
|
1774
|
-
/**
|
|
1775
|
-
* An abstract class to inherit to manage AWS DDB streams in an AWS Lambda function.
|
|
1776
|
-
*/
|
|
1777
|
-
class StreamController extends genericController_1.GenericController {
|
|
1778
|
-
constructor(event, callback, options) {
|
|
1779
|
-
super(event, callback, options);
|
|
1780
|
-
this.records = event.Records || [];
|
|
1781
|
-
idea_toolbox_1.logger(`START STREAM: ${this.records.length || 0} records`, null, null, true);
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
exports.StreamController = StreamController;
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
/***/ }),
|
|
1788
|
-
|
|
1789
|
-
/***/ 580:
|
|
1790
|
-
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1794
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1795
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1796
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1797
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1798
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1799
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1800
|
-
});
|
|
1801
|
-
};
|
|
1802
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1803
|
-
exports.Translate = void 0;
|
|
1804
|
-
const aws_sdk_1 = __webpack_require__(480);
|
|
1805
|
-
const idea_toolbox_1 = __webpack_require__(81);
|
|
1806
|
-
/**
|
|
1807
|
-
* A wrapper for Amazon Translate.
|
|
1808
|
-
*/
|
|
1809
|
-
class Translate {
|
|
1810
|
-
/**
|
|
1811
|
-
* Initialize a new Translate helper object.
|
|
1812
|
-
*/
|
|
1813
|
-
constructor() {
|
|
1814
|
-
this.translate = new aws_sdk_1.Translate({ apiVersion: '2017-07-01' });
|
|
1815
|
-
this.sourceLanguageCode = 'en';
|
|
1816
|
-
this.targetLanguageCode = 'en';
|
|
1817
|
-
this.terminologyNames = new Array();
|
|
1818
|
-
}
|
|
1819
|
-
/**
|
|
1820
|
-
* Translates input text from the source language to the target language.
|
|
1821
|
-
* @param params the parameters for translateText
|
|
1822
|
-
*/
|
|
1823
|
-
text(params) {
|
|
1824
|
-
return new Promise((resolve, reject) => {
|
|
1825
|
-
// load source and target languages codes
|
|
1826
|
-
if (params.sourceLanguageCode)
|
|
1827
|
-
this.sourceLanguageCode = params.sourceLanguageCode;
|
|
1828
|
-
if (params.targetLanguageCode)
|
|
1829
|
-
this.targetLanguageCode = params.targetLanguageCode;
|
|
1830
|
-
if (params.terminologyNames)
|
|
1831
|
-
this.terminologyNames = params.terminologyNames;
|
|
1832
|
-
// check for obligatory params
|
|
1833
|
-
if (!this.sourceLanguageCode || !this.targetLanguageCode || !params.text)
|
|
1834
|
-
return reject();
|
|
1835
|
-
// execute the translation
|
|
1836
|
-
this.translate.translateText({
|
|
1837
|
-
Text: params.text,
|
|
1838
|
-
SourceLanguageCode: this.sourceLanguageCode,
|
|
1839
|
-
TargetLanguageCode: this.targetLanguageCode,
|
|
1840
|
-
TerminologyNames: this.terminologyNames
|
|
1841
|
-
}, (err, data) => {
|
|
1842
|
-
if (err)
|
|
1843
|
-
reject(err);
|
|
1844
|
-
else
|
|
1845
|
-
resolve(data.TranslatedText);
|
|
1846
|
-
});
|
|
1847
|
-
});
|
|
1848
|
-
}
|
|
1849
|
-
/**
|
|
1850
|
-
* Get the contents of a PDF template (against a PDFEntity) translated in the desired language,
|
|
1851
|
-
* if the latter isn't between the ones already available.
|
|
1852
|
-
* @return an object that maps original texts with their translations (or nothing).
|
|
1853
|
-
*/
|
|
1854
|
-
pdfTemplate(entity, template, language, languages) {
|
|
1855
|
-
return new Promise(resolve => {
|
|
1856
|
-
// if the language is included in the ones supported by the team, skip
|
|
1857
|
-
if (languages.available.some(l => l === language))
|
|
1858
|
-
return resolve(null);
|
|
1859
|
-
// analyse the template to extract terms to translate based on the entity (using a sourceLanguage as reference)
|
|
1860
|
-
this.analysePDFTemplateForTermsToTranslate(template, entity, languages.default).then(termsToTranslate => {
|
|
1861
|
-
const translations = {};
|
|
1862
|
-
Array.from(termsToTranslate).forEach((original) => __awaiter(this, void 0, void 0, function* () {
|
|
1863
|
-
const translated = yield this.text({
|
|
1864
|
-
sourceLanguageCode: languages.default,
|
|
1865
|
-
targetLanguageCode: language,
|
|
1866
|
-
text: original
|
|
1867
|
-
});
|
|
1868
|
-
translations[original] = translated
|
|
1869
|
-
// fix markdown issue (the translations add a space before and after asterisks)
|
|
1870
|
-
.replace(/\*\* /gm, '**')
|
|
1871
|
-
.replace(/ \*\*/gm, '**');
|
|
1872
|
-
}));
|
|
1873
|
-
resolve(translations);
|
|
1874
|
-
});
|
|
1875
|
-
});
|
|
1876
|
-
}
|
|
1877
|
-
/**
|
|
1878
|
-
* Analyse a PDFTemplate to extract terms to translate based on a PDFEntity (using a sourceLanguage as reference).
|
|
1879
|
-
*/
|
|
1880
|
-
analysePDFTemplateForTermsToTranslate(template, entity, sourceLanguage) {
|
|
1881
|
-
return new Promise(resolve => {
|
|
1882
|
-
const toTranslate = new Set();
|
|
1883
|
-
// gather the terms to translate from contents available on this level
|
|
1884
|
-
template
|
|
1885
|
-
.filter(s => s.isEither(idea_toolbox_1.PDFTemplateSectionTypes.ROW, idea_toolbox_1.PDFTemplateSectionTypes.HEADER))
|
|
1886
|
-
.forEach(s => {
|
|
1887
|
-
switch (s.type) {
|
|
1888
|
-
case idea_toolbox_1.PDFTemplateSectionTypes.ROW:
|
|
1889
|
-
s.columns
|
|
1890
|
-
.filter((_, index) => s.doesColumnContainAField(index))
|
|
1891
|
-
.forEach(field => {
|
|
1892
|
-
field = field;
|
|
1893
|
-
if (field.isComplex()) {
|
|
1894
|
-
const complex = field;
|
|
1895
|
-
toTranslate.add(complex.content[sourceLanguage]);
|
|
1896
|
-
}
|
|
1897
|
-
else {
|
|
1898
|
-
const simple = field;
|
|
1899
|
-
toTranslate.add(simple.label[sourceLanguage]);
|
|
1900
|
-
// try to consider only notes (long fields)
|
|
1901
|
-
if (typeof entity[simple.code] === 'string' && entity[simple.code].length > 50)
|
|
1902
|
-
toTranslate.add(entity[simple.code]);
|
|
1903
|
-
}
|
|
1904
|
-
});
|
|
1905
|
-
break;
|
|
1906
|
-
case idea_toolbox_1.PDFTemplateSectionTypes.HEADER:
|
|
1907
|
-
toTranslate.add(s.title[sourceLanguage]);
|
|
1908
|
-
break;
|
|
1909
|
-
}
|
|
1910
|
-
});
|
|
1911
|
-
// gather inner sections in a flat structure for further elaboraton
|
|
1912
|
-
const innerSections = new Array();
|
|
1913
|
-
template
|
|
1914
|
-
.filter(s => s.isEither(idea_toolbox_1.PDFTemplateSectionTypes.INNER_SECTION, idea_toolbox_1.PDFTemplateSectionTypes.REPEATED_INNER_SECTION))
|
|
1915
|
-
.forEach(s => {
|
|
1916
|
-
switch (s.type) {
|
|
1917
|
-
case idea_toolbox_1.PDFTemplateSectionTypes.INNER_SECTION:
|
|
1918
|
-
innerSections.push({ data: entity[s.context], template: s.innerTemplate });
|
|
1919
|
-
break;
|
|
1920
|
-
case idea_toolbox_1.PDFTemplateSectionTypes.REPEATED_INNER_SECTION:
|
|
1921
|
-
entity[s.context].forEach((element) => innerSections.push({ data: element, template: s.innerTemplate }));
|
|
1922
|
-
break;
|
|
1923
|
-
}
|
|
1924
|
-
});
|
|
1925
|
-
// run (inception) the inner sections to gather terms to translate from inner levels
|
|
1926
|
-
innerSections.forEach((s) => __awaiter(this, void 0, void 0, function* () {
|
|
1927
|
-
const res = yield this.analysePDFTemplateForTermsToTranslate(s.template, s.data, sourceLanguage);
|
|
1928
|
-
res.forEach(x => toTranslate.add(x));
|
|
1929
|
-
}));
|
|
1930
|
-
resolve(toTranslate);
|
|
1931
|
-
});
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
exports.Translate = Translate;
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
/***/ }),
|
|
1938
|
-
|
|
1939
|
-
/***/ 480:
|
|
1940
|
-
/***/ ((module) => {
|
|
1941
|
-
|
|
1942
|
-
module.exports = require("aws-sdk");;
|
|
1943
|
-
|
|
1944
|
-
/***/ }),
|
|
1945
|
-
|
|
1946
|
-
/***/ 747:
|
|
1947
|
-
/***/ ((module) => {
|
|
1948
|
-
|
|
1949
|
-
module.exports = require("fs");;
|
|
1950
|
-
|
|
1951
|
-
/***/ }),
|
|
1952
|
-
|
|
1953
|
-
/***/ 81:
|
|
1954
|
-
/***/ ((module) => {
|
|
1955
|
-
|
|
1956
|
-
module.exports = require("idea-toolbox");;
|
|
1957
|
-
|
|
1958
|
-
/***/ }),
|
|
1959
|
-
|
|
1960
|
-
/***/ 324:
|
|
1961
|
-
/***/ ((module) => {
|
|
1962
|
-
|
|
1963
|
-
module.exports = require("nanoid");;
|
|
1964
|
-
|
|
1965
|
-
/***/ }),
|
|
1966
|
-
|
|
1967
|
-
/***/ 123:
|
|
1968
|
-
/***/ ((module) => {
|
|
1969
|
-
|
|
1970
|
-
module.exports = require("nodemailer");;
|
|
1971
|
-
|
|
1972
|
-
/***/ }),
|
|
1973
|
-
|
|
1974
|
-
/***/ 942:
|
|
1975
|
-
/***/ ((module) => {
|
|
1976
|
-
|
|
1977
|
-
module.exports = require("shortid");;
|
|
1978
|
-
|
|
1979
|
-
/***/ }),
|
|
1980
|
-
|
|
1981
|
-
/***/ 669:
|
|
1982
|
-
/***/ ((module) => {
|
|
1983
|
-
|
|
1984
|
-
module.exports = require("util");;
|
|
1985
|
-
|
|
1986
|
-
/***/ }),
|
|
1987
|
-
|
|
1988
|
-
/***/ 180:
|
|
1989
|
-
/***/ ((module) => {
|
|
1990
|
-
|
|
1991
|
-
module.exports = require("uuid/v4");;
|
|
1992
|
-
|
|
1993
|
-
/***/ })
|
|
1994
|
-
|
|
1995
|
-
/******/ });
|
|
1996
|
-
/************************************************************************/
|
|
1997
|
-
/******/ // The module cache
|
|
1998
|
-
/******/ var __webpack_module_cache__ = {};
|
|
1999
|
-
/******/
|
|
2000
|
-
/******/ // The require function
|
|
2001
|
-
/******/ function __webpack_require__(moduleId) {
|
|
2002
|
-
/******/ // Check if module is in cache
|
|
2003
|
-
/******/ if(__webpack_module_cache__[moduleId]) {
|
|
2004
|
-
/******/ return __webpack_module_cache__[moduleId].exports;
|
|
2005
|
-
/******/ }
|
|
2006
|
-
/******/ // Create a new module (and put it into the cache)
|
|
2007
|
-
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
2008
|
-
/******/ // no module.id needed
|
|
2009
|
-
/******/ // no module.loaded needed
|
|
2010
|
-
/******/ exports: {}
|
|
2011
|
-
/******/ };
|
|
2012
|
-
/******/
|
|
2013
|
-
/******/ // Execute the module function
|
|
2014
|
-
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
2015
|
-
/******/
|
|
2016
|
-
/******/ // Return the exports of the module
|
|
2017
|
-
/******/ return module.exports;
|
|
2018
|
-
/******/ }
|
|
2019
|
-
/******/
|
|
2020
|
-
/************************************************************************/
|
|
2021
|
-
/******/ // module exports must be returned from runtime so entry inlining is disabled
|
|
2022
|
-
/******/ // startup
|
|
2023
|
-
/******/ // Load entry module and return exports
|
|
2024
|
-
/******/ return __webpack_require__(341);
|
|
2025
|
-
/******/ })()
|
|
2026
|
-
;
|
|
2027
|
-
});
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./src/genericController"), exports);
|
|
14
|
+
__exportStar(require("./src/resourceController"), exports);
|
|
15
|
+
__exportStar(require("./src/streamController"), exports);
|
|
16
|
+
__exportStar(require("./src/dynamoDB"), exports);
|
|
17
|
+
__exportStar(require("./src/cognito"), exports);
|
|
18
|
+
__exportStar(require("./src/comprehend"), exports);
|
|
19
|
+
__exportStar(require("./src/s3"), exports);
|
|
20
|
+
__exportStar(require("./src/ses"), exports);
|
|
21
|
+
__exportStar(require("./src/sns"), exports);
|
|
22
|
+
__exportStar(require("./src/translate"), exports);
|
|
23
|
+
__exportStar(require("./src/attachments"), exports);
|