diff --git a/packages/crypto/src/context.tsx b/packages/crypto/src/context.tsx index 588aff1..7e701c5 100644 --- a/packages/crypto/src/context.tsx +++ b/packages/crypto/src/context.tsx @@ -76,11 +76,11 @@ export default function Provider(props: { children: React.ReactNode }) { /** * Creates crypto action functions that safely delegate to the worker API. - * @param apiRef Worker API reference object. + * @param getApiRef Function that returns the worker API reference. * @returns Typed crypto action functions. */ export function createCryptoActions( - apiRef: React.RefObject, + getApiRef: () => ApiRef | null, ): CryptoContextType { /** * Encrypts plaintext by delegating to the crypto worker API. @@ -92,7 +92,7 @@ export function createCryptoActions( secret: string, plaintext: string, ): Promise => { - const api = apiRef.current; + const api = getApiRef(); if (!api) throw new Error("API not initialized"); return await api.encrypt(secret, plaintext); }; @@ -107,7 +107,7 @@ export function createCryptoActions( secret: string, ciphertext: string, ): Promise => { - const api = apiRef.current; + const api = getApiRef(); if (!api) throw new Error("API not initialized"); return await api.decrypt(secret, ciphertext); }; @@ -124,7 +124,7 @@ export function createCryptoActions( ownPublicKey: string, otherPublicKey: string, ): Promise => { - const api = apiRef.current; + const api = getApiRef(); if (!api) throw new Error("API not initialized"); return await api.getSharedSecret( ownPrivateKey, diff --git a/packages/crypto/src/worker.test.ts b/packages/crypto/src/worker.test.ts index 3d0020d..eae1c3c 100644 --- a/packages/crypto/src/worker.test.ts +++ b/packages/crypto/src/worker.test.ts @@ -8,8 +8,27 @@ import { decrypt, encrypt, getSharedSecret } from "./worker"; * @returns Base64url string. */ function bytesToB64u(value: Uint8Array): string { - const b64 = Buffer.from(value).toString("base64"); - return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); + const alphabet = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + let output = ""; + + for (let index = 0; index < value.length; index += 3) { + const first = value[index] ?? 0; + const second = value[index + 1] ?? 0; + const third = value[index + 2] ?? 0; + const chunk = (first << 16) | (second << 8) | third; + + output += alphabet[(chunk >> 18) & 63]; + output += alphabet[(chunk >> 12) & 63]; + output += index + 1 < value.length ? alphabet[(chunk >> 6) & 63] : "="; + output += index + 2 < value.length ? alphabet[chunk & 63] : "="; + } + + return output + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/g, ""); } /**