From ea4849410133acf7b2d83ec661fc6ec223b4e2e2 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Sat, 26 Jul 2025 22:10:57 -0700 Subject: [PATCH] Refactor data extraction into separate function. --- src/lib/workers/passkey.ts | 46 +++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/lib/workers/passkey.ts b/src/lib/workers/passkey.ts index e98f79d..2082fbe 100644 --- a/src/lib/workers/passkey.ts +++ b/src/lib/workers/passkey.ts @@ -14,8 +14,19 @@ export class Passkey extends WorkerInterface { this.listen() } - static async work (data: NamedData | unknown): Promise { - let method, password, salt + static async work (data: NamedData | unknown): Promise> { + const { purpose, password, salt } = this.#extractData(data) + try { + const key = await this.#createAesKey(purpose, password, salt) + return { salt, key } + } catch (err) { + throw new Error('Failed to derive key from password', { cause: err }) + } finally { + password.transfer() + } + } + + static #extractData (data: unknown) { if (data == null) { throw new TypeError('Worker received no data') } @@ -26,29 +37,22 @@ export class Passkey extends WorkerInterface { if (!('password' in dataObject) || !(dataObject.password instanceof ArrayBuffer)) { throw new TypeError('Password must be ArrayBuffer') } - password = dataObject.password - if (!('method' in dataObject)) { - throw new TypeError('Method is required') + const password: ArrayBuffer = dataObject.password + if (!('purpose' in dataObject)) { + throw new TypeError('Key purpose is required') } - if (dataObject.method !== 'encrypt' && dataObject.method !== 'decrypt') { - throw new TypeError('Invalid method') + if (dataObject.purpose !== 'encrypt' && dataObject.purpose !== 'decrypt') { + throw new TypeError('Invalid key purpose') } - method = dataObject.method as typeof dataObject.method - if (method === 'decrypt') { - if (!('salt' in dataObject) || !(dataObject.salt instanceof ArrayBuffer)) { - throw new TypeError('Salt required for decryption key') - } - salt = dataObject.salt + const purpose: 'encrypt' | 'decrypt' = dataObject.purpose + if (purpose === 'decrypt' && !('salt' in dataObject)) { + throw new TypeError('Salt required for decryption key') } - try { - salt ??= globalThis.crypto.getRandomValues(new Uint8Array(32)).buffer - const key = await this.#createAesKey(method, password, salt) - return { salt, key } - } catch (err) { - throw new Error('Failed to derive key from password', { cause: err }) - } finally { - password.transfer() + if (dataObject.salt != null && !(dataObject.salt instanceof ArrayBuffer)) { + throw new TypeError('Salt must be ArrayBuffer') } + const salt: ArrayBuffer = dataObject.salt ?? globalThis.crypto.getRandomValues(new Uint8Array(32)).buffer + return { purpose, password, salt } } static async #createAesKey (purpose: 'encrypt' | 'decrypt', password: ArrayBuffer, salt: ArrayBuffer): Promise { -- 2.47.3