b61f929cf7
packages/shared/src/index.ts and all sub-modules used .js extensions on relative imports (e.g. './admin/index.js') pointing at .ts source files. TypeScript with moduleResolution: "Bundler" doesn't need them, and Metro's eager exporter (used for preview / production builds) reads them literally and fails — only the dev-server Metro fell back to .ts. Workspace typecheck remains 8/8 green; Vite and TS Bundler resolution already accept both styles, so desktop is unaffected.
59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
import { getCryptoBackend } from './backend';
|
|
import { decryptFrom, encryptFor, type EncryptedEnvelope } from './box';
|
|
|
|
// Sender-Key (Signal-style) helpers — one symmetric XSalsa20-Poly1305 key per
|
|
// conversation, wrapped with `crypto_box` for each recipient device's pubkey.
|
|
//
|
|
// Flow:
|
|
// - generateConvKey() produces 32 random bytes
|
|
// - wrapConvKeyForRecipient() encrypts the conv-key with sender's private key
|
|
// and recipient's pubkey -> stored in `conversation_keys` table
|
|
// - unwrapConvKey() reverses it on the receiving side
|
|
// - encryptWithConvKey()/decryptWithConvKey() do the message-payload work
|
|
|
|
export function generateConvKey(): Uint8Array {
|
|
const backend = getCryptoBackend();
|
|
return backend.randomBytes(backend.secretboxKeyLength);
|
|
}
|
|
|
|
export async function wrapConvKeyForRecipient(
|
|
convKey: Uint8Array,
|
|
recipientPublicKey: Uint8Array,
|
|
senderPrivateKey: Uint8Array,
|
|
): Promise<EncryptedEnvelope> {
|
|
return encryptFor(convKey, recipientPublicKey, senderPrivateKey);
|
|
}
|
|
|
|
export async function unwrapConvKey(
|
|
encryptedKey: Uint8Array,
|
|
nonce: Uint8Array,
|
|
senderPublicKey: Uint8Array,
|
|
recipientPrivateKey: Uint8Array,
|
|
): Promise<Uint8Array> {
|
|
return decryptFrom(encryptedKey, nonce, senderPublicKey, recipientPrivateKey);
|
|
}
|
|
|
|
export interface ConvCipher {
|
|
ciphertext: Uint8Array;
|
|
nonce: Uint8Array;
|
|
}
|
|
|
|
export function encryptWithConvKey(
|
|
plaintext: Uint8Array,
|
|
convKey: Uint8Array,
|
|
): ConvCipher {
|
|
const backend = getCryptoBackend();
|
|
const nonce = backend.randomBytes(backend.secretboxNonceLength);
|
|
const ciphertext = backend.secretbox(plaintext, nonce, convKey);
|
|
return { ciphertext, nonce };
|
|
}
|
|
|
|
export function decryptWithConvKey(
|
|
ciphertext: Uint8Array,
|
|
nonce: Uint8Array,
|
|
convKey: Uint8Array,
|
|
): Uint8Array {
|
|
const backend = getCryptoBackend();
|
|
return backend.secretboxOpen(ciphertext, nonce, convKey);
|
|
}
|