Load cloud provider credentials for the user provided kms providers.
+Credentials will only attempt to get loaded if they do not exist
+and no existing credentials will get overwritten.
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,10 +288,14 @@ 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)
+ * [._encrypt(value, expressionMode, options)](#ClientEncryption+_encrypt)
+
* _inner_
* [~decryptCallback](#ClientEncryption..decryptCallback)
@@ -534,10 +561,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 +596,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.The aggregation or match expression you wish to encrypt. The value must be in the form
+
+| 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)
@@ -607,6 +646,23 @@ This returns anything that looks like the kmsProviders original input
option. It can be empty, and any provider specified here will override
the original ones.
+
+
+### *clientEncryption*._encrypt(value, expressionMode, options)
+**Internal**:
+
+| Param | Type | Description |
+| --- | --- | --- |
+| value | \* | The value that you wish to encrypt. Must be of a type that can be serialized into BSON |
+| expressionMode | boolean | a boolean that indicates whether or not to encrypt the value as an expression |
+| options | [EncryptOptions](#EncryptOptions) | |
+
+A helper that perform explicit encryption of values and expressions.
+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.
+
+**Returns**: the raw result of the call to stateMachine.execute(). When expressionMode is set to true, the return
+ value will be a bson document. When false, the value will be a BSON Binary.
### *ClientEncryption*~decryptCallback
@@ -621,6 +677,29 @@ the original ones.
## MongoCryptError
An error indicating that something went wrong specifically with MongoDB Client Encryption
+
+
+## loadCredentials(kmsProviders)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| kmsProviders | Object | The user provided kms providers. |
+
+Load cloud provider credentials for the user provided kms providers.
+Credentials will only attempt to get loaded if they do not exist
+and no existing credentials will get overwritten.
+
+**Returns**: Promise - The new kms providers.
+
+
+## BSONValue
+any serializable BSON value
+
+
+
+## Long
+A 64 bit integer, represented by the js-bson Long type.
+
## KMSProviders
@@ -771,3 +850,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..1d4ac1f5c 100644
--- a/bindings/node/index.d.ts
+++ b/bindings/node/index.d.ts
@@ -1,4 +1,4 @@
-import type { Document, Binary } from 'bson';
+import type { Document, Binary, Long } from 'bson';
import type { MongoClient, BulkWriteResult, ClientSession, DeleteResult, FindCursor } from 'mongodb';
export type ClientEncryptionDataKeyProvider = 'aws' | 'azure' | 'gcp' | 'local' | 'kmip';
@@ -330,6 +330,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 +349,7 @@ 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 +365,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;
}
/**
@@ -493,6 +508,26 @@ 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
diff --git a/bindings/node/lib/clientEncryption.js b/bindings/node/lib/clientEncryption.js
index a67d501f1..5b36760e3 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.The aggregation or match expression you wish to encrypt. The value must be in the form
+ *
+ * @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