@proteinjs/db 1.35.0 → 1.36.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.
- package/CHANGELOG.md +22 -0
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +7 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/test/index.d.ts.map +1 -1
- package/dist/generated/test/index.js +7 -1
- package/dist/generated/test/index.js.map +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/src/Db.d.ts +25 -0
- package/dist/src/Db.d.ts.map +1 -1
- package/dist/src/Db.js +219 -22
- package/dist/src/Db.js.map +1 -1
- package/dist/src/Record.d.ts +7 -1
- package/dist/src/Record.d.ts.map +1 -1
- package/dist/src/Record.js +56 -21
- package/dist/src/Record.js.map +1 -1
- package/dist/src/Table.d.ts +82 -1
- package/dist/src/Table.d.ts.map +1 -1
- package/dist/src/Table.js +24 -1
- package/dist/src/Table.js.map +1 -1
- package/dist/src/TableQueryTransformProvider.d.ts +17 -0
- package/dist/src/TableQueryTransformProvider.d.ts.map +1 -0
- package/dist/src/TableQueryTransformProvider.js +34 -0
- package/dist/src/TableQueryTransformProvider.js.map +1 -0
- package/dist/src/encryption/Base64Url.d.ts +12 -0
- package/dist/src/encryption/Base64Url.d.ts.map +1 -0
- package/dist/src/encryption/Base64Url.js +21 -0
- package/dist/src/encryption/Base64Url.js.map +1 -0
- package/dist/src/encryption/DataEncryptionKeyTable.d.ts +33 -0
- package/dist/src/encryption/DataEncryptionKeyTable.d.ts.map +1 -0
- package/dist/src/encryption/DataEncryptionKeyTable.js +45 -0
- package/dist/src/encryption/DataEncryptionKeyTable.js.map +1 -0
- package/dist/src/encryption/DataKeyStore.d.ts +84 -0
- package/dist/src/encryption/DataKeyStore.d.ts.map +1 -0
- package/dist/src/encryption/DataKeyStore.js +481 -0
- package/dist/src/encryption/DataKeyStore.js.map +1 -0
- package/dist/src/encryption/DbEncryptionConfig.d.ts +62 -0
- package/dist/src/encryption/DbEncryptionConfig.d.ts.map +1 -0
- package/dist/src/encryption/DbEncryptionConfig.js +67 -0
- package/dist/src/encryption/DbEncryptionConfig.js.map +1 -0
- package/dist/src/encryption/EncryptedColumnQueryError.d.ts +10 -0
- package/dist/src/encryption/EncryptedColumnQueryError.d.ts.map +1 -0
- package/dist/src/encryption/EncryptedColumnQueryError.js +38 -0
- package/dist/src/encryption/EncryptedColumnQueryError.js.map +1 -0
- package/dist/src/encryption/EncryptedColumnQueryTransform.d.ts +52 -0
- package/dist/src/encryption/EncryptedColumnQueryTransform.d.ts.map +1 -0
- package/dist/src/encryption/EncryptedColumnQueryTransform.js +423 -0
- package/dist/src/encryption/EncryptedColumnQueryTransform.js.map +1 -0
- package/dist/src/encryption/EncryptedColumns.d.ts +69 -0
- package/dist/src/encryption/EncryptedColumns.d.ts.map +1 -0
- package/dist/src/encryption/EncryptedColumns.js +286 -0
- package/dist/src/encryption/EncryptedColumns.js.map +1 -0
- package/dist/src/encryption/EncryptionDerivedTableRegistry.d.ts +20 -0
- package/dist/src/encryption/EncryptionDerivedTableRegistry.d.ts.map +1 -0
- package/dist/src/encryption/EncryptionDerivedTableRegistry.js +36 -0
- package/dist/src/encryption/EncryptionDerivedTableRegistry.js.map +1 -0
- package/dist/src/encryption/EncryptionEnvelope.d.ts +25 -0
- package/dist/src/encryption/EncryptionEnvelope.d.ts.map +1 -0
- package/dist/src/encryption/EncryptionEnvelope.js +59 -0
- package/dist/src/encryption/EncryptionEnvelope.js.map +1 -0
- package/dist/src/encryption/EncryptionLifecycleWalker.d.ts +65 -0
- package/dist/src/encryption/EncryptionLifecycleWalker.d.ts.map +1 -0
- package/dist/src/encryption/EncryptionLifecycleWalker.js +343 -0
- package/dist/src/encryption/EncryptionLifecycleWalker.js.map +1 -0
- package/dist/src/encryption/EncryptionRecordHooks.d.ts +47 -0
- package/dist/src/encryption/EncryptionRecordHooks.d.ts.map +1 -0
- package/dist/src/encryption/EncryptionRecordHooks.js +229 -0
- package/dist/src/encryption/EncryptionRecordHooks.js.map +1 -0
- package/dist/src/encryption/EncryptionTokenMaintenance.d.ts +34 -0
- package/dist/src/encryption/EncryptionTokenMaintenance.d.ts.map +1 -0
- package/dist/src/encryption/EncryptionTokenMaintenance.js +211 -0
- package/dist/src/encryption/EncryptionTokenMaintenance.js.map +1 -0
- package/dist/src/encryption/InMemoryMasterKeyProvider.d.ts +20 -0
- package/dist/src/encryption/InMemoryMasterKeyProvider.d.ts.map +1 -0
- package/dist/src/encryption/InMemoryMasterKeyProvider.js +87 -0
- package/dist/src/encryption/InMemoryMasterKeyProvider.js.map +1 -0
- package/dist/src/encryption/MasterKeyProvider.d.ts +27 -0
- package/dist/src/encryption/MasterKeyProvider.d.ts.map +1 -0
- package/dist/src/encryption/MasterKeyProvider.js +3 -0
- package/dist/src/encryption/MasterKeyProvider.js.map +1 -0
- package/dist/src/encryption/SearchTokenizer.d.ts +49 -0
- package/dist/src/encryption/SearchTokenizer.d.ts.map +1 -0
- package/dist/src/encryption/SearchTokenizer.js +106 -0
- package/dist/src/encryption/SearchTokenizer.js.map +1 -0
- package/dist/src/schema/TableManager.d.ts +10 -0
- package/dist/src/schema/TableManager.d.ts.map +1 -1
- package/dist/src/schema/TableManager.js +62 -5
- package/dist/src/schema/TableManager.js.map +1 -1
- package/dist/src/tables/MigrationTable.d.ts +2 -2
- package/dist/test/EncryptedColumnsSchema.test.d.ts +2 -0
- package/dist/test/EncryptedColumnsSchema.test.d.ts.map +1 -0
- package/dist/test/EncryptedColumnsSchema.test.js +151 -0
- package/dist/test/EncryptedColumnsSchema.test.js.map +1 -0
- package/dist/test/EncryptionEnvelope.test.d.ts +2 -0
- package/dist/test/EncryptionEnvelope.test.d.ts.map +1 -0
- package/dist/test/EncryptionEnvelope.test.js +109 -0
- package/dist/test/EncryptionEnvelope.test.js.map +1 -0
- package/dist/test/EncryptionQueryContract.test.d.ts +2 -0
- package/dist/test/EncryptionQueryContract.test.d.ts.map +1 -0
- package/dist/test/EncryptionQueryContract.test.js +399 -0
- package/dist/test/EncryptionQueryContract.test.js.map +1 -0
- package/dist/test/SearchTokenizer.test.d.ts +2 -0
- package/dist/test/SearchTokenizer.test.d.ts.map +1 -0
- package/dist/test/SearchTokenizer.test.js +64 -0
- package/dist/test/SearchTokenizer.test.js.map +1 -0
- package/dist/test/reusable/CascadeDeleteTests.js +2 -2
- package/dist/test/reusable/CascadeDeleteTests.js.map +1 -1
- package/dist/test/reusable/ColumnTypesTests.js +2 -2
- package/dist/test/reusable/ColumnTypesTests.js.map +1 -1
- package/dist/test/reusable/CrudTests.js +2 -2
- package/dist/test/reusable/CrudTests.js.map +1 -1
- package/dist/test/reusable/DynamicReferenceColumnTests.js +2 -2
- package/dist/test/reusable/DynamicReferenceColumnTests.js.map +1 -1
- package/dist/test/reusable/PreloadReferencesTests.js +2 -2
- package/dist/test/reusable/PreloadReferencesTests.js.map +1 -1
- package/dist/test/reusable/RecordIteratorTests.js +2 -2
- package/dist/test/reusable/RecordIteratorTests.js.map +1 -1
- package/dist/test/reusable/TableManagerTests.js +2 -2
- package/dist/test/reusable/TableManagerTests.js.map +1 -1
- package/dist/test/reusable/TransactionTests.js +2 -2
- package/dist/test/reusable/TransactionTests.js.map +1 -1
- package/generated/index.ts +7 -1
- package/generated/test/index.ts +7 -1
- package/index.ts +16 -0
- package/package.json +3 -3
- package/src/Db.ts +137 -12
- package/src/Record.ts +21 -4
- package/src/Table.ts +109 -2
- package/src/TableQueryTransformProvider.ts +31 -0
- package/src/encryption/Base64Url.ts +14 -0
- package/src/encryption/DataEncryptionKeyTable.ts +40 -0
- package/src/encryption/DataKeyStore.ts +305 -0
- package/src/encryption/DbEncryptionConfig.ts +92 -0
- package/src/encryption/EncryptedColumnQueryError.ts +15 -0
- package/src/encryption/EncryptedColumnQueryTransform.ts +383 -0
- package/src/encryption/EncryptedColumns.ts +318 -0
- package/src/encryption/EncryptionDerivedTableRegistry.ts +34 -0
- package/src/encryption/EncryptionEnvelope.ts +60 -0
- package/src/encryption/EncryptionLifecycleWalker.ts +243 -0
- package/src/encryption/EncryptionRecordHooks.ts +167 -0
- package/src/encryption/EncryptionTokenMaintenance.ts +123 -0
- package/src/encryption/InMemoryMasterKeyProvider.ts +42 -0
- package/src/encryption/MasterKeyProvider.ts +26 -0
- package/src/encryption/SearchTokenizer.ts +103 -0
- package/src/schema/TableManager.ts +43 -1
- package/test/EncryptedColumnsSchema.test.ts +172 -0
- package/test/EncryptionEnvelope.test.ts +66 -0
- package/test/EncryptionQueryContract.test.ts +195 -0
- package/test/SearchTokenizer.test.ts +67 -0
- package/test/reusable/CascadeDeleteTests.ts +2 -2
- package/test/reusable/ColumnTypesTests.ts +2 -2
- package/test/reusable/CrudTests.ts +2 -2
- package/test/reusable/DynamicReferenceColumnTests.ts +2 -2
- package/test/reusable/PreloadReferencesTests.ts +2 -2
- package/test/reusable/RecordIteratorTests.ts +2 -2
- package/test/reusable/TableManagerTests.ts +2 -2
- package/test/reusable/TransactionTests.ts +2 -2
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __assign = (this && this.__assign) || function () {
|
|
18
|
+
__assign = Object.assign || function(t) {
|
|
19
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
+
s = arguments[i];
|
|
21
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
+
t[p] = s[p];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
return __assign.apply(this, arguments);
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.EncryptedColumns = void 0;
|
|
30
|
+
var util_1 = require("@proteinjs/util");
|
|
31
|
+
var Table_1 = require("../Table");
|
|
32
|
+
var Record_1 = require("../Record");
|
|
33
|
+
var Columns_1 = require("../Columns");
|
|
34
|
+
var DbEncryptionConfig_1 = require("./DbEncryptionConfig");
|
|
35
|
+
var EncryptionDerivedTableRegistry_1 = require("./EncryptionDerivedTableRegistry");
|
|
36
|
+
/**
|
|
37
|
+
* The schema side of column encryption (`ColumnOptions.encrypted`): validation of the
|
|
38
|
+
* declaration, and derivation of the physical schema an encrypted column needs —
|
|
39
|
+
* automatically, at the framework seam, never by callers:
|
|
40
|
+
*
|
|
41
|
+
* - the ciphertext column itself widens to STRING(MAX) (envelopes outgrow declared widths);
|
|
42
|
+
* - `searchable: 'equality'` derives an indexed whole-value fingerprint companion column
|
|
43
|
+
* (`<column>_enc_eq`); a `unique` declaration on the base column moves onto it (per-owner
|
|
44
|
+
* value uniqueness — fingerprints are keyed per owner);
|
|
45
|
+
* - `searchable: 'contains'` derives a companion search-token TABLE (`<table>_enc_tok`) —
|
|
46
|
+
* a plain indexed inverted index, portable across drivers (Spanner's native search
|
|
47
|
+
* indexes are a named later optimization at the driver layer);
|
|
48
|
+
* - `sortKey: { revealPrefix: N }` derives an ordered-prefix companion column
|
|
49
|
+
* (`<column>_enc_srt`) for native ORDER BY — the declared bounded reveal.
|
|
50
|
+
*
|
|
51
|
+
* `ensureSchema` is idempotent and runs wherever the physical schema is consulted
|
|
52
|
+
* (TableManager, the record serializer, the query translator).
|
|
53
|
+
*/
|
|
54
|
+
var EncryptedColumns = /** @class */ (function () {
|
|
55
|
+
function EncryptedColumns() {
|
|
56
|
+
}
|
|
57
|
+
/** Validate declarations and inject the derived physical schema (idempotent). */
|
|
58
|
+
EncryptedColumns.prototype.ensureSchema = function (table) {
|
|
59
|
+
if (table[EncryptedColumns.SCHEMA_APPLIED_MARKER]) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
var hasContainsColumns = false;
|
|
63
|
+
var _loop_1 = function (prop) {
|
|
64
|
+
var column = table.columns[prop];
|
|
65
|
+
var config = this_1.validateDeclaration(table, prop, column);
|
|
66
|
+
if (!config) {
|
|
67
|
+
return "continue";
|
|
68
|
+
}
|
|
69
|
+
if (typeof column.maxLength !== 'undefined') {
|
|
70
|
+
// Envelopes outgrow the declared plaintext width; the physical column is MAX.
|
|
71
|
+
column.maxLength = 'MAX';
|
|
72
|
+
}
|
|
73
|
+
if (config.searchable === 'equality') {
|
|
74
|
+
this_1.injectEqualityCompanion(table, prop, column);
|
|
75
|
+
}
|
|
76
|
+
if (config.searchable === 'contains') {
|
|
77
|
+
hasContainsColumns = true;
|
|
78
|
+
}
|
|
79
|
+
if (config.sortKey) {
|
|
80
|
+
this_1.injectSortCompanion(table, prop, column, config.sortKey.revealPrefix);
|
|
81
|
+
}
|
|
82
|
+
// The column's QUERY-side contract (`Column.queryTransform` — the parallel of the
|
|
83
|
+
// storage-side serialize/deserialize seam), DERIVED from the declaration at this
|
|
84
|
+
// framework seam, never caller-declared. `QueryBuilder.applyColumnTransforms`
|
|
85
|
+
// consults it on every query. Call-time require: the transform pulls the key-store
|
|
86
|
+
// stack, which sits beside Db in the module graph.
|
|
87
|
+
column.queryTransform = function (runtime) {
|
|
88
|
+
var EncryptedColumnQueryTransform =
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
90
|
+
require('./EncryptedColumnQueryTransform').EncryptedColumnQueryTransform;
|
|
91
|
+
return new EncryptedColumnQueryTransform(table, prop, column, config, runtime);
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
var this_1 = this;
|
|
95
|
+
for (var _i = 0, _a = Object.keys(table.columns); _i < _a.length; _i++) {
|
|
96
|
+
var prop = _a[_i];
|
|
97
|
+
_loop_1(prop);
|
|
98
|
+
}
|
|
99
|
+
if (hasContainsColumns) {
|
|
100
|
+
EncryptionDerivedTableRegistry_1.EncryptionDerivedTableRegistry.register(this.tokenTableShape(table));
|
|
101
|
+
}
|
|
102
|
+
// Marked only after full success: a validation throw above must re-validate (and
|
|
103
|
+
// re-throw, loudly) on every subsequent use, never half-apply.
|
|
104
|
+
table[EncryptedColumns.SCHEMA_APPLIED_MARKER] = true;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* The mandatory-declaration gate (`DbEncryptionConfig.requireEncryptedDeclarations`):
|
|
108
|
+
* every text-holding column must declare `encrypted` (`false` or a config object), so no
|
|
109
|
+
* column can be added without deciding, and the encrypted set can never silently drift.
|
|
110
|
+
* Identifier-bearing column classes (uuids, references) are metadata by construction and
|
|
111
|
+
* are exempt.
|
|
112
|
+
*/
|
|
113
|
+
EncryptedColumns.prototype.validateDeclarations = function (table) {
|
|
114
|
+
var _a;
|
|
115
|
+
var undeclared = [];
|
|
116
|
+
for (var _i = 0, _b = Object.keys(table.columns); _i < _b.length; _i++) {
|
|
117
|
+
var prop = _b[_i];
|
|
118
|
+
var column = table.columns[prop];
|
|
119
|
+
if (!this.isTextColumn(column) || this.isInternalColumn(column)) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (typeof ((_a = column.options) === null || _a === void 0 ? void 0 : _a.encrypted) === 'undefined') {
|
|
123
|
+
undeclared.push("".concat(prop, " ('").concat(column.name, "')"));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (undeclared.length > 0) {
|
|
127
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ") Every text-holding column must declare 'encrypted' (false, or a config ") +
|
|
128
|
+
"object such as {} or { searchable: 'contains' }). Missing declarations: ".concat(undeclared.join(', ')));
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
/** The `encrypted` config object for a column property, or undefined when not encrypted. */
|
|
132
|
+
EncryptedColumns.prototype.configFor = function (table, prop) {
|
|
133
|
+
var _a;
|
|
134
|
+
var column = table.columns[prop];
|
|
135
|
+
var encrypted = (_a = column === null || column === void 0 ? void 0 : column.options) === null || _a === void 0 ? void 0 : _a.encrypted;
|
|
136
|
+
return encrypted && typeof encrypted === 'object' ? encrypted : undefined;
|
|
137
|
+
};
|
|
138
|
+
/** Property names of this table's encrypted columns. */
|
|
139
|
+
EncryptedColumns.prototype.encryptedProps = function (table) {
|
|
140
|
+
var _this = this;
|
|
141
|
+
return Object.keys(table.columns).filter(function (prop) { return !!_this.configFor(table, prop); });
|
|
142
|
+
};
|
|
143
|
+
/** Property names declared `searchable: 'contains'`. */
|
|
144
|
+
EncryptedColumns.prototype.containsProps = function (table) {
|
|
145
|
+
var _this = this;
|
|
146
|
+
return this.encryptedProps(table).filter(function (prop) { return _this.configFor(table, prop).searchable === 'contains'; });
|
|
147
|
+
};
|
|
148
|
+
/** Does this write payload touch any encrypted column? */
|
|
149
|
+
EncryptedColumns.prototype.recordTouchesEncryptedColumns = function (table, record) {
|
|
150
|
+
return this.encryptedProps(table).some(function (prop) { return typeof record[prop] !== 'undefined'; });
|
|
151
|
+
};
|
|
152
|
+
EncryptedColumns.prototype.hasEncryptedColumns = function (table) {
|
|
153
|
+
return this.encryptedProps(table).length > 0;
|
|
154
|
+
};
|
|
155
|
+
/** The derived search-token table for `table`, or undefined when nothing is `contains`-searchable. */
|
|
156
|
+
EncryptedColumns.prototype.tokenTableFor = function (table) {
|
|
157
|
+
this.ensureSchema(table);
|
|
158
|
+
return EncryptionDerivedTableRegistry_1.EncryptionDerivedTableRegistry.get(this.tokenTableName(table));
|
|
159
|
+
};
|
|
160
|
+
EncryptedColumns.prototype.tokenTableName = function (table) {
|
|
161
|
+
return "".concat(table.name, "_enc_tok");
|
|
162
|
+
};
|
|
163
|
+
/** Companion property names EQUAL their column names (several seams assume prop == name). */
|
|
164
|
+
EncryptedColumns.prototype.eqCompanionProp = function (table, prop) {
|
|
165
|
+
return "".concat(table.columns[prop].name, "_enc_eq");
|
|
166
|
+
};
|
|
167
|
+
EncryptedColumns.prototype.sortCompanionProp = function (table, prop) {
|
|
168
|
+
return "".concat(table.columns[prop].name, "_enc_srt");
|
|
169
|
+
};
|
|
170
|
+
/** Framework-derived companion columns are dropped from deserialized records and exempt from declaration checks. */
|
|
171
|
+
EncryptedColumns.prototype.isInternalColumn = function (column) {
|
|
172
|
+
return !!column[EncryptedColumns.INTERNAL_COLUMN_MARKER];
|
|
173
|
+
};
|
|
174
|
+
EncryptedColumns.prototype.validateDeclaration = function (table, prop, column) {
|
|
175
|
+
var _a, _b, _c;
|
|
176
|
+
var encrypted = (_a = column.options) === null || _a === void 0 ? void 0 : _a.encrypted;
|
|
177
|
+
if (typeof encrypted === 'undefined' || encrypted === false) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
if (typeof encrypted !== 'object') {
|
|
181
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ".").concat(prop, ") 'encrypted' must be false or a config object ") +
|
|
182
|
+
"(e.g. {}, { searchable: 'contains' }); got: ".concat(JSON.stringify(encrypted)));
|
|
183
|
+
}
|
|
184
|
+
if (!this.isTextColumn(column)) {
|
|
185
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ".").concat(prop, ") 'encrypted' is only supported on text columns (StringColumn family). ") +
|
|
186
|
+
"Identifier and reference columns are metadata by construction; JSON-typed columns must use a " +
|
|
187
|
+
"string-serialized column type to encrypt.");
|
|
188
|
+
}
|
|
189
|
+
if (encrypted.searchable && encrypted.searchable !== 'contains' && encrypted.searchable !== 'equality') {
|
|
190
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ".").concat(prop, ") encrypted.searchable must be 'contains' or 'equality'; ") +
|
|
191
|
+
"got: ".concat(JSON.stringify(encrypted.searchable)));
|
|
192
|
+
}
|
|
193
|
+
if ((encrypted.searchable || encrypted.sortKey) && (0, util_1.isInstanceOf)(column, Columns_1.ObjectColumn)) {
|
|
194
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ".").concat(prop, ") encrypted.searchable / encrypted.sortKey require a plain string column ") +
|
|
195
|
+
"(the search and sort derivatives cover the value's text, not its serialization). " +
|
|
196
|
+
"Object/array columns may declare encrypted: {} (encrypted, never queried by value).");
|
|
197
|
+
}
|
|
198
|
+
if (encrypted.sortKey) {
|
|
199
|
+
var revealPrefix = encrypted.sortKey.revealPrefix;
|
|
200
|
+
if (!Number.isInteger(revealPrefix) || revealPrefix < 1) {
|
|
201
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ".").concat(prop, ") encrypted.sortKey.revealPrefix must be a positive integer ") +
|
|
202
|
+
"(the number of leading characters whose order the sort column reveals); " +
|
|
203
|
+
"got: ".concat(JSON.stringify(revealPrefix)));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (((_c = (_b = column.options) === null || _b === void 0 ? void 0 : _b.unique) === null || _c === void 0 ? void 0 : _c.unique) && encrypted.searchable !== 'equality') {
|
|
207
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ".").concat(prop, ") a unique constraint on an encrypted column requires ") +
|
|
208
|
+
"encrypted: { searchable: 'equality' } \u2014 uniqueness is enforced through a unique index on " +
|
|
209
|
+
"the whole-value fingerprint (ciphertext is never equal, so a unique index on it cannot bite).");
|
|
210
|
+
}
|
|
211
|
+
return encrypted;
|
|
212
|
+
};
|
|
213
|
+
EncryptedColumns.prototype.injectEqualityCompanion = function (table, prop, column) {
|
|
214
|
+
var _a, _b;
|
|
215
|
+
var companionProp = "".concat(column.name, "_enc_eq");
|
|
216
|
+
var baseUnique = ((_b = (_a = column.options) === null || _a === void 0 ? void 0 : _a.unique) === null || _b === void 0 ? void 0 : _b.unique) === true;
|
|
217
|
+
var companion = new Columns_1.StringColumn("".concat(column.name, "_enc_eq"), __assign(__assign({ nullable: true }, (baseUnique ? { unique: { unique: true, indexName: "".concat(table.name, "_").concat(column.name, "_enc_eq_unique") } } : {})), { ui: { hidden: true } }), 64);
|
|
218
|
+
this.injectCompanionColumn(table, companionProp, companion);
|
|
219
|
+
if (baseUnique) {
|
|
220
|
+
// Uniqueness moves to the fingerprint column (see validateDeclaration).
|
|
221
|
+
delete column.options.unique;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
table.indexes.push({
|
|
225
|
+
columns: [companionProp],
|
|
226
|
+
name: "".concat(table.name, "_").concat(column.name, "_enc_eq_idx"),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
EncryptedColumns.prototype.injectSortCompanion = function (table, prop, column, revealPrefix) {
|
|
231
|
+
var companion = new Columns_1.StringColumn("".concat(column.name, "_enc_srt"), { nullable: true, ui: { hidden: true } }, Math.max(revealPrefix, 1));
|
|
232
|
+
this.injectCompanionColumn(table, "".concat(column.name, "_enc_srt"), companion);
|
|
233
|
+
};
|
|
234
|
+
EncryptedColumns.prototype.injectCompanionColumn = function (table, companionProp, companion) {
|
|
235
|
+
if (table.columns[companionProp] && !this.isInternalColumn(table.columns[companionProp])) {
|
|
236
|
+
throw new DbEncryptionConfig_1.EncryptedColumnConfigError("(".concat(table.name, ") Column property '").concat(companionProp, "' collides with a framework-derived ") +
|
|
237
|
+
"encryption companion column. Rename the declared column.");
|
|
238
|
+
}
|
|
239
|
+
companion[EncryptedColumns.INTERNAL_COLUMN_MARKER] = true;
|
|
240
|
+
table.columns[companionProp] = companion;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* The token table's SHAPE for `table`, independent of registration — the lifecycle
|
|
244
|
+
* walker's decrypt-out sweep needs it after the config stopped declaring any
|
|
245
|
+
* `searchable: 'contains'` column (when `tokenTableFor` no longer resolves).
|
|
246
|
+
*/
|
|
247
|
+
EncryptedColumns.prototype.tokenTableShape = function (table) {
|
|
248
|
+
var tokenTableName = this.tokenTableName(table);
|
|
249
|
+
var tokenTable = new (/** @class */ (function (_super) {
|
|
250
|
+
__extends(class_1, _super);
|
|
251
|
+
function class_1() {
|
|
252
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
253
|
+
_this.name = tokenTableName;
|
|
254
|
+
_this.columns = (0, Record_1.withRecordColumns)({
|
|
255
|
+
recordId: new Columns_1.StringColumn('record_id', { nullable: false }, 36),
|
|
256
|
+
columnName: new Columns_1.StringColumn('column_name', { nullable: false }, 128),
|
|
257
|
+
token: new Columns_1.StringColumn('token', { nullable: false }, 64),
|
|
258
|
+
});
|
|
259
|
+
_this.indexes = [
|
|
260
|
+
{ columns: ['token', 'columnName'], name: "".concat(tokenTableName, "_cover_idx") },
|
|
261
|
+
{ columns: ['recordId'], name: "".concat(tokenTableName, "_record_idx") },
|
|
262
|
+
];
|
|
263
|
+
return _this;
|
|
264
|
+
// No auth block: default-deny for non-system callers; only framework system paths
|
|
265
|
+
// (EncryptionTokenMaintenance, the query translator's subqueries) touch token rows.
|
|
266
|
+
}
|
|
267
|
+
return class_1;
|
|
268
|
+
}(Table_1.Table)))();
|
|
269
|
+
return tokenTable;
|
|
270
|
+
};
|
|
271
|
+
EncryptedColumns.prototype.isTextColumn = function (column) {
|
|
272
|
+
if (!(0, util_1.isInstanceOf)(column, Columns_1.StringColumn)) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
return !((0, util_1.isInstanceOf)(column, Columns_1.UuidColumn) ||
|
|
276
|
+
(0, util_1.isInstanceOf)(column, Columns_1.ReferenceColumn) ||
|
|
277
|
+
(0, util_1.isInstanceOf)(column, Columns_1.ReferenceArrayColumn) ||
|
|
278
|
+
(0, util_1.isInstanceOf)(column, Columns_1.DynamicReferenceColumn) ||
|
|
279
|
+
(0, util_1.isInstanceOf)(column, Columns_1.DynamicReferenceTableNameColumn));
|
|
280
|
+
};
|
|
281
|
+
EncryptedColumns.SCHEMA_APPLIED_MARKER = '__encSchemaApplied';
|
|
282
|
+
EncryptedColumns.INTERNAL_COLUMN_MARKER = '__encInternalColumn';
|
|
283
|
+
return EncryptedColumns;
|
|
284
|
+
}());
|
|
285
|
+
exports.EncryptedColumns = EncryptedColumns;
|
|
286
|
+
//# sourceMappingURL=EncryptedColumns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncryptedColumns.js","sourceRoot":"","sources":["../../../src/encryption/EncryptedColumns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Table } from '../Table';
|
|
2
|
+
/**
|
|
3
|
+
* Registry of framework-DERIVED tables (search-token tables beside encrypted-searchable
|
|
4
|
+
* columns — see `EncryptedColumns`). Derived tables are synthesized from column config, not
|
|
5
|
+
* declared in source, so the reflection-backed table registry never sees them; `tableByName`
|
|
6
|
+
* consults this registry after the source registry misses.
|
|
7
|
+
*
|
|
8
|
+
* Lives on the global object so every live copy of this package (per-package installs)
|
|
9
|
+
* shares one registry — same pattern as `Db.getDefaultDbDriver`.
|
|
10
|
+
*
|
|
11
|
+
* Deliberately import-cycle-free: `Table` is a type-only import (erased at runtime), so
|
|
12
|
+
* `Table.ts` can import this module without closing a load-order loop.
|
|
13
|
+
*/
|
|
14
|
+
export declare class EncryptionDerivedTableRegistry {
|
|
15
|
+
private static readonly GLOBAL_KEY;
|
|
16
|
+
static get(tableName: string): Table<any> | undefined;
|
|
17
|
+
static register(table: Table<any>): void;
|
|
18
|
+
private static tables;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=EncryptionDerivedTableRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncryptionDerivedTableRegistry.d.ts","sourceRoot":"","sources":["../../../src/encryption/EncryptionDerivedTableRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;;;;;;;;GAWG;AACH,qBAAa,8BAA8B;IACzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAA4C;IAE9E,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS;IAIrD,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI;IAIxC,OAAO,CAAC,MAAM,CAAC,MAAM;CAQtB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EncryptionDerivedTableRegistry = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Registry of framework-DERIVED tables (search-token tables beside encrypted-searchable
|
|
6
|
+
* columns — see `EncryptedColumns`). Derived tables are synthesized from column config, not
|
|
7
|
+
* declared in source, so the reflection-backed table registry never sees them; `tableByName`
|
|
8
|
+
* consults this registry after the source registry misses.
|
|
9
|
+
*
|
|
10
|
+
* Lives on the global object so every live copy of this package (per-package installs)
|
|
11
|
+
* shares one registry — same pattern as `Db.getDefaultDbDriver`.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately import-cycle-free: `Table` is a type-only import (erased at runtime), so
|
|
14
|
+
* `Table.ts` can import this module without closing a load-order loop.
|
|
15
|
+
*/
|
|
16
|
+
var EncryptionDerivedTableRegistry = /** @class */ (function () {
|
|
17
|
+
function EncryptionDerivedTableRegistry() {
|
|
18
|
+
}
|
|
19
|
+
EncryptionDerivedTableRegistry.get = function (tableName) {
|
|
20
|
+
return EncryptionDerivedTableRegistry.tables().get(tableName);
|
|
21
|
+
};
|
|
22
|
+
EncryptionDerivedTableRegistry.register = function (table) {
|
|
23
|
+
EncryptionDerivedTableRegistry.tables().set(table.name, table);
|
|
24
|
+
};
|
|
25
|
+
EncryptionDerivedTableRegistry.tables = function () {
|
|
26
|
+
var globalObject = globalThis;
|
|
27
|
+
if (!globalObject[EncryptionDerivedTableRegistry.GLOBAL_KEY]) {
|
|
28
|
+
globalObject[EncryptionDerivedTableRegistry.GLOBAL_KEY] = new Map();
|
|
29
|
+
}
|
|
30
|
+
return globalObject[EncryptionDerivedTableRegistry.GLOBAL_KEY];
|
|
31
|
+
};
|
|
32
|
+
EncryptionDerivedTableRegistry.GLOBAL_KEY = '__proteinjs_db_encryptionDerivedTables';
|
|
33
|
+
return EncryptionDerivedTableRegistry;
|
|
34
|
+
}());
|
|
35
|
+
exports.EncryptionDerivedTableRegistry = EncryptionDerivedTableRegistry;
|
|
36
|
+
//# sourceMappingURL=EncryptionDerivedTableRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncryptionDerivedTableRegistry.js","sourceRoot":"","sources":["../../../src/encryption/EncryptionDerivedTableRegistry.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;GAWG;AACH;IAAA;IAmBA,CAAC;IAhBQ,kCAAG,GAAV,UAAW,SAAiB;QAC1B,OAAO,8BAA8B,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IAEM,uCAAQ,GAAf,UAAgB,KAAiB;QAC/B,8BAA8B,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;IAEc,qCAAM,GAArB;QACE,IAAM,YAAY,GAAG,UAAiB,CAAC;QACvC,IAAI,CAAC,YAAY,CAAC,8BAA8B,CAAC,UAAU,CAAC,EAAE;YAC5D,YAAY,CAAC,8BAA8B,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,EAAsB,CAAC;SACzF;QAED,OAAO,YAAY,CAAC,8BAA8B,CAAC,UAAU,CAAC,CAAC;IACjE,CAAC;IAjBuB,yCAAU,GAAG,wCAAwC,CAAC;IAkBhF,qCAAC;CAAA,AAnBD,IAmBC;AAnBY,wEAA8B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DataKeyMaterial } from './DataKeyStore';
|
|
2
|
+
/**
|
|
3
|
+
* The self-describing ciphertext envelope an encrypted column stores:
|
|
4
|
+
*
|
|
5
|
+
* `pjenc:1:<ownerId>:<keyVersion>:<base64url(iv || authTag || ciphertext)>`
|
|
6
|
+
*
|
|
7
|
+
* Decrypt resolves the key FROM the envelope (owner + version), never from who is asking —
|
|
8
|
+
* a shared row decrypts for whoever the permission layer admits, and key rotation is a
|
|
9
|
+
* background rewrite. Cipher: AES-256-GCM (12-byte IV, 16-byte tag), the data key's cipher
|
|
10
|
+
* half (`DataKeyMaterial.cipherKey`).
|
|
11
|
+
*/
|
|
12
|
+
export declare class EncryptionEnvelope {
|
|
13
|
+
static readonly PREFIX = "pjenc:1:";
|
|
14
|
+
private static readonly ENVELOPE_PATTERN;
|
|
15
|
+
encrypt(plaintext: string, key: DataKeyMaterial): string;
|
|
16
|
+
decrypt(envelope: string, key: DataKeyMaterial): string;
|
|
17
|
+
/** Owner + version + payload when `value` is an envelope, else undefined. */
|
|
18
|
+
parse(value: unknown): {
|
|
19
|
+
owner: string;
|
|
20
|
+
version: number;
|
|
21
|
+
payload: string;
|
|
22
|
+
} | undefined;
|
|
23
|
+
isEnvelope(value: unknown): boolean;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=EncryptionEnvelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncryptionEnvelope.d.ts","sourceRoot":"","sources":["../../../src/encryption/EncryptionEnvelope.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD;;;;;;;;;GASG;AACH,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,QAAQ,CAAC,MAAM,cAAc;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAA8C;IAEtF,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM;IASxD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,MAAM;IAevD,6EAA6E;IAC7E,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAatF,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;CAGpC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EncryptionEnvelope = void 0;
|
|
4
|
+
var crypto_1 = require("crypto");
|
|
5
|
+
var Base64Url_1 = require("./Base64Url");
|
|
6
|
+
/**
|
|
7
|
+
* The self-describing ciphertext envelope an encrypted column stores:
|
|
8
|
+
*
|
|
9
|
+
* `pjenc:1:<ownerId>:<keyVersion>:<base64url(iv || authTag || ciphertext)>`
|
|
10
|
+
*
|
|
11
|
+
* Decrypt resolves the key FROM the envelope (owner + version), never from who is asking —
|
|
12
|
+
* a shared row decrypts for whoever the permission layer admits, and key rotation is a
|
|
13
|
+
* background rewrite. Cipher: AES-256-GCM (12-byte IV, 16-byte tag), the data key's cipher
|
|
14
|
+
* half (`DataKeyMaterial.cipherKey`).
|
|
15
|
+
*/
|
|
16
|
+
var EncryptionEnvelope = /** @class */ (function () {
|
|
17
|
+
function EncryptionEnvelope() {
|
|
18
|
+
}
|
|
19
|
+
EncryptionEnvelope.prototype.encrypt = function (plaintext, key) {
|
|
20
|
+
var iv = (0, crypto_1.randomBytes)(12);
|
|
21
|
+
var cipher = (0, crypto_1.createCipheriv)('aes-256-gcm', key.cipherKey, iv);
|
|
22
|
+
var ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
23
|
+
var authTag = cipher.getAuthTag();
|
|
24
|
+
var payload = Base64Url_1.Base64Url.encode(Buffer.concat([iv, authTag, ciphertext]));
|
|
25
|
+
return "".concat(EncryptionEnvelope.PREFIX).concat(key.owner, ":").concat(key.version, ":").concat(payload);
|
|
26
|
+
};
|
|
27
|
+
EncryptionEnvelope.prototype.decrypt = function (envelope, key) {
|
|
28
|
+
var parsed = this.parse(envelope);
|
|
29
|
+
if (!parsed) {
|
|
30
|
+
throw new Error("Value is not a ciphertext envelope");
|
|
31
|
+
}
|
|
32
|
+
var bytes = Base64Url_1.Base64Url.decode(parsed.payload);
|
|
33
|
+
var iv = bytes.subarray(0, 12);
|
|
34
|
+
var authTag = bytes.subarray(12, 28);
|
|
35
|
+
var ciphertext = bytes.subarray(28);
|
|
36
|
+
var decipher = (0, crypto_1.createDecipheriv)('aes-256-gcm', key.cipherKey, iv);
|
|
37
|
+
decipher.setAuthTag(authTag);
|
|
38
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('utf8');
|
|
39
|
+
};
|
|
40
|
+
/** Owner + version + payload when `value` is an envelope, else undefined. */
|
|
41
|
+
EncryptionEnvelope.prototype.parse = function (value) {
|
|
42
|
+
if (typeof value !== 'string') {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
var match = EncryptionEnvelope.ENVELOPE_PATTERN.exec(value);
|
|
46
|
+
if (!match) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return { owner: match[1], version: parseInt(match[2], 10), payload: match[3] };
|
|
50
|
+
};
|
|
51
|
+
EncryptionEnvelope.prototype.isEnvelope = function (value) {
|
|
52
|
+
return this.parse(value) !== undefined;
|
|
53
|
+
};
|
|
54
|
+
EncryptionEnvelope.PREFIX = 'pjenc:1:';
|
|
55
|
+
EncryptionEnvelope.ENVELOPE_PATTERN = /^pjenc:1:([^:]+):(\d+):([A-Za-z0-9_-]+)$/;
|
|
56
|
+
return EncryptionEnvelope;
|
|
57
|
+
}());
|
|
58
|
+
exports.EncryptionEnvelope = EncryptionEnvelope;
|
|
59
|
+
//# sourceMappingURL=EncryptionEnvelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncryptionEnvelope.js","sourceRoot":"","sources":["../../../src/encryption/EncryptionEnvelope.ts"],"names":[],"mappings":";;;AAAA,iCAAuE;AACvE,yCAAwC;AAGxC;;;;;;;;;GASG;AACH;IAAA;IA6CA,CAAC;IAzCC,oCAAO,GAAP,UAAQ,SAAiB,EAAE,GAAoB;QAC7C,IAAM,EAAE,GAAG,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC;QAC3B,IAAM,MAAM,GAAG,IAAA,uBAAc,EAAC,aAAa,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAChE,IAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACrF,IAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACpC,IAAM,OAAO,GAAG,qBAAS,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,UAAG,kBAAkB,CAAC,MAAM,SAAG,GAAG,CAAC,KAAK,cAAI,GAAG,CAAC,OAAO,cAAI,OAAO,CAAE,CAAC;IAC9E,CAAC;IAED,oCAAO,GAAP,UAAQ,QAAgB,EAAE,GAAoB;QAC5C,IAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACvD;QAED,IAAM,KAAK,GAAG,qBAAS,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjC,IAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACvC,IAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtC,IAAM,QAAQ,GAAG,IAAA,yBAAgB,EAAC,aAAa,EAAE,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACpE,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzF,CAAC;IAED,6EAA6E;IAC7E,kCAAK,GAAL,UAAM,KAAc;QAClB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC7B,OAAO,SAAS,CAAC;SAClB;QAED,IAAM,KAAK,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,SAAS,CAAC;SAClB;QAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,CAAC;IAED,uCAAU,GAAV,UAAW,KAAc;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;IACzC,CAAC;IA3Ce,yBAAM,GAAG,UAAU,CAAC;IACZ,mCAAgB,GAAG,0CAA0C,CAAC;IA2CxF,yBAAC;CAAA,AA7CD,IA6CC;AA7CY,gDAAkB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Table } from '../Table';
|
|
2
|
+
/**
|
|
3
|
+
* The config-lifecycle transitions, all riding this one walker:
|
|
4
|
+
* - `encrypt` — plaintext → `encrypted: {...}` adoption: rewrite rows whose stored value is
|
|
5
|
+
* not yet an envelope (also how the initial adoption wave lands).
|
|
6
|
+
* - `retokenize` — a `searchable`/`sortKey` capability added later: rewrite every non-null
|
|
7
|
+
* value so the write seam derives the new companions/tokens.
|
|
8
|
+
* - `decrypt` — `encrypted` → `false` (a deliberate, reviewed reclassification): rewrite
|
|
9
|
+
* rows whose stored value is still an envelope; pass the affected columns explicitly
|
|
10
|
+
* (the config no longer marks them). Stale token rows are swept.
|
|
11
|
+
* - `rotate-keys` — after `DataKeyStore.rotateKey`: rewrite rows whose envelope names an
|
|
12
|
+
* older version (plaintext stragglers are encrypted too), then the caller retires the old
|
|
13
|
+
* version.
|
|
14
|
+
*/
|
|
15
|
+
export type EncryptionWalkMode = 'encrypt' | 'retokenize' | 'decrypt' | 'rotate-keys';
|
|
16
|
+
export interface EncryptionWalkSummary {
|
|
17
|
+
scanned: number;
|
|
18
|
+
rewritten: number;
|
|
19
|
+
}
|
|
20
|
+
export interface EncryptionWalkOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Column property names to walk. Required for mode 'decrypt' (the config no longer marks
|
|
23
|
+
* the columns); defaults to every encrypted-declared column otherwise.
|
|
24
|
+
*/
|
|
25
|
+
columns?: string[];
|
|
26
|
+
/** Resume after this row id (the walk is id-ordered; re-running from the start is also safe — done rows are skipped). */
|
|
27
|
+
startAfterId?: string;
|
|
28
|
+
windowSize?: number;
|
|
29
|
+
/** The driver to scan with; defaults to the process's default driver. */
|
|
30
|
+
dbDriver?: import('../Db').DbDriver;
|
|
31
|
+
/** The Db to rewrite through (must be a SYSTEM db); defaults to `getDbAsSystem()`. */
|
|
32
|
+
db?: import('../Db').Db<any>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The reusable ONLINE backfill behind every encrypted-column config transition (and key
|
|
36
|
+
* rotation) — the migration-runner pattern: a server-side, id-ordered, windowed table walk
|
|
37
|
+
* that rewrites pending rows THROUGH the normal write seam (so encryption, companions, and
|
|
38
|
+
* search tokens all derive exactly as a live write would).
|
|
39
|
+
*
|
|
40
|
+
* Idempotent and resumable by construction: pending-ness is detected from the stored value
|
|
41
|
+
* itself (envelope or not, version current or not), so a re-run — after a crash, or just to
|
|
42
|
+
* be sure — skips completed rows and continues. Rows written by live traffic mid-walk are
|
|
43
|
+
* already in the new shape and skip too. Run it from a `Migration.run()` for deploy-coupled
|
|
44
|
+
* transitions.
|
|
45
|
+
*/
|
|
46
|
+
export declare class EncryptionLifecycleWalker {
|
|
47
|
+
private static readonly DEFAULT_WINDOW_SIZE;
|
|
48
|
+
private logger;
|
|
49
|
+
private encryptedColumns;
|
|
50
|
+
private envelope;
|
|
51
|
+
walkTable(table: Table<any>, mode: EncryptionWalkMode, options?: EncryptionWalkOptions): Promise<EncryptionWalkSummary>;
|
|
52
|
+
private isPending;
|
|
53
|
+
/**
|
|
54
|
+
* Rewrite one row through the normal seam: read it (the deserialize hook decrypts — or
|
|
55
|
+
* passes plaintext through, the adoption path), write the pending columns back (the
|
|
56
|
+
* serialize hook re-derives ciphertext, companions, and tokens under the current config).
|
|
57
|
+
*/
|
|
58
|
+
private rewriteRow;
|
|
59
|
+
/** Raw (un-deserialized) id-ordered window — pending-ness must see stored bytes, not decrypted values. */
|
|
60
|
+
private rawWindow;
|
|
61
|
+
/** After decrypt-out, the decrypted columns' token rows are stale — sweep them. */
|
|
62
|
+
private sweepTokenRows;
|
|
63
|
+
private resolveProps;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=EncryptionLifecycleWalker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncryptionLifecycleWalker.d.ts","sourceRoot":"","sources":["../../../src/encryption/EncryptionLifecycleWalker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAKtC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC;AAEtF,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yHAAyH;IACzH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,OAAO,EAAE,QAAQ,CAAC;IACpC,sFAAsF;IACtF,EAAE,CAAC,EAAE,OAAO,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAO;IAClD,OAAO,CAAC,MAAM,CAA+C;IAC7D,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAA4B;IAEtC,SAAS,CACb,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,IAAI,EAAE,kBAAkB,EACxB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,qBAAqB,CAAC;YA4DnB,SAAS;IA+BvB;;;;OAIG;YACW,UAAU;IAyBxB,0GAA0G;YAC5F,SAAS;IAiBvB,mFAAmF;YACrE,cAAc;IAc5B,OAAO,CAAC,YAAY;CAwBrB"}
|