mirror of
https://github.com/fromchat-messenger/web.git
synced 2026-09-22 19:15:08 +03:00
@@ -13,7 +13,7 @@ export async function decryptDm(envelope: DmEnvelope, senderPublicKeyB64: string
|
||||
if (!keys) throw new Error("Keys not initialized");
|
||||
|
||||
// Obtain the key
|
||||
const shared = await ecdhSharedSecret(keys.privateKey, ub64(senderPublicKeyB64));
|
||||
const shared = ecdhSharedSecret(keys.privateKey, ub64(senderPublicKeyB64));
|
||||
const wkRaw = await deriveWrappingKey(shared, ub64(envelope.salt), new Uint8Array([1]));
|
||||
const wk = await importAesGcmKey(wkRaw);
|
||||
const mk = await aesGcmDecrypt(wk, ub64(envelope.iv2), ub64(envelope.wrappedMk));
|
||||
@@ -53,7 +53,7 @@ export async function sendDMViaWebSocket(recipientId: number, recipientPublicKey
|
||||
// Encryption key
|
||||
const mk = randomBytes(32);
|
||||
const wkSalt = randomBytes(16);
|
||||
const shared = await ecdhSharedSecret(keys.privateKey, ub64(recipientPublicKeyB64));
|
||||
const shared = ecdhSharedSecret(keys.privateKey, ub64(recipientPublicKeyB64));
|
||||
const wkRaw = await deriveWrappingKey(shared, wkSalt, new Uint8Array([1]));
|
||||
const wk = await importAesGcmKey(wkRaw);
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ export async function ensureKeysOnLogin(password: string, token: string): Promis
|
||||
currentPublicKey = serverPub;
|
||||
} else {
|
||||
// We don't have the corresponding public key from server; regenerate pair to resync
|
||||
const pair = await generateX25519KeyPair();
|
||||
const pair = generateX25519KeyPair();
|
||||
currentPublicKey = pair.publicKey;
|
||||
currentPrivateKey = pair.privateKey;
|
||||
await uploadPublicKey(currentPublicKey, token);
|
||||
@@ -107,7 +107,7 @@ export async function ensureKeysOnLogin(password: string, token: string): Promis
|
||||
}
|
||||
|
||||
// First-time setup: generate keys and upload
|
||||
const pair = await generateX25519KeyPair();
|
||||
const pair = generateX25519KeyPair();
|
||||
currentPublicKey = pair.publicKey;
|
||||
currentPrivateKey = pair.privateKey;
|
||||
await uploadPublicKey(currentPublicKey, token);
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Message as MessageType } from "../../../core/types";
|
||||
import defaultAvatar from "../../../resources/images/default-avatar.png";
|
||||
import Quote from "../core/Quote";
|
||||
import { parse } from "marked";
|
||||
import DOMPurify from "dompurify";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface MessageProps {
|
||||
@@ -15,15 +16,13 @@ interface MessageProps {
|
||||
}
|
||||
|
||||
export function Message({ message, isAuthor, onProfileClick, onContextMenu, isLoadingProfile = false, isDm = false }: MessageProps) {
|
||||
const [formattedMessage, setFormattedMessage] = useState({ __html: "" });
|
||||
const [formattedMessage, setFormattedMessage] = useState({ __html: DOMPurify.sanitize(message.content).trim() });
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const DOMPurify = await import("dompurify");
|
||||
|
||||
setFormattedMessage({
|
||||
__html: DOMPurify.default.sanitize(
|
||||
await parse(message.content.trim())
|
||||
__html: DOMPurify.sanitize(
|
||||
await parse(message.content)
|
||||
).trim()
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import nacl from "tweetnacl";
|
||||
import { hkdfExtractAndExpand } from "../crypto/kdf";
|
||||
|
||||
export interface X25519KeyPair {
|
||||
@@ -7,16 +8,12 @@ export interface X25519KeyPair {
|
||||
|
||||
export type KeyPair = X25519KeyPair;
|
||||
|
||||
export async function generateX25519KeyPair(): Promise<X25519KeyPair> {
|
||||
const nacl = await import("tweetnacl");
|
||||
|
||||
export function generateX25519KeyPair(): X25519KeyPair {
|
||||
const kp = nacl.box.keyPair();
|
||||
return { publicKey: kp.publicKey, privateKey: kp.secretKey };
|
||||
}
|
||||
|
||||
export async function ecdhSharedSecret(myPrivateKey: Uint8Array, theirPublicKey: Uint8Array): Promise<Uint8Array> {
|
||||
const nacl = await import("tweetnacl");
|
||||
|
||||
export function ecdhSharedSecret(myPrivateKey: Uint8Array, theirPublicKey: Uint8Array): Uint8Array {
|
||||
// nacl.box.before returns shared key (Curve25519, XSalsa20-Poly1305 context). We use it as IKM into HKDF.
|
||||
return nacl.box.before(theirPublicKey, myPrivateKey);
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ export default defineConfig({
|
||||
cssMinify: true,
|
||||
assetsInlineLimit: 0,
|
||||
outDir: process.env.VITE_ELECTRON ? "build/electron/dist" : "build/normal/dist",
|
||||
chunkSizeWarningLimit: 1024,
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: resolve(__dirname, "index.html"),
|
||||
|
||||
Reference in New Issue
Block a user