Implement E2EE and message content moderation

This commit is contained in:
Jamie Brunton committed 2026-01-02 20:49:11 +00:00
1 parent e1ff87dc03
commit 198cd80dfd
74 files changed
+12939 -2178

No files matched your search

@@ -0,0 +1,52 @@
/**
* Text Message Decryption
*
* Decrypts E2EE text messages using the user's RSA private key.
*/
import { unwrapAESKey, importAESKey, decryptAES } from './crypto';
import { base64ToArrayBuffer, base64ToUint8Array } from './utils';
import type { KeysMetadata, RSAPrivateKeyJWK } from './types';
/**
* Decrypt an E2EE text message
*
* @param encryptedContent - Base64-encoded ciphertext
* @param encryptionIv - Base64-encoded initialization vector
* @param keysMetadata - The wrapped keys metadata
* @param privateKeyJwk - User's RSA private key
* @param isRecipient - Whether the current user is the recipient (true) or sender (false)
* @returns The decrypted plaintext message
*/
export async function decryptTextMessage(
encryptedContent: string,
encryptionIv: string,
keysMetadata: KeysMetadata,
privateKeyJwk: RSAPrivateKeyJWK,
isRecipient: boolean
): Promise<string> {
// 1. Select the correct wrapped key
const wrappedKeyBase64 = isRecipient
? keysMetadata.recipient_wrapped_key
: keysMetadata.sender_wrapped_key;
if (!wrappedKeyBase64) {
throw new Error('No wrapped key available for decryption');
}
// 2. Unwrap AES key using RSA private key
const rawAesKey = await unwrapAESKey(wrappedKeyBase64, privateKeyJwk);
// 3. Import AES key
const aesKey = await importAESKey(rawAesKey);
// 4. Decrypt content
const iv = base64ToUint8Array(encryptionIv);
const ciphertext = base64ToArrayBuffer(encryptedContent);
const plaintext = await decryptAES(ciphertext, aesKey, iv);
// 5. Decode to string
return new TextDecoder().decode(plaintext);
}