@trap_stevo/veripath
Version:
The pinnacle of real-time encrypted routing and session-bound communication through a precision-crafted middleware system. Empowering developers to secure every route with dynamic request decryption, intelligent session validation, and seamless encrypted
150 lines (149 loc) โข 4.93 kB
JavaScript
"use strict";
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
const {
Level
} = require("level");
var _VeriVaultManager_brand = /*#__PURE__*/new WeakSet();
class VeriVaultManager {
constructor() {
_classPrivateMethodInitSpec(this, _VeriVaultManager_brand);
this.memoryStore = {};
this.db = null;
this.dbPath = "./verivault";
this.options = {
persistSessionKey: false,
persistSessionID: false,
mutator: new TextEncoder().encode("vlk"),
vaultSGN: "vlx",
linkSGN: "vli"
};
this.extractSessionID = this.defaultSessionIDExtractor;
}
async restorePaths() {
if (!this.db) {
return;
}
try {
for await (const [sessionID, entry] of this.db.iterator()) {
const alreadyInMemory = this.memoryStore[sessionID];
if (!alreadyInMemory) {
const expired = entry.expiresAt && Date.now() > entry.expiresAt;
if (!expired) {
this.memoryStore[sessionID] = entry;
console.log(`๐ Restored session path ~ ${sessionID}`);
} else {
await this.deleteKey(sessionID);
console.log(`๐งน Pruned expired session path ~ ${sessionID}`);
}
}
}
} catch (error) {
console.log("๐ Did not restore VeriVault session paths ~", error);
}
}
defaultSessionIDExtractor(req) {
return req.headers["x-vlink-session-id"] || null;
}
setCustomSessionIDExtractor(fn) {
if (typeof fn !== "function") {
console.log("Must use a function for Session ID extractor.");
return;
}
this.extractSessionID = fn;
}
async configure(config = {}) {
this.dbPath = config.dbPath || "./verivault";
this.options.persistSessionKey = config.persistSessionKey ?? false;
this.options.persistSessionID = config.persistSessionID ?? false;
this.options.mutator = typeof config.mutator === "string" ? new TextEncoder().encode(config.mutator) : config.mutator;
this.options.vaultSGN = config.vaultSGN || "vlx";
this.options.linkSGN = config.linkSGN || "vli";
this.db = new Level(this.dbPath, {
valueEncoding: "json"
});
}
async setKey(id, keyBuffer, options = {}) {
const key = keyBuffer instanceof ArrayBuffer ? keyBuffer : Uint8Array.from(keyBuffer).buffer;
const entry = {
expiresAt: options.expiresAt || null,
key: _assertClassBrand(_VeriVaultManager_brand, this, _mutateKey).call(this, key)
};
this.memoryStore[id] = entry;
try {
await this.db.put(id, entry);
} catch (error) {
console.log(`VeriVault Set Error [${id}]`, error);
}
}
async containsKey(sessionID) {
if (this.memoryStore[sessionID]) {
return true;
}
try {
const sessionData = await this.db.get(sessionID);
if (!entry) {
return false;
}
const expired = entry.expiresAt && Date.now() > entry.expiresAt;
if (expired) {
await this.deleteKey(sessionID);
return false;
}
return true;
} catch {
return false;
}
}
async getKey(req) {
const id = this.extractSessionID(req);
if (!id) {
return null;
}
let entry = this.memoryStore[id];
if (entry) {
if (entry.expiresAt && Date.now() > entry.expiresAt) {
await this.deleteKey(id);
return null;
}
return _assertClassBrand(_VeriVaultManager_brand, this, _unmutateKey).call(this, entry.key);
}
try {
entry = await this.db.get(id);
if (entry.expiresAt && Date.now() > entry.expiresAt) {
await this.deleteKey(id);
return null;
}
this.memoryStore[id] = entry;
return _assertClassBrand(_VeriVaultManager_brand, this, _unmutateKey).call(this, entry.key);
} catch {
return null;
}
}
async deleteKey(id) {
delete this.memoryStore[id];
try {
await this.db.del(id);
} catch (error) {
console.log(`VeriVault Delete Error [${id}]`, error);
}
}
}
function _mutateKey(arrayBuffer) {
const bytes = new Uint8Array(arrayBuffer);
const salt = this.options.mutator;
const mutated = bytes.map((b, i) => b ^ salt[i % salt.length]);
return Buffer.from(mutated).toString("base64");
}
function _unmutateKey(base64) {
const bytes = Buffer.from(base64, "base64");
const salt = this.options.mutator;
const restored = Uint8Array.from(bytes.map((b, i) => b ^ salt[i % salt.length]));
return restored.buffer;
}
;
const veriVaultManager = new VeriVaultManager();
module.exports = {
veriVaultManager
};