opusdev/vector-similarity-api
1
1import { AutoEncrypter, type AutoEncryptionOptions } from './client-side-encryption/auto_encrypter';2import { MONGO_CLIENT_EVENTS } from './constants';3import { getMongoDBClientEncryption } from './deps';4import { MongoInvalidArgumentError, MongoMissingDependencyError } from './error';5import { MongoClient, type MongoClientOptions } from './mongo_client';6 7/** @internal */8export interface EncrypterOptions {9 autoEncryption: AutoEncryptionOptions;10 maxPoolSize?: number;11}12 13/** @internal */14export class Encrypter {15 private internalClient: MongoClient | null;16 bypassAutoEncryption: boolean;17 needsConnecting: boolean;18 autoEncrypter: AutoEncrypter;19 20 constructor(client: MongoClient, uri: string, options: MongoClientOptions) {21 if (typeof options.autoEncryption !== 'object') {22 throw new MongoInvalidArgumentError('Option "autoEncryption" must be specified');23 }24 // initialize to null, if we call getInternalClient, we may set this it is important to not overwrite those function calls.25 this.internalClient = null;26 27 this.bypassAutoEncryption = !!options.autoEncryption.bypassAutoEncryption;28 this.needsConnecting = false;29 30 if (options.maxPoolSize === 0 && options.autoEncryption.keyVaultClient == null) {31 options.autoEncryption.keyVaultClient = client;32 } else if (options.autoEncryption.keyVaultClient == null) {33 options.autoEncryption.keyVaultClient = this.getInternalClient(client, uri, options);34 }35 36 if (this.bypassAutoEncryption) {37 options.autoEncryption.metadataClient = undefined;38 } else if (options.maxPoolSize === 0) {39 options.autoEncryption.metadataClient = client;40 } else {41 options.autoEncryption.metadataClient = this.getInternalClient(client, uri, options);42 }43 44 if (options.proxyHost) {45 options.autoEncryption.proxyOptions = {46 proxyHost: options.proxyHost,47 proxyPort: options.proxyPort,48 proxyUsername: options.proxyUsername,49 proxyPassword: options.proxyPassword50 };51 }52 53 this.autoEncrypter = new AutoEncrypter(client, options.autoEncryption);54 }55 56 getInternalClient(client: MongoClient, uri: string, options: MongoClientOptions): MongoClient {57 let internalClient = this.internalClient;58 if (internalClient == null) {59 const clonedOptions: MongoClientOptions = {};60 61 for (const key of [62 ...Object.getOwnPropertyNames(options),63 ...Object.getOwnPropertySymbols(options)64 ] as string[]) {65 if (['autoEncryption', 'minPoolSize', 'servers', 'caseTranslate', 'dbName'].includes(key))66 continue;67 Reflect.set(clonedOptions, key, Reflect.get(options, key));68 }69 70 clonedOptions.minPoolSize = 0;71 72 internalClient = new MongoClient(uri, clonedOptions);73 this.internalClient = internalClient;74 75 for (const eventName of MONGO_CLIENT_EVENTS) {76 for (const listener of client.listeners(eventName)) {77 internalClient.on(eventName, listener);78 }79 }80 81 client.on('newListener', (eventName, listener) => {82 internalClient?.on(eventName, listener);83 });84 85 this.needsConnecting = true;86 }87 return internalClient;88 }89 90 async connectInternalClient(): Promise<void> {91 const internalClient = this.internalClient;92 if (this.needsConnecting && internalClient != null) {93 this.needsConnecting = false;94 await internalClient.connect();95 }96 }97 98 async close(client: MongoClient): Promise<void> {99 let error;100 try {101 await this.autoEncrypter.close();102 } catch (autoEncrypterError) {103 error = autoEncrypterError;104 }105 const internalClient = this.internalClient;106 if (internalClient != null && client !== internalClient) {107 return await internalClient.close();108 }109 if (error != null) {110 throw error;111 }112 }113 114 static checkForMongoCrypt(): void {115 const mongodbClientEncryption = getMongoDBClientEncryption();116 if ('kModuleError' in mongodbClientEncryption) {117 throw new MongoMissingDependencyError(118 'Auto-encryption requested, but the module is not installed. ' +119 'Please add `mongodb-client-encryption` as a dependency of your project',120 {121 cause: mongodbClientEncryption['kModuleError'],122 dependencyName: 'mongodb-client-encryption'123 }124 );125 }126 }127}128 