deps.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. /* eslint-disable @typescript-eslint/no-var-requires */
  2. import type { Document } from './bson';
  3. import type { ProxyOptions } from './cmap/connection';
  4. import { MongoMissingDependencyError } from './error';
  5. import type { MongoClient } from './mongo_client';
  6. import type { Callback } from './utils';
  7. function makeErrorModule(error: any) {
  8. const props = error ? { kModuleError: error } : {};
  9. return new Proxy(props, {
  10. get: (_: any, key: any) => {
  11. if (key === 'kModuleError') {
  12. return error;
  13. }
  14. throw error;
  15. },
  16. set: () => {
  17. throw error;
  18. }
  19. });
  20. }
  21. export let Kerberos: typeof import('kerberos') | { kModuleError: MongoMissingDependencyError } =
  22. makeErrorModule(
  23. new MongoMissingDependencyError(
  24. 'Optional module `kerberos` not found. Please install it to enable kerberos authentication'
  25. )
  26. );
  27. export function getKerberos(): typeof Kerberos | { kModuleError: MongoMissingDependencyError } {
  28. try {
  29. // Ensure you always wrap an optional require in the try block NODE-3199
  30. Kerberos = require('kerberos');
  31. return Kerberos;
  32. } catch {
  33. return Kerberos;
  34. }
  35. }
  36. export interface KerberosClient {
  37. step(challenge: string): Promise<string>;
  38. step(challenge: string, callback: Callback<string>): void;
  39. wrap(challenge: string, options: { user: string }): Promise<string>;
  40. wrap(challenge: string, options: { user: string }, callback: Callback<string>): void;
  41. unwrap(challenge: string): Promise<string>;
  42. unwrap(challenge: string, callback: Callback<string>): void;
  43. }
  44. type ZStandardLib = {
  45. /**
  46. * Compress using zstd.
  47. * @param buf - Buffer to be compressed.
  48. */
  49. compress(buf: Buffer, level?: number): Promise<Buffer>;
  50. /**
  51. * Decompress using zstd.
  52. */
  53. decompress(buf: Buffer): Promise<Buffer>;
  54. };
  55. export let ZStandard: ZStandardLib | { kModuleError: MongoMissingDependencyError } =
  56. makeErrorModule(
  57. new MongoMissingDependencyError(
  58. 'Optional module `@mongodb-js/zstd` not found. Please install it to enable zstd compression'
  59. )
  60. );
  61. export function getZstdLibrary(): typeof ZStandard | { kModuleError: MongoMissingDependencyError } {
  62. try {
  63. ZStandard = require('@mongodb-js/zstd');
  64. return ZStandard;
  65. } catch {
  66. return ZStandard;
  67. }
  68. }
  69. /**
  70. * @internal
  71. * Copy of the AwsCredentialIdentityProvider interface from [`smithy/types`](https://socket.dev/npm/package/\@smithy/types/files/1.1.1/dist-types/identity/awsCredentialIdentity.d.ts),
  72. * the return type of the aws-sdk's `fromNodeProviderChain().provider()`.
  73. */
  74. export interface AWSCredentials {
  75. accessKeyId: string;
  76. secretAccessKey: string;
  77. sessionToken: string;
  78. expiration?: Date;
  79. }
  80. type CredentialProvider = {
  81. fromNodeProviderChain(
  82. this: void,
  83. options: { clientConfig: { region: string } }
  84. ): () => Promise<AWSCredentials>;
  85. fromNodeProviderChain(this: void): () => Promise<AWSCredentials>;
  86. };
  87. export function getAwsCredentialProvider():
  88. | CredentialProvider
  89. | { kModuleError: MongoMissingDependencyError } {
  90. try {
  91. // Ensure you always wrap an optional require in the try block NODE-3199
  92. const credentialProvider = require('@aws-sdk/credential-providers');
  93. return credentialProvider;
  94. } catch {
  95. return makeErrorModule(
  96. new MongoMissingDependencyError(
  97. 'Optional module `@aws-sdk/credential-providers` not found.' +
  98. ' Please install it to enable getting aws credentials via the official sdk.'
  99. )
  100. );
  101. }
  102. }
  103. /** @internal */
  104. export type SnappyLib = {
  105. /**
  106. * In order to support both we must check the return value of the function
  107. * @param buf - Buffer to be compressed
  108. */
  109. compress(buf: Buffer): Promise<Buffer>;
  110. /**
  111. * In order to support both we must check the return value of the function
  112. * @param buf - Buffer to be compressed
  113. */
  114. uncompress(buf: Buffer, opt: { asBuffer: true }): Promise<Buffer>;
  115. };
  116. export function getSnappy(): SnappyLib | { kModuleError: MongoMissingDependencyError } {
  117. try {
  118. // Ensure you always wrap an optional require in the try block NODE-3199
  119. const value = require('snappy');
  120. return value;
  121. } catch (cause) {
  122. const kModuleError = new MongoMissingDependencyError(
  123. 'Optional module `snappy` not found. Please install it to enable snappy compression',
  124. { cause }
  125. );
  126. return { kModuleError };
  127. }
  128. }
  129. export let saslprep:
  130. | typeof import('@mongodb-js/saslprep')
  131. | { kModuleError: MongoMissingDependencyError } = makeErrorModule(
  132. new MongoMissingDependencyError(
  133. 'Optional module `saslprep` not found.' +
  134. ' Please install it to enable Stringprep Profile for User Names and Passwords'
  135. )
  136. );
  137. try {
  138. // Ensure you always wrap an optional require in the try block NODE-3199
  139. saslprep = require('@mongodb-js/saslprep');
  140. } catch {} // eslint-disable-line
  141. interface AWS4 {
  142. /**
  143. * Created these inline types to better assert future usage of this API
  144. * @param options - options for request
  145. * @param credentials - AWS credential details, sessionToken should be omitted entirely if its false-y
  146. */
  147. sign(
  148. this: void,
  149. options: {
  150. path: '/';
  151. body: string;
  152. host: string;
  153. method: 'POST';
  154. headers: {
  155. 'Content-Type': 'application/x-www-form-urlencoded';
  156. 'Content-Length': number;
  157. 'X-MongoDB-Server-Nonce': string;
  158. 'X-MongoDB-GS2-CB-Flag': 'n';
  159. };
  160. service: string;
  161. region: string;
  162. },
  163. credentials:
  164. | {
  165. accessKeyId: string;
  166. secretAccessKey: string;
  167. sessionToken: string;
  168. }
  169. | {
  170. accessKeyId: string;
  171. secretAccessKey: string;
  172. }
  173. | undefined
  174. ): {
  175. headers: {
  176. Authorization: string;
  177. 'X-Amz-Date': string;
  178. };
  179. };
  180. }
  181. export let aws4: AWS4 | { kModuleError: MongoMissingDependencyError } = makeErrorModule(
  182. new MongoMissingDependencyError(
  183. 'Optional module `aws4` not found. Please install it to enable AWS authentication'
  184. )
  185. );
  186. try {
  187. // Ensure you always wrap an optional require in the try block NODE-3199
  188. aws4 = require('aws4');
  189. } catch {} // eslint-disable-line
  190. /** @public */
  191. export const AutoEncryptionLoggerLevel = Object.freeze({
  192. FatalError: 0,
  193. Error: 1,
  194. Warning: 2,
  195. Info: 3,
  196. Trace: 4
  197. } as const);
  198. /** @public */
  199. export type AutoEncryptionLoggerLevel =
  200. (typeof AutoEncryptionLoggerLevel)[keyof typeof AutoEncryptionLoggerLevel];
  201. /** @public */
  202. export interface AutoEncryptionTlsOptions {
  203. /**
  204. * Specifies the location of a local .pem file that contains
  205. * either the client's TLS/SSL certificate and key or only the
  206. * client's TLS/SSL key when tlsCertificateFile is used to
  207. * provide the certificate.
  208. */
  209. tlsCertificateKeyFile?: string;
  210. /**
  211. * Specifies the password to de-crypt the tlsCertificateKeyFile.
  212. */
  213. tlsCertificateKeyFilePassword?: string;
  214. /**
  215. * Specifies the location of a local .pem file that contains the
  216. * root certificate chain from the Certificate Authority.
  217. * This file is used to validate the certificate presented by the
  218. * KMS provider.
  219. */
  220. tlsCAFile?: string;
  221. }
  222. /** @public */
  223. export interface AutoEncryptionOptions {
  224. /** @internal client for metadata lookups */
  225. metadataClient?: MongoClient;
  226. /** A `MongoClient` used to fetch keys from a key vault */
  227. keyVaultClient?: MongoClient;
  228. /** The namespace where keys are stored in the key vault */
  229. keyVaultNamespace?: string;
  230. /** Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. */
  231. kmsProviders?: {
  232. /** Configuration options for using 'aws' as your KMS provider */
  233. aws?:
  234. | {
  235. /** The access key used for the AWS KMS provider */
  236. accessKeyId: string;
  237. /** The secret access key used for the AWS KMS provider */
  238. secretAccessKey: string;
  239. /**
  240. * An optional AWS session token that will be used as the
  241. * X-Amz-Security-Token header for AWS requests.
  242. */
  243. sessionToken?: string;
  244. }
  245. | Record<string, never>;
  246. /** Configuration options for using 'local' as your KMS provider */
  247. local?: {
  248. /**
  249. * The master key used to encrypt/decrypt data keys.
  250. * A 96-byte long Buffer or base64 encoded string.
  251. */
  252. key: Buffer | string;
  253. };
  254. /** Configuration options for using 'azure' as your KMS provider */
  255. azure?:
  256. | {
  257. /** The tenant ID identifies the organization for the account */
  258. tenantId: string;
  259. /** The client ID to authenticate a registered application */
  260. clientId: string;
  261. /** The client secret to authenticate a registered application */
  262. clientSecret: string;
  263. /**
  264. * If present, a host with optional port. E.g. "example.com" or "example.com:443".
  265. * This is optional, and only needed if customer is using a non-commercial Azure instance
  266. * (e.g. a government or China account, which use different URLs).
  267. * Defaults to "login.microsoftonline.com"
  268. */
  269. identityPlatformEndpoint?: string | undefined;
  270. }
  271. | {
  272. /**
  273. * If present, an access token to authenticate with Azure.
  274. */
  275. accessToken: string;
  276. }
  277. | Record<string, never>;
  278. /** Configuration options for using 'gcp' as your KMS provider */
  279. gcp?:
  280. | {
  281. /** The service account email to authenticate */
  282. email: string;
  283. /** A PKCS#8 encrypted key. This can either be a base64 string or a binary representation */
  284. privateKey: string | Buffer;
  285. /**
  286. * If present, a host with optional port. E.g. "example.com" or "example.com:443".
  287. * Defaults to "oauth2.googleapis.com"
  288. */
  289. endpoint?: string | undefined;
  290. }
  291. | {
  292. /**
  293. * If present, an access token to authenticate with GCP.
  294. */
  295. accessToken: string;
  296. }
  297. | Record<string, never>;
  298. /**
  299. * Configuration options for using 'kmip' as your KMS provider
  300. */
  301. kmip?: {
  302. /**
  303. * The output endpoint string.
  304. * The endpoint consists of a hostname and port separated by a colon.
  305. * E.g. "example.com:123". A port is always present.
  306. */
  307. endpoint?: string;
  308. };
  309. };
  310. /**
  311. * A map of namespaces to a local JSON schema for encryption
  312. *
  313. * **NOTE**: Supplying options.schemaMap provides more security than relying on JSON Schemas obtained from the server.
  314. * It protects against a malicious server advertising a false JSON Schema, which could trick the client into sending decrypted data that should be encrypted.
  315. * Schemas supplied in the schemaMap only apply to configuring automatic encryption for Client-Side Field Level Encryption.
  316. * Other validation rules in the JSON schema will not be enforced by the driver and will result in an error.
  317. */
  318. schemaMap?: Document;
  319. /** Supply a schema for the encrypted fields in the document */
  320. encryptedFieldsMap?: Document;
  321. /** Allows the user to bypass auto encryption, maintaining implicit decryption */
  322. bypassAutoEncryption?: boolean;
  323. /** Allows users to bypass query analysis */
  324. bypassQueryAnalysis?: boolean;
  325. options?: {
  326. /** An optional hook to catch logging messages from the underlying encryption engine */
  327. logger?: (level: AutoEncryptionLoggerLevel, message: string) => void;
  328. };
  329. extraOptions?: {
  330. /**
  331. * A local process the driver communicates with to determine how to encrypt values in a command.
  332. * Defaults to "mongodb://%2Fvar%2Fmongocryptd.sock" if domain sockets are available or "mongodb://localhost:27020" otherwise
  333. */
  334. mongocryptdURI?: string;
  335. /** If true, autoEncryption will not attempt to spawn a mongocryptd before connecting */
  336. mongocryptdBypassSpawn?: boolean;
  337. /** The path to the mongocryptd executable on the system */
  338. mongocryptdSpawnPath?: string;
  339. /** Command line arguments to use when auto-spawning a mongocryptd */
  340. mongocryptdSpawnArgs?: string[];
  341. /**
  342. * Full path to a MongoDB Crypt shared library to be used (instead of mongocryptd).
  343. *
  344. * This needs to be the path to the file itself, not a directory.
  345. * It can be an absolute or relative path. If the path is relative and
  346. * its first component is `$ORIGIN`, it will be replaced by the directory
  347. * containing the mongodb-client-encryption native addon file. Otherwise,
  348. * the path will be interpreted relative to the current working directory.
  349. *
  350. * Currently, loading different MongoDB Crypt shared library files from different
  351. * MongoClients in the same process is not supported.
  352. *
  353. * If this option is provided and no MongoDB Crypt shared library could be loaded
  354. * from the specified location, creating the MongoClient will fail.
  355. *
  356. * If this option is not provided and `cryptSharedLibRequired` is not specified,
  357. * the AutoEncrypter will attempt to spawn and/or use mongocryptd according
  358. * to the mongocryptd-specific `extraOptions` options.
  359. *
  360. * Specifying a path prevents mongocryptd from being used as a fallback.
  361. *
  362. * Requires the MongoDB Crypt shared library, available in MongoDB 6.0 or higher.
  363. */
  364. cryptSharedLibPath?: string;
  365. /**
  366. * If specified, never use mongocryptd and instead fail when the MongoDB Crypt
  367. * shared library could not be loaded.
  368. *
  369. * This is always true when `cryptSharedLibPath` is specified.
  370. *
  371. * Requires the MongoDB Crypt shared library, available in MongoDB 6.0 or higher.
  372. */
  373. cryptSharedLibRequired?: boolean;
  374. /**
  375. * Search paths for a MongoDB Crypt shared library to be used (instead of mongocryptd)
  376. * Only for driver testing!
  377. * @internal
  378. */
  379. cryptSharedLibSearchPaths?: string[];
  380. };
  381. proxyOptions?: ProxyOptions;
  382. /** The TLS options to use connecting to the KMS provider */
  383. tlsOptions?: {
  384. aws?: AutoEncryptionTlsOptions;
  385. local?: AutoEncryptionTlsOptions;
  386. azure?: AutoEncryptionTlsOptions;
  387. gcp?: AutoEncryptionTlsOptions;
  388. kmip?: AutoEncryptionTlsOptions;
  389. };
  390. }
  391. /**
  392. * @public
  393. * @deprecated This interface will be removed in the next major version.
  394. */
  395. export interface AutoEncrypter {
  396. // eslint-disable-next-line @typescript-eslint/no-misused-new
  397. new (client: MongoClient, options: AutoEncryptionOptions): AutoEncrypter;
  398. init(cb: Callback): void;
  399. teardown(force: boolean, callback: Callback): void;
  400. encrypt(ns: string, cmd: Document, options: any, callback: Callback<Document>): void;
  401. decrypt(cmd: Document, options: any, callback: Callback<Document>): void;
  402. /** @experimental */
  403. readonly cryptSharedLibVersionInfo: { version: bigint; versionStr: string } | null;
  404. }