min, max, sparsity, and range must match the values set in the encryptedFields of the destination collection.
+For double and decimal128, min/max/precision must all be set, or all be unset.
@@ -265,6 +278,8 @@ The public interface for explicit in-use encryption
* [.encrypt(value, options, [callback])](#ClientEncryption+encrypt)
+ * [.encryptExpression(expression, options)](#ClientEncryption+encryptExpression)
+
* [.decrypt(value, callback)](#ClientEncryption+decrypt)
* [.askForKMSCredentials()](#ClientEncryption+askForKMSCredentials)
@@ -534,10 +549,7 @@ if (!oldKey) {
| Param | Type | Description |
| --- | --- | --- |
| value | \* | The value that you wish to serialize. Must be of a type that can be serialized into BSON |
-| options | object | |
-| [options.keyId] | [ClientEncryptionDataKeyId](#ClientEncryptionDataKeyId) | The id of the Binary dataKey to use for encryption |
-| [options.keyAltName] | string | A unique string name corresponding to an already existing dataKey. |
-| [options.algorithm] | | The algorithm to use for encryption. Must be either `'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'`, `'AEAD_AES_256_CBC_HMAC_SHA_512-Random'`, `'Indexed'` or `'Unindexed'` |
+| options | [EncryptOptions](#EncryptOptions) | |
| [callback] | [ClientEncryptionEncryptCallback](#ClientEncryptionEncryptCallback) | Optional callback to invoke when value is encrypted |
Explicitly encrypt a provided value. Note that either `options.keyId` or `options.keyAltName` must
@@ -572,6 +584,21 @@ async function encryptMyData(value) {
return clientEncryption.encrypt(value, { keyAltName: 'mySpecialKey', algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' });
}
```
+
+
+### *clientEncryption*.encryptExpression(expression, options)
+**Experimental**: The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
+
+| Param | Type | Description |
+| --- | --- | --- |
+| expression | object | a BSON document of one of the following forms: 1. A Match Expression of this form: `{$and: [{: {$gt: }}, {: {$lt: }}]}` 2. An Aggregate Expression of this form: `{$and: [{$gt: [, ]}, {$lt: [, ]}]}` `$gt` may also be `$gte`. `$lt` may also be `$lte`. |
+| options | [EncryptOptions](#EncryptOptions) | |
+
+Encrypts a Match Expression or Aggregate Expression to query a range index.
+
+Only supported when queryType is "rangePreview" and algorithm is "RangePreview".
+
+**Returns**: Promise.<object> - Returns a Promise that either resolves with the encrypted value or rejects with an error.
### *clientEncryption*.decrypt(value, callback)
@@ -621,6 +648,16 @@ the original ones.
## MongoCryptError
An error indicating that something went wrong specifically with MongoDB Client Encryption
+
+
+## BSONValue
+any serializable BSON value
+
+
+
+## Long
+A 64 bit integer, represented by the js-bson Long type.
+
## KMSProviders
@@ -771,3 +808,34 @@ Configuration options for making an Azure encryption key
| [err] | Error | If present, indicates an error that occurred in the process of encryption |
| [result] | Buffer | If present, is the encrypted result |
+
+
+## RangeOptions
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| min | [BSONValue](#BSONValue) | is required if precision is set. |
+| max | [BSONValue](#BSONValue) | is required if precision is set. |
+| sparsity | BSON.Long | |
+| precision | number \| undefined | (may only be set for double or decimal128). |
+
+min, max, sparsity, and range must match the values set in the encryptedFields of the destination collection.
+For double and decimal128, min/max/precision must all be set, or all be unset.
+
+
+
+## EncryptOptions
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| [keyId] | [ClientEncryptionDataKeyId](#ClientEncryptionDataKeyId) | The id of the Binary dataKey to use for encryption. |
+| [keyAltName] | string | A unique string name corresponding to an already existing dataKey. |
+| [algorithm] | string | The algorithm to use for encryption. Must be either `'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'`, `'AEAD_AES_256_CBC_HMAC_SHA_512-Random'`, `'Indexed'` or `'Unindexed'` |
+| [contentionFactor] | bigint \| number | (experimental) - the contention factor. |
+| queryType | 'equality' \| 'rangePreview' | (experimental) - the query type supported. |
+| [rangeOptions] | [RangeOptions](#RangeOptions) | (experimental) The index options for a Queryable Encryption field supporting "rangePreview" queries. |
+
+Options to provide when encrypting data.
+
diff --git a/bindings/node/index.d.ts b/bindings/node/index.d.ts
index 1e2e00675..f2ddafe03 100644
--- a/bindings/node/index.d.ts
+++ b/bindings/node/index.d.ts
@@ -1,5 +1,10 @@
-import type { Document, Binary } from 'bson';
-import type { MongoClient, BulkWriteResult, ClientSession, DeleteResult, FindCursor } from 'mongodb';
+import type { Document, Binary, Long } from 'bson';
+import type {
+ MongoClient,
+ BulkWriteResult,
+ DeleteResult,
+ FindCursor
+} from 'mongodb';
export type ClientEncryptionDataKeyProvider = 'aws' | 'azure' | 'gcp' | 'local' | 'kmip';
@@ -20,8 +25,7 @@ export interface DataKey {
/**
* An error indicating that something went wrong specifically with MongoDB Client Encryption
*/
-export class MongoCryptError extends Error {
-}
+export class MongoCryptError extends Error {}
/**
* A set of options for specifying a Socks5 proxy.
@@ -152,7 +156,7 @@ export interface KMSProviders {
* Defaults to "oauth2.googleapis.com"
*/
endpoint?: string | undefined;
- }
+ };
}
/**
@@ -306,7 +310,11 @@ export interface ClientEncryptionCreateDataKeyProviderOptions {
/**
* Idenfities a new KMS-specific key used to encrypt the new data key
*/
- masterKey?: AWSEncryptionKeyOptions | AzureEncryptionKeyOptions | GCPEncryptionKeyOptions | undefined;
+ masterKey?:
+ | AWSEncryptionKeyOptions
+ | AzureEncryptionKeyOptions
+ | GCPEncryptionKeyOptions
+ | undefined;
/**
* An optional list of string alternate names used to reference a key.
@@ -321,7 +329,11 @@ export interface ClientEncryptionCreateDataKeyProviderOptions {
/** @experimental */
export interface ClientEncryptionRewrapManyDataKeyProviderOptions {
provider: ClientEncryptionDataKeyProvider;
- masterKey?: AWSEncryptionKeyOptions | AzureEncryptionKeyOptions | GCPEncryptionKeyOptions | undefined;
+ masterKey?:
+ | AWSEncryptionKeyOptions
+ | AzureEncryptionKeyOptions
+ | GCPEncryptionKeyOptions
+ | undefined;
}
/** @experimental */
@@ -330,6 +342,18 @@ export interface ClientEncryptionRewrapManyDataKeyResult {
bulkWriteResult?: BulkWriteResult;
}
+/**
+ * RangeOpts specifies index options for a Queryable Encryption field supporting "rangePreview" queries.
+ * min, max, sparsity, and range must match the values set in the encryptedFields of the destination collection.
+ * For double and decimal128, min/max/precision must all be set, or all be unset.
+ */
+interface RangeOptions {
+ min?: any;
+ max?: any;
+ sparsity: Long;
+ precision?: number;
+}
+
/**
* Options to provide when encrypting data.
*/
@@ -337,7 +361,12 @@ export interface ClientEncryptionEncryptOptions {
/**
* The algorithm to use for encryption.
*/
- algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' | 'AEAD_AES_256_CBC_HMAC_SHA_512-Random' | 'Indexed' | 'Unindexed';
+ algorithm:
+ | 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
+ | 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'
+ | 'Indexed'
+ | 'Unindexed'
+ | 'RangePreview';
/**
* The id of the Binary dataKey to use for encryption
@@ -353,7 +382,10 @@ export interface ClientEncryptionEncryptOptions {
contentionFactor?: bigint | number;
/** @experimental Public Technical Preview: The query type supported */
- queryType?: 'equality';
+ queryType?: 'equality' | 'rangePreview';
+
+ /** @experimental Public Technical Preview: The index options for a Queryable Encryption field supporting "rangePreview" queries.*/
+ rangeOpts?: RangeOptions;
}
/**
@@ -371,9 +403,7 @@ export class ClientEncryption {
* Creates a data key used for explicit encryption and inserts it into the key vault namespace
* @param provider The KMS provider used for this data key. Must be `'aws'`, `'azure'`, `'gcp'`, or `'local'`
*/
- createDataKey(
- provider: ClientEncryptionDataKeyProvider
- ): Promise;
+ createDataKey(provider: ClientEncryptionDataKeyProvider): Promise;
/**
* Creates a data key used for explicit encryption and inserts it into the key vault namespace
@@ -474,10 +504,7 @@ export class ClientEncryption {
* @param value The value that you wish to serialize. Must be of a type that can be serialized into BSON
* @param options
*/
- encrypt(
- value: any,
- options: ClientEncryptionEncryptOptions
- ): Promise;
+ encrypt(value: any, options: ClientEncryptionEncryptOptions): Promise;
/**
* Explicitly encrypt a provided value.
@@ -493,23 +520,35 @@ export class ClientEncryption {
callback: ClientEncryptionEncryptCallback
): void;
+ /**
+ * Encrypts a Match Expression or Aggregate Expression to query a range index.
+ *
+ * Only supported when queryType is "rangePreview" and algorithm is "RangePreview".
+ *
+ * @experimental The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.The aggregation or match expression you wish to encrypt. The value must be in the form
+ *
+ * The expression to encrypt must be one of the following:
+ * 1. A Match Expression of this form:
+ * `{$and: [{: {$gt: }}, {: {$lt: }}]}`
+ * 2. An Aggregate Expression of this form:
+ * `{$and: [{$gt: [, ]}, {$lt: [, ]}]}`
+ *
+ * `$gt` may also be `$gte`. `$lt` may also be `$lte`.
+ */
+ encryptExpression(value: Document, options: ClientEncryptionOptions): Promise;
+
/**
* Explicitly decrypt a provided encrypted value
* @param value An encrypted value
*/
- decrypt(
- value: Buffer | Binary
- ): Promise;
+ decrypt(value: Buffer | Binary): Promise;
/**
* Explicitly decrypt a provided encrypted value
* @param value An encrypted value
* @param callback Callback to invoke when value is decrypted
*/
- decrypt(
- value: Buffer | Binary,
- callback: ClientEncryptionDecryptCallback
- ): void;
+ decrypt(value: Buffer | Binary, callback: ClientEncryptionDecryptCallback): void;
static readonly libmongocryptVersion: string;
}
diff --git a/bindings/node/lib/clientEncryption.js b/bindings/node/lib/clientEncryption.js
index a67d501f1..21839187b 100644
--- a/bindings/node/lib/clientEncryption.js
+++ b/bindings/node/lib/clientEncryption.js
@@ -6,12 +6,16 @@ module.exports = function (modules) {
const databaseNamespace = common.databaseNamespace;
const collectionNamespace = common.collectionNamespace;
const promiseOrCallback = common.promiseOrCallback;
+ const maybeCallback = common.maybeCallback;
const StateMachine = modules.stateMachine.StateMachine;
const BSON = modules.mongodb.BSON;
const { loadCredentials } = require('./credentialsProvider');
const cryptoCallbacks = require('./cryptoCallbacks');
const { promisify } = require('util');
+ /** @typedef {*} BSONValue - any serializable BSON value */
+ /** @typedef {BSON.Long} Long A 64 bit integer, represented by the js-bson Long type.*/
+
/**
* @typedef {object} KMSProviders Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.
* @property {object} [aws] Configuration options for using 'aws' as your KMS provider
@@ -551,15 +555,32 @@ module.exports = function (modules) {
* @param {Buffer} [result] If present, is the encrypted result
*/
+ /**
+ * @typedef {object} RangeOptions
+ * min, max, sparsity, and range must match the values set in the encryptedFields of the destination collection.
+ * For double and decimal128, min/max/precision must all be set, or all be unset.
+ * @property {BSONValue} min is required if precision is set.
+ * @property {BSONValue} max is required if precision is set.
+ * @property {BSON.Long} sparsity
+ * @property {number | undefined} precision (may only be set for double or decimal128).
+ */
+
+ /**
+ * @typedef {object} EncryptOptions Options to provide when encrypting data.
+ * @property {ClientEncryptionDataKeyId} [keyId] The id of the Binary dataKey to use for encryption.
+ * @property {string} [keyAltName] A unique string name corresponding to an already existing dataKey.
+ * @property {string} [algorithm] The algorithm to use for encryption. Must be either `'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'`, `'AEAD_AES_256_CBC_HMAC_SHA_512-Random'`, `'Indexed'` or `'Unindexed'`
+ * @property {bigint | number} [contentionFactor] (experimental) - the contention factor.
+ * @property {'equality' | 'rangePreview'} queryType (experimental) - the query type supported.
+ * @property {RangeOptions} [rangeOptions] (experimental) The index options for a Queryable Encryption field supporting "rangePreview" queries.
+ */
+
/**
* Explicitly encrypt a provided value. Note that either `options.keyId` or `options.keyAltName` must
* be specified. Specifying both `options.keyId` and `options.keyAltName` is considered an error.
*
* @param {*} value The value that you wish to serialize. Must be of a type that can be serialized into BSON
- * @param {object} options
- * @param {ClientEncryptionDataKeyId} [options.keyId] The id of the Binary dataKey to use for encryption
- * @param {string} [options.keyAltName] A unique string name corresponding to an already existing dataKey.
- * @param {} [options.algorithm] The algorithm to use for encryption. Must be either `'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'`, `'AEAD_AES_256_CBC_HMAC_SHA_512-Random'`, `'Indexed'` or `'Unindexed'`
+ * @param {EncryptOptions} options
* @param {ClientEncryptionEncryptCallback} [callback] Optional callback to invoke when value is encrypted
* @returns {Promise|void} If no callback is provided, returns a Promise that either resolves with the encrypted value, or rejects with an error. If a callback is provided, returns nothing.
*
@@ -589,44 +610,29 @@ module.exports = function (modules) {
* }
*/
encrypt(value, options, callback) {
- const bson = this._bson;
- const valueBuffer = bson.serialize({ v: value });
- const contextOptions = Object.assign({}, options);
- if (options.keyId) {
- contextOptions.keyId = options.keyId.buffer;
- }
- if (options.keyAltName) {
- const keyAltName = options.keyAltName;
- if (options.keyId) {
- throw new TypeError(`"options" cannot contain both "keyId" and "keyAltName"`);
- }
- const keyAltNameType = typeof keyAltName;
- if (keyAltNameType !== 'string') {
- throw new TypeError(
- `"options.keyAltName" must be of type string, but was of type ${keyAltNameType}`
- );
- }
-
- contextOptions.keyAltName = bson.serialize({ keyAltName });
- }
-
- const stateMachine = new StateMachine({
- bson,
- proxyOptions: this._proxyOptions,
- tlsOptions: this._tlsOptions
- });
- const context = this._mongoCrypt.makeExplicitEncryptionContext(valueBuffer, contextOptions);
-
- return promiseOrCallback(callback, cb => {
- stateMachine.execute(this, context, (err, result) => {
- if (err) {
- cb(err, null);
- return;
- }
+ return maybeCallback(() => this._encrypt(value, false, options), callback);
+ }
- cb(null, result.v);
- });
- });
+ /**
+ * Encrypts a Match Expression or Aggregate Expression to query a range index.
+ *
+ * Only supported when queryType is "rangePreview" and algorithm is "RangePreview".
+ *
+ * @experimental The Range algorithm is experimental only. It is not intended for public use. It is subject to breaking changes.
+ *
+ * @param {object} expression a BSON document of one of the following forms:
+ * 1. A Match Expression of this form:
+ * `{$and: [{: {$gt: }}, {: {$lt: }}]}`
+ * 2. An Aggregate Expression of this form:
+ * `{$and: [{$gt: [, ]}, {$lt: [, ]}]}`
+ *
+ * `$gt` may also be `$gte`. `$lt` may also be `$lte`.
+ *
+ * @param {EncryptOptions} options
+ * @returns {Promise