Skip to content

Commit cab69b2

Browse files
authored
Merge pull request #165 from cipherstash/bulk-fallible
ci(protect): add test for mixed lock contexts and bulk decrypt
2 parents 7205ee5 + b0ed084 commit cab69b2

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

packages/protect/__tests__/bulk-protect.test.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,83 @@ describe('bulk encryption and decryption', () => {
501501
expect(decryptedData.data[1]).toHaveProperty('data')
502502
expect(decryptedData.data[1].data).toBeNull()
503503
}, 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)
504581
})
505582

506583
describe('bulk operations round-trip', () => {

0 commit comments

Comments
 (0)