@cipherstash/stack 0.2.0 → 0.4.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 +12 -0
- package/README.md +2 -3
- package/dist/bin/stash.js +109 -186
- package/dist/bin/stash.js.map +1 -1
- package/dist/{chunk-SUYMGQBY.js → chunk-4RNBI3UH.js} +1 -7
- package/dist/chunk-4RNBI3UH.js.map +1 -0
- package/dist/{chunk-5G4F4JJG.js → chunk-KOU2MHXJ.js} +1 -1
- package/dist/chunk-KOU2MHXJ.js.map +1 -0
- package/dist/{chunk-5DCT6YU2.js → chunk-OAPLZLR5.js} +7 -3
- package/dist/{chunk-5DCT6YU2.js.map → chunk-OAPLZLR5.js.map} +1 -1
- package/dist/{chunk-LHZ6KZIG.js → chunk-WUZGKTMG.js} +84 -162
- package/dist/chunk-WUZGKTMG.js.map +1 -0
- package/dist/{chunk-7XRPN2KX.js → chunk-Y35W4WFN.js} +31 -28
- package/dist/chunk-Y35W4WFN.js.map +1 -0
- package/dist/{client-D-ZH8SB2.d.cts → client-CUGXheRq.d.cts} +33 -31
- package/dist/{client-BV9pXC-d.d.ts → client-CrGQnSlk.d.ts} +33 -31
- package/dist/client.cjs +30 -27
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +5 -5
- package/dist/drizzle/index.cjs +24 -21
- package/dist/drizzle/index.cjs.map +1 -1
- package/dist/drizzle/index.d.cts +5 -5
- package/dist/drizzle/index.d.ts +5 -5
- package/dist/drizzle/index.js +2 -2
- package/dist/drizzle/index.js.map +1 -1
- package/dist/dynamodb/index.cjs.map +1 -1
- package/dist/dynamodb/index.d.cts +10 -10
- package/dist/dynamodb/index.d.ts +10 -10
- package/dist/dynamodb/index.js.map +1 -1
- package/dist/identity/index.cjs +6 -2
- package/dist/identity/index.cjs.map +1 -1
- package/dist/identity/index.js +1 -1
- package/dist/index.cjs +113 -190
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +8 -8
- package/dist/schema/index.cjs +36 -33
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.js +11 -11
- package/dist/secrets/index.cjs +109 -186
- package/dist/secrets/index.cjs.map +1 -1
- package/dist/secrets/index.d.cts +1 -1
- package/dist/secrets/index.d.ts +1 -1
- package/dist/secrets/index.js +5 -5
- package/dist/secrets/index.js.map +1 -1
- package/dist/supabase/index.cjs +9 -9
- package/dist/supabase/index.cjs.map +1 -1
- package/dist/supabase/index.d.cts +3 -3
- package/dist/supabase/index.d.ts +3 -3
- package/dist/supabase/index.js +4 -4
- package/dist/supabase/index.js.map +1 -1
- package/dist/{types-public-Dfg-hkuQ.d.cts → types-public-Wj6tB_ux.d.cts} +115 -76
- package/dist/{types-public-Dfg-hkuQ.d.ts → types-public-Wj6tB_ux.d.ts} +115 -76
- package/dist/types-public.cjs.map +1 -1
- package/dist/types-public.d.cts +1 -1
- package/dist/types-public.d.ts +1 -1
- package/dist/types-public.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-5G4F4JJG.js.map +0 -1
- package/dist/chunk-7XRPN2KX.js.map +0 -1
- package/dist/chunk-LHZ6KZIG.js.map +0 -1
- package/dist/chunk-SUYMGQBY.js.map +0 -1
package/dist/secrets/index.cjs
CHANGED
|
@@ -41,15 +41,9 @@ function encryptedToPgComposite(obj) {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
function encryptedToCompositeLiteral(obj) {
|
|
44
|
-
if (obj === null) {
|
|
45
|
-
throw new Error("encryptedToCompositeLiteral: obj cannot be null");
|
|
46
|
-
}
|
|
47
44
|
return `(${JSON.stringify(JSON.stringify(obj))})`;
|
|
48
45
|
}
|
|
49
46
|
function encryptedToEscapedCompositeLiteral(obj) {
|
|
50
|
-
if (obj === null) {
|
|
51
|
-
throw new Error("encryptedToEscapedCompositeLiteral: obj cannot be null");
|
|
52
|
-
}
|
|
53
47
|
return JSON.stringify(encryptedToCompositeLiteral(obj));
|
|
54
48
|
}
|
|
55
49
|
function formatEncryptedResult(encrypted, returnType) {
|
|
@@ -89,7 +83,7 @@ var EncryptionErrorTypes = {
|
|
|
89
83
|
|
|
90
84
|
// src/schema/index.ts
|
|
91
85
|
var import_zod = require("zod");
|
|
92
|
-
var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json"]).default("
|
|
86
|
+
var castAsEnum = import_zod.z.enum(["bigint", "boolean", "date", "number", "string", "json", "text"]).default("text");
|
|
93
87
|
var tokenFilterSchema = import_zod.z.object({
|
|
94
88
|
kind: import_zod.z.literal("downcase")
|
|
95
89
|
});
|
|
@@ -132,28 +126,28 @@ var encryptConfigSchema = import_zod.z.object({
|
|
|
132
126
|
v: import_zod.z.number(),
|
|
133
127
|
tables: tablesSchema
|
|
134
128
|
});
|
|
135
|
-
var
|
|
129
|
+
var EncryptedField = class {
|
|
136
130
|
valueName;
|
|
137
131
|
castAsValue;
|
|
138
132
|
constructor(valueName) {
|
|
139
133
|
this.valueName = valueName;
|
|
140
|
-
this.castAsValue = "
|
|
134
|
+
this.castAsValue = "text";
|
|
141
135
|
}
|
|
142
136
|
/**
|
|
143
|
-
* Set or override the plaintext data type for this
|
|
137
|
+
* Set or override the plaintext data type for this field.
|
|
144
138
|
*
|
|
145
139
|
* By default all values are treated as `'string'`. Use this method to specify
|
|
146
140
|
* a different type so the encryption layer knows how to encode the plaintext
|
|
147
141
|
* before encrypting.
|
|
148
142
|
*
|
|
149
|
-
* @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
|
|
150
|
-
* @returns This `
|
|
143
|
+
* @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'text'`, `'bigint'`, or `'json'`.
|
|
144
|
+
* @returns This `EncryptedField` instance for method chaining.
|
|
151
145
|
*
|
|
152
146
|
* @example
|
|
153
147
|
* ```typescript
|
|
154
|
-
* import {
|
|
148
|
+
* import { encryptedField } from "@cipherstash/stack/schema"
|
|
155
149
|
*
|
|
156
|
-
* const age =
|
|
150
|
+
* const age = encryptedField("age").dataType("number")
|
|
157
151
|
* ```
|
|
158
152
|
*/
|
|
159
153
|
dataType(castAs) {
|
|
@@ -162,7 +156,7 @@ var ProtectValue = class {
|
|
|
162
156
|
}
|
|
163
157
|
build() {
|
|
164
158
|
return {
|
|
165
|
-
cast_as: this.castAsValue,
|
|
159
|
+
cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
|
|
166
160
|
indexes: {}
|
|
167
161
|
};
|
|
168
162
|
}
|
|
@@ -170,7 +164,7 @@ var ProtectValue = class {
|
|
|
170
164
|
return this.valueName;
|
|
171
165
|
}
|
|
172
166
|
};
|
|
173
|
-
var
|
|
167
|
+
var EncryptedColumn = class {
|
|
174
168
|
columnName;
|
|
175
169
|
castAsValue;
|
|
176
170
|
indexesValue = {};
|
|
@@ -186,7 +180,7 @@ var ProtectColumn = class {
|
|
|
186
180
|
* before encrypting.
|
|
187
181
|
*
|
|
188
182
|
* @param castAs - The plaintext data type: `'string'`, `'number'`, `'boolean'`, `'date'`, `'bigint'`, or `'json'`.
|
|
189
|
-
* @returns This `
|
|
183
|
+
* @returns This `EncryptedColumn` instance for method chaining.
|
|
190
184
|
*
|
|
191
185
|
* @example
|
|
192
186
|
* ```typescript
|
|
@@ -205,7 +199,7 @@ var ProtectColumn = class {
|
|
|
205
199
|
* ORE allows sorting, comparison, and range queries on encrypted data.
|
|
206
200
|
* Use with `encryptQuery` and `queryType: 'orderAndRange'`.
|
|
207
201
|
*
|
|
208
|
-
* @returns This `
|
|
202
|
+
* @returns This `EncryptedColumn` instance for method chaining.
|
|
209
203
|
*
|
|
210
204
|
* @example
|
|
211
205
|
* ```typescript
|
|
@@ -228,7 +222,7 @@ var ProtectColumn = class {
|
|
|
228
222
|
*
|
|
229
223
|
* @param tokenFilters - Optional array of token filters (e.g. `[{ kind: 'downcase' }]`).
|
|
230
224
|
* When omitted, no token filters are applied.
|
|
231
|
-
* @returns This `
|
|
225
|
+
* @returns This `EncryptedColumn` instance for method chaining.
|
|
232
226
|
*
|
|
233
227
|
* @example
|
|
234
228
|
* ```typescript
|
|
@@ -253,7 +247,7 @@ var ProtectColumn = class {
|
|
|
253
247
|
*
|
|
254
248
|
* @param opts - Optional match index configuration. Defaults to 3-character ngram
|
|
255
249
|
* tokenization with a downcase filter, `k=6`, `m=2048`, and `include_original=true`.
|
|
256
|
-
* @returns This `
|
|
250
|
+
* @returns This `EncryptedColumn` instance for method chaining.
|
|
257
251
|
*
|
|
258
252
|
* @example
|
|
259
253
|
* ```typescript
|
|
@@ -298,7 +292,7 @@ var ProtectColumn = class {
|
|
|
298
292
|
* the plaintext type: strings become selector queries, objects/arrays become
|
|
299
293
|
* containment queries.
|
|
300
294
|
*
|
|
301
|
-
* @returns This `
|
|
295
|
+
* @returns This `EncryptedColumn` instance for method chaining.
|
|
302
296
|
*
|
|
303
297
|
* @example
|
|
304
298
|
* ```typescript
|
|
@@ -316,7 +310,7 @@ var ProtectColumn = class {
|
|
|
316
310
|
}
|
|
317
311
|
build() {
|
|
318
312
|
return {
|
|
319
|
-
cast_as: this.castAsValue,
|
|
313
|
+
cast_as: this.castAsValue === "string" ? "text" : this.castAsValue,
|
|
320
314
|
indexes: this.indexesValue
|
|
321
315
|
};
|
|
322
316
|
}
|
|
@@ -324,7 +318,7 @@ var ProtectColumn = class {
|
|
|
324
318
|
return this.columnName;
|
|
325
319
|
}
|
|
326
320
|
};
|
|
327
|
-
var
|
|
321
|
+
var EncryptedTable = class {
|
|
328
322
|
constructor(tableName, columnBuilders) {
|
|
329
323
|
this.tableName = tableName;
|
|
330
324
|
this.columnBuilders = columnBuilders;
|
|
@@ -351,7 +345,7 @@ var ProtectTable = class {
|
|
|
351
345
|
build() {
|
|
352
346
|
const builtColumns = {};
|
|
353
347
|
const processColumn = (builder, colName) => {
|
|
354
|
-
if (builder instanceof
|
|
348
|
+
if (builder instanceof EncryptedColumn) {
|
|
355
349
|
const builtColumn = builder.build();
|
|
356
350
|
if (builtColumn.cast_as === "json" && builtColumn.indexes.ste_vec?.prefix === "enabled") {
|
|
357
351
|
builtColumns[colName] = {
|
|
@@ -368,7 +362,7 @@ var ProtectTable = class {
|
|
|
368
362
|
}
|
|
369
363
|
} else {
|
|
370
364
|
for (const [key, value] of Object.entries(builder)) {
|
|
371
|
-
if (value instanceof
|
|
365
|
+
if (value instanceof EncryptedField) {
|
|
372
366
|
builtColumns[value.getName()] = value.build();
|
|
373
367
|
} else {
|
|
374
368
|
processColumn(value, key);
|
|
@@ -386,7 +380,10 @@ var ProtectTable = class {
|
|
|
386
380
|
}
|
|
387
381
|
};
|
|
388
382
|
function encryptedTable(tableName, columns) {
|
|
389
|
-
const tableBuilder = new
|
|
383
|
+
const tableBuilder = new EncryptedTable(
|
|
384
|
+
tableName,
|
|
385
|
+
columns
|
|
386
|
+
);
|
|
390
387
|
for (const [colName, colBuilder] of Object.entries(columns)) {
|
|
391
388
|
;
|
|
392
389
|
tableBuilder[colName] = colBuilder;
|
|
@@ -394,7 +391,7 @@ function encryptedTable(tableName, columns) {
|
|
|
394
391
|
return tableBuilder;
|
|
395
392
|
}
|
|
396
393
|
function encryptedColumn(columnName) {
|
|
397
|
-
return new
|
|
394
|
+
return new EncryptedColumn(columnName);
|
|
398
395
|
}
|
|
399
396
|
function buildEncryptConfig(...protectTables) {
|
|
400
397
|
const config = {
|
|
@@ -488,7 +485,7 @@ function initStackLogger(config) {
|
|
|
488
485
|
const rates = samplingFromEnv();
|
|
489
486
|
(0, import_evlog.initLogger)({
|
|
490
487
|
env: { service: "@cipherstash/stack" },
|
|
491
|
-
enabled: config?.enabled ??
|
|
488
|
+
enabled: config?.enabled ?? !!rates,
|
|
492
489
|
pretty: config?.pretty,
|
|
493
490
|
...rates && { sampling: { rates } },
|
|
494
491
|
...config?.drain && { drain: config.drain }
|
|
@@ -501,7 +498,11 @@ function safeMessage(args) {
|
|
|
501
498
|
var logger = {
|
|
502
499
|
debug(...args) {
|
|
503
500
|
const log = (0, import_evlog.createRequestLogger)();
|
|
504
|
-
log.set({
|
|
501
|
+
log.set({
|
|
502
|
+
level: "debug",
|
|
503
|
+
source: "@cipherstash/stack",
|
|
504
|
+
message: safeMessage(args)
|
|
505
|
+
});
|
|
505
506
|
log.emit();
|
|
506
507
|
},
|
|
507
508
|
info(...args) {
|
|
@@ -522,22 +523,22 @@ var logger = {
|
|
|
522
523
|
}
|
|
523
524
|
};
|
|
524
525
|
|
|
525
|
-
// src/encryption/
|
|
526
|
+
// src/encryption/index.ts
|
|
526
527
|
var import_result11 = require("@byteslice/result");
|
|
527
528
|
var import_protect_ffi9 = require("@cipherstash/protect-ffi");
|
|
528
529
|
|
|
529
|
-
// src/encryption/
|
|
530
|
+
// src/encryption/helpers/type-guards.ts
|
|
530
531
|
function isScalarQueryTermArray(value) {
|
|
531
532
|
return Array.isArray(value) && value.length > 0 && typeof value[0] === "object" && value[0] !== null && "column" in value[0] && "table" in value[0];
|
|
532
533
|
}
|
|
533
534
|
|
|
534
|
-
// src/encryption/
|
|
535
|
+
// src/encryption/helpers/error-code.ts
|
|
535
536
|
var import_protect_ffi = require("@cipherstash/protect-ffi");
|
|
536
537
|
function getErrorCode(error) {
|
|
537
538
|
return error instanceof import_protect_ffi.ProtectError ? error.code : void 0;
|
|
538
539
|
}
|
|
539
540
|
|
|
540
|
-
// src/encryption/
|
|
541
|
+
// src/encryption/operations/batch-encrypt-query.ts
|
|
541
542
|
var import_result = require("@byteslice/result");
|
|
542
543
|
var import_protect_ffi2 = require("@cipherstash/protect-ffi");
|
|
543
544
|
|
|
@@ -555,7 +556,7 @@ var queryTypeToQueryOp = {
|
|
|
555
556
|
steVecTerm: "ste_vec_term"
|
|
556
557
|
};
|
|
557
558
|
|
|
558
|
-
// src/encryption/
|
|
559
|
+
// src/encryption/helpers/infer-index-type.ts
|
|
559
560
|
function inferIndexType(column) {
|
|
560
561
|
const config = column.build();
|
|
561
562
|
const indexes = config.indexes;
|
|
@@ -615,7 +616,7 @@ function resolveIndexType(column, queryType, plaintext) {
|
|
|
615
616
|
return { indexType };
|
|
616
617
|
}
|
|
617
618
|
|
|
618
|
-
// src/encryption/
|
|
619
|
+
// src/encryption/helpers/validation.ts
|
|
619
620
|
function validateNumericValue(value) {
|
|
620
621
|
if (typeof value === "number" && Number.isNaN(value)) {
|
|
621
622
|
return {
|
|
@@ -651,7 +652,7 @@ function assertValueIndexCompatibility(value, indexType, columnName) {
|
|
|
651
652
|
}
|
|
652
653
|
}
|
|
653
654
|
|
|
654
|
-
// src/encryption/
|
|
655
|
+
// src/encryption/operations/base-operation.ts
|
|
655
656
|
var EncryptionOperation = class {
|
|
656
657
|
auditMetadata;
|
|
657
658
|
/**
|
|
@@ -679,19 +680,7 @@ var EncryptionOperation = class {
|
|
|
679
680
|
}
|
|
680
681
|
};
|
|
681
682
|
|
|
682
|
-
// src/encryption/
|
|
683
|
-
function filterNullTerms(terms) {
|
|
684
|
-
const nullIndices = /* @__PURE__ */ new Set();
|
|
685
|
-
const nonNullTerms = [];
|
|
686
|
-
terms.forEach((term, index) => {
|
|
687
|
-
if (term.value === null || term.value === void 0) {
|
|
688
|
-
nullIndices.add(index);
|
|
689
|
-
} else {
|
|
690
|
-
nonNullTerms.push({ term, originalIndex: index });
|
|
691
|
-
}
|
|
692
|
-
});
|
|
693
|
-
return { nullIndices, nonNullTerms };
|
|
694
|
-
}
|
|
683
|
+
// src/encryption/operations/batch-encrypt-query.ts
|
|
695
684
|
function buildQueryPayload(term, lockContext) {
|
|
696
685
|
assertValidNumericValue(term.value);
|
|
697
686
|
const { indexType, queryOp } = resolveIndexType(
|
|
@@ -712,13 +701,10 @@ function buildQueryPayload(term, lockContext) {
|
|
|
712
701
|
}
|
|
713
702
|
return payload;
|
|
714
703
|
}
|
|
715
|
-
function assembleResults(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
results[originalIndex] = formatEncryptedResult(encrypted, term.returnType);
|
|
720
|
-
});
|
|
721
|
-
return results;
|
|
704
|
+
function assembleResults(terms, encryptedValues) {
|
|
705
|
+
return terms.map(
|
|
706
|
+
(term, i) => formatEncryptedResult(encryptedValues[i], term.returnType)
|
|
707
|
+
);
|
|
722
708
|
}
|
|
723
709
|
var BatchEncryptQueryOperation = class extends EncryptionOperation {
|
|
724
710
|
constructor(client, terms) {
|
|
@@ -745,23 +731,18 @@ var BatchEncryptQueryOperation = class extends EncryptionOperation {
|
|
|
745
731
|
log.emit();
|
|
746
732
|
return { data: [] };
|
|
747
733
|
}
|
|
748
|
-
const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
|
|
749
|
-
if (nonNullTerms.length === 0) {
|
|
750
|
-
log.emit();
|
|
751
|
-
return { data: this.terms.map(() => null) };
|
|
752
|
-
}
|
|
753
734
|
const result = await (0, import_result.withResult)(
|
|
754
735
|
async () => {
|
|
755
736
|
if (!this.client) throw noClientError();
|
|
756
737
|
const { metadata } = this.getAuditData();
|
|
757
|
-
const queries =
|
|
758
|
-
(
|
|
738
|
+
const queries = this.terms.map(
|
|
739
|
+
(term) => buildQueryPayload(term)
|
|
759
740
|
);
|
|
760
741
|
const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
|
|
761
742
|
queries,
|
|
762
743
|
unverifiedContext: metadata
|
|
763
744
|
});
|
|
764
|
-
return assembleResults(this.terms
|
|
745
|
+
return assembleResults(this.terms, encrypted);
|
|
765
746
|
},
|
|
766
747
|
(error) => {
|
|
767
748
|
log.set({ errorCode: getErrorCode(error) ?? "unknown" });
|
|
@@ -795,11 +776,6 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
|
|
|
795
776
|
log.emit();
|
|
796
777
|
return { data: [] };
|
|
797
778
|
}
|
|
798
|
-
const { nullIndices, nonNullTerms } = filterNullTerms(this.terms);
|
|
799
|
-
if (nonNullTerms.length === 0) {
|
|
800
|
-
log.emit();
|
|
801
|
-
return { data: this.terms.map(() => null) };
|
|
802
|
-
}
|
|
803
779
|
const lockContextResult = await this.lockContext.getLockContext();
|
|
804
780
|
if (lockContextResult.failure) {
|
|
805
781
|
log.emit();
|
|
@@ -810,15 +786,15 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
|
|
|
810
786
|
async () => {
|
|
811
787
|
if (!this.client) throw noClientError();
|
|
812
788
|
const { metadata } = this.getAuditData();
|
|
813
|
-
const queries =
|
|
814
|
-
(
|
|
789
|
+
const queries = this.terms.map(
|
|
790
|
+
(term) => buildQueryPayload(term, context)
|
|
815
791
|
);
|
|
816
792
|
const encrypted = await (0, import_protect_ffi2.encryptQueryBulk)(this.client, {
|
|
817
793
|
queries,
|
|
818
794
|
serviceToken: ctsToken,
|
|
819
795
|
unverifiedContext: metadata
|
|
820
796
|
});
|
|
821
|
-
return assembleResults(this.terms
|
|
797
|
+
return assembleResults(this.terms, encrypted);
|
|
822
798
|
},
|
|
823
799
|
(error) => {
|
|
824
800
|
log.set({ errorCode: getErrorCode(error) ?? "unknown" });
|
|
@@ -834,46 +810,29 @@ var BatchEncryptQueryOperationWithLockContext = class extends EncryptionOperatio
|
|
|
834
810
|
}
|
|
835
811
|
};
|
|
836
812
|
|
|
837
|
-
// src/encryption/
|
|
813
|
+
// src/encryption/operations/bulk-decrypt.ts
|
|
838
814
|
var import_result2 = require("@byteslice/result");
|
|
839
815
|
var import_protect_ffi3 = require("@cipherstash/protect-ffi");
|
|
840
816
|
var createDecryptPayloads = (encryptedPayloads, lockContext) => {
|
|
841
|
-
return encryptedPayloads.map((
|
|
817
|
+
return encryptedPayloads.map(({ id, data }) => ({
|
|
842
818
|
id,
|
|
843
819
|
ciphertext: data,
|
|
844
|
-
originalIndex,
|
|
845
820
|
...lockContext && { lockContext }
|
|
846
821
|
}));
|
|
847
822
|
};
|
|
848
|
-
var createNullResult = (encryptedPayloads) => {
|
|
849
|
-
return encryptedPayloads.map(({ id }) => ({
|
|
850
|
-
id,
|
|
851
|
-
data: null
|
|
852
|
-
}));
|
|
853
|
-
};
|
|
854
823
|
var mapDecryptedDataToResult = (encryptedPayloads, decryptedData) => {
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
const decryptResult = decryptedData[decryptedIndex];
|
|
862
|
-
if ("error" in decryptResult) {
|
|
863
|
-
result[i] = {
|
|
864
|
-
id: encryptedPayloads[i].id,
|
|
865
|
-
error: decryptResult.error
|
|
866
|
-
};
|
|
867
|
-
} else {
|
|
868
|
-
result[i] = {
|
|
869
|
-
id: encryptedPayloads[i].id,
|
|
870
|
-
data: decryptResult.data
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
decryptedIndex++;
|
|
824
|
+
return decryptedData.map((decryptResult, i) => {
|
|
825
|
+
if ("error" in decryptResult) {
|
|
826
|
+
return {
|
|
827
|
+
id: encryptedPayloads[i].id,
|
|
828
|
+
error: decryptResult.error
|
|
829
|
+
};
|
|
874
830
|
}
|
|
875
|
-
|
|
876
|
-
|
|
831
|
+
return {
|
|
832
|
+
id: encryptedPayloads[i].id,
|
|
833
|
+
data: decryptResult.data
|
|
834
|
+
};
|
|
835
|
+
});
|
|
877
836
|
};
|
|
878
837
|
var BulkDecryptOperation = class extends EncryptionOperation {
|
|
879
838
|
client;
|
|
@@ -898,13 +857,10 @@ var BulkDecryptOperation = class extends EncryptionOperation {
|
|
|
898
857
|
if (!this.client) throw noClientError();
|
|
899
858
|
if (!this.encryptedPayloads || this.encryptedPayloads.length === 0)
|
|
900
859
|
return [];
|
|
901
|
-
const
|
|
902
|
-
if (nonNullPayloads.length === 0) {
|
|
903
|
-
return createNullResult(this.encryptedPayloads);
|
|
904
|
-
}
|
|
860
|
+
const payloads = createDecryptPayloads(this.encryptedPayloads);
|
|
905
861
|
const { metadata } = this.getAuditData();
|
|
906
862
|
const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(this.client, {
|
|
907
|
-
ciphertexts:
|
|
863
|
+
ciphertexts: payloads,
|
|
908
864
|
unverifiedContext: metadata
|
|
909
865
|
});
|
|
910
866
|
return mapDecryptedDataToResult(this.encryptedPayloads, decryptedData);
|
|
@@ -956,16 +912,13 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
956
912
|
if (context.failure) {
|
|
957
913
|
throw new Error(`[encryption]: ${context.failure.message}`);
|
|
958
914
|
}
|
|
959
|
-
const
|
|
915
|
+
const payloads = createDecryptPayloads(
|
|
960
916
|
encryptedPayloads,
|
|
961
917
|
context.data.context
|
|
962
918
|
);
|
|
963
|
-
if (nonNullPayloads.length === 0) {
|
|
964
|
-
return createNullResult(encryptedPayloads);
|
|
965
|
-
}
|
|
966
919
|
const { metadata } = this.getAuditData();
|
|
967
920
|
const decryptedData = await (0, import_protect_ffi3.decryptBulkFallible)(client, {
|
|
968
|
-
ciphertexts:
|
|
921
|
+
ciphertexts: payloads,
|
|
969
922
|
serviceToken: context.data.ctsToken,
|
|
970
923
|
unverifiedContext: metadata
|
|
971
924
|
});
|
|
@@ -985,10 +938,10 @@ var BulkDecryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
985
938
|
}
|
|
986
939
|
};
|
|
987
940
|
|
|
988
|
-
// src/encryption/
|
|
941
|
+
// src/encryption/operations/bulk-decrypt-models.ts
|
|
989
942
|
var import_result3 = require("@byteslice/result");
|
|
990
943
|
|
|
991
|
-
// src/encryption/
|
|
944
|
+
// src/encryption/helpers/model-helpers.ts
|
|
992
945
|
var import_protect_ffi4 = require("@cipherstash/protect-ffi");
|
|
993
946
|
function setNestedValue(obj, path2, value) {
|
|
994
947
|
const FORBIDDEN_KEYS = ["__proto__", "prototype", "constructor"];
|
|
@@ -1503,7 +1456,7 @@ async function bulkEncryptModelsWithLockContext(models, table, client, lockConte
|
|
|
1503
1456
|
});
|
|
1504
1457
|
}
|
|
1505
1458
|
|
|
1506
|
-
// src/encryption/
|
|
1459
|
+
// src/encryption/operations/bulk-decrypt-models.ts
|
|
1507
1460
|
var BulkDecryptModelsOperation = class extends EncryptionOperation {
|
|
1508
1461
|
client;
|
|
1509
1462
|
models;
|
|
@@ -1600,38 +1553,18 @@ var BulkDecryptModelsOperationWithLockContext = class extends EncryptionOperatio
|
|
|
1600
1553
|
}
|
|
1601
1554
|
};
|
|
1602
1555
|
|
|
1603
|
-
// src/encryption/
|
|
1556
|
+
// src/encryption/operations/bulk-encrypt.ts
|
|
1604
1557
|
var import_result4 = require("@byteslice/result");
|
|
1605
1558
|
var import_protect_ffi5 = require("@cipherstash/protect-ffi");
|
|
1606
1559
|
var createEncryptPayloads = (plaintexts, column, table, lockContext) => {
|
|
1607
|
-
return plaintexts.map((
|
|
1560
|
+
return plaintexts.map(({ id, plaintext }) => ({
|
|
1608
1561
|
id,
|
|
1609
1562
|
plaintext,
|
|
1610
1563
|
column: column.getName(),
|
|
1611
1564
|
table: table.tableName,
|
|
1612
|
-
originalIndex,
|
|
1613
1565
|
...lockContext && { lockContext }
|
|
1614
1566
|
}));
|
|
1615
1567
|
};
|
|
1616
|
-
var createNullResult2 = (plaintexts) => {
|
|
1617
|
-
return plaintexts.map(({ id }) => ({ id, data: null }));
|
|
1618
|
-
};
|
|
1619
|
-
var mapEncryptedDataToResult = (plaintexts, encryptedData) => {
|
|
1620
|
-
const result = new Array(plaintexts.length);
|
|
1621
|
-
let encryptedIndex = 0;
|
|
1622
|
-
for (let i = 0; i < plaintexts.length; i++) {
|
|
1623
|
-
if (plaintexts[i].plaintext === null) {
|
|
1624
|
-
result[i] = { id: plaintexts[i].id, data: null };
|
|
1625
|
-
} else {
|
|
1626
|
-
result[i] = {
|
|
1627
|
-
id: plaintexts[i].id,
|
|
1628
|
-
data: encryptedData[encryptedIndex]
|
|
1629
|
-
};
|
|
1630
|
-
encryptedIndex++;
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
return result;
|
|
1634
|
-
};
|
|
1635
1568
|
var BulkEncryptOperation = class extends EncryptionOperation {
|
|
1636
1569
|
client;
|
|
1637
1570
|
plaintexts;
|
|
@@ -1664,20 +1597,20 @@ var BulkEncryptOperation = class extends EncryptionOperation {
|
|
|
1664
1597
|
if (!this.plaintexts || this.plaintexts.length === 0) {
|
|
1665
1598
|
return [];
|
|
1666
1599
|
}
|
|
1667
|
-
const
|
|
1600
|
+
const payloads = createEncryptPayloads(
|
|
1668
1601
|
this.plaintexts,
|
|
1669
1602
|
this.column,
|
|
1670
1603
|
this.table
|
|
1671
1604
|
);
|
|
1672
|
-
if (nonNullPayloads.length === 0) {
|
|
1673
|
-
return createNullResult2(this.plaintexts);
|
|
1674
|
-
}
|
|
1675
1605
|
const { metadata } = this.getAuditData();
|
|
1676
1606
|
const encryptedData = await (0, import_protect_ffi5.encryptBulk)(this.client, {
|
|
1677
|
-
plaintexts:
|
|
1607
|
+
plaintexts: payloads,
|
|
1678
1608
|
unverifiedContext: metadata
|
|
1679
1609
|
});
|
|
1680
|
-
return
|
|
1610
|
+
return encryptedData.map((data, i) => ({
|
|
1611
|
+
id: this.plaintexts[i].id,
|
|
1612
|
+
data
|
|
1613
|
+
}));
|
|
1681
1614
|
},
|
|
1682
1615
|
(error) => {
|
|
1683
1616
|
log.set({ errorCode: getErrorCode(error) ?? "unknown" });
|
|
@@ -1734,22 +1667,22 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
1734
1667
|
if (context.failure) {
|
|
1735
1668
|
throw new Error(`[encryption]: ${context.failure.message}`);
|
|
1736
1669
|
}
|
|
1737
|
-
const
|
|
1670
|
+
const payloads = createEncryptPayloads(
|
|
1738
1671
|
plaintexts,
|
|
1739
1672
|
column,
|
|
1740
1673
|
table,
|
|
1741
1674
|
context.data.context
|
|
1742
1675
|
);
|
|
1743
|
-
if (nonNullPayloads.length === 0) {
|
|
1744
|
-
return createNullResult2(plaintexts);
|
|
1745
|
-
}
|
|
1746
1676
|
const { metadata } = this.getAuditData();
|
|
1747
1677
|
const encryptedData = await (0, import_protect_ffi5.encryptBulk)(client, {
|
|
1748
|
-
plaintexts:
|
|
1678
|
+
plaintexts: payloads,
|
|
1749
1679
|
serviceToken: context.data.ctsToken,
|
|
1750
1680
|
unverifiedContext: metadata
|
|
1751
1681
|
});
|
|
1752
|
-
return
|
|
1682
|
+
return encryptedData.map((data, i) => ({
|
|
1683
|
+
id: plaintexts[i].id,
|
|
1684
|
+
data
|
|
1685
|
+
}));
|
|
1753
1686
|
},
|
|
1754
1687
|
(error) => {
|
|
1755
1688
|
log.set({ errorCode: getErrorCode(error) ?? "unknown" });
|
|
@@ -1765,7 +1698,7 @@ var BulkEncryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
1765
1698
|
}
|
|
1766
1699
|
};
|
|
1767
1700
|
|
|
1768
|
-
// src/encryption/
|
|
1701
|
+
// src/encryption/operations/bulk-encrypt-models.ts
|
|
1769
1702
|
var import_result5 = require("@byteslice/result");
|
|
1770
1703
|
var BulkEncryptModelsOperation = class extends EncryptionOperation {
|
|
1771
1704
|
client;
|
|
@@ -1874,7 +1807,7 @@ var BulkEncryptModelsOperationWithLockContext = class extends EncryptionOperatio
|
|
|
1874
1807
|
}
|
|
1875
1808
|
};
|
|
1876
1809
|
|
|
1877
|
-
// src/encryption/
|
|
1810
|
+
// src/encryption/operations/decrypt.ts
|
|
1878
1811
|
var import_result6 = require("@byteslice/result");
|
|
1879
1812
|
var import_protect_ffi6 = require("@cipherstash/protect-ffi");
|
|
1880
1813
|
var DecryptOperation = class extends EncryptionOperation {
|
|
@@ -1899,9 +1832,6 @@ var DecryptOperation = class extends EncryptionOperation {
|
|
|
1899
1832
|
if (!this.client) {
|
|
1900
1833
|
throw noClientError();
|
|
1901
1834
|
}
|
|
1902
|
-
if (this.encryptedData === null) {
|
|
1903
|
-
return null;
|
|
1904
|
-
}
|
|
1905
1835
|
const { metadata } = this.getAuditData();
|
|
1906
1836
|
return await (0, import_protect_ffi6.decrypt)(this.client, {
|
|
1907
1837
|
ciphertext: this.encryptedData,
|
|
@@ -1952,9 +1882,6 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
1952
1882
|
if (!client) {
|
|
1953
1883
|
throw noClientError();
|
|
1954
1884
|
}
|
|
1955
|
-
if (encryptedData === null) {
|
|
1956
|
-
return null;
|
|
1957
|
-
}
|
|
1958
1885
|
const { metadata } = this.getAuditData();
|
|
1959
1886
|
const context = await this.lockContext.getLockContext();
|
|
1960
1887
|
if (context.failure) {
|
|
@@ -1981,7 +1908,7 @@ var DecryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
1981
1908
|
}
|
|
1982
1909
|
};
|
|
1983
1910
|
|
|
1984
|
-
// src/encryption/
|
|
1911
|
+
// src/encryption/operations/decrypt-model.ts
|
|
1985
1912
|
var import_result7 = require("@byteslice/result");
|
|
1986
1913
|
var DecryptModelOperation = class extends EncryptionOperation {
|
|
1987
1914
|
client;
|
|
@@ -2077,7 +2004,7 @@ var DecryptModelOperationWithLockContext = class extends EncryptionOperation {
|
|
|
2077
2004
|
}
|
|
2078
2005
|
};
|
|
2079
2006
|
|
|
2080
|
-
// src/encryption/
|
|
2007
|
+
// src/encryption/operations/encrypt.ts
|
|
2081
2008
|
var import_result8 = require("@byteslice/result");
|
|
2082
2009
|
var import_protect_ffi7 = require("@cipherstash/protect-ffi");
|
|
2083
2010
|
var EncryptOperation = class extends EncryptionOperation {
|
|
@@ -2108,9 +2035,6 @@ var EncryptOperation = class extends EncryptionOperation {
|
|
|
2108
2035
|
if (!this.client) {
|
|
2109
2036
|
throw noClientError();
|
|
2110
2037
|
}
|
|
2111
|
-
if (this.plaintext === null) {
|
|
2112
|
-
return null;
|
|
2113
|
-
}
|
|
2114
2038
|
if (typeof this.plaintext === "number" && Number.isNaN(this.plaintext)) {
|
|
2115
2039
|
throw new Error("[encryption]: Cannot encrypt NaN value");
|
|
2116
2040
|
}
|
|
@@ -2172,9 +2096,6 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
2172
2096
|
if (!client) {
|
|
2173
2097
|
throw noClientError();
|
|
2174
2098
|
}
|
|
2175
|
-
if (plaintext === null) {
|
|
2176
|
-
return null;
|
|
2177
|
-
}
|
|
2178
2099
|
const { metadata } = this.getAuditData();
|
|
2179
2100
|
const context = await this.lockContext.getLockContext();
|
|
2180
2101
|
if (context.failure) {
|
|
@@ -2203,7 +2124,7 @@ var EncryptOperationWithLockContext = class extends EncryptionOperation {
|
|
|
2203
2124
|
}
|
|
2204
2125
|
};
|
|
2205
2126
|
|
|
2206
|
-
// src/encryption/
|
|
2127
|
+
// src/encryption/operations/encrypt-model.ts
|
|
2207
2128
|
var import_result9 = require("@byteslice/result");
|
|
2208
2129
|
var EncryptModelOperation = class extends EncryptionOperation {
|
|
2209
2130
|
client;
|
|
@@ -2310,7 +2231,7 @@ var EncryptModelOperationWithLockContext = class extends EncryptionOperation {
|
|
|
2310
2231
|
}
|
|
2311
2232
|
};
|
|
2312
2233
|
|
|
2313
|
-
// src/encryption/
|
|
2234
|
+
// src/encryption/operations/encrypt-query.ts
|
|
2314
2235
|
var import_result10 = require("@byteslice/result");
|
|
2315
2236
|
var import_protect_ffi8 = require("@cipherstash/protect-ffi");
|
|
2316
2237
|
var EncryptQueryOperation = class extends EncryptionOperation {
|
|
@@ -2338,10 +2259,6 @@ var EncryptQueryOperation = class extends EncryptionOperation {
|
|
|
2338
2259
|
queryType: this.opts.queryType,
|
|
2339
2260
|
lockContext: false
|
|
2340
2261
|
});
|
|
2341
|
-
if (this.plaintext === null || this.plaintext === void 0) {
|
|
2342
|
-
log.emit();
|
|
2343
|
-
return { data: null };
|
|
2344
|
-
}
|
|
2345
2262
|
const validationError = validateNumericValue(this.plaintext);
|
|
2346
2263
|
if (validationError?.failure) {
|
|
2347
2264
|
log.emit();
|
|
@@ -2405,10 +2322,6 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
|
|
|
2405
2322
|
queryType: this.opts.queryType,
|
|
2406
2323
|
lockContext: true
|
|
2407
2324
|
});
|
|
2408
|
-
if (this.plaintext === null || this.plaintext === void 0) {
|
|
2409
|
-
log.emit();
|
|
2410
|
-
return { data: null };
|
|
2411
|
-
}
|
|
2412
2325
|
const validationError = validateNumericValue(this.plaintext);
|
|
2413
2326
|
if (validationError?.failure) {
|
|
2414
2327
|
log.emit();
|
|
@@ -2460,9 +2373,9 @@ var EncryptQueryOperationWithLockContext = class extends EncryptionOperation {
|
|
|
2460
2373
|
}
|
|
2461
2374
|
};
|
|
2462
2375
|
|
|
2463
|
-
// src/encryption/
|
|
2376
|
+
// src/encryption/index.ts
|
|
2464
2377
|
var noClientError = () => new Error(
|
|
2465
|
-
"The
|
|
2378
|
+
"The Encryption client has not been initialized. Please call init() before using the client."
|
|
2466
2379
|
);
|
|
2467
2380
|
var EncryptionClient = class {
|
|
2468
2381
|
client;
|
|
@@ -2485,7 +2398,7 @@ var EncryptionClient = class {
|
|
|
2485
2398
|
config.encryptConfig
|
|
2486
2399
|
);
|
|
2487
2400
|
logger.debug(
|
|
2488
|
-
"Initializing the
|
|
2401
|
+
"Initializing the Encryption client with the following config:",
|
|
2489
2402
|
{
|
|
2490
2403
|
encryptConfig: validated
|
|
2491
2404
|
}
|
|
@@ -2501,7 +2414,7 @@ var EncryptionClient = class {
|
|
|
2501
2414
|
}
|
|
2502
2415
|
});
|
|
2503
2416
|
this.encryptConfig = validated;
|
|
2504
|
-
logger.debug("Successfully initialized the
|
|
2417
|
+
logger.debug("Successfully initialized the Encryption client.");
|
|
2505
2418
|
return this;
|
|
2506
2419
|
},
|
|
2507
2420
|
(error) => ({
|
|
@@ -2513,8 +2426,8 @@ var EncryptionClient = class {
|
|
|
2513
2426
|
/**
|
|
2514
2427
|
* Encrypt a value - returns a promise which resolves to an encrypted value.
|
|
2515
2428
|
*
|
|
2516
|
-
* @param plaintext - The plaintext value to be encrypted.
|
|
2517
|
-
* @param opts - Options specifying the column and table for encryption.
|
|
2429
|
+
* @param plaintext - The plaintext value to be encrypted.
|
|
2430
|
+
* @param opts - Options specifying the column (or nested field) and table for encryption. See {@link EncryptOptions}.
|
|
2518
2431
|
* @returns An EncryptOperation that can be awaited or chained with additional methods.
|
|
2519
2432
|
*
|
|
2520
2433
|
* @example
|
|
@@ -2577,8 +2490,11 @@ var EncryptionClient = class {
|
|
|
2577
2490
|
* .withLockContext(lockContext)
|
|
2578
2491
|
* ```
|
|
2579
2492
|
*
|
|
2493
|
+
* @see {@link EncryptOptions}
|
|
2580
2494
|
* @see {@link Result}
|
|
2581
2495
|
* @see {@link encryptedTable}
|
|
2496
|
+
* @see {@link encryptedColumn}
|
|
2497
|
+
* @see {@link encryptedField}
|
|
2582
2498
|
* @see {@link LockContext}
|
|
2583
2499
|
* @see {@link EncryptOperation}
|
|
2584
2500
|
*/
|
|
@@ -2686,7 +2602,11 @@ var EncryptionClient = class {
|
|
|
2686
2602
|
* ```
|
|
2687
2603
|
*/
|
|
2688
2604
|
encryptModel(input, table) {
|
|
2689
|
-
return new EncryptModelOperation(
|
|
2605
|
+
return new EncryptModelOperation(
|
|
2606
|
+
this.client,
|
|
2607
|
+
input,
|
|
2608
|
+
table
|
|
2609
|
+
);
|
|
2690
2610
|
}
|
|
2691
2611
|
/**
|
|
2692
2612
|
* Decrypt a model (object) whose fields contain encrypted values.
|
|
@@ -2765,7 +2685,11 @@ var EncryptionClient = class {
|
|
|
2765
2685
|
* ```
|
|
2766
2686
|
*/
|
|
2767
2687
|
bulkEncryptModels(input, table) {
|
|
2768
|
-
return new BulkEncryptModelsOperation(
|
|
2688
|
+
return new BulkEncryptModelsOperation(
|
|
2689
|
+
this.client,
|
|
2690
|
+
input,
|
|
2691
|
+
table
|
|
2692
|
+
);
|
|
2769
2693
|
}
|
|
2770
2694
|
/**
|
|
2771
2695
|
* Decrypt multiple models (objects) in a single bulk operation.
|
|
@@ -2803,10 +2727,10 @@ var EncryptionClient = class {
|
|
|
2803
2727
|
*
|
|
2804
2728
|
* Each value is encrypted with its own unique key via a single call to ZeroKMS.
|
|
2805
2729
|
* Values can include optional `id` fields for correlating results back to
|
|
2806
|
-
* your application data.
|
|
2730
|
+
* your application data.
|
|
2807
2731
|
*
|
|
2808
2732
|
* @param plaintexts - An array of objects with `plaintext` (and optional `id`) fields.
|
|
2809
|
-
* @param opts - Options specifying the target column and table
|
|
2733
|
+
* @param opts - Options specifying the target column (or nested {@link encryptedField}) and table. See {@link EncryptOptions}.
|
|
2810
2734
|
* @returns A `BulkEncryptOperation` that can be awaited to get a `Result`
|
|
2811
2735
|
* containing an array of `{ id?, data: Encrypted }` objects, or an `EncryptionError`.
|
|
2812
2736
|
*
|
|
@@ -2824,7 +2748,6 @@ var EncryptionClient = class {
|
|
|
2824
2748
|
* [
|
|
2825
2749
|
* { id: "u1", plaintext: "alice@example.com" },
|
|
2826
2750
|
* { id: "u2", plaintext: "bob@example.com" },
|
|
2827
|
-
* { id: "u3", plaintext: null },
|
|
2828
2751
|
* ],
|
|
2829
2752
|
* { column: users.email, table: users },
|
|
2830
2753
|
* )
|