81 lines
2.4 KiB
TypeScript
81 lines
2.4 KiB
TypeScript
import { decryptBinary, decryptDirectMessage, encryptBinary, encryptDirectMessage } from '@/lib/e2e-crypto';
|
|
|
|
export type E2EMessageKind = 'text' | 'emoji' | 'image' | 'voice' | 'audio' | 'video' | 'video_note' | 'file';
|
|
|
|
export interface E2EMessagePayload {
|
|
kind: E2EMessageKind;
|
|
text?: string;
|
|
emojiId?: string;
|
|
fileName?: string;
|
|
mimeType?: string;
|
|
fileSize?: number;
|
|
durationMs?: number;
|
|
}
|
|
|
|
export async function encryptE2EPayload(userId: string, peerPublicKey: string, payload: E2EMessagePayload) {
|
|
return encryptDirectMessage(userId, peerPublicKey, JSON.stringify(payload));
|
|
}
|
|
|
|
export async function decryptE2EPayload(userId: string, peerPublicKey: string, encrypted: string): Promise<E2EMessagePayload | null> {
|
|
const decrypted = await decryptDirectMessage(userId, peerPublicKey, encrypted);
|
|
if (decrypted.startsWith('🔒')) return null;
|
|
try {
|
|
return JSON.parse(decrypted) as E2EMessagePayload;
|
|
} catch {
|
|
return { kind: 'text', text: decrypted };
|
|
}
|
|
}
|
|
|
|
export async function encryptE2EBlob(userId: string, peerPublicKey: string, data: ArrayBuffer) {
|
|
return encryptBinary(userId, peerPublicKey, data);
|
|
}
|
|
|
|
export async function decryptE2EBlob(userId: string, peerPublicKey: string, encryptedBytes: ArrayBuffer) {
|
|
return decryptBinary(userId, peerPublicKey, encryptedBytes);
|
|
}
|
|
|
|
export function e2eKindFromMessageType(type: string): E2EMessageKind {
|
|
switch (type) {
|
|
case 'EMOJI':
|
|
return 'emoji';
|
|
case 'IMAGE':
|
|
return 'image';
|
|
case 'VOICE':
|
|
return 'voice';
|
|
case 'AUDIO':
|
|
return 'audio';
|
|
case 'VIDEO':
|
|
return 'video';
|
|
case 'VIDEO_NOTE':
|
|
return 'video_note';
|
|
case 'FILE':
|
|
return 'file';
|
|
default:
|
|
return 'text';
|
|
}
|
|
}
|
|
|
|
export function readableE2EPayload(payload: E2EMessagePayload | null) {
|
|
if (!payload) return '🔒 Зашифрованное сообщение';
|
|
switch (payload.kind) {
|
|
case 'emoji':
|
|
return payload.emojiId ?? '';
|
|
case 'text':
|
|
return payload.text ?? '';
|
|
case 'voice':
|
|
return 'Голосовое сообщение';
|
|
case 'audio':
|
|
return 'Аудио';
|
|
case 'image':
|
|
return 'Фото';
|
|
case 'video':
|
|
return 'Видео';
|
|
case 'video_note':
|
|
return 'Кружок';
|
|
case 'file':
|
|
return payload.fileName ?? 'Файл';
|
|
default:
|
|
return '🔒 Зашифрованное сообщение';
|
|
}
|
|
}
|