blixify-server 0.1.68 → 0.1.70
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/dist/apis/crypto.d.ts +9 -0
- package/dist/apis/crypto.d.ts.map +1 -0
- package/dist/apis/crypto.js +77 -0
- package/dist/apis/fbWrapper.d.ts.map +1 -1
- package/dist/apis/fbWrapper.js +16 -15
- package/dist/apis/mongoWrapper.d.ts.map +1 -1
- package/dist/apis/mongoWrapper.js +1 -0
- package/dist/apis/postgresqlWrapper.d.ts +35 -0
- package/dist/apis/postgresqlWrapper.d.ts.map +1 -0
- package/dist/apis/postgresqlWrapper.js +514 -0
- package/package.json +4 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class CryptoMiddleware {
|
|
2
|
+
secretKey: string;
|
|
3
|
+
forceDecryption: boolean;
|
|
4
|
+
nextJs: boolean;
|
|
5
|
+
constructor(secretKey: string, forceDecryption: boolean, nextJs: boolean);
|
|
6
|
+
handleDecryption: (data: string) => any;
|
|
7
|
+
init(): (req: any, res: any) => Promise<any>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/apis/crypto.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAC3B,SAAS,SAAM;IACf,eAAe,UAAS;IACxB,MAAM,UAAS;gBAEH,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;IAMxE,gBAAgB,SAAU,MAAM,SAiB9B;IAEF,IAAI,UAG4C,GAAG,OAAO,GAAG;CAmB9D"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CryptoMiddleware = void 0;
|
|
16
|
+
const CryptoJS = require("crypto-js");
|
|
17
|
+
const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
18
|
+
class CryptoMiddleware {
|
|
19
|
+
constructor(secretKey, forceDecryption, nextJs) {
|
|
20
|
+
this.secretKey = "";
|
|
21
|
+
this.forceDecryption = false;
|
|
22
|
+
this.nextJs = false;
|
|
23
|
+
this.handleDecryption = (data) => {
|
|
24
|
+
// Decrypt the data
|
|
25
|
+
const bytes = CryptoJS.AES.decrypt(data, this.secretKey);
|
|
26
|
+
const decrypted = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
|
|
27
|
+
if (decrypted) {
|
|
28
|
+
if (decrypted.baseSignDate) {
|
|
29
|
+
const tolerance = moment_timezone_1.default.duration(1, "minute");
|
|
30
|
+
const startWindow = (0, moment_timezone_1.default)(decrypted.baseSignDate).utc();
|
|
31
|
+
const endWindow = startWindow.clone().add(tolerance);
|
|
32
|
+
const currentUTCDate = (0, moment_timezone_1.default)().utc();
|
|
33
|
+
if (currentUTCDate.isBetween(startWindow, endWindow)) {
|
|
34
|
+
delete decrypted["baseSignDate"];
|
|
35
|
+
return decrypted;
|
|
36
|
+
}
|
|
37
|
+
else
|
|
38
|
+
throw "Error";
|
|
39
|
+
}
|
|
40
|
+
else
|
|
41
|
+
throw "Error";
|
|
42
|
+
}
|
|
43
|
+
return {};
|
|
44
|
+
};
|
|
45
|
+
this.secretKey = secretKey;
|
|
46
|
+
this.forceDecryption = forceDecryption;
|
|
47
|
+
this.nextJs = nextJs;
|
|
48
|
+
}
|
|
49
|
+
init() {
|
|
50
|
+
// eslint-disable-next-line
|
|
51
|
+
const wrapper = this;
|
|
52
|
+
const cryptoMiddleware = function (req, res) {
|
|
53
|
+
var _a, _b;
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
try {
|
|
56
|
+
if (wrapper.forceDecryption && !req.body.sign) {
|
|
57
|
+
throw new Error("Missing signature for signing");
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
if ((_a = req.body) === null || _a === void 0 ? void 0 : _a.sign)
|
|
61
|
+
req.body = wrapper.handleDecryption(req.body.sign);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
throw new Error("Wrong Signature");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
if (wrapper.nextJs)
|
|
69
|
+
return err;
|
|
70
|
+
return res.status(400).json({ error: (_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : "" });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
return cryptoMiddleware;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.CryptoMiddleware = CryptoMiddleware;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fbWrapper.d.ts","sourceRoot":"","sources":["../../src/apis/fbWrapper.ts"],"names":[],"mappings":"AASA,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,EAAE,GAAG,CAAM;IAClB,UAAU,SAAM;IAChB,MAAM,UAAS;IACf,MAAM,EAAE,cAAc,CAQpB;IACF,GAAG,EAAE,UAAU,CAAC;IAEhB,YAAY,QAAS,GAAG,aAEtB;gBAGA,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,EACrD,GAAG,EAAE,UAAU;IAUjB,UAAU,SAAU,GAAG,SAIrB;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC,gCA4E5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCA6CtC;IAEF,OAAO,QAAe,GAAG,OAAO,GAAG,mBA6BjC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCAoItC;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCAkFtC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC,gCAwH5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCA4CtC;IAEF,QAAQ,QAAe,GAAG,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"fbWrapper.d.ts","sourceRoot":"","sources":["../../src/apis/fbWrapper.ts"],"names":[],"mappings":"AASA,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,EAAE,GAAG,CAAM;IAClB,UAAU,SAAM;IAChB,MAAM,UAAS;IACf,MAAM,EAAE,cAAc,CAQpB;IACF,GAAG,EAAE,UAAU,CAAC;IAEhB,YAAY,QAAS,GAAG,aAEtB;gBAGA,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,EACrD,GAAG,EAAE,UAAU;IAUjB,UAAU,SAAU,GAAG,SAIrB;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC,gCA4E5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCA6CtC;IAEF,OAAO,QAAe,GAAG,OAAO,GAAG,mBA6BjC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCAoItC;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCAkFtC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC,gCAwH5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC,gCA4CtC;IAEF,QAAQ,QAAe,GAAG,OAAO,GAAG,mBAmQlC;IAEF,IAAI,YA+EF;CACH"}
|
package/dist/apis/fbWrapper.js
CHANGED
|
@@ -14,7 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.FirebaseWrapper = void 0;
|
|
16
16
|
const firestore_1 = require("firebase-admin/firestore");
|
|
17
|
-
const
|
|
17
|
+
const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
18
18
|
const QueryModel_1 = require("../model/QueryModel");
|
|
19
19
|
const utils_1 = require("./utils");
|
|
20
20
|
/**
|
|
@@ -41,7 +41,7 @@ class FirebaseWrapper {
|
|
|
41
41
|
};
|
|
42
42
|
this.parseModel = (data) => {
|
|
43
43
|
delete data["id"];
|
|
44
|
-
data["baseUpdatedAt"] = (0,
|
|
44
|
+
data["baseUpdatedAt"] = (0, moment_timezone_1.default)().toDate();
|
|
45
45
|
return data;
|
|
46
46
|
};
|
|
47
47
|
this.initBatchCreate = (req, res, workflow) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -94,7 +94,7 @@ class FirebaseWrapper {
|
|
|
94
94
|
if (workflow)
|
|
95
95
|
yield workflow(dataList);
|
|
96
96
|
yield Promise.all(dataList.map((eachData) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
eachData["baseUpdatedAt"] = (0,
|
|
97
|
+
eachData["baseUpdatedAt"] = (0, moment_timezone_1.default)().toDate();
|
|
98
98
|
const batchRef = fbCollection.doc(eachData["id"]);
|
|
99
99
|
batch.set(batchRef, Object.assign({}, eachData));
|
|
100
100
|
})));
|
|
@@ -128,7 +128,7 @@ class FirebaseWrapper {
|
|
|
128
128
|
const fbCollection = this.fbAdmin
|
|
129
129
|
.firestore()
|
|
130
130
|
.collection(this.collection);
|
|
131
|
-
req.body.data["baseUpdatedAt"] = (0,
|
|
131
|
+
req.body.data["baseUpdatedAt"] = (0, moment_timezone_1.default)().toDate();
|
|
132
132
|
if (req.body.unique && ((_a = req.body.data) === null || _a === void 0 ? void 0 : _a[req.body.unique])) {
|
|
133
133
|
const querySnapshot = yield fbCollection
|
|
134
134
|
.where(req.body.unique, "==", (_b = req.body.data) === null || _b === void 0 ? void 0 : _b[req.body.unique])
|
|
@@ -243,7 +243,7 @@ class FirebaseWrapper {
|
|
|
243
243
|
const fbData = eachDataDoc.data();
|
|
244
244
|
filterDataIds.push(fbData.id);
|
|
245
245
|
if (req.body.sensitive) {
|
|
246
|
-
if (!(0,
|
|
246
|
+
if (!(0, moment_timezone_1.default)(req.body.data.baseUpdatedAt).isAfter((0, moment_timezone_1.default)(fbData.baseUpdatedAt.seconds * 1000))) {
|
|
247
247
|
res.status(400).json({ err: "Refresh Sensitive Model" });
|
|
248
248
|
}
|
|
249
249
|
}
|
|
@@ -326,7 +326,7 @@ class FirebaseWrapper {
|
|
|
326
326
|
}
|
|
327
327
|
const { workflowUpdateFields, updatedFields } = (0, utils_1.compareUpdatedFields)(fbData, req.body.data);
|
|
328
328
|
if (req.body.sensitive) {
|
|
329
|
-
if ((0,
|
|
329
|
+
if ((0, moment_timezone_1.default)(req.body.data.baseUpdatedAt).isAfter((0, moment_timezone_1.default)(fbData.baseUpdatedAt.seconds * 1000))) {
|
|
330
330
|
if (workflow)
|
|
331
331
|
yield workflow(workflowUpdateFields);
|
|
332
332
|
const data = this.parseModel(updatedFields);
|
|
@@ -558,12 +558,13 @@ class FirebaseWrapper {
|
|
|
558
558
|
});
|
|
559
559
|
}
|
|
560
560
|
const date = dateRange.split("-");
|
|
561
|
-
const [startDate, endDate = (0,
|
|
561
|
+
const [startDate, endDate = (0, moment_timezone_1.default)().format("DD/MM/YYYY HH:mm:ss"),] = date;
|
|
562
562
|
const isDuration = date.length === 2;
|
|
563
|
-
const isValidStartDate = (0,
|
|
564
|
-
const isValidEndDate = (0,
|
|
565
|
-
|
|
566
|
-
const
|
|
563
|
+
const isValidStartDate = (0, moment_timezone_1.default)(startDate, "DD/MM/YYYY").isValid();
|
|
564
|
+
const isValidEndDate = (0, moment_timezone_1.default)(endDate, "DD/MM/YYYY").isValid();
|
|
565
|
+
//TODO : Client should send timezone
|
|
566
|
+
const isoStartDate = (0, moment_timezone_1.default)(startDate, "DD/MM/YYYY HH:mm:ss").format("YYYY-MM-DD HH:mm:ss");
|
|
567
|
+
const isoEndDate = (0, moment_timezone_1.default)(endDate, "DD/MM/YYYY HH:mm:ss").format("YYYY-MM-DD HH:mm:ss");
|
|
567
568
|
if (!isValidStartDate || !isValidEndDate) {
|
|
568
569
|
res
|
|
569
570
|
.status(400)
|
|
@@ -572,14 +573,14 @@ class FirebaseWrapper {
|
|
|
572
573
|
}
|
|
573
574
|
const id = isDuration
|
|
574
575
|
? dateRange
|
|
575
|
-
: `Begining until ${(0,
|
|
576
|
+
: `Begining until ${(0, moment_timezone_1.default)(isoStartDate).format("DD/MM/YYYY")}`;
|
|
576
577
|
if (isDuration) {
|
|
577
578
|
fbCollection = fbCollection
|
|
578
|
-
.where(dateId, ">=", (0,
|
|
579
|
-
.where(dateId, "<=", (0,
|
|
579
|
+
.where(dateId, ">=", (0, moment_timezone_1.default)(isoStartDate).toDate())
|
|
580
|
+
.where(dateId, "<=", (0, moment_timezone_1.default)(isoEndDate).toDate());
|
|
580
581
|
}
|
|
581
582
|
else {
|
|
582
|
-
fbCollection = fbCollection.where(dateId, "<", (0,
|
|
583
|
+
fbCollection = fbCollection.where(dateId, "<", (0, moment_timezone_1.default)(isoStartDate).toDate());
|
|
583
584
|
}
|
|
584
585
|
let value = 0;
|
|
585
586
|
switch (aggregate.type) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongoWrapper.d.ts","sourceRoot":"","sources":["../../src/apis/mongoWrapper.ts"],"names":[],"mappings":"AAQA,OAAO,cAAc,MAAM,yBAAyB,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAmGD;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,EAAE,GAAG,CAAM;IAClB,UAAU,SAAM;IAChB,MAAM,UAAS;IACf,MAAM,EAAE,cAAc,CAQpB;IACF,GAAG,EAAE,UAAU,CAAC;IAChB,OAAO,SAAM;IACb,KAAK,EAAE,GAAG,CAAC;IAEX,YAAY,QAAS,GAAG,aAEtB;gBAGA,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,EACrD,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI;IAa3D,UAAU,SAAU,GAAG,SAIrB;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC;;mBAyE5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAgDtC;IAEF,OAAO,QAAe,GAAG,OAAO,GAAG;;mBAgCjC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAmJtC;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAwFtC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC;;mBA6H5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAqCtC;IAEF,QAAQ,QAAe,GAAG,OAAO,GAAG;;;;;
|
|
1
|
+
{"version":3,"file":"mongoWrapper.d.ts","sourceRoot":"","sources":["../../src/apis/mongoWrapper.ts"],"names":[],"mappings":"AAQA,OAAO,cAAc,MAAM,yBAAyB,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAmGD;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,EAAE,GAAG,CAAM;IAClB,UAAU,SAAM;IAChB,MAAM,UAAS;IACf,MAAM,EAAE,cAAc,CAQpB;IACF,GAAG,EAAE,UAAU,CAAC;IAChB,OAAO,SAAM;IACb,KAAK,EAAE,GAAG,CAAC;IAEX,YAAY,QAAS,GAAG,aAEtB;gBAGA,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,EACrD,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI;IAa3D,UAAU,SAAU,GAAG,SAIrB;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC;;mBAyE5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAgDtC;IAEF,OAAO,QAAe,GAAG,OAAO,GAAG;;mBAgCjC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAmJtC;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAwFtC;IAEF,eAAe,QACR,GAAG,OACH,GAAG,yBACc,GAAG,EAAE,KAAK,QAAQ,GAAG,CAAC;;mBA6H5C;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAqCtC;IAEF,QAAQ,QAAe,GAAG,OAAO,GAAG;;;;;mBAoQlC;IAEF,IAAI,YA+EF;CACH"}
|
|
@@ -668,6 +668,7 @@ class MongoWrapper {
|
|
|
668
668
|
const isDuration = date.length === 2;
|
|
669
669
|
const isValidStartDate = (0, moment_timezone_1.default)(startDate, "DD/MM/YYYY").isValid();
|
|
670
670
|
const isValidEndDate = (0, moment_timezone_1.default)(endDate, "DD/MM/YYYY").isValid();
|
|
671
|
+
//TODO : Client should send timezone
|
|
671
672
|
const isoStartDate = (0, moment_timezone_1.default)(startDate, "DD/MM/YYYY HH:mm:ss")
|
|
672
673
|
.tz("Asia/Kuala_lumpur")
|
|
673
674
|
.toDate();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import SecurityConfig from "../model/SecurityConfig";
|
|
2
|
+
export interface WrapperLib {
|
|
3
|
+
express?: any;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* @Wrapper
|
|
7
|
+
* collection - PostgreSQL Collection
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
export declare class PostgreSQLWrapper {
|
|
11
|
+
pgDB: any;
|
|
12
|
+
collection: string;
|
|
13
|
+
isProd: boolean;
|
|
14
|
+
config: SecurityConfig;
|
|
15
|
+
lib: WrapperLib;
|
|
16
|
+
debug: any;
|
|
17
|
+
modelChecker: (obj: any) => boolean;
|
|
18
|
+
constructor(pgDB: any, collection: string, isProd: boolean, config: SecurityConfig, modelChecker: (obj: any, ignore?: boolean) => boolean, lib: WrapperLib, debug?: (reqBody: any, curBody: any, errMsg: any) => void);
|
|
19
|
+
buildUpdateQuery(pgData: any): string;
|
|
20
|
+
initCreate: (req: any, res: any, workflow?: ((data: any) => Promise<any>) | undefined) => Promise<{
|
|
21
|
+
success: boolean;
|
|
22
|
+
} | undefined>;
|
|
23
|
+
initGet: (req: any, res: any) => Promise<{
|
|
24
|
+
data: null;
|
|
25
|
+
} | undefined>;
|
|
26
|
+
initUpdate: (req: any, res: any, workflow?: ((data: any) => Promise<any>) | undefined) => Promise<{
|
|
27
|
+
success: boolean;
|
|
28
|
+
} | undefined>;
|
|
29
|
+
initDelete: (req: any, res: any, workflow?: ((data: any) => Promise<any>) | undefined) => Promise<{
|
|
30
|
+
success: boolean;
|
|
31
|
+
} | undefined>;
|
|
32
|
+
initList: (req: any, res: any) => Promise<void>;
|
|
33
|
+
init: () => any;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=postgresqlWrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgresqlWrapper.d.ts","sourceRoot":"","sources":["../../src/apis/postgresqlWrapper.ts"],"names":[],"mappings":"AAQA,OAAO,cAAc,MAAM,yBAAyB,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B,IAAI,EAAE,GAAG,CAAM;IACf,UAAU,SAAM;IAChB,MAAM,UAAS;IACf,MAAM,EAAE,cAAc,CAQpB;IACF,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,GAAG,CAAC;IAEX,YAAY,QAAS,GAAG,aAEtB;gBAGA,IAAI,EAAE,GAAG,EACT,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,cAAc,EACtB,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,EACrD,GAAG,EAAE,UAAU,EACf,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI;IAqB3D,gBAAgB,CAAC,MAAM,EAAE,GAAG;IAM5B,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAuDtC;IAEF,OAAO,QAAe,GAAG,OAAO,GAAG;;mBAiCjC;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAgFtC;IAEF,UAAU,QACH,GAAG,OACH,GAAG,qBACU,GAAG,KAAK,QAAQ,GAAG,CAAC;;mBAmCtC;IAEF,QAAQ,QAAe,GAAG,OAAO,GAAG,mBAgPlC;IAEF,IAAI,YA+EF;CACH"}
|
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.PostgreSQLWrapper = void 0;
|
|
16
|
+
const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
17
|
+
const QueryModel_1 = require("../model/QueryModel");
|
|
18
|
+
const utils_1 = require("./utils");
|
|
19
|
+
/**
|
|
20
|
+
* @Wrapper
|
|
21
|
+
* collection - PostgreSQL Collection
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
class PostgreSQLWrapper {
|
|
25
|
+
constructor(pgDB, collection, isProd, config, modelChecker, lib, debug) {
|
|
26
|
+
this.pgDB = "";
|
|
27
|
+
this.collection = "";
|
|
28
|
+
this.isProd = false;
|
|
29
|
+
this.config = {
|
|
30
|
+
baseConfig: [],
|
|
31
|
+
opsConfig: {
|
|
32
|
+
read: [],
|
|
33
|
+
create: [],
|
|
34
|
+
update: [],
|
|
35
|
+
delete: [],
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
// eslint-disable-next-line
|
|
39
|
+
this.modelChecker = (obj) => {
|
|
40
|
+
return false;
|
|
41
|
+
};
|
|
42
|
+
this.initCreate = (req, res, workflow) => __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
try {
|
|
45
|
+
const valid = this.modelChecker(req.body.data);
|
|
46
|
+
if (valid) {
|
|
47
|
+
//INFO : Security Checker
|
|
48
|
+
const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
|
|
49
|
+
const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, "create", req, req.body.data);
|
|
50
|
+
if (!validBaseConfig || !validOpsConfig) {
|
|
51
|
+
res.status(400).json({ err: "Invalid Security Configuration" });
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// req.body.data["baseUpdatedAt"] = moment().toDate();
|
|
55
|
+
if (req.body.unique && ((_a = req.body.data) === null || _a === void 0 ? void 0 : _a[req.body.unique])) {
|
|
56
|
+
const uniqueField = req.body.unique;
|
|
57
|
+
const uniqueValue = req.body.data[uniqueField];
|
|
58
|
+
const { rowCount } = yield this.pgDB.query(`SELECT * FROM ${this.collection} WHERE ${uniqueField} = $1 LIMIT 1`, [uniqueValue]);
|
|
59
|
+
if (rowCount > 0) {
|
|
60
|
+
res
|
|
61
|
+
.status(400)
|
|
62
|
+
.json({ err: `Unique:${req.body.data[req.body.unique]} exists` });
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (workflow)
|
|
67
|
+
yield workflow(req.body.data);
|
|
68
|
+
const columns = Object.keys(req.body.data).join(", ");
|
|
69
|
+
const values = Object.values(req.body.data);
|
|
70
|
+
const placeholders = values
|
|
71
|
+
.map((_, index) => `$${index + 1}`)
|
|
72
|
+
.join(", ");
|
|
73
|
+
yield this.pgDB.query(`INSERT INTO ${this.collection} (${columns}) VALUES (${placeholders})`, values);
|
|
74
|
+
const resBody = { success: true };
|
|
75
|
+
if ((_b = req.body) === null || _b === void 0 ? void 0 : _b.stopRes)
|
|
76
|
+
return resBody;
|
|
77
|
+
res.send(resBody);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
res.status(400).json({ err: "Invalid Model Structure" });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
res.status(400).json({ err: err });
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
this.initGet = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
var _c;
|
|
89
|
+
try {
|
|
90
|
+
const valid = req.body.id;
|
|
91
|
+
if (valid) {
|
|
92
|
+
//INFO : Security Checker
|
|
93
|
+
const pgResult = yield this.pgDB.query(`SELECT * FROM ${this.collection} WHERE id = $1 LIMIT 1`, [valid]);
|
|
94
|
+
const resBody = { data: null };
|
|
95
|
+
if (pgResult.rowCount > 0) {
|
|
96
|
+
const pgData = pgResult.rows[0];
|
|
97
|
+
const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
|
|
98
|
+
const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, "read", req, pgData);
|
|
99
|
+
if (!validBaseConfig || !validOpsConfig) {
|
|
100
|
+
res.status(400).json({ err: "Invalid Security Configuration" });
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
resBody["data"] = pgData;
|
|
104
|
+
}
|
|
105
|
+
if ((_c = req.body) === null || _c === void 0 ? void 0 : _c.stopRes)
|
|
106
|
+
return resBody;
|
|
107
|
+
res.send(resBody);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
res.status(400).json({ err: "Invalid Fields" });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
res.status(400).json({ err: err });
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
this.initUpdate = (req, res, workflow) => __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
var _d, _e, _f;
|
|
119
|
+
try {
|
|
120
|
+
const valid = this.modelChecker(req.body.data) && req.body.id;
|
|
121
|
+
if (valid) {
|
|
122
|
+
const pgResult = yield this.pgDB.query(`SELECT * FROM ${this.collection} WHERE id = $1`, [valid]);
|
|
123
|
+
if (pgResult.rowCount > 0) {
|
|
124
|
+
const pgData = pgResult.rows[0];
|
|
125
|
+
if (this.debug)
|
|
126
|
+
this.debug(req.body, pgData);
|
|
127
|
+
const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
|
|
128
|
+
const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, "update", req, pgData);
|
|
129
|
+
if (!validBaseConfig || !validOpsConfig) {
|
|
130
|
+
res.status(400).json({ err: "Invalid Security Configuration" });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (req.body.unique && ((_d = req.body.data) === null || _d === void 0 ? void 0 : _d[req.body.unique])) {
|
|
134
|
+
const uniqueField = req.body.unique;
|
|
135
|
+
const uniqueValue = req.body.data[uniqueField];
|
|
136
|
+
const { rowCount } = yield this.pgDB.query(`SELECT * FROM ${this.collection} WHERE ${uniqueField} = $1 LIMIT 1`, [uniqueValue]);
|
|
137
|
+
if (rowCount > 0) {
|
|
138
|
+
res.status(400).json({
|
|
139
|
+
err: `Unique:${req.body.data[req.body.unique]} exists`,
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const { updatedFields } = (0, utils_1.compareUpdatedFields)(pgData, req.body.data);
|
|
145
|
+
const resBody = { success: true };
|
|
146
|
+
if (workflow)
|
|
147
|
+
yield workflow(updatedFields);
|
|
148
|
+
// const data = this.parseModel(updatedFields);
|
|
149
|
+
//INFO : Security Checker
|
|
150
|
+
const updateQuery = this.buildUpdateQuery(updatedFields);
|
|
151
|
+
const sqlQuery = `UPDATE ${this.collection} SET ${updateQuery} WHERE id = $${Object.keys(updatedFields).length + 1}`;
|
|
152
|
+
const values = [...Object.values(updatedFields), valid];
|
|
153
|
+
if (req.body.sensitive) {
|
|
154
|
+
if ((0, moment_timezone_1.default)(req.body.data.baseUpdatedAt).isAfter((0, moment_timezone_1.default)(pgData.baseUpdatedAt))) {
|
|
155
|
+
yield this.pgDB.query(sqlQuery, values);
|
|
156
|
+
if ((_e = req.body) === null || _e === void 0 ? void 0 : _e.stopRes)
|
|
157
|
+
return resBody;
|
|
158
|
+
res.send(resBody);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
res.status(400).json({ err: "Refresh Sensitive Model" });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
yield this.pgDB.query(sqlQuery, values);
|
|
166
|
+
if ((_f = req.body) === null || _f === void 0 ? void 0 : _f.stopRes)
|
|
167
|
+
return resBody;
|
|
168
|
+
res.send(resBody);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else
|
|
172
|
+
throw "No Data Found";
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
throw "Invalid Model Structure";
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
if (this.debug)
|
|
180
|
+
this.debug(null, null, err);
|
|
181
|
+
res.status(400).json({ err: err });
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
this.initDelete = (req, res, workflow) => __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
var _g;
|
|
186
|
+
try {
|
|
187
|
+
const valid = req.body.id;
|
|
188
|
+
if (valid) {
|
|
189
|
+
const pgResult = yield this.pgDB.query(`SELECT * FROM ${this.collection} WHERE id = $1 LIMIT 1`, [valid]);
|
|
190
|
+
if (pgResult.rowCount > 0) {
|
|
191
|
+
const pgData = pgResult.rows[0];
|
|
192
|
+
const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
|
|
193
|
+
const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, "read", req, pgData);
|
|
194
|
+
if (!validBaseConfig || !validOpsConfig) {
|
|
195
|
+
res.status(400).json({ err: "Invalid Security Configuration" });
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (workflow)
|
|
199
|
+
yield workflow(pgData);
|
|
200
|
+
yield this.pgDB.query(`DELETE FROM ${this.collection} WHERE id = $1`, [valid]);
|
|
201
|
+
const resBody = { success: true };
|
|
202
|
+
if ((_g = req.body) === null || _g === void 0 ? void 0 : _g.stopRes)
|
|
203
|
+
return resBody;
|
|
204
|
+
res.send(resBody);
|
|
205
|
+
}
|
|
206
|
+
else
|
|
207
|
+
throw "No Data Found";
|
|
208
|
+
}
|
|
209
|
+
else
|
|
210
|
+
throw "Invalid Fields";
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
res.status(400).json({ err: err });
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
this.initList = (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
217
|
+
var _h, _j, _k, _l, _m;
|
|
218
|
+
try {
|
|
219
|
+
//INFO : Security Checker
|
|
220
|
+
const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
|
|
221
|
+
if (validBaseConfig) {
|
|
222
|
+
const aggregate = req.body.aggregate;
|
|
223
|
+
const queryList = (_h = req.body.query) !== null && _h !== void 0 ? _h : [];
|
|
224
|
+
if (aggregate) {
|
|
225
|
+
const queryId = (_j = aggregate.queryId) !== null && _j !== void 0 ? _j : "";
|
|
226
|
+
const dateId = (_k = aggregate.dateId) !== null && _k !== void 0 ? _k : "baseUpdatedAt";
|
|
227
|
+
const dateRanges = (_l = aggregate.range) !== null && _l !== void 0 ? _l : [];
|
|
228
|
+
const dataList = [];
|
|
229
|
+
for (const dateRange of dateRanges) {
|
|
230
|
+
//INFO : Step 1 - Query
|
|
231
|
+
let query = `SELECT * FROM ${this.collection}`;
|
|
232
|
+
const whereClauses = [];
|
|
233
|
+
if (queryList && queryList.length > 0) {
|
|
234
|
+
queryList.map((eachQuery) => {
|
|
235
|
+
var _a;
|
|
236
|
+
const queryId = (_a = eachQuery.queryId) !== null && _a !== void 0 ? _a : "";
|
|
237
|
+
const value = eachQuery.value;
|
|
238
|
+
switch (eachQuery.type) {
|
|
239
|
+
case "=":
|
|
240
|
+
whereClauses.push(`${queryId} = ${value}`);
|
|
241
|
+
break;
|
|
242
|
+
case "!=":
|
|
243
|
+
whereClauses.push(`${queryId} != ${value}`);
|
|
244
|
+
break;
|
|
245
|
+
case ">":
|
|
246
|
+
whereClauses.push(`${queryId} > ${value}`);
|
|
247
|
+
break;
|
|
248
|
+
case "<":
|
|
249
|
+
whereClauses.push(`${queryId} < ${value}`);
|
|
250
|
+
break;
|
|
251
|
+
case "><":
|
|
252
|
+
if (Array.isArray(value) && value.length >= 2) {
|
|
253
|
+
whereClauses.push(`${queryId} BETWEEN ${value[0]} AND ${value[1]}`);
|
|
254
|
+
}
|
|
255
|
+
break;
|
|
256
|
+
case "in":
|
|
257
|
+
whereClauses.push(`${queryId} IN (${value
|
|
258
|
+
.map((eachValue) => `'${eachValue}'`)
|
|
259
|
+
.join(", ")})`);
|
|
260
|
+
break;
|
|
261
|
+
default:
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
const date = dateRange.split("-");
|
|
267
|
+
const [startDate, endDate = (0, moment_timezone_1.default)().format("DD/MM/YYYY HH:mm:ss"),] = date;
|
|
268
|
+
const isDuration = date.length === 2;
|
|
269
|
+
const isValidStartDate = (0, moment_timezone_1.default)(startDate, "DD/MM/YYYY").isValid();
|
|
270
|
+
const isValidEndDate = (0, moment_timezone_1.default)(endDate, "DD/MM/YYYY").isValid();
|
|
271
|
+
const startMoment = (0, moment_timezone_1.default)(startDate, "DD/MM/YYYY HH:mm:ss").tz("Asia/Kuala_lumpur");
|
|
272
|
+
const endMoment = (0, moment_timezone_1.default)(endDate, "DD/MM/YYYY HH:mm:ss").tz("Asia/Kuala_lumpur");
|
|
273
|
+
const isoStartDate = startMoment.toDate();
|
|
274
|
+
const queryStartDate = startMoment.toISOString();
|
|
275
|
+
const queryEndDate = endMoment.toISOString();
|
|
276
|
+
if (!isValidStartDate || !isValidEndDate) {
|
|
277
|
+
res
|
|
278
|
+
.status(400)
|
|
279
|
+
.json({ err: "Invalid Aggregate Range Configuration" });
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const id = isDuration
|
|
283
|
+
? dateRange
|
|
284
|
+
: `Begining until ${(0, moment_timezone_1.default)(isoStartDate).format("DD/MM/YYYY")}`;
|
|
285
|
+
if (isDuration) {
|
|
286
|
+
whereClauses.push(`${dateId} BETWEEN '${queryStartDate}' AND '${queryEndDate}'`);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
whereClauses.push(`${dateId} < '${queryStartDate}'`);
|
|
290
|
+
}
|
|
291
|
+
const allWhereClauses = `${whereClauses.length > 0
|
|
292
|
+
? "WHERE " + whereClauses.join(" AND ")
|
|
293
|
+
: ""}`;
|
|
294
|
+
let value = 0;
|
|
295
|
+
switch (aggregate.type) {
|
|
296
|
+
case "count":
|
|
297
|
+
query = `SELECT COUNT(*) as count FROM ${this.collection} ${allWhereClauses}`;
|
|
298
|
+
const countResult = yield this.pgDB.query(query);
|
|
299
|
+
value = parseInt(countResult.rows[0].count, 10);
|
|
300
|
+
break;
|
|
301
|
+
case "sum":
|
|
302
|
+
query = `SELECT SUM(${queryId}) as sum FROM ${this.collection} ${allWhereClauses}`;
|
|
303
|
+
const sumResult = yield this.pgDB.query(query);
|
|
304
|
+
value = parseFloat(sumResult.rows[0].sum);
|
|
305
|
+
break;
|
|
306
|
+
case "avg":
|
|
307
|
+
query = `SELECT AVG(${queryId}) as avg FROM ${this.collection} ${allWhereClauses}`;
|
|
308
|
+
const avgResult = yield this.pgDB.query(query);
|
|
309
|
+
value = parseFloat(avgResult.rows[0].avg);
|
|
310
|
+
break;
|
|
311
|
+
case "value":
|
|
312
|
+
query = `SELECT * FROM ${this.collection} ${allWhereClauses} ORDER BY ${dateId} DESC LIMIT 1`;
|
|
313
|
+
const valueResult = yield this.pgDB.query(query);
|
|
314
|
+
if (valueResult.rows.length > 0)
|
|
315
|
+
value = valueResult.rows[0][queryId];
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
dataList.push({
|
|
321
|
+
_id: id,
|
|
322
|
+
value: value,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
res.send({
|
|
326
|
+
data: dataList,
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
//INFO : Step 1 - Query
|
|
331
|
+
let query = `SELECT * FROM ${this.collection}`;
|
|
332
|
+
const whereClauses = [];
|
|
333
|
+
if (queryList && queryList.length > 0) {
|
|
334
|
+
queryList.map((eachQuery) => {
|
|
335
|
+
var _a;
|
|
336
|
+
const queryId = (_a = eachQuery.queryId) !== null && _a !== void 0 ? _a : "";
|
|
337
|
+
const value = eachQuery.value;
|
|
338
|
+
switch (eachQuery.type) {
|
|
339
|
+
case "search":
|
|
340
|
+
if (eachQuery.searchIds && eachQuery.searchIds.length > 0) {
|
|
341
|
+
whereClauses.push(`${eachQuery.searchIds[0]} ILIKE '${value}%'`);
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
case "=":
|
|
345
|
+
whereClauses.push(`${queryId} = '${value}'`);
|
|
346
|
+
break;
|
|
347
|
+
case "!=":
|
|
348
|
+
whereClauses.push(`${queryId} != '${value}'`);
|
|
349
|
+
break;
|
|
350
|
+
case ">":
|
|
351
|
+
whereClauses.push(`${queryId} > '${value}'`);
|
|
352
|
+
break;
|
|
353
|
+
case "<":
|
|
354
|
+
whereClauses.push(`${queryId} < '${value}'`);
|
|
355
|
+
break;
|
|
356
|
+
case "><":
|
|
357
|
+
if (Array.isArray(value) && value.length >= 2) {
|
|
358
|
+
whereClauses.push(`${queryId} BETWEEN '${value[0]}' AND '${value[1]}'`);
|
|
359
|
+
}
|
|
360
|
+
break;
|
|
361
|
+
case "in":
|
|
362
|
+
whereClauses.push(`${queryId} IN (${value
|
|
363
|
+
.map((eachValue) => `'${eachValue}'`)
|
|
364
|
+
.join(", ")})`);
|
|
365
|
+
break;
|
|
366
|
+
default:
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
const allWhereClauses = `${whereClauses.length > 0 ? "WHERE " + whereClauses.join(" AND ") : ""}`;
|
|
372
|
+
query += ` ${allWhereClauses}`;
|
|
373
|
+
//INFO : Step 2 - Sort
|
|
374
|
+
if (req.body.sort) {
|
|
375
|
+
const sortReq = req.body.sort;
|
|
376
|
+
query += ` ORDER BY ${sortReq.sortId} ${sortReq.type === "asc" ? "ASC" : "DESC"}`;
|
|
377
|
+
}
|
|
378
|
+
//INFO : Step 3 - Pagination
|
|
379
|
+
if (req.body.cursor) {
|
|
380
|
+
query += ` OFFSET ${req.body.cursor}`;
|
|
381
|
+
}
|
|
382
|
+
//INFO : Step 4 - Limit
|
|
383
|
+
if (!req.body.stopLimit) {
|
|
384
|
+
const limit = (_m = req.body.limit) !== null && _m !== void 0 ? _m : 10;
|
|
385
|
+
query += ` LIMIT ${limit}`;
|
|
386
|
+
}
|
|
387
|
+
const { rows, rowCount } = yield this.pgDB.query(query);
|
|
388
|
+
//INFO : Security Checker
|
|
389
|
+
let validOpsConfig = true;
|
|
390
|
+
const dataList = [];
|
|
391
|
+
if (rows) {
|
|
392
|
+
rows.forEach((eachData) => {
|
|
393
|
+
dataList.push(eachData);
|
|
394
|
+
if (!(0, QueryModel_1.checkOpsConfig)(this.config, "read", req, eachData)) {
|
|
395
|
+
validOpsConfig = false;
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
if (!validBaseConfig || !validOpsConfig) {
|
|
400
|
+
res.status(400).json({ err: "Invalid Security Configuration" });
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
res.send({
|
|
404
|
+
data: dataList,
|
|
405
|
+
count: rowCount,
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
res.status(400).json({ err: "Invalid Security Configuration" });
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
catch (err) {
|
|
414
|
+
if (err.message)
|
|
415
|
+
res.status(400).json({ err: err.message });
|
|
416
|
+
else
|
|
417
|
+
res.status(400).json({ err: err });
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
this.init = () => {
|
|
421
|
+
const router = this.lib.express.Router();
|
|
422
|
+
/**
|
|
423
|
+
* @Input :
|
|
424
|
+
* data - Model
|
|
425
|
+
* unique - string (Optional)
|
|
426
|
+
*/
|
|
427
|
+
router.post("/create", (req, res) => {
|
|
428
|
+
this.initCreate(req, res);
|
|
429
|
+
});
|
|
430
|
+
/**
|
|
431
|
+
* @Input :
|
|
432
|
+
* data - Model
|
|
433
|
+
* unique - string (Optional)
|
|
434
|
+
*/
|
|
435
|
+
// router.post("/batchCreate", (req: any, res: any) => {
|
|
436
|
+
// this.initBatchCreate(req, res);
|
|
437
|
+
// });
|
|
438
|
+
/**
|
|
439
|
+
* @Input :
|
|
440
|
+
* id - string
|
|
441
|
+
*/
|
|
442
|
+
router.post("/get", (req, res) => {
|
|
443
|
+
this.initGet(req, res);
|
|
444
|
+
});
|
|
445
|
+
/**
|
|
446
|
+
* @Input :
|
|
447
|
+
* data - Model
|
|
448
|
+
* id - string
|
|
449
|
+
* unique - string (Optional)
|
|
450
|
+
*/
|
|
451
|
+
router.post("/update", (req, res) => {
|
|
452
|
+
this.initUpdate(req, res);
|
|
453
|
+
});
|
|
454
|
+
/**
|
|
455
|
+
* @Input :
|
|
456
|
+
* data - Model
|
|
457
|
+
* query - Query[]
|
|
458
|
+
* unsetData - string[] (Unset Attribute Id) (Optional)
|
|
459
|
+
* isOr - boolean (Optional)
|
|
460
|
+
*/
|
|
461
|
+
// router.post("/batchUpdate", (req: any, res: any) => {
|
|
462
|
+
// this.initBatchUpdate(req, res);
|
|
463
|
+
// });
|
|
464
|
+
/**
|
|
465
|
+
* @Input :
|
|
466
|
+
* id - string
|
|
467
|
+
*/
|
|
468
|
+
router.post("/delete", (req, res) => {
|
|
469
|
+
this.initDelete(req, res);
|
|
470
|
+
});
|
|
471
|
+
/**
|
|
472
|
+
* @Input :
|
|
473
|
+
* id - string[]
|
|
474
|
+
*/
|
|
475
|
+
// router.post("/batchDelete", (req: any, res: any) => {
|
|
476
|
+
// this.initBatchDelete(req, res);
|
|
477
|
+
// });
|
|
478
|
+
/**
|
|
479
|
+
* @Input
|
|
480
|
+
* query - Query interface (Optional)
|
|
481
|
+
* cursor - any (Optional)
|
|
482
|
+
* limit - number (Optional)
|
|
483
|
+
* sort - Sort interface (Optional)
|
|
484
|
+
* stopLimit - boolean to retreive all data (Optional)
|
|
485
|
+
*/
|
|
486
|
+
router.post("/list", (req, res) => {
|
|
487
|
+
this.initList(req, res);
|
|
488
|
+
});
|
|
489
|
+
return router;
|
|
490
|
+
};
|
|
491
|
+
this.pgDB = pgDB;
|
|
492
|
+
this.collection = collection;
|
|
493
|
+
this.isProd = isProd;
|
|
494
|
+
this.config = config;
|
|
495
|
+
this.modelChecker = modelChecker;
|
|
496
|
+
this.lib = lib;
|
|
497
|
+
this.debug = debug;
|
|
498
|
+
}
|
|
499
|
+
//TODO: Parse Model
|
|
500
|
+
//TODO: Batch Create & Update
|
|
501
|
+
//TODO: Change table schema dynanically
|
|
502
|
+
//TODO: Count algorithm is wrong
|
|
503
|
+
// parseModel = (data: any) => {
|
|
504
|
+
// delete data["_id"];
|
|
505
|
+
// data["baseUpdatedAt"] = moment().toDate();
|
|
506
|
+
// return data;
|
|
507
|
+
// };
|
|
508
|
+
buildUpdateQuery(pgData) {
|
|
509
|
+
return Object.keys(pgData)
|
|
510
|
+
.map((key, index) => `${key} = $${index + 1}`)
|
|
511
|
+
.join(", ");
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
exports.PostgreSQLWrapper = PostgreSQLWrapper;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blixify-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.70",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/apis/index.js",
|
|
6
6
|
"private": false,
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"build": "yarn run lint && tsc --build \"./tsconfig.json\"",
|
|
22
22
|
"deploy": "yarn run lint && tsc --build \"./buildtsconfig.json\"",
|
|
23
23
|
"lint": "eslint . --max-warnings=0",
|
|
24
|
+
"start:postgres": "cd dist && node postgresServer.js",
|
|
24
25
|
"start:mongo": "cd dist && node mongoServer.js",
|
|
25
26
|
"start:fb": "cd dist && node firebaseServer.js",
|
|
26
27
|
"start:aws": "cd dist && node awsServer.js",
|
|
@@ -37,9 +38,11 @@
|
|
|
37
38
|
"dependencies": {
|
|
38
39
|
"@types/uuid": "^9.0.7",
|
|
39
40
|
"axios": "^1.4.0",
|
|
41
|
+
"crypto-js": "^4.2.0",
|
|
40
42
|
"mime": "^3.0.0",
|
|
41
43
|
"moment": "^2.29.4",
|
|
42
44
|
"moment-timezone": "^0.5.43",
|
|
45
|
+
"pg": "^8.12.0",
|
|
43
46
|
"uuid": "^9.0.1"
|
|
44
47
|
},
|
|
45
48
|
"devDependencies": {
|