diff --git a/addon/mongocrypt.cc b/addon/mongocrypt.cc index 421bb93..9ea3c41 100644 --- a/addon/mongocrypt.cc +++ b/addon/mongocrypt.cc @@ -589,13 +589,29 @@ Value MongoCrypt::MakeEncryptionContext(const CallbackInfo& info) { } Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) { - std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); - Uint8Array valueBuffer = Uint8ArrayFromValue(info[0], "value"); Object options = info.Length() > 1 ? info[1].ToObject() : Object::New(info.Env()); + if (!options.Get("expressionMode").IsBoolean()) { + throw TypeError::New(Env(), "option `expressionMode` is required."); + } + + bool expression_mode = options.Get("expressionMode").ToBoolean(); + ExplicitEncryptionContextInitFunction context_init_function = + expression_mode ? mongocrypt_ctx_explicit_encrypt_expression_init + : mongocrypt_ctx_explicit_encrypt_init; + + return MakeExplicitEncryptionContextInternal(context_init_function, valueBuffer, options); +} + +Value MongoCrypt::MakeExplicitEncryptionContextInternal( + ExplicitEncryptionContextInitFunction context_init_function, + const Uint8Array& valueBuffer, + const Object& options) { + std::unique_ptr context( + mongocrypt_ctx_new(_mongo_crypt.get())); + if (!options.Get("keyId").IsUndefined()) { Uint8Array keyId = Uint8ArrayFromValue(options["keyId"], "keyId"); @@ -658,12 +674,7 @@ Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) { std::unique_ptr binaryValue( Uint8ArrayToBinary(valueBuffer)); - const bool isExpressionMode = options.Get("expressionMode").ToBoolean(); - - const bool status = - isExpressionMode - ? mongocrypt_ctx_explicit_encrypt_expression_init(context.get(), binaryValue.get()) - : mongocrypt_ctx_explicit_encrypt_init(context.get(), binaryValue.get()); + const bool status = context_init_function(context.get(), binaryValue.get()); if (!status) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); diff --git a/addon/mongocrypt.h b/addon/mongocrypt.h index 61d6950..fb3d73d 100644 --- a/addon/mongocrypt.h +++ b/addon/mongocrypt.h @@ -56,6 +56,8 @@ namespace opensslcrypto { std::unique_ptr createOpenSSLCryptoHooks(); } +typedef bool (*ExplicitEncryptionContextInitFunction)(mongocrypt_ctx_t*, mongocrypt_binary_t*); + class MongoCrypt : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); @@ -67,6 +69,9 @@ class MongoCrypt : public Napi::ObjectWrap { Napi::Value MakeExplicitDecryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeDataKeyContext(const Napi::CallbackInfo& info); Napi::Value MakeRewrapManyDataKeyContext(const Napi::CallbackInfo& info); + Napi::Value MakeExplicitEncryptionContextInternal(ExplicitEncryptionContextInitFunction init_fn, + const Napi::Uint8Array& value, + const Napi::Object& options); Napi::Value Status(const Napi::CallbackInfo& info); Napi::Value CryptSharedLibVersionInfo(const Napi::CallbackInfo& info); diff --git a/package.json b/package.json index 93a8f34..2e84a4a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "check:clang-format": "clang-format --style=file:.clang-format --dry-run --Werror addon/*", "test": "mocha test", "prepare": "tsc", + "rebuild": "node-gyp rebuild", "prebuild": "prebuild --runtime napi --strip --verbose --all" }, "author": { diff --git a/test/bindings.test.ts b/test/bindings.test.ts index 186bc01..53e2803 100644 --- a/test/bindings.test.ts +++ b/test/bindings.test.ts @@ -387,6 +387,20 @@ describe('MongoCryptConstructor', () => { ).to.be.instanceOf(MongoCryptContextCtor); }); }); + + describe('options.expressionMode', function () { + it('throws if `expressionMode` is not defined', function () { + expect(() => + mc.makeExplicitEncryptionContext(value, { + // minimum required arguments from libmongocrypt + keyId: keyId.buffer, + algorithm: 'Unindexed' + }) + ) + .to.throw(/option `expressionMode` is required./) + .to.be.instanceOf(TypeError); + }); + }); }); }); diff --git a/test/crypto.test.ts b/test/crypto.test.ts index 628dd33..21edd54 100644 --- a/test/crypto.test.ts +++ b/test/crypto.test.ts @@ -38,7 +38,8 @@ function createEncryptedDocument(mongoCrypt: MongoCrypt) { const ctx = mongoCrypt.makeExplicitEncryptionContext(BSON.serialize({ v }), { keyId: keyId.buffer, - algorithm + algorithm, + expressionMode: false }); const getState = () => ctx.state;