diff --git a/packages/app/src/background/cryptKeeper.ts b/packages/app/src/background/cryptKeeper.ts index 9be425652..285c556a5 100644 --- a/packages/app/src/background/cryptKeeper.ts +++ b/packages/app/src/background/cryptKeeper.ts @@ -11,7 +11,7 @@ import RequestManager from "./controllers/requestManager"; import ApprovalService from "./services/approval"; import BackupService from "./services/backup"; import VerifiableCredentialsService from "./services/credentials"; -import { validateSerializedVerifiableCredential } from "./services/credentials/utils"; +import { validateSerializedVC } from "./services/credentials/utils"; import { GroupService } from "./services/group"; import HistoryService from "./services/history"; import InjectorService from "./services/injector"; @@ -210,58 +210,58 @@ export default class CryptKeeperController { this.handler.add( RPCAction.ADD_VERIFIABLE_CREDENTIAL, this.lockService.ensure, - this.verifiableCredentialsService.addVerifiableCredential, + this.verifiableCredentialsService.addVC, ); this.handler.add( RPCAction.ADD_VERIFIABLE_CREDENTIAL_REQUEST, this.lockService.ensure, - validateSerializedVerifiableCredential, - this.verifiableCredentialsService.addVerifiableCredentialRequest, + validateSerializedVC, + this.verifiableCredentialsService.addVCRequest, ); this.handler.add( RPCAction.REJECT_VERIFIABLE_CREDENTIAL_REQUEST, this.lockService.ensure, - this.verifiableCredentialsService.rejectVerifiableCredentialRequest, + this.verifiableCredentialsService.rejectVCRequest, ); this.handler.add( RPCAction.RENAME_VERIFIABLE_CREDENTIAL, this.lockService.ensure, - this.verifiableCredentialsService.renameVerifiableCredential, + this.verifiableCredentialsService.renameVC, ); this.handler.add( RPCAction.GET_ALL_VERIFIABLE_CREDENTIALS, this.lockService.ensure, - this.verifiableCredentialsService.getAllVerifiableCredentials, + this.verifiableCredentialsService.getAllVC, ); this.handler.add( RPCAction.DELETE_VERIFIABLE_CREDENTIAL, this.lockService.ensure, - this.verifiableCredentialsService.deleteVerifiableCredential, + this.verifiableCredentialsService.deleteVC, ); this.handler.add( RPCAction.DELETE_ALL_VERIFIABLE_CREDENTIALS, this.lockService.ensure, - this.verifiableCredentialsService.deleteAllVerifiableCredentials, + this.verifiableCredentialsService.deleteAllVC, ); this.handler.add( RPCAction.GENERATE_VERIFIABLE_PRESENTATION, this.lockService.ensure, - this.verifiableCredentialsService.generateVerifiablePresentation, + this.verifiableCredentialsService.announceVP, ); this.handler.add( RPCAction.GENERATE_VERIFIABLE_PRESENTATION_WITH_CRYPTKEEPER, this.lockService.ensure, - this.verifiableCredentialsService.generateVerifiablePresentationWithCryptkeeper, + this.verifiableCredentialsService.signAndAnnounceVP, ); this.handler.add( RPCAction.GENERATE_VERIFIABLE_PRESENTATION_REQUEST, this.lockService.ensure, - this.verifiableCredentialsService.generateVerifiablePresentationRequest, + this.verifiableCredentialsService.handleVPRequest, ); this.handler.add( RPCAction.REJECT_VERIFIABLE_PRESENTATION_REQUEST, this.lockService.ensure, - this.verifiableCredentialsService.rejectVerifiablePresentationRequest, + this.verifiableCredentialsService.rejectVPRequest, ); // Injector diff --git a/packages/app/src/background/services/credentials/__tests__/credentials.test.ts b/packages/app/src/background/services/credentials/__tests__/credentials.test.ts index bb8270799..236f08cf8 100644 --- a/packages/app/src/background/services/credentials/__tests__/credentials.test.ts +++ b/packages/app/src/background/services/credentials/__tests__/credentials.test.ts @@ -1,12 +1,12 @@ /* eslint-disable @typescript-eslint/unbound-method */ -import { EventName } from "@cryptkeeperzk/providers"; +import { EventName } from "@cryptkeeperzk/providers/dist/src/event"; import browser from "webextension-polyfill"; import VerifiableCredentialsService from "@src/background/services/credentials"; import { - generateInitialMetadataForVerifiableCredential, - serializeCryptkeeperVerifiableCredential, - serializeVerifiableCredential, + generateInitialMetadataForVC, + serializeCryptkeeperVC, + serializeVC, } from "@src/background/services/credentials/utils"; import SimpleStorage from "@src/background/services/storage"; import pushMessage from "@src/util/pushMessage"; @@ -60,17 +60,14 @@ describe("background/services/credentials", () => { }, }, }; - const exampleCredentialString = serializeVerifiableCredential(exampleCredential); - const exampleCredentialMetadata = generateInitialMetadataForVerifiableCredential( - exampleCredential, - defaultCredentialName, - ); + const exampleCredentialString = serializeVC(exampleCredential); + const exampleCredentialMetadata = generateInitialMetadataForVC(exampleCredential, defaultCredentialName); const exampleCredentialHash = exampleCredentialMetadata.hash; const exampleCryptkeeperCredential: ICryptkeeperVerifiableCredential = { verifiableCredential: exampleCredential, metadata: exampleCredentialMetadata, }; - const exampleCryptkeeperCredentialString = serializeCryptkeeperVerifiableCredential(exampleCryptkeeperCredential); + const exampleCryptkeeperCredentialString = serializeCryptkeeperVC(exampleCryptkeeperCredential); const exampleCredentialTwo: IVerifiableCredential = { context: ["https://www.w3.org/2018/credentials/v1"], @@ -85,19 +82,14 @@ describe("background/services/credentials", () => { }, }, }; - const exampleCredentialStringTwo = serializeVerifiableCredential(exampleCredentialTwo); - const exampleCredentialMetadataTwo = generateInitialMetadataForVerifiableCredential( - exampleCredentialTwo, - defaultCredentialName, - ); + const exampleCredentialStringTwo = serializeVC(exampleCredentialTwo); + const exampleCredentialMetadataTwo = generateInitialMetadataForVC(exampleCredentialTwo, defaultCredentialName); const exampleCredentialHashTwo = exampleCredentialMetadataTwo.hash; const exampleCryptkeeperCredentialTwo: ICryptkeeperVerifiableCredential = { verifiableCredential: exampleCredentialTwo, metadata: exampleCredentialMetadataTwo, }; - const exampleCryptkeeperCredentialStringTwo = serializeCryptkeeperVerifiableCredential( - exampleCryptkeeperCredentialTwo, - ); + const exampleCryptkeeperCredentialStringTwo = serializeCryptkeeperVC(exampleCryptkeeperCredentialTwo); const credentialsMap = new Map(); credentialsMap.set(exampleCredentialHash, exampleCryptkeeperCredentialString); @@ -147,7 +139,7 @@ describe("background/services/credentials", () => { describe("add and reject verifiable credential requests", () => { test("should successfully create an add verifiable credential request", async () => { - await verifiableCredentialsService.addVerifiableCredentialRequest(exampleCredentialString); + await verifiableCredentialsService.addVCRequest(exampleCredentialString); expect(browser.tabs.query).toBeCalledWith({ lastFocusedWindow: true }); @@ -163,7 +155,7 @@ describe("background/services/credentials", () => { }); test("should successfully reject a verifiable credential request", async () => { - await verifiableCredentialsService.rejectVerifiableCredentialRequest(); + await verifiableCredentialsService.rejectVCRequest(); expect(browser.tabs.query).toBeCalledWith({ lastFocusedWindow: true }); expect(browser.tabs.sendMessage).toBeCalledWith(defaultTabs[0].id, { @@ -175,7 +167,7 @@ describe("background/services/credentials", () => { describe("generate verifiable presentations", () => { test("should successfully create a generate verifiable presentation request", async () => { - await verifiableCredentialsService.generateVerifiablePresentationRequest(exampleVerifiablePresentationRequest); + await verifiableCredentialsService.handleVPRequest(exampleVerifiablePresentationRequest); expect(browser.tabs.query).toBeCalledWith({ lastFocusedWindow: true }); @@ -191,7 +183,7 @@ describe("background/services/credentials", () => { }); test("should successfully reject a verifiable presentation request", async () => { - await verifiableCredentialsService.rejectVerifiablePresentationRequest(); + await verifiableCredentialsService.rejectVPRequest(); expect(browser.tabs.query).toBeCalledWith({ lastFocusedWindow: true }); expect(browser.tabs.sendMessage).toBeCalledWith(defaultTabs[0].id, { @@ -201,7 +193,7 @@ describe("background/services/credentials", () => { }); test("should successfully generate a verifiable presentation", async () => { - await verifiableCredentialsService.generateVerifiablePresentation(exampleVerifiablePresentation); + await verifiableCredentialsService.announceVP(exampleVerifiablePresentation); expect(browser.tabs.query).toBeCalledWith({ lastFocusedWindow: true }); expect(browser.tabs.sendMessage).toBeCalledWith(defaultTabs[0].id, { @@ -215,7 +207,7 @@ describe("background/services/credentials", () => { const ETHEREUM_SIGNATURE_SPECIFICATION_TYPE = "EthereumEip712Signature2021"; const VERIFIABLE_CREDENTIAL_PROOF_PURPOSE = "assertionMethod"; - await verifiableCredentialsService.generateVerifiablePresentationWithCryptkeeper({ + await verifiableCredentialsService.signAndAnnounceVP({ verifiablePresentation: exampleVerifiablePresentation, address: exampleAddress, }); @@ -247,7 +239,7 @@ describe("background/services/credentials", () => { credentialsStorage.get.mockReturnValue(undefined); credentialsStorage.set.mockReturnValue(undefined); - const result = verifiableCredentialsService.addVerifiableCredential({ + const result = verifiableCredentialsService.addVC({ serializedVerifiableCredential: exampleCredentialString, verifiableCredentialName: defaultCredentialName, }); @@ -259,17 +251,17 @@ describe("background/services/credentials", () => { const [credentialsStorage] = (SimpleStorage as jest.Mock).mock.instances as [MockStorage]; credentialsStorage.get.mockReturnValue(undefined); - await verifiableCredentialsService.addVerifiableCredential({ + await verifiableCredentialsService.addVC({ serializedVerifiableCredential: exampleCredentialString, verifiableCredentialName: defaultCredentialName, }); - await verifiableCredentialsService.addVerifiableCredential({ + await verifiableCredentialsService.addVC({ serializedVerifiableCredential: exampleCredentialStringTwo, verifiableCredentialName: defaultCredentialName, }); credentialsStorage.get.mockReturnValue(credentialsStorageString); - const verifiableCredentials = await verifiableCredentialsService.getAllVerifiableCredentials(); + const verifiableCredentials = await verifiableCredentialsService.getAllVC(); expect(verifiableCredentials.length).toBe(2); expect(verifiableCredentials[0].verifiableCredential).toEqual(exampleCredential); @@ -282,7 +274,7 @@ describe("background/services/credentials", () => { credentialsStorage.set.mockReturnValue(undefined); await expect( - verifiableCredentialsService.addVerifiableCredential({ + verifiableCredentialsService.addVC({ serializedVerifiableCredential: exampleCredentialString, verifiableCredentialName: defaultCredentialName, }), @@ -291,7 +283,7 @@ describe("background/services/credentials", () => { test("should not add a verifiable credential with an invalid format", async () => { await expect( - verifiableCredentialsService.addVerifiableCredential({ + verifiableCredentialsService.addVC({ serializedVerifiableCredential: "invalid credential", verifiableCredentialName: "test name", }), @@ -305,7 +297,7 @@ describe("background/services/credentials", () => { credentialsStorage.get.mockReturnValue(credentialsStorageString); credentialsStorage.set.mockReturnValue(undefined); - await verifiableCredentialsService.deleteVerifiableCredential(exampleCredentialHash); + await verifiableCredentialsService.deleteVC(exampleCredentialHash); expect(credentialsStorage.set).toBeCalledTimes(1); expect(credentialsStorage.set).toBeCalledWith(JSON.stringify([[...credentialsMap.entries()][1]])); @@ -316,7 +308,7 @@ describe("background/services/credentials", () => { credentialsStorage.get.mockReturnValue(credentialsStorageString); credentialsStorage.set.mockReturnValue(undefined); - await expect(verifiableCredentialsService.deleteVerifiableCredential("example hash")).rejects.toThrow( + await expect(verifiableCredentialsService.deleteVC("example hash")).rejects.toThrow( "Verifiable Credential does not exist.", ); expect(credentialsStorage.set).toBeCalledTimes(0); @@ -327,7 +319,7 @@ describe("background/services/credentials", () => { credentialsStorage.get.mockReturnValue(credentialsStorageString); credentialsStorage.set.mockReturnValue(undefined); - await verifiableCredentialsService.deleteAllVerifiableCredentials(); + await verifiableCredentialsService.deleteAllVC(); expect(credentialsStorage.clear).toBeCalledTimes(1); }); @@ -337,9 +329,7 @@ describe("background/services/credentials", () => { credentialsStorage.get.mockReturnValue(undefined); credentialsStorage.set.mockReturnValue(undefined); - await expect(verifiableCredentialsService.deleteAllVerifiableCredentials()).rejects.toThrow( - "No Verifiable Credentials to delete.", - ); + await expect(verifiableCredentialsService.deleteAllVC()).rejects.toThrow("No Verifiable Credentials to delete."); expect(credentialsStorage.clear).toBeCalledTimes(0); }); }); diff --git a/packages/app/src/background/services/credentials/__tests__/utils.test.ts b/packages/app/src/background/services/credentials/__tests__/utils.test.ts index 61bb1c990..ae65d3873 100644 --- a/packages/app/src/background/services/credentials/__tests__/utils.test.ts +++ b/packages/app/src/background/services/credentials/__tests__/utils.test.ts @@ -2,17 +2,17 @@ import stringify from "json-stable-stringify"; import * as yup from "yup"; import { - serializeCryptkeeperVerifiableCredential, - deserializeCryptkeeperVerifiableCredential, - serializeVerifiableCredential, - deserializeVerifiableCredential, - validateSerializedVerifiableCredential, - generateInitialMetadataForVerifiableCredential, - hashVerifiableCredential, - serializeVerifiablePresentation, + serializeCryptkeeperVC, + deserializeCryptkeeperVC, + serializeVC, + deserializeVC, + validateSerializedVC, + generateInitialMetadataForVC, + hashVC, + serializeVP, } from "../utils"; -describe("util/serializeCryptkeeperVerifiableCredential", () => { +describe("util/serializeCryptkeeperVC", () => { test("should serialize and deserialize CryptkeeperVerifiableCredential object correctly", async () => { const defaultCredentialName = "Verifiable Credential"; const rawCredential = { @@ -27,23 +27,21 @@ describe("util/serializeCryptkeeperVerifiableCredential", () => { }, }, }; - const metadata = generateInitialMetadataForVerifiableCredential(rawCredential, defaultCredentialName); + const metadata = generateInitialMetadataForVC(rawCredential, defaultCredentialName); const cryptkeeperCred = { verifiableCredential: rawCredential, metadata, }; - const serializedCred = serializeCryptkeeperVerifiableCredential(cryptkeeperCred); - const deserializedCred = await deserializeCryptkeeperVerifiableCredential(serializedCred); + const serializedCred = serializeCryptkeeperVC(cryptkeeperCred); + const deserializedCred = await deserializeCryptkeeperVC(serializedCred); expect(deserializedCred.verifiableCredential).toStrictEqual(rawCredential); expect(deserializedCred.metadata).toStrictEqual(metadata); - expect(serializeCryptkeeperVerifiableCredential(deserializedCred)).toBe( - serializeCryptkeeperVerifiableCredential(cryptkeeperCred), - ); + expect(serializeCryptkeeperVC(deserializedCred)).toBe(serializeCryptkeeperVC(cryptkeeperCred)); }); }); -describe("util/serializeVerifiablePresentation", () => { +describe("util/serializeVP", () => { test("should serialize a verifiable presentation correctly", () => { const rawCredential = { context: ["https://www.w3.org/2018/credentials/v1"], @@ -63,8 +61,8 @@ describe("util/serializeVerifiablePresentation", () => { verifiableCredential: [rawCredential], }; - expect(serializeVerifiablePresentation(verifiablePresentation)).toStrictEqual( - stringify({ ...verifiablePresentation, verifiableCredential: [serializeVerifiableCredential(rawCredential)] }), + expect(serializeVP(verifiablePresentation)).toStrictEqual( + stringify({ ...verifiablePresentation, verifiableCredential: [serializeVC(rawCredential)] }), ); }); @@ -74,11 +72,11 @@ describe("util/serializeVerifiablePresentation", () => { type: ["VerifiablePresentation"], }; - expect(serializeVerifiablePresentation(verifiablePresentation)).toStrictEqual(stringify(verifiablePresentation)); + expect(serializeVP(verifiablePresentation)).toStrictEqual(stringify(verifiablePresentation)); }); }); -describe("util/deserializeVerifiableCredential", () => { +describe("util/deserializeVC", () => { test("should deserialize a verifiable credential correctly", async () => { const rawCredential = { context: ["https://www.w3.org/2018/credentials/v1"], @@ -92,15 +90,15 @@ describe("util/deserializeVerifiableCredential", () => { }, }, }; - const credJson = serializeVerifiableCredential(rawCredential); - const deserializedCred = await deserializeVerifiableCredential(credJson); + const credJson = serializeVC(rawCredential); + const deserializedCred = await deserializeVC(credJson); expect(deserializedCred).toStrictEqual(rawCredential); - expect(serializeVerifiableCredential(deserializedCred)).toBe(credJson); + expect(serializeVC(deserializedCred)).toBe(credJson); }); }); -describe("util/validateSerializedVerifiableCredential", () => { +describe("util/validateSerializedVC", () => { test("should correctly validate a valid verifiable credential", async () => { const rawCredential = { context: ["https://www.w3.org/2018/credentials/v1"], @@ -114,16 +112,16 @@ describe("util/validateSerializedVerifiableCredential", () => { }, }, }; - const credJson = serializeVerifiableCredential(rawCredential); - const cred = await deserializeVerifiableCredential(credJson); + const credJson = serializeVC(rawCredential); + const cred = await deserializeVC(credJson); expect(cred).not.toBeNull(); - expect(validateSerializedVerifiableCredential(credJson)).not.toBeNull(); + expect(validateSerializedVC(credJson)).not.toBeNull(); }); test("should return null if the string is not valid JSON", async () => { const rawCredential = "asdf"; - await expect(deserializeVerifiableCredential(rawCredential)).rejects.toThrow(SyntaxError); + await expect(deserializeVC(rawCredential)).rejects.toThrow(SyntaxError); }); test("should return false if the context property is not an array", async () => { @@ -141,7 +139,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if context entries are not strings", async () => { @@ -159,7 +157,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the id property is not a string", async () => { @@ -178,7 +176,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the type property is not an array", async () => { @@ -196,7 +194,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the type array entries are not strings", async () => { @@ -214,7 +212,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the issuer property does not exist", async () => { @@ -231,7 +229,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the issuer property is not a string", async () => { @@ -249,7 +247,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the issuance date does not exist", async () => { @@ -266,7 +264,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the issuance date is not a date", async () => { @@ -284,7 +282,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the expiration date is not a date", async () => { @@ -303,7 +301,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the subject property does not exist", async () => { @@ -315,7 +313,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the subject id is not a string", async () => { @@ -333,7 +331,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the claims are not of valid format", async () => { @@ -353,7 +351,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the status id is not a string", async () => { @@ -375,7 +373,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the status type is not a string", async () => { @@ -397,7 +395,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the proof id is not a string", async () => { @@ -425,7 +423,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the proof type is not a string", async () => { @@ -453,7 +451,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the proof purpose is not a string", async () => { @@ -481,7 +479,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the proof verification method is not a string", async () => { @@ -509,7 +507,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the proof created time is not a date", async () => { @@ -537,7 +535,7 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); test("should return false if the proof value is not a string", async () => { @@ -565,11 +563,11 @@ describe("util/validateSerializedVerifiableCredential", () => { }; const credentialJson = stringify(rawCredential); - await expect(deserializeVerifiableCredential(credentialJson)).rejects.toThrow(yup.ValidationError); + await expect(deserializeVC(credentialJson)).rejects.toThrow(yup.ValidationError); }); }); -describe("util/hashVerifiableCredential", () => { +describe("util/hashVC", () => { test("should produce deterministic hashes", () => { const credOne = { context: ["https://www.w3.org/2018/credentials/v1"], @@ -596,7 +594,7 @@ describe("util/hashVerifiableCredential", () => { }, }; - expect(hashVerifiableCredential(credOne)).toBe(hashVerifiableCredential(credTwo)); + expect(hashVC(credOne)).toBe(hashVC(credTwo)); }); test("should produce the same hash after serialization/deserialization", async () => { @@ -612,14 +610,14 @@ describe("util/hashVerifiableCredential", () => { }, }, }; - const credJson = serializeVerifiableCredential(cred); - const deserializedCred = await deserializeVerifiableCredential(credJson); + const credJson = serializeVC(cred); + const deserializedCred = await deserializeVC(credJson); - expect(hashVerifiableCredential(cred)).toBe(hashVerifiableCredential(deserializedCred)); + expect(hashVC(cred)).toBe(hashVC(deserializedCred)); }); }); -describe("util/generateInitialMetadataForVerifiableCredential", () => { +describe("util/generateInitialMetadataForVC", () => { const defaultCredentialName = "Verifiable Credential"; test("should generate the correct metadata for a verifiable credential", () => { @@ -635,10 +633,10 @@ describe("util/generateInitialMetadataForVerifiableCredential", () => { }, }, }; - const metadata = generateInitialMetadataForVerifiableCredential(rawCredential, defaultCredentialName); + const metadata = generateInitialMetadataForVC(rawCredential, defaultCredentialName); const expectedMetadata = { name: "Verifiable Credential", - hash: hashVerifiableCredential(rawCredential), + hash: hashVC(rawCredential), }; expect(metadata).toStrictEqual(expectedMetadata); diff --git a/packages/app/src/background/services/credentials/index.ts b/packages/app/src/background/services/credentials/index.ts index c09a26215..9127d9780 100644 --- a/packages/app/src/background/services/credentials/index.ts +++ b/packages/app/src/background/services/credentials/index.ts @@ -1,10 +1,10 @@ -import { EventName } from "@cryptkeeperzk/providers"; +import { EventName } from "@cryptkeeperzk/providers/dist/src/event"; import browser from "webextension-polyfill"; import BrowserUtils from "@src/background/controllers/browserUtils"; import CryptoService, { ECryptMode } from "@src/background/services/crypto"; import HistoryService from "@src/background/services/history"; -import NotificationService from "@src/background/services/notification"; +import NotificationService, { ICreateNotificationOptions } from "@src/background/services/notification"; import SimpleStorage from "@src/background/services/storage"; import WalletService from "@src/background/services/wallet"; import { Paths } from "@src/constants"; @@ -18,18 +18,27 @@ import type { } from "@src/types/verifiableCredentials"; import { - generateInitialMetadataForVerifiableCredential, - serializeCryptkeeperVerifiableCredential, - deserializeVerifiableCredential, - deserializeCryptkeeperVerifiableCredential, - validateSerializedVerifiableCredential, - serializeVerifiablePresentation, + generateInitialMetadataForVC, + serializeCryptkeeperVC, + deserializeVC, + deserializeCryptkeeperVC, + validateSerializedVC, + serializeVP, } from "./utils"; const VERIFIABLE_CREDENTIALS_KEY = "@@VERIFIABLE-CREDENTIALS@@"; const ETHEREUM_SIGNATURE_SPECIFICATION_TYPE = "EthereumEip712Signature2021"; const VERIFIABLE_CREDENTIAL_PROOF_PURPOSE = "assertionMethod"; +interface IAnnounceVCArgs { + notificationTitle: ICreateNotificationOptions["title"]; + notificationMessage: ICreateNotificationOptions["message"]; + notificationType: ICreateNotificationOptions["type"]; + historyOperationType?: OperationType; + responseType?: EventName; + responsePayload?: unknown; +} + export default class VerifiableCredentialsService implements IBackupable { private static INSTANCE?: VerifiableCredentialsService; @@ -62,156 +71,128 @@ export default class VerifiableCredentialsService implements IBackupable { return VerifiableCredentialsService.INSTANCE; } - addVerifiableCredentialRequest = async (serializedVerifiableCredential: string): Promise => { - await validateSerializedVerifiableCredential(serializedVerifiableCredential); + addVCRequest = async (serializedVerifiableCredential: string): Promise => { + await validateSerializedVC(serializedVerifiableCredential); await this.browserController.openPopup({ params: { redirect: Paths.ADD_VERIFIABLE_CREDENTIAL, serializedVerifiableCredential }, }); }; - rejectVerifiableCredentialRequest = async (): Promise => { - await this.notificationService.create({ - options: { - title: "Request rejected", - message: `Rejected a request to add Verifiable Credential.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + rejectVCRequest = async (): Promise => { + await this.announce({ + notificationTitle: "Request rejected", + notificationMessage: `Rejected a request to add Verifiable Credential.`, + notificationType: "basic", + historyOperationType: OperationType.REJECT_VERIFIABLE_CREDENTIAL_REQUEST, + responseType: EventName.USER_REJECT, + responsePayload: { type: EventName.ADD_VERIFIABLE_CREDENTIAL }, }); - - const tabs = await browser.tabs.query({ active: true }); - await Promise.all( - tabs.map((tab) => - browser.tabs - .sendMessage(tab.id!, { - type: EventName.USER_REJECT, - payload: { type: EventName.ADD_VERIFIABLE_CREDENTIAL }, - }) - .catch(() => undefined), - ), - ); }; - addVerifiableCredential = async (addVerifiableCredentialArgs: IAddVerifiableCredentialArgs): Promise => { - const { serializedVerifiableCredential, verifiableCredentialName } = addVerifiableCredentialArgs; + addVC = async (addVCArgs: IAddVerifiableCredentialArgs): Promise => { + const { serializedVerifiableCredential, verifiableCredentialName } = addVCArgs; if (!serializedVerifiableCredential) { throw new Error("Serialized Verifiable Credential is required."); } try { - const verifiableCredential = await deserializeVerifiableCredential(serializedVerifiableCredential); - const metadata = generateInitialMetadataForVerifiableCredential(verifiableCredential, verifiableCredentialName); + const verifiableCredential = await deserializeVC(serializedVerifiableCredential); + const metadata = generateInitialMetadataForVC(verifiableCredential, verifiableCredentialName); const cryptkeeperVerifiableCredential: ICryptkeeperVerifiableCredential = { verifiableCredential, metadata, }; - await this.insertCryptkeeperVerifiableCredentialIntoStore(cryptkeeperVerifiableCredential); + await this.insertCryptkeeperVCIntoStore(cryptkeeperVerifiableCredential); } catch (error) { - await this.notificationService.create({ - options: { - title: "Failed to add Verifiable Credential.", - message: `The Verifiable Credential you are trying to add is invalid.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + await this.announce({ + notificationTitle: "Failed to add Verifiable Credential.", + notificationMessage: `The Verifiable Credential you are trying to add is invalid.`, + notificationType: "basic", }); - throw error; } }; - renameVerifiableCredential = async ( - renameVerifiableCredentialArgs: IRenameVerifiableCredentialArgs, - ): Promise => { - const { verifiableCredentialHash, newVerifiableCredentialName } = renameVerifiableCredentialArgs; + renameVC = async (renameVCArgs: IRenameVerifiableCredentialArgs): Promise => { + const { verifiableCredentialHash, newVerifiableCredentialName } = renameVCArgs; if (!verifiableCredentialHash || !newVerifiableCredentialName) { throw new Error("Verifiable Credential hash and name are required."); } - const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVerifiableCredentialsFromStore(); + const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVCFromStore(); if (!cryptkeeperVerifiableCredentials.has(verifiableCredentialHash)) { throw new Error("Verifiable Credential does not exist."); } const serializedCryptkeeperVerifiableCredential = cryptkeeperVerifiableCredentials.get(verifiableCredentialHash)!; - const cryptkeeperVerifiableCredential = await deserializeCryptkeeperVerifiableCredential( - serializedCryptkeeperVerifiableCredential, - ); + const cryptkeeperVerifiableCredential = await deserializeCryptkeeperVC(serializedCryptkeeperVerifiableCredential); cryptkeeperVerifiableCredential.metadata.name = newVerifiableCredentialName; cryptkeeperVerifiableCredentials.set( verifiableCredentialHash, - serializeCryptkeeperVerifiableCredential(cryptkeeperVerifiableCredential), + serializeCryptkeeperVC(cryptkeeperVerifiableCredential), ); - await this.writeCryptkeeperVerifiableCredentials(cryptkeeperVerifiableCredentials); - await this.historyService.trackOperation(OperationType.RENAME_VERIFIABLE_CREDENTIAL, {}); - await this.notificationService.create({ - options: { - title: "Verifiable Credential renamed.", - message: `Renamed 1 Verifiable Credential.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + await this.writeCryptkeeperVC(cryptkeeperVerifiableCredentials); + await this.announce({ + notificationTitle: "Verifiable Credential renamed.", + notificationMessage: `Renamed 1 Verifiable Credential.`, + notificationType: "basic", + historyOperationType: OperationType.RENAME_VERIFIABLE_CREDENTIAL, }); }; - getAllVerifiableCredentials = async (): Promise => { - const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVerifiableCredentialsFromStore(); + getAllVC = async (): Promise => { + const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVCFromStore(); const cryptkeeperVerifiableCredentialsArray = Array.from(cryptkeeperVerifiableCredentials.values()); return Promise.all( cryptkeeperVerifiableCredentialsArray.map(async (cryptkeeperVerifiableCredential) => - deserializeCryptkeeperVerifiableCredential(cryptkeeperVerifiableCredential), + deserializeCryptkeeperVC(cryptkeeperVerifiableCredential), ), ); }; - deleteVerifiableCredential = async (verifiableCredentialHash: string): Promise => { + deleteVC = async (verifiableCredentialHash: string): Promise => { if (!verifiableCredentialHash) { throw new Error("Verifiable Credential hash is required."); } - const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVerifiableCredentialsFromStore(); + const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVCFromStore(); if (!cryptkeeperVerifiableCredentials.has(verifiableCredentialHash)) { throw new Error("Verifiable Credential does not exist."); } cryptkeeperVerifiableCredentials.delete(verifiableCredentialHash); - await this.writeCryptkeeperVerifiableCredentials(cryptkeeperVerifiableCredentials); - await this.historyService.trackOperation(OperationType.DELETE_VERIFIABLE_CREDENTIAL, {}); - await this.notificationService.create({ - options: { - title: "Verifiable Credential deleted.", - message: `Deleted 1 Verifiable Credential.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + await this.writeCryptkeeperVC(cryptkeeperVerifiableCredentials); + + await this.announce({ + notificationTitle: "Verifiable Credential deleted.", + notificationMessage: `Deleted 1 Verifiable Credential.`, + notificationType: "basic", + historyOperationType: OperationType.DELETE_VERIFIABLE_CREDENTIAL, }); }; - deleteAllVerifiableCredentials = async (): Promise => { - const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVerifiableCredentialsFromStore(); + deleteAllVC = async (): Promise => { + const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVCFromStore(); if (cryptkeeperVerifiableCredentials.size === 0) { throw new Error("No Verifiable Credentials to delete."); } await this.verifiableCredentialsStore.clear(); - await this.historyService.trackOperation(OperationType.DELETE_ALL_VERIFIABLE_CREDENTIALS, {}); - await this.notificationService.create({ - options: { - title: "All Verifiable Credentials deleted.", - message: `Deleted ${cryptkeeperVerifiableCredentials.size} Verifiable Credential(s).`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + await this.announce({ + notificationTitle: "All Verifiable Credentials deleted.", + notificationMessage: `Deleted ${cryptkeeperVerifiableCredentials.size} Verifiable Credential(s).`, + notificationType: "basic", + historyOperationType: OperationType.DELETE_ALL_VERIFIABLE_CREDENTIALS, }); }; - generateVerifiablePresentationRequest = async ({ request }: IVerifiablePresentationRequest): Promise => { + handleVPRequest = async ({ request }: IVerifiablePresentationRequest): Promise => { await this.browserController.openPopup({ params: { redirect: Paths.GENERATE_VERIFIABLE_PRESENTATION_REQUEST, @@ -220,34 +201,22 @@ export default class VerifiableCredentialsService implements IBackupable { }); }; - generateVerifiablePresentation = async (verifiablePresentation: IVerifiablePresentation): Promise => { - await this.historyService.trackOperation(OperationType.GENERATE_VERIFIABLE_PRESENTATION, {}); - await this.notificationService.create({ - options: { - title: "Verifiable Presentation generated.", - message: `Generated 1 Verifiable Presentation.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + announceVP = async (verifiablePresentation: IVerifiablePresentation): Promise => { + await this.announce({ + notificationTitle: "Verifiable Presentation generated.", + notificationMessage: `Generated 1 Verifiable Presentation.`, + notificationType: "basic", + historyOperationType: OperationType.GENERATE_VERIFIABLE_PRESENTATION, + responseType: EventName.GENERATE_VERIFIABLE_PRESENTATION, + responsePayload: { verifiablePresentation }, }); - const tabs = await browser.tabs.query({ active: true }); - await Promise.all( - tabs.map((tab) => - browser.tabs - .sendMessage(tab.id!, { - type: EventName.GENERATE_VERIFIABLE_PRESENTATION, - payload: { verifiablePresentation }, - }) - .catch(() => undefined), - ), - ); }; - generateVerifiablePresentationWithCryptkeeper = async ({ + signAndAnnounceVP = async ({ verifiablePresentation, address, }: IGenerateVerifiablePresentationWithCryptkeeperArgs): Promise => { - const serializedVerifiablePresentation = serializeVerifiablePresentation(verifiablePresentation); + const serializedVerifiablePresentation = serializeVP(verifiablePresentation); const signature = await this.walletService.signMessage({ message: serializedVerifiablePresentation, address, @@ -265,66 +234,39 @@ export default class VerifiableCredentialsService implements IBackupable { ], }; - await this.historyService.trackOperation(OperationType.GENERATE_VERIFIABLE_PRESENTATION, {}); - await this.notificationService.create({ - options: { - title: "Verifiable Presentation generated.", - message: `Generated 1 Verifiable Presentation.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + await this.announce({ + notificationTitle: "Verifiable Presentation generated.", + notificationMessage: `Generated 1 Verifiable Presentation.`, + notificationType: "basic", + historyOperationType: OperationType.GENERATE_VERIFIABLE_PRESENTATION, + responseType: EventName.GENERATE_VERIFIABLE_PRESENTATION, + responsePayload: { verifiablePresentation: signedVerifiablePresentation }, }); - const tabs = await browser.tabs.query({ active: true }); - await Promise.all( - tabs.map((tab) => - browser.tabs - .sendMessage(tab.id!, { - type: EventName.GENERATE_VERIFIABLE_PRESENTATION, - payload: { verifiablePresentation: signedVerifiablePresentation }, - }) - .catch(() => undefined), - ), - ); }; - rejectVerifiablePresentationRequest = async (): Promise => { - await this.historyService.trackOperation(OperationType.REJECT_VERIFIABLE_PRESENTATION_REQUEST, {}); - await this.notificationService.create({ - options: { - title: "Request to generate Verifiable Presentation rejected", - message: `Rejected a request to generate 1 Verifiable Presentation.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + rejectVPRequest = async (): Promise => { + await this.announce({ + notificationTitle: "Request to generate Verifiable Presentation rejected", + notificationMessage: `Rejected a request to generate Verifiable Presentation.`, + notificationType: "basic", + historyOperationType: OperationType.REJECT_VERIFIABLE_PRESENTATION_REQUEST, + responseType: EventName.USER_REJECT, + responsePayload: { type: EventName.VERIFIABLE_PRESENTATION_REQUEST }, }); - const tabs = await browser.tabs.query({ active: true }); - await Promise.all( - tabs.map((tab) => - browser.tabs - .sendMessage(tab.id!, { - type: EventName.USER_REJECT, - payload: { type: EventName.VERIFIABLE_PRESENTATION_REQUEST }, - }) - .catch(() => undefined), - ), - ); }; - private insertCryptkeeperVerifiableCredentialIntoStore = async ( + private insertCryptkeeperVCIntoStore = async ( cryptkeeperVerifiableCredential: ICryptkeeperVerifiableCredential, ): Promise => { const verifiableCredentialHash = cryptkeeperVerifiableCredential.metadata.hash; - const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVerifiableCredentialsFromStore(); + const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVCFromStore(); if (cryptkeeperVerifiableCredentials.has(verifiableCredentialHash)) { - await this.notificationService.create({ - options: { - title: "Failed to add Verifiable Credential.", - message: `The Verifiable Credential you are trying to add already exists in your wallet.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + await this.announce({ + notificationTitle: "Failed to add Verifiable Credential.", + notificationMessage: `The Verifiable Credential you are trying to add already exists in your wallet.`, + notificationType: "basic", }); throw new Error("Verifiable Credential already exists."); @@ -332,33 +274,21 @@ export default class VerifiableCredentialsService implements IBackupable { cryptkeeperVerifiableCredentials.set( verifiableCredentialHash, - serializeCryptkeeperVerifiableCredential(cryptkeeperVerifiableCredential), + serializeCryptkeeperVC(cryptkeeperVerifiableCredential), ); - await this.writeCryptkeeperVerifiableCredentials(cryptkeeperVerifiableCredentials); - - await this.historyService.trackOperation(OperationType.ADD_VERIFIABLE_CREDENTIAL, {}); - await this.notificationService.create({ - options: { - title: "Verifiable Credential added.", - message: `Added 1 Verifiable Credential.`, - iconUrl: browser.runtime.getURL("/icons/logo.png"), - type: "basic", - }, + await this.writeCryptkeeperVC(cryptkeeperVerifiableCredentials); + + await this.announce({ + notificationTitle: "Verifiable Credential added.", + notificationMessage: `Added 1 Verifiable Credential.`, + notificationType: "basic", + historyOperationType: OperationType.ADD_VERIFIABLE_CREDENTIAL, + responseType: EventName.ADD_VERIFIABLE_CREDENTIAL, + responsePayload: { verifiableCredentialHash }, }); - const tabs = await browser.tabs.query({ active: true }); - await Promise.all( - tabs.map((tab) => - browser.tabs - .sendMessage(tab.id!, { - type: EventName.ADD_VERIFIABLE_CREDENTIAL, - payload: { verifiableCredentialHash }, - }) - .catch(() => undefined), - ), - ); }; - private getCryptkeeperVerifiableCredentialsFromStore = async (): Promise> => { + private getCryptkeeperVCFromStore = async (): Promise> => { const ciphertext = await this.verifiableCredentialsStore.get(); if (!ciphertext) { @@ -371,15 +301,50 @@ export default class VerifiableCredentialsService implements IBackupable { return allCredentials; }; - private writeCryptkeeperVerifiableCredentials = async ( - cryptkeeperVerifiableCredentials: Map, - ): Promise => { + private writeCryptkeeperVC = async (cryptkeeperVerifiableCredentials: Map): Promise => { const serializedCredentials = JSON.stringify(Array.from(cryptkeeperVerifiableCredentials)); const ciphertext = this.cryptoService.encrypt(serializedCredentials, { mode: ECryptMode.MNEMONIC }); await this.verifiableCredentialsStore.set(ciphertext); }; + private announce = async ({ + notificationTitle, + notificationMessage, + notificationType, + historyOperationType, + responseType, + responsePayload, + }: IAnnounceVCArgs) => { + if (historyOperationType) { + await this.historyService.trackOperation(historyOperationType, {}); + } + + await this.notificationService.create({ + options: { + title: notificationTitle, + message: notificationMessage, + iconUrl: browser.runtime.getURL("/icons/logo.png"), + type: notificationType, + }, + }); + + if (responseType) { + const tabs = await browser.tabs.query({ active: true }); + await Promise.all( + tabs.map((tab) => + browser.tabs + .sendMessage(tab.id!, { + type: responseType, + payload: responsePayload, + }) + .catch(() => undefined), + ), + ); + // this.browserController.pushEvent({ type: responseType, payload: responsePayload }); + } + }; + downloadStorage = (): Promise => this.verifiableCredentialsStore.get(); restoreStorage = async (data: BackupData | null): Promise => { @@ -420,9 +385,9 @@ export default class VerifiableCredentialsService implements IBackupable { const backup = this.cryptoService.decrypt(encryptedBackup, { secret: backupPassword }); const backupCredentials = new Map(JSON.parse(backup) as [string, string][]); - const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVerifiableCredentialsFromStore(); + const cryptkeeperVerifiableCredentials = await this.getCryptkeeperVCFromStore(); const mergedCredentials = new Map([...cryptkeeperVerifiableCredentials, ...backupCredentials]); - await this.writeCryptkeeperVerifiableCredentials(mergedCredentials); + await this.writeCryptkeeperVC(mergedCredentials); }; } diff --git a/packages/app/src/background/services/credentials/utils.ts b/packages/app/src/background/services/credentials/utils.ts index 67788c313..35a78c777 100644 --- a/packages/app/src/background/services/credentials/utils.ts +++ b/packages/app/src/background/services/credentials/utils.ts @@ -115,11 +115,9 @@ const verifiableCredentialSchema: yup.Schema = yup.object * @param cryptkeeperVerifiableCredential An object representing a CryptkeeperVerifiableCredential. * @returns A string representing a CryptkeeperVerifiableCredential. */ -export function serializeCryptkeeperVerifiableCredential( - cryptkeeperVerifiableCredential: ICryptkeeperVerifiableCredential, -): string { +export function serializeCryptkeeperVC(cryptkeeperVerifiableCredential: ICryptkeeperVerifiableCredential): string { return JSON.stringify({ - verifiableCredential: serializeVerifiableCredential(cryptkeeperVerifiableCredential.verifiableCredential), + verifiableCredential: serializeVC(cryptkeeperVerifiableCredential.verifiableCredential), metadata: cryptkeeperVerifiableCredential.metadata, }); } @@ -129,7 +127,7 @@ export function serializeCryptkeeperVerifiableCredential( * @param serializedCryptkeeperVerifiableCredential A JSON string representing a CryptkeeperVerifiableCredential. * @returns A CryptkeeperVerifiableCredential object. Throws error if the object is not a valid CryptkeeperVerifiableCredential. */ -export async function deserializeCryptkeeperVerifiableCredential( +export async function deserializeCryptkeeperVC( serializedCryptkeeperVerifiableCredential: string, ): Promise { if (!serializedCryptkeeperVerifiableCredential) { @@ -142,9 +140,7 @@ export async function deserializeCryptkeeperVerifiableCredential( }; return { - verifiableCredential: await deserializeVerifiableCredential( - parsedCryptkeeperVerifiableCredential.verifiableCredential, - ), + verifiableCredential: await deserializeVC(parsedCryptkeeperVerifiableCredential.verifiableCredential), metadata: parsedCryptkeeperVerifiableCredential.metadata, }; } @@ -154,7 +150,7 @@ export async function deserializeCryptkeeperVerifiableCredential( * @param verifiableCredential An object representing a VerifiableCredential. * @returns A string representing a VerifiableCredential. */ -export function serializeVerifiableCredential(verifiableCredential: IVerifiableCredential): string { +export function serializeVC(verifiableCredential: IVerifiableCredential): string { return stringify(verifiableCredential); } @@ -163,9 +159,7 @@ export function serializeVerifiableCredential(verifiableCredential: IVerifiableC * @param serializedVerifiableCredential A JSON string representing a VerifiableCredential. * @returns An object representing a VerifiableCredential. Throws error if the object is not a valid VerifiableCredential. */ -export async function deserializeVerifiableCredential( - serializedVerifiableCredential: string, -): Promise { +export async function deserializeVC(serializedVerifiableCredential: string): Promise { if (!serializedVerifiableCredential) { throw new Error("Serialized Verifiable Credential is not provided"); } @@ -180,13 +174,13 @@ export async function deserializeVerifiableCredential( * @param verifiablePresentation An object representing a VerifiablePresentation. * @returns A string representing a VerifiablePresentation. */ -export function serializeVerifiablePresentation(verifiablePresentation: IVerifiablePresentation): string { +export function serializeVP(verifiablePresentation: IVerifiablePresentation): string { if (!verifiablePresentation.verifiableCredential) { return stringify(verifiablePresentation); } const serializedVerifiableCredentials = verifiablePresentation.verifiableCredential.map((verifiableCredential) => - serializeVerifiableCredential(verifiableCredential), + serializeVC(verifiableCredential), ); return stringify({ @@ -200,8 +194,8 @@ export function serializeVerifiablePresentation(verifiablePresentation: IVerifia * @param serializedVerifiableCredential An string representing a VerifiableCredential. * @returns The string if it is a valid VerifiableCredential, otherwise throws an error. */ -export async function validateSerializedVerifiableCredential(serializedVerifiableCredential: string): Promise { - await deserializeVerifiableCredential(serializedVerifiableCredential); +export async function validateSerializedVC(serializedVerifiableCredential: string): Promise { + await deserializeVC(serializedVerifiableCredential); return serializedVerifiableCredential; } @@ -211,8 +205,8 @@ export async function validateSerializedVerifiableCredential(serializedVerifiabl * @param verifiableCredential An object representing a VerifiableCredential. * @returns A string representing the hash of the VerifiableCredential. */ -export function hashVerifiableCredential(verifiableCredential: IVerifiableCredential): string { - return SHA256(serializeVerifiableCredential(verifiableCredential)).toString(); +export function hashVC(verifiableCredential: IVerifiableCredential): string { + return SHA256(serializeVC(verifiableCredential)).toString(); } /** @@ -220,19 +214,22 @@ export function hashVerifiableCredential(verifiableCredential: IVerifiableCreden * @param verifiableCredential An object representing a VerifiableCredential. * @returns An object representing the initial metadata for the VerifiableCredential. */ -export function generateInitialMetadataForVerifiableCredential( +export function generateInitialMetadataForVC( verifiableCredential: IVerifiableCredential, initialVerifiableCredentialName: string, ): IVerifiableCredentialMetadata { return { name: initialVerifiableCredentialName, - hash: hashVerifiableCredential(verifiableCredential), + hash: hashVC(verifiableCredential), }; } -export function generateVerifiablePresentationFromVerifiableCredentials( - verifiableCredentials: IVerifiableCredential[], -): IVerifiablePresentation { +/** + * Generates a VerifiablePresentation from a list of VerifiableCredential objects. + * @param verifiableCredentials An array of objects representing Verifiable Credentials. + * @returns An object representing a VerifiablePresentation. + */ +export function generateVPFromVC(verifiableCredentials: IVerifiableCredential[]): IVerifiablePresentation { return { context: ["https://www.w3.org/2018/credentials/v1"], type: ["VerifiablePresentation"], diff --git a/packages/app/src/background/services/notification/index.ts b/packages/app/src/background/services/notification/index.ts index 4040c3fe5..60bd0e02f 100644 --- a/packages/app/src/background/services/notification/index.ts +++ b/packages/app/src/background/services/notification/index.ts @@ -1,13 +1,15 @@ import browser from "webextension-polyfill"; +export interface ICreateNotificationOptions { + title: string; + message: string; + type: "basic" | "image" | "list" | "progress"; + iconUrl?: string; +} + export interface CreateNotificationArgs { id?: string; - options: { - title: string; - message: string; - type: "basic" | "image" | "list" | "progress"; - iconUrl?: string; - }; + options: ICreateNotificationOptions; } export default class NotificationService { diff --git a/packages/app/src/ui/ducks/__tests__/verifiableCredentials.test.tsx b/packages/app/src/ui/ducks/__tests__/verifiableCredentials.test.tsx index 63096017c..ad7f5bb29 100644 --- a/packages/app/src/ui/ducks/__tests__/verifiableCredentials.test.tsx +++ b/packages/app/src/ui/ducks/__tests__/verifiableCredentials.test.tsx @@ -6,7 +6,7 @@ import { RPCAction } from "@cryptkeeperzk/providers"; import { renderHook } from "@testing-library/react"; import { Provider } from "react-redux"; -import { serializeCryptkeeperVerifiableCredential } from "@src/background/services/credentials/utils"; +import { serializeCryptkeeperVC } from "@src/background/services/credentials/utils"; import { store } from "@src/ui/store/configureAppStore"; import postMessage from "@src/util/postMessage"; @@ -77,8 +77,8 @@ describe("ui/ducks/verifiableCredentials", () => { }; const mockSerializedVerifiableCredentials = [ - serializeCryptkeeperVerifiableCredential(mockCryptkeeperVerifiableCredentials[0]), - serializeCryptkeeperVerifiableCredential(mockCryptkeeperVerifiableCredentials[1]), + serializeCryptkeeperVC(mockCryptkeeperVerifiableCredentials[0]), + serializeCryptkeeperVC(mockCryptkeeperVerifiableCredentials[1]), ]; afterEach(() => { diff --git a/packages/app/src/ui/ducks/verifiableCredentials.ts b/packages/app/src/ui/ducks/verifiableCredentials.ts index 69ec725a0..d85c31a9a 100644 --- a/packages/app/src/ui/ducks/verifiableCredentials.ts +++ b/packages/app/src/ui/ducks/verifiableCredentials.ts @@ -2,7 +2,7 @@ import { RPCAction } from "@cryptkeeperzk/providers"; import { createSlice, PayloadAction } from "@reduxjs/toolkit"; -import { serializeCryptkeeperVerifiableCredential } from "@src/background/services/credentials/utils"; +import { serializeCryptkeeperVC } from "@src/background/services/credentials/utils"; import postMessage from "@src/util/postMessage"; import type { IVerifiablePresentation } from "@cryptkeeperzk/types"; @@ -95,7 +95,7 @@ export const fetchVerifiableCredentials = (): TypedThunk => async (dispatch) => }); const serializedVerifiableCredentials = cryptkeeperVerifiableCredentials.map((cryptkeeperVerifiableCredential) => - serializeCryptkeeperVerifiableCredential(cryptkeeperVerifiableCredential), + serializeCryptkeeperVC(cryptkeeperVerifiableCredential), ); dispatch(setVerifiableCredentials(serializedVerifiableCredentials)); diff --git a/packages/app/src/ui/hooks/verifiableCredentials/__tests__/useCryptkeeperVerifiableCredentials.test.tsx b/packages/app/src/ui/hooks/verifiableCredentials/__tests__/useCryptkeeperVerifiableCredentials.test.tsx index 95402ff36..7faa53ff7 100644 --- a/packages/app/src/ui/hooks/verifiableCredentials/__tests__/useCryptkeeperVerifiableCredentials.test.tsx +++ b/packages/app/src/ui/hooks/verifiableCredentials/__tests__/useCryptkeeperVerifiableCredentials.test.tsx @@ -4,7 +4,7 @@ import { renderHook, waitFor } from "@testing-library/react"; -import { serializeCryptkeeperVerifiableCredential } from "@src/background/services/credentials/utils"; +import { serializeCryptkeeperVC } from "@src/background/services/credentials/utils"; import { useVerifiableCredentials } from "@src/ui/ducks/verifiableCredentials"; import { useCryptkeeperVerifiableCredentials } from "../useCryptkeeperVerifiableCredentials"; @@ -57,9 +57,7 @@ describe("ui/hooks/verifiableCredentials", () => { }, ]; - const mockSerializedVerifiableCredentials = mockCryptkeeperVerifiableCredentials.map( - serializeCryptkeeperVerifiableCredential, - ); + const mockSerializedVerifiableCredentials = mockCryptkeeperVerifiableCredentials.map(serializeCryptkeeperVC); beforeEach(() => { (useVerifiableCredentials as jest.Mock).mockReturnValue(mockSerializedVerifiableCredentials); diff --git a/packages/app/src/ui/hooks/verifiableCredentials/useCryptkeeperVerifiableCredentials.ts b/packages/app/src/ui/hooks/verifiableCredentials/useCryptkeeperVerifiableCredentials.ts index 90ec75d03..d4b49d5e8 100644 --- a/packages/app/src/ui/hooks/verifiableCredentials/useCryptkeeperVerifiableCredentials.ts +++ b/packages/app/src/ui/hooks/verifiableCredentials/useCryptkeeperVerifiableCredentials.ts @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; -import { deserializeCryptkeeperVerifiableCredential } from "@src/background/services/credentials/utils"; +import { deserializeCryptkeeperVC } from "@src/background/services/credentials/utils"; import { ICryptkeeperVerifiableCredential } from "@src/types"; import { useVerifiableCredentials } from "@src/ui/ducks/verifiableCredentials"; @@ -15,7 +15,7 @@ export const useCryptkeeperVerifiableCredentials = (): ICryptkeeperVerifiableCre async function deserializeCredentials() { const deserializedVerifiableCredentials = await Promise.all( serializedVerifiableCredentials.map((serializedVerifiableCredential) => - deserializeCryptkeeperVerifiableCredential(serializedVerifiableCredential), + deserializeCryptkeeperVC(serializedVerifiableCredential), ), ); setCryptkeeperVerifiableCredentials(deserializedVerifiableCredentials); diff --git a/packages/app/src/ui/pages/AddVerifiableCredential/__tests__/useAddVerifiableCredential.test.ts b/packages/app/src/ui/pages/AddVerifiableCredential/__tests__/useAddVerifiableCredential.test.ts index 4e231a7a6..4c561eb8c 100644 --- a/packages/app/src/ui/pages/AddVerifiableCredential/__tests__/useAddVerifiableCredential.test.ts +++ b/packages/app/src/ui/pages/AddVerifiableCredential/__tests__/useAddVerifiableCredential.test.ts @@ -4,7 +4,7 @@ import { act, renderHook, waitFor } from "@testing-library/react"; -import { hashVerifiableCredential, serializeVerifiableCredential } from "@src/background/services/credentials/utils"; +import { hashVC, serializeVC } from "@src/background/services/credentials/utils"; import { closePopup } from "@src/ui/ducks/app"; import { useAppDispatch } from "@src/ui/ducks/hooks"; import { addVerifiableCredential, rejectVerifiableCredentialRequest } from "@src/ui/ducks/verifiableCredentials"; @@ -45,12 +45,12 @@ describe("ui/pages/AddVerifiableCredential/useAddVerifiableCredential", () => { }, }, }; - const mockSerializedVerifiableCredential = serializeVerifiableCredential(mockVerifiableCredential); + const mockSerializedVerifiableCredential = serializeVC(mockVerifiableCredential); const expectedCryptkeeperVerifiableCredential = { verifiableCredential: mockVerifiableCredential, metadata: { - hash: hashVerifiableCredential(mockVerifiableCredential), + hash: hashVC(mockVerifiableCredential), name: defaultVerifiableCredentialName, }, }; diff --git a/packages/app/src/ui/pages/AddVerifiableCredential/useAddVerifiableCredential.ts b/packages/app/src/ui/pages/AddVerifiableCredential/useAddVerifiableCredential.ts index 46de9db86..00376372b 100644 --- a/packages/app/src/ui/pages/AddVerifiableCredential/useAddVerifiableCredential.ts +++ b/packages/app/src/ui/pages/AddVerifiableCredential/useAddVerifiableCredential.ts @@ -1,10 +1,6 @@ import { useCallback, useEffect, useState } from "react"; -import { - deserializeVerifiableCredential, - hashVerifiableCredential, - serializeVerifiableCredential, -} from "@src/background/services/credentials/utils"; +import { deserializeVC, hashVC, serializeVC } from "@src/background/services/credentials/utils"; import { ICryptkeeperVerifiableCredential } from "@src/types"; import { closePopup } from "@src/ui/ducks/app"; import { useAppDispatch } from "@src/ui/ducks/hooks"; @@ -35,11 +31,11 @@ export const useAddVerifiableCredential = (): IUseAddVerifiableCredentialData => return; } - const deserializedVerifiableCredential = await deserializeVerifiableCredential(serializedVerifiableCredential); + const deserializedVerifiableCredential = await deserializeVC(serializedVerifiableCredential); setCryptkeeperVerifiableCredential({ verifiableCredential: deserializedVerifiableCredential, metadata: { - hash: hashVerifiableCredential(deserializedVerifiableCredential), + hash: hashVC(deserializedVerifiableCredential), name: defaultVerifiableCredentialName, }, }); @@ -75,9 +71,7 @@ export const useAddVerifiableCredential = (): IUseAddVerifiableCredentialData => return; } - const serializedVerifiableCredential = serializeVerifiableCredential( - cryptkeeperVerifiableCredential.verifiableCredential, - ); + const serializedVerifiableCredential = serializeVC(cryptkeeperVerifiableCredential.verifiableCredential); try { await dispatch( diff --git a/packages/app/src/ui/pages/PresentVerifiableCredential/usePresentVerifiableCredential.ts b/packages/app/src/ui/pages/PresentVerifiableCredential/usePresentVerifiableCredential.ts index 98916d983..5ae2dad2d 100644 --- a/packages/app/src/ui/pages/PresentVerifiableCredential/usePresentVerifiableCredential.ts +++ b/packages/app/src/ui/pages/PresentVerifiableCredential/usePresentVerifiableCredential.ts @@ -1,10 +1,7 @@ import * as React from "react"; import { useCallback, useEffect, useState } from "react"; -import { - generateVerifiablePresentationFromVerifiableCredentials, - serializeVerifiablePresentation, -} from "@src/background/services/credentials/utils"; +import { generateVPFromVC, serializeVP } from "@src/background/services/credentials/utils"; import { closePopup } from "@src/ui/ducks/app"; import { useAppDispatch } from "@src/ui/ducks/hooks"; import { @@ -109,7 +106,7 @@ export const usePresentVerifiableCredential = (): IUsePresentVerifiableCredentia ) .map((cryptkeeperVerifiableCredential) => cryptkeeperVerifiableCredential.verifiableCredential); - return generateVerifiablePresentationFromVerifiableCredentials(verifiableCredentials); + return generateVPFromVC(verifiableCredentials); } const onToggleMenu = () => { @@ -145,7 +142,7 @@ export const usePresentVerifiableCredential = (): IUsePresentVerifiableCredentia } try { - const serializedVerifiablePresentation = serializeVerifiablePresentation(verifiablePresentation); + const serializedVerifiablePresentation = serializeVP(verifiablePresentation); const signature = await signer.signMessage(serializedVerifiablePresentation); const signedVerifiablePresentation = { ...verifiablePresentation,