feat(chat): Implement end-to-end encrypted swarm messaging system

- Add Swarm Chat documentation with architecture, API endpoints, and security considerations
- Create database schema for chat conversations, messages, and typing indicators
- Implement chat API endpoints for sending, receiving, and managing messages
- Add client-side encryption utilities using RSA-OAEP with SHA-256
- Create chat page UI for viewing conversations and messages
- Add chat type definitions for TypeScript support
- Update database schema with new chat tables and relationships
- Update sidebar navigation to include chat link
- Enable true end-to-end encrypted messaging across swarm nodes without ActivityPub limitations
This commit is contained in:
Christomatt
2026-01-26 20:00:17 +01:00
parent c5a5985aa6
commit 6b8eeb6814
13 changed files with 5957 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
/**
* Swarm Chat Cryptography
*
* End-to-end encryption for chat messages using public key cryptography.
*/
import crypto from 'crypto';
/**
* Encrypt a message using the recipient's public key
*/
export function encryptMessage(message: string, recipientPublicKey: string): string {
try {
// Use RSA-OAEP for encryption
const encrypted = crypto.publicEncrypt(
{
key: recipientPublicKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256',
},
Buffer.from(message, 'utf8')
);
return encrypted.toString('base64');
} catch (error) {
console.error('Failed to encrypt message:', error);
throw new Error('Encryption failed');
}
}
/**
* Decrypt a message using the recipient's private key
*/
export function decryptMessage(encryptedMessage: string, privateKey: string): string {
try {
const decrypted = crypto.privateDecrypt(
{
key: privateKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256',
},
Buffer.from(encryptedMessage, 'base64')
);
return decrypted.toString('utf8');
} catch (error) {
console.error('Failed to decrypt message:', error);
throw new Error('Decryption failed');
}
}
/**
* Sign a message payload for authenticity verification
*/
export function signPayload(payload: string, privateKey: string): string {
try {
const sign = crypto.createSign('SHA256');
sign.update(payload);
sign.end();
const signature = sign.sign(privateKey, 'base64');
return signature;
} catch (error) {
console.error('Failed to sign payload:', error);
throw new Error('Signing failed');
}
}
/**
* Verify a signed payload
*/
export function verifySignature(payload: string, signature: string, publicKey: string): boolean {
try {
const verify = crypto.createVerify('SHA256');
verify.update(payload);
verify.end();
return verify.verify(publicKey, signature, 'base64');
} catch (error) {
console.error('Failed to verify signature:', error);
return false;
}
}
+66
View File
@@ -0,0 +1,66 @@
/**
* Swarm Chat Types
*
* Type definitions for the swarm chat system.
*/
export interface SwarmChatMessage {
id: string;
conversationId: string;
senderHandle: string;
senderDisplayName?: string;
senderAvatarUrl?: string;
senderNodeDomain?: string;
encryptedContent: string;
deliveredAt?: string;
readAt?: string;
createdAt: string;
}
export interface SwarmChatConversation {
id: string;
type: 'direct' | 'group';
participant1Id: string;
participant2Handle: string;
lastMessageAt?: string;
lastMessagePreview?: string;
unreadCount?: number;
createdAt: string;
updatedAt: string;
}
/**
* Payload for sending a chat message to a remote node
*/
export interface SwarmChatMessagePayload {
messageId: string;
senderHandle: string;
senderDisplayName?: string;
senderAvatarUrl?: string;
senderNodeDomain: string;
recipientHandle: string;
encryptedContent: string;
timestamp: string;
signature?: string;
}
/**
* Payload for typing indicator
*/
export interface SwarmChatTypingPayload {
senderHandle: string;
senderNodeDomain: string;
recipientHandle: string;
isTyping: boolean;
timestamp: string;
}
/**
* Payload for read receipt
*/
export interface SwarmChatReadReceiptPayload {
messageId: string;
readerHandle: string;
readerNodeDomain: string;
timestamp: string;
}