@trap_stevo/star-vault
Version:
Deterministic data engine that eliminates query-time joins and enables normalized data execution. Architect secure, scalable, real-time systems with integrated sharding, encryption, and event-driven data flows. Manage hierarchical structures, execute adva
135 lines (134 loc) • 5.95 kB
JavaScript
;
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var crypto = require("crypto");
var path = require("path");
var fs = require("fs");
var os = require("os");
var SecurityCore = /*#__PURE__*/function () {
function SecurityCore() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$masterKey = _ref.masterKey,
masterKey = _ref$masterKey === void 0 ? null : _ref$masterKey,
_ref$vaultPath = _ref.vaultPath,
vaultPath = _ref$vaultPath === void 0 ? "./star-vault.json" : _ref$vaultPath,
_ref$dirMode = _ref.dirMode,
dirMode = _ref$dirMode === void 0 ? 448 : _ref$dirMode,
_ref$fileMode = _ref.fileMode,
fileMode = _ref$fileMode === void 0 ? 384 : _ref$fileMode;
_classCallCheck(this, SecurityCore);
var rawKey = masterKey || os.hostname();
this.masterKey = rawKey ? this.forgeMasterKey(rawKey) : null;
this.vaultPath = vaultPath;
this.fileMode = fileMode;
this.dirMode = dirMode;
this.vault = new Map(this.loadVault());
}
return _createClass(SecurityCore, [{
key: "forgeMasterKey",
value: function forgeMasterKey(rawKey) {
return crypto.scryptSync(String(rawKey), "global-salt", 32);
}
}, {
key: "generateToken",
value: function generateToken() {
return crypto.randomBytes(32);
}
}, {
key: "sealKey",
value: function sealKey(dek) {
if (!this.masterKey) {
throw new Error("MasterKey required to seal keys.");
}
var iv = crypto.randomBytes(16);
var cipher = crypto.createCipheriv("aes-256-cbc", this.masterKey, iv);
var sealed = Buffer.concat([cipher.update(dek), cipher["final"]()]);
return {
sealed: sealed.toString("hex"),
iv: iv.toString("hex")
};
}
}, {
key: "unsealKey",
value: function unsealKey(sealedDEK) {
if (!this.masterKey) {
throw new Error("MasterKey required to unseal keys.");
}
var sealed = sealedDEK.sealed,
iv = sealedDEK.iv;
var decipher = crypto.createDecipheriv("aes-256-cbc", this.masterKey, Buffer.from(iv, "hex"));
var unsealed = Buffer.concat([decipher.update(Buffer.from(sealed, "hex")), decipher["final"]()]);
return unsealed;
}
}, {
key: "getKeyForContext",
value: function getKeyForContext(context) {
if (!this.vault.has(context)) {
var token = this.generateToken();
var sealedToken = this.masterKey ? this.sealKey(token) : token;
this.vault.set(context, sealedToken);
this.saveVault();
}
var storedKey = this.vault.get(context);
return this.masterKey ? this.unsealKey(storedKey) : storedKey;
}
}, {
key: "lock",
value: function lock(data, context) {
var currentContext = context.replace("\\", "/");
var dek = this.getKeyForContext(currentContext);
var iv = crypto.randomBytes(16);
var cipher = crypto.createCipheriv("aes-256-cbc", dek, iv);
var locked = Buffer.concat([cipher.update(JSON.stringify(data)), cipher["final"]()]);
return {
locked: locked.toString("hex"),
iv: iv.toString("hex")
};
}
}, {
key: "unlock",
value: function unlock(lockedData, context) {
var currentContext = context.replace("\\", "/");
if (!lockedData || _typeof(lockedData) !== "object" || !lockedData.locked || !lockedData.iv) {
throw new Error("Invalid encrypted data received for context ~ \"".concat(currentContext, "\"."));
}
var dek = this.getKeyForContext(currentContext);
if (!dek) {
throw new Error("No DEK found for context ~ \"".concat(concurrentContexttext, "\"."));
}
var decipher = crypto.createDecipheriv("aes-256-cbc", dek, Buffer.from(lockedData.iv, "hex"));
var decrypted = Buffer.concat([decipher.update(Buffer.from(lockedData.locked, "hex")), decipher["final"]()]);
return JSON.parse(decrypted.toString());
}
}, {
key: "loadVault",
value: function loadVault() {
if (fs.existsSync(this.vaultPath)) {
var vaultData = fs.readFileSync(this.vaultPath, "utf-8");
var parsedVault = JSON.parse(vaultData);
return Object.entries(parsedVault);
}
return [];
}
}, {
key: "saveVault",
value: function saveVault() {
var vaultDir = path.dirname(this.vaultPath);
if (!fs.existsSync(vaultDir)) {
fs.mkdirSync(vaultDir, {
recursive: true,
mode: 448
});
}
var vaultObject = Object.fromEntries(this.vault);
fs.writeFileSync(this.vaultPath, JSON.stringify(vaultObject), {
mode: 384
});
}
}]);
}();
module.exports = SecurityCore;