Skip to content

Commit c7b6098

Browse files
committed
Added test cases for the direct-shared records
1 parent 7e9be5a commit c7b6098

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

keeperapi/src/__tests__/vault.test.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ describe('Sync Down', () => {
1717
username: string,
1818
accountUid: Uint8Array,
1919
}
20+
let anotherUserA: {
21+
username: string,
22+
accountUid: Uint8Array,
23+
}
2024
beforeAll(async () => {
2125
connectPlatform(nodePlatform)
2226
dataKey = platform.getRandomBytes(32)
@@ -25,6 +29,10 @@ describe('Sync Down', () => {
2529
username: 'keeper@keepersecurity.com',
2630
accountUid: platform.getRandomBytes(16)
2731
}
32+
anotherUserA = {
33+
username: 'another@keepersecurity.com',
34+
accountUid: platform.getRandomBytes(16)
35+
}
2836
})
2937
describe('Owned Records', () => {
3038
beforeEach(() => {
@@ -254,5 +262,132 @@ describe('Sync Down', () => {
254262
expect(storage.delete).toHaveBeenCalledWith('record', webSafe64FromBytes(recordUid))
255263
})
256264
})
265+
describe('Directly-Shared Records', () => {
266+
it('saves the record data when a record is direct-shared by other user', async () => {
267+
const decryptedRecordKey = platform.getRandomBytes(32)
268+
const recordKey = await platform.aesGcmEncrypt(decryptedRecordKey, auth.dataKey!)
269+
const recordUid = platform.getRandomBytes(16)
270+
const recordUidStr = webSafe64FromBytes(recordUid)
271+
const decryptedRecordData = {
272+
title: 'test record',
273+
}
274+
const decodedRecordData = platform.stringToBytes(JSON.stringify(decryptedRecordData))
275+
const recordData = await platform.aesGcmEncrypt(decodedRecordData, decryptedRecordKey)
276+
const userFolderRecord: Vault.IUserFolderRecord = {
277+
recordUid,
278+
revision: 1,
279+
}
280+
const recordMetadata: Vault.IRecordMetaData = {
281+
recordUid,
282+
recordKey,
283+
owner: false,
284+
canEdit: true,
285+
canShare: true,
286+
recordKeyType: Records.RecordKeyType.ENCRYPTED_BY_DATA_KEY_GCM,
287+
ownerUsername: anotherUserA.username,
288+
ownerAccountUid: anotherUserA.accountUid,
289+
}
290+
const record: Vault.IRecord = {
291+
recordUid,
292+
version: 3,
293+
data: recordData,
294+
extra: new Uint8Array([]),
295+
}
296+
syncDownResponseBuilder
297+
.addUserFolderRecord(userFolderRecord)
298+
.addRecordMetadata(recordMetadata)
299+
.addRecord(record)
300+
mockSyncDownCommand.mockResolvedValue(syncDownResponseBuilder.build())
301+
await syncDown({
302+
auth,
303+
storage,
304+
})
305+
expect(storage.put).toHaveBeenCalledWith(
306+
expect.objectContaining({
307+
kind: 'metadata',
308+
uid: recordUidStr,
309+
owner: recordMetadata.owner,
310+
ownerUsername: recordMetadata.ownerUsername,
311+
})
312+
)
313+
expect(storage.put).toHaveBeenCalledWith(
314+
expect.objectContaining({
315+
kind: 'record',
316+
uid: recordUidStr,
317+
data: decryptedRecordData,
318+
})
319+
)
320+
expect(storage.addDependencies).toHaveBeenCalledWith({
321+
"": new Set([{
322+
kind: "record",
323+
"parentUid": "",
324+
uid: recordUidStr,
325+
}])
326+
})
327+
})
328+
it('saves the record data when the direct-shared record is updated by another user or the user', async () => {
329+
const decryptedRecordKey = platform.getRandomBytes(32)
330+
const recordKey = await platform.aesGcmEncrypt(decryptedRecordKey, auth.dataKey!)
331+
const recordUid = platform.getRandomBytes(16)
332+
const recordUidStr = webSafe64FromBytes(recordUid)
333+
await platform.unwrapKey(recordKey, recordUidStr, 'data', 'gcm', 'aes')
334+
const decryptedRecordData = {
335+
title: 'test record updated',
336+
}
337+
const decodedRecordData = platform.stringToBytes(JSON.stringify(decryptedRecordData))
338+
const recordData = await platform.aesGcmEncrypt(decodedRecordData, decryptedRecordKey)
339+
const recordMetadata: Vault.IRecordMetaData = {
340+
recordUid,
341+
recordKey,
342+
owner: false,
343+
canEdit: true,
344+
canShare: true,
345+
recordKeyType: Records.RecordKeyType.ENCRYPTED_BY_DATA_KEY_GCM,
346+
ownerUsername: anotherUserA.username,
347+
ownerAccountUid: anotherUserA.accountUid,
348+
}
349+
const record: Vault.IRecord = {
350+
recordUid,
351+
version: 3,
352+
data: recordData,
353+
extra: new Uint8Array([]),
354+
}
355+
syncDownResponseBuilder
356+
.addRecord(record)
357+
.addRecordMetadata(recordMetadata)
358+
mockSyncDownCommand.mockResolvedValue(syncDownResponseBuilder.build())
359+
await syncDown({
360+
auth,
361+
storage,
362+
})
363+
expect(storage.put).toHaveBeenCalledWith(
364+
expect.objectContaining({
365+
kind: 'metadata',
366+
uid: recordUidStr,
367+
owner: recordMetadata.owner,
368+
ownerUsername: recordMetadata.ownerUsername,
369+
})
370+
)
371+
expect(storage.put).toHaveBeenCalledWith(
372+
expect.objectContaining({
373+
kind: 'record',
374+
uid: recordUidStr,
375+
data: decryptedRecordData,
376+
})
377+
)
378+
})
379+
it('deletes the record data when the direct-shared record is unshared by another user or deleted by the user', async () => {
380+
const recordUid = platform.getRandomBytes(16)
381+
syncDownResponseBuilder
382+
.addRemovedRecord(recordUid)
383+
mockSyncDownCommand.mockResolvedValue(syncDownResponseBuilder.build())
384+
await syncDown({
385+
auth,
386+
storage,
387+
})
388+
expect(storage.delete).toHaveBeenCalledWith('record', webSafe64FromBytes(recordUid))
389+
})
390+
it('does nothing when the direct-shared record is deleted by another user', () => {})
391+
})
257392
})
258393

0 commit comments

Comments
 (0)