mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
105 lines
2.6 KiB
JavaScript
105 lines
2.6 KiB
JavaScript
require('dotenv').config();
|
|
|
|
const { webcrypto } = require('node:crypto');
|
|
const key = Buffer.from(process.env.CREDS_KEY, 'hex');
|
|
const iv = Buffer.from(process.env.CREDS_IV, 'hex');
|
|
const algorithm = 'AES-CBC';
|
|
|
|
async function encrypt(value) {
|
|
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
|
|
'encrypt',
|
|
]);
|
|
|
|
const encoder = new TextEncoder();
|
|
const data = encoder.encode(value);
|
|
|
|
const encryptedBuffer = await webcrypto.subtle.encrypt(
|
|
{
|
|
name: algorithm,
|
|
iv: iv,
|
|
},
|
|
cryptoKey,
|
|
data,
|
|
);
|
|
|
|
return Buffer.from(encryptedBuffer).toString('hex');
|
|
}
|
|
|
|
async function decrypt(encryptedValue) {
|
|
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
|
|
'decrypt',
|
|
]);
|
|
|
|
const encryptedBuffer = Buffer.from(encryptedValue, 'hex');
|
|
|
|
const decryptedBuffer = await webcrypto.subtle.decrypt(
|
|
{
|
|
name: algorithm,
|
|
iv: iv,
|
|
},
|
|
cryptoKey,
|
|
encryptedBuffer,
|
|
);
|
|
|
|
const decoder = new TextDecoder();
|
|
return decoder.decode(decryptedBuffer);
|
|
}
|
|
|
|
// Programmatically generate iv
|
|
async function encryptV2(value) {
|
|
const gen_iv = webcrypto.getRandomValues(new Uint8Array(16));
|
|
|
|
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
|
|
'encrypt',
|
|
]);
|
|
|
|
const encoder = new TextEncoder();
|
|
const data = encoder.encode(value);
|
|
|
|
const encryptedBuffer = await webcrypto.subtle.encrypt(
|
|
{
|
|
name: algorithm,
|
|
iv: gen_iv,
|
|
},
|
|
cryptoKey,
|
|
data,
|
|
);
|
|
|
|
return Buffer.from(gen_iv).toString('hex') + ':' + Buffer.from(encryptedBuffer).toString('hex');
|
|
}
|
|
|
|
async function decryptV2(encryptedValue) {
|
|
const parts = encryptedValue.split(':');
|
|
// Already decrypted from an earlier invocation
|
|
if (parts.length === 1) {
|
|
return parts[0];
|
|
}
|
|
const gen_iv = Buffer.from(parts.shift(), 'hex');
|
|
const encrypted = parts.join(':');
|
|
|
|
const cryptoKey = await webcrypto.subtle.importKey('raw', key, { name: algorithm }, false, [
|
|
'decrypt',
|
|
]);
|
|
|
|
const encryptedBuffer = Buffer.from(encrypted, 'hex');
|
|
|
|
const decryptedBuffer = await webcrypto.subtle.decrypt(
|
|
{
|
|
name: algorithm,
|
|
iv: gen_iv,
|
|
},
|
|
cryptoKey,
|
|
encryptedBuffer,
|
|
);
|
|
|
|
const decoder = new TextDecoder();
|
|
return decoder.decode(decryptedBuffer);
|
|
}
|
|
|
|
async function hashToken(str) {
|
|
const data = new TextEncoder().encode(str);
|
|
const hashBuffer = await webcrypto.subtle.digest('SHA-256', data);
|
|
return Buffer.from(hashBuffer).toString('hex');
|
|
}
|
|
|
|
module.exports = { encrypt, decrypt, encryptV2, decryptV2, hashToken };
|