@vollcrypt/db-guard 0.1.0 → 0.1.2
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.
- package/dist/drivers.d.ts +15 -0
- package/dist/drivers.js +181 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/provenance.json +20 -8
- package/dist/provenance.json.sig +1 -1
- package/dist/sbom.json +16 -8
- package/dist/sbom.json.sig +2 -1
- package/dist/security.d.ts +2 -0
- package/dist/security.js +31 -10
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RateLimiterOptions } from './security.js';
|
|
2
|
+
export interface DbGuardDriverOptions {
|
|
3
|
+
key: Buffer | Record<string, Buffer>;
|
|
4
|
+
activeKeyVersion?: string;
|
|
5
|
+
entities: Record<string, string[]>;
|
|
6
|
+
cryptoRbac?: {
|
|
7
|
+
roles: Record<string, {
|
|
8
|
+
decrypt: string[];
|
|
9
|
+
mask?: Record<string, 'credit_card' | 'email' | 'tc_no' | ((v: any) => any) | string>;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
rateLimiter?: RateLimiterOptions;
|
|
13
|
+
}
|
|
14
|
+
export declare function wrapSqliteDatabase(db: any, options: DbGuardDriverOptions): any;
|
|
15
|
+
export declare function wrapOracleConnection(connection: any, options: DbGuardDriverOptions): any;
|
package/dist/drivers.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapSqliteDatabase = wrapSqliteDatabase;
|
|
4
|
+
exports.wrapOracleConnection = wrapOracleConnection;
|
|
5
|
+
const prisma_js_1 = require("./prisma.js");
|
|
6
|
+
const security_js_1 = require("./security.js");
|
|
7
|
+
function getKeys(options) {
|
|
8
|
+
let keys;
|
|
9
|
+
let activeVersion;
|
|
10
|
+
if (Buffer.isBuffer(options.key)) {
|
|
11
|
+
keys = { '1': options.key };
|
|
12
|
+
activeVersion = '1';
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
keys = options.key;
|
|
16
|
+
activeVersion = options.activeKeyVersion || Object.keys(keys)[0];
|
|
17
|
+
}
|
|
18
|
+
return { keys, activeVersion };
|
|
19
|
+
}
|
|
20
|
+
function getParamColumns(sql) {
|
|
21
|
+
const sqlClean = sql.replace(/\s+/g, ' ').trim();
|
|
22
|
+
// Match INSERT INTO table (col1, col2) ...
|
|
23
|
+
const insertMatch = sqlClean.match(/INSERT\s+INTO\s+(\w+)\s*\(([^)]+)\)/i);
|
|
24
|
+
if (insertMatch) {
|
|
25
|
+
const table = insertMatch[1];
|
|
26
|
+
const columns = insertMatch[2].split(',').map(c => c.trim());
|
|
27
|
+
return { table, columns };
|
|
28
|
+
}
|
|
29
|
+
// Match UPDATE table SET col1 = ?, col2 = ? ...
|
|
30
|
+
const updateMatch = sqlClean.match(/UPDATE\s+(\w+)\s+SET\s+([\s\S]+?)(?:\s+WHERE|$)/i);
|
|
31
|
+
if (updateMatch) {
|
|
32
|
+
const table = updateMatch[1];
|
|
33
|
+
const setParts = updateMatch[2].split(',');
|
|
34
|
+
const columns = [];
|
|
35
|
+
for (const part of setParts) {
|
|
36
|
+
const match = part.match(/(\w+)\s*=/);
|
|
37
|
+
if (match) {
|
|
38
|
+
columns.push(match[1]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { table, columns };
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
function decryptRow(row, table, keys, options) {
|
|
46
|
+
if (!row)
|
|
47
|
+
return row;
|
|
48
|
+
if (typeof row === 'object') {
|
|
49
|
+
const cloned = Array.isArray(row) ? [...row] : { ...row };
|
|
50
|
+
if (Array.isArray(row)) {
|
|
51
|
+
// Array format (index-based)
|
|
52
|
+
for (let i = 0; i < row.length; i++) {
|
|
53
|
+
const val = row[i];
|
|
54
|
+
if (typeof val === 'string' && val.startsWith('VOLLVALT:')) {
|
|
55
|
+
try {
|
|
56
|
+
cloned[i] = (0, security_js_1.decryptWithSecurity)(val, (v) => (0, prisma_js_1.decryptValue)(v, keys), table, `column_${i}`, undefined, options);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Keep original on failure
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Object format (key-value)
|
|
66
|
+
const fields = options.entities[table] || [];
|
|
67
|
+
for (const [key, val] of Object.entries(row)) {
|
|
68
|
+
if (typeof val === 'string' && val.startsWith('VOLLVALT:')) {
|
|
69
|
+
try {
|
|
70
|
+
cloned[key] = (0, security_js_1.decryptWithSecurity)(val, (v) => (0, prisma_js_1.decryptValue)(v, keys), table, key, row.id || row._id, options);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Keep original on failure
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return cloned;
|
|
79
|
+
}
|
|
80
|
+
return row;
|
|
81
|
+
}
|
|
82
|
+
function wrapSqliteDatabase(db, options) {
|
|
83
|
+
const { keys, activeVersion } = getKeys(options);
|
|
84
|
+
const activeKey = keys[activeVersion];
|
|
85
|
+
(0, security_js_1.registerKeysForZeroization)(keys);
|
|
86
|
+
const originalPrepare = db.prepare;
|
|
87
|
+
db.prepare = function (sql, ...args) {
|
|
88
|
+
const statement = originalPrepare.call(this, sql, ...args);
|
|
89
|
+
const parsed = getParamColumns(sql);
|
|
90
|
+
// Helper to encrypt query input parameters
|
|
91
|
+
const encryptParams = (params) => {
|
|
92
|
+
if (!parsed)
|
|
93
|
+
return params;
|
|
94
|
+
const table = parsed.table;
|
|
95
|
+
const columns = parsed.columns;
|
|
96
|
+
const fieldsToEncrypt = options.entities[table] || [];
|
|
97
|
+
if (fieldsToEncrypt.length === 0)
|
|
98
|
+
return params;
|
|
99
|
+
return params.map((param, index) => {
|
|
100
|
+
const colName = columns[index];
|
|
101
|
+
if (colName && fieldsToEncrypt.includes(colName)) {
|
|
102
|
+
return (0, prisma_js_1.encryptValue)(param, activeKey, activeVersion);
|
|
103
|
+
}
|
|
104
|
+
return param;
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
const wrapStatementMethod = (originalMethod) => {
|
|
108
|
+
return function (...params) {
|
|
109
|
+
const processedParams = encryptParams(params);
|
|
110
|
+
const result = originalMethod.apply(statement, processedParams);
|
|
111
|
+
if (parsed) {
|
|
112
|
+
const table = parsed.table;
|
|
113
|
+
if (Array.isArray(result)) {
|
|
114
|
+
return result.map(row => decryptRow(row, table, keys, options));
|
|
115
|
+
}
|
|
116
|
+
else if (result) {
|
|
117
|
+
return decryptRow(result, table, keys, options);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// If query SQL parsing was skipped (e.g. SELECT *), decrypt rows generically
|
|
122
|
+
// using first table configured in options as fallback
|
|
123
|
+
const defaultTable = Object.keys(options.entities)[0] || 'Model';
|
|
124
|
+
if (Array.isArray(result)) {
|
|
125
|
+
return result.map(row => decryptRow(row, defaultTable, keys, options));
|
|
126
|
+
}
|
|
127
|
+
else if (result) {
|
|
128
|
+
return decryptRow(result, defaultTable, keys, options);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
statement.run = wrapStatementMethod(statement.run);
|
|
135
|
+
statement.get = wrapStatementMethod(statement.get);
|
|
136
|
+
statement.all = wrapStatementMethod(statement.all);
|
|
137
|
+
return statement;
|
|
138
|
+
};
|
|
139
|
+
return db;
|
|
140
|
+
}
|
|
141
|
+
function wrapOracleConnection(connection, options) {
|
|
142
|
+
const { keys, activeVersion } = getKeys(options);
|
|
143
|
+
const activeKey = keys[activeVersion];
|
|
144
|
+
(0, security_js_1.registerKeysForZeroization)(keys);
|
|
145
|
+
const originalExecute = connection.execute;
|
|
146
|
+
connection.execute = async function (sql, bindParams = {}, execOptions = {}, ...args) {
|
|
147
|
+
const parsed = getParamColumns(sql);
|
|
148
|
+
let processedBinds = bindParams;
|
|
149
|
+
if (parsed) {
|
|
150
|
+
const table = parsed.table;
|
|
151
|
+
const columns = parsed.columns;
|
|
152
|
+
const fieldsToEncrypt = options.entities[table] || [];
|
|
153
|
+
if (fieldsToEncrypt.length > 0) {
|
|
154
|
+
if (Array.isArray(bindParams)) {
|
|
155
|
+
processedBinds = bindParams.map((param, index) => {
|
|
156
|
+
const colName = columns[index];
|
|
157
|
+
if (colName && fieldsToEncrypt.includes(colName)) {
|
|
158
|
+
return (0, prisma_js_1.encryptValue)(param, activeKey, activeVersion);
|
|
159
|
+
}
|
|
160
|
+
return param;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
else if (bindParams && typeof bindParams === 'object') {
|
|
164
|
+
processedBinds = { ...bindParams };
|
|
165
|
+
for (const field of fieldsToEncrypt) {
|
|
166
|
+
if (processedBinds[field] !== undefined && processedBinds[field] !== null) {
|
|
167
|
+
processedBinds[field] = (0, prisma_js_1.encryptValue)(processedBinds[field], activeKey, activeVersion);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const result = await originalExecute.call(this, sql, processedBinds, execOptions, ...args);
|
|
174
|
+
if (result && result.rows) {
|
|
175
|
+
const targetTable = parsed ? parsed.table : (Object.keys(options.entities)[0] || 'Model');
|
|
176
|
+
result.rows = result.rows.map((row) => decryptRow(row, targetTable, keys, options));
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
};
|
|
180
|
+
return connection;
|
|
181
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ export { prismaDbGuard, PrismaDbGuardOptions, encryptValue, decryptValue, resolv
|
|
|
2
2
|
export { mongooseDbGuard, MongooseDbGuardOptions } from './mongoose';
|
|
3
3
|
export { createDrizzleGuard } from './drizzle';
|
|
4
4
|
export { createTypeOrmSubscriber } from './typeorm';
|
|
5
|
+
export { wrapSqliteDatabase, wrapOracleConnection, DbGuardDriverOptions } from './drivers';
|
|
5
6
|
export { KmsProvider, AwsKmsProvider, GcpKmsProvider, VaultKmsProvider, unwrapDekLocal, Pkcs11KmsProvider } from './kms';
|
|
6
7
|
export { computeBlindIndex } from './blind-index';
|
|
7
|
-
export { dbGuardContextStore, configureAuditLogger, decryptWithSecurity, checkRateLimit, checkPageSize, resetFailClosedStatusForTesting, resetAuditLoggerForTesting, getCachedKey, setCachedKey, resetSecureKeyCacheForTesting, configureBreakGlass, deactivateBreakGlass, isBreakGlassActive, getBreakGlassKey, activateBreakGlass, parseCiphertext, CRYPTO_ALGORITHMS, VERSION_ALGORITHMS } from './security';
|
|
8
|
+
export { dbGuardContextStore, configureAuditLogger, decryptWithSecurity, checkRateLimit, checkPageSize, resetFailClosedStatusForTesting, resetAuditLoggerForTesting, getCachedKey, setCachedKey, resetSecureKeyCacheForTesting, configureBreakGlass, deactivateBreakGlass, isBreakGlassActive, getBreakGlassKey, activateBreakGlass, parseCiphertext, CRYPTO_ALGORITHMS, VERSION_ALGORITHMS, maskValue } from './security';
|
|
8
9
|
export { auditConfiguration, generateComplianceHtmlReport, ComplianceAuditInput, ComplianceScorecard } from './compliance';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateComplianceHtmlReport = exports.auditConfiguration = exports.VERSION_ALGORITHMS = exports.CRYPTO_ALGORITHMS = exports.parseCiphertext = exports.activateBreakGlass = exports.getBreakGlassKey = exports.isBreakGlassActive = exports.deactivateBreakGlass = exports.configureBreakGlass = exports.resetSecureKeyCacheForTesting = exports.setCachedKey = exports.getCachedKey = exports.resetAuditLoggerForTesting = exports.resetFailClosedStatusForTesting = exports.checkPageSize = exports.checkRateLimit = exports.decryptWithSecurity = exports.configureAuditLogger = exports.dbGuardContextStore = exports.computeBlindIndex = exports.Pkcs11KmsProvider = exports.unwrapDekLocal = exports.VaultKmsProvider = exports.GcpKmsProvider = exports.AwsKmsProvider = exports.createTypeOrmSubscriber = exports.createDrizzleGuard = exports.mongooseDbGuard = exports.resolveKeys = exports.decryptValue = exports.encryptValue = exports.prismaDbGuard = void 0;
|
|
3
|
+
exports.generateComplianceHtmlReport = exports.auditConfiguration = exports.maskValue = exports.VERSION_ALGORITHMS = exports.CRYPTO_ALGORITHMS = exports.parseCiphertext = exports.activateBreakGlass = exports.getBreakGlassKey = exports.isBreakGlassActive = exports.deactivateBreakGlass = exports.configureBreakGlass = exports.resetSecureKeyCacheForTesting = exports.setCachedKey = exports.getCachedKey = exports.resetAuditLoggerForTesting = exports.resetFailClosedStatusForTesting = exports.checkPageSize = exports.checkRateLimit = exports.decryptWithSecurity = exports.configureAuditLogger = exports.dbGuardContextStore = exports.computeBlindIndex = exports.Pkcs11KmsProvider = exports.unwrapDekLocal = exports.VaultKmsProvider = exports.GcpKmsProvider = exports.AwsKmsProvider = exports.wrapOracleConnection = exports.wrapSqliteDatabase = exports.createTypeOrmSubscriber = exports.createDrizzleGuard = exports.mongooseDbGuard = exports.resolveKeys = exports.decryptValue = exports.encryptValue = exports.prismaDbGuard = void 0;
|
|
4
4
|
var prisma_1 = require("./prisma");
|
|
5
5
|
Object.defineProperty(exports, "prismaDbGuard", { enumerable: true, get: function () { return prisma_1.prismaDbGuard; } });
|
|
6
6
|
Object.defineProperty(exports, "encryptValue", { enumerable: true, get: function () { return prisma_1.encryptValue; } });
|
|
@@ -12,6 +12,9 @@ var drizzle_1 = require("./drizzle");
|
|
|
12
12
|
Object.defineProperty(exports, "createDrizzleGuard", { enumerable: true, get: function () { return drizzle_1.createDrizzleGuard; } });
|
|
13
13
|
var typeorm_1 = require("./typeorm");
|
|
14
14
|
Object.defineProperty(exports, "createTypeOrmSubscriber", { enumerable: true, get: function () { return typeorm_1.createTypeOrmSubscriber; } });
|
|
15
|
+
var drivers_1 = require("./drivers");
|
|
16
|
+
Object.defineProperty(exports, "wrapSqliteDatabase", { enumerable: true, get: function () { return drivers_1.wrapSqliteDatabase; } });
|
|
17
|
+
Object.defineProperty(exports, "wrapOracleConnection", { enumerable: true, get: function () { return drivers_1.wrapOracleConnection; } });
|
|
15
18
|
var kms_1 = require("./kms");
|
|
16
19
|
Object.defineProperty(exports, "AwsKmsProvider", { enumerable: true, get: function () { return kms_1.AwsKmsProvider; } });
|
|
17
20
|
Object.defineProperty(exports, "GcpKmsProvider", { enumerable: true, get: function () { return kms_1.GcpKmsProvider; } });
|
|
@@ -39,6 +42,7 @@ Object.defineProperty(exports, "activateBreakGlass", { enumerable: true, get: fu
|
|
|
39
42
|
Object.defineProperty(exports, "parseCiphertext", { enumerable: true, get: function () { return security_1.parseCiphertext; } });
|
|
40
43
|
Object.defineProperty(exports, "CRYPTO_ALGORITHMS", { enumerable: true, get: function () { return security_1.CRYPTO_ALGORITHMS; } });
|
|
41
44
|
Object.defineProperty(exports, "VERSION_ALGORITHMS", { enumerable: true, get: function () { return security_1.VERSION_ALGORITHMS; } });
|
|
45
|
+
Object.defineProperty(exports, "maskValue", { enumerable: true, get: function () { return security_1.maskValue; } });
|
|
42
46
|
var compliance_1 = require("./compliance");
|
|
43
47
|
Object.defineProperty(exports, "auditConfiguration", { enumerable: true, get: function () { return compliance_1.auditConfiguration; } });
|
|
44
48
|
Object.defineProperty(exports, "generateComplianceHtmlReport", { enumerable: true, get: function () { return compliance_1.generateComplianceHtmlReport; } });
|
package/dist/provenance.json
CHANGED
|
@@ -37,6 +37,18 @@
|
|
|
37
37
|
"sha256": "0b660e3eafcc27a78d5c97c7d34837a25c68295660a3d1c7da0ae8e0a676bfb6"
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
"name": "dist/drivers.d.ts",
|
|
42
|
+
"digest": {
|
|
43
|
+
"sha256": "1363416c7c4ce5549331a13c43f89c8cba2865b26cac8e699b4504c48c29b049"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "dist/drivers.js",
|
|
48
|
+
"digest": {
|
|
49
|
+
"sha256": "44623a5cf632c22a41b8196b809a3c00d50276bde28c2fbde13d6f4bef3177ce"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
40
52
|
{
|
|
41
53
|
"name": "dist/drizzle.d.ts",
|
|
42
54
|
"digest": {
|
|
@@ -52,13 +64,13 @@
|
|
|
52
64
|
{
|
|
53
65
|
"name": "dist/index.d.ts",
|
|
54
66
|
"digest": {
|
|
55
|
-
"sha256": "
|
|
67
|
+
"sha256": "a4864c4ea0bb9e9cc9bc1f58cdbc31863e5543a572e6049ee900b53b9fecb003"
|
|
56
68
|
}
|
|
57
69
|
},
|
|
58
70
|
{
|
|
59
71
|
"name": "dist/index.js",
|
|
60
72
|
"digest": {
|
|
61
|
-
"sha256": "
|
|
73
|
+
"sha256": "496292f1edd16bd779f6e8712291c4b90e5b3f404d71b54f5c369c6736c26814"
|
|
62
74
|
}
|
|
63
75
|
},
|
|
64
76
|
{
|
|
@@ -100,13 +112,13 @@
|
|
|
100
112
|
{
|
|
101
113
|
"name": "dist/security.d.ts",
|
|
102
114
|
"digest": {
|
|
103
|
-
"sha256": "
|
|
115
|
+
"sha256": "554d9ba00f800470666ab66127079df889b8d717a9cf7b28ab252f0adad64304"
|
|
104
116
|
}
|
|
105
117
|
},
|
|
106
118
|
{
|
|
107
119
|
"name": "dist/security.js",
|
|
108
120
|
"digest": {
|
|
109
|
-
"sha256": "
|
|
121
|
+
"sha256": "5e907c9f5ec9fb93ef07f6360d7f8572aa5a1ea1c0a32d0b10496477d0b8fd33"
|
|
110
122
|
}
|
|
111
123
|
},
|
|
112
124
|
{
|
|
@@ -129,7 +141,7 @@
|
|
|
129
141
|
"externalParameters": {
|
|
130
142
|
"packageJson": {
|
|
131
143
|
"name": "@vollcrypt/db-guard",
|
|
132
|
-
"version": "0.1.
|
|
144
|
+
"version": "0.1.2",
|
|
133
145
|
"scripts": {
|
|
134
146
|
"build": "tsc && node scripts/generate-sbom.js",
|
|
135
147
|
"test": "node --import tsx --test tests/*.test.ts"
|
|
@@ -213,9 +225,9 @@
|
|
|
213
225
|
"id": "https://vollcrypt.dev/builders/local-hermetic-env"
|
|
214
226
|
},
|
|
215
227
|
"metadata": {
|
|
216
|
-
"invocationId": "
|
|
217
|
-
"startedOn": "2026-06-
|
|
218
|
-
"finishedOn": "2026-06-
|
|
228
|
+
"invocationId": "19095e456ee2a685d43df5cc56999080",
|
|
229
|
+
"startedOn": "2026-06-11T16:17:36.609Z",
|
|
230
|
+
"finishedOn": "2026-06-11T16:17:36.610Z"
|
|
219
231
|
}
|
|
220
232
|
}
|
|
221
233
|
}
|
package/dist/provenance.json.sig
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
�
|
|
1
|
+
?NENc0�HӰ�@�S�t��J�ɽ<(:3�8O �7X�q-du�Y�^~՚�8�z� Dž�
|
package/dist/sbom.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.5",
|
|
4
|
-
"serialNumber": "urn:uuid:
|
|
4
|
+
"serialNumber": "urn:uuid:45a7c8f7-12f3-4e25-ab52-81be917b4646",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "2026-06-
|
|
7
|
+
"timestamp": "2026-06-11T16:17:36.609Z",
|
|
8
8
|
"tools": [
|
|
9
9
|
{
|
|
10
10
|
"vendor": "Vollcrypt",
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"component": {
|
|
16
|
-
"bomRef": "pkg:npm/@vollcrypt/db-guard@0.1.
|
|
16
|
+
"bomRef": "pkg:npm/@vollcrypt/db-guard@0.1.2",
|
|
17
17
|
"type": "library",
|
|
18
18
|
"name": "@vollcrypt/db-guard",
|
|
19
|
-
"version": "0.1.
|
|
19
|
+
"version": "0.1.2",
|
|
20
20
|
"description": "Database field-level encryption integrations for Vollcrypt (Prisma, Mongoose, Drizzle, TypeORM)",
|
|
21
21
|
"hashes": [
|
|
22
22
|
{
|
|
@@ -43,6 +43,14 @@
|
|
|
43
43
|
"alg": "SHA-256",
|
|
44
44
|
"content": "0b660e3eafcc27a78d5c97c7d34837a25c68295660a3d1c7da0ae8e0a676bfb6"
|
|
45
45
|
},
|
|
46
|
+
{
|
|
47
|
+
"alg": "SHA-256",
|
|
48
|
+
"content": "1363416c7c4ce5549331a13c43f89c8cba2865b26cac8e699b4504c48c29b049"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"alg": "SHA-256",
|
|
52
|
+
"content": "44623a5cf632c22a41b8196b809a3c00d50276bde28c2fbde13d6f4bef3177ce"
|
|
53
|
+
},
|
|
46
54
|
{
|
|
47
55
|
"alg": "SHA-256",
|
|
48
56
|
"content": "cb43fec66c7da1e84b96a97e8a18b0d08606535c64236f66ff950250d0f23292"
|
|
@@ -53,11 +61,11 @@
|
|
|
53
61
|
},
|
|
54
62
|
{
|
|
55
63
|
"alg": "SHA-256",
|
|
56
|
-
"content": "
|
|
64
|
+
"content": "a4864c4ea0bb9e9cc9bc1f58cdbc31863e5543a572e6049ee900b53b9fecb003"
|
|
57
65
|
},
|
|
58
66
|
{
|
|
59
67
|
"alg": "SHA-256",
|
|
60
|
-
"content": "
|
|
68
|
+
"content": "496292f1edd16bd779f6e8712291c4b90e5b3f404d71b54f5c369c6736c26814"
|
|
61
69
|
},
|
|
62
70
|
{
|
|
63
71
|
"alg": "SHA-256",
|
|
@@ -85,11 +93,11 @@
|
|
|
85
93
|
},
|
|
86
94
|
{
|
|
87
95
|
"alg": "SHA-256",
|
|
88
|
-
"content": "
|
|
96
|
+
"content": "554d9ba00f800470666ab66127079df889b8d717a9cf7b28ab252f0adad64304"
|
|
89
97
|
},
|
|
90
98
|
{
|
|
91
99
|
"alg": "SHA-256",
|
|
92
|
-
"content": "
|
|
100
|
+
"content": "5e907c9f5ec9fb93ef07f6360d7f8572aa5a1ea1c0a32d0b10496477d0b8fd33"
|
|
93
101
|
},
|
|
94
102
|
{
|
|
95
103
|
"alg": "SHA-256",
|
package/dist/sbom.json.sig
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
��7gu
|
|
2
|
+
�
|
package/dist/security.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export interface UserContext {
|
|
|
19
19
|
maxPageSize?: number;
|
|
20
20
|
onPageSizeExceeded?: 'warn' | 'error' | 'bypass';
|
|
21
21
|
tenantId?: string;
|
|
22
|
+
decryptCount?: number;
|
|
23
|
+
windowStart?: number;
|
|
22
24
|
}
|
|
23
25
|
export declare const dbGuardContextStore: AsyncLocalStorage<UserContext>;
|
|
24
26
|
export declare function maskValue(val: any, rule: 'credit_card' | 'email' | 'tc_no' | ((v: any) => any) | string): any;
|
package/dist/security.js
CHANGED
|
@@ -370,17 +370,38 @@ function checkRateLimit(options) {
|
|
|
370
370
|
const limit = context?.maxDecryptionsPerSecond || options?.maxDecryptionsPerSecond || 500;
|
|
371
371
|
const mode = context?.rateLimiterMode || options?.mode || 'fail_closed';
|
|
372
372
|
const now = Date.now();
|
|
373
|
-
if (
|
|
374
|
-
decryptCount
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
decryptCount++;
|
|
378
|
-
if (decryptCount > limit) {
|
|
379
|
-
if (mode === 'fail_closed') {
|
|
380
|
-
triggerFailClosed(options?.onFailClosed);
|
|
373
|
+
if (context) {
|
|
374
|
+
if (context.windowStart === undefined || context.decryptCount === undefined) {
|
|
375
|
+
context.windowStart = now;
|
|
376
|
+
context.decryptCount = 0;
|
|
381
377
|
}
|
|
382
|
-
|
|
383
|
-
|
|
378
|
+
if (now - context.windowStart > 1000) {
|
|
379
|
+
context.decryptCount = 0;
|
|
380
|
+
context.windowStart = now;
|
|
381
|
+
}
|
|
382
|
+
context.decryptCount++;
|
|
383
|
+
if (context.decryptCount > limit) {
|
|
384
|
+
if (mode === 'fail_closed') {
|
|
385
|
+
triggerFailClosed(options?.onFailClosed);
|
|
386
|
+
}
|
|
387
|
+
else if (mode === 'warn') {
|
|
388
|
+
console.warn(`Vollcrypt Warning: Decryption rate limit exceeded. ${context.decryptCount} decryptions in the current window (limit: ${limit}).`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
if (now - windowStart > 1000) {
|
|
394
|
+
decryptCount = 0;
|
|
395
|
+
windowStart = now;
|
|
396
|
+
}
|
|
397
|
+
decryptCount++;
|
|
398
|
+
if (decryptCount > limit) {
|
|
399
|
+
if (mode === 'fail_closed') {
|
|
400
|
+
triggerFailClosed(options?.onFailClosed);
|
|
401
|
+
}
|
|
402
|
+
else if (mode === 'warn') {
|
|
403
|
+
console.warn(`Vollcrypt Warning: Decryption rate limit exceeded. ${decryptCount} decryptions in the current window (limit: ${limit}).`);
|
|
404
|
+
}
|
|
384
405
|
}
|
|
385
406
|
}
|
|
386
407
|
}
|
package/package.json
CHANGED