mirror of
https://github.com/ramvignesh-b/pi-ku.git
synced 2026-05-04 08:56:52 +00:00
fix: update keystore nullish check
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
|
import { CryptoUtils } from "./crypto";
|
||||||
|
import { clearMasterKey, loadMasterKey, saveMasterKey } from "./keystore";
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
// clear to avoid in-memory db conflicts when running tests in parallel
|
||||||
|
await clearMasterKey();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function makeMasterKey() {
|
||||||
|
return CryptoUtils.deriveMasterKey("test-password", "test@example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("keystore", () => {
|
||||||
|
it("should save and load a CryptoKey successfully", async () => {
|
||||||
|
const key = await makeMasterKey();
|
||||||
|
|
||||||
|
await saveMasterKey(key);
|
||||||
|
const keyfromMemory = await loadMasterKey();
|
||||||
|
|
||||||
|
expect(keyfromMemory).toBeInstanceOf(CryptoKey);
|
||||||
|
expect(keyfromMemory).toEqual(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should remove the stored key from memory", async () => {
|
||||||
|
await saveMasterKey(await makeMasterKey());
|
||||||
|
await clearMasterKey();
|
||||||
|
|
||||||
|
const keyfromMemory = await loadMasterKey();
|
||||||
|
|
||||||
|
expect(keyfromMemory).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function generateTestKey() {
|
||||||
|
// generate a random 'extractable' key for testing
|
||||||
|
return crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, [
|
||||||
|
"encrypt",
|
||||||
|
"decrypt",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
it("should overwrite the previous key when calling saveMasterKey twice", async () => {
|
||||||
|
const key1 = await generateTestKey();
|
||||||
|
const key2 = await generateTestKey();
|
||||||
|
|
||||||
|
await saveMasterKey(key1);
|
||||||
|
await saveMasterKey(key2);
|
||||||
|
const loadedKey = await loadMasterKey();
|
||||||
|
const loadedJwk = await crypto.subtle.exportKey("jwk", loadedKey);
|
||||||
|
const key1Jwk = await crypto.subtle.exportKey("jwk", key1);
|
||||||
|
const key2Jwk = await crypto.subtle.exportKey("jwk", key2);
|
||||||
|
|
||||||
|
expect(loadedJwk).toStrictEqual(key2Jwk);
|
||||||
|
expect(loadedJwk).not.toStrictEqual(key1Jwk);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -7,11 +7,17 @@ const db = openDB("piku-keys", 1, {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const saveMasterKey = async (key: CryptoKey) =>
|
export const saveMasterKey = async (key: CryptoKey) => {
|
||||||
(await db).put("master-key", key, "masterKey");
|
const database = await db;
|
||||||
|
return await database.put("master-key", key, "masterKey");
|
||||||
|
};
|
||||||
|
|
||||||
export const loadMasterKey = async (): Promise<CryptoKey | null> =>
|
export const loadMasterKey = async (): Promise<CryptoKey | null> => {
|
||||||
(await db).get("master-key", "masterKey") ?? null;
|
const database = await db;
|
||||||
|
return (await database.get("master-key", "masterKey")) || null;
|
||||||
|
};
|
||||||
|
|
||||||
export const clearMasterKey = async () =>
|
export const clearMasterKey = async () => {
|
||||||
(await db).delete("master-key", "masterKey");
|
const database = await db;
|
||||||
|
return await database.delete("master-key", "masterKey");
|
||||||
|
};
|
||||||
|
|||||||
+1
-10
@@ -1,17 +1,8 @@
|
|||||||
import "@testing-library/jest-dom";
|
import "@testing-library/jest-dom";
|
||||||
import { IDBFactory } from "fake-indexeddb";
|
import "fake-indexeddb/auto"; // auto configures the indexedDB
|
||||||
import { afterAll, afterEach, beforeAll } from "vitest";
|
import { afterAll, afterEach, beforeAll } from "vitest";
|
||||||
import { server } from "./mocks/server";
|
import { server } from "./mocks/server";
|
||||||
|
|
||||||
/**
|
|
||||||
* faking indexeddb in memory for testing crypto key storage
|
|
||||||
*/
|
|
||||||
Object.defineProperty(globalThis, "indexedDB", {
|
|
||||||
value: new IDBFactory(),
|
|
||||||
writable: true,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeAll(() => server.listen({ onUnhandledRequest: "warn" }));
|
beforeAll(() => server.listen({ onUnhandledRequest: "warn" }));
|
||||||
afterEach(() => server.resetHandlers());
|
afterEach(() => server.resetHandlers());
|
||||||
afterAll(() => server.close());
|
afterAll(() => server.close());
|
||||||
|
|||||||
Reference in New Issue
Block a user