7
7
import { deserialize , type Document , serialize } from '../bson' ;
8
8
import { type CommandOptions , type ProxyOptions } from '../cmap/connection' ;
9
9
import { getMongoDBClientEncryption } from '../deps' ;
10
- import { type AnyError , MongoRuntimeError } from '../error' ;
10
+ import { MongoRuntimeError } from '../error' ;
11
11
import { MongoClient , type MongoClientOptions } from '../mongo_client' ;
12
- import { type Callback , MongoDBCollectionNamespace } from '../utils' ;
12
+ import { MongoDBCollectionNamespace } from '../utils' ;
13
13
import * as cryptoCallbacks from './crypto_callbacks' ;
14
14
import { MongoCryptInvalidArgumentError } from './errors' ;
15
15
import { MongocryptdManager } from './mongocryptd_manager' ;
@@ -396,133 +396,66 @@ export class AutoEncrypter {
396
396
*
397
397
* This function is a no-op when bypassSpawn is set or the crypt shared library is used.
398
398
*/
399
- init ( callback : Callback < MongoClient > ) {
399
+ async init ( ) : Promise < MongoClient | void > {
400
400
if ( this . _bypassMongocryptdAndCryptShared || this . cryptSharedLibVersionInfo ) {
401
- return callback ( ) ;
401
+ return ;
402
402
}
403
403
if ( ! this . _mongocryptdManager ) {
404
- return callback (
405
- new MongoRuntimeError (
406
- 'Reached impossible state: mongocryptdManager is undefined when neither bypassSpawn nor the shared lib are specified.'
407
- )
404
+ throw new MongoRuntimeError (
405
+ 'Reached impossible state: mongocryptdManager is undefined when neither bypassSpawn nor the shared lib are specified.'
408
406
) ;
409
407
}
410
408
if ( ! this . _mongocryptdClient ) {
411
- return callback (
412
- new MongoRuntimeError (
413
- 'Reached impossible state: mongocryptdClient is undefined when neither bypassSpawn nor the shared lib are specified.'
414
- )
409
+ throw new MongoRuntimeError (
410
+ 'Reached impossible state: mongocryptdClient is undefined when neither bypassSpawn nor the shared lib are specified.'
415
411
) ;
416
412
}
417
- const _callback = ( err ?: AnyError , res ?: MongoClient ) => {
418
- if (
419
- err &&
420
- err . message &&
421
- ( err . message . match ( / t i m e d o u t a f t e r / ) || err . message . match ( / E N O T F O U N D / ) )
422
- ) {
423
- callback (
424
- new MongoRuntimeError (
425
- 'Unable to connect to `mongocryptd`, please make sure it is running or in your PATH for auto-spawn' ,
426
- { cause : err }
427
- )
428
- ) ;
429
- return ;
430
- }
431
-
432
- callback ( err , res ) ;
433
- } ;
434
413
435
- if ( this . _mongocryptdManager . bypassSpawn ) {
436
- this . _mongocryptdClient . connect ( ) . then (
437
- result => {
438
- return _callback ( undefined , result ) ;
439
- } ,
440
- error => {
441
- _callback ( error , undefined ) ;
442
- }
443
- ) ;
444
- return ;
414
+ if ( ! this . _mongocryptdManager . bypassSpawn ) {
415
+ await this . _mongocryptdManager . spawn ( ) ;
445
416
}
446
417
447
- this . _mongocryptdManager . spawn ( ( ) => {
448
- if ( ! this . _mongocryptdClient ) {
449
- return callback (
450
- new MongoRuntimeError (
451
- 'Reached impossible state: mongocryptdClient is undefined after spawning libmongocrypt.'
452
- )
418
+ try {
419
+ const client = await this . _mongocryptdClient . connect ( ) ;
420
+ return client ;
421
+ } catch ( error ) {
422
+ const { message } = error ;
423
+ if ( message && ( message . match ( / t i m e d o u t a f t e r / ) || message . match ( / E N O T F O U N D / ) ) ) {
424
+ throw new MongoRuntimeError (
425
+ 'Unable to connect to `mongocryptd`, please make sure it is running or in your PATH for auto-spawn' ,
426
+ { cause : error }
453
427
) ;
454
428
}
455
- this . _mongocryptdClient . connect ( ) . then (
456
- result => {
457
- return _callback ( undefined , result ) ;
458
- } ,
459
- error => {
460
- _callback ( error , undefined ) ;
461
- }
462
- ) ;
463
- } ) ;
429
+ throw error ;
430
+ }
464
431
}
465
432
466
433
/**
467
434
* Cleans up the `_mongocryptdClient`, if present.
468
435
*/
469
- teardown ( force : boolean , callback : Callback < void > ) {
470
- if ( this . _mongocryptdClient ) {
471
- this . _mongocryptdClient . close ( force ) . then (
472
- result => {
473
- return callback ( undefined , result ) ;
474
- } ,
475
- error => {
476
- callback ( error ) ;
477
- }
478
- ) ;
479
- } else {
480
- callback ( ) ;
481
- }
436
+ async teardown ( force : boolean ) : Promise < void > {
437
+ await this . _mongocryptdClient ?. close ( force ) ;
482
438
}
483
439
484
- encrypt ( ns : string , cmd : Document , callback : Callback < Document | Uint8Array > ) : void ;
485
- encrypt (
486
- ns : string ,
487
- cmd : Document ,
488
- options : CommandOptions ,
489
- callback : Callback < Document | Uint8Array >
490
- ) : void ;
491
440
/**
492
441
* Encrypt a command for a given namespace.
493
442
*/
494
- encrypt (
443
+ async encrypt (
495
444
ns : string ,
496
445
cmd : Document ,
497
- options ?: CommandOptions | Callback < Document | Uint8Array > ,
498
- callback ?: Callback < Document | Uint8Array >
499
- ) {
500
- callback = typeof options === 'function' ? options : callback ;
501
-
502
- if ( callback == null ) {
503
- throw new MongoCryptInvalidArgumentError ( 'Callback must be provided' ) ;
504
- }
505
-
506
- options = typeof options === 'function' ? { } : options ;
507
-
508
- // If `bypassAutoEncryption` has been specified, don't encrypt
446
+ options : CommandOptions = { }
447
+ ) : Promise < Document | Uint8Array > {
509
448
if ( this . _bypassEncryption ) {
510
- callback ( undefined , cmd ) ;
511
- return ;
449
+ // If `bypassAutoEncryption` has been specified, don't encrypt
450
+ return cmd ;
512
451
}
513
452
514
453
const commandBuffer = Buffer . isBuffer ( cmd ) ? cmd : serialize ( cmd , options ) ;
515
454
516
- let context ;
517
- try {
518
- context = this . _mongocrypt . makeEncryptionContext (
519
- MongoDBCollectionNamespace . fromString ( ns ) . db ,
520
- commandBuffer
521
- ) ;
522
- } catch ( err ) {
523
- callback ( err , undefined ) ;
524
- return ;
525
- }
455
+ const context = this . _mongocrypt . makeEncryptionContext (
456
+ MongoDBCollectionNamespace . fromString ( ns ) . db ,
457
+ commandBuffer
458
+ ) ;
526
459
527
460
context . id = this . _contextCounter ++ ;
528
461
context . ns = ns ;
@@ -534,34 +467,16 @@ export class AutoEncrypter {
534
467
proxyOptions : this . _proxyOptions ,
535
468
tlsOptions : this . _tlsOptions
536
469
} ) ;
537
- stateMachine . execute < Document > ( this , context , callback ) ;
470
+ return stateMachine . execute < Document > ( this , context ) ;
538
471
}
539
472
540
473
/**
541
474
* Decrypt a command response
542
475
*/
543
- decrypt (
544
- response : Uint8Array ,
545
- options : CommandOptions | Callback < Document > ,
546
- callback ?: Callback < Document >
547
- ) {
548
- callback = typeof options === 'function' ? options : callback ;
549
-
550
- if ( callback == null ) {
551
- throw new MongoCryptInvalidArgumentError ( 'Callback must be provided' ) ;
552
- }
553
-
554
- options = typeof options === 'function' ? { } : options ;
555
-
476
+ async decrypt ( response : Uint8Array | Document , options : CommandOptions = { } ) : Promise < Document > {
556
477
const buffer = Buffer . isBuffer ( response ) ? response : serialize ( response , options ) ;
557
478
558
- let context ;
559
- try {
560
- context = this . _mongocrypt . makeDecryptionContext ( buffer ) ;
561
- } catch ( err ) {
562
- callback ( err , undefined ) ;
563
- return ;
564
- }
479
+ const context = this . _mongocrypt . makeDecryptionContext ( buffer ) ;
565
480
566
481
context . id = this . _contextCounter ++ ;
567
482
@@ -572,16 +487,11 @@ export class AutoEncrypter {
572
487
} ) ;
573
488
574
489
const decorateResult = this [ kDecorateResult ] ;
575
- stateMachine . execute ( this , context , function ( error ?: Error , result ?: Document ) {
576
- // Only for testing/internal usage
577
- if ( ! error && result && decorateResult ) {
578
- const error = decorateDecryptionResult ( result , response ) ;
579
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
580
- if ( error ) return callback ! ( error ) ;
581
- }
582
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
583
- callback ! ( error , result ) ;
584
- } ) ;
490
+ const result = await stateMachine . execute < Document > ( this , context ) ;
491
+ if ( decorateResult ) {
492
+ decorateDecryptionResult ( result , response ) ;
493
+ }
494
+ return result ;
585
495
}
586
496
587
497
/**
@@ -621,14 +531,14 @@ function decorateDecryptionResult(
621
531
decrypted : Document & { [ kDecoratedKeys ] ?: Array < string > } ,
622
532
original : Document ,
623
533
isTopLevelDecorateCall = true
624
- ) : Error | void {
534
+ ) : void {
625
535
if ( isTopLevelDecorateCall ) {
626
536
// The original value could have been either a JS object or a BSON buffer
627
537
if ( Buffer . isBuffer ( original ) ) {
628
538
original = deserialize ( original ) ;
629
539
}
630
540
if ( Buffer . isBuffer ( decrypted ) ) {
631
- return new MongoRuntimeError ( 'Expected result of decryption to be deserialized BSON object' ) ;
541
+ throw new MongoRuntimeError ( 'Expected result of decryption to be deserialized BSON object' ) ;
632
542
}
633
543
}
634
544
@@ -647,10 +557,10 @@ function decorateDecryptionResult(
647
557
writable : false
648
558
} ) ;
649
559
}
650
- // this is defined in the preceeding if-statement
560
+ // this is defined in the preceding if-statement
651
561
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
652
562
decrypted [ kDecoratedKeys ] ! . push ( k ) ;
653
- // Do not recurse into this decrypted value. It could be a subdocument /array,
563
+ // Do not recurse into this decrypted value. It could be a sub-document /array,
654
564
// in which case there is no original value associated with its subfields.
655
565
continue ;
656
566
}
0 commit comments