mirror of
https://github.com/20kaushik02/express-sequelize-backend-template.git
synced 2026-01-25 07:14:06 +00:00
utils
This commit is contained in:
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,
|
||||
};
|
||||
Reference in New Issue
Block a user