@vollcrypt/db-guard 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.createTypeOrmSubscriber = createTypeOrmSubscriber;
38
+ const typeorm_1 = require("typeorm");
39
+ const prisma_1 = require("./prisma");
40
+ const blind_index_1 = require("./blind-index");
41
+ const security_1 = require("./security");
42
+ function getKeys(options) {
43
+ let keys;
44
+ let activeVersion;
45
+ if (Buffer.isBuffer(options.key)) {
46
+ keys = { '1': options.key };
47
+ activeVersion = '1';
48
+ }
49
+ else {
50
+ keys = options.key;
51
+ activeVersion = options.activeKeyVersion || Object.keys(keys)[0];
52
+ }
53
+ return { keys, activeVersion };
54
+ }
55
+ function createTypeOrmSubscriber(options) {
56
+ const { keys, activeVersion } = getKeys(options);
57
+ const activeKey = keys[activeVersion];
58
+ if (!activeKey) {
59
+ throw new Error(`Active encryption key version "${activeVersion}" is not present in the key map.`);
60
+ }
61
+ (0, security_1.registerKeysForZeroization)(keys);
62
+ let VollcryptDbGuardSubscriber = (() => {
63
+ let _classDecorators = [(0, typeorm_1.EventSubscriber)()];
64
+ let _classDescriptor;
65
+ let _classExtraInitializers = [];
66
+ let _classThis;
67
+ var VollcryptDbGuardSubscriber = class {
68
+ static { _classThis = this; }
69
+ static {
70
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
71
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
72
+ VollcryptDbGuardSubscriber = _classThis = _classDescriptor.value;
73
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
74
+ __runInitializers(_classThis, _classExtraInitializers);
75
+ }
76
+ listenTo() {
77
+ return Object;
78
+ }
79
+ beforeInsert(event) {
80
+ const entityName = event.metadata.name;
81
+ const fields = options.entities[entityName];
82
+ if (fields && event.entity) {
83
+ // Calculate blind indexes first (before the original field gets encrypted)
84
+ if (options.blindIndexes && options.blindIndexes.rootSalt) {
85
+ const bidxFields = options.blindIndexes.entities[entityName];
86
+ if (bidxFields) {
87
+ for (const field of bidxFields) {
88
+ if (event.entity[field] !== undefined && event.entity[field] !== null) {
89
+ const bidxField = `${field}_bidx`;
90
+ event.entity[bidxField] = (0, blind_index_1.computeBlindIndex)(event.entity[field], options.blindIndexes.rootSalt, `${entityName}.${field}`);
91
+ }
92
+ }
93
+ }
94
+ }
95
+ // Encrypt fields
96
+ for (const field of fields) {
97
+ if (event.entity[field] !== undefined && event.entity[field] !== null) {
98
+ event.entity[field] = (0, prisma_1.encryptValue)(event.entity[field], activeKey, activeVersion);
99
+ }
100
+ }
101
+ }
102
+ }
103
+ beforeUpdate(event) {
104
+ const entityName = event.metadata.name;
105
+ const fields = options.entities[entityName];
106
+ if (fields && event.entity) {
107
+ // Calculate blind indexes first
108
+ if (options.blindIndexes && options.blindIndexes.rootSalt) {
109
+ const bidxFields = options.blindIndexes.entities[entityName];
110
+ if (bidxFields) {
111
+ for (const field of bidxFields) {
112
+ if (event.entity[field] !== undefined && event.entity[field] !== null) {
113
+ const bidxField = `${field}_bidx`;
114
+ event.entity[bidxField] = (0, blind_index_1.computeBlindIndex)(event.entity[field], options.blindIndexes.rootSalt, `${entityName}.${field}`);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ // Encrypt fields
120
+ for (const field of fields) {
121
+ if (event.entity[field] !== undefined && event.entity[field] !== null) {
122
+ event.entity[field] = (0, prisma_1.encryptValue)(event.entity[field], activeKey, activeVersion);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ afterLoad(entity, event) {
128
+ if (!event || !event.metadata)
129
+ return;
130
+ const entityName = event.metadata.name;
131
+ const fields = options.entities[entityName];
132
+ if (fields && entity) {
133
+ for (const field of fields) {
134
+ if (entity[field] !== undefined && entity[field] !== null) {
135
+ try {
136
+ entity[field] = (0, security_1.decryptWithSecurity)(entity[field], (val) => (0, prisma_1.decryptValue)(val, keys), entityName, field, entity.id || entity._id, options);
137
+ }
138
+ catch (err) {
139
+ throw new Error(`TypeORM db-guard failed to decrypt field "${field}": ${err.message}`);
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+ };
146
+ return VollcryptDbGuardSubscriber = _classThis;
147
+ })();
148
+ return VollcryptDbGuardSubscriber;
149
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@vollcrypt/db-guard",
3
+ "version": "0.1.0",
4
+ "description": "Database field-level encryption integrations for Vollcrypt (Prisma, Mongoose, Drizzle, TypeORM)",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "vollcrypt-db-guard": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "compliance-config.json"
14
+ ],
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/BeratVural/vollcrypt.git",
21
+ "directory": "db-guard/node"
22
+ },
23
+ "author": "Berat Vural <berat.vural.tr@gmail.com>",
24
+ "license": "GPL-3.0-only OR LicenseRef-Commercial",
25
+ "bugs": {
26
+ "url": "https://github.com/BeratVural/vollcrypt/issues"
27
+ },
28
+ "homepage": "https://github.com/BeratVural/vollcrypt/tree/main/db-guard/node#readme",
29
+ "scripts": {
30
+ "build": "tsc && node scripts/generate-sbom.js",
31
+ "test": "node --import tsx --test tests/*.test.ts"
32
+ },
33
+ "dependencies": {},
34
+ "peerDependencies": {
35
+ "@prisma/client": ">=4.7.0",
36
+ "mongoose": ">=6.0.0",
37
+ "drizzle-orm": ">=0.28.0",
38
+ "typeorm": ">=0.3.0"
39
+ },
40
+ "devDependencies": {
41
+ "@prisma/client": "^5.0.0",
42
+ "@types/node": "^20.11.0",
43
+ "mongoose": "^8.0.0",
44
+ "prisma": "^5.0.0",
45
+ "drizzle-orm": "^0.30.0",
46
+ "typeorm": "^0.3.20",
47
+ "tsx": "^4.7.0",
48
+ "typescript": "^5.5.2"
49
+ }
50
+ }