UNPKG

adba

Version:
133 lines (132 loc) 5.2 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import crypto from 'crypto'; import jwt from "jsonwebtoken"; import bcrypt from 'bcrypt'; import useragent from 'useragent'; export function encrypt(text, password, ivString) { const iv = ivString ? Buffer.from(ivString, 'hex') : crypto.randomBytes(16); const key = crypto.scryptSync(password, 'salt', 32); const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { encryptedData: encrypted, iv: iv.toString('hex') }; } export function decrypt(encryptedData, password, ivString) { const key = crypto.scryptSync(password, 'salt', 32); const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(ivString, 'hex')); let decrypted = decipher.update(encryptedData, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } /** * Generates a unique 6-digit code. * @returns {string} A 6-digit unique code. */ export function generateCode() { const bytes = crypto.randomBytes(4); const uint = bytes.readUInt32BE(0); const sixDigitCode = uint % 1000000; return sixDigitCode.toString().padStart(6, '0'); } /** * Generates a 32-byte key from any given string. * @param {string} input - The input string from which to generate the key. * @returns {Buffer} A 32-byte Buffer containing the key. */ const generateKeyFromInput = (input) => { // Create a SHA-256 hash of the input const hash = crypto.createHash('sha256'); hash.update(input); return hash.digest(); // This returns a Buffer with the 32-byte hash }; /** * Build a secure token * * @param {Object} data - The payload data * @param {string} pass - The encryption key * @param {string} ivString - ivString * @param {number|string} expiresIn - The expiration time for the token * @returns {string} - Returns the URL-safe encrypted token */ export const buildToken = (data, pass, ivString, expiresIn) => { // Encrypt the JSON content const key_in_bytes = generateKeyFromInput(pass); const cipher = crypto.createCipheriv('aes-256-cbc', key_in_bytes, Buffer.from(ivString, 'hex')); let encrypted = cipher.update(JSON.stringify(data), 'utf8', 'base64'); encrypted += cipher.final('base64'); // Generate the JWT token const token = jwt.sign({ payload: encrypted }, pass, { expiresIn }); // Make the token URL-safe return encodeURIComponent(token); }; /** * Decrypt a secure token to get the payload data * @param {string} encryptedToken - The encrypted token * @param {string} pass - The decryption key * @param {string} ivString - ivString * @returns {Object|null} - Returns the decrypted payload data, or null if decryption fails */ export const readToken = (encryptedToken, pass, ivString) => { try { // Decode the token first if it is URL-encoded const token = decodeURIComponent(encryptedToken); // Verify and decode the JWT token const decoded = jwt.verify(token, pass); if (typeof decoded !== 'object') { throw new Error("decoded data is not an object, spect an object:\n" + decoded); } // Decrypt the payload const key_in_bytes = generateKeyFromInput(pass); const decipher = crypto.createDecipheriv('aes-256-cbc', key_in_bytes, Buffer.from(ivString, 'hex')); let decrypted = decipher.update(decoded.payload, 'base64', 'utf8'); decrypted += decipher.final('utf8'); // Parse the decrypted content to an object const parsed = JSON.parse(decrypted); return parsed; } catch (err) { return err; } }; export function generatePasswordHash(password) { return __awaiter(this, void 0, void 0, function* () { try { const saltRounds = 10; const hash = yield bcrypt.hash(password, saltRounds); return hash; } catch (error) { return error; } }); } export function verifyPasswordHash(password, hash) { return __awaiter(this, void 0, void 0, function* () { try { const isMatch = yield bcrypt.compare(password, hash); return isMatch; } catch (error) { return error; } }); } export function getClientType(userAgent, device) { const agent = useragent.parse(userAgent); return agent.family; } export default { buildToken, readToken, generatePasswordHash, verifyPasswordHash, getClientType };