mirror of
https://github.com/20kaushik02/express-sequelize-backend-template.git
synced 2025-12-06 08:54:07 +00:00
utils
This commit is contained in:
parent
af932c038d
commit
ca0c8e96d4
34
middleware/admin.js
Normal file
34
middleware/admin.js
Normal file
@ -0,0 +1,34 @@
|
||||
const typedefs = require("../typedefs");
|
||||
const logger = require("../utils/logger")(module);
|
||||
|
||||
const creds = JSON.parse(process.env.ADMIN_CREDS);
|
||||
|
||||
/**
|
||||
* Middleware to validate admin access
|
||||
* @param {typedefs.Req} req
|
||||
* @param {typedefs.Res} res
|
||||
* @param {typedefs.Next} next
|
||||
*/
|
||||
const adminQueryCreds = async (req, res, next) => {
|
||||
try {
|
||||
/** @type {JSON} */
|
||||
const { user, access } = req.query;
|
||||
if (creds[user] === access) {
|
||||
logger.info("Admin access - " + user);
|
||||
next();
|
||||
}
|
||||
else {
|
||||
// we do a bit of trolling here
|
||||
const unauthIP = req.headers['x-real-ip'] || req.ip
|
||||
logger.warn("Intruder alert.", { ip: unauthIP });
|
||||
return res.status(401).send("Intruder alert. IP address: " + unauthIP);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error("adminQueryCreds", { error });
|
||||
return res.status(500).send({ message: "Server Error. Try again." });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
adminQueryCreds,
|
||||
}
|
||||
189
package-lock.json
generated
189
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "backend-template",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "backend-template",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
@ -16,7 +16,7 @@
|
||||
"express-validator": "^6.14.2",
|
||||
"fast-csv": "^4.3.6",
|
||||
"helmet": "^6.0.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"nodemailer": "^6.8.0",
|
||||
"pg": "^8.8.0",
|
||||
"sequelize": "^6.24.0",
|
||||
@ -1160,24 +1160,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "8.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
|
||||
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
|
||||
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
|
||||
"dependencies": {
|
||||
"jws": "^3.2.2",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^5.6.0"
|
||||
"semver": "^7.3.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4",
|
||||
"npm": ">=1.4.28"
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/ms": {
|
||||
@ -1185,6 +1190,25 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/semver": {
|
||||
"version": "7.5.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
|
||||
"integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
|
||||
@ -1224,11 +1248,6 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
|
||||
"integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw=="
|
||||
},
|
||||
"node_modules/lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
|
||||
},
|
||||
"node_modules/lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
@ -1244,41 +1263,16 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
|
||||
"integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw=="
|
||||
},
|
||||
"node_modules/lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
|
||||
},
|
||||
"node_modules/lodash.isnil": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz",
|
||||
"integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng=="
|
||||
},
|
||||
"node_modules/lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
|
||||
},
|
||||
"node_modules/lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
|
||||
},
|
||||
"node_modules/lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
|
||||
},
|
||||
"node_modules/lodash.isundefined": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz",
|
||||
"integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA=="
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
|
||||
},
|
||||
"node_modules/lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
@ -1847,9 +1841,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/retry-as-promised": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-6.1.0.tgz",
|
||||
"integrity": "sha512-Hj/jY+wFC+SB9SDlIIFWiGOHnNG0swYbGYsOj2BJ8u2HKUaobNKab0OIC0zOLYzDy0mb7A4xA5BMo4LMz5YtEA=="
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz",
|
||||
"integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA=="
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
@ -1887,6 +1881,7 @@
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
@ -1920,9 +1915,9 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/sequelize": {
|
||||
"version": "6.25.4",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.25.4.tgz",
|
||||
"integrity": "sha512-gD6RoEVlTKxQh9GC6Qd+pW2A9uhmqeuwBHGMGcZtDg2CchXQhrwS+k6ZnWZ1ggYZ3tUkk4q8fkFL3/XmXnMFFQ==",
|
||||
"version": "6.31.1",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.31.1.tgz",
|
||||
"integrity": "sha512-cahWtRrYLjqoZP/aurGBoaxn29qQCF4bxkAUPEQ/ozjJjt6mtL4Q113S3N39mQRmX5fgxRbli+bzZARP/N51eg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@ -1937,9 +1932,9 @@
|
||||
"inflection": "^1.13.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"moment-timezone": "^0.5.35",
|
||||
"pg-connection-string": "^2.5.0",
|
||||
"retry-as-promised": "^6.1.0",
|
||||
"retry-as-promised": "^7.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"sequelize-pool": "^7.1.0",
|
||||
"toposort-class": "^1.0.1",
|
||||
@ -3462,26 +3457,41 @@
|
||||
}
|
||||
},
|
||||
"jsonwebtoken": {
|
||||
"version": "8.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
|
||||
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
|
||||
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
|
||||
"requires": {
|
||||
"jws": "^3.2.2",
|
||||
"lodash.includes": "^4.3.0",
|
||||
"lodash.isboolean": "^3.0.3",
|
||||
"lodash.isinteger": "^4.0.4",
|
||||
"lodash.isnumber": "^3.0.3",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"lodash.isstring": "^4.0.1",
|
||||
"lodash.once": "^4.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"ms": "^2.1.1",
|
||||
"semver": "^5.6.0"
|
||||
"semver": "^7.3.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.5.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
|
||||
"integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3524,11 +3534,6 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
|
||||
"integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw=="
|
||||
},
|
||||
"lodash.includes": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
|
||||
},
|
||||
"lodash.isboolean": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
|
||||
@ -3544,41 +3549,16 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz",
|
||||
"integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw=="
|
||||
},
|
||||
"lodash.isinteger": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
|
||||
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
|
||||
},
|
||||
"lodash.isnil": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz",
|
||||
"integrity": "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng=="
|
||||
},
|
||||
"lodash.isnumber": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
|
||||
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
|
||||
},
|
||||
"lodash.isplainobject": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
|
||||
},
|
||||
"lodash.isstring": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
|
||||
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
|
||||
},
|
||||
"lodash.isundefined": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isundefined/-/lodash.isundefined-3.0.1.tgz",
|
||||
"integrity": "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA=="
|
||||
},
|
||||
"lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
|
||||
},
|
||||
"lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
@ -4006,9 +3986,9 @@
|
||||
}
|
||||
},
|
||||
"retry-as-promised": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-6.1.0.tgz",
|
||||
"integrity": "sha512-Hj/jY+wFC+SB9SDlIIFWiGOHnNG0swYbGYsOj2BJ8u2HKUaobNKab0OIC0zOLYzDy0mb7A4xA5BMo4LMz5YtEA=="
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz",
|
||||
"integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
@ -4028,7 +4008,8 @@
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
},
|
||||
"send": {
|
||||
"version": "0.18.0",
|
||||
@ -4058,9 +4039,9 @@
|
||||
}
|
||||
},
|
||||
"sequelize": {
|
||||
"version": "6.25.4",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.25.4.tgz",
|
||||
"integrity": "sha512-gD6RoEVlTKxQh9GC6Qd+pW2A9uhmqeuwBHGMGcZtDg2CchXQhrwS+k6ZnWZ1ggYZ3tUkk4q8fkFL3/XmXnMFFQ==",
|
||||
"version": "6.31.1",
|
||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.31.1.tgz",
|
||||
"integrity": "sha512-cahWtRrYLjqoZP/aurGBoaxn29qQCF4bxkAUPEQ/ozjJjt6mtL4Q113S3N39mQRmX5fgxRbli+bzZARP/N51eg==",
|
||||
"requires": {
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/validator": "^13.7.1",
|
||||
@ -4069,9 +4050,9 @@
|
||||
"inflection": "^1.13.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.34",
|
||||
"moment-timezone": "^0.5.35",
|
||||
"pg-connection-string": "^2.5.0",
|
||||
"retry-as-promised": "^6.1.0",
|
||||
"retry-as-promised": "^7.0.3",
|
||||
"semver": "^7.3.5",
|
||||
"sequelize-pool": "^7.1.0",
|
||||
"toposort-class": "^1.0.1",
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
"express-validator": "^6.14.2",
|
||||
"fast-csv": "^4.3.6",
|
||||
"helmet": "^6.0.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"nodemailer": "^6.8.0",
|
||||
"pg": "^8.8.0",
|
||||
"sequelize": "^6.24.0",
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
* @typedef {import("express").Response} Res
|
||||
* @typedef {import("express").NextFunction} Next
|
||||
*
|
||||
* @typedef {import("sequelize") Sequelize}
|
||||
* @typedef {import("sequelize").Model Model}
|
||||
* @typedef {import("sequelize").QueryInterface QueryInterface}
|
||||
* @typedef {import("sequelize")} Sequelize
|
||||
* @typedef {import("sequelize").Model} Model
|
||||
* @typedef {import("sequelize").QueryInterface} QueryInterface
|
||||
*
|
||||
* @typedef {import("winston").Logger} Logger
|
||||
*/
|
||||
|
||||
27
utils/archiver.js
Normal file
27
utils/archiver.js
Normal file
@ -0,0 +1,27 @@
|
||||
const fs = require("fs");
|
||||
const archiver = require('archiver');
|
||||
|
||||
/**
|
||||
* @param {String} sourceDir: /some/folder/to/compress
|
||||
* @param {String} outPath: /path/to/created.zip
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function zipDirectory(sourceDir, outPath) {
|
||||
const archive = archiver('zip', { zlib: { level: 9 } });
|
||||
const stream = fs.createWriteStream(outPath);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
archive
|
||||
.directory(sourceDir, false)
|
||||
.on('error', err => reject(err))
|
||||
.pipe(stream)
|
||||
;
|
||||
|
||||
stream.on('close', () => resolve());
|
||||
archive.finalize();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
zipDirectory,
|
||||
}
|
||||
12
utils/dateFormatter.js
Normal file
12
utils/dateFormatter.js
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Returns a timestamp string to use for timestamped files
|
||||
* @returns {string} String of current datetime in YYYY.MM.DD-HH:MM:SS format
|
||||
*/
|
||||
const dateForFilename = () => {
|
||||
const dt = new Date();
|
||||
return `${dt.getFullYear()}-${dt.getMonth() + 1}-${dt.getDate()}-${dt.getHours()}-${dt.getMinutes()}-${dt.getSeconds()}`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
dateForFilename,
|
||||
}
|
||||
24
utils/formData.js
Normal file
24
utils/formData.js
Normal file
@ -0,0 +1,24 @@
|
||||
function buildFormData(formData, data, parentKey) {
|
||||
if (data && typeof data === 'object' && !(data instanceof Date)) {
|
||||
Object.keys(data).forEach(key => {
|
||||
buildFormData(formData, data[key], parentKey ? `${parentKey}[${key}]` : key);
|
||||
});
|
||||
} else {
|
||||
const value = data == null ? '' : data;
|
||||
|
||||
formData.append(parentKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
function jsonToFormData(data) {
|
||||
const formData = new FormData();
|
||||
|
||||
buildFormData(formData, data);
|
||||
|
||||
return formData;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
jsonToFormData,
|
||||
buildFormData,
|
||||
}
|
||||
58
utils/qrGenerator.js
Normal file
58
utils/qrGenerator.js
Normal file
@ -0,0 +1,58 @@
|
||||
const pathLib = require("path");
|
||||
const qr = require("qrcode");
|
||||
const logger = require("./logger")(module);
|
||||
const { getSignedJWT } = require("./token");
|
||||
|
||||
/**
|
||||
* Generates QR code from data and writes to file in tmp folder.
|
||||
* To avoid race conditions, use email or other unique attributes for id.
|
||||
* @param {string|any} data String or JSON object
|
||||
*/
|
||||
const qrPNGFile = (id, data) => {
|
||||
qr.toFile(
|
||||
path = pathLib.join(__dirname, "../tmp/tmpQR-" + id + ".png"),
|
||||
text = (typeof data === "object" ? JSON.stringify(data) : data),
|
||||
options = { type: 'png' },
|
||||
(err) => {
|
||||
if (err) {
|
||||
logger.error("qrPNGFile", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates QR code from data after signing and writes to file in tmp or k-qrs folder.
|
||||
*
|
||||
* To avoid race conditions, use email or other unique attributes for ID.
|
||||
* @param {string|any} data String or JSON object
|
||||
*/
|
||||
const qrSignedPNGFile = (id, data, tmp = true) => {
|
||||
const signedData = getSignedJWT(data);
|
||||
const qrFilename = `${tmp ? 'tmpEncQR' : 'K-QR'}-${id}.png`;
|
||||
const targetPath = pathLib.join(
|
||||
__dirname, "..",
|
||||
tmp ? "tmp" : pathLib.join("uploads", "2023", "k-qrs"),
|
||||
qrFilename,
|
||||
);
|
||||
|
||||
qr.toFile(
|
||||
path = targetPath,
|
||||
text = (typeof data === "object" ? JSON.stringify(signedData) : signedData),
|
||||
options = { type: 'png' },
|
||||
(err) => {
|
||||
if (err) {
|
||||
logger.error("qrSignedPNGFile", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return qrFilename;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
qrPNGFile,
|
||||
qrSignedPNGFile,
|
||||
}
|
||||
23
utils/quickEncrypt.js
Normal file
23
utils/quickEncrypt.js
Normal file
@ -0,0 +1,23 @@
|
||||
/* Taken from quick-encrypt package, which is not maintained anymore */
|
||||
|
||||
const crypto = require('crypto')
|
||||
|
||||
const acceptableBitSizes = [1024, 2048];
|
||||
|
||||
exports.generate = (sizeInBits) => {
|
||||
if (!acceptableBitSizes.includes(sizeInBits))
|
||||
throw Error('Error generating public and private key. Key size can only be 1024 or 2048. Example usage: ` let keys = QuickEncrypt.generate(2048); `')
|
||||
return keypair({ bits: sizeInBits })
|
||||
}
|
||||
|
||||
exports.encrypt = (payloadString, publicKey) => {
|
||||
if (typeof payloadString !== 'string' || typeof publicKey !== 'string')
|
||||
throw Error("Error encrypting. Payload and Public Key should be in text format. Example usage: ` let encryptedText = QuickEncrypt.encrypt('Some secret text here!', 'the public RSA key in text format here'); ` ")
|
||||
return crypto.publicEncrypt(publicKey, Buffer.from(payloadString, 'utf8')).toString('hex')
|
||||
}
|
||||
|
||||
exports.decrypt = (encryptedString, privateKey) => {
|
||||
if (typeof encryptedString !== 'string' || typeof privateKey !== 'string')
|
||||
throw Error("Error decrypting. Decrypted Text and Private Key should be in text format. Example usage: ` let decryptedText = QuickEncrypt.decrypt('asddd213d19jenacanscasn', 'the private RSA key in text format here'); ` ")
|
||||
return crypto.privateDecrypt({ key: privateKey }, Buffer.from(encryptedString, 'hex')).toString()
|
||||
}
|
||||
30
utils/sendAttachment.js
Normal file
30
utils/sendAttachment.js
Normal file
@ -0,0 +1,30 @@
|
||||
const typedefs = require("../typedefs");
|
||||
|
||||
const fastCSV = require("fast-csv");
|
||||
const stream = require("stream");
|
||||
|
||||
/**
|
||||
* Sends object data from Sequelize after formatting into CSV
|
||||
*
|
||||
* @param {typedefs.Res} res Express response object
|
||||
* @param {string} filename Filename for attachment. Prefer timestamped names
|
||||
* @param {any[]} data Data from database queries, without metadata
|
||||
* @returns
|
||||
*/
|
||||
const sendCSV = async (res, filename, data) => {
|
||||
const csvData = await fastCSV.writeToBuffer(data, { headers: true });
|
||||
|
||||
// refer https://stackoverflow.com/a/45922316/
|
||||
const fileStream = new stream.PassThrough();
|
||||
fileStream.end(csvData);
|
||||
|
||||
res.attachment(filename + ".csv");
|
||||
res.type("text/csv");
|
||||
|
||||
fileStream.pipe(res);
|
||||
return;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
sendCSV,
|
||||
}
|
||||
60
utils/token.js
Normal file
60
utils/token.js
Normal file
@ -0,0 +1,60 @@
|
||||
const fs = require("fs");
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
const privateKey = fs.readFileSync(process.env.PRIVKEY);
|
||||
const publicKey = fs.readFileSync(process.env.PUBKEY);
|
||||
|
||||
/**
|
||||
* Sign data into JWT with JWT env secret
|
||||
* @param {string|any} data
|
||||
* @returns {jwt.JwtPayload}
|
||||
*/
|
||||
const getJWT = (data) => {
|
||||
return jwt.sign({ id: data }, process.env.JWTSECRET, { algorithm: "HS256" }); // symmetric encryption, so simple secret with SHA
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign data into JWT with private key.
|
||||
* @param {string|any} data
|
||||
* @returns {jwt.JwtPayload}
|
||||
*/
|
||||
const getSignedJWT = (data) => {
|
||||
return jwt.sign(
|
||||
{ id: data },
|
||||
privateKey,
|
||||
{
|
||||
algorithm: "RS256", // asymmetric signing, so private key with RSA
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a JWT with JWT env secret
|
||||
* @param {jwt.JwtPayload} data
|
||||
* @returns {string|any}
|
||||
*/
|
||||
const verifyJWT = (data) => {
|
||||
return jwt.verify(data, process.env.JWTSECRET, { algorithms: ["HS256"] });
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a signed JWT with public key.
|
||||
* @param {jwt.JwtPayload} signedString
|
||||
* @returns {string|any}
|
||||
*/
|
||||
const verifySignedJWT = (signedString) => {
|
||||
return jwt.verify(
|
||||
signedString,
|
||||
publicKey,
|
||||
{
|
||||
algorithms: ["RS256"]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getJWT,
|
||||
verifyJWT,
|
||||
getSignedJWT,
|
||||
verifySignedJWT,
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user