Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-4964): support range indexes #533

Merged
merged 7 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 72 additions & 4 deletions bindings/node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ npm test
## Typedefs

<dl>
<dt><a href="#BSONValue">BSONValue</a> : <code>*</code></dt>
<dd><p>any serializable BSON value</p>
</dd>
<dt><a href="#Long">Long</a> : <code>BSON.Long</code></dt>
<dd><p>A 64 bit integer, represented by the js-bson Long type.</p>
</dd>
<dt><a href="#KMSProviders">KMSProviders</a> : <code>object</code></dt>
<dd><p>Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.</p>
</dd>
Expand Down Expand Up @@ -100,6 +106,13 @@ query for the data key itself against the key vault namespace.</p>
<dd></dd>
<dt><a href="#ClientEncryptionEncryptCallback">ClientEncryptionEncryptCallback</a> : <code>function</code></dt>
<dd></dd>
<dt><a href="#RangeOptions">RangeOptions</a> : <code>object</code></dt>
<dd><p>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.</p>
</dd>
<dt><a href="#EncryptOptions">EncryptOptions</a> : <code>object</code></dt>
<dd><p>Options to provide when encrypting data.</p>
</dd>
</dl>

<a name="AutoEncrypter"></a>
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -534,10 +549,7 @@ if (!oldKey) {
| Param | Type | Description |
| --- | --- | --- |
| value | <code>\*</code> | The value that you wish to serialize. Must be of a type that can be serialized into BSON |
| options | <code>object</code> | |
| [options.keyId] | [<code>ClientEncryptionDataKeyId</code>](#ClientEncryptionDataKeyId) | The id of the Binary dataKey to use for encryption |
| [options.keyAltName] | <code>string</code> | 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 | [<code>EncryptOptions</code>](#EncryptOptions) | |
| [callback] | [<code>ClientEncryptionEncryptCallback</code>](#ClientEncryptionEncryptCallback) | Optional callback to invoke when value is encrypted |

Explicitly encrypt a provided value. Note that either `options.keyId` or `options.keyAltName` must
Expand Down Expand Up @@ -572,6 +584,21 @@ async function encryptMyData(value) {
return clientEncryption.encrypt(value, { keyAltName: 'mySpecialKey', algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' });
}
```
<a name="ClientEncryption+encryptExpression"></a>

### *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 | <code>object</code> | a BSON document of one of the following forms: 1. A Match Expression of this form: `{$and: [{<field>: {$gt: <value1>}}, {<field>: {$lt: <value2> }}]}` 2. An Aggregate Expression of this form: `{$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]}` `$gt` may also be `$gte`. `$lt` may also be `$lte`. |
| options | [<code>EncryptOptions</code>](#EncryptOptions) | |

Encrypts a Match Expression or Aggregate Expression to query a range index.

Only supported when queryType is "rangePreview" and algorithm is "RangePreview".

**Returns**: <code>Promise.&lt;object&gt;</code> - Returns a Promise that either resolves with the encrypted value or rejects with an error.
<a name="ClientEncryption+decrypt"></a>

### *clientEncryption*.decrypt(value, callback)
Expand Down Expand Up @@ -621,6 +648,16 @@ the original ones.
## MongoCryptError
An error indicating that something went wrong specifically with MongoDB Client Encryption

<a name="BSONValue"></a>

## BSONValue
any serializable BSON value

<a name="Long"></a>

## Long
A 64 bit integer, represented by the js-bson Long type.

<a name="KMSProviders"></a>

## KMSProviders
Expand Down Expand Up @@ -771,3 +808,34 @@ Configuration options for making an Azure encryption key
| [err] | <code>Error</code> | If present, indicates an error that occurred in the process of encryption |
| [result] | <code>Buffer</code> | If present, is the encrypted result |

<a name="RangeOptions"></a>

## RangeOptions
**Properties**

| Name | Type | Description |
| --- | --- | --- |
| min | [<code>BSONValue</code>](#BSONValue) | is required if precision is set. |
| max | [<code>BSONValue</code>](#BSONValue) | is required if precision is set. |
| sparsity | <code>BSON.Long</code> | |
| precision | <code>number</code> \| <code>undefined</code> | (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.

<a name="EncryptOptions"></a>

## EncryptOptions
**Properties**

| Name | Type | Description |
| --- | --- | --- |
| [keyId] | [<code>ClientEncryptionDataKeyId</code>](#ClientEncryptionDataKeyId) | The id of the Binary dataKey to use for encryption. |
| [keyAltName] | <code>string</code> | A unique string name corresponding to an already existing dataKey. |
| [algorithm] | <code>string</code> | 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] | <code>bigint</code> \| <code>number</code> | (experimental) - the contention factor. |
| queryType | <code>&#x27;equality&#x27;</code> \| <code>&#x27;rangePreview&#x27;</code> | (experimental) - the query type supported. |
| [rangeOptions] | [<code>RangeOptions</code>](#RangeOptions) | (experimental) The index options for a Queryable Encryption field supporting "rangePreview" queries. |

Options to provide when encrypting data.

85 changes: 62 additions & 23 deletions bindings/node/index.d.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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.
Expand Down Expand Up @@ -152,7 +156,7 @@ export interface KMSProviders {
* Defaults to "oauth2.googleapis.com"
*/
endpoint?: string | undefined;
}
};
}

/**
Expand Down Expand Up @@ -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.
Expand All @@ -321,7 +329,11 @@ export interface ClientEncryptionCreateDataKeyProviderOptions {
/** @experimental */
export interface ClientEncryptionRewrapManyDataKeyProviderOptions {
provider: ClientEncryptionDataKeyProvider;
masterKey?: AWSEncryptionKeyOptions | AzureEncryptionKeyOptions | GCPEncryptionKeyOptions | undefined;
masterKey?:
| AWSEncryptionKeyOptions
| AzureEncryptionKeyOptions
| GCPEncryptionKeyOptions
| undefined;
}

/** @experimental */
Expand All @@ -330,14 +342,31 @@ 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.
*/
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
Expand All @@ -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;
}

/**
Expand All @@ -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<Binary>;
createDataKey(provider: ClientEncryptionDataKeyProvider): Promise<Binary>;

/**
* Creates a data key used for explicit encryption and inserts it into the key vault namespace
Expand Down Expand Up @@ -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<Binary>;
encrypt(value: any, options: ClientEncryptionEncryptOptions): Promise<Binary>;

/**
* Explicitly encrypt a provided value.
Expand All @@ -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: [{<field>: {$gt: <value1>}}, {<field>: {$lt: <value2> }}]}`
* 2. An Aggregate Expression of this form:
* `{$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]}`
*
* `$gt` may also be `$gte`. `$lt` may also be `$lte`.
*/
encryptExpression(value: Document, options: ClientEncryptionOptions): Promise<Document>;

/**
* Explicitly decrypt a provided encrypted value
* @param value An encrypted value
*/
decrypt(
value: Buffer | Binary
): Promise<any>;
decrypt(value: Buffer | Binary): Promise<any>;

/**
* 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;
}
Loading