UNPKG

18 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10Object.defineProperty(exports, "__esModule", { value: true });
11const AWS = require("aws-sdk");
12const tools_1 = require("./tools");
13AWS.config.update({ region: 'us-east-1' });
14const kms = new AWS.KMS({ apiVersion: '2014-11-01' });
15function encrypt(data, kmsKeyId) {
16 return new Promise((res, rej) => {
17 try {
18 if (!data || data === '') {
19 return res(null);
20 }
21 kms.encrypt({ KeyId: kmsKeyId, Plaintext: data }, function (err, _data) {
22 if (err) {
23 rej(err);
24 }
25 else {
26 res(_data);
27 }
28 });
29 }
30 catch (error) {
31 rej(error.message);
32 }
33 });
34}
35function decrypt(blob, kmsKeyId) {
36 return new Promise((res, rej) => {
37 try {
38 if ((blob && !blob.CiphertextBlob) || !blob) {
39 return res(blob);
40 }
41 kms.decrypt({ CiphertextBlob: blob.CiphertextBlob }, function (err, _data) {
42 if (err) {
43 console.log(err);
44 rej(err);
45 }
46 else {
47 res(_data);
48 }
49 });
50 }
51 catch (error) {
52 console.log(143, error.message);
53 rej(error.message);
54 }
55 });
56}
57class DynamoDbApi {
58 constructor(dynamoDb, _kmsKeyId) {
59 this.dynamoDb = dynamoDb;
60 this.kmsKeyId = _kmsKeyId;
61 process.setMaxListeners(Infinity);
62 }
63 decryptItem(item, decryptFields) {
64 return __awaiter(this, void 0, void 0, function* () {
65 try {
66 const Keys = Object.keys(item);
67 for (let i = 0; i < Keys.length; i++) {
68 if (item[Keys[i]] && item[Keys[i]]['CiphertextBlob'] && decryptFields.indexOf(Keys[i]) > -1) {
69 const decryptedTmp = yield decrypt(item[Keys[i]], this.kmsKeyId);
70 if (decryptedTmp && decryptedTmp.Plaintext) {
71 const val = decryptedTmp.Plaintext.toString();
72 item[Keys[i]] = val.indexOf('{') > -1 ? JSON.parse(val) : val;
73 }
74 }
75 }
76 }
77 catch (error) {
78 console.log('decryptItem():', error);
79 }
80 return item;
81 });
82 }
83 encryptItem(item, encryptFields) {
84 return __awaiter(this, void 0, void 0, function* () {
85 try {
86 const Keys = Object.keys(item);
87 for (let i = 0; i < Keys.length; i++) {
88 if (item[Keys[i]] && encryptFields.indexOf(Keys[i]) > -1) {
89 const encryptedTmp = yield encrypt(typeof item[Keys[i]] === 'object' ? JSON.stringify(item[Keys[i]]) : item[Keys[i]], this.kmsKeyId);
90 if (encryptedTmp) {
91 item[Keys[i]] = encryptedTmp;
92 }
93 }
94 }
95 }
96 catch (error) {
97 console.log('tools.encryptItem() error:', error.message);
98 }
99 finally {
100 return item;
101 }
102 });
103 }
104 get(params, context, decryptFields) {
105 const dynamoDb = this.dynamoDb;
106 return new Promise((res, rej) => {
107 if (!dynamoDb) {
108 return rej(tools_1.response(false, 'dynamoDbTable undefined'));
109 }
110 try {
111 dynamoDb.get(params, (error, result) => __awaiter(this, void 0, void 0, function* () {
112 if (error) {
113 return rej(tools_1.response(false, error, `Could not get '${context}' info`));
114 }
115 else if (result.Item) {
116 if (decryptFields && decryptFields.length) {
117 result.Item = yield this.decryptItem(result.Item, decryptFields);
118 }
119 return res(tools_1.response(true, null, result.Item));
120 }
121 else {
122 return res(tools_1.response(false, `'${context}' info not found`));
123 }
124 }));
125 }
126 catch (error) {
127 console.log(479, error.message);
128 rej(tools_1.response(false, error));
129 }
130 });
131 }
132 _scan(dynamoDb, params, context, decryptFields) {
133 return __awaiter(this, void 0, void 0, function* () {
134 if (!dynamoDb) {
135 return tools_1.response(false, 'dynamoDbTable undefined');
136 }
137 try {
138 let count = 0;
139 const result = yield dynamoDb.scan(params).promise();
140 if (result.Items && result.Items.length) {
141 if (decryptFields && decryptFields.length) {
142 for (let i = 0; i < result.Items.length; i++) {
143 result.Items[i] = yield this.decryptItem(result.Items[i], decryptFields);
144 }
145 }
146 return tools_1.response(true, null, result);
147 }
148 else {
149 return tools_1.response(false, `${context} info not found`, result);
150 }
151 }
152 catch (error) {
153 console.log('263 Error tools.db._scan()', error.message, params);
154 return tools_1.response(false, error);
155 }
156 });
157 }
158 scan(params, context, decryptFields) {
159 return __awaiter(this, void 0, void 0, function* () {
160 const dynamoDb = this.dynamoDb;
161 try {
162 let items = [], result, whileMax = 1000, i = 0, count = 0, done = false, LastEvaluatedKey = null;
163 while (!done && (i < whileMax)) {
164 result = yield this._scan(dynamoDb, params, context, decryptFields);
165 if (!result.success && !params.Limit) {
166 done = true;
167 return result;
168 }
169 else {
170 if (params.Limit) {
171 if (result.data) {
172 count += result.data.Count;
173 if (!result.data.LastEvaluatedKey) {
174 done = true;
175 items.push(...result.data.Items);
176 }
177 else {
178 if (count === params.Limit) {
179 done = true;
180 items.push(...result.data.Items);
181 LastEvaluatedKey = result.data.LastEvaluatedKey;
182 }
183 else if (count > params.Limit) {
184 done = true;
185 const keys = Object.keys(result.data.LastEvaluatedKey);
186 items.push(...result.data.Items.slice(0, (count - params.Limit)));
187 for (let j = 0; j < keys.length; j++) {
188 LastEvaluatedKey[keys[j]] = result.data.Items[count - params.Limit - 1][keys[j]];
189 }
190 }
191 else {
192 LastEvaluatedKey = result.data.LastEvaluatedKey;
193 params['ExclusiveStartKey'] = LastEvaluatedKey;
194 items.push(...result.data.Items);
195 }
196 }
197 }
198 else {
199 LastEvaluatedKey = result.data.LastEvaluatedKey;
200 params['ExclusiveStartKey'] = LastEvaluatedKey;
201 }
202 }
203 else {
204 done = true;
205 LastEvaluatedKey = result.data.LastEvaluatedKey;
206 items.push(...result.data.Items);
207 }
208 }
209 i++;
210 }
211 return tools_1.response(true, null, {
212 Items: items,
213 Count: items.length,
214 CountV2: result.data.ScannedCount,
215 LastEvaluatedKey: LastEvaluatedKey,
216 Loops: i
217 });
218 }
219 catch (error) {
220 return tools_1.response(false, error);
221 }
222 });
223 }
224 query(params, context, decryptFields) {
225 return __awaiter(this, void 0, void 0, function* () {
226 const dynamoDb = this.dynamoDb;
227 if (!dynamoDb) {
228 return tools_1.response(false, 'dynamoDbTable undefined');
229 }
230 try {
231 const result = yield dynamoDb.query(params).promise();
232 if (result.Items && result.Items.length) {
233 if (decryptFields && decryptFields.length) {
234 for (let i = 0; i < result.Items.length; i++) {
235 result.Items[i] = yield this.decryptItem(result.Items[i], decryptFields);
236 }
237 }
238 return tools_1.response(true, null, result.Items.length > 1 ? result.Items : result.Items[0]);
239 }
240 else {
241 return tools_1.response(false, `'${context}' info not found`);
242 }
243 }
244 catch (error) {
245 console.log('263 Error tools.db.query()', error.message, params);
246 return tools_1.response(false, error.message, `Could not get '${context}' info`);
247 }
248 });
249 }
250 queryRAW(params, context, decryptFields) {
251 return __awaiter(this, void 0, void 0, function* () {
252 const dynamoDb = this.dynamoDb;
253 if (!dynamoDb) {
254 return tools_1.response(false, 'dynamoDbTable undefined');
255 }
256 try {
257 let result = yield dynamoDb.query(params).promise();
258 if (!result) {
259 return tools_1.response(false, `'${context}' - Error on dynamoDb.query(params).promise().`);
260 }
261 let promises = [];
262 if (result.Items && result.Items.length) {
263 if (decryptFields && decryptFields.length) {
264 for (let i = 0; i < result.Items.length; i++) {
265 promises.push(this.decryptItem(result.Items[i], decryptFields));
266 }
267 result = yield Promise.all(promises).then(results => {
268 delete result.Items;
269 result['Items'] = results;
270 return result;
271 });
272 }
273 return tools_1.response(true, null, result);
274 }
275 else {
276 return tools_1.response(false, `'${context}' info not found`, result);
277 }
278 }
279 catch (error) {
280 console.log('263 Error tools.db.query()', error.message, params);
281 return tools_1.response(false, error.message, `Could not get '${context}' info`);
282 }
283 });
284 }
285 delete(params, context, decryptFields) {
286 const dynamoDb = this.dynamoDb;
287 return new Promise((res, rej) => {
288 if (!dynamoDb) {
289 return rej(tools_1.response(false, 'dynamoDbTable undefined'));
290 }
291 try {
292 if (params.force) {
293 dynamoDb.delete(params, (error, result) => __awaiter(this, void 0, void 0, function* () {
294 if (error) {
295 return rej(tools_1.response(false, error, `Could not delete '${context}' info`));
296 }
297 return res(tools_1.response(true, null, result));
298 }));
299 }
300 else {
301 if (!params.Key) {
302 return tools_1.response(false, 'Key is required. Cannot delete item');
303 }
304 const _params = {
305 TableName: params.TableName,
306 Key: params.Key,
307 UpdateExpression: "set deleted =:d",
308 ExpressionAttributeValues: {
309 ":d": true
310 }
311 };
312 dynamoDb.update(_params, (error, result) => {
313 if (error) {
314 console.log(params, error);
315 return rej(tools_1.response(false, error, `Could not update '${context}' item to 'deleted' state`));
316 }
317 else {
318 return res(tools_1.response(true, null, result));
319 }
320 });
321 }
322 }
323 catch (error) {
324 console.log(479, error.message);
325 rej(tools_1.response(false, error));
326 }
327 });
328 }
329 put(params, context, encryptFields) {
330 return new Promise((res, rej) => __awaiter(this, void 0, void 0, function* () {
331 const dynamoDb = this.dynamoDb;
332 try {
333 if (!dynamoDb) {
334 return rej(tools_1.response(false, 'dynamoDbTable undefined'));
335 }
336 if (encryptFields && encryptFields.length) {
337 params.Item = yield this.encryptItem(params.Item, encryptFields);
338 }
339 params.Item.updatedAt = new Date().toISOString();
340 params.Item.createdAt = new Date().toISOString();
341 dynamoDb.put(params, (error, result) => {
342 if (error) {
343 console.log(params, error);
344 return rej(tools_1.response(false, error, `Could not insert '${context}' item`));
345 }
346 else {
347 return res(tools_1.response(true, null, result));
348 }
349 });
350 }
351 catch (error) {
352 console.log('295 tools.db.put()', error);
353 rej(tools_1.response(false, error.message));
354 }
355 }));
356 }
357 getUpdateExpression(item, encryptFields) {
358 return __awaiter(this, void 0, void 0, function* () {
359 let expressions = {}, updates = '';
360 if (encryptFields) {
361 item = yield this.encryptItem(item, encryptFields);
362 }
363 const Keys = Object.keys(item);
364 for (let i = 0; i < Keys.length; i++) {
365 expressions[`:v${i}`] = item[Keys[i]];
366 updates += `${Keys[i]} =:v${i},`;
367 }
368 updates = updates.replace(/(^,)|(,$)/g, "");
369 return {
370 expressions: expressions,
371 updates: updates
372 };
373 });
374 }
375 getUpdateExpressionV2(item, encryptFields) {
376 return __awaiter(this, void 0, void 0, function* () {
377 let attributesValue = {}, attributesName = {}, updates = '';
378 if (encryptFields) {
379 item = yield this.encryptItem(item, encryptFields);
380 }
381 const Keys = Object.keys(item);
382 for (let i = 0; i < Keys.length; i++) {
383 attributesValue[`:v${i}`] = item[Keys[i]];
384 attributesName[`#a${i}`] = Keys[i];
385 updates += `#a${i} =:v${i},`;
386 }
387 updates = updates.replace(/(^,)|(,$)/g, "");
388 return {
389 attributesValue: attributesValue,
390 updates: updates,
391 attributesName: attributesName
392 };
393 });
394 }
395 update(params, context, encryptFields) {
396 const dynamoDb = this.dynamoDb;
397 return new Promise((res, rej) => {
398 if (!dynamoDb) {
399 return rej(tools_1.response(false, 'dynamoDbTable undefined'));
400 }
401 try {
402 params.ExpressionAttributeValues[':upd'] = new Date().toISOString();
403 params.UpdateExpression += ', updatedAt =:upd';
404 dynamoDb.update(params, (error, result) => {
405 if (error) {
406 console.log(params, error);
407 return rej(tools_1.response(false, error));
408 }
409 else {
410 return res(tools_1.response(true, null, result));
411 }
412 });
413 }
414 catch (error) {
415 console.log(error);
416 rej(tools_1.response(false, error));
417 }
418 });
419 }
420}
421exports.DynamoDbApi = DynamoDbApi;
422//# sourceMappingURL=tools.db.js.map
\No newline at end of file