diff --git a/crypto-ffi/bindings/js/CoreCrypto.ts b/crypto-ffi/bindings/js/CoreCrypto.ts index 1324861f4..3d13bde6d 100644 --- a/crypto-ffi/bindings/js/CoreCrypto.ts +++ b/crypto-ffi/bindings/js/CoreCrypto.ts @@ -53,9 +53,9 @@ export class CoreCryptoError extends Error { private constructor( msg: string, richError: CoreCryptoRichError, - ...params: any[] + ...params: unknown[] ) { - // @ts-ignore + // @ts-expect-error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter. super(msg, ...params); Object.setPrototypeOf(this, new.target.prototype); @@ -64,15 +64,15 @@ export class CoreCryptoError extends Error { this.proteusErrorCode = richError.proteusErrorCode; } - private static fallback(msg: string, ...params: any[]): Error { + private static fallback(msg: string, ...params: unknown[]): Error { console.warn( `Cannot build CoreCryptoError, falling back to standard Error! ctx: ${msg}` ); - // @ts-ignore + // @ts-expect-error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter. return new Error(msg, ...params); } - static build(msg: string, ...params: any[]): CoreCryptoError | Error { + static build(msg: string, ...params: unknown[]): CoreCryptoError | Error { const parts = msg.split("\n\n"); if (parts.length < 2) { const cause = new Error( @@ -92,7 +92,7 @@ export class CoreCryptoError extends Error { static fromStdError(e: Error): CoreCryptoError | Error { const opts = { - // @ts-ignore + // @ts-expect-error TS2550: Property 'cause' does not exist on type 'Error'. Try changing the 'lib' compiler option to 'es2022' or later. cause: e.cause || undefined, stack: e.stack || undefined, }; @@ -894,7 +894,7 @@ export enum CoreCryptoLogLevel { export function initLogger( logger: CoreCryptoLogger, level: CoreCryptoLogLevel, - ctx: any = null + ctx: unknown = null ): void { const wasmLogger = new CoreCryptoWasmLogger(logger.log, ctx); CoreCrypto.setLogger(wasmLogger, level); @@ -935,7 +935,7 @@ export class CoreCrypto { } static setLogger(logger: CoreCryptoWasmLogger, level: CoreCryptoLogLevel) { - this.#assertModuleLoaded() + this.#assertModuleLoaded(); CoreCryptoFfi.set_logger(logger, level); } @@ -983,7 +983,7 @@ export class CoreCrypto { }: CoreCryptoParams): Promise { await this.#loadModule(wasmFilePath); - let cs = ciphersuites.map((cs) => cs.valueOf()); + const cs = ciphersuites.map((cs) => cs.valueOf()); const cc = await CoreCryptoError.asyncMapErr( CoreCryptoFfi._internal_new( databaseName, @@ -1030,7 +1030,7 @@ export class CoreCrypto { ciphersuites: Ciphersuite[], nbKeyPackage?: number ): Promise { - let cs = ciphersuites.map((cs) => cs.valueOf()); + const cs = ciphersuites.map((cs) => cs.valueOf()); return await CoreCryptoError.asyncMapErr( this.#cc.mls_init(clientId, Uint16Array.of(...cs), nbKeyPackage) ); @@ -1046,7 +1046,7 @@ export class CoreCrypto { async mlsGenerateKeypair( ciphersuites: Ciphersuite[] ): Promise { - let cs = ciphersuites.map((cs) => cs.valueOf()); + const cs = ciphersuites.map((cs) => cs.valueOf()); return await CoreCryptoError.asyncMapErr( this.#cc.mls_generate_keypair(Uint16Array.of(...cs)) ); @@ -1066,7 +1066,7 @@ export class CoreCrypto { signaturePublicKeys: Uint8Array[], ciphersuites: Ciphersuite[] ): Promise { - let cs = ciphersuites.map((cs) => cs.valueOf()); + const cs = ciphersuites.map((cs) => cs.valueOf()); return await CoreCryptoError.asyncMapErr( this.#cc.mls_init_with_client_id( clientId, @@ -1116,7 +1116,7 @@ export class CoreCrypto { */ async registerCallbacks( callbacks: CoreCryptoCallbacks, - ctx: any = null + ctx: unknown = null ): Promise { try { const wasmCallbacks = new CoreCryptoWasmCallbacks( @@ -1566,9 +1566,7 @@ export class CoreCrypto { * * @returns A {@link CommitBundle} */ - async e2eiRotate( - conversationId: ConversationId - ): Promise { + async e2eiRotate(conversationId: ConversationId): Promise { try { const ffiRet: CoreCryptoFfiTypes.CommitBundle = await CoreCryptoError.asyncMapErr( @@ -1689,7 +1687,7 @@ export class CoreCrypto { ): Promise { switch (externalProposalType) { case ExternalProposalType.Add: { - let addArgs = args as ExternalAddProposalArgs; + const addArgs = args as ExternalAddProposalArgs; return await CoreCryptoError.asyncMapErr( this.#cc.new_external_add_proposal( args.conversationId, @@ -2392,7 +2390,7 @@ export class CoreCrypto { async e2eiConversationState( conversationId: ConversationId ): Promise { - let state = await CoreCryptoError.asyncMapErr( + const state = await CoreCryptoError.asyncMapErr( this.#cc.e2ei_conversation_state(conversationId) ); @@ -2473,7 +2471,7 @@ export class CoreCrypto { groupInfo: Uint8Array, credentialType: CredentialType = CredentialType.X509 ): Promise { - let state = await CoreCryptoError.asyncMapErr( + const state = await CoreCryptoError.asyncMapErr( this.#cc.get_credential_in_use(groupInfo, credentialType) ); return normalizeEnum(E2eiConversationState, state); diff --git a/crypto-ffi/bindings/js/test/CoreCrypto.test.js b/crypto-ffi/bindings/js/test/CoreCrypto.test.js index c91b13c79..ea132c1f6 100644 --- a/crypto-ffi/bindings/js/test/CoreCrypto.test.js +++ b/crypto-ffi/bindings/js/test/CoreCrypto.test.js @@ -1,13 +1,18 @@ -const puppeteer = require("puppeteer"); -const {exec} = require("child_process"); -import {rm} from "node:fs/promises"; -import {expect, test, beforeAll, afterAll} from "bun:test"; +import puppeteer from "puppeteer"; + +import { rm } from "node:fs/promises"; +import { expect, test, beforeAll, afterAll } from "bun:test"; + +import { exec } from "child_process"; let server; let browser; beforeAll(async () => { - await Bun.write("../platforms/web/index.html", Bun.file(import.meta.dir + '/index.html')); + await Bun.write( + "../platforms/web/index.html", + Bun.file(import.meta.dir + "/index.html") + ); server = Bun.serve({ port: 3000, @@ -19,13 +24,17 @@ beforeAll(async () => { if (url.pathname === "/") { filename = "/index.html"; } else if (url.pathname === "/favicon.ico") { - return new Response("Not Found", {status: 404}); + return new Response("Not Found", { status: 404 }); } - const filePath = Bun.resolveSync(`../platforms/web${filename}`, process.cwd()); + const filePath = Bun.resolveSync( + `../platforms/web${filename}`, + process.cwd() + ); const file = Bun.file(filePath); - if (file.size === 0) { // Not exists - return new Response("Not Found", {status: 404}); + if (file.size === 0) { + // Not exists + return new Response("Not Found", { status: 404 }); } return new Response(file); @@ -38,14 +47,14 @@ afterAll(async () => { await rm("../platforms/web/index.html"); }); -async function initBrowser(args = {captureLogs: true}) { +async function initBrowser(args = { captureLogs: true }) { if (!browser) { - browser = await puppeteer.launch({headless: "new"}); + browser = await puppeteer.launch({ headless: "new" }); } const context = await browser.createBrowserContext(); const page = await context.newPage(); if (args.captureLogs) { - page.on("console", msg => { + page.on("console", (msg) => { const msgText = msg.text(); if (msgText.includes("404 (Not Found)")) { return; @@ -60,15 +69,17 @@ async function initBrowser(args = {captureLogs: true}) { } async function execAsync(command, options = {}) { - return new Promise((resolve, reject) => exec(command, options, (err, stdout, stderr) => { - if (err) { - err.stderr = stderr; - err.stdout = stdout; - return reject(err); - } + return new Promise((resolve, reject) => + exec(command, options, (err, stdout, stderr) => { + if (err) { + err.stderr = stderr; + err.stdout = stdout; + return reject(err); + } - resolve([stdout, stderr]); - })); + resolve([stdout, stderr]); + }) + ); } test("tsc import of package", async () => { @@ -82,16 +93,19 @@ test("tsc import of package", async () => { try { await execAsync( - `bunx typescript@latest ${args.join(" ")} ./bindings/js/test/tsc-import-test.ts`, + `bunx typescript@latest ${args.join(" ")} ./bindings/js/test/tsc-import-test.ts` ); } catch (cause) { - throw new Error(`Couldn't build @wireapp/core-crypto import. + throw new Error( + `Couldn't build @wireapp/core-crypto import. tsc output: ${cause.stdout} - ${cause.stderr}`, { - cause, - }); + ${cause.stderr}`, + { + cause, + } + ); } }, 10000); @@ -99,10 +113,11 @@ test("init", async () => { const [ctx, page] = await initBrowser(); const version = await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite } = await import("./corecrypto.js"); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; - const cc = await CoreCrypto.init({ + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + await CoreCrypto.init({ databaseName: "test init", key: "test", ciphersuites: [ciphersuite], @@ -121,28 +136,33 @@ test("init", async () => { test("can use groupInfo enums", async () => { const [ctx, page] = await initBrowser(); - const [GroupInfoEncryptionType, RatchetTreeType, CredentialType] = await page.evaluate(async () => { - const { - CoreCrypto, - Ciphersuite, - CredentialType, - GroupInfoEncryptionType, - RatchetTreeType, - } = await import ("./corecrypto.js"); - - window.GroupInfoEncryptionType = GroupInfoEncryptionType; - window.RatchetTreeType = RatchetTreeType; - window.CoreCrypto = CoreCrypto; - window.Ciphersuite = Ciphersuite; - window.CredentialType = CredentialType; - - return [GroupInfoEncryptionType, RatchetTreeType, CredentialType]; - }); + const [GroupInfoEncryptionType, RatchetTreeType, CredentialType] = + await page.evaluate(async () => { + const { + CoreCrypto, + Ciphersuite, + CredentialType, + GroupInfoEncryptionType, + RatchetTreeType, + } = await import("./corecrypto.js"); + + window.GroupInfoEncryptionType = GroupInfoEncryptionType; + window.RatchetTreeType = RatchetTreeType; + window.CoreCrypto = CoreCrypto; + window.Ciphersuite = Ciphersuite; + window.CredentialType = CredentialType; + + return [GroupInfoEncryptionType, RatchetTreeType, CredentialType]; + }); expect(GroupInfoEncryptionType.Plaintext).toBe(0x01); expect(GroupInfoEncryptionType.JweEncrypted).toBe(0x02); - expect(await page.evaluate(() => window.GroupInfoEncryptionType.Plaintext)).toBe(0x01); - expect(await page.evaluate(() => window.GroupInfoEncryptionType.JweEncrypted)).toBe(0x02); + expect( + await page.evaluate(() => window.GroupInfoEncryptionType.Plaintext) + ).toBe(0x01); + expect( + await page.evaluate(() => window.GroupInfoEncryptionType.JweEncrypted) + ).toBe(0x02); expect(CredentialType.Basic).toBe(0x01); expect(CredentialType.X509).toBe(0x02); expect(await page.evaluate(() => window.CredentialType.Basic)).toBe(0x01); @@ -155,7 +175,8 @@ test("can use groupInfo enums", async () => { expect(await page.evaluate(() => window.RatchetTreeType.ByRef)).toBe(0x03); const pgs = await page.evaluate(async () => { - const ciphersuite = window.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + window.Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const client1Config = { databaseName: "test init", key: "test", @@ -173,14 +194,24 @@ test("can use groupInfo enums", async () => { const cc = await window.CoreCrypto.init(client1Config); const cc2 = await window.CoreCrypto.init(client2Config); - const [kp] = await cc2.clientKeypackages(ciphersuite, window.CredentialType.Basic, 1); + const [kp] = await cc2.clientKeypackages( + ciphersuite, + window.CredentialType.Basic, + 1 + ); const encoder = new TextEncoder(); const conversationId = encoder.encode("testConversation"); - await cc.createConversation(conversationId, window.CredentialType.Basic); + await cc.createConversation( + conversationId, + window.CredentialType.Basic + ); - const {groupInfo: groupInfo} = await cc.addClientsToConversation(conversationId, [kp]); + const { groupInfo: groupInfo } = await cc.addClientsToConversation( + conversationId, + [kp] + ); return groupInfo; }); @@ -194,17 +225,18 @@ test("can use groupInfo enums", async () => { await ctx.close(); }); - test("can import ciphersuite enum", async () => { const [ctx, page] = await initBrowser(); const Ciphersuite = await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite } = await import("./corecrypto.js"); window.cc = await CoreCrypto.init({ databaseName: "test ciphersuite", key: "test", - ciphersuites: [Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519], + ciphersuites: [ + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519, + ], clientId: "test", }); @@ -212,21 +244,60 @@ test("can import ciphersuite enum", async () => { return Ciphersuite; }); - expect(Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519).toBe(0x0001); + expect(Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519).toBe( + 0x0001 + ); expect(Ciphersuite.MLS_128_DHKEMP256_AES128GCM_SHA256_P256).toBe(0x0002); - expect(Ciphersuite.MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519).toBe(0x0003); + expect( + Ciphersuite.MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519 + ).toBe(0x0003); expect(Ciphersuite.MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448).toBe(0x0004); expect(Ciphersuite.MLS_256_DHKEMP521_AES256GCM_SHA512_P521).toBe(0x0005); - expect(Ciphersuite.MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448).toBe(0x0006); + expect(Ciphersuite.MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448).toBe( + 0x0006 + ); expect(Ciphersuite.MLS_256_DHKEMP384_AES256GCM_SHA384_P384).toBe(0x0007); - expect(await page.evaluate(() => window.ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519)).toBe(0x0001); - expect(await page.evaluate(() => window.ciphersuite.MLS_128_DHKEMP256_AES128GCM_SHA256_P256)).toBe(0x0002); - expect(await page.evaluate(() => window.ciphersuite.MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519)).toBe(0x0003); - expect(await page.evaluate(() => window.ciphersuite.MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448)).toBe(0x0004); - expect(await page.evaluate(() => window.ciphersuite.MLS_256_DHKEMP521_AES256GCM_SHA512_P521)).toBe(0x0005); - expect(await page.evaluate(() => window.ciphersuite.MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448)).toBe(0x0006); - expect(await page.evaluate(() => window.ciphersuite.MLS_256_DHKEMP384_AES256GCM_SHA384_P384)).toBe(0x0007); + expect( + await page.evaluate( + () => + window.ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 + ) + ).toBe(0x0001); + expect( + await page.evaluate( + () => window.ciphersuite.MLS_128_DHKEMP256_AES128GCM_SHA256_P256 + ) + ).toBe(0x0002); + expect( + await page.evaluate( + () => + window.ciphersuite + .MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519 + ) + ).toBe(0x0003); + expect( + await page.evaluate( + () => window.ciphersuite.MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448 + ) + ).toBe(0x0004); + expect( + await page.evaluate( + () => window.ciphersuite.MLS_256_DHKEMP521_AES256GCM_SHA512_P521 + ) + ).toBe(0x0005); + expect( + await page.evaluate( + () => + window.ciphersuite + .MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448 + ) + ).toBe(0x0006); + expect( + await page.evaluate( + () => window.ciphersuite.MLS_256_DHKEMP384_AES256GCM_SHA384_P384 + ) + ).toBe(0x0007); await page.close(); await ctx.close(); @@ -238,40 +309,43 @@ test("external entropy", async () => { // Test vectors 1 and 2 from // https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04 const vector1 = Uint32Array.from([ - 0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653, - 0xb819d2bd, 0x1aed8da0, 0xccef36a8, 0xc70d778b, - 0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8, + 0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653, 0xb819d2bd, 0x1aed8da0, + 0xccef36a8, 0xc70d778b, 0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8, 0xf4b8436a, 0x1ca11815, 0x69b687c3, 0x8665eeb2, ]); const vector2 = Uint32Array.from([ - 0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73, - 0xa0290fcb, 0x6965e348, 0x3e53c612, 0xed7aee32, - 0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874, + 0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73, 0xa0290fcb, 0x6965e348, + 0x3e53c612, 0xed7aee32, 0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874, 0x281fed31, 0x45fb0a51, 0x1f0ae1ac, 0x6f4d794b, ]); - let [produced1, produced2] = await page.evaluate(async (expected1Length, expected2Length) => { - const {CoreCrypto, Ciphersuite} = await import("./corecrypto.js"); - - // Null byte seed - const seed = new Uint8Array(32); - - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; - const cc = await CoreCrypto.init({ - databaseName: "test init", - key: "test", - clientId: "test", - ciphersuites: [ciphersuite], - entropySeed: seed, - }); - - // Reset it because the `init` method performed some RNG calls and made it "dirty" - await cc.reseedRng(seed); - - const produced1 = await cc.randomBytes(expected1Length); - const produced2 = await cc.randomBytes(expected2Length); - return [produced1, produced2]; - }, vector1.length * vector1.BYTES_PER_ELEMENT, vector2.length * vector2.BYTES_PER_ELEMENT); + let [produced1, produced2] = await page.evaluate( + async (expected1Length, expected2Length) => { + const { CoreCrypto, Ciphersuite } = await import("./corecrypto.js"); + + // Null byte seed + const seed = new Uint8Array(32); + + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const cc = await CoreCrypto.init({ + databaseName: "test init", + key: "test", + clientId: "test", + ciphersuites: [ciphersuite], + entropySeed: seed, + }); + + // Reset it because the `init` method performed some RNG calls and made it "dirty" + await cc.reseedRng(seed); + + const produced1 = await cc.randomBytes(expected1Length); + const produced2 = await cc.randomBytes(expected2Length); + return [produced1, produced2]; + }, + vector1.length * vector1.BYTES_PER_ELEMENT, + vector2.length * vector2.BYTES_PER_ELEMENT + ); produced1 = Uint8Array.from(Object.values(produced1)); produced2 = Uint8Array.from(Object.values(produced2)); @@ -290,9 +364,12 @@ test("externally generated clients", async () => { const [ctx, page] = await initBrowser(); await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CredentialType, WelcomeBundle} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite, CredentialType } = await import( + "./corecrypto.js" + ); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const alice = await CoreCrypto.deferredInit({ databaseName: "extgen alice test", @@ -314,13 +391,20 @@ test("externally generated clients", async () => { clientId: "bob", }); - const [bobKp] = await bob.clientKeypackages(ciphersuite, credentialType, 1); + const [bobKp] = await bob.clientKeypackages( + ciphersuite, + credentialType, + 1 + ); const conversationId = encoder.encode("testConversation"); await alice.createConversation(conversationId, credentialType); - const memberAdded = await alice.addClientsToConversation(conversationId, [bobKp]); + const memberAdded = await alice.addClientsToConversation( + conversationId, + [bobKp] + ); if (!memberAdded) { throw new Error("no welcome message was generated"); @@ -331,8 +415,12 @@ test("externally generated clients", async () => { const welcome = await bob.processWelcomeMessage(memberAdded.welcome); const welcomeConversationId = welcome.id; - if (!conversationId.every((val, i) => val === welcomeConversationId[i])) { - throw new Error(`conversationId mismatch, got ${welcomeConversationId}, expected ${conversationId}`); + if ( + !conversationId.every((val, i) => val === welcomeConversationId[i]) + ) { + throw new Error( + `conversationId mismatch, got ${welcomeConversationId}, expected ${conversationId}` + ); } const messageText = "Hello world!"; @@ -340,35 +428,54 @@ test("externally generated clients", async () => { const encryptedMessage = await alice.encryptMessage( conversationId, - messageBuffer, + messageBuffer ); - const decryptedMessage = await bob.decryptMessage(welcomeConversationId, encryptedMessage); + const decryptedMessage = await bob.decryptMessage( + welcomeConversationId, + encryptedMessage + ); if (!decryptedMessage.message) { - return new Error("alice -> bob decrypted message isn't an application message"); + return new Error( + "alice -> bob decrypted message isn't an application message" + ); } - if (!decryptedMessage.message.every((val, i) => val === messageBuffer[i])) { - throw new Error("alice -> bob message differs from bob's point of view"); + if ( + !decryptedMessage.message.every( + (val, i) => val === messageBuffer[i] + ) + ) { + throw new Error( + "alice -> bob message differs from bob's point of view" + ); } const bobEncryptedMessage = await bob.encryptMessage( conversationId, - messageBuffer, + messageBuffer ); const aliceDecryptedMessage = await alice.decryptMessage( conversationId, - bobEncryptedMessage, + bobEncryptedMessage ); if (!aliceDecryptedMessage.message) { - return new Error("bob -> alice decrypted message isn't an application message"); + return new Error( + "bob -> alice decrypted message isn't an application message" + ); } - if (!aliceDecryptedMessage.message.every((val, i) => val === messageBuffer[i])) { - throw new Error("bob -> alice message differs from alice's point of view"); + if ( + !aliceDecryptedMessage.message.every( + (val, i) => val === messageBuffer[i] + ) + ) { + throw new Error( + "bob -> alice message differs from alice's point of view" + ); } }); @@ -380,9 +487,12 @@ test("get client public key", async () => { const [ctx, page] = await initBrowser(); const pkLength = await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CredentialType} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite, CredentialType } = await import( + "./corecrypto.js" + ); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const cc = await CoreCrypto.init({ databaseName: "get client public key", key: "test", @@ -390,7 +500,9 @@ test("get client public key", async () => { clientId: "test", }); - const len = (await cc.clientPublicKey(ciphersuite, CredentialType.Basic)).length; + const len = ( + await cc.clientPublicKey(ciphersuite, CredentialType.Basic) + ).length; await cc.wipe(); return len; }); @@ -405,9 +517,12 @@ test("get client keypackages", async () => { const [ctx, page] = await initBrowser(); const kpNumber = await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CredentialType} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite, CredentialType } = await import( + "./corecrypto.js" + ); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const cc = await CoreCrypto.init({ databaseName: "get client keypackages", @@ -434,7 +549,9 @@ test("encrypt message", async () => { const [ctx, page] = await initBrowser(); const [msgLen, cs, Ciphersuite] = await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CredentialType} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite, CredentialType } = await import( + "./corecrypto.js" + ); const ciphersuite = Ciphersuite.MLS_128_DHKEMP256_AES128GCM_SHA256_P256; const credentialType = CredentialType.Basic; @@ -449,12 +566,14 @@ test("encrypt message", async () => { const conversationId = encoder.encode("testConversation"); - await cc.createConversation(conversationId, credentialType, {ciphersuite}); + await cc.createConversation(conversationId, credentialType, { + ciphersuite, + }); const cs = await cc.conversationCiphersuite(conversationId); const encryptedMessage = await cc.encryptMessage( conversationId, - encoder.encode("Hello World!"), + encoder.encode("Hello World!") ); const len = encryptedMessage.length; @@ -480,9 +599,12 @@ test("roundtrip message", async () => { const clientId2 = "test2"; let kp = await page2.evaluate(async (clientId) => { - const {CoreCrypto, Ciphersuite, CredentialType} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite, CredentialType } = await import( + "./corecrypto.js" + ); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const config = { databaseName: "roundtrip message test 2", @@ -493,48 +615,64 @@ test("roundtrip message", async () => { const cc2 = await CoreCrypto.init(config); - const [kp] = await cc2.clientKeypackages(ciphersuite, credentialType, 1); + const [kp] = await cc2.clientKeypackages( + ciphersuite, + credentialType, + 1 + ); await cc2.close(); return kp; }, clientId2); kp = Uint8Array.from(Object.values(kp)); - let [welcome, message] = await page.evaluate(async (kp, messageText, conversationId, clientId2) => { - const {CoreCrypto, Ciphersuite, CredentialType} = await import("./corecrypto.js"); + let [welcome, message] = await page.evaluate( + async (kp, messageText, conversationId) => { + const { CoreCrypto, Ciphersuite, CredentialType } = await import( + "./corecrypto.js" + ); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; - const credentialType = CredentialType.Basic; - const config = { - databaseName: "roundtrip message test 1", - key: "test", - clientId: "test", - ciphersuites: [ciphersuite], - }; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const credentialType = CredentialType.Basic; + const config = { + databaseName: "roundtrip message test 1", + key: "test", + clientId: "test", + ciphersuites: [ciphersuite], + }; - const cc = await CoreCrypto.init(config); + const cc = await CoreCrypto.init(config); - const encoder = new TextEncoder(); + const encoder = new TextEncoder(); - const conversationIdBuffer = encoder.encode(conversationId); + const conversationIdBuffer = encoder.encode(conversationId); - await cc.createConversation(conversationIdBuffer, credentialType); + await cc.createConversation(conversationIdBuffer, credentialType); - const memberAdded = await cc.addClientsToConversation(conversationIdBuffer, [Uint8Array.from(Object.values(kp))]); + const memberAdded = await cc.addClientsToConversation( + conversationIdBuffer, + [Uint8Array.from(Object.values(kp))] + ); - await cc.commitAccepted(conversationIdBuffer); + await cc.commitAccepted(conversationIdBuffer); - if (!memberAdded) { - throw new Error("no welcome message was generated"); - } + if (!memberAdded) { + throw new Error("no welcome message was generated"); + } - const message = await cc.encryptMessage( - conversationIdBuffer, - encoder.encode(messageText), - ); + const message = await cc.encryptMessage( + conversationIdBuffer, + encoder.encode(messageText) + ); - return [memberAdded, message]; - }, kp, messageText, conversationId, clientId2); + return [memberAdded, message]; + }, + kp, + messageText, + conversationId, + clientId2 + ); welcome.welcome = Uint8Array.from(welcome.welcome); welcome.commit = Uint8Array.from(welcome.commit); @@ -542,40 +680,59 @@ test("roundtrip message", async () => { message = Uint8Array.from(Object.values(message)); - const isMessageIdentical = await page2.evaluate(async (welcome, message, messageText, conversationId, clientId) => { - const welcomeMessage = Uint8Array.from(Object.values(welcome)); - const encryptedMessage = Uint8Array.from(Object.values(message)); - const {CoreCrypto, Ciphersuite} = await import("./corecrypto.js"); - - const encoder = new TextEncoder(); - - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; - const config = { - databaseName: "roundtrip message test 2", - key: "test2", - clientId: clientId, - ciphersuites: [ciphersuite], - }; - const cc2 = await CoreCrypto.init(config); - - const messageBuffer = encoder.encode(messageText); - - const conversationIdBuffer = encoder.encode(conversationId); - - const welcome2 = await cc2.processWelcomeMessage(welcomeMessage); - const welcomeConversationId = welcome2.id; - if (!conversationIdBuffer.every((val, i) => val === welcomeConversationId[i])) { - throw new Error(`conversationId mismatch, got ${welcomeConversationId}, expected ${conversationIdBuffer}`); - } + const isMessageIdentical = await page2.evaluate( + async (welcome, message, messageText, conversationId, clientId) => { + const welcomeMessage = Uint8Array.from(Object.values(welcome)); + const encryptedMessage = Uint8Array.from(Object.values(message)); + const { CoreCrypto, Ciphersuite } = await import("./corecrypto.js"); + + const encoder = new TextEncoder(); + + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const config = { + databaseName: "roundtrip message test 2", + key: "test2", + clientId: clientId, + ciphersuites: [ciphersuite], + }; + const cc2 = await CoreCrypto.init(config); + + const messageBuffer = encoder.encode(messageText); + + const conversationIdBuffer = encoder.encode(conversationId); + + const welcome2 = await cc2.processWelcomeMessage(welcomeMessage); + const welcomeConversationId = welcome2.id; + if ( + !conversationIdBuffer.every( + (val, i) => val === welcomeConversationId[i] + ) + ) { + throw new Error( + `conversationId mismatch, got ${welcomeConversationId}, expected ${conversationIdBuffer}` + ); + } - const decryptedMessage = await cc2.decryptMessage(welcomeConversationId, encryptedMessage); + const decryptedMessage = await cc2.decryptMessage( + welcomeConversationId, + encryptedMessage + ); - if (!decryptedMessage.message) { - return false; - } + if (!decryptedMessage.message) { + return false; + } - return decryptedMessage.message.every((val, i) => val === messageBuffer[i]); - }, welcome.welcome, message, messageText, conversationId, clientId2); + return decryptedMessage.message.every( + (val, i) => val === messageBuffer[i] + ); + }, + welcome.welcome, + message, + messageText, + conversationId, + clientId2 + ); expect(isMessageIdentical).toBe(true); @@ -586,12 +743,15 @@ test("roundtrip message", async () => { }, 20000); test("callbacks default to false when not async", async () => { - const [ctx, page] = await initBrowser({captureLogs: false}); + const [, page] = await initBrowser({ captureLogs: false }); const result = await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CredentialType, ExternalProposalType} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite, CredentialType } = await import( + "./corecrypto.js" + ); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const client1Config = { databaseName: "test cb", @@ -608,13 +768,13 @@ test("callbacks default to false when not async", async () => { }; const callbacks = { - authorize(conversationId, clientId) { + authorize() { return true; }, - userAuthorize(conversationId, externalClientId, existingClients) { + userAuthorize() { return true; }, - clientIsExistingGroupUser(conversationId, clientId, existingClients, parentConversationIds) { + clientIsExistingGroupUser() { return true; }, }; @@ -624,7 +784,11 @@ test("callbacks default to false when not async", async () => { await cc.registerCallbacks(callbacks); const cc2 = await CoreCrypto.init(client2Config); - const [cc2Kp] = await cc2.clientKeypackages(ciphersuite, credentialType, 1); + const [cc2Kp] = await cc2.clientKeypackages( + ciphersuite, + credentialType, + 1 + ); const encoder = new TextEncoder(); @@ -633,7 +797,7 @@ test("callbacks default to false when not async", async () => { await cc.createConversation(conversationId, credentialType); try { - const creationMessage = await cc.addClientsToConversation(conversationId, [cc2Kp]); + await cc.addClientsToConversation(conversationId, [cc2Kp]); } catch (e) { return false; } @@ -647,15 +811,22 @@ test("callbacks default to false when not async", async () => { test("ext commits|proposals & callbacks", async () => { const [ctx, page] = await initBrowser(); - const callbacksResults = await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CredentialType, ExternalProposalType} = await import("./corecrypto.js"); + await page.evaluate(async () => { + const { + CoreCrypto, + Ciphersuite, + CredentialType, + ExternalProposalType, + } = await import("./corecrypto.js"); let theoreticalEpoch = 0; const assertEpoch = async (conversationId, expected, client) => { const got = await client.conversationEpoch(conversationId); if (parseInt(expected, 10) !== parseInt(got, 10)) { - throw new Error(`Epoch mismatch, expected ${expected}; got ${got}`); + throw new Error( + `Epoch mismatch, expected ${expected}; got ${got}` + ); } }; @@ -666,7 +837,8 @@ test("ext commits|proposals & callbacks", async () => { }; const credentialType = CredentialType.Basic; - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const client1Config = { databaseName: "test init", key: "test", @@ -696,15 +868,15 @@ test("ext commits|proposals & callbacks", async () => { }; const callbacks = { - async authorize(conversationId, clientId) { + async authorize() { callbacksResults.authorize = true; return true; }, - async userAuthorize(conversationId, externalClientId, existingClients) { + async userAuthorize() { callbacksResults.userAuthorize = true; return true; }, - async clientIsExistingGroupUser(conversationId, clientId, existingClients) { + async clientIsExistingGroupUser() { callbacksResults.clientIsExistingGroupUser = true; return true; }, @@ -715,10 +887,16 @@ test("ext commits|proposals & callbacks", async () => { await cc.registerCallbacks(callbacks); const cc2 = await CoreCrypto.init(client2Config); - const [cc2Kp] = await cc2.clientKeypackages(ciphersuite, credentialType, 1); + const [cc2Kp] = await cc2.clientKeypackages( + ciphersuite, + credentialType, + 1 + ); - const ccExternalProposal = await CoreCrypto.init(clientExtProposalConfig); - const ccExternalCommit = await CoreCrypto.init(clientExtCommitConfig); + const ccExternalProposal = await CoreCrypto.init( + clientExtProposalConfig + ); + await CoreCrypto.init(clientExtCommitConfig); const encoder = new TextEncoder(); @@ -727,7 +905,10 @@ test("ext commits|proposals & callbacks", async () => { await cc.createConversation(conversationId, credentialType); // ! This should trigger the authorize callback - const creationMessage = await cc.addClientsToConversation(conversationId, [cc2Kp]); + const creationMessage = await cc.addClientsToConversation( + conversationId, + [cc2Kp] + ); await cc.commitAccepted(conversationId); await assertEpoch(conversationId, ++theoreticalEpoch, cc); @@ -738,34 +919,38 @@ test("ext commits|proposals & callbacks", async () => { await cc2.processWelcomeMessage(creationMessage.welcome); - const extProposal = await ccExternalProposal.newExternalProposal(ExternalProposalType.Add, { - conversationId, - // ? Be careful; If you change anything above the epoch might change because right now it's a guesswork - // ? Normally, clients should obtain the epoch *somehow*, usually from the MLS DS, but we just guess that since we only added - // ? one client, the epoch should only have moved from 0 (initial state) to 1 (added 1 client -> committed) - epoch: theoreticalEpoch, - ciphersuite: ciphersuite, - credentialType: credentialType, - }); + const extProposal = await ccExternalProposal.newExternalProposal( + ExternalProposalType.Add, + { + conversationId, + // ? Be careful; If you change anything above the epoch might change because right now it's a guesswork + // ? Normally, clients should obtain the epoch *somehow*, usually from the MLS DS, but we just guess that since we only added + // ? one client, the epoch should only have moved from 0 (initial state) to 1 (added 1 client -> committed) + epoch: theoreticalEpoch, + ciphersuite: ciphersuite, + credentialType: credentialType, + } + ); // ! This should trigger the clientIsExistingGroupUser callback - const somethingProposal = await cc.decryptMessage(conversationId, extProposal); + await cc.decryptMessage(conversationId, extProposal); - const extProposalCommit = await cc.commitPendingProposals(conversationId); + await cc.commitPendingProposals(conversationId); await cc.commitAccepted(conversationId); await assertEpoch(conversationId, ++theoreticalEpoch, cc); if (!callbacksResults.clientIsExistingGroupUser) { - throw new Error("clientIsExistingGroupUser callback wasn't triggered"); + throw new Error( + "clientIsExistingGroupUser callback wasn't triggered" + ); } - const groupInfo = extProposalCommit.groupInfo; - /* TODO: this test cannot work anymore since this 'groupInfo' is wrapped in a MlsMessage and 'joinByExternalCommit' expects a raw GroupInfo. We don't have the required methods here to unwrap the MlsMessage. Tracking issue: WPB-9583 */ /*const extCommit = await ccExternalCommit.joinByExternalCommit(groupInfo.payload, credentialType); + // const groupInfo = extProposalCommit.groupInfo; // ! This should trigger the userAuthorize callback const somethingCommit = cc.decryptMessage(conversationId, extCommit.commit); @@ -793,7 +978,7 @@ test("proteusError", async () => { const [ctx, page] = await initBrowser(); await page.evaluate(async () => { - const {CoreCryptoError} = await import("./corecrypto.js"); + const { CoreCryptoError } = await import("./corecrypto.js"); const richErrorJSON = { errorName: "ErrorTest", @@ -808,19 +993,18 @@ test("proteusError", async () => { const ccErr = CoreCryptoError.fromStdError(e); const ccErr2 = CoreCryptoError.build(e.message); - if (ccErr.name !== ccErr2.name || ccErr.name !== "ErrorTest") { - throw new Error("Errors are different", {cause: ccErr}); + throw new Error("Errors are different", { cause: ccErr }); } if (ccErr.proteusErrorCode !== 22) { - throw new Error("Errors are different", {cause: ccErr}); + throw new Error("Errors are different", { cause: ccErr }); } try { throw ccErr; } catch (e) { - if (!e instanceof CoreCryptoError) { + if ((!e) instanceof CoreCryptoError) { throw new Error("Error is of the incorrect class"); } } @@ -834,12 +1018,14 @@ test("proteus", async () => { const [ctx, page] = await initBrowser(); await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CoreCryptoError} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite, CoreCryptoError } = await import( + "./corecrypto.js" + ); const encoder = new TextEncoder(); const decoder = new TextDecoder(); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const client1Config = { databaseName: "proteus test1", key: "test", @@ -858,7 +1044,9 @@ test("proteus", async () => { const lrPkId = CoreCrypto.proteusLastResortPrekeyId(); const u16MAX = Math.pow(2, 16) - 1; if (lrPkId !== u16MAX) { - throw new Error(`Last resort Prekey ID differs from expected ${u16MAX}, got ${lrPkId}`); + throw new Error( + `Last resort Prekey ID differs from expected ${u16MAX}, got ${lrPkId}` + ); } const aliceLrPk1 = await alice.proteusLastResortPrekey(); @@ -877,46 +1065,63 @@ test("proteus", async () => { const bobPrekey = await bob.proteusNewPrekey(10); await alice.proteusSessionFromPrekey("ab", bobPrekey); - const aliceBobMessage = await alice.proteusEncrypt("ab", encoder.encode(message)); + const aliceBobMessage = await alice.proteusEncrypt( + "ab", + encoder.encode(message) + ); - const decrypted = decoder.decode(await bob.proteusSessionFromMessage("ba", aliceBobMessage)); + const decrypted = decoder.decode( + await bob.proteusSessionFromMessage("ba", aliceBobMessage) + ); if (decrypted !== message) { - throw new Error("Message decrypted by bob doesn't match message sent by alice"); + throw new Error( + "Message decrypted by bob doesn't match message sent by alice" + ); } let proteusErrCode = 0; proteusErrCode = await bob.proteusLastErrorCode(); if (proteusErrCode !== 0) { - throw new Error(`bob has encountered an unlikely error [code ${proteusErrCode}`); + throw new Error( + `bob has encountered an unlikely error [code ${proteusErrCode}` + ); } try { await bob.proteusSessionFromMessage("ba", aliceBobMessage); - throw new TypeError("Error not thrown when CoreCryptoError[proteus error 101] should be triggered, something is wrong"); + throw new TypeError( + "Error not thrown when CoreCryptoError[proteus error 101] should be triggered, something is wrong" + ); } catch (e) { if (e instanceof CoreCryptoError) { const errorCode = e.proteusErrorCode; if (errorCode !== 101) { - throw new TypeError(`CoreCryptoError has been thrown, but the code isn't correct. Expected 101, got ${errorCode}`); + throw new TypeError( + `CoreCryptoError has been thrown, but the code isn't correct. Expected 101, got ${errorCode}` + ); } proteusErrCode = await bob.proteusLastErrorCode(); if (proteusErrCode !== 101) { - throw new TypeError(`The \`proteusLastErrorCode()\` method isn't consistent with the code returned. Expected 101, got ${proteusErrCode}`); + throw new TypeError( + `The \`proteusLastErrorCode()\` method isn't consistent with the code returned. Expected 101, got ${proteusErrCode}` + ); } return null; } else if (e instanceof TypeError) { throw e; } else { - throw new Error(`Unknown error type\nCause[${typeof e}]:\n${e}`, {cause: e}); + throw new Error( + `Unknown error type\nCause[${typeof e}]:\n${e}`, + { cause: e } + ); } } }); - await page.close(); await ctx.close(); }); @@ -925,193 +1130,214 @@ test("end-to-end-identity", async () => { const [ctx, page] = await initBrowser(); await page.evaluate(async () => { - const {CoreCrypto, Ciphersuite, CoreCryptoError} = await import("./corecrypto.js"); + const { CoreCrypto, Ciphersuite } = await import("./corecrypto.js"); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const cc = await CoreCrypto.deferredInit({ databaseName: "e2ei test", key: "test", }); const encoder = new TextEncoder(); - const jsonToByteArray = json => encoder.encode(JSON.stringify(json, null, 0)); + const jsonToByteArray = (json) => + encoder.encode(JSON.stringify(json, null, 0)); - const clientId = "b7ac11a4-8f01-4527-af88-1c30885a7931:4959bc6ab12f2846@wire.com"; + const clientId = + "b7ac11a4-8f01-4527-af88-1c30885a7931:4959bc6ab12f2846@wire.com"; const displayName = "Alice Smith"; const handle = "alice_wire"; const expirySec = 90 * 24 * 3600; - let enrollment = await cc.e2eiNewEnrollment(clientId, displayName, handle, expirySec, ciphersuite); + let enrollment = await cc.e2eiNewEnrollment( + clientId, + displayName, + handle, + expirySec, + ciphersuite + ); const directoryResp = { - "newNonce": "https://example.com/acme/new-nonce", - "newAccount": "https://example.com/acme/new-account", - "newOrder": "https://example.com/acme/new-order", - "revokeCert": "https://example.com/acme/revoke-cert", + newNonce: "https://example.com/acme/new-nonce", + newAccount: "https://example.com/acme/new-account", + newOrder: "https://example.com/acme/new-order", + revokeCert: "https://example.com/acme/revoke-cert", }; await enrollment.directoryResponse(jsonToByteArray(directoryResp)); const previousNonce = "YUVndEZQVTV6ZUNlUkJxRG10c0syQmNWeW1kanlPbjM"; - const accountReq = await enrollment.newAccountRequest(previousNonce); + await enrollment.newAccountRequest(previousNonce); const accountResp = { - "status": "valid", - "orders": "https://example.com/acme/acct/evOfKhNU60wg/orders", + status: "valid", + orders: "https://example.com/acme/acct/evOfKhNU60wg/orders", }; await enrollment.newAccountResponse(jsonToByteArray(accountResp)); - const newOrderReq = await enrollment.newOrderRequest(previousNonce); + await enrollment.newOrderRequest(previousNonce); const newOrderResp = { - "status": "pending", - "expires": "2037-01-05T14:09:07.99Z", - "notBefore": "2016-01-01T00:00:00Z", - "notAfter": "2037-01-08T00:00:00Z", - "identifiers": [ + status: "pending", + expires: "2037-01-05T14:09:07.99Z", + notBefore: "2016-01-01T00:00:00Z", + notAfter: "2037-01-08T00:00:00Z", + identifiers: [ { - "type": "wireapp-user", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", + type: "wireapp-user", + value: '{"name":"Alice Smith","domain":"wire.com","handle":"wireapp://%40alice_wire@wire.com"}', }, { - "type": "wireapp-device", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"client-id\":\"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", - } + type: "wireapp-device", + value: '{"name":"Alice Smith","domain":"wire.com","client-id":"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com","handle":"wireapp://%40alice_wire@wire.com"}', + }, ], - "authorizations": [ + authorizations: [ "https://example.com/acme/authz/6SDQFoXfk1UT75qRfzurqxWCMEatapiL", - "https://example.com/acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz" + "https://example.com/acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz", ], - "finalize": "https://example.com/acme/order/TOlocE8rfgo/finalize", + finalize: "https://example.com/acme/order/TOlocE8rfgo/finalize", }; - const newOrder = await enrollment.newOrderResponse(jsonToByteArray(newOrderResp)); + await enrollment.newOrderResponse(jsonToByteArray(newOrderResp)); - const userAuthzUrl = "https://example.com/acme/wire-acme/authz/6SDQFoXfk1UT75qRfzurqxWCMEatapiL"; - const userAuthzReq = await enrollment.newAuthzRequest(userAuthzUrl, previousNonce); + const userAuthzUrl = + "https://example.com/acme/wire-acme/authz/6SDQFoXfk1UT75qRfzurqxWCMEatapiL"; + await enrollment.newAuthzRequest(userAuthzUrl, previousNonce); const userAuthzResp = { - "status": "pending", - "expires": "2037-01-02T14:09:30Z", - "identifier": { - "type": "wireapp-user", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", + status: "pending", + expires: "2037-01-02T14:09:30Z", + identifier: { + type: "wireapp-user", + value: '{"name":"Alice Smith","domain":"wire.com","handle":"wireapp://%40alice_wire@wire.com"}', }, - "challenges": [ + challenges: [ { - "type": "wire-oidc-01", - "url": "https://localhost:55170/acme/acme/challenge/ZelRfonEK02jDGlPCJYHrY8tJKNsH0mw/RNb3z6tvknq7vz2U5DoHsSOGiWQyVtAz", - "status": "pending", - "token": "Gvg5AyOaw0uIQOWKE8lCSIP9nIYwcQiY", - "target": "https://dex/dex", - } + type: "wire-oidc-01", + url: "https://localhost:55170/acme/acme/challenge/ZelRfonEK02jDGlPCJYHrY8tJKNsH0mw/RNb3z6tvknq7vz2U5DoHsSOGiWQyVtAz", + status: "pending", + token: "Gvg5AyOaw0uIQOWKE8lCSIP9nIYwcQiY", + target: "https://dex/dex", + }, ], }; - const userAuthz = await enrollment.newAuthzResponse(jsonToByteArray(userAuthzResp)); + await enrollment.newAuthzResponse(jsonToByteArray(userAuthzResp)); - const deviceAuthzUrl = "https://example.com/acme/wire-acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz"; - const deviceAuthzReq = await enrollment.newAuthzRequest(deviceAuthzUrl, previousNonce); + const deviceAuthzUrl = + "https://example.com/acme/wire-acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz"; + await enrollment.newAuthzRequest(deviceAuthzUrl, previousNonce); const deviceAuthzResp = { - "status": "pending", - "expires": "2037-01-02T14:09:30Z", - "identifier": { - "type": "wireapp-device", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"client-id\":\"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", + status: "pending", + expires: "2037-01-02T14:09:30Z", + identifier: { + type: "wireapp-device", + value: '{"name":"Alice Smith","domain":"wire.com","client-id":"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com","handle":"wireapp://%40alice_wire@wire.com"}', }, - "challenges": [ + challenges: [ { - "type": "wire-dpop-01", - "url": "https://localhost:55170/acme/acme/challenge/ZelRfonEK02jDGlPCJYHrY8tJKNsH0mw/0y6hLM0TTOVUkawDhQcw5RB7ONwuhooW", - "status": "pending", - "token": "Gvg5AyOaw0uIQOWKE8lCSIP9nIYwcQiY", - "target": "https://wire.com/clients/4959bc6ab12f2846/access-token", + type: "wire-dpop-01", + url: "https://localhost:55170/acme/acme/challenge/ZelRfonEK02jDGlPCJYHrY8tJKNsH0mw/0y6hLM0TTOVUkawDhQcw5RB7ONwuhooW", + status: "pending", + token: "Gvg5AyOaw0uIQOWKE8lCSIP9nIYwcQiY", + target: "https://wire.com/clients/4959bc6ab12f2846/access-token", }, ], }; - const deviceAuthz = await enrollment.newAuthzResponse(jsonToByteArray(deviceAuthzResp)); + await enrollment.newAuthzResponse(jsonToByteArray(deviceAuthzResp)); const backendNonce = "U09ZR0tnWE5QS1ozS2d3bkF2eWJyR3ZVUHppSTJsMnU"; const dpopTokenExpirySecs = 3600; - const clientDpopToken = await enrollment.createDpopToken(dpopTokenExpirySecs, backendNonce); + await enrollment.createDpopToken(dpopTokenExpirySecs, backendNonce); - const accessToken = "eyJhbGciOiJFZERTQSIsInR5cCI6ImF0K2p3dCIsImp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6InlldjZPWlVudWlwbmZrMHRWZFlLRnM5MWpSdjVoVmF6a2llTEhBTmN1UEUifX0.eyJpYXQiOjE2NzU5NjE3NTYsImV4cCI6MTY4MzczNzc1NiwibmJmIjoxNjc1OTYxNzU2LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjU5MzA3LyIsInN1YiI6ImltcHA6d2lyZWFwcD1OREV5WkdZd05qYzJNekZrTkRCaU5UbGxZbVZtTWpReVpUSXpOVGM0TldRLzY1YzNhYzFhMTYzMWMxMzZAZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjU5MzA3LyIsImp0aSI6Ijk4NGM1OTA0LWZhM2UtNDVhZi1iZGM1LTlhODMzNjkxOGUyYiIsIm5vbmNlIjoiYjNWSU9YTk9aVE4xVUV0b2FXSk9VM1owZFVWdWJFMDNZV1ZIUVdOb2NFMCIsImNoYWwiOiJTWTc0dEptQUlJaGR6UnRKdnB4Mzg5ZjZFS0hiWHV4USIsImNuZiI6eyJraWQiOiJocG9RV2xNUmtjUURKN2xNcDhaSHp4WVBNVDBJM0Vhc2VqUHZhWmlGUGpjIn0sInByb29mIjoiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNkltUndiM0FyYW5kMElpd2lhbmRySWpwN0ltdDBlU0k2SWs5TFVDSXNJbU55ZGlJNklrVmtNalUxTVRraUxDSjRJam9pZVVGM1QxVmZTMXBpYUV0SFIxUjRaMGQ0WTJsa1VVZHFiMUpXWkdOdFlWQmpSblI0VG5Gd1gydzJTU0o5ZlEuZXlKcFlYUWlPakUyTnpVNU5qRTNOVFlzSW1WNGNDSTZNVFkzTmpBME9ERTFOaXdpYm1KbUlqb3hOamMxT1RZeE56VTJMQ0p6ZFdJaU9pSnBiWEJ3T25kcGNtVmhjSEE5VGtSRmVWcEhXWGRPYW1NeVRYcEdhMDVFUW1sT1ZHeHNXVzFXYlUxcVVYbGFWRWw2VGxSak5FNVhVUzgyTldNellXTXhZVEUyTXpGak1UTTJRR1Y0WVcxd2JHVXVZMjl0SWl3aWFuUnBJam9pTlRBM09HWmtaVEl0TlRCaU9DMDBabVZtTFdJeE5EQXRNekJrWVRrellqQmtZems1SWl3aWJtOXVZMlVpT2lKaU0xWkpUMWhPVDFwVVRqRlZSWFJ2WVZkS1QxVXpXakJrVlZaMVlrVXdNMWxYVmtoUlYwNXZZMFV3SWl3aWFIUnRJam9pVUU5VFZDSXNJbWgwZFNJNkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk5Ua3pNRGN2SWl3aVkyaGhiQ0k2SWxOWk56UjBTbTFCU1Vsb1pIcFNkRXAyY0hnek9EbG1Oa1ZMU0dKWWRYaFJJbjAuQk1MS1Y1OG43c1dITXkxMlUtTHlMc0ZJSkd0TVNKcXVoUkZvYnV6ZTlGNEpBN1NjdlFWSEdUTFF2ZVZfUXBfUTROZThyeU9GcEphUTc1VW5ORHR1RFEiLCJjbGllbnRfaWQiOiJpbXBwOndpcmVhcHA9TkRFeVpHWXdOamMyTXpGa05EQmlOVGxsWW1WbU1qUXlaVEl6TlRjNE5XUS82NWMzYWMxYTE2MzFjMTM2QGV4YW1wbGUuY29tIiwiYXBpX3ZlcnNpb24iOjMsInNjb3BlIjoid2lyZV9jbGllbnRfaWQifQ.Tf10dkKrNikGNgGhIdkrMHb0v6Jpde09MaIyBeuY6KORcxuglMGY7_V9Kd0LcVVPMDy1q4xbd39ZqosGz1NUBQ"; - const dpopChallengeReq = await enrollment.newDpopChallengeRequest(accessToken, previousNonce); + const accessToken = + "eyJhbGciOiJFZERTQSIsInR5cCI6ImF0K2p3dCIsImp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6InlldjZPWlVudWlwbmZrMHRWZFlLRnM5MWpSdjVoVmF6a2llTEhBTmN1UEUifX0.eyJpYXQiOjE2NzU5NjE3NTYsImV4cCI6MTY4MzczNzc1NiwibmJmIjoxNjc1OTYxNzU2LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjU5MzA3LyIsInN1YiI6ImltcHA6d2lyZWFwcD1OREV5WkdZd05qYzJNekZrTkRCaU5UbGxZbVZtTWpReVpUSXpOVGM0TldRLzY1YzNhYzFhMTYzMWMxMzZAZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjU5MzA3LyIsImp0aSI6Ijk4NGM1OTA0LWZhM2UtNDVhZi1iZGM1LTlhODMzNjkxOGUyYiIsIm5vbmNlIjoiYjNWSU9YTk9aVE4xVUV0b2FXSk9VM1owZFVWdWJFMDNZV1ZIUVdOb2NFMCIsImNoYWwiOiJTWTc0dEptQUlJaGR6UnRKdnB4Mzg5ZjZFS0hiWHV4USIsImNuZiI6eyJraWQiOiJocG9RV2xNUmtjUURKN2xNcDhaSHp4WVBNVDBJM0Vhc2VqUHZhWmlGUGpjIn0sInByb29mIjoiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNkltUndiM0FyYW5kMElpd2lhbmRySWpwN0ltdDBlU0k2SWs5TFVDSXNJbU55ZGlJNklrVmtNalUxTVRraUxDSjRJam9pZVVGM1QxVmZTMXBpYUV0SFIxUjRaMGQ0WTJsa1VVZHFiMUpXWkdOdFlWQmpSblI0VG5Gd1gydzJTU0o5ZlEuZXlKcFlYUWlPakUyTnpVNU5qRTNOVFlzSW1WNGNDSTZNVFkzTmpBME9ERTFOaXdpYm1KbUlqb3hOamMxT1RZeE56VTJMQ0p6ZFdJaU9pSnBiWEJ3T25kcGNtVmhjSEE5VGtSRmVWcEhXWGRPYW1NeVRYcEdhMDVFUW1sT1ZHeHNXVzFXYlUxcVVYbGFWRWw2VGxSak5FNVhVUzgyTldNellXTXhZVEUyTXpGak1UTTJRR1Y0WVcxd2JHVXVZMjl0SWl3aWFuUnBJam9pTlRBM09HWmtaVEl0TlRCaU9DMDBabVZtTFdJeE5EQXRNekJrWVRrellqQmtZems1SWl3aWJtOXVZMlVpT2lKaU0xWkpUMWhPVDFwVVRqRlZSWFJ2WVZkS1QxVXpXakJrVlZaMVlrVXdNMWxYVmtoUlYwNXZZMFV3SWl3aWFIUnRJam9pVUU5VFZDSXNJbWgwZFNJNkltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk5Ua3pNRGN2SWl3aVkyaGhiQ0k2SWxOWk56UjBTbTFCU1Vsb1pIcFNkRXAyY0hnek9EbG1Oa1ZMU0dKWWRYaFJJbjAuQk1MS1Y1OG43c1dITXkxMlUtTHlMc0ZJSkd0TVNKcXVoUkZvYnV6ZTlGNEpBN1NjdlFWSEdUTFF2ZVZfUXBfUTROZThyeU9GcEphUTc1VW5ORHR1RFEiLCJjbGllbnRfaWQiOiJpbXBwOndpcmVhcHA9TkRFeVpHWXdOamMyTXpGa05EQmlOVGxsWW1WbU1qUXlaVEl6TlRjNE5XUS82NWMzYWMxYTE2MzFjMTM2QGV4YW1wbGUuY29tIiwiYXBpX3ZlcnNpb24iOjMsInNjb3BlIjoid2lyZV9jbGllbnRfaWQifQ.Tf10dkKrNikGNgGhIdkrMHb0v6Jpde09MaIyBeuY6KORcxuglMGY7_V9Kd0LcVVPMDy1q4xbd39ZqosGz1NUBQ"; + await enrollment.newDpopChallengeRequest(accessToken, previousNonce); const dpopChallengeResp = { - "type": "wire-dpop-01", - "url": "https://example.com/acme/chall/prV_B7yEyA4", - "status": "valid", - "token": "LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0", - "target": "http://example.com/target" + type: "wire-dpop-01", + url: "https://example.com/acme/chall/prV_B7yEyA4", + status: "valid", + token: "LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0", + target: "http://example.com/target", }; - await enrollment.newDpopChallengeResponse(jsonToByteArray(dpopChallengeResp)); + await enrollment.newDpopChallengeResponse( + jsonToByteArray(dpopChallengeResp) + ); // simulate the OAuth redirect let storeHandle = await cc.e2eiEnrollmentStash(enrollment); enrollment = await cc.e2eiEnrollmentStashPop(storeHandle); - const idToken = "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NzU5NjE3NTYsImV4cCI6MTY3NjA0ODE1NiwibmJmIjoxNjc1OTYxNzU2LCJpc3MiOiJodHRwOi8vaWRwLyIsInN1YiI6ImltcHA6d2lyZWFwcD1OREV5WkdZd05qYzJNekZrTkRCaU5UbGxZbVZtTWpReVpUSXpOVGM0TldRLzY1YzNhYzFhMTYzMWMxMzZAZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwOi8vaWRwLyIsIm5hbWUiOiJTbWl0aCwgQWxpY2UgTSAoUUEpIiwiaGFuZGxlIjoiaW1wcDp3aXJlYXBwPWFsaWNlLnNtaXRoLnFhQGV4YW1wbGUuY29tIiwia2V5YXV0aCI6IlNZNzR0Sm1BSUloZHpSdEp2cHgzODlmNkVLSGJYdXhRLi15V29ZVDlIQlYwb0ZMVElSRGw3cjhPclZGNFJCVjhOVlFObEw3cUxjbWcifQ.0iiq3p5Bmmp8ekoFqv4jQu_GrnPbEfxJ36SCuw-UvV6hCi6GlxOwU7gwwtguajhsd1sednGWZpN8QssKI5_CDQ"; - const oidcChallengeReq = await enrollment.newOidcChallengeRequest(idToken, previousNonce); + const idToken = + "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NzU5NjE3NTYsImV4cCI6MTY3NjA0ODE1NiwibmJmIjoxNjc1OTYxNzU2LCJpc3MiOiJodHRwOi8vaWRwLyIsInN1YiI6ImltcHA6d2lyZWFwcD1OREV5WkdZd05qYzJNekZrTkRCaU5UbGxZbVZtTWpReVpUSXpOVGM0TldRLzY1YzNhYzFhMTYzMWMxMzZAZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwOi8vaWRwLyIsIm5hbWUiOiJTbWl0aCwgQWxpY2UgTSAoUUEpIiwiaGFuZGxlIjoiaW1wcDp3aXJlYXBwPWFsaWNlLnNtaXRoLnFhQGV4YW1wbGUuY29tIiwia2V5YXV0aCI6IlNZNzR0Sm1BSUloZHpSdEp2cHgzODlmNkVLSGJYdXhRLi15V29ZVDlIQlYwb0ZMVElSRGw3cjhPclZGNFJCVjhOVlFObEw3cUxjbWcifQ.0iiq3p5Bmmp8ekoFqv4jQu_GrnPbEfxJ36SCuw-UvV6hCi6GlxOwU7gwwtguajhsd1sednGWZpN8QssKI5_CDQ"; + await enrollment.newOidcChallengeRequest(idToken, previousNonce); const oidcChallengeResp = { - "type": "wire-oidc-01", - "url": "https://localhost:55794/acme/acme/challenge/tR33VAzGrR93UnBV5mTV9nVdTZrG2Ln0/QXgyA324mTntfVAIJKw2cF23i4UFJltk", - "status": "valid", - "token": "2FpTOmNQvNfWDktNWt1oIJnjLE3MkyFb", - "target": "http://example.com/target" + type: "wire-oidc-01", + url: "https://localhost:55794/acme/acme/challenge/tR33VAzGrR93UnBV5mTV9nVdTZrG2Ln0/QXgyA324mTntfVAIJKw2cF23i4UFJltk", + status: "valid", + token: "2FpTOmNQvNfWDktNWt1oIJnjLE3MkyFb", + target: "http://example.com/target", }; - await enrollment.newOidcChallengeResponse(jsonToByteArray(oidcChallengeResp)); + await enrollment.newOidcChallengeResponse( + jsonToByteArray(oidcChallengeResp) + ); - const orderUrl = "https://example.com/acme/wire-acme/order/C7uOXEgg5KPMPtbdE3aVMzv7cJjwUVth"; - const checkOrderReq = await enrollment.checkOrderRequest(orderUrl, previousNonce); + const orderUrl = + "https://example.com/acme/wire-acme/order/C7uOXEgg5KPMPtbdE3aVMzv7cJjwUVth"; + await enrollment.checkOrderRequest(orderUrl, previousNonce); const checkOrderResp = { - "status": "ready", - "finalize": "https://localhost:55170/acme/acme/order/FaKNEM5iL79ROLGJdO1DXVzIq5rxPEob/finalize", - "identifiers": [ + status: "ready", + finalize: + "https://localhost:55170/acme/acme/order/FaKNEM5iL79ROLGJdO1DXVzIq5rxPEob/finalize", + identifiers: [ { - "type": "wireapp-user", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", + type: "wireapp-user", + value: '{"name":"Alice Smith","domain":"wire.com","handle":"wireapp://%40alice_wire@wire.com"}', }, { - "type": "wireapp-device", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"client-id\":\"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", + type: "wireapp-device", + value: '{"name":"Alice Smith","domain":"wire.com","client-id":"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com","handle":"wireapp://%40alice_wire@wire.com"}', }, ], - "authorizations": [ + authorizations: [ "https://example.com/acme/authz/6SDQFoXfk1UT75qRfzurqxWCMEatapiL", - "https://example.com/acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz" + "https://example.com/acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz", ], - "expires": "2032-02-10T14:59:20Z", - "notBefore": "2013-02-09T14:59:20.442908Z", - "notAfter": "2032-02-09T15:59:20.442908Z", + expires: "2032-02-10T14:59:20Z", + notBefore: "2013-02-09T14:59:20.442908Z", + notAfter: "2032-02-09T15:59:20.442908Z", }; await enrollment.checkOrderResponse(jsonToByteArray(checkOrderResp)); - const finalizeReq = await enrollment.finalizeRequest(previousNonce); + await enrollment.finalizeRequest(previousNonce); const finalizeResp = { - "certificate": "https://localhost:55170/acme/acme/certificate/rLhCIYygqzWhUmP1i5tmtZxFUvJPFxSL", - "status": "valid", - "finalize": "https://localhost:55170/acme/acme/order/FaKNEM5iL79ROLGJdO1DXVzIq5rxPEob/finalize", - "identifiers": [ + certificate: + "https://localhost:55170/acme/acme/certificate/rLhCIYygqzWhUmP1i5tmtZxFUvJPFxSL", + status: "valid", + finalize: + "https://localhost:55170/acme/acme/order/FaKNEM5iL79ROLGJdO1DXVzIq5rxPEob/finalize", + identifiers: [ { - "type": "wireapp-user", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", + type: "wireapp-user", + value: '{"name":"Alice Smith","domain":"wire.com","handle":"wireapp://%40alice_wire@wire.com"}', }, { - "type": "wireapp-device", - "value": "{\"name\":\"Alice Smith\",\"domain\":\"wire.com\",\"client-id\":\"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com\",\"handle\":\"wireapp://%40alice_wire@wire.com\"}", - } + type: "wireapp-device", + value: '{"name":"Alice Smith","domain":"wire.com","client-id":"wireapp://t6wRpI8BRSeviBwwiFp5MQ!4959bc6ab12f2846@wire.com","handle":"wireapp://%40alice_wire@wire.com"}', + }, ], - "authorizations": [ + authorizations: [ "https://example.com/acme/authz/6SDQFoXfk1UT75qRfzurqxWCMEatapiL", - "https://example.com/acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz" + "https://example.com/acme/authz/d2sJyM0MaV6wTX4ClP8eUQ8TF4ZKk7jz", ], - "expires": "2032-02-10T14:59:20Z", - "notBefore": "2013-02-09T14:59:20.442908Z", - "notAfter": "2032-02-09T15:59:20.442908Z", + expires: "2032-02-10T14:59:20Z", + notBefore: "2013-02-09T14:59:20.442908Z", + notAfter: "2032-02-09T15:59:20.442908Z", }; await enrollment.finalizeResponse(jsonToByteArray(finalizeResp)); - const certificateReq = await enrollment.certificateRequest(previousNonce); + await enrollment.certificateRequest(previousNonce); }); await page.close(); @@ -1122,9 +1348,15 @@ test("e2ei is conversation invalid", async () => { const [ctx, page] = await initBrowser(); let [state, E2eiConversationState] = await page.evaluate(async () => { - const { CoreCrypto, Ciphersuite, CredentialType, E2eiConversationState } = await import("./corecrypto.js"); + const { + CoreCrypto, + Ciphersuite, + CredentialType, + E2eiConversationState, + } = await import("./corecrypto.js"); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const cc = await CoreCrypto.init({ databaseName: "is invalid", @@ -1153,9 +1385,16 @@ test("logs are forwarded when logger is registered", async () => { const [ctx, page] = await initBrowser(); let [logs] = await page.evaluate(async () => { - const { CoreCrypto, Ciphersuite, CredentialType, CoreCryptoLogLevel, initLogger } = await import("./corecrypto.js"); + const { + CoreCrypto, + Ciphersuite, + CredentialType, + CoreCryptoLogLevel, + initLogger, + } = await import("./corecrypto.js"); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const cc = await CoreCrypto.init({ databaseName: "is invalid", @@ -1165,11 +1404,14 @@ test("logs are forwarded when logger is registered", async () => { }); const logs = []; - initLogger({ - log: (level, json_msg) => { - logs.push(json_msg) + initLogger( + { + log: (level, json_msg) => { + logs.push(json_msg); + }, }, - }, CoreCryptoLogLevel.Debug) + CoreCryptoLogLevel.Debug + ); const encoder = new TextEncoder(); const conversationId = encoder.encode("invalidConversation"); @@ -1179,7 +1421,7 @@ test("logs are forwarded when logger is registered", async () => { return [logs]; }); - expect(logs.length).toBeGreaterThan(0) + expect(logs.length).toBeGreaterThan(0); await page.close(); await ctx.close(); @@ -1189,9 +1431,16 @@ test("logs are not forwarded when logger is registered, but log level is too hig const [ctx, page] = await initBrowser(); let [logs] = await page.evaluate(async () => { - const { CoreCrypto, Ciphersuite, CredentialType, CoreCryptoLogLevel, initLogger } = await import("./corecrypto.js"); + const { + CoreCrypto, + Ciphersuite, + CredentialType, + CoreCryptoLogLevel, + initLogger, + } = await import("./corecrypto.js"); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const cc = await CoreCrypto.init({ databaseName: "is invalid", @@ -1201,11 +1450,14 @@ test("logs are not forwarded when logger is registered, but log level is too hig }); const logs = []; - initLogger({ - log: (level, json_msg) => { - logs.push(json_msg) + initLogger( + { + log: (level, json_msg) => { + logs.push(json_msg); + }, }, - }, CoreCryptoLogLevel.Warn) + CoreCryptoLogLevel.Warn + ); const encoder = new TextEncoder(); const conversationId = encoder.encode("invalidConversation"); @@ -1215,7 +1467,7 @@ test("logs are not forwarded when logger is registered, but log level is too hig return [logs]; }); - expect(logs).toHaveLength(0) + expect(logs).toHaveLength(0); await page.close(); await ctx.close(); @@ -1225,16 +1477,23 @@ test("errors thrown by logger are reported as errors", async () => { const [ctx, page] = await initBrowser(); const consoleErrors = []; - page.on("console", msg => { + page.on("console", (msg) => { if (msg.type() == "error") { - consoleErrors.push(msg) + consoleErrors.push(msg); } }); await page.evaluate(async () => { - const { CoreCrypto, Ciphersuite, CredentialType, CoreCryptoLogLevel, initLogger } = await import("./corecrypto.js"); + const { + CoreCrypto, + Ciphersuite, + CredentialType, + CoreCryptoLogLevel, + initLogger, + } = await import("./corecrypto.js"); - const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; + const ciphersuite = + Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519; const credentialType = CredentialType.Basic; const cc = await CoreCrypto.init({ databaseName: "is invalid", @@ -1243,11 +1502,14 @@ test("errors thrown by logger are reported as errors", async () => { clientId: "test", }); - initLogger({ - log: (level, json_msg) => { - throw Error("test error"); + initLogger( + { + log: () => { + throw Error("test error"); + }, }, - }, CoreCryptoLogLevel.Debug) + CoreCryptoLogLevel.Debug + ); const encoder = new TextEncoder(); const conversationId = encoder.encode("invalidConversation"); @@ -1255,15 +1517,18 @@ test("errors thrown by logger are reported as errors", async () => { await cc.wipe(); }); - expect(consoleErrors.length).toBeGreaterThan(0) + expect(consoleErrors.length).toBeGreaterThan(0); // find any console error with a remote object, we expect this to be the error we have thrown. - const consoleError = consoleErrors.find((element) => element.args().length > 0); - const remoteObject = consoleError.args()[0].remoteObject() + const consoleError = consoleErrors.find( + (element) => element.args().length > 0 + ); + const remoteObject = consoleError.args()[0].remoteObject(); expect(remoteObject.className).toBe("Error"); - expect(remoteObject.description).toEqual(expect.stringContaining("test error")) + expect(remoteObject.description).toEqual( + expect.stringContaining("test error") + ); await page.close(); await ctx.close(); }); -