From ec3847976e7cc3a842ae210eaedb09f2243618d8 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 21 Feb 2025 10:26:19 -0500 Subject: [PATCH 01/17] feat(NODE-6774): support $lookup on encrypted collections --- .gitignore | 1 + etc/bash_to_fish.mjs | 39 ++ src/client-side-encryption/state_machine.ts | 24 +- ...nt_side_encryption.prose.25.lookup.test.ts | 345 ++++++++++++++++++ .../etc/data/lookup/key-doc.json | 30 ++ .../etc/data/lookup/schema-csfle.json | 19 + .../etc/data/lookup/schema-csfle2.json | 19 + .../etc/data/lookup/schema-qe.json | 20 + .../etc/data/lookup/schema-qe2.json | 20 + 9 files changed, 504 insertions(+), 13 deletions(-) create mode 100644 etc/bash_to_fish.mjs create mode 100644 test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts create mode 100644 test/spec/client-side-encryption/etc/data/lookup/key-doc.json create mode 100644 test/spec/client-side-encryption/etc/data/lookup/schema-csfle.json create mode 100644 test/spec/client-side-encryption/etc/data/lookup/schema-csfle2.json create mode 100644 test/spec/client-side-encryption/etc/data/lookup/schema-qe.json create mode 100644 test/spec/client-side-encryption/etc/data/lookup/schema-qe2.json diff --git a/.gitignore b/.gitignore index f04e671f84f..d0fdc406efd 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,7 @@ test/lambda/env.json # files generated by tooling in drivers-evergreen-tools secrets-export.sh +secrets-export.fish mo-expansion.sh mo-expansion.yml expansions.sh diff --git a/etc/bash_to_fish.mjs b/etc/bash_to_fish.mjs new file mode 100644 index 00000000000..3f499180b1e --- /dev/null +++ b/etc/bash_to_fish.mjs @@ -0,0 +1,39 @@ +import { createReadStream, promises as fs } from 'node:fs'; +import path from 'node:path'; +import readline from 'node:readline/promises'; + +/** + * Takes an "exports" only bash script file + * and converts it to fish syntax. + * Will crash on any line that isn't: + * - a comment + * - an empty line + * - a bash 'set' call + * - export VAR=VAL + */ + +const fileName = process.argv[2]; +const outFileName = path.basename(fileName, '.sh') + '.fish'; +const input = createReadStream(process.argv[2]); +const lines = readline.createInterface({ input }); +const output = await fs.open(outFileName, 'w'); + +for await (let line of lines) { + line = line.trim(); + + if (!line.startsWith('export ')) { + if (line.startsWith('#')) continue; + if (line === '') continue; + if (line.startsWith('set')) continue; + throw new Error('Cannot translate: ' + line); + } + + const varVal = line.slice('export '.length); + const variable = varVal.slice(0, varVal.indexOf('=')); + const value = varVal.slice(varVal.indexOf('=') + 1); + output.appendFile(`set -x ${variable} ${value}\n`); +} + +output.close(); +input.close(); +lines.close(); diff --git a/src/client-side-encryption/state_machine.ts b/src/client-side-encryption/state_machine.ts index 096c4cfc635..982400326db 100644 --- a/src/client-side-encryption/state_machine.ts +++ b/src/client-side-encryption/state_machine.ts @@ -12,10 +12,12 @@ import { } from '../bson'; import { type ProxyOptions } from '../cmap/connection'; import { CursorTimeoutContext } from '../cursor/abstract_cursor'; +import { type ListCollectionsCursor } from '../cursor/list_collections_cursor'; import { getSocks, type SocksLib } from '../deps'; import { MongoOperationTimeoutError } from '../error'; import { type MongoClient, type MongoClientOptions } from '../mongo_client'; import { type Abortable } from '../mongo_types'; +import { type CollectionInfo } from '../operations/list_collections'; import { Timeout, type TimeoutContext, TimeoutError } from '../timeout'; import { addAbortListener, @@ -218,14 +220,15 @@ export class StateMachine { ); } - const collInfo = await this.fetchCollectionInfo( + const collInfoCursor = this.fetchCollectionInfo( metaDataClient, context.ns, filter, options ); - if (collInfo) { - context.addMongoOperationResponse(collInfo); + + for await (const collInfo of collInfoCursor) { + context.addMongoOperationResponse(serialize(collInfo)); } context.finishMongoOperation(); @@ -527,12 +530,12 @@ export class StateMachine { * @param filter - A filter for the listCollections command * @param callback - Invoked with the info of the requested collection, or with an error */ - async fetchCollectionInfo( + fetchCollectionInfo( client: MongoClient, ns: string, filter: Document, options?: { timeoutContext?: TimeoutContext } & Abortable - ): Promise { + ): ListCollectionsCursor { const { db } = MongoDBCollectionNamespace.fromString(ns); const cursor = client.db(db).listCollections(filter, { @@ -540,16 +543,11 @@ export class StateMachine { promoteValues: false, timeoutContext: options?.timeoutContext && new CursorTimeoutContext(options?.timeoutContext, Symbol()), - signal: options?.signal + signal: options?.signal, + nameOnly: false }); - // There is always exactly zero or one matching documents, so this should always exhaust the cursor - // in a single batch. We call `toArray()` just to be safe and ensure that the cursor is always - // exhausted and closed. - const collections = await cursor.toArray(); - - const info = collections.length > 0 ? serialize(collections[0]) : null; - return info; + return cursor; } /** diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts new file mode 100644 index 00000000000..a4327c0e4b7 --- /dev/null +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -0,0 +1,345 @@ +import * as fs from 'node:fs/promises'; +import * as path from 'node:path'; + +import { expect } from 'chai'; + +import { getCSFLEKMSProviders } from '../../csfle-kms-providers'; +import { BSON, type Document, type MongoClient } from '../../mongodb'; +import { type TestConfiguration } from '../../tools/runner/config'; +import { getEncryptExtraOptions } from '../../tools/utils'; + +const defaultMetadata: MongoDBMetadataUI = { + requires: { + topology: '!single', + clientSideEncryption: '>=6.3.0', + mongodb: '>=8.1.0' + } +}; + +const readFixture = async (name: string) => + BSON.EJSON.parse( + await fs.readFile( + path.resolve(__dirname, `../../spec/client-side-encryption/etc/data/lookup/${name}`), + 'utf8' + ) + ); + +const newEncryptedClient = ({ configuration }: { configuration: TestConfiguration }) => + configuration.newClient( + {}, + { + autoEncryption: { + keyVaultNamespace: 'db.keyvault', + kmsProviders: { local: getCSFLEKMSProviders().local }, + extraOptions: { + cryptSharedLibPath: getEncryptExtraOptions().cryptSharedLibPath, + mongocryptdBypassSpawn: true, + cryptSharedLibRequired: true + } + } + } + ); + +describe.only('$lookup support', function () { + before(async function () { + let client: MongoClient, encryptedClient: MongoClient; + try { + /** Create an unencrypted MongoClient. */ + client = this.configuration.newClient(); + /** Drop database db. */ + await client.db('db').dropDatabase(); + + /** Insert `key-doc.json` into db.keyvault. */ + const keyDoc = await readFixture('key-doc.json'); + await client.db('db').collection('keyvault').insertOne(keyDoc); + + /** + * Create the following collections: + * ``` + * db.csfle with options: { "validator": { "$jsonSchema": ""}}. + * db.csfle2 with options: { "validator": { "$jsonSchema": ""}}. + * db.qe with options: { "encryptedFields": ""}. + * db.qe2 with options: { "encryptedFields": ""}. + * db.no_schema with no options. + * db.no_schema2 with no options. + * ``` + */ + const collections = [ + { + name: 'csfle', + options: { validator: { $jsonSchema: await readFixture('schema-csfle.json') } }, + document: { csfle: 'csfle' } + }, + { + name: 'csfle2', + options: { validator: { $jsonSchema: await readFixture('schema-csfle2.json') } }, + document: { csfle2: 'csfle2' } + }, + { + name: 'qe', + options: { encryptedFields: await readFixture('schema-qe.json') }, + document: { qe: 'qe' } + }, + { + name: 'qe2', + options: { encryptedFields: await readFixture('schema-qe2.json') }, + document: { qe2: 'qe2' } + }, + { + name: 'no_schema', + options: {}, + document: { no_schema: 'no_schema' } + }, + { + name: 'no_schema2', + options: {}, + document: { no_schema2: 'no_schema2' } + } + ]; + + for (const { name, options } of collections) { + await client.db('db').createCollection(name, options); + } + + /** + * Create an encrypted MongoClient configured with: + * + * ```txt + * AutoEncryptionOpts( + * keyVaultNamespace="db.keyvault", + * kmsProviders={"local": { "key": "" }} + * ) + * ``` + */ + encryptedClient = newEncryptedClient(this); + + /** + * ``` + * {"csfle": "csfle"} into db.csfle + * Use the unencrypted client to retrieve it. Assert the csfle field is BSON binary. + * {"csfle2": "csfle2"} into db.csfle2 + * Use the unencrypted client to retrieve it. Assert the csfle2 field is BSON binary. + * {"qe": "qe"} into db.qe + * Use the unencrypted client to retrieve it. Assert the qe field is BSON binary. + * {"qe2": "qe2"} into db.qe2 + * Use the unencrypted client to retrieve it. Assert the qe2 field is BSON binary. + * {"no_schema": "no_schema"} into db.no_schema + * {"no_schema2": "no_schema2"} into db.no_schema2 + * ``` + */ + for (const { name, document } of collections) { + const { insertedId } = await encryptedClient.db('db').collection(name).insertOne(document); + + if (name.startsWith('no_')) continue; + + expect(await client.db('db').collection(name).findOne(insertedId)) + .to.have.property(Object.keys(document)[0]) + .that.has.property('_bsontype', 'Binary'); + } + } finally { + await client?.close(); + await encryptedClient?.close(); + } + }); + + const test = function ( + title: string, + collName: string, + pipeline: Document[], + expected: Document, + metadata?: MongoDBMetadataUI + ) { + describe(title.slice(0, title.indexOf(':')), function () { + let client: MongoClient; + + beforeEach(async function () { + Error.stackTraceLimit = 0; + client = newEncryptedClient(this); + }); + + afterEach(async function () { + await client.close(); + }); + + it(title.slice(title.indexOf(':') + 1).trim(), metadata ?? defaultMetadata, async () => { + const collection = client.db('db').collection(collName); + const actual = await collection + .aggregate(pipeline) + .toArray() + .catch(error => error); + + const expectedError = expected instanceof Error; + + if (expectedError) { + expect(actual).to.be.instanceOf(Error); + const expectedErrorMessage = new RegExp(expected.message, 'i'); + if (!expectedErrorMessage.test(actual.message)) { + throw actual; + } + } else if (actual instanceof Error) { + throw actual; + } else { + expect(actual).to.have.lengthOf(1); + expect(actual[0]).to.deep.equal(expected); + } + }); + }); + }; + + test( + 'Case 1: db.csfle joins db.no_schema', + 'csfle', + [ + { $match: { csfle: 'csfle' } }, + { + $lookup: { + from: 'no_schema', + as: 'matched', + pipeline: [{ $match: { no_schema: 'no_schema' } }, { $project: { _id: 0 } }] + } + }, + { $project: { _id: 0 } } + ], + { csfle: 'csfle', matched: [{ no_schema: 'no_schema' }] } + ); + + test( + 'Case 2: db.qe joins db.no_schema', + 'qe', + [ + { $match: { qe: 'qe' } }, + { + $lookup: { + from: 'no_schema', + as: 'matched', + pipeline: [ + { $match: { no_schema: 'no_schema' } }, + { $project: { _id: 0, __safeContent__: 0 } } + ] + } + }, + { $project: { _id: 0, __safeContent__: 0 } } + ], + { qe: 'qe', matched: [{ no_schema: 'no_schema' }] } + ); + + test( + 'Case 3: db.no_schema joins db.csfle', + 'no_schema', + [ + { $match: { no_schema: 'no_schema' } }, + { + $lookup: { + from: 'csfle', + as: 'matched', + pipeline: [{ $match: { csfle: 'csfle' } }, { $project: { _id: 0 } }] + } + }, + { $project: { _id: 0 } } + ], + { no_schema: 'no_schema', matched: [{ csfle: 'csfle' }] } + ); + + test( + 'Case 4: db.no_schema joins db.qe', + 'no_schema', + [ + { $match: { no_schema: 'no_schema' } }, + { + $lookup: { + from: 'qe', + as: 'matched', + pipeline: [{ $match: { qe: 'qe' } }, { $project: { _id: 0, __safeContent__: 0 } }] + } + }, + { $project: { _id: 0 } } + ], + { no_schema: 'no_schema', matched: [{ qe: 'qe' }] } + ); + + test( + 'Case 5: db.csfle joins db.csfle2', + 'csfle', + [ + { $match: { csfle: 'csfle' } }, + { + $lookup: { + from: 'csfle2', + as: 'matched', + pipeline: [{ $match: { csfle2: 'csfle2' } }, { $project: { _id: 0 } }] + } + }, + { $project: { _id: 0 } } + ], + { csfle: 'csfle', matched: [{ csfle2: 'csfle2' }] } + ); + + test( + 'Case 6: db.qe joins db.qe2', + 'qe', + [ + { $match: { qe: 'qe' } }, + { + $lookup: { + from: 'qe2', + as: 'matched', + pipeline: [{ $match: { qe2: 'qe2' } }, { $project: { _id: 0, __safeContent__: 0 } }] + } + }, + { $project: { _id: 0, __safeContent__: 0 } } + ], + { qe: 'qe', matched: [{ qe2: 'qe2' }] } + ); + + test( + 'Case 7: db.no_schema joins db.no_schema2', + 'no_schema', + [ + { $match: { no_schema: 'no_schema' } }, + { + $lookup: { + from: 'no_schema2', + as: 'matched', + pipeline: [{ $match: { no_schema2: 'no_schema2' } }, { $project: { _id: 0 } }] + } + }, + { $project: { _id: 0 } } + ], + { no_schema: 'no_schema', matched: [{ no_schema2: 'no_schema2' }] } + ); + + test( + 'Case 8: db.csfle joins db.qe', + 'csfle', + [ + { $match: { csfle: 'qe' } }, + { + $lookup: { + from: 'qe', + as: 'matched', + pipeline: [{ $match: { qe: 'qe' } }, { $project: { _id: 0 } }] + } + }, + { $project: { _id: 0 } } + ], + new Error('not supported') + ); + + test( + 'Case 9: db.csfle joins db.qe', + 'csfle', + [ + { $match: { csfle: 'csfle' } }, + { + $lookup: { + from: 'no_schema', + as: 'matched', + pipeline: [{ $match: { no_schema: 'no_schema' } }, { $project: { _id: 0 } }] + } + }, + { $project: { _id: 0 } } + ], + new Error('Upgrade'), + { requires: { ...defaultMetadata.requires, mongodb: '<8.1.0' } } + ); +}); diff --git a/test/spec/client-side-encryption/etc/data/lookup/key-doc.json b/test/spec/client-side-encryption/etc/data/lookup/key-doc.json new file mode 100644 index 00000000000..566b56c354f --- /dev/null +++ b/test/spec/client-side-encryption/etc/data/lookup/key-doc.json @@ -0,0 +1,30 @@ +{ + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } +} diff --git a/test/spec/client-side-encryption/etc/data/lookup/schema-csfle.json b/test/spec/client-side-encryption/etc/data/lookup/schema-csfle.json new file mode 100644 index 00000000000..29ac9ad5da4 --- /dev/null +++ b/test/spec/client-side-encryption/etc/data/lookup/schema-csfle.json @@ -0,0 +1,19 @@ +{ + "properties": { + "csfle": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" +} diff --git a/test/spec/client-side-encryption/etc/data/lookup/schema-csfle2.json b/test/spec/client-side-encryption/etc/data/lookup/schema-csfle2.json new file mode 100644 index 00000000000..3f1c02781c5 --- /dev/null +++ b/test/spec/client-side-encryption/etc/data/lookup/schema-csfle2.json @@ -0,0 +1,19 @@ +{ + "properties": { + "csfle2": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" +} diff --git a/test/spec/client-side-encryption/etc/data/lookup/schema-qe.json b/test/spec/client-side-encryption/etc/data/lookup/schema-qe.json new file mode 100644 index 00000000000..9428ea1b458 --- /dev/null +++ b/test/spec/client-side-encryption/etc/data/lookup/schema-qe.json @@ -0,0 +1,20 @@ +{ + "escCollection": "enxcol_.qe.esc", + "ecocCollection": "enxcol_.qe.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "qe", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ] +} diff --git a/test/spec/client-side-encryption/etc/data/lookup/schema-qe2.json b/test/spec/client-side-encryption/etc/data/lookup/schema-qe2.json new file mode 100644 index 00000000000..77d5bd37cbb --- /dev/null +++ b/test/spec/client-side-encryption/etc/data/lookup/schema-qe2.json @@ -0,0 +1,20 @@ +{ + "escCollection": "enxcol_.qe2.esc", + "ecocCollection": "enxcol_.qe2.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "qe2", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ] +} From 8ae45914e15d006b942f7a2365f0f6d34298dc72 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 21 Feb 2025 15:10:25 -0500 Subject: [PATCH 02/17] chore: add options --- src/client-side-encryption/auto_encrypter.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/client-side-encryption/auto_encrypter.ts b/src/client-side-encryption/auto_encrypter.ts index 1d7a9de4c66..f455a9eeb1a 100644 --- a/src/client-side-encryption/auto_encrypter.ts +++ b/src/client-side-encryption/auto_encrypter.ts @@ -239,6 +239,8 @@ export class AutoEncrypter { this._kmsProviders = options.kmsProviders || {}; const mongoCryptOptions: MongoCryptOptions = { + //@ts-expect-error: not yet in the defs + enableMultipleCollinfo: true, cryptoCallbacks }; if (options.schemaMap) { From 57ba430fbfb08b366cd633ec8a794dcbddbca62e Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 21 Feb 2025 15:46:39 -0500 Subject: [PATCH 03/17] test: multiple collection fails with a specific error when not enabled --- ...nt_side_encryption.prose.25.lookup.test.ts | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index a4327c0e4b7..1a4306b7446 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -2,9 +2,11 @@ import * as fs from 'node:fs/promises'; import * as path from 'node:path'; import { expect } from 'chai'; +import { type MongoCryptOptions } from 'mongodb-client-encryption'; +import * as sinon from 'sinon'; import { getCSFLEKMSProviders } from '../../csfle-kms-providers'; -import { BSON, type Document, type MongoClient } from '../../mongodb'; +import { AutoEncrypter, BSON, type Document, type MongoClient } from '../../mongodb'; import { type TestConfiguration } from '../../tools/runner/config'; import { getEncryptExtraOptions } from '../../tools/utils'; @@ -342,4 +344,70 @@ describe.only('$lookup support', function () { new Error('Upgrade'), { requires: { ...defaultMetadata.requires, mongodb: '<8.1.0' } } ); + + describe('Node.js custom test', function () { + describe('when enableMultipleCollinfo is off and a $lookup is run', function () { + let client: MongoClient; + + beforeEach(async function () { + const getMongoCrypt = sinon.stub(AutoEncrypter, 'getMongoCrypt').callsFake(function () { + const MongoCrypt = getMongoCrypt.wrappedMethod.call(this); + return class extends MongoCrypt { + constructor(options: MongoCryptOptions) { + //@ts-expect-error: not yet in the defs + options.enableMultipleCollinfo = false; + super(options); + } + }; + }); + + client = this.configuration.newClient( + {}, + { + autoEncryption: { + keyVaultNamespace: 'db.keyvault', + kmsProviders: { local: getCSFLEKMSProviders().local }, + extraOptions: { + cryptSharedLibPath: getEncryptExtraOptions().cryptSharedLibPath, + mongocryptdBypassSpawn: true, + cryptSharedLibRequired: true + } + } + } + ); + }); + + afterEach(async function () { + sinon.restore(); + await client.close(); + }); + + it( + 'throws a TypeError about libmongocrypt not enabled to support multiple collections', + defaultMetadata, + async () => { + const collection = client.db('db').collection('csfle'); + const actual = await collection + .aggregate([ + { $match: { csfle: 'csfle' } }, + { + $lookup: { + from: 'csfle2', + as: 'matched', + pipeline: [{ $match: { csfle2: 'csfle2' } }, { $project: { _id: 0 } }] + } + }, + { $project: { _id: 0 } } + ]) + .toArray() + .catch(error => error); + + expect(actual).to.be.instanceOf(TypeError); + expect(actual.message).to.match( + /libmongocrypt is not configured to support encrypting a command with multiple collections/i + ); + } + ); + }); + }); }); From 7e880c51fbd4c795ec39b31a8b6bcf2ab47e6412 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Mon, 24 Feb 2025 13:41:38 -0500 Subject: [PATCH 04/17] chore: fixes --- .../client_side_encryption.prose.25.lookup.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index 1a4306b7446..6556b62b8dd 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -42,7 +42,7 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio } ); -describe.only('$lookup support', function () { +describe('$lookup support', function () { before(async function () { let client: MongoClient, encryptedClient: MongoClient; try { @@ -155,7 +155,6 @@ describe.only('$lookup support', function () { let client: MongoClient; beforeEach(async function () { - Error.stackTraceLimit = 0; client = newEncryptedClient(this); }); @@ -354,6 +353,7 @@ describe.only('$lookup support', function () { const MongoCrypt = getMongoCrypt.wrappedMethod.call(this); return class extends MongoCrypt { constructor(options: MongoCryptOptions) { + expect(options).to.have.property('enableMultipleCollinfo', true); // assert invariant //@ts-expect-error: not yet in the defs options.enableMultipleCollinfo = false; super(options); From 7807e60656d606c824686e0d9d32730de67f0b87 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Mon, 24 Feb 2025 15:17:32 -0500 Subject: [PATCH 05/17] chore: try fixing tests --- src/client-side-encryption/state_machine.ts | 31 ++++++++++------- ...nt_side_encryption.prose.25.lookup.test.ts | 2 +- .../client-side-encryption/driver.test.ts | 21 ++++++++---- .../auto_encrypter.test.ts | 8 +++-- .../state_machine.test.ts | 33 ++++++++++++++----- 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/src/client-side-encryption/state_machine.ts b/src/client-side-encryption/state_machine.ts index 982400326db..8bf9f82db70 100644 --- a/src/client-side-encryption/state_machine.ts +++ b/src/client-side-encryption/state_machine.ts @@ -12,7 +12,6 @@ import { } from '../bson'; import { type ProxyOptions } from '../cmap/connection'; import { CursorTimeoutContext } from '../cursor/abstract_cursor'; -import { type ListCollectionsCursor } from '../cursor/list_collections_cursor'; import { getSocks, type SocksLib } from '../deps'; import { MongoOperationTimeoutError } from '../error'; import { type MongoClient, type MongoClientOptions } from '../mongo_client'; @@ -207,11 +206,19 @@ export class StateMachine { const mongocryptdManager = executor._mongocryptdManager; let result: Uint8Array | null = null; - while (context.state !== MONGOCRYPT_CTX_DONE && context.state !== MONGOCRYPT_CTX_ERROR) { + // Typescript treats getters just like properties: Once you've tested it for equality + // it cannot change. Which is exactly the opposite of what we use state and status for. + // Every call to at least `addMongoOperationResponse` and `finalize` can change the state. + // These wrappers let us write code more naturally and not add compiler exceptions + // to conditions checks inside the state machine. + const getStatus = () => context.status; + const getState = () => context.state; + + while (getState() !== MONGOCRYPT_CTX_DONE && getState() !== MONGOCRYPT_CTX_ERROR) { options.signal?.throwIfAborted(); - debug(`[context#${context.id}] ${stateToString.get(context.state) || context.state}`); + debug(`[context#${context.id}] ${stateToString.get(getState()) || getState()}`); - switch (context.state) { + switch (getState()) { case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: { const filter = deserialize(context.nextMongoOperation()); if (!metaDataClient) { @@ -229,8 +236,11 @@ export class StateMachine { for await (const collInfo of collInfoCursor) { context.addMongoOperationResponse(serialize(collInfo)); + if (getState() === MONGOCRYPT_CTX_ERROR) break; } + if (getState() === MONGOCRYPT_CTX_ERROR) break; + context.finishMongoOperation(); break; } @@ -286,9 +296,8 @@ export class StateMachine { case MONGOCRYPT_CTX_READY: { const finalizedContext = context.finalize(); - // @ts-expect-error finalize can change the state, check for error - if (context.state === MONGOCRYPT_CTX_ERROR) { - const message = context.status.message || 'Finalization error'; + if (getState() === MONGOCRYPT_CTX_ERROR) { + const message = getStatus().message || 'Finalization error'; throw new MongoCryptError(message); } result = finalizedContext; @@ -296,12 +305,12 @@ export class StateMachine { } default: - throw new MongoCryptError(`Unknown state: ${context.state}`); + throw new MongoCryptError(`Unknown state: ${getState()}`); } } - if (context.state === MONGOCRYPT_CTX_ERROR || result == null) { - const message = context.status.message; + if (getState() === MONGOCRYPT_CTX_ERROR || result == null) { + const message = getStatus().message; if (!message) { debug( `unidentifiable error in MongoCrypt - received an error status from \`libmongocrypt\` but received no error message.` @@ -535,7 +544,7 @@ export class StateMachine { ns: string, filter: Document, options?: { timeoutContext?: TimeoutContext } & Abortable - ): ListCollectionsCursor { + ): AsyncIterable { const { db } = MongoDBCollectionNamespace.fromString(ns); const cursor = client.db(db).listCollections(filter, { diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index 6556b62b8dd..f5ae53109dd 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -42,7 +42,7 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio } ); -describe('$lookup support', function () { +describe('$lookup support', defaultMetadata, function () { before(async function () { let client: MongoClient, encryptedClient: MongoClient; try { diff --git a/test/integration/client-side-encryption/driver.test.ts b/test/integration/client-side-encryption/driver.test.ts index 991b93491d5..8862b6ac41a 100644 --- a/test/integration/client-side-encryption/driver.test.ts +++ b/test/integration/client-side-encryption/driver.test.ts @@ -1047,11 +1047,19 @@ describe('CSOT', function () { }); it('the command should fail due to a timeout error', metadata, async function () { - const { duration, result: error } = await measureDuration(() => - stateMachine - .fetchCollectionInfo(encryptedClient, 'test.test', { a: 1 }, timeoutContext()) - .catch(e => e) - ); + const { duration, result: error } = await measureDuration(async () => { + try { + const cursor = stateMachine.fetchCollectionInfo( + encryptedClient, + 'test.test', + { a: 1 }, + timeoutContext() + ); + for await (const doc of cursor) void doc; + } catch (error) { + return error; + } + }); expect(error).to.be.instanceOf(MongoOperationTimeoutError); expect(duration).to.be.within(timeoutMS - 100, timeoutMS + 100); }); @@ -1074,7 +1082,8 @@ describe('CSOT', function () { }); it('the command succeeds', metadata, async function () { - await stateMachine.fetchCollectionInfo(encryptedClient, 'test.test', { a: 1 }); + const cursor = stateMachine.fetchCollectionInfo(encryptedClient, 'test.test', { a: 1 }); + for await (const doc of cursor) void doc; }); } ); diff --git a/test/unit/client-side-encryption/auto_encrypter.test.ts b/test/unit/client-side-encryption/auto_encrypter.test.ts index 79bc321b802..f249e311e6f 100644 --- a/test/unit/client-side-encryption/auto_encrypter.test.ts +++ b/test/unit/client-side-encryption/auto_encrypter.test.ts @@ -11,7 +11,7 @@ import { MongocryptdManager } from '../../../src/client-side-encryption/mongocry import { StateMachine } from '../../../src/client-side-encryption/state_machine'; // eslint-disable-next-line @typescript-eslint/no-restricted-imports import { MongoClient } from '../../../src/mongo_client'; -import { BSON, type DataKey } from '../../mongodb'; +import { BSON, type DataKey, type Db, ListCollectionsCursor } from '../../mongodb'; import * as requirements from './requirements.helper'; const bson = BSON; @@ -63,7 +63,11 @@ describe('AutoEncrypter', function () { return Promise.resolve(); }); - sandbox.stub(StateMachine.prototype, 'fetchCollectionInfo').resolves(MOCK_COLLINFO_RESPONSE); + sandbox.stub(StateMachine.prototype, 'fetchCollectionInfo').returns( + (async function* () { + while (true) yield MOCK_COLLINFO_RESPONSE; + })() + ); sandbox.stub(StateMachine.prototype, 'markCommand').callsFake(() => { if (ENABLE_LOG_TEST) { diff --git a/test/unit/client-side-encryption/state_machine.test.ts b/test/unit/client-side-encryption/state_machine.test.ts index 3d6a92765a8..1f43b57007b 100644 --- a/test/unit/client-side-encryption/state_machine.test.ts +++ b/test/unit/client-side-encryption/state_machine.test.ts @@ -580,11 +580,21 @@ describe('StateMachine', function () { serverSelectionTimeoutMS: 30000 }); await sleep(300); - await stateMachine - .fetchCollectionInfo(client, 'keyVault', BSON.serialize({ a: 1 }), { - timeoutContext: context - }) - .catch(e => squashError(e)); + + try { + const cursor = stateMachine.fetchCollectionInfo( + client, + 'keyVault', + BSON.serialize({ a: 1 }), + { + timeoutContext: context + } + ); + for await (const doc of cursor) void doc; + } catch { + // ignore + } + const [_filter, { timeoutContext }] = listCollectionsSpy.getCalls()[0].args; expect(timeoutContext).to.exist; expect(timeoutContext.timeoutContext).to.equal(context); @@ -596,9 +606,16 @@ describe('StateMachine', function () { 'when StateMachine.fetchCollectionInfo() is not passed a `CSOTimeoutContext`', function () { it('no timeoutContext is provided to listCollections', async function () { - await stateMachine - .fetchCollectionInfo(client, 'keyVault', BSON.serialize({ a: 1 })) - .catch(e => squashError(e)); + try { + const cursor = stateMachine.fetchCollectionInfo( + client, + 'keyVault', + BSON.serialize({ a: 1 }) + ); + for await (const doc of cursor) void doc; + } catch { + // ignore + } const [_filter, { timeoutContext }] = listCollectionsSpy.getCalls()[0].args; expect(timeoutContext).not.to.exist; }); From 2abcda4566e58e261da555119c7f5ee21f55c0bc Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Mon, 24 Feb 2025 15:39:47 -0500 Subject: [PATCH 06/17] chore: version filter --- ...nt_side_encryption.prose.25.lookup.test.ts | 9 ++++++ test/tools/runner/config.ts | 7 +++++ test/tools/runner/hooks/configuration.ts | 30 ++++++++++--------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index f5ae53109dd..d246e83d8e2 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -2,6 +2,7 @@ import * as fs from 'node:fs/promises'; import * as path from 'node:path'; import { expect } from 'chai'; +import { type Test } from 'mocha'; import { type MongoCryptOptions } from 'mongodb-client-encryption'; import * as sinon from 'sinon'; @@ -44,6 +45,14 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio describe('$lookup support', defaultMetadata, function () { before(async function () { + if ( + this.configuration.filters.MongoDBVersionFilter.filter({ + metadata: defaultMetadata + } as unknown as Test) + ) { + return; + } + let client: MongoClient, encryptedClient: MongoClient; try { /** Create an unencrypted MongoClient. */ diff --git a/test/tools/runner/config.ts b/test/tools/runner/config.ts index 96d1f677a66..5385ace8cc2 100644 --- a/test/tools/runner/config.ts +++ b/test/tools/runner/config.ts @@ -13,6 +13,7 @@ import { type WriteConcernSettings } from '../../mongodb'; import { getEnvironmentalOptions } from '../utils'; +import { type Filter } from './filters/filter'; interface ProxyParams { proxyHost?: string; @@ -85,6 +86,7 @@ export class TestConfiguration { serverApi?: ServerApi; activeResources: number; isSrv: boolean; + filters: Record; constructor( private uri: string, @@ -129,6 +131,11 @@ export class TestConfiguration { password: url.password }; } + + this.filters = Object.fromEntries( + context.filters.map(filter => [filter.constructor.name, filter]) + ); + if (context.serverlessCredentials) { const { username, password } = context.serverlessCredentials; this.options.auth = { username, password, authSource: 'admin' }; diff --git a/test/tools/runner/hooks/configuration.ts b/test/tools/runner/hooks/configuration.ts index ee31fc506f3..d6c4100f339 100644 --- a/test/tools/runner/hooks/configuration.ts +++ b/test/tools/runner/hooks/configuration.ts @@ -51,20 +51,22 @@ async function initializeFilters(client): Promise> { return {}; } initializedFilters = true; - const context = {}; - - for (const filter of [ - new ApiVersionFilter(), - new AuthFilter(), - new ClientSideEncryptionFilter(), - new GenericPredicateFilter(), - new IDMSMockServerFilter(), - new MongoDBTopologyFilter(), - new MongoDBVersionFilter(), - new NodeVersionFilter(), - new OSFilter(), - new ServerlessFilter() - ]) { + const context = { + filters: [ + new ApiVersionFilter(), + new AuthFilter(), + new ClientSideEncryptionFilter(), + new GenericPredicateFilter(), + new IDMSMockServerFilter(), + new MongoDBTopologyFilter(), + new MongoDBVersionFilter(), + new NodeVersionFilter(), + new OSFilter(), + new ServerlessFilter() + ] + }; + + for (const filter of context.filters) { filters.push(filter); await filter.initializeFilter(client, context); } From 9925881a5d75199fc3ad7fb4738ec91ca6bb78d6 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Mon, 24 Feb 2025 15:49:41 -0500 Subject: [PATCH 07/17] chore: lint --- test/unit/client-side-encryption/auto_encrypter.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/client-side-encryption/auto_encrypter.test.ts b/test/unit/client-side-encryption/auto_encrypter.test.ts index f249e311e6f..0fbe95e8eea 100644 --- a/test/unit/client-side-encryption/auto_encrypter.test.ts +++ b/test/unit/client-side-encryption/auto_encrypter.test.ts @@ -11,7 +11,7 @@ import { MongocryptdManager } from '../../../src/client-side-encryption/mongocry import { StateMachine } from '../../../src/client-side-encryption/state_machine'; // eslint-disable-next-line @typescript-eslint/no-restricted-imports import { MongoClient } from '../../../src/mongo_client'; -import { BSON, type DataKey, type Db, ListCollectionsCursor } from '../../mongodb'; +import { BSON, type DataKey } from '../../mongodb'; import * as requirements from './requirements.helper'; const bson = BSON; From 47faa6fd93227fcc281f9f77eab19ff971097b2e Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Mon, 24 Feb 2025 16:06:32 -0500 Subject: [PATCH 08/17] chore: wrong filter --- .../client_side_encryption.prose.25.lookup.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index d246e83d8e2..9d439af1717 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -46,7 +46,7 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio describe('$lookup support', defaultMetadata, function () { before(async function () { if ( - this.configuration.filters.MongoDBVersionFilter.filter({ + !this.configuration.filters.MongoDBVersionFilter.filter({ metadata: defaultMetadata } as unknown as Test) ) { From bfaf9b82f8efc6c40c2fe02a5893a6f6288d74b1 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Mon, 24 Feb 2025 16:24:07 -0500 Subject: [PATCH 09/17] chore: more metadata --- ...ent_side_encryption.prose.25.lookup.test.ts | 18 +++++++++++++----- test/integration/crud/crud.prose.test.ts | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index 9d439af1717..936ec87d547 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -45,11 +45,19 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio describe('$lookup support', defaultMetadata, function () { before(async function () { - if ( - !this.configuration.filters.MongoDBVersionFilter.filter({ - metadata: defaultMetadata - } as unknown as Test) - ) { + const mochaTest = { + metadata: defaultMetadata + } as unknown as Test; + + if (!this.configuration.filters.MongoDBVersionFilter.filter(mochaTest)) { + return; + } + + if (!this.configuration.filters.MongoDBTopologyFilter.filter(mochaTest)) { + return; + } + + if (!this.configuration.filters.ClientSideEncryptionFilter.filter(mochaTest)) { return; } diff --git a/test/integration/crud/crud.prose.test.ts b/test/integration/crud/crud.prose.test.ts index 8a0d80cc139..0823dcf5d60 100644 --- a/test/integration/crud/crud.prose.test.ts +++ b/test/integration/crud/crud.prose.test.ts @@ -1032,7 +1032,7 @@ describe('CRUD Prose Spec Tests', () => { }); afterEach(async function () { - await client.close(); + await client?.close(); }); it('raises a client side error', async function () { From aedae0c41f635773953d715e54943b19fb1892a0 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Tue, 25 Feb 2025 10:05:37 -0500 Subject: [PATCH 10/17] chore: run on cryptd too --- src/client-side-encryption/state_machine.ts | 2 ++ ...nt_side_encryption.prose.25.lookup.test.ts | 30 ++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/client-side-encryption/state_machine.ts b/src/client-side-encryption/state_machine.ts index 8bf9f82db70..c45fdf1f093 100644 --- a/src/client-side-encryption/state_machine.ts +++ b/src/client-side-encryption/state_machine.ts @@ -247,6 +247,8 @@ export class StateMachine { case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: { const command = context.nextMongoOperation(); + if (getState() === MONGOCRYPT_CTX_ERROR) break; + if (!mongocryptdClient) { throw new MongoCryptError( 'unreachable state machine state: entered MONGOCRYPT_CTX_NEED_MONGO_MARKINGS but mongocryptdClient is undefined' diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index 936ec87d547..3e2ca983370 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -34,11 +34,7 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio autoEncryption: { keyVaultNamespace: 'db.keyvault', kmsProviders: { local: getCSFLEKMSProviders().local }, - extraOptions: { - cryptSharedLibPath: getEncryptExtraOptions().cryptSharedLibPath, - mongocryptdBypassSpawn: true, - cryptSharedLibRequired: true - } + extraOptions: getEncryptExtraOptions() } } ); @@ -366,6 +362,22 @@ describe('$lookup support', defaultMetadata, function () { let client: MongoClient; beforeEach(async function () { + const mochaTest = { + metadata: defaultMetadata + } as unknown as Test; + + if (!this.configuration.filters.MongoDBVersionFilter.filter(mochaTest)) { + return; + } + + if (!this.configuration.filters.MongoDBTopologyFilter.filter(mochaTest)) { + return; + } + + if (!this.configuration.filters.ClientSideEncryptionFilter.filter(mochaTest)) { + return; + } + const getMongoCrypt = sinon.stub(AutoEncrypter, 'getMongoCrypt').callsFake(function () { const MongoCrypt = getMongoCrypt.wrappedMethod.call(this); return class extends MongoCrypt { @@ -384,11 +396,7 @@ describe('$lookup support', defaultMetadata, function () { autoEncryption: { keyVaultNamespace: 'db.keyvault', kmsProviders: { local: getCSFLEKMSProviders().local }, - extraOptions: { - cryptSharedLibPath: getEncryptExtraOptions().cryptSharedLibPath, - mongocryptdBypassSpawn: true, - cryptSharedLibRequired: true - } + extraOptions: getEncryptExtraOptions() } } ); @@ -396,7 +404,7 @@ describe('$lookup support', defaultMetadata, function () { afterEach(async function () { sinon.restore(); - await client.close(); + await client?.close(); }); it( From e7ec664107047e8993f1d2c6e30dfb10769f2aa9 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Tue, 25 Feb 2025 15:16:12 -0500 Subject: [PATCH 11/17] chore: fix stub --- .../client-side-encryption/auto_encrypter.test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/unit/client-side-encryption/auto_encrypter.test.ts b/test/unit/client-side-encryption/auto_encrypter.test.ts index 0fbe95e8eea..496ca728d3e 100644 --- a/test/unit/client-side-encryption/auto_encrypter.test.ts +++ b/test/unit/client-side-encryption/auto_encrypter.test.ts @@ -63,11 +63,12 @@ describe('AutoEncrypter', function () { return Promise.resolve(); }); - sandbox.stub(StateMachine.prototype, 'fetchCollectionInfo').returns( - (async function* () { - while (true) yield MOCK_COLLINFO_RESPONSE; - })() - ); + const iterator = (async function* () { + yield BSON.deserialize(MOCK_COLLINFO_RESPONSE); + yield BSON.deserialize(MOCK_COLLINFO_RESPONSE); + yield BSON.deserialize(MOCK_COLLINFO_RESPONSE); + })(); + sandbox.stub(StateMachine.prototype, 'fetchCollectionInfo').returns(iterator); sandbox.stub(StateMachine.prototype, 'markCommand').callsFake(() => { if (ENABLE_LOG_TEST) { From d7089c2c07c58e8cb6a89271f467cd9e98397a2a Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 27 Feb 2025 09:44:51 -0500 Subject: [PATCH 12/17] chore: await append --- etc/bash_to_fish.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/bash_to_fish.mjs b/etc/bash_to_fish.mjs index 3f499180b1e..09cfe054110 100644 --- a/etc/bash_to_fish.mjs +++ b/etc/bash_to_fish.mjs @@ -31,7 +31,7 @@ for await (let line of lines) { const varVal = line.slice('export '.length); const variable = varVal.slice(0, varVal.indexOf('=')); const value = varVal.slice(varVal.indexOf('=') + 1); - output.appendFile(`set -x ${variable} ${value}\n`); + await output.appendFile(`set -x ${variable} ${value}\n`); } output.close(); From 227b90492eb88d6449afc2554dcaca42765f7dde Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 27 Feb 2025 13:05:59 -0500 Subject: [PATCH 13/17] chore: comments --- ...nt_side_encryption.prose.25.lookup.test.ts | 95 +++++++++---------- .../client_side_encryption.prose.test.js | 4 +- .../client_side_encryption.spec.test.ts | 19 +--- test/tools/runner/filters/filter.ts | 4 +- test/tools/spec-runner/index.js | 7 +- 5 files changed, 53 insertions(+), 76 deletions(-) diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index 3e2ca983370..556588f38d1 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -2,7 +2,6 @@ import * as fs from 'node:fs/promises'; import * as path from 'node:path'; import { expect } from 'chai'; -import { type Test } from 'mocha'; import { type MongoCryptOptions } from 'mongodb-client-encryption'; import * as sinon from 'sinon'; @@ -15,7 +14,7 @@ const defaultMetadata: MongoDBMetadataUI = { requires: { topology: '!single', clientSideEncryption: '>=6.3.0', - mongodb: '>=8.1.0' + mongodb: '>=7.0.0' } }; @@ -31,6 +30,7 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio configuration.newClient( {}, { + writeConcern: { w: 'majority' }, autoEncryption: { keyVaultNamespace: 'db.keyvault', kmsProviders: { local: getCSFLEKMSProviders().local }, @@ -41,9 +41,7 @@ const newEncryptedClient = ({ configuration }: { configuration: TestConfiguratio describe('$lookup support', defaultMetadata, function () { before(async function () { - const mochaTest = { - metadata: defaultMetadata - } as unknown as Test; + const mochaTest = { metadata: defaultMetadata }; if (!this.configuration.filters.MongoDBVersionFilter.filter(mochaTest)) { return; @@ -57,16 +55,26 @@ describe('$lookup support', defaultMetadata, function () { return; } - let client: MongoClient, encryptedClient: MongoClient; + let unencryptedClient: MongoClient, encryptedClient: MongoClient; try { - /** Create an unencrypted MongoClient. */ - client = this.configuration.newClient(); + /** + * Create an encrypted MongoClient configured with: + * + * ```txt + * AutoEncryptionOpts( + * keyVaultNamespace="db.keyvault", + * kmsProviders={"local": { "key": "" }} + * ) + * ``` + */ + encryptedClient = newEncryptedClient(this); + /** Drop database db. */ - await client.db('db').dropDatabase(); + await encryptedClient.db('db').dropDatabase(); /** Insert `key-doc.json` into db.keyvault. */ const keyDoc = await readFixture('key-doc.json'); - await client.db('db').collection('keyvault').insertOne(keyDoc); + await encryptedClient.db('db').collection('keyvault').insertOne(keyDoc); /** * Create the following collections: @@ -113,20 +121,11 @@ describe('$lookup support', defaultMetadata, function () { ]; for (const { name, options } of collections) { - await client.db('db').createCollection(name, options); + await encryptedClient.db('db').createCollection(name, options); } - /** - * Create an encrypted MongoClient configured with: - * - * ```txt - * AutoEncryptionOpts( - * keyVaultNamespace="db.keyvault", - * kmsProviders={"local": { "key": "" }} - * ) - * ``` - */ - encryptedClient = newEncryptedClient(this); + /** Create an unencrypted MongoClient. */ + unencryptedClient = this.configuration.newClient({}, { writeConcern: { w: 'majority' } }); /** * ``` @@ -147,12 +146,12 @@ describe('$lookup support', defaultMetadata, function () { if (name.startsWith('no_')) continue; - expect(await client.db('db').collection(name).findOne(insertedId)) + expect(await unencryptedClient.db('db').collection(name).findOne(insertedId)) .to.have.property(Object.keys(document)[0]) .that.has.property('_bsontype', 'Binary'); } } finally { - await client?.close(); + await unencryptedClient?.close(); await encryptedClient?.close(); } }); @@ -161,7 +160,7 @@ describe('$lookup support', defaultMetadata, function () { title: string, collName: string, pipeline: Document[], - expected: Document, + expected: Document | RegExp, metadata?: MongoDBMetadataUI ) { describe(title.slice(0, title.indexOf(':')), function () { @@ -182,12 +181,11 @@ describe('$lookup support', defaultMetadata, function () { .toArray() .catch(error => error); - const expectedError = expected instanceof Error; + const expectedError = expected instanceof RegExp; if (expectedError) { expect(actual).to.be.instanceOf(Error); - const expectedErrorMessage = new RegExp(expected.message, 'i'); - if (!expectedErrorMessage.test(actual.message)) { + if (!expected.test(actual.message)) { throw actual; } } else if (actual instanceof Error) { @@ -214,7 +212,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0 } } ], - { csfle: 'csfle', matched: [{ no_schema: 'no_schema' }] } + { csfle: 'csfle', matched: [{ no_schema: 'no_schema' }] }, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -234,7 +233,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0, __safeContent__: 0 } } ], - { qe: 'qe', matched: [{ no_schema: 'no_schema' }] } + { qe: 'qe', matched: [{ no_schema: 'no_schema' }] }, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -251,7 +251,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0 } } ], - { no_schema: 'no_schema', matched: [{ csfle: 'csfle' }] } + { no_schema: 'no_schema', matched: [{ csfle: 'csfle' }] }, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -268,7 +269,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0 } } ], - { no_schema: 'no_schema', matched: [{ qe: 'qe' }] } + { no_schema: 'no_schema', matched: [{ qe: 'qe' }] }, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -285,7 +287,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0 } } ], - { csfle: 'csfle', matched: [{ csfle2: 'csfle2' }] } + { csfle: 'csfle', matched: [{ csfle2: 'csfle2' }] }, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -302,7 +305,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0, __safeContent__: 0 } } ], - { qe: 'qe', matched: [{ qe2: 'qe2' }] } + { qe: 'qe', matched: [{ qe2: 'qe2' }] }, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -319,7 +323,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0 } } ], - { no_schema: 'no_schema', matched: [{ no_schema2: 'no_schema2' }] } + { no_schema: 'no_schema', matched: [{ no_schema2: 'no_schema2' }] }, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -336,7 +341,8 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0 } } ], - new Error('not supported') + /not supported/i, + { requires: { ...defaultMetadata.requires, mongodb: '>=8.1.0' } } ); test( @@ -353,7 +359,7 @@ describe('$lookup support', defaultMetadata, function () { }, { $project: { _id: 0 } } ], - new Error('Upgrade'), + /Upgrade/i, { requires: { ...defaultMetadata.requires, mongodb: '<8.1.0' } } ); @@ -362,9 +368,7 @@ describe('$lookup support', defaultMetadata, function () { let client: MongoClient; beforeEach(async function () { - const mochaTest = { - metadata: defaultMetadata - } as unknown as Test; + const mochaTest = { metadata: defaultMetadata }; if (!this.configuration.filters.MongoDBVersionFilter.filter(mochaTest)) { return; @@ -390,16 +394,7 @@ describe('$lookup support', defaultMetadata, function () { }; }); - client = this.configuration.newClient( - {}, - { - autoEncryption: { - keyVaultNamespace: 'db.keyvault', - kmsProviders: { local: getCSFLEKMSProviders().local }, - extraOptions: getEncryptExtraOptions() - } - } - ); + client = newEncryptedClient(this); }); afterEach(async function () { diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.test.js b/test/integration/client-side-encryption/client_side_encryption.prose.test.js index afbb83b7a8a..92b6c3f9939 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.test.js +++ b/test/integration/client-side-encryption/client_side_encryption.prose.test.js @@ -1703,9 +1703,7 @@ describe('Client Side Encryption Prose Tests', metadata, function () { context('Case 6: named KMS providers apply TLS options', function () { afterEach(() => keyvaultClient?.close()); beforeEach(async function () { - const filter = new ClientSideEncryptionFilter(); - await filter.initializeFilter({}, {}); - const shouldSkip = filter.filter({ + const shouldSkip = this.configuration.filters.ClientSideEncryptionFilter.filter({ metadata: { requires: { // 6.0.1 includes libmongocrypt 1.10. diff --git a/test/integration/client-side-encryption/client_side_encryption.spec.test.ts b/test/integration/client-side-encryption/client_side_encryption.spec.test.ts index 36b20f4460d..58fe5bb19bc 100644 --- a/test/integration/client-side-encryption/client_side_encryption.spec.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.spec.test.ts @@ -1,7 +1,6 @@ import * as path from 'path'; import { loadSpecTests } from '../../spec'; -import { ClientSideEncryptionFilter } from '../../tools/runner/filters/client_encryption_filter'; import { gatherTestSuites, generateTopologyTests, @@ -60,8 +59,6 @@ const SKIPPED_TESTS = new Set([ const isServerless = !!process.env.SERVERLESS; -const filter = new ClientSideEncryptionFilter(); - describe('Client Side Encryption (Legacy)', function () { const testContext = new TestRunnerContext({ requiresCSFLE: true }); const testSuites = gatherTestSuites( @@ -75,11 +72,7 @@ describe('Client Side Encryption (Legacy)', function () { return testContext.setup(this.configuration); }); - before(async function () { - await filter.initializeFilter({} as any, {}); - }); - - generateTopologyTests(testSuites, testContext, test => { + generateTopologyTests(testSuites, testContext, (test, configuration) => { const { description } = test; if (SKIPPED_TESTS.has(description)) { return 'Skipped by generic test name skip filter.'; @@ -109,7 +102,7 @@ describe('Client Side Encryption (Legacy)', function () { 'Automatically encrypt and decrypt with a named KMS provider' ].includes(description) ) { - const result = filter.filter({ + const result = configuration.filters.ClientSideEncryptionFilter.filter({ metadata: { requires: { clientSideEncryption: '>=6.0.1' } } }); @@ -121,13 +114,9 @@ describe('Client Side Encryption (Legacy)', function () { }); describe('Client Side Encryption (Unified)', function () { - before(async function () { - await filter.initializeFilter({} as any, {}); - }); - runUnifiedSuite( loadSpecTests(path.join('client-side-encryption', 'tests', 'unified')), - ({ description }) => { + ({ description }, configuration) => { const delegatedKMIPTests = [ 'rewrap with current KMS provider', 'rewrap with new local KMS provider', @@ -154,7 +143,7 @@ describe('Client Side Encryption (Unified)', function () { 'can explicitly encrypt with a named KMS provider' ]; if (delegatedKMIPTests.includes(description)) { - const shouldSkip = filter.filter({ + const shouldSkip = configuration.filters.ClientSideEncryptionFilter.filter({ metadata: { requires: { clientSideEncryption: '>=6.0.1' } } }); if (typeof shouldSkip === 'string') return shouldSkip; diff --git a/test/tools/runner/filters/filter.ts b/test/tools/runner/filters/filter.ts index b03ad83d5e9..6251cf44c8c 100644 --- a/test/tools/runner/filters/filter.ts +++ b/test/tools/runner/filters/filter.ts @@ -1,5 +1,3 @@ -import { type Test } from 'mocha'; - import { type MongoClient } from '../../../mongodb'; export abstract class Filter { @@ -7,5 +5,5 @@ export abstract class Filter { return; } - abstract filter(test: Test): string | boolean; + abstract filter(test: { metadata?: MongoDBMetadataUI }): string | boolean; } diff --git a/test/tools/spec-runner/index.js b/test/tools/spec-runner/index.js index f312990137c..62ee50ff71e 100644 --- a/test/tools/spec-runner/index.js +++ b/test/tools/spec-runner/index.js @@ -15,7 +15,6 @@ const { HEARTBEAT_EVENTS } = require('../../mongodb'); const { isAnyRequirementSatisfied } = require('../unified-spec-runner/unified-utils'); -const { ClientSideEncryptionFilter } = require('../runner/filters/client_encryption_filter'); const { getCSFLEKMSProviders } = require('../../csfle-kms-providers'); // Promise.try alternative https://stackoverflow.com/questions/60624081/promise-try-without-bluebird/60624164?noredirect=1#comment107255389_60624164 @@ -153,7 +152,7 @@ function legacyRunOnToRunOnRequirement(runOn) { } /** - * @param {((test: { description: string }) => true | string)?} filter a function that returns true for any tests that should run, false otherwise. + * @param {((test: { description: string }, configuration: TestConfiguration) => true | string)?} filter a function that returns true for any tests that should run, false otherwise. */ function generateTopologyTests(testSuites, testContext, filter) { for (const testSuite of testSuites) { @@ -198,10 +197,8 @@ function generateTopologyTests(testSuites, testContext, filter) { let csfleFilterError = null; if (shouldRun && testContext.requiresCSFLE) { - const csfleFilter = new ClientSideEncryptionFilter(); - await csfleFilter.initializeFilter(null, {}); try { - const filterResult = csfleFilter.filter({ + const filterResult = this.configuration.filters.ClientSideEncryptionFilter.filter({ metadata: { requires: { clientSideEncryption: true } } }); if (typeof filterResult === 'string') { From a36087095ecaee9576728fc48e9e4e0aac449c4c Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 27 Feb 2025 13:22:18 -0500 Subject: [PATCH 14/17] chore: bump package --- package-lock.json | 195 +++++++++--------- package.json | 2 +- src/client-side-encryption/auto_encrypter.ts | 1 - .../client_side_encryption.prose.test.js | 3 - 4 files changed, 95 insertions(+), 106 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea9ce112329..c434bcf8262 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "js-yaml": "^4.1.0", "mocha": "^10.8.2", "mocha-sinon": "^2.1.2", - "mongodb-client-encryption": "^6.2.0", + "mongodb-client-encryption": "^6.3.0", "mongodb-legacy": "^6.1.3", "nyc": "^15.1.0", "prettier": "^3.4.2", @@ -1146,9 +1146,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1451,9 +1451,9 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.50.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.50.0.tgz", - "integrity": "sha512-Ds/PHTiVzuENQsmXrJKkSdfgNkr/SDG/2rDef0AWl3BchAnXdO7gXaYsAkNx4gWiC4OngNA3fQfd3+BcQxP1DQ==", + "version": "7.51.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.51.0.tgz", + "integrity": "sha512-LjyQ2xljliss2kIsSo8Npu9mBv6wnaR3ikBagCU2mC7Ggn30sTAOFLzVNyMLOMiuSOFxsEbskrBO5lLn92qnZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1469,7 +1469,7 @@ "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "5.7.2" + "typescript": "5.7.3" }, "bin": { "api-extractor": "bin/api-extractor" @@ -1517,9 +1517,9 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2062,9 +2062,9 @@ } }, "node_modules/@smithy/core": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.4.tgz", - "integrity": "sha512-wFExFGK+7r2wYriOqe7RRIBNpvxwiS95ih09+GSLRBdoyK/O1uZA7K7pKesj5CBvwJuSBeXwLyR88WwIAY+DGA==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.5.tgz", + "integrity": "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2073,7 +2073,7 @@ "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", - "@smithy/util-stream": "^4.1.1", + "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -2174,13 +2174,13 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.5.tgz", - "integrity": "sha512-cPzGZV7qStHwboFrm6GfrzQE+YDiCzWcTh4+7wKrP/ZQ4gkw+r7qDjV8GjM4N0UYsuUyLfpzLGg5hxsYTU11WA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.6.tgz", + "integrity": "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.1.4", + "@smithy/core": "^3.1.5", "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", @@ -2194,16 +2194,16 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.6.tgz", - "integrity": "sha512-s8QzuOQnbdvRymD9Gt9c9zMq10wUQAHQ3z72uirrBHCwZcLTrL5iCOuVTMdka2IXOYhQE890WD5t6G24+F+Qcg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.7.tgz", + "integrity": "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/service-error-classification": "^4.0.1", - "@smithy/smithy-client": "^4.1.5", + "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", @@ -2259,9 +2259,9 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.2.tgz", - "integrity": "sha512-X66H9aah9hisLLSnGuzRYba6vckuFtGE+a5DcHLliI/YlqKrGoxhisD5XbX44KyoeRzoNlGr94eTsMVHFAzPOw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.3.tgz", + "integrity": "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2380,18 +2380,18 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.5.tgz", - "integrity": "sha512-DMXYoYeL4QkElr216n1yodTFeATbfb4jwYM9gKn71Rw/FNA1/Sm36tkTSCsZEs7mgpG3OINmkxL9vgVFzyGPaw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.6.tgz", + "integrity": "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.1.4", - "@smithy/middleware-endpoint": "^4.0.5", + "@smithy/core": "^3.1.5", + "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", - "@smithy/util-stream": "^4.1.1", + "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" }, "engines": { @@ -2495,14 +2495,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.6.tgz", - "integrity": "sha512-N8+VCt+piupH1A7DgSVDNrVHqRLz8r6DvBkpS7EWHiIxsUk4jqGuQLjqC/gnCzmwGkVBdNruHoYAzzaSQ8e80w==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.7.tgz", + "integrity": "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q==", "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.5", + "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -2512,9 +2512,9 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.6.tgz", - "integrity": "sha512-9zhx1shd1VwSSVvLZB8CM3qQ3RPD3le7A3h/UPuyh/PC7g4OaWDi2xUNzamsVoSmCGtmUBONl56lM2EU6LcH7A==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.7.tgz", + "integrity": "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2522,7 +2522,7 @@ "@smithy/credential-provider-imds": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.5", + "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, @@ -2588,14 +2588,14 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.1.tgz", - "integrity": "sha512-+Xvh8nhy0Wjv1y71rBVyV3eJU3356XsFQNI8dEZVNrQju7Eib8G31GWtO+zMa9kTCGd41Mflu+ZKfmQL/o2XzQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.2.tgz", + "integrity": "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", - "@smithy/node-http-handler": "^4.0.2", + "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", @@ -2718,13 +2718,11 @@ } }, "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -2806,9 +2804,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.13.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", - "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==", + "version": "22.13.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", + "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", "dev": true, "license": "MIT", "dependencies": { @@ -2884,9 +2882,9 @@ } }, "node_modules/@types/sinon": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", - "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "version": "17.0.4", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", + "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==", "dev": true, "license": "MIT", "dependencies": { @@ -3735,9 +3733,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001700", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", - "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", + "version": "1.0.30001701", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001701.tgz", + "integrity": "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==", "dev": true, "funding": [ { @@ -4204,9 +4202,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.102", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz", - "integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==", + "version": "1.5.107", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.107.tgz", + "integrity": "sha512-dJr1o6yCntRkXElnhsHh1bAV19bo/hKyFf7tCcWgpXbuFIF0Lakjgqv5LRfSDaNzAII8Fnxg2tqgHkgCvxdbxw==", "dev": true, "license": "ISC" }, @@ -4413,17 +4411,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-formatter-pretty/node_modules/@types/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, "node_modules/eslint-plugin-mocha": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.5.0.tgz", @@ -4919,9 +4906,9 @@ } }, "node_modules/fastq": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", - "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -5226,18 +5213,18 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -6646,21 +6633,21 @@ } }, "node_modules/mongodb": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.0.tgz", - "integrity": "sha512-KeESYR5TEaFxOuwRqkOm3XOsMqCSkdeDMjaW5u2nuKfX7rqaofp7JQGoi7sVqQcNJTKuveNbzZtWMstb8ABP6Q==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.1.tgz", + "integrity": "sha512-gdq40tX8StmhP6akMp1pPoEVv+9jTYFSrga/g23JxajPAQhH39ysZrHGzQCSd9PEOnuEQEdjIWqxO7ZSwC0w7Q==", "dev": true, "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "^6.10.1", + "bson": "^6.10.3", "mongodb-connection-string-url": "^3.0.0" }, "engines": { "node": ">=16.20.1" }, "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", + "@aws-sdk/credential-providers": "^3.632.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", @@ -6693,9 +6680,9 @@ } }, "node_modules/mongodb-client-encryption": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/mongodb-client-encryption/-/mongodb-client-encryption-6.2.0.tgz", - "integrity": "sha512-jfOCthPH0jxd9RJCerNbf1aRAcUJFwiWikJ2j9oBPRc+Oets3aKUriyZe4n16sF3Ibc1xar1zNInAfHEcVtYRg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/mongodb-client-encryption/-/mongodb-client-encryption-6.3.0.tgz", + "integrity": "sha512-OaOg02vglPxxrfY01alC0ER0W4WMuNO2ZJR3ehAUcuGYreJaJ+aX+rUQiQkdQHiXvnVPDUx/4QDr2CR1/FvpcQ==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -7505,9 +7492,9 @@ } }, "node_modules/prettier": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz", - "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz", + "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==", "dev": true, "license": "MIT", "bin": { @@ -7975,9 +7962,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -8641,10 +8628,16 @@ } }, "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT" }, "node_modules/supports-color": { @@ -9124,9 +9117,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index fb7f68574b4..1e5a8b1f394 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "js-yaml": "^4.1.0", "mocha": "^10.8.2", "mocha-sinon": "^2.1.2", - "mongodb-client-encryption": "^6.2.0", + "mongodb-client-encryption": "^6.3.0", "mongodb-legacy": "^6.1.3", "nyc": "^15.1.0", "prettier": "^3.4.2", diff --git a/src/client-side-encryption/auto_encrypter.ts b/src/client-side-encryption/auto_encrypter.ts index f455a9eeb1a..a24f8cd6da6 100644 --- a/src/client-side-encryption/auto_encrypter.ts +++ b/src/client-side-encryption/auto_encrypter.ts @@ -239,7 +239,6 @@ export class AutoEncrypter { this._kmsProviders = options.kmsProviders || {}; const mongoCryptOptions: MongoCryptOptions = { - //@ts-expect-error: not yet in the defs enableMultipleCollinfo: true, cryptoCallbacks }; diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.test.js b/test/integration/client-side-encryption/client_side_encryption.prose.test.js index 92b6c3f9939..0e773654ec7 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.test.js +++ b/test/integration/client-side-encryption/client_side_encryption.prose.test.js @@ -16,9 +16,6 @@ const { } = require('../../spec/client-side-encryption/external/external-schema.json'); /* eslint-disable no-restricted-modules */ const { ClientEncryption } = require('../../../src/client-side-encryption/client_encryption'); -const { - ClientSideEncryptionFilter -} = require('../../tools/runner/filters/client_encryption_filter'); const { getCSFLEKMSProviders } = require('../../csfle-kms-providers'); const { AlpineTestConfiguration } = require('../../tools/runner/config'); From e371fd91863a06ef733260c44b1355e001929b31 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 27 Feb 2025 13:52:33 -0500 Subject: [PATCH 15/17] fix lock file --- package-lock.json | 187 ++++++++++++++++++++++++---------------------- 1 file changed, 97 insertions(+), 90 deletions(-) diff --git a/package-lock.json b/package-lock.json index c434bcf8262..fa56b4aa307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1146,9 +1146,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", - "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "license": "MIT", "dependencies": { @@ -1451,9 +1451,9 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.51.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.51.0.tgz", - "integrity": "sha512-LjyQ2xljliss2kIsSo8Npu9mBv6wnaR3ikBagCU2mC7Ggn30sTAOFLzVNyMLOMiuSOFxsEbskrBO5lLn92qnZQ==", + "version": "7.50.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.50.0.tgz", + "integrity": "sha512-Ds/PHTiVzuENQsmXrJKkSdfgNkr/SDG/2rDef0AWl3BchAnXdO7gXaYsAkNx4gWiC4OngNA3fQfd3+BcQxP1DQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1469,7 +1469,7 @@ "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "5.7.3" + "typescript": "5.7.2" }, "bin": { "api-extractor": "bin/api-extractor" @@ -1517,9 +1517,9 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2062,9 +2062,9 @@ } }, "node_modules/@smithy/core": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.5.tgz", - "integrity": "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.4.tgz", + "integrity": "sha512-wFExFGK+7r2wYriOqe7RRIBNpvxwiS95ih09+GSLRBdoyK/O1uZA7K7pKesj5CBvwJuSBeXwLyR88WwIAY+DGA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2073,7 +2073,7 @@ "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", - "@smithy/util-stream": "^4.1.2", + "@smithy/util-stream": "^4.1.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" }, @@ -2174,13 +2174,13 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.6.tgz", - "integrity": "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.5.tgz", + "integrity": "sha512-cPzGZV7qStHwboFrm6GfrzQE+YDiCzWcTh4+7wKrP/ZQ4gkw+r7qDjV8GjM4N0UYsuUyLfpzLGg5hxsYTU11WA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.1.5", + "@smithy/core": "^3.1.4", "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", @@ -2194,16 +2194,16 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.7.tgz", - "integrity": "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.6.tgz", + "integrity": "sha512-s8QzuOQnbdvRymD9Gt9c9zMq10wUQAHQ3z72uirrBHCwZcLTrL5iCOuVTMdka2IXOYhQE890WD5t6G24+F+Qcg==", "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/service-error-classification": "^4.0.1", - "@smithy/smithy-client": "^4.1.6", + "@smithy/smithy-client": "^4.1.5", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", @@ -2259,9 +2259,9 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.3.tgz", - "integrity": "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.2.tgz", + "integrity": "sha512-X66H9aah9hisLLSnGuzRYba6vckuFtGE+a5DcHLliI/YlqKrGoxhisD5XbX44KyoeRzoNlGr94eTsMVHFAzPOw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2380,18 +2380,18 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.6.tgz", - "integrity": "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.5.tgz", + "integrity": "sha512-DMXYoYeL4QkElr216n1yodTFeATbfb4jwYM9gKn71Rw/FNA1/Sm36tkTSCsZEs7mgpG3OINmkxL9vgVFzyGPaw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.1.5", - "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/core": "^3.1.4", + "@smithy/middleware-endpoint": "^4.0.5", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", - "@smithy/util-stream": "^4.1.2", + "@smithy/util-stream": "^4.1.1", "tslib": "^2.6.2" }, "engines": { @@ -2495,14 +2495,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.7.tgz", - "integrity": "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.6.tgz", + "integrity": "sha512-N8+VCt+piupH1A7DgSVDNrVHqRLz8r6DvBkpS7EWHiIxsUk4jqGuQLjqC/gnCzmwGkVBdNruHoYAzzaSQ8e80w==", "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.6", + "@smithy/smithy-client": "^4.1.5", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" @@ -2512,9 +2512,9 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.7.tgz", - "integrity": "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.6.tgz", + "integrity": "sha512-9zhx1shd1VwSSVvLZB8CM3qQ3RPD3le7A3h/UPuyh/PC7g4OaWDi2xUNzamsVoSmCGtmUBONl56lM2EU6LcH7A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2522,7 +2522,7 @@ "@smithy/credential-provider-imds": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.6", + "@smithy/smithy-client": "^4.1.5", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, @@ -2588,14 +2588,14 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.2.tgz", - "integrity": "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.1.tgz", + "integrity": "sha512-+Xvh8nhy0Wjv1y71rBVyV3eJU3356XsFQNI8dEZVNrQju7Eib8G31GWtO+zMa9kTCGd41Mflu+ZKfmQL/o2XzQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", - "@smithy/node-http-handler": "^4.0.3", + "@smithy/node-http-handler": "^4.0.2", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", @@ -2718,11 +2718,13 @@ } }, "node_modules/@types/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -2804,9 +2806,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.13.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", - "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", + "version": "22.13.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz", + "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==", "dev": true, "license": "MIT", "dependencies": { @@ -2882,9 +2884,9 @@ } }, "node_modules/@types/sinon": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", - "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, "license": "MIT", "dependencies": { @@ -3733,9 +3735,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001701", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001701.tgz", - "integrity": "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==", + "version": "1.0.30001700", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", + "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", "dev": true, "funding": [ { @@ -4202,9 +4204,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.107", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.107.tgz", - "integrity": "sha512-dJr1o6yCntRkXElnhsHh1bAV19bo/hKyFf7tCcWgpXbuFIF0Lakjgqv5LRfSDaNzAII8Fnxg2tqgHkgCvxdbxw==", + "version": "1.5.102", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz", + "integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==", "dev": true, "license": "ISC" }, @@ -4411,6 +4413,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint-formatter-pretty/node_modules/@types/eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, "node_modules/eslint-plugin-mocha": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.5.0.tgz", @@ -4906,9 +4919,9 @@ } }, "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", + "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==", "dev": true, "license": "ISC", "dependencies": { @@ -5213,18 +5226,18 @@ } }, "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", + "call-bind-apply-helpers": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "get-proto": "^1.0.1", + "get-proto": "^1.0.0", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -6633,21 +6646,21 @@ } }, "node_modules/mongodb": { - "version": "6.13.1", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.1.tgz", - "integrity": "sha512-gdq40tX8StmhP6akMp1pPoEVv+9jTYFSrga/g23JxajPAQhH39ysZrHGzQCSd9PEOnuEQEdjIWqxO7ZSwC0w7Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.13.0.tgz", + "integrity": "sha512-KeESYR5TEaFxOuwRqkOm3XOsMqCSkdeDMjaW5u2nuKfX7rqaofp7JQGoi7sVqQcNJTKuveNbzZtWMstb8ABP6Q==", "dev": true, "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "^6.10.3", + "bson": "^6.10.1", "mongodb-connection-string-url": "^3.0.0" }, "engines": { "node": ">=16.20.1" }, "peerDependencies": { - "@aws-sdk/credential-providers": "^3.632.0", + "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", @@ -7492,9 +7505,9 @@ } }, "node_modules/prettier": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz", - "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz", + "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==", "dev": true, "license": "MIT", "bin": { @@ -7962,9 +7975,9 @@ } }, "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "license": "MIT", "engines": { @@ -8628,16 +8641,10 @@ } }, "node_modules/strnum": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], "license": "MIT" }, "node_modules/supports-color": { @@ -9117,9 +9124,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "dev": true, "funding": [ { From 6cd6ea4b185efc91a1c0b782e232ad8eb2b46438 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 27 Feb 2025 14:07:32 -0500 Subject: [PATCH 16/17] fix: copy pasta --- test/unit/client-side-encryption/auto_encrypter.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/unit/client-side-encryption/auto_encrypter.test.ts b/test/unit/client-side-encryption/auto_encrypter.test.ts index 496ca728d3e..816b3a6cb93 100644 --- a/test/unit/client-side-encryption/auto_encrypter.test.ts +++ b/test/unit/client-side-encryption/auto_encrypter.test.ts @@ -65,8 +65,6 @@ describe('AutoEncrypter', function () { const iterator = (async function* () { yield BSON.deserialize(MOCK_COLLINFO_RESPONSE); - yield BSON.deserialize(MOCK_COLLINFO_RESPONSE); - yield BSON.deserialize(MOCK_COLLINFO_RESPONSE); })(); sandbox.stub(StateMachine.prototype, 'fetchCollectionInfo').returns(iterator); From a0e96d2ec3f961aee97ed17df4002c5ed7e62707 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 27 Feb 2025 14:09:54 -0500 Subject: [PATCH 17/17] chore: case 9 name and version --- .../client_side_encryption.prose.25.lookup.test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts index 556588f38d1..d4365ac6d6d 100644 --- a/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts +++ b/test/integration/client-side-encryption/client_side_encryption.prose.25.lookup.test.ts @@ -346,7 +346,7 @@ describe('$lookup support', defaultMetadata, function () { ); test( - 'Case 9: db.csfle joins db.qe', + 'Case 9: test error with <8.1', 'csfle', [ { $match: { csfle: 'csfle' } }, @@ -360,7 +360,7 @@ describe('$lookup support', defaultMetadata, function () { { $project: { _id: 0 } } ], /Upgrade/i, - { requires: { ...defaultMetadata.requires, mongodb: '<8.1.0' } } + { requires: { ...defaultMetadata.requires, mongodb: '>=7.0.0 <8.1.0' } } ); describe('Node.js custom test', function () { @@ -387,7 +387,6 @@ describe('$lookup support', defaultMetadata, function () { return class extends MongoCrypt { constructor(options: MongoCryptOptions) { expect(options).to.have.property('enableMultipleCollinfo', true); // assert invariant - //@ts-expect-error: not yet in the defs options.enableMultipleCollinfo = false; super(options); }