@@ -501,6 +501,83 @@ describe('bulk encryption and decryption', () => {
501
501
expect ( decryptedData . data [ 1 ] ) . toHaveProperty ( 'data' )
502
502
expect ( decryptedData . data [ 1 ] . data ) . toBeNull ( )
503
503
} , 30000 )
504
+
505
+ it ( 'should decrypt mixed lock context payloads with specific lock context' , async ( ) => {
506
+ const userJwt = process . env . USER_JWT
507
+ const user2Jwt = process . env . USER_2_JWT
508
+
509
+ if ( ! userJwt || ! user2Jwt ) {
510
+ console . log (
511
+ 'Skipping mixed lock context test - missing USER_JWT or USER_2_JWT' ,
512
+ )
513
+ return
514
+ }
515
+
516
+ const lc = new LockContext ( )
517
+ const lc2 = new LockContext ( )
518
+ const lockContext1 = await lc . identify ( userJwt )
519
+ const lockContext2 = await lc2 . identify ( user2Jwt )
520
+
521
+ if ( lockContext1 . failure ) {
522
+ throw new Error ( `[protect]: ${ lockContext1 . failure . message } ` )
523
+ }
524
+
525
+ if ( lockContext2 . failure ) {
526
+ throw new Error ( `[protect]: ${ lockContext2 . failure . message } ` )
527
+ }
528
+
529
+ // Encrypt first value with USER_JWT lock context
530
+ const encryptedData1 = await protectClient
531
+ . bulkEncrypt ( [ { id : 'user1' , plaintext : 'alice@example.com' } ] , {
532
+ column : users . email ,
533
+ table : users ,
534
+ } )
535
+ . withLockContext ( lockContext1 . data )
536
+
537
+ if ( encryptedData1 . failure ) {
538
+ throw new Error ( `[protect]: ${ encryptedData1 . failure . message } ` )
539
+ }
540
+
541
+ // Encrypt second value with USER_2_JWT lock context
542
+ const encryptedData2 = await protectClient
543
+ . bulkEncrypt ( [ { id : 'user2' , plaintext : 'bob@example.com' } ] , {
544
+ column : users . email ,
545
+ table : users ,
546
+ } )
547
+ . withLockContext ( lockContext2 . data )
548
+
549
+ if ( encryptedData2 . failure ) {
550
+ throw new Error ( `[protect]: ${ encryptedData2 . failure . message } ` )
551
+ }
552
+
553
+ // Combine both encrypted payloads
554
+ const combinedEncryptedData = [
555
+ ...encryptedData1 . data ,
556
+ ...encryptedData2 . data ,
557
+ ]
558
+
559
+ // Decrypt with USER_2_JWT lock context
560
+ const decryptedData = await protectClient
561
+ . bulkDecrypt ( combinedEncryptedData )
562
+ . withLockContext ( lockContext2 . data )
563
+
564
+ if ( decryptedData . failure ) {
565
+ throw new Error ( `[protect]: ${ decryptedData . failure . message } ` )
566
+ }
567
+
568
+ // Verify both payloads are returned
569
+ expect ( decryptedData . data ) . toHaveLength ( 2 )
570
+
571
+ // First payload should fail to decrypt since it was encrypted with different lock context
572
+ expect ( decryptedData . data [ 0 ] ) . toHaveProperty ( 'id' , 'user1' )
573
+ expect ( decryptedData . data [ 0 ] ) . toHaveProperty ( 'error' )
574
+ expect ( decryptedData . data [ 0 ] ) . not . toHaveProperty ( 'data' )
575
+
576
+ // Second payload should be decrypted since it was encrypted with the same lock context
577
+ expect ( decryptedData . data [ 1 ] ) . toHaveProperty ( 'id' , 'user2' )
578
+ expect ( decryptedData . data [ 1 ] ) . toHaveProperty ( 'data' , 'bob@example.com' )
579
+ expect ( decryptedData . data [ 1 ] ) . not . toHaveProperty ( 'error' )
580
+ } , 30000 )
504
581
} )
505
582
506
583
describe ( 'bulk operations round-trip' , ( ) => {
0 commit comments