corebasic 1.0.216 → 1.0.218
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/libs/auth.js +6 -3
- package/dist/libs/compression.js +1 -0
- package/dist/libs/elabase.js +1 -0
- package/dist/libs/features.js +2 -0
- package/dist/libs/kafka.js +1 -0
- package/dist/libs/messaging.js +3 -1
- package/dist/libs/session.js +16 -15
- package/dist/libs/utils.js +88 -42
- package/libs/auth.ts +6 -3
- package/libs/compression.ts +1 -0
- package/libs/dip/suffix/index.ts +1 -1
- package/libs/dip/suffix/policy.ts +3 -2
- package/libs/dip/suffix/suffix.ts +2 -2
- package/libs/dip.ts +1 -1
- package/libs/elabase.ts +5 -4
- package/libs/features.ts +2 -0
- package/libs/kafka.ts +3 -2
- package/libs/messaging.ts +4 -1
- package/libs/session.ts +13 -7
- package/libs/utils.ts +126 -61
- package/package.json +1 -4
- package/libs/ObjectId.ts +0 -123
package/dist/libs/auth.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
// @ts-ignore
|
|
1
2
|
import axios from 'axios';
|
|
3
|
+
// @ts-ignore
|
|
2
4
|
import otpGenerator from 'otp-generator';
|
|
3
5
|
import * as Dip from './dip.js';
|
|
4
6
|
import * as Utils from './utils.js';
|
|
@@ -35,7 +37,8 @@ async function attemptLogin(req, res) {
|
|
|
35
37
|
let meta = { company: "GLOBAL", outlet: "GLOBAL" };
|
|
36
38
|
let expiry = 300000;
|
|
37
39
|
let userMob = req.body.mob ?? req.body.phone;
|
|
38
|
-
|
|
40
|
+
const code = req.body.code;
|
|
41
|
+
let mob = userMob.endsWith('123456789') ? '0123456789' : Utils.parseMob(userMob, code);
|
|
39
42
|
let time = new Date().getTime();
|
|
40
43
|
let collection = (req.body.app ? req.body.app + '.' : '') + "auth.login";
|
|
41
44
|
let errMessage = { success: false, message: "Login Server Error" };
|
|
@@ -52,7 +55,7 @@ async function attemptLogin(req, res) {
|
|
|
52
55
|
catch (err) {
|
|
53
56
|
throw { ...errMessage, mode: 'verify', info: 'Cleanup Failed' };
|
|
54
57
|
}
|
|
55
|
-
return { ...res[0], mode: 'verify', success: true, userId: res[0].userId, phone: res[0]._id, mob: res[0]._id };
|
|
58
|
+
return { ...res[0], mode: 'verify', success: true, userId: res[0].userId, phone: res[0]._id, mob: res[0]._id, code };
|
|
56
59
|
}
|
|
57
60
|
throw { ...errMessage, mode: 'verify', info: "Invalid/Expired OTP" };
|
|
58
61
|
}
|
|
@@ -64,7 +67,7 @@ async function attemptLogin(req, res) {
|
|
|
64
67
|
let data = req.body.data ?? {};
|
|
65
68
|
let info = { clientId, created: now, updated: now, ...data };
|
|
66
69
|
await Dip.update(meta, collection, { _id: mob }, { $set: { otp, clientId, time, updated: now, attemptLogin: true }, $setOnInsert: { _id: mob, otp, time, userId, ...info } }, { upsert: true });
|
|
67
|
-
return { mode: 'login', success: true, userId, expiry, phone: mob, mob };
|
|
70
|
+
return { mode: 'login', success: true, userId, expiry, phone: mob, mob, code };
|
|
68
71
|
}
|
|
69
72
|
throw { ...errMessage, mode: 'login', info: 'Generating Info Failed' };
|
|
70
73
|
}
|
package/dist/libs/compression.js
CHANGED
package/dist/libs/elabase.js
CHANGED
package/dist/libs/features.js
CHANGED
|
@@ -11,7 +11,9 @@ import * as Kafka from './kafka.js';
|
|
|
11
11
|
import * as Utils from './utils.js';
|
|
12
12
|
import * as Session from './session.js';
|
|
13
13
|
import * as Messaging from './messaging.js';
|
|
14
|
+
// @ts-ignore
|
|
14
15
|
import axios from 'axios';
|
|
16
|
+
// @ts-ignore
|
|
15
17
|
import jwt from 'jsonwebtoken';
|
|
16
18
|
let features = {};
|
|
17
19
|
let apis = {};
|
package/dist/libs/kafka.js
CHANGED
package/dist/libs/messaging.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import * as Utils from './utils.js';
|
|
2
|
+
// @ts-ignore
|
|
1
3
|
import axios from 'axios';
|
|
4
|
+
// @ts-ignore
|
|
2
5
|
import { createClient } from 'redis';
|
|
3
|
-
import * as Utils from './utils.js';
|
|
4
6
|
const url = process.env.REDIS_URL || "redis://localhost:6380";
|
|
5
7
|
// url: 'redis://alice:foobared@localhost:6380'
|
|
6
8
|
let consumer, publisher;
|
package/dist/libs/session.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import jwt from 'jsonwebtoken';
|
|
2
1
|
import * as Utils from './utils.js';
|
|
3
2
|
import * as Features from './features.js';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import jwt from 'jsonwebtoken';
|
|
4
5
|
let app;
|
|
5
6
|
const ACCESS_TOKEN_SECRET = process.env.JWT_ACCESS_TOKEN_SECRET || "MY_SECRET_ACCESS_TOKEN";
|
|
6
7
|
const REFRESH_TOKEN_SECRET = process.env.JWT_REFRESH_TOKEN_SECRET || "MY_SECRET_REFRESH_TOKEN";
|
|
@@ -27,13 +28,13 @@ export const start = (expressApp, allowedUrls) => {
|
|
|
27
28
|
try {
|
|
28
29
|
const token = req.header('JWT'); // 'Authorization' for Spring Boot, 'x-access-token' for Node.js Express back-end
|
|
29
30
|
const service = req.header('SERVICE'); // Case insensitive search
|
|
30
|
-
const additionalValidation = async (
|
|
31
|
+
const additionalValidation = async () => (process.env.GRANT_FULL_ACCESS || allowedDefaults || await checkPrivilege(req));
|
|
31
32
|
async function verifyDeveloperAccess() {
|
|
32
33
|
const NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN = req.header('NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN');
|
|
33
34
|
const isDeveloper = NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN && NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN_SECRET;
|
|
34
35
|
if (!isDeveloper)
|
|
35
36
|
return false;
|
|
36
|
-
const verify =
|
|
37
|
+
const verify = () => jwt.verify(NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN, NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN_SECRET, { algorithms: ['RS512'] });
|
|
37
38
|
try {
|
|
38
39
|
if (service && verify())
|
|
39
40
|
return true;
|
|
@@ -62,12 +63,12 @@ export const start = (expressApp, allowedUrls) => {
|
|
|
62
63
|
const decoded = jwt.verify(refreshToken, REFRESH_TOKEN_SECRET);
|
|
63
64
|
if (decoded.userId === userId && decoded.clientId === clientId) {
|
|
64
65
|
let now = Utils.now();
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
refreshTokenExpiry =
|
|
66
|
+
let _accessTokenExpiry = new Date(now);
|
|
67
|
+
_accessTokenExpiry.setDate(_accessTokenExpiry.getDate() + 1);
|
|
68
|
+
let _refreshTokenExpiry = new Date(now);
|
|
69
|
+
_refreshTokenExpiry.setDate(_refreshTokenExpiry.getDate() + 30);
|
|
70
|
+
const accessTokenExpiry = _accessTokenExpiry.getTime();
|
|
71
|
+
const refreshTokenExpiry = _refreshTokenExpiry.getTime();
|
|
71
72
|
const accessToken = jwt.sign({ userId, clientId }, ACCESS_TOKEN_SECRET, { expiresIn: '1d' });
|
|
72
73
|
const refreshToken = jwt.sign({ userId, clientId }, REFRESH_TOKEN_SECRET, { expiresIn: '30d' });
|
|
73
74
|
return res.json({ tokens: { accessToken, refreshToken, accessTokenExpiry, refreshTokenExpiry } });
|
|
@@ -84,12 +85,12 @@ export const start = (expressApp, allowedUrls) => {
|
|
|
84
85
|
export const generateAccessToken = (userId, clientId) => {
|
|
85
86
|
let data = { userId, clientId };
|
|
86
87
|
let now = Utils.now();
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
refreshTokenExpiry =
|
|
88
|
+
let _accessTokenExpiry = new Date(now);
|
|
89
|
+
_accessTokenExpiry.setDate(_accessTokenExpiry.getDate() + 1);
|
|
90
|
+
let _refreshTokenExpiry = new Date(now);
|
|
91
|
+
_refreshTokenExpiry.setDate(_refreshTokenExpiry.getDate() + 30);
|
|
92
|
+
const accessTokenExpiry = _accessTokenExpiry.getTime();
|
|
93
|
+
const refreshTokenExpiry = _refreshTokenExpiry.getTime();
|
|
93
94
|
const accessToken = jwt.sign(data, ACCESS_TOKEN_SECRET, { expiresIn: '1d' });
|
|
94
95
|
const refreshToken = jwt.sign(data, REFRESH_TOKEN_SECRET, { expiresIn: '365d' });
|
|
95
96
|
return { accessToken, refreshToken, accessTokenExpiry, refreshTokenExpiry };
|
package/dist/libs/utils.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import * as ObjectId from './ObjectId.js';
|
|
2
1
|
import * as Mobile from './mobilecodes.js';
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
3
|
// Parse JSON file: fileToJson
|
|
4
4
|
import { readFile, writeFile } from 'fs/promises';
|
|
5
|
-
import 'jsonminify';
|
|
6
|
-
// S3 Object Storage
|
|
7
|
-
import { S3Client, ListBucketsCommand, ListObjectsV2Command, GetObjectCommand, PutObjectCommand, CreateBucketCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
|
|
8
|
-
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
9
|
-
let bucketName = process.env.APP_DEPLOYMENT_NAME ?? ((global?.app?.name ?? "app") + '-dev');
|
|
10
|
-
let _ = (async () => { try {
|
|
11
|
-
const data = await S3.send(new CreateBucketCommand({ Bucket: bucketName }));
|
|
12
|
-
}
|
|
13
|
-
catch { } })(); // Create Bucket
|
|
14
5
|
export let pipeline = { execute: execute };
|
|
15
6
|
export function log(...args) {
|
|
16
7
|
let res = [];
|
|
17
8
|
args.forEach(arg => res.push(typeof arg === "object" ? JSON.stringify(arg, null, '\t') : arg));
|
|
18
9
|
console.log(...res);
|
|
19
10
|
}
|
|
11
|
+
let UID_COUNTER = crypto.randomBytes(3).readUIntBE(0, 3);
|
|
12
|
+
const UID_PROCESS = crypto.randomBytes(5);
|
|
20
13
|
export function uid() {
|
|
21
|
-
|
|
14
|
+
const buf = Buffer.allocUnsafe(12);
|
|
15
|
+
// 4-byte timestamp (big endian)
|
|
16
|
+
buf.writeUInt32BE((Date.now() / 1000) | 0, 0);
|
|
17
|
+
// 5-byte process unique
|
|
18
|
+
UID_PROCESS.copy(buf, 4);
|
|
19
|
+
// 3-byte counter
|
|
20
|
+
buf.writeUIntBE(UID_COUNTER++ & 0xffffff, 9, 3);
|
|
21
|
+
return buf.toString("hex");
|
|
22
22
|
}
|
|
23
23
|
export function isEmpty(str) {
|
|
24
24
|
if (!str)
|
|
@@ -27,7 +27,7 @@ export function isEmpty(str) {
|
|
|
27
27
|
}
|
|
28
28
|
export let GLOBAL_META = { company: "GLOBAL", outlet: "GLOBAL" };
|
|
29
29
|
export function isEmptyJson(json) {
|
|
30
|
-
for (
|
|
30
|
+
for (let i in json)
|
|
31
31
|
return false;
|
|
32
32
|
return true;
|
|
33
33
|
}
|
|
@@ -41,10 +41,12 @@ export function uniqueObjects(array, key) {
|
|
|
41
41
|
// Parse Numbers
|
|
42
42
|
// --------------
|
|
43
43
|
export function parseFloatValue(val) {
|
|
44
|
-
|
|
44
|
+
const ret = parseFloat(String(val ?? "0"));
|
|
45
|
+
return ret ? ret : 0;
|
|
45
46
|
}
|
|
46
47
|
export function parseIntValue(val) {
|
|
47
|
-
|
|
48
|
+
const ret = parseInt(String(val ?? "0"));
|
|
49
|
+
return ret ? ret : 0;
|
|
48
50
|
}
|
|
49
51
|
// ----------------
|
|
50
52
|
// Dates
|
|
@@ -55,38 +57,38 @@ export function now() {
|
|
|
55
57
|
export function toAppDate(date) {
|
|
56
58
|
if (Object.prototype.toString.call(date) === '[object String]')
|
|
57
59
|
date = new Date(date);
|
|
58
|
-
|
|
59
|
-
if (isNaN(temp)
|
|
60
|
+
let temp = date;
|
|
61
|
+
if (isNaN(temp.getTime()))
|
|
60
62
|
return '';
|
|
61
|
-
|
|
63
|
+
let day = temp.getDate().toString();
|
|
62
64
|
if (day.length === 1)
|
|
63
65
|
day = "0" + day;
|
|
64
|
-
|
|
66
|
+
let month = (temp.getMonth() + 1).toString();
|
|
65
67
|
if (month.length == 1)
|
|
66
68
|
month = "0" + month;
|
|
67
69
|
return (day + "/" + month + "/" + temp.getFullYear().toString());
|
|
68
70
|
}
|
|
69
71
|
export function toDate(arg, currentTime) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
let st = arg.split('/');
|
|
73
|
+
let temp = new Date(parseInt(st[2]), parseInt(st[1]) - 1, parseInt(st[0]));
|
|
72
74
|
temp.setHours(0);
|
|
73
75
|
temp.setMinutes(0);
|
|
74
76
|
temp.setSeconds(0);
|
|
75
77
|
temp.setMilliseconds(0);
|
|
76
78
|
if (currentTime) {
|
|
77
|
-
|
|
79
|
+
let curdate = now();
|
|
78
80
|
temp.setHours(curdate.getHours());
|
|
79
81
|
temp.setMinutes(curdate.getMinutes());
|
|
80
82
|
temp.setSeconds(curdate.getSeconds());
|
|
81
83
|
temp.setMilliseconds(curdate.getMilliseconds());
|
|
82
84
|
}
|
|
83
|
-
if (isNaN(temp))
|
|
85
|
+
if (isNaN(temp.getTime()))
|
|
84
86
|
return undefined;
|
|
85
87
|
return temp;
|
|
86
88
|
}
|
|
87
89
|
export function getDatesBetweenTwoDates(start, end) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
let arr = [];
|
|
91
|
+
let dt = new Date(start);
|
|
90
92
|
dt.setHours(0);
|
|
91
93
|
dt.setMinutes(0);
|
|
92
94
|
dt.setSeconds(0);
|
|
@@ -99,7 +101,7 @@ export function getDatesBetweenTwoDates(start, end) {
|
|
|
99
101
|
}
|
|
100
102
|
export function deepCopy(obj) {
|
|
101
103
|
if (Object.prototype.toString.call(obj) === '[object Array]') {
|
|
102
|
-
|
|
104
|
+
let out = [], i = 0, len = obj.length;
|
|
103
105
|
for (; i < len; i++) {
|
|
104
106
|
if (Object.prototype.toString.call(obj[i]) === '[object Date]')
|
|
105
107
|
out[i] = new Date(obj[i]);
|
|
@@ -109,7 +111,7 @@ export function deepCopy(obj) {
|
|
|
109
111
|
return out;
|
|
110
112
|
}
|
|
111
113
|
if (typeof obj === 'object') {
|
|
112
|
-
|
|
114
|
+
let out = {}, i;
|
|
113
115
|
for (i in obj) {
|
|
114
116
|
if (Object.prototype.toString.call(obj[i]) === '[object Date]')
|
|
115
117
|
out[i] = new Date(obj[i]);
|
|
@@ -121,18 +123,18 @@ export function deepCopy(obj) {
|
|
|
121
123
|
return obj;
|
|
122
124
|
}
|
|
123
125
|
export function formatAMPM(date) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
let hours = date.getHours();
|
|
127
|
+
let minutes = date.getMinutes();
|
|
128
|
+
let ampm = hours >= 12 ? 'pm' : 'am';
|
|
127
129
|
hours = hours % 12;
|
|
128
130
|
hours = hours ? hours : 12; // the hour '0' should be '12'
|
|
129
131
|
minutes = minutes < 10 ? '0' + minutes : minutes;
|
|
130
|
-
|
|
132
|
+
let strTime = hours + ':' + minutes + ' ' + ampm;
|
|
131
133
|
return strTime;
|
|
132
134
|
}
|
|
133
135
|
export function sum(array) {
|
|
134
|
-
|
|
135
|
-
for (
|
|
136
|
+
let res = 0;
|
|
137
|
+
for (let i in array)
|
|
136
138
|
res += parseFloat(array[i]) ? parseFloat(array[i]) : 0;
|
|
137
139
|
return res;
|
|
138
140
|
}
|
|
@@ -225,7 +227,60 @@ export function validityToUTCMillisecs(start, validity) {
|
|
|
225
227
|
// ----------------
|
|
226
228
|
export async function fileToJson(path, file) {
|
|
227
229
|
let data = (await readFile(new URL(file, path).toString().replace('file://', ''), 'utf8'));
|
|
228
|
-
return JSON.parse(JSON.minify(data))
|
|
230
|
+
// return JSON.parse((JSON as Record<string, any>).minify(data))
|
|
231
|
+
const json_minify = function (json) {
|
|
232
|
+
var tokenizer = /"|(\/\*)|(\*\/)|(\/\/)|\n|\r|\[|]/g, in_string = false, in_multiline_comment = false, in_singleline_comment = false, tmp, tmp2, new_str = [], ns = 0, from = 0, lc, rc, prevFrom;
|
|
233
|
+
tokenizer.lastIndex = 0;
|
|
234
|
+
while (tmp = tokenizer.exec(json)) {
|
|
235
|
+
lc = RegExp.leftContext;
|
|
236
|
+
rc = RegExp.rightContext;
|
|
237
|
+
if (!in_multiline_comment && !in_singleline_comment) {
|
|
238
|
+
tmp2 = lc.substring(from);
|
|
239
|
+
if (!in_string) {
|
|
240
|
+
tmp2 = tmp2.replace(/(\n|\r|\s)*/g, "");
|
|
241
|
+
}
|
|
242
|
+
new_str[ns++] = tmp2;
|
|
243
|
+
}
|
|
244
|
+
prevFrom = from;
|
|
245
|
+
from = tokenizer.lastIndex;
|
|
246
|
+
// found a " character, and we're not currently in
|
|
247
|
+
// a comment? check for previous `\` escaping immediately
|
|
248
|
+
// leftward adjacent to this match
|
|
249
|
+
if (tmp[0] === "\"" && !in_multiline_comment && !in_singleline_comment) {
|
|
250
|
+
// limit left-context matching to only go back
|
|
251
|
+
// to the position of the last token match
|
|
252
|
+
//
|
|
253
|
+
// see: https://github.com/getify/JSON.minify/issues/64
|
|
254
|
+
lc.lastIndex = prevFrom;
|
|
255
|
+
// perform leftward adjacent escaping match
|
|
256
|
+
tmp2 = lc.match(/(\\)*$/);
|
|
257
|
+
// start of string with ", or unescaped " character found to end string?
|
|
258
|
+
if (!in_string || !tmp2 || (tmp2[0].length % 2) === 0) {
|
|
259
|
+
in_string = !in_string;
|
|
260
|
+
}
|
|
261
|
+
from--; // include " character in next catch
|
|
262
|
+
rc = json.substring(from);
|
|
263
|
+
}
|
|
264
|
+
else if (tmp[0] === "/*" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
|
265
|
+
in_multiline_comment = true;
|
|
266
|
+
}
|
|
267
|
+
else if (tmp[0] === "*/" && !in_string && in_multiline_comment && !in_singleline_comment) {
|
|
268
|
+
in_multiline_comment = false;
|
|
269
|
+
}
|
|
270
|
+
else if (tmp[0] === "//" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
|
271
|
+
in_singleline_comment = true;
|
|
272
|
+
}
|
|
273
|
+
else if ((tmp[0] === "\n" || tmp[0] === "\r") && !in_string && !in_multiline_comment && in_singleline_comment) {
|
|
274
|
+
in_singleline_comment = false;
|
|
275
|
+
}
|
|
276
|
+
else if (!in_multiline_comment && !in_singleline_comment && !(/\n|\r|\s/.test(tmp[0]))) {
|
|
277
|
+
new_str[ns++] = tmp[0];
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
new_str[ns++] = rc;
|
|
281
|
+
return new_str.join("");
|
|
282
|
+
};
|
|
283
|
+
return JSON.parse(json_minify(data));
|
|
229
284
|
}
|
|
230
285
|
// ----------------
|
|
231
286
|
// File
|
|
@@ -249,15 +304,6 @@ function startPipeline(pipeline, index, data, errfn) {
|
|
|
249
304
|
pipeline[index](data).then(data => startPipeline(pipeline, index + 1, data)).catch(err => { if (errfn)
|
|
250
305
|
errfn(err); });
|
|
251
306
|
}
|
|
252
|
-
// -----------------
|
|
253
|
-
// S3 Object Storage
|
|
254
|
-
// -----------------
|
|
255
|
-
export async function getUrl(path, expiry = 3600) {
|
|
256
|
-
return await getSignedUrl(S3, new GetObjectCommand({ Bucket: bucketName, Key: path }), { expiresIn: expiry });
|
|
257
|
-
}
|
|
258
|
-
export async function putUrl(path, expiry = 3600) {
|
|
259
|
-
return await getSignedUrl(S3, new PutObjectCommand({ Bucket: bucketName, Key: path }), { expiresIn: expiry });
|
|
260
|
-
}
|
|
261
307
|
// ---------------------------
|
|
262
308
|
// Express Middleware Exclude
|
|
263
309
|
// ---------------------------
|
package/libs/auth.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
// @ts-ignore
|
|
1
2
|
import axios from 'axios'
|
|
3
|
+
// @ts-ignore
|
|
2
4
|
import otpGenerator from 'otp-generator'
|
|
3
5
|
|
|
4
6
|
import * as Dip from './dip.ts'
|
|
@@ -38,7 +40,8 @@ async function attemptLogin(req, res) {
|
|
|
38
40
|
|
|
39
41
|
let expiry = 300000
|
|
40
42
|
let userMob = req.body.mob ?? req.body.phone
|
|
41
|
-
|
|
43
|
+
const code = req.body.code
|
|
44
|
+
let mob = userMob.endsWith('123456789') ? '0123456789' : Utils.parseMob(userMob, code)
|
|
42
45
|
let time = new Date().getTime()
|
|
43
46
|
let collection = (req.body.app ? req.body.app + '.' : '') + "auth.login"
|
|
44
47
|
let errMessage = {success: false, message: "Login Server Error"}
|
|
@@ -51,7 +54,7 @@ async function attemptLogin(req, res) {
|
|
|
51
54
|
let res = await Dip.query(meta, collection, { _id: mob, otp: req.body.otp, clientId, time: { $gt: time - expiry } })
|
|
52
55
|
if (res.length) {
|
|
53
56
|
try {await Dip.update(meta, collection, { _id: mob }, { $set: { otp: '', clientId: '', loggedIn: true } }) } catch (err) { throw {...errMessage, mode: 'verify', info: 'Cleanup Failed'} }
|
|
54
|
-
return {...res[0], mode: 'verify', success: true, userId: res[0].userId, phone: res[0]._id, mob: res[0]._id}
|
|
57
|
+
return {...res[0], mode: 'verify', success: true, userId: res[0].userId, phone: res[0]._id, mob: res[0]._id, code}
|
|
55
58
|
}
|
|
56
59
|
throw {...errMessage, mode: 'verify', info: "Invalid/Expired OTP"}
|
|
57
60
|
} else { // generate login
|
|
@@ -63,7 +66,7 @@ async function attemptLogin(req, res) {
|
|
|
63
66
|
let info = { clientId, created: now, updated: now, ...data}
|
|
64
67
|
await Dip.update(meta, collection, { _id: mob }, { $set: { otp, clientId, time, updated: now, attemptLogin: true }, $setOnInsert: { _id: mob, otp, time, userId, ...info } }, { upsert: true })
|
|
65
68
|
|
|
66
|
-
return {mode: 'login', success: true, userId, expiry, phone: mob, mob}
|
|
69
|
+
return {mode: 'login', success: true, userId, expiry, phone: mob, mob, code}
|
|
67
70
|
}
|
|
68
71
|
throw {...errMessage, mode: 'login', info: 'Generating Info Failed'}
|
|
69
72
|
}
|
package/libs/compression.ts
CHANGED
package/libs/dip/suffix/index.ts
CHANGED
|
@@ -72,7 +72,7 @@ function flatten_value(target_key, value, flattened, ancestor_has_id) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
export function entries(target_key, query, binary_slice) {
|
|
75
|
+
export function entries(target_key: string, query, binary_slice?: Buffer) {
|
|
76
76
|
let result = flatten_id_values(target_key, query); // extract all valid _id
|
|
77
77
|
|
|
78
78
|
// let cows = result.map(v => extract_direct_id(v, binary_slice))
|
|
@@ -88,7 +88,7 @@ export function intersects(w_values, w_bounds, q_values, q_bounds) {
|
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
// NOTE: Matching is based on intersection, not equality. A policy matches if, for every key in `when`, there exists at least one value that satisfies both the `when` constraint and the query constraint.
|
|
91
|
-
export function matchPolicy(query, when, g_obj) {
|
|
91
|
+
export function matchPolicy(query, when, g_obj?: Record<string, any>) {
|
|
92
92
|
let obj = g_obj ?? {}
|
|
93
93
|
for (let key in when) {
|
|
94
94
|
if (key === "$and" || key === "$or") {
|
|
@@ -135,8 +135,9 @@ export function matchPolicy(query, when, g_obj) {
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
|
|
138
|
+
type Arg = { db?: string; collection?: string; [key: string]: any }
|
|
138
139
|
|
|
139
|
-
export async function applySuffixPolicy(COLLECTIONS_JSON, collections, query, insertMode, arg) {
|
|
140
|
+
export async function applySuffixPolicy(COLLECTIONS_JSON, collections, query, insertMode?: boolean, arg?: Arg) {
|
|
140
141
|
collections = Array.isArray(collections) ? collections : [collections]
|
|
141
142
|
let suffixes = []
|
|
142
143
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {entries, reduceRanges, extractBounds, getNormalizedBounds} from './index.ts'
|
|
2
2
|
import {formatDate, fillDates} from './date.ts'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type Arg = { db?: string; collection?: string; [key: string]: any }
|
|
5
5
|
|
|
6
6
|
const EXPLICIT_SUFFIX_POLICY_TYPES = new Set([ "string", "date", "number" ]);
|
|
7
|
-
export async function suffix(doc, policies, insertMode, arg) {
|
|
7
|
+
export async function suffix(doc, policies, insertMode?: boolean, arg?: Arg) {
|
|
8
8
|
let suffixes = [""]
|
|
9
9
|
for (const policy of policies) {
|
|
10
10
|
|
package/libs/dip.ts
CHANGED
|
@@ -37,7 +37,7 @@ export const IdempotentDip = () => {
|
|
|
37
37
|
return {
|
|
38
38
|
txn: '',
|
|
39
39
|
meta: undefined,
|
|
40
|
-
new: (async function (meta, txn, blank) {
|
|
40
|
+
new: (async function (meta, txn, blank?: {blank: boolean}) {
|
|
41
41
|
this.txn = txn
|
|
42
42
|
this.meta = meta
|
|
43
43
|
return blank ? this : ((await Elabase.query(this.meta, "txns",{_id: this.txn})).length ? false : this)
|
package/libs/elabase.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-ignore
|
|
1
2
|
import axios from 'axios'
|
|
2
3
|
import {default as dipper, shard_stats as ShardStats} from './dipper.ts'
|
|
3
4
|
import * as Utils from './utils.ts'
|
|
@@ -308,7 +309,7 @@ export const operation = async (name, extras) => {
|
|
|
308
309
|
|
|
309
310
|
|
|
310
311
|
// Ported
|
|
311
|
-
export const insert = async (meta, collection, value, options, extras) => {
|
|
312
|
+
export const insert = async (meta, collection, value, options?: any, extras?: any) => {
|
|
312
313
|
|
|
313
314
|
if (!(meta instanceof DipMeta)) console.warn('Warn: Provided meta is not an instance of DipMeta in Dip.insert()') // TODO: throw error once review completes
|
|
314
315
|
|
|
@@ -352,7 +353,7 @@ export const insert = async (meta, collection, value, options, extras) => {
|
|
|
352
353
|
}
|
|
353
354
|
|
|
354
355
|
// Ported
|
|
355
|
-
export const query = async (meta, collection, query, options, extras) => {
|
|
356
|
+
export const query = async (meta, collection, query, options?: any, extras?: any) => {
|
|
356
357
|
|
|
357
358
|
if (!(meta instanceof DipMeta)) console.warn('Warn: Provided meta is not an instance of DipMeta in Dip.query()') // TODO: throw error once review completes
|
|
358
359
|
|
|
@@ -404,7 +405,7 @@ function collectionArray(col) {
|
|
|
404
405
|
}
|
|
405
406
|
|
|
406
407
|
// Ported
|
|
407
|
-
export const update = async (meta, collection, query, update, options, extras) => {
|
|
408
|
+
export const update = async (meta, collection, query, update, options?: any, extras?: any) => {
|
|
408
409
|
|
|
409
410
|
if (!(meta instanceof DipMeta)) console.warn('Warn: Provided meta is not an instance of DipMeta in Dip.update()') // TODO: throw error once review completes
|
|
410
411
|
|
|
@@ -444,7 +445,7 @@ export const update = async (meta, collection, query, update, options, extras) =
|
|
|
444
445
|
}
|
|
445
446
|
|
|
446
447
|
// Ported
|
|
447
|
-
export const remove = async (meta, collection, query, options, extras) => {
|
|
448
|
+
export const remove = async (meta, collection, query, options?: any, extras?: any) => {
|
|
448
449
|
|
|
449
450
|
if (!(meta instanceof DipMeta)) console.warn('Warn: Provided meta is not an instance of DipMeta in Dip.remove()') // TODO: throw error once review completes
|
|
450
451
|
|
package/libs/features.ts
CHANGED
|
@@ -3,7 +3,9 @@ import * as Kafka from './kafka.ts'
|
|
|
3
3
|
import * as Utils from './utils.ts'
|
|
4
4
|
import * as Session from './session.ts'
|
|
5
5
|
import * as Messaging from './messaging.ts'
|
|
6
|
+
// @ts-ignore
|
|
6
7
|
import axios from 'axios'
|
|
8
|
+
// @ts-ignore
|
|
7
9
|
import jwt from 'jsonwebtoken'
|
|
8
10
|
|
|
9
11
|
let features = {}
|
package/libs/kafka.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-ignore
|
|
1
2
|
import { Kafka, logLevel as KafkaLogLevel, CompressionTypes as KafkaCompressionTypes } from 'kafkajs'
|
|
2
3
|
|
|
3
4
|
export const logLevel = KafkaLogLevel
|
|
@@ -38,7 +39,7 @@ export const createTopic = async (topic, partition, replicas) => {
|
|
|
38
39
|
|
|
39
40
|
let consumers = []
|
|
40
41
|
|
|
41
|
-
const start_consumer = async function (topic, groupId, callback) {
|
|
42
|
+
const start_consumer = async function (topic, groupId, callback?: Function) {
|
|
42
43
|
callback = typeof groupId === "string" ? callback : groupId
|
|
43
44
|
groupId = typeof groupId === "string" ? `${appName}.${groupId}` : `${appName}.${topic}`
|
|
44
45
|
|
|
@@ -96,7 +97,7 @@ const start_producer = async function (topic, message, key, options) {
|
|
|
96
97
|
// start_consumer('quickstart-events')
|
|
97
98
|
// start_producer('quickstart-events', 'Hello KafkaJS user! Little')
|
|
98
99
|
|
|
99
|
-
export const receive = async function(topic, groupId, callback) {
|
|
100
|
+
export const receive = async function(topic, groupId, callback?: Function) {
|
|
100
101
|
topic = topicPrefix + topic
|
|
101
102
|
return (await start_consumer(topic, groupId, callback))
|
|
102
103
|
}
|
package/libs/messaging.ts
CHANGED
package/libs/session.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import jwt from 'jsonwebtoken'
|
|
2
1
|
import * as Utils from './utils.ts'
|
|
3
2
|
import * as Features from './features.ts'
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import jwt from 'jsonwebtoken'
|
|
5
|
+
|
|
4
6
|
let app
|
|
5
7
|
|
|
6
8
|
|
|
@@ -42,14 +44,14 @@ export const start = (expressApp, allowedUrls) => {
|
|
|
42
44
|
try {
|
|
43
45
|
const token = req.header('JWT'); // 'Authorization' for Spring Boot, 'x-access-token' for Node.js Express back-end
|
|
44
46
|
const service = req.header('SERVICE'); // Case insensitive search
|
|
45
|
-
const additionalValidation = async
|
|
47
|
+
const additionalValidation = async () => (process.env.GRANT_FULL_ACCESS || allowedDefaults || await checkPrivilege(req))
|
|
46
48
|
|
|
47
49
|
async function verifyDeveloperAccess() {
|
|
48
50
|
const NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN = req.header('NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN')
|
|
49
51
|
const isDeveloper = NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN && NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN_SECRET
|
|
50
52
|
if (!isDeveloper)
|
|
51
53
|
return false
|
|
52
|
-
const verify =
|
|
54
|
+
const verify = () => jwt.verify(NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN, NDCURVE_DEVELOPER_LICENSE_ACCESS_TOKEN_SECRET, { algorithms: ['RS512'] })
|
|
53
55
|
try {
|
|
54
56
|
if (service && verify())
|
|
55
57
|
return true
|
|
@@ -79,8 +81,10 @@ export const start = (expressApp, allowedUrls) => {
|
|
|
79
81
|
const decoded = jwt.verify(refreshToken, REFRESH_TOKEN_SECRET)
|
|
80
82
|
if (decoded.userId === userId && decoded.clientId === clientId) {
|
|
81
83
|
let now = Utils.now()
|
|
82
|
-
let
|
|
83
|
-
let
|
|
84
|
+
let _accessTokenExpiry = new Date(now); _accessTokenExpiry.setDate(_accessTokenExpiry.getDate() + 1);
|
|
85
|
+
let _refreshTokenExpiry = new Date(now); _refreshTokenExpiry.setDate(_refreshTokenExpiry.getDate() + 30);
|
|
86
|
+
const accessTokenExpiry = _accessTokenExpiry.getTime()
|
|
87
|
+
const refreshTokenExpiry = _refreshTokenExpiry.getTime()
|
|
84
88
|
const accessToken = jwt.sign({ userId, clientId }, ACCESS_TOKEN_SECRET, { expiresIn: '1d' });
|
|
85
89
|
const refreshToken = jwt.sign({ userId, clientId }, REFRESH_TOKEN_SECRET, { expiresIn: '30d' });
|
|
86
90
|
return res.json({ tokens: { accessToken, refreshToken, accessTokenExpiry, refreshTokenExpiry} });
|
|
@@ -100,8 +104,10 @@ export const generateAccessToken = (userId, clientId) => {
|
|
|
100
104
|
let data = { userId, clientId }
|
|
101
105
|
|
|
102
106
|
let now = Utils.now()
|
|
103
|
-
let
|
|
104
|
-
let
|
|
107
|
+
let _accessTokenExpiry = new Date(now); _accessTokenExpiry.setDate(_accessTokenExpiry.getDate() + 1);
|
|
108
|
+
let _refreshTokenExpiry = new Date(now); _refreshTokenExpiry.setDate(_refreshTokenExpiry.getDate() + 30);
|
|
109
|
+
const accessTokenExpiry = _accessTokenExpiry.getTime()
|
|
110
|
+
const refreshTokenExpiry = _refreshTokenExpiry.getTime()
|
|
105
111
|
|
|
106
112
|
const accessToken = jwt.sign(data, ACCESS_TOKEN_SECRET, { expiresIn: '1d' });
|
|
107
113
|
const refreshToken = jwt.sign(data, REFRESH_TOKEN_SECRET, { expiresIn: '365d' });
|
package/libs/utils.ts
CHANGED
|
@@ -1,20 +1,11 @@
|
|
|
1
|
-
import * as ObjectId from './ObjectId.ts'
|
|
2
1
|
import * as Mobile from './mobilecodes.ts'
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
3
|
|
|
4
4
|
// Parse JSON file: fileToJson
|
|
5
5
|
import {readFile,writeFile} from 'fs/promises';
|
|
6
|
-
import 'jsonminify'
|
|
7
|
-
|
|
8
|
-
// S3 Object Storage
|
|
9
|
-
import { S3Client, ListBucketsCommand, ListObjectsV2Command, GetObjectCommand, PutObjectCommand, CreateBucketCommand, DeleteObjectCommand } from '@aws-sdk/client-s3'
|
|
10
|
-
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
|
|
11
|
-
let bucketName = process.env.APP_DEPLOYMENT_NAME ?? ((global?.app?.name ?? "app") + '-dev')
|
|
12
|
-
let _ = (async () => { try { const data = await S3.send(new CreateBucketCommand({ Bucket: bucketName })) } catch { } })() // Create Bucket
|
|
13
|
-
|
|
14
6
|
|
|
15
7
|
export let pipeline = { execute: execute }
|
|
16
8
|
|
|
17
|
-
|
|
18
9
|
export function log(...args) {
|
|
19
10
|
let res = []
|
|
20
11
|
args.forEach(arg => res.push(typeof arg === "object" ? JSON.stringify(arg,null,'\t') : arg))
|
|
@@ -22,11 +13,26 @@ export function log(...args) {
|
|
|
22
13
|
}
|
|
23
14
|
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
let UID_COUNTER = crypto.randomBytes(3).readUIntBE(0, 3);
|
|
17
|
+
const UID_PROCESS = crypto.randomBytes(5);
|
|
18
|
+
|
|
19
|
+
export function uid(): string {
|
|
20
|
+
|
|
21
|
+
const buf = Buffer.allocUnsafe(12);
|
|
22
|
+
|
|
23
|
+
// 4-byte timestamp (big endian)
|
|
24
|
+
buf.writeUInt32BE((Date.now() / 1000) | 0, 0);
|
|
25
|
+
|
|
26
|
+
// 5-byte process unique
|
|
27
|
+
UID_PROCESS.copy(buf, 4);
|
|
28
|
+
|
|
29
|
+
// 3-byte counter
|
|
30
|
+
buf.writeUIntBE(UID_COUNTER++ & 0xffffff, 9, 3);
|
|
31
|
+
|
|
32
|
+
return buf.toString("hex");
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
export function isEmpty(str) { // returns true for undefined
|
|
35
|
+
export function isEmpty(str): boolean { // returns true for undefined
|
|
30
36
|
if(!str)
|
|
31
37
|
return true
|
|
32
38
|
return str.match(/\S/) ? false : true // matches a non space character
|
|
@@ -34,8 +40,8 @@ export function isEmpty(str) { // returns true for undefined
|
|
|
34
40
|
|
|
35
41
|
export let GLOBAL_META = { company: "GLOBAL", outlet: "GLOBAL" }
|
|
36
42
|
|
|
37
|
-
export function isEmptyJson(json) {
|
|
38
|
-
for (
|
|
43
|
+
export function isEmptyJson(json): boolean {
|
|
44
|
+
for (let i in json)
|
|
39
45
|
return false
|
|
40
46
|
return true
|
|
41
47
|
}
|
|
@@ -53,12 +59,14 @@ export function uniqueObjects(array, key) {
|
|
|
53
59
|
// Parse Numbers
|
|
54
60
|
// --------------
|
|
55
61
|
|
|
56
|
-
export function parseFloatValue(val) {
|
|
57
|
-
|
|
62
|
+
export function parseFloatValue(val: number | string | undefined): number {
|
|
63
|
+
const ret = parseFloat(String(val ?? "0"))
|
|
64
|
+
return ret ? ret : 0
|
|
58
65
|
}
|
|
59
66
|
|
|
60
|
-
export function parseIntValue(val) {
|
|
61
|
-
|
|
67
|
+
export function parseIntValue(val: number | string | undefined): number {
|
|
68
|
+
const ret = parseInt(String(val ?? "0"))
|
|
69
|
+
return ret ? ret : 0
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
|
|
@@ -71,38 +79,38 @@ export function now() {
|
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
|
|
74
|
-
export function toAppDate(date) { // New
|
|
82
|
+
export function toAppDate(date: Date): string { // New
|
|
75
83
|
if (Object.prototype.toString.call(date) === '[object String]')
|
|
76
84
|
date = new Date(date)
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
if (isNaN(temp)
|
|
86
|
+
let temp = date
|
|
87
|
+
if (isNaN(temp.getTime()))
|
|
80
88
|
return ''
|
|
81
89
|
|
|
82
|
-
|
|
90
|
+
let day = temp.getDate().toString()
|
|
83
91
|
if(day.length === 1) day = "0"+day
|
|
84
|
-
|
|
92
|
+
let month = (temp.getMonth() + 1).toString()
|
|
85
93
|
if(month.length == 1) month = "0"+month
|
|
86
94
|
return (day + "/" + month + "/" + temp.getFullYear().toString())
|
|
87
95
|
}
|
|
88
96
|
|
|
89
97
|
|
|
90
|
-
export function toDate(arg, currentTime) { // New
|
|
98
|
+
export function toDate(arg: string, currentTime?: boolean): Date { // New
|
|
91
99
|
|
|
92
|
-
|
|
100
|
+
let st = arg.split('/')
|
|
93
101
|
|
|
94
|
-
|
|
102
|
+
let temp = new Date(parseInt(st[2]), parseInt(st[1]) - 1, parseInt(st[0]));
|
|
95
103
|
temp.setHours(0) ; temp.setMinutes(0); temp.setSeconds(0); temp.setMilliseconds(0)
|
|
96
104
|
|
|
97
105
|
if (currentTime) {
|
|
98
|
-
|
|
106
|
+
let curdate = now()
|
|
99
107
|
temp.setHours(curdate.getHours())
|
|
100
108
|
temp.setMinutes(curdate.getMinutes())
|
|
101
109
|
temp.setSeconds(curdate.getSeconds())
|
|
102
110
|
temp.setMilliseconds(curdate.getMilliseconds())
|
|
103
111
|
}
|
|
104
112
|
|
|
105
|
-
if (isNaN(temp))
|
|
113
|
+
if (isNaN(temp.getTime()))
|
|
106
114
|
return undefined
|
|
107
115
|
return temp
|
|
108
116
|
}
|
|
@@ -110,8 +118,8 @@ export function toDate(arg, currentTime) { // New
|
|
|
110
118
|
|
|
111
119
|
|
|
112
120
|
export function getDatesBetweenTwoDates(start, end) {
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
let arr = [];
|
|
122
|
+
let dt = new Date(start);
|
|
115
123
|
|
|
116
124
|
dt.setHours(0)
|
|
117
125
|
dt.setMinutes(0)
|
|
@@ -127,7 +135,7 @@ export function getDatesBetweenTwoDates(start, end) {
|
|
|
127
135
|
|
|
128
136
|
export function deepCopy(obj) {
|
|
129
137
|
if (Object.prototype.toString.call(obj) === '[object Array]') {
|
|
130
|
-
|
|
138
|
+
let out = [], i = 0, len = obj.length;
|
|
131
139
|
for ( ; i < len; i++ ) {
|
|
132
140
|
if (Object.prototype.toString.call(obj[i]) === '[object Date]')
|
|
133
141
|
out[i] = new Date(obj[i])
|
|
@@ -137,7 +145,7 @@ export function deepCopy(obj) {
|
|
|
137
145
|
return out;
|
|
138
146
|
}
|
|
139
147
|
if (typeof obj === 'object') {
|
|
140
|
-
|
|
148
|
+
let out = {}, i;
|
|
141
149
|
for ( i in obj ) {
|
|
142
150
|
if (Object.prototype.toString.call(obj[i]) === '[object Date]')
|
|
143
151
|
out[i] = new Date(obj[i])
|
|
@@ -151,24 +159,24 @@ export function deepCopy(obj) {
|
|
|
151
159
|
|
|
152
160
|
|
|
153
161
|
export function formatAMPM(date) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
162
|
+
let hours = date.getHours();
|
|
163
|
+
let minutes = date.getMinutes();
|
|
164
|
+
let ampm = hours >= 12 ? 'pm' : 'am';
|
|
157
165
|
hours = hours % 12;
|
|
158
166
|
hours = hours ? hours : 12; // the hour '0' should be '12'
|
|
159
167
|
minutes = minutes < 10 ? '0'+minutes : minutes;
|
|
160
|
-
|
|
168
|
+
let strTime = hours + ':' + minutes + ' ' + ampm;
|
|
161
169
|
return strTime;
|
|
162
170
|
}
|
|
163
171
|
export function sum(array) { // Eg: sum([10,20,undefined, NaN, 40])
|
|
164
|
-
|
|
165
|
-
for (
|
|
172
|
+
let res = 0
|
|
173
|
+
for (let i in array)
|
|
166
174
|
res += parseFloat(array[i]) ? parseFloat(array[i]) : 0
|
|
167
175
|
return res;
|
|
168
176
|
}
|
|
169
177
|
|
|
170
178
|
|
|
171
|
-
export function addMonths(date, monthsToAdd) { // simpler alternative to setNextMonth because rollover always changes the day number
|
|
179
|
+
export function addMonths(date: Date, monthsToAdd: number): Date { // simpler alternative to setNextMonth because rollover always changes the day number
|
|
172
180
|
const day = date.getDate();
|
|
173
181
|
date.setMonth(date.getMonth() + monthsToAdd);
|
|
174
182
|
// If the day rolled over, clamp to last day of target month
|
|
@@ -177,11 +185,11 @@ export function addMonths(date, monthsToAdd) { // simpler alternative to setNext
|
|
|
177
185
|
}
|
|
178
186
|
return date;
|
|
179
187
|
}
|
|
180
|
-
export function addYears(date, yearsToAdd) { // Reuse addMonths to cleanly clamp Feb 29 to Feb 28 instead of 1 March on non-leap years
|
|
188
|
+
export function addYears(date: Date, yearsToAdd: number): Date { // Reuse addMonths to cleanly clamp Feb 29 to Feb 28 instead of 1 March on non-leap years
|
|
181
189
|
return addMonths(date, yearsToAdd * 12)
|
|
182
190
|
}
|
|
183
191
|
|
|
184
|
-
export function addUTCMonths(date, monthsToAdd) { // simpler alternative to setUTCNextMonth because rollover always changes the day number
|
|
192
|
+
export function addUTCMonths(date: Date, monthsToAdd: number): Date { // simpler alternative to setUTCNextMonth because rollover always changes the day number
|
|
185
193
|
const day = date.getUTCDate();
|
|
186
194
|
date.setUTCMonth(date.getUTCMonth() + monthsToAdd);
|
|
187
195
|
// If the day rolled over, clamp to last day of target month
|
|
@@ -190,23 +198,23 @@ export function addUTCMonths(date, monthsToAdd) { // simpler alternative to setU
|
|
|
190
198
|
}
|
|
191
199
|
return date;
|
|
192
200
|
}
|
|
193
|
-
export function addUTCYears(date, yearsToAdd) { // Reuse addMonths to cleanly clamp Feb 29 to Feb 28 instead of 1 March on non-leap years
|
|
201
|
+
export function addUTCYears(date: Date, yearsToAdd: number): Date { // Reuse addMonths to cleanly clamp Feb 29 to Feb 28 instead of 1 March on non-leap years
|
|
194
202
|
return addUTCMonths(date, yearsToAdd * 12)
|
|
195
203
|
}
|
|
196
204
|
|
|
197
|
-
export function addDays(date, daysToAdd) {
|
|
205
|
+
export function addDays(date: Date, daysToAdd: number): Date {
|
|
198
206
|
date.setDate(date.getDate() + daysToAdd)
|
|
199
207
|
return date
|
|
200
208
|
}
|
|
201
|
-
export function addHours(date, hoursToAdd) {
|
|
209
|
+
export function addHours(date: Date, hoursToAdd: number): Date {
|
|
202
210
|
date.setHours(date.getHours() + hoursToAdd)
|
|
203
211
|
return date
|
|
204
212
|
}
|
|
205
|
-
export function addUTCDays(date, daysToAdd) {
|
|
213
|
+
export function addUTCDays(date: Date, daysToAdd: number): Date {
|
|
206
214
|
date.setUTCDate(date.getUTCDate() + daysToAdd)
|
|
207
215
|
return date
|
|
208
216
|
}
|
|
209
|
-
export function addUTCHours(date, hoursToAdd) {
|
|
217
|
+
export function addUTCHours(date: Date, hoursToAdd: number): Date {
|
|
210
218
|
date.setUTCHours(date.getUTCHours() + hoursToAdd)
|
|
211
219
|
return date
|
|
212
220
|
}
|
|
@@ -270,7 +278,74 @@ export function validityToUTCMillisecs(start, validity) { // start is in ms
|
|
|
270
278
|
// ----------------
|
|
271
279
|
export async function fileToJson(path, file) {
|
|
272
280
|
let data = (await readFile(new URL(file, path).toString().replace('file://',''), 'utf8'))
|
|
273
|
-
return JSON.parse(JSON.minify(data))
|
|
281
|
+
// return JSON.parse((JSON as Record<string, any>).minify(data))
|
|
282
|
+
|
|
283
|
+
const json_minify = function (json: string): string {
|
|
284
|
+
|
|
285
|
+
var tokenizer = /"|(\/\*)|(\*\/)|(\/\/)|\n|\r|\[|]/g,
|
|
286
|
+
in_string = false,
|
|
287
|
+
in_multiline_comment = false,
|
|
288
|
+
in_singleline_comment = false,
|
|
289
|
+
tmp, tmp2, new_str = [], ns = 0, from = 0, lc, rc,
|
|
290
|
+
prevFrom
|
|
291
|
+
;
|
|
292
|
+
|
|
293
|
+
tokenizer.lastIndex = 0;
|
|
294
|
+
|
|
295
|
+
while ( tmp = tokenizer.exec(json) ) {
|
|
296
|
+
lc = RegExp.leftContext;
|
|
297
|
+
rc = RegExp.rightContext;
|
|
298
|
+
if (!in_multiline_comment && !in_singleline_comment) {
|
|
299
|
+
tmp2 = lc.substring(from);
|
|
300
|
+
if (!in_string) {
|
|
301
|
+
tmp2 = tmp2.replace(/(\n|\r|\s)*/g,"");
|
|
302
|
+
}
|
|
303
|
+
new_str[ns++] = tmp2;
|
|
304
|
+
}
|
|
305
|
+
prevFrom = from;
|
|
306
|
+
from = tokenizer.lastIndex;
|
|
307
|
+
|
|
308
|
+
// found a " character, and we're not currently in
|
|
309
|
+
// a comment? check for previous `\` escaping immediately
|
|
310
|
+
// leftward adjacent to this match
|
|
311
|
+
if (tmp[0] === "\"" && !in_multiline_comment && !in_singleline_comment) {
|
|
312
|
+
// limit left-context matching to only go back
|
|
313
|
+
// to the position of the last token match
|
|
314
|
+
//
|
|
315
|
+
// see: https://github.com/getify/JSON.minify/issues/64
|
|
316
|
+
lc.lastIndex = prevFrom;
|
|
317
|
+
|
|
318
|
+
// perform leftward adjacent escaping match
|
|
319
|
+
tmp2 = lc.match(/(\\)*$/);
|
|
320
|
+
// start of string with ", or unescaped " character found to end string?
|
|
321
|
+
if (!in_string || !tmp2 || (tmp2[0].length % 2) === 0) {
|
|
322
|
+
in_string = !in_string;
|
|
323
|
+
}
|
|
324
|
+
from--; // include " character in next catch
|
|
325
|
+
rc = json.substring(from);
|
|
326
|
+
}
|
|
327
|
+
else if (tmp[0] === "/*" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
|
328
|
+
in_multiline_comment = true;
|
|
329
|
+
}
|
|
330
|
+
else if (tmp[0] === "*/" && !in_string && in_multiline_comment && !in_singleline_comment) {
|
|
331
|
+
in_multiline_comment = false;
|
|
332
|
+
}
|
|
333
|
+
else if (tmp[0] === "//" && !in_string && !in_multiline_comment && !in_singleline_comment) {
|
|
334
|
+
in_singleline_comment = true;
|
|
335
|
+
}
|
|
336
|
+
else if ((tmp[0] === "\n" || tmp[0] === "\r") && !in_string && !in_multiline_comment && in_singleline_comment) {
|
|
337
|
+
in_singleline_comment = false;
|
|
338
|
+
}
|
|
339
|
+
else if (!in_multiline_comment && !in_singleline_comment && !(/\n|\r|\s/.test(tmp[0]))) {
|
|
340
|
+
new_str[ns++] = tmp[0];
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
new_str[ns++] = rc;
|
|
344
|
+
return new_str.join("");
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
return JSON.parse(json_minify(data))
|
|
274
349
|
}
|
|
275
350
|
|
|
276
351
|
// ----------------
|
|
@@ -289,27 +364,17 @@ export async function stringToFile(file, data) {
|
|
|
289
364
|
// ----------------
|
|
290
365
|
|
|
291
366
|
|
|
292
|
-
function execute(pipeline, errfn) {
|
|
367
|
+
function execute(pipeline, errfn?: Function) {
|
|
293
368
|
startPipeline(pipeline, 0, undefined, errfn)
|
|
294
369
|
}
|
|
295
370
|
|
|
296
|
-
function startPipeline(pipeline, index, data, errfn) {
|
|
371
|
+
function startPipeline(pipeline, index, data, errfn?: Function) {
|
|
297
372
|
index = index == undefined ? 0 : index
|
|
298
373
|
if (index == pipeline.length)
|
|
299
374
|
return
|
|
300
375
|
pipeline[index](data).then(data => startPipeline(pipeline, index + 1, data)).catch(err => { if (errfn) errfn(err) } )
|
|
301
376
|
}
|
|
302
377
|
|
|
303
|
-
// -----------------
|
|
304
|
-
// S3 Object Storage
|
|
305
|
-
// -----------------
|
|
306
|
-
|
|
307
|
-
export async function getUrl(path, expiry = 3600) { // expiry default: 1 Hour
|
|
308
|
-
return await getSignedUrl(S3, new GetObjectCommand({ Bucket: bucketName, Key: path }), { expiresIn: expiry })
|
|
309
|
-
}
|
|
310
|
-
export async function putUrl(path, expiry = 3600) { // expiry default: 1 Hour
|
|
311
|
-
return await getSignedUrl(S3, new PutObjectCommand({ Bucket: bucketName, Key: path }), { expiresIn: expiry })
|
|
312
|
-
}
|
|
313
378
|
|
|
314
379
|
// ---------------------------
|
|
315
380
|
// Express Middleware Exclude
|
|
@@ -332,7 +397,7 @@ export const excludeMiddleware = function(middleware, ...paths) {
|
|
|
332
397
|
// Parse Mobile Number
|
|
333
398
|
// --------------------
|
|
334
399
|
|
|
335
|
-
export function parseMob(mob, code) {
|
|
400
|
+
export function parseMob(mob: string, code: string): string {
|
|
336
401
|
code = code ?? "IN"
|
|
337
402
|
if (isEmpty(mob))
|
|
338
403
|
return mob
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corebasic",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.218",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "./index.ts",
|
|
@@ -11,11 +11,8 @@
|
|
|
11
11
|
"author": "",
|
|
12
12
|
"license": "ISC",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@aws-sdk/client-s3": "^3.398.0",
|
|
15
|
-
"@aws-sdk/s3-request-presigner": "^3.398.0",
|
|
16
14
|
"axios": "^1.4.0",
|
|
17
15
|
"compression": "^1.7.4",
|
|
18
|
-
"jsonminify": "^0.4.2",
|
|
19
16
|
"jsonwebtoken": "^9.0.1",
|
|
20
17
|
"otp-generator": "^4.0.1",
|
|
21
18
|
"redis": "^4.6.8"
|
package/libs/ObjectId.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*
|
|
3
|
-
* Copyright (c) 2011-2014- Justin Dearing (zippy1981@gmail.com)
|
|
4
|
-
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
5
|
-
* and GPL (http://www.opensource.org/licenses/gpl-license.php) version 2 licenses.
|
|
6
|
-
* This software is not distributed under version 3 or later of the GPL.
|
|
7
|
-
*
|
|
8
|
-
* Version 1.0.2
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (!document) var document = { cookie: '' }; // fix crashes on node
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Javascript class that mimics how WCF serializes a object of type MongoDB.Bson.ObjectId
|
|
18
|
-
* and converts between that format and the standard 24 character representation.
|
|
19
|
-
*/
|
|
20
|
-
export var ObjectId = (function () {
|
|
21
|
-
var increment = Math.floor(Math.random() * (16777216));
|
|
22
|
-
var pid = Math.floor(Math.random() * (65536));
|
|
23
|
-
var machine = Math.floor(Math.random() * (16777216));
|
|
24
|
-
|
|
25
|
-
var setMachineCookie = function() {
|
|
26
|
-
var cookieList = document.cookie.split('; ');
|
|
27
|
-
for (var i in cookieList) {
|
|
28
|
-
var cookie = cookieList[i].split('=');
|
|
29
|
-
var cookieMachineId = parseInt(cookie[1], 10);
|
|
30
|
-
if (cookie[0] == 'mongoMachineId' && cookieMachineId && cookieMachineId >= 0 && cookieMachineId <= 16777215) {
|
|
31
|
-
machine = cookieMachineId;
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
document.cookie = 'mongoMachineId=' + machine + ';expires=Tue, 19 Jan 2038 05:00:00 GMT;path=/';
|
|
36
|
-
};
|
|
37
|
-
if (typeof (localStorage) != 'undefined') {
|
|
38
|
-
try {
|
|
39
|
-
var mongoMachineId = parseInt(localStorage['mongoMachineId']);
|
|
40
|
-
if (mongoMachineId >= 0 && mongoMachineId <= 16777215) {
|
|
41
|
-
machine = Math.floor(localStorage['mongoMachineId']);
|
|
42
|
-
}
|
|
43
|
-
// Just always stick the value in.
|
|
44
|
-
localStorage['mongoMachineId'] = machine;
|
|
45
|
-
} catch (e) {
|
|
46
|
-
setMachineCookie();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
setMachineCookie();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function ObjId() {
|
|
54
|
-
if (!(this instanceof ObjectId)) {
|
|
55
|
-
return new ObjectId(arguments[0], arguments[1], arguments[2], arguments[3]).toString();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (typeof (arguments[0]) == 'object') {
|
|
59
|
-
this.timestamp = arguments[0].timestamp;
|
|
60
|
-
this.machine = arguments[0].machine;
|
|
61
|
-
this.pid = arguments[0].pid;
|
|
62
|
-
this.increment = arguments[0].increment;
|
|
63
|
-
}
|
|
64
|
-
else if (typeof (arguments[0]) == 'string' && arguments[0].length == 24) {
|
|
65
|
-
this.timestamp = Number('0x' + arguments[0].substr(0, 8)),
|
|
66
|
-
this.machine = Number('0x' + arguments[0].substr(8, 6)),
|
|
67
|
-
this.pid = Number('0x' + arguments[0].substr(14, 4)),
|
|
68
|
-
this.increment = Number('0x' + arguments[0].substr(18, 6))
|
|
69
|
-
}
|
|
70
|
-
else if (arguments.length == 4 && arguments[0] != null) {
|
|
71
|
-
this.timestamp = arguments[0];
|
|
72
|
-
this.machine = arguments[1];
|
|
73
|
-
this.pid = arguments[2];
|
|
74
|
-
this.increment = arguments[3];
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
this.timestamp = Math.floor(new Date().valueOf() / 1000);
|
|
78
|
-
this.machine = machine;
|
|
79
|
-
this.pid = pid;
|
|
80
|
-
this.increment = increment++;
|
|
81
|
-
if (increment > 0xffffff) {
|
|
82
|
-
increment = 0;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
return ObjId;
|
|
87
|
-
})();
|
|
88
|
-
|
|
89
|
-
ObjectId.prototype.getDate = function () {
|
|
90
|
-
return new Date(this.timestamp * 1000);
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
ObjectId.prototype.toArray = function () {
|
|
94
|
-
var strOid = this.toString();
|
|
95
|
-
var array = [];
|
|
96
|
-
var i;
|
|
97
|
-
for(i = 0; i < 12; i++) {
|
|
98
|
-
array[i] = parseInt(strOid.slice(i*2, i*2+2), 16);
|
|
99
|
-
}
|
|
100
|
-
return array;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Turns a WCF representation of a BSON ObjectId into a 24 character string representation.
|
|
105
|
-
*/
|
|
106
|
-
ObjectId.prototype.toString = function () {
|
|
107
|
-
if (this.timestamp === undefined
|
|
108
|
-
|| this.machine === undefined
|
|
109
|
-
|| this.pid === undefined
|
|
110
|
-
|| this.increment === undefined) {
|
|
111
|
-
return 'Invalid ObjectId';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
var timestamp = this.timestamp.toString(16);
|
|
115
|
-
var machine = this.machine.toString(16);
|
|
116
|
-
var pid = this.pid.toString(16);
|
|
117
|
-
var increment = this.increment.toString(16);
|
|
118
|
-
return '00000000'.substr(0, 8 - timestamp.length) + timestamp +
|
|
119
|
-
'000000'.substr(0, 6 - machine.length) + machine +
|
|
120
|
-
'0000'.substr(0, 4 - pid.length) + pid +
|
|
121
|
-
'000000'.substr(0, 6 - increment.length) + increment;
|
|
122
|
-
};
|
|
123
|
-
|