]> git.codecow.com Git - libnemo.git/commitdiff
Add CryptoKey to accepted worker data types. Fix passkey worker.
authorChris Duncan <chris@zoso.dev>
Sat, 26 Jul 2025 23:27:39 +0000 (16:27 -0700)
committerChris Duncan <chris@zoso.dev>
Sat, 26 Jul 2025 23:27:39 +0000 (16:27 -0700)
src/lib/workers/passkey.ts
src/types.d.ts

index 80c9f54b0a4f1b592de74e586dae69c1fef31c08..baf0e4af4b8c2fe97ec40e976ee1b6b78ee67cf5 100644 (file)
@@ -17,21 +17,43 @@ export class Passkey extends WorkerInterface {
                this.listen()
        }
 
-       static async work (data: NamedData<ArrayBuffer>): Promise<NamedData<CryptoKey>> {
-               this.#validate(data)
+       static async work (data: NamedData | unknown): Promise<NamedData> {
+               let method, password, salt
+               if (data == null) {
+                       throw new TypeError('Worker received no data')
+               }
+               if (typeof data !== 'object') {
+                       throw new Error('Invalid data')
+               }
+               const dataObject = data as { [key: string]: unknown }
+               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')
+               }
+               if (dataObject.method !== 'encrypt' && dataObject.method !== 'decrypt') {
+                       throw new TypeError('Invalid method')
+               }
+               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
+               }
                try {
-                       const salt = (method === 'decrypt')
-                               ? data.salt
-                               : (await Entropy.create()).buffer
+                       salt ??= (await Entropy.create()).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()
-               }       
+               }
        }
-       
+
        static async #createAesKey (purpose: 'encrypt' | 'decrypt', password: ArrayBuffer, salt: ArrayBuffer): Promise<CryptoKey> {
                const derivationKey = await globalThis.crypto.subtle.importKey('raw', password, 'PBKDF2', false, ['deriveBits', 'deriveKey'])
                const derivationAlgorithm: Pbkdf2Params = {
@@ -46,24 +68,6 @@ export class Passkey extends WorkerInterface {
                }
                return await globalThis.crypto.subtle.deriveKey(derivationAlgorithm, derivationKey, derivedKeyType, false, [purpose])
        }
-
-       static #validate (data: unknown): asserts data is NamedData<ArrayBuffer> } {
-               if (data == null) {
-                       throw new TypeError('Worker received no data')
-               }
-               if (typeof data !== 'object') {
-                       throw new Error('Invalid data')
-               }
-               const dataObject = data as { [key: string]: unknown }
-               if (!(data.password instanceof ArrayBuffer)) {
-                       throw new TypeError('Password must be ArrayBuffer')
-               }
-               if (data.method !== 'encrypt' && data.method !== 'decrypt') {
-                       throw new TypeError('Invalid method')
-               }
-               if (data.method === 'decrypt' && !(data.salt instanceof ArrayBuffer)) {
-                       throw new TypeError('Salt required for decryption key')
-       }
 }
 
 let importWorkerThreads = ''
index 636e1b22d9c0a07d2a142c00304da888e3cb19d3..3bf50bf557e2c936254186ec3e564f5e296e5ef4 100644 (file)
@@ -377,7 +377,7 @@ export declare class ChangeBlock extends Block {
        constructor (account: Account | string, balance: string, representative: Account | string, frontier: string, work?: string)
 }
 
-export type Data = boolean | number[] | string | ArrayBuffer
+export type Data = boolean | number[] | string | ArrayBuffer | CryptoKey
 
 /**
 * Represents a cryptographically strong source of entropy suitable for use in