mongodb 6.7.0 → 6.8.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/README.md +20 -1
- package/lib/bson.js.map +1 -1
- package/lib/client-side-encryption/auto_encrypter.js +8 -61
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
- package/lib/client-side-encryption/client_encryption.js +5 -5
- package/lib/client-side-encryption/client_encryption.js.map +1 -1
- package/lib/client-side-encryption/providers/index.js.map +1 -1
- package/lib/client-side-encryption/state_machine.js +15 -11
- package/lib/client-side-encryption/state_machine.js.map +1 -1
- package/lib/cmap/connection.js +22 -20
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/wire_protocol/on_demand/document.js +8 -5
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
- package/lib/cmap/wire_protocol/responses.js +116 -40
- package/lib/cmap/wire_protocol/responses.js.map +1 -1
- package/lib/collection.js +13 -2
- package/lib/collection.js.map +1 -1
- package/lib/constants.js +9 -1
- package/lib/constants.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +231 -285
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +11 -19
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/change_stream_cursor.js +12 -14
- package/lib/cursor/change_stream_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +64 -84
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/cursor/list_collections_cursor.js +0 -1
- package/lib/cursor/list_collections_cursor.js.map +1 -1
- package/lib/cursor/list_indexes_cursor.js +0 -1
- package/lib/cursor/list_indexes_cursor.js.map +1 -1
- package/lib/cursor/run_command_cursor.js +4 -6
- package/lib/cursor/run_command_cursor.js.map +1 -1
- package/lib/error.js +10 -23
- package/lib/error.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/operations/aggregate.js +2 -2
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/bulk_write.js +1 -2
- package/lib/operations/bulk_write.js.map +1 -1
- package/lib/operations/command.js +2 -3
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +2 -1
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/get_more.js +1 -1
- package/lib/operations/get_more.js.map +1 -1
- package/lib/operations/indexes.js +2 -1
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/list_collections.js +2 -1
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/run_command.js +1 -1
- package/lib/operations/run_command.js.map +1 -1
- package/lib/operations/update.js +2 -1
- package/lib/operations/update.js.map +1 -1
- package/lib/sdam/server.js +7 -2
- package/lib/sdam/server.js.map +1 -1
- package/lib/sessions.js +1 -1
- package/lib/sessions.js.map +1 -1
- package/lib/utils.js +45 -1
- package/lib/utils.js.map +1 -1
- package/lib/write_concern.js +17 -1
- package/lib/write_concern.js.map +1 -1
- package/mongodb.d.ts +187 -150
- package/package.json +2 -2
- package/src/bson.ts +1 -0
- package/src/client-side-encryption/auto_encrypter.ts +9 -70
- package/src/client-side-encryption/client_encryption.ts +33 -19
- package/src/client-side-encryption/providers/index.ts +118 -92
- package/src/client-side-encryption/state_machine.ts +22 -18
- package/src/cmap/connection.ts +46 -50
- package/src/cmap/wire_protocol/on_demand/document.ts +13 -6
- package/src/cmap/wire_protocol/responses.ts +140 -45
- package/src/collection.ts +25 -5
- package/src/constants.ts +9 -0
- package/src/cursor/abstract_cursor.ts +280 -373
- package/src/cursor/aggregation_cursor.ts +24 -33
- package/src/cursor/change_stream_cursor.ts +31 -48
- package/src/cursor/find_cursor.ts +77 -92
- package/src/cursor/list_collections_cursor.ts +3 -4
- package/src/cursor/list_indexes_cursor.ts +3 -4
- package/src/cursor/run_command_cursor.ts +13 -19
- package/src/error.ts +20 -30
- package/src/index.ts +19 -10
- package/src/operations/aggregate.ts +12 -5
- package/src/operations/bulk_write.ts +1 -2
- package/src/operations/command.ts +17 -3
- package/src/operations/delete.ts +2 -2
- package/src/operations/execute_operation.ts +0 -13
- package/src/operations/find.ts +7 -3
- package/src/operations/find_and_modify.ts +1 -1
- package/src/operations/get_more.ts +6 -10
- package/src/operations/indexes.ts +7 -3
- package/src/operations/list_collections.ts +8 -3
- package/src/operations/run_command.ts +16 -6
- package/src/operations/update.ts +2 -1
- package/src/sdam/server.ts +7 -2
- package/src/sessions.ts +1 -1
- package/src/utils.ts +52 -2
- package/src/write_concern.ts +18 -0
- package/lib/operations/count_documents.js +0 -31
- package/lib/operations/count_documents.js.map +0 -1
- package/src/operations/count_documents.ts +0 -46
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
|
|
7
7
|
import { deserialize, type Document, serialize } from '../bson';
|
|
8
8
|
import { type CommandOptions, type ProxyOptions } from '../cmap/connection';
|
|
9
|
+
import { kDecorateResult } from '../constants';
|
|
9
10
|
import { getMongoDBClientEncryption } from '../deps';
|
|
10
11
|
import { MongoRuntimeError } from '../error';
|
|
11
12
|
import { MongoClient, type MongoClientOptions } from '../mongo_client';
|
|
@@ -212,15 +213,6 @@ export const AutoEncryptionLoggerLevel = Object.freeze({
|
|
|
212
213
|
export type AutoEncryptionLoggerLevel =
|
|
213
214
|
(typeof AutoEncryptionLoggerLevel)[keyof typeof AutoEncryptionLoggerLevel];
|
|
214
215
|
|
|
215
|
-
// Typescript errors if we index objects with `Symbol.for(...)`, so
|
|
216
|
-
// to avoid TS errors we pull them out into variables. Then we can type
|
|
217
|
-
// the objects (and class) that we expect to see them on and prevent TS
|
|
218
|
-
// errors.
|
|
219
|
-
/** @internal */
|
|
220
|
-
const kDecorateResult = Symbol.for('@@mdb.decorateDecryptionResult');
|
|
221
|
-
/** @internal */
|
|
222
|
-
const kDecoratedKeys = Symbol.for('@@mdb.decryptedKeys');
|
|
223
|
-
|
|
224
216
|
/**
|
|
225
217
|
* @internal An internal class to be used by the driver for auto encryption
|
|
226
218
|
* **NOTE**: Not meant to be instantiated directly, this is for internal use only.
|
|
@@ -467,16 +459,18 @@ export class AutoEncrypter {
|
|
|
467
459
|
proxyOptions: this._proxyOptions,
|
|
468
460
|
tlsOptions: this._tlsOptions
|
|
469
461
|
});
|
|
470
|
-
|
|
462
|
+
|
|
463
|
+
return deserialize(await stateMachine.execute(this, context), {
|
|
464
|
+
promoteValues: false,
|
|
465
|
+
promoteLongs: false
|
|
466
|
+
});
|
|
471
467
|
}
|
|
472
468
|
|
|
473
469
|
/**
|
|
474
470
|
* Decrypt a command response
|
|
475
471
|
*/
|
|
476
|
-
async decrypt(response: Uint8Array
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
const context = this._mongocrypt.makeDecryptionContext(buffer);
|
|
472
|
+
async decrypt(response: Uint8Array, options: CommandOptions = {}): Promise<Uint8Array> {
|
|
473
|
+
const context = this._mongocrypt.makeDecryptionContext(response);
|
|
480
474
|
|
|
481
475
|
context.id = this._contextCounter++;
|
|
482
476
|
|
|
@@ -486,12 +480,7 @@ export class AutoEncrypter {
|
|
|
486
480
|
tlsOptions: this._tlsOptions
|
|
487
481
|
});
|
|
488
482
|
|
|
489
|
-
|
|
490
|
-
const result = await stateMachine.execute<Document>(this, context);
|
|
491
|
-
if (decorateResult) {
|
|
492
|
-
decorateDecryptionResult(result, response);
|
|
493
|
-
}
|
|
494
|
-
return result;
|
|
483
|
+
return await stateMachine.execute(this, context);
|
|
495
484
|
}
|
|
496
485
|
|
|
497
486
|
/**
|
|
@@ -518,53 +507,3 @@ export class AutoEncrypter {
|
|
|
518
507
|
return AutoEncrypter.getMongoCrypt().libmongocryptVersion;
|
|
519
508
|
}
|
|
520
509
|
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* Recurse through the (identically-shaped) `decrypted` and `original`
|
|
524
|
-
* objects and attach a `decryptedKeys` property on each sub-object that
|
|
525
|
-
* contained encrypted fields. Because we only call this on BSON responses,
|
|
526
|
-
* we do not need to worry about circular references.
|
|
527
|
-
*
|
|
528
|
-
* @internal
|
|
529
|
-
*/
|
|
530
|
-
function decorateDecryptionResult(
|
|
531
|
-
decrypted: Document & { [kDecoratedKeys]?: Array<string> },
|
|
532
|
-
original: Document,
|
|
533
|
-
isTopLevelDecorateCall = true
|
|
534
|
-
): void {
|
|
535
|
-
if (isTopLevelDecorateCall) {
|
|
536
|
-
// The original value could have been either a JS object or a BSON buffer
|
|
537
|
-
if (Buffer.isBuffer(original)) {
|
|
538
|
-
original = deserialize(original);
|
|
539
|
-
}
|
|
540
|
-
if (Buffer.isBuffer(decrypted)) {
|
|
541
|
-
throw new MongoRuntimeError('Expected result of decryption to be deserialized BSON object');
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
if (!decrypted || typeof decrypted !== 'object') return;
|
|
546
|
-
for (const k of Object.keys(decrypted)) {
|
|
547
|
-
const originalValue = original[k];
|
|
548
|
-
|
|
549
|
-
// An object was decrypted by libmongocrypt if and only if it was
|
|
550
|
-
// a BSON Binary object with subtype 6.
|
|
551
|
-
if (originalValue && originalValue._bsontype === 'Binary' && originalValue.sub_type === 6) {
|
|
552
|
-
if (!decrypted[kDecoratedKeys]) {
|
|
553
|
-
Object.defineProperty(decrypted, kDecoratedKeys, {
|
|
554
|
-
value: [],
|
|
555
|
-
configurable: true,
|
|
556
|
-
enumerable: false,
|
|
557
|
-
writable: false
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
// this is defined in the preceding if-statement
|
|
561
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
562
|
-
decrypted[kDecoratedKeys]!.push(k);
|
|
563
|
-
// Do not recurse into this decrypted value. It could be a sub-document/array,
|
|
564
|
-
// in which case there is no original value associated with its subfields.
|
|
565
|
-
continue;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
decorateDecryptionResult(decrypted[k], originalValue, false);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
MongoCryptOptions
|
|
6
6
|
} from 'mongodb-client-encryption';
|
|
7
7
|
|
|
8
|
-
import { type Binary, type Document, type Long, serialize, type UUID } from '../bson';
|
|
8
|
+
import { type Binary, deserialize, type Document, type Long, serialize, type UUID } from '../bson';
|
|
9
9
|
import { type AnyBulkWriteOperation, type BulkWriteResult } from '../bulk/common';
|
|
10
10
|
import { type ProxyOptions } from '../cmap/connection';
|
|
11
11
|
import { type Collection } from '../collection';
|
|
@@ -202,7 +202,7 @@ export class ClientEncryption {
|
|
|
202
202
|
tlsOptions: this._tlsOptions
|
|
203
203
|
});
|
|
204
204
|
|
|
205
|
-
const dataKey = await stateMachine.execute
|
|
205
|
+
const dataKey = deserialize(await stateMachine.execute(this, context)) as DataKey;
|
|
206
206
|
|
|
207
207
|
const { db: dbName, collection: collectionName } = MongoDBCollectionNamespace.fromString(
|
|
208
208
|
this._keyVaultNamespace
|
|
@@ -259,7 +259,7 @@ export class ClientEncryption {
|
|
|
259
259
|
tlsOptions: this._tlsOptions
|
|
260
260
|
});
|
|
261
261
|
|
|
262
|
-
const { v: dataKeys } = await stateMachine.execute
|
|
262
|
+
const { v: dataKeys } = deserialize(await stateMachine.execute(this, context));
|
|
263
263
|
if (dataKeys.length === 0) {
|
|
264
264
|
return {};
|
|
265
265
|
}
|
|
@@ -640,7 +640,7 @@ export class ClientEncryption {
|
|
|
640
640
|
tlsOptions: this._tlsOptions
|
|
641
641
|
});
|
|
642
642
|
|
|
643
|
-
const { v } = await stateMachine.execute
|
|
643
|
+
const { v } = deserialize(await stateMachine.execute(this, context));
|
|
644
644
|
|
|
645
645
|
return v;
|
|
646
646
|
}
|
|
@@ -719,8 +719,8 @@ export class ClientEncryption {
|
|
|
719
719
|
});
|
|
720
720
|
const context = this._mongoCrypt.makeExplicitEncryptionContext(valueBuffer, contextOptions);
|
|
721
721
|
|
|
722
|
-
const
|
|
723
|
-
return
|
|
722
|
+
const { v } = deserialize(await stateMachine.execute(this, context));
|
|
723
|
+
return v;
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
726
|
|
|
@@ -773,6 +773,7 @@ export interface ClientEncryptionRewrapManyDataKeyProviderOptions {
|
|
|
773
773
|
| AWSEncryptionKeyOptions
|
|
774
774
|
| AzureEncryptionKeyOptions
|
|
775
775
|
| GCPEncryptionKeyOptions
|
|
776
|
+
| KMIPEncryptionKeyOptions
|
|
776
777
|
| undefined;
|
|
777
778
|
}
|
|
778
779
|
|
|
@@ -885,6 +886,31 @@ export interface AzureEncryptionKeyOptions {
|
|
|
885
886
|
keyVersion?: string | undefined;
|
|
886
887
|
}
|
|
887
888
|
|
|
889
|
+
/**
|
|
890
|
+
* @public
|
|
891
|
+
* Configuration options for making a KMIP encryption key
|
|
892
|
+
*/
|
|
893
|
+
export interface KMIPEncryptionKeyOptions {
|
|
894
|
+
/**
|
|
895
|
+
* keyId is the KMIP Unique Identifier to a 96 byte KMIP Secret Data managed object.
|
|
896
|
+
*
|
|
897
|
+
* If keyId is omitted, a random 96 byte KMIP Secret Data managed object will be created.
|
|
898
|
+
*/
|
|
899
|
+
keyId?: string;
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Host with optional port.
|
|
903
|
+
*/
|
|
904
|
+
endpoint?: string;
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* If true, this key should be decrypted by the KMIP server.
|
|
908
|
+
*
|
|
909
|
+
* Requires `mongodb-client-encryption>=6.0.1`.
|
|
910
|
+
*/
|
|
911
|
+
delegated?: boolean;
|
|
912
|
+
}
|
|
913
|
+
|
|
888
914
|
/**
|
|
889
915
|
* @public
|
|
890
916
|
* Options to provide when creating a new data key.
|
|
@@ -897,6 +923,7 @@ export interface ClientEncryptionCreateDataKeyProviderOptions {
|
|
|
897
923
|
| AWSEncryptionKeyOptions
|
|
898
924
|
| AzureEncryptionKeyOptions
|
|
899
925
|
| GCPEncryptionKeyOptions
|
|
926
|
+
| KMIPEncryptionKeyOptions
|
|
900
927
|
| undefined;
|
|
901
928
|
|
|
902
929
|
/**
|
|
@@ -909,19 +936,6 @@ export interface ClientEncryptionCreateDataKeyProviderOptions {
|
|
|
909
936
|
keyMaterial?: Buffer | Binary;
|
|
910
937
|
}
|
|
911
938
|
|
|
912
|
-
/**
|
|
913
|
-
* @public
|
|
914
|
-
* @experimental
|
|
915
|
-
*/
|
|
916
|
-
export interface ClientEncryptionRewrapManyDataKeyProviderOptions {
|
|
917
|
-
provider: ClientEncryptionDataKeyProvider;
|
|
918
|
-
masterKey?:
|
|
919
|
-
| AWSEncryptionKeyOptions
|
|
920
|
-
| AzureEncryptionKeyOptions
|
|
921
|
-
| GCPEncryptionKeyOptions
|
|
922
|
-
| undefined;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
939
|
/**
|
|
926
940
|
* @public
|
|
927
941
|
* @experimental
|
|
@@ -1,127 +1,153 @@
|
|
|
1
|
+
import type { Binary } from '../../bson';
|
|
1
2
|
import { loadAWSCredentials } from './aws';
|
|
2
3
|
import { loadAzureCredentials } from './azure';
|
|
3
4
|
import { loadGCPCredentials } from './gcp';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* @public
|
|
8
|
+
*
|
|
9
|
+
* A data key provider. Allowed values:
|
|
10
|
+
*
|
|
11
|
+
* - aws, gcp, local, kmip or azure
|
|
12
|
+
* - (`mongodb-client-encryption>=6.0.1` only) a named key, in the form of:
|
|
13
|
+
* `aws:<name>`, `gcp:<name>`, `local:<name>`, `kmip:<name>`, `azure:<name>`
|
|
14
|
+
* where `name` is an alphanumeric string, underscores allowed.
|
|
7
15
|
*/
|
|
8
|
-
export type ClientEncryptionDataKeyProvider =
|
|
16
|
+
export type ClientEncryptionDataKeyProvider = keyof KMSProviders;
|
|
17
|
+
|
|
18
|
+
/** @public */
|
|
19
|
+
export interface AWSKMSProviderConfiguration {
|
|
20
|
+
/**
|
|
21
|
+
* The access key used for the AWS KMS provider
|
|
22
|
+
*/
|
|
23
|
+
accessKeyId: string;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The secret access key used for the AWS KMS provider
|
|
27
|
+
*/
|
|
28
|
+
secretAccessKey: string;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* An optional AWS session token that will be used as the
|
|
32
|
+
* X-Amz-Security-Token header for AWS requests.
|
|
33
|
+
*/
|
|
34
|
+
sessionToken?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** @public */
|
|
38
|
+
export interface LocalKMSProviderConfiguration {
|
|
39
|
+
/**
|
|
40
|
+
* The master key used to encrypt/decrypt data keys.
|
|
41
|
+
* A 96-byte long Buffer or base64 encoded string.
|
|
42
|
+
*/
|
|
43
|
+
key: Binary | Uint8Array | string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** @public */
|
|
47
|
+
export interface KMIPKMSProviderConfiguration {
|
|
48
|
+
/**
|
|
49
|
+
* The output endpoint string.
|
|
50
|
+
* The endpoint consists of a hostname and port separated by a colon.
|
|
51
|
+
* E.g. "example.com:123". A port is always present.
|
|
52
|
+
*/
|
|
53
|
+
endpoint?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** @public */
|
|
57
|
+
export type AzureKMSProviderConfiguration =
|
|
58
|
+
| {
|
|
59
|
+
/**
|
|
60
|
+
* The tenant ID identifies the organization for the account
|
|
61
|
+
*/
|
|
62
|
+
tenantId: string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The client ID to authenticate a registered application
|
|
66
|
+
*/
|
|
67
|
+
clientId: string;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The client secret to authenticate a registered application
|
|
71
|
+
*/
|
|
72
|
+
clientSecret: string;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
|
|
76
|
+
* This is optional, and only needed if customer is using a non-commercial Azure instance
|
|
77
|
+
* (e.g. a government or China account, which use different URLs).
|
|
78
|
+
* Defaults to "login.microsoftonline.com"
|
|
79
|
+
*/
|
|
80
|
+
identityPlatformEndpoint?: string | undefined;
|
|
81
|
+
}
|
|
82
|
+
| {
|
|
83
|
+
/**
|
|
84
|
+
* If present, an access token to authenticate with Azure.
|
|
85
|
+
*/
|
|
86
|
+
accessToken: string;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** @public */
|
|
90
|
+
export type GCPKMSProviderConfiguration =
|
|
91
|
+
| {
|
|
92
|
+
/**
|
|
93
|
+
* The service account email to authenticate
|
|
94
|
+
*/
|
|
95
|
+
email: string;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* A PKCS#8 encrypted key. This can either be a base64 string or a binary representation
|
|
99
|
+
*/
|
|
100
|
+
privateKey: string | Buffer;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
|
|
104
|
+
* Defaults to "oauth2.googleapis.com"
|
|
105
|
+
*/
|
|
106
|
+
endpoint?: string | undefined;
|
|
107
|
+
}
|
|
108
|
+
| {
|
|
109
|
+
/**
|
|
110
|
+
* If present, an access token to authenticate with GCP.
|
|
111
|
+
*/
|
|
112
|
+
accessToken: string;
|
|
113
|
+
};
|
|
9
114
|
|
|
10
115
|
/**
|
|
11
116
|
* @public
|
|
12
117
|
* Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.
|
|
118
|
+
*
|
|
119
|
+
* Named KMS providers _are not supported_ for automatic KMS credential fetching.
|
|
13
120
|
*/
|
|
14
121
|
export interface KMSProviders {
|
|
15
122
|
/**
|
|
16
123
|
* Configuration options for using 'aws' as your KMS provider
|
|
17
124
|
*/
|
|
18
|
-
aws?:
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The access key used for the AWS KMS provider
|
|
22
|
-
*/
|
|
23
|
-
accessKeyId: string;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* The secret access key used for the AWS KMS provider
|
|
27
|
-
*/
|
|
28
|
-
secretAccessKey: string;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* An optional AWS session token that will be used as the
|
|
32
|
-
* X-Amz-Security-Token header for AWS requests.
|
|
33
|
-
*/
|
|
34
|
-
sessionToken?: string;
|
|
35
|
-
}
|
|
36
|
-
| Record<string, never>;
|
|
125
|
+
aws?: AWSKMSProviderConfiguration | Record<string, never>;
|
|
126
|
+
[key: `aws:${string}`]: AWSKMSProviderConfiguration;
|
|
37
127
|
|
|
38
128
|
/**
|
|
39
129
|
* Configuration options for using 'local' as your KMS provider
|
|
40
130
|
*/
|
|
41
|
-
local?:
|
|
42
|
-
|
|
43
|
-
* The master key used to encrypt/decrypt data keys.
|
|
44
|
-
* A 96-byte long Buffer or base64 encoded string.
|
|
45
|
-
*/
|
|
46
|
-
key: Buffer | string;
|
|
47
|
-
};
|
|
131
|
+
local?: LocalKMSProviderConfiguration;
|
|
132
|
+
[key: `local:${string}`]: LocalKMSProviderConfiguration;
|
|
48
133
|
|
|
49
134
|
/**
|
|
50
135
|
* Configuration options for using 'kmip' as your KMS provider
|
|
51
136
|
*/
|
|
52
|
-
kmip?:
|
|
53
|
-
|
|
54
|
-
* The output endpoint string.
|
|
55
|
-
* The endpoint consists of a hostname and port separated by a colon.
|
|
56
|
-
* E.g. "example.com:123". A port is always present.
|
|
57
|
-
*/
|
|
58
|
-
endpoint?: string;
|
|
59
|
-
};
|
|
137
|
+
kmip?: KMIPKMSProviderConfiguration;
|
|
138
|
+
[key: `kmip:${string}`]: KMIPKMSProviderConfiguration;
|
|
60
139
|
|
|
61
140
|
/**
|
|
62
141
|
* Configuration options for using 'azure' as your KMS provider
|
|
63
142
|
*/
|
|
64
|
-
azure?:
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* The tenant ID identifies the organization for the account
|
|
68
|
-
*/
|
|
69
|
-
tenantId: string;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* The client ID to authenticate a registered application
|
|
73
|
-
*/
|
|
74
|
-
clientId: string;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* The client secret to authenticate a registered application
|
|
78
|
-
*/
|
|
79
|
-
clientSecret: string;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
|
|
83
|
-
* This is optional, and only needed if customer is using a non-commercial Azure instance
|
|
84
|
-
* (e.g. a government or China account, which use different URLs).
|
|
85
|
-
* Defaults to "login.microsoftonline.com"
|
|
86
|
-
*/
|
|
87
|
-
identityPlatformEndpoint?: string | undefined;
|
|
88
|
-
}
|
|
89
|
-
| {
|
|
90
|
-
/**
|
|
91
|
-
* If present, an access token to authenticate with Azure.
|
|
92
|
-
*/
|
|
93
|
-
accessToken: string;
|
|
94
|
-
}
|
|
95
|
-
| Record<string, never>;
|
|
143
|
+
azure?: AzureKMSProviderConfiguration | Record<string, never>;
|
|
144
|
+
[key: `azure:${string}`]: AzureKMSProviderConfiguration;
|
|
96
145
|
|
|
97
146
|
/**
|
|
98
147
|
* Configuration options for using 'gcp' as your KMS provider
|
|
99
148
|
*/
|
|
100
|
-
gcp?:
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* The service account email to authenticate
|
|
104
|
-
*/
|
|
105
|
-
email: string;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* A PKCS#8 encrypted key. This can either be a base64 string or a binary representation
|
|
109
|
-
*/
|
|
110
|
-
privateKey: string | Buffer;
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* If present, a host with optional port. E.g. "example.com" or "example.com:443".
|
|
114
|
-
* Defaults to "oauth2.googleapis.com"
|
|
115
|
-
*/
|
|
116
|
-
endpoint?: string | undefined;
|
|
117
|
-
}
|
|
118
|
-
| {
|
|
119
|
-
/**
|
|
120
|
-
* If present, an access token to authenticate with GCP.
|
|
121
|
-
*/
|
|
122
|
-
accessToken: string;
|
|
123
|
-
}
|
|
124
|
-
| Record<string, never>;
|
|
149
|
+
gcp?: GCPKMSProviderConfiguration | Record<string, never>;
|
|
150
|
+
[key: `gcp:${string}`]: GCPKMSProviderConfiguration;
|
|
125
151
|
}
|
|
126
152
|
|
|
127
153
|
/**
|
|
@@ -17,7 +17,7 @@ import { BufferPool, MongoDBCollectionNamespace, promiseWithResolvers } from '..
|
|
|
17
17
|
import { type DataKey } from './client_encryption';
|
|
18
18
|
import { MongoCryptError } from './errors';
|
|
19
19
|
import { type MongocryptdManager } from './mongocryptd_manager';
|
|
20
|
-
import { type
|
|
20
|
+
import { type KMSProviders } from './providers';
|
|
21
21
|
|
|
22
22
|
let socks: SocksLib | null = null;
|
|
23
23
|
function loadSocks(): SocksLib {
|
|
@@ -110,8 +110,23 @@ export type CSFLEKMSTlsOptions = {
|
|
|
110
110
|
kmip?: ClientEncryptionTlsOptions;
|
|
111
111
|
local?: ClientEncryptionTlsOptions;
|
|
112
112
|
azure?: ClientEncryptionTlsOptions;
|
|
113
|
+
|
|
114
|
+
[key: string]: ClientEncryptionTlsOptions | undefined;
|
|
113
115
|
};
|
|
114
116
|
|
|
117
|
+
/**
|
|
118
|
+
* This is kind of a hack. For `rewrapManyDataKey`, we have tests that
|
|
119
|
+
* guarantee that when there are no matching keys, `rewrapManyDataKey` returns
|
|
120
|
+
* nothing. We also have tests for auto encryption that guarantee for `encrypt`
|
|
121
|
+
* we return an error when there are no matching keys. This error is generated in
|
|
122
|
+
* subsequent iterations of the state machine.
|
|
123
|
+
* Some apis (`encrypt`) throw if there are no filter matches and others (`rewrapManyDataKey`)
|
|
124
|
+
* do not. We set the result manually here, and let the state machine continue. `libmongocrypt`
|
|
125
|
+
* will inform us if we need to error by setting the state to `MONGOCRYPT_CTX_ERROR` but
|
|
126
|
+
* otherwise we'll return `{ v: [] }`.
|
|
127
|
+
*/
|
|
128
|
+
let EMPTY_V;
|
|
129
|
+
|
|
115
130
|
/**
|
|
116
131
|
* @internal
|
|
117
132
|
*
|
|
@@ -154,16 +169,13 @@ export class StateMachine {
|
|
|
154
169
|
/**
|
|
155
170
|
* Executes the state machine according to the specification
|
|
156
171
|
*/
|
|
157
|
-
async execute
|
|
158
|
-
executor: StateMachineExecutable,
|
|
159
|
-
context: MongoCryptContext
|
|
160
|
-
): Promise<T> {
|
|
172
|
+
async execute(executor: StateMachineExecutable, context: MongoCryptContext): Promise<Uint8Array> {
|
|
161
173
|
const keyVaultNamespace = executor._keyVaultNamespace;
|
|
162
174
|
const keyVaultClient = executor._keyVaultClient;
|
|
163
175
|
const metaDataClient = executor._metaDataClient;
|
|
164
176
|
const mongocryptdClient = executor._mongocryptdClient;
|
|
165
177
|
const mongocryptdManager = executor._mongocryptdManager;
|
|
166
|
-
let result:
|
|
178
|
+
let result: Uint8Array | null = null;
|
|
167
179
|
|
|
168
180
|
while (context.state !== MONGOCRYPT_CTX_DONE && context.state !== MONGOCRYPT_CTX_ERROR) {
|
|
169
181
|
debug(`[context#${context.id}] ${stateToString.get(context.state) || context.state}`);
|
|
@@ -211,16 +223,8 @@ export class StateMachine {
|
|
|
211
223
|
const keys = await this.fetchKeys(keyVaultClient, keyVaultNamespace, filter);
|
|
212
224
|
|
|
213
225
|
if (keys.length === 0) {
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
// nothing. We also have tests for auto encryption that guarantee for `encrypt`
|
|
217
|
-
// we return an error when there are no matching keys. This error is generated in
|
|
218
|
-
// subsequent iterations of the state machine.
|
|
219
|
-
// Some apis (`encrypt`) throw if there are no filter matches and others (`rewrapManyDataKey`)
|
|
220
|
-
// do not. We set the result manually here, and let the state machine continue. `libmongocrypt`
|
|
221
|
-
// will inform us if we need to error by setting the state to `MONGOCRYPT_CTX_ERROR` but
|
|
222
|
-
// otherwise we'll return `{ v: [] }`.
|
|
223
|
-
result = { v: [] } as any as T;
|
|
226
|
+
// See docs on EMPTY_V
|
|
227
|
+
result = EMPTY_V ??= serialize({ v: [] });
|
|
224
228
|
}
|
|
225
229
|
for await (const key of keys) {
|
|
226
230
|
context.addMongoOperationResponse(serialize(key));
|
|
@@ -252,7 +256,7 @@ export class StateMachine {
|
|
|
252
256
|
const message = context.status.message || 'Finalization error';
|
|
253
257
|
throw new MongoCryptError(message);
|
|
254
258
|
}
|
|
255
|
-
result =
|
|
259
|
+
result = finalizedContext;
|
|
256
260
|
break;
|
|
257
261
|
}
|
|
258
262
|
|
|
@@ -319,7 +323,7 @@ export class StateMachine {
|
|
|
319
323
|
|
|
320
324
|
const tlsOptions = this.options.tlsOptions;
|
|
321
325
|
if (tlsOptions) {
|
|
322
|
-
const kmsProvider = request.kmsProvider
|
|
326
|
+
const kmsProvider = request.kmsProvider;
|
|
323
327
|
const providerTlsOptions = tlsOptions[kmsProvider];
|
|
324
328
|
if (providerTlsOptions) {
|
|
325
329
|
const error = this.validateTlsOptions(kmsProvider, providerTlsOptions);
|