Ondes.Chat
Le module Ondes.Chat permet de créer des applications de messagerie avec chiffrement de bout en bout (E2EE) automatique. Tous les messages sont chiffrés localement avant d'être envoyés et déchiffrés à la réception, sans que les développeurs n'aient besoin de gérer la cryptographie.
Chiffrement 100% Automatique
Aucune configuration requise! Les clés E2EE sont générées automatiquement dès que l'utilisateur se connecte à Ondes. Vous envoyez du texte clair, il est chiffré. Vous recevez des messages déjà déchiffrés.
Sécurité
| Composant | Algorithme |
|---|---|
| Échange de clés | X25519 (Curve25519) |
| Chiffrement | AES-256-GCM |
| Authentification | HMAC intégré (GCM) |
Les clés privées ne quittent jamais l'appareil de l'utilisateur. Le serveur ne voit que les messages chiffrés.
Clés générées au login
Chaque utilisateur Ondes possède automatiquement une paire de clés E2EE créée lors de sa première connexion. Cela garantit que le chiffrement X25519 fonctionne toujours entre deux utilisateurs.
Initialisation
Ondes.Chat.init()
Connecte au service de chat temps réel (WebSocket).
Retour: Promise<{success: boolean, userId: number}>
E2EE automatique
Les clés de chiffrement sont déjà configurées au login. Cette méthode établit simplement la connexion WebSocket pour les messages en temps réel.
Ondes.Chat.disconnect()
Déconnecte du service de chat.
Ondes.Chat.isReady()
Vérifie si le chat est initialisé et connecté.
Retour: boolean
Conversations
Ondes.Chat.getConversations()
Récupère toutes les conversations de l'utilisateur.
Retour: Promise<Array<Conversation>>
const conversations = await Ondes.Chat.getConversations();
for (const conv of conversations) {
console.log(conv.name);
console.log(conv.lastMessage?.content); // Déjà déchiffré!
}
Structure Conversation:
interface Conversation {
id: string; // UUID unique
name: string; // Nom de la conversation
type: 'private' | 'group';
avatar?: string;
members: Array<{
id: number;
username: string;
avatar?: string;
}>;
lastMessage?: {
content: string; // Contenu déchiffré
sender: string;
createdAt: string;
};
unreadCount: number;
updatedAt: string;
}
Ondes.Chat.getConversation(conversationId)
Récupère une conversation spécifique.
| Paramètre | Type | Description |
|---|---|---|
conversationId |
string |
UUID de la conversation |
Retour: Promise<Conversation>
Ondes.Chat.startChat(user)
Démarre une conversation privée avec un utilisateur.
| Paramètre | Type | Description |
|---|---|---|
user |
string ou number |
Nom d'utilisateur ou ID |
Retour: Promise<Conversation>
// Par nom d'utilisateur
const conv = await Ondes.Chat.startChat('alice');
// Par ID
const conv = await Ondes.Chat.startChat(42);
Ondes.Chat.createGroup(name, members)
Crée un groupe de discussion.
| Paramètre | Type | Description |
|---|---|---|
name |
string |
Nom du groupe |
members |
Array<string\|number> |
Membres (usernames ou IDs) |
Retour: Promise<Conversation>
const group = await Ondes.Chat.createGroup('Projet Alpha', [
'alice',
'bob',
42 // ID utilisateur
]);
Messages
Ondes.Chat.send(conversationId, message, options?)
Envoie un message dans une conversation.
| Paramètre | Type | Description |
|---|---|---|
conversationId |
string |
UUID de la conversation |
message |
string |
Contenu du message (texte clair) |
options |
object |
Options (optionnel) |
Options:
- replyTo: UUID du message auquel répondre
- type: Type de message ('text', 'image', 'file')
Retour: Promise<{success: boolean}>
// Message simple
await Ondes.Chat.send(conv.id, 'Salut!');
// Réponse à un message
await Ondes.Chat.send(conv.id, 'D\'accord!', {
replyTo: 'message-uuid-123'
});
Ondes.Chat.getMessages(conversationId, options?)
Récupère les messages d'une conversation.
| Paramètre | Type | Description |
|---|---|---|
conversationId |
string |
UUID de la conversation |
options.limit |
number |
Nombre max (défaut: 50) |
options.before |
string |
UUID pour pagination |
Retour: Promise<Array<Message>>
// 50 derniers messages
const messages = await Ondes.Chat.getMessages(conv.id);
// Pagination
const olderMessages = await Ondes.Chat.getMessages(conv.id, {
limit: 20,
before: messages[0].id
});
Structure Message:
interface Message {
id: string; // UUID unique
conversationId: string;
senderId: number;
sender: string; // Username
content: string; // Contenu DÉCHIFFRÉ
type: string; // 'text', 'image', etc.
createdAt: string;
editedAt?: string;
isDeleted: boolean;
replyTo?: string;
}
Ondes.Chat.editMessage(messageId, newContent, conversationId?)
Modifie un message existant.
| Paramètre | Type | Description |
|---|---|---|
messageId |
string |
UUID du message à modifier |
newContent |
string |
Nouveau contenu (texte clair) |
conversationId |
string |
UUID de la conversation (optionnel, pour le chiffrement) |
Chiffrement
Si conversationId est fourni, le nouveau contenu sera automatiquement chiffré.
Ondes.Chat.deleteMessage(messageId)
Supprime un message.
Ondes.Chat.markAsRead(messageIds)
Marque des messages comme lus.
// Un message
await Ondes.Chat.markAsRead('msg-uuid');
// Plusieurs messages
await Ondes.Chat.markAsRead(['msg-1', 'msg-2', 'msg-3']);
Indicateurs
Ondes.Chat.setTyping(conversationId, isTyping)
Envoie un indicateur de frappe.
| Paramètre | Type | Description |
|---|---|---|
conversationId |
string |
UUID de la conversation |
isTyping |
boolean |
true si en train d'écrire |
// L'utilisateur commence à taper
Ondes.Chat.setTyping(conv.id, true);
// L'utilisateur a fini
Ondes.Chat.setTyping(conv.id, false);
Événements
Ondes.Chat.onMessage(callback)
Écoute les nouveaux messages.
Callback: (message: Message) => void
Retour: Fonction pour se désabonner
const unsubscribe = Ondes.Chat.onMessage((msg) => {
console.log(`${msg.sender}: ${msg.content}`);
// Le message est déjà déchiffré!
});
// Plus tard, pour arrêter d'écouter:
unsubscribe();
Ondes.Chat.onTyping(callback)
Écoute les indicateurs de frappe.
Callback: ({conversationId, userId, username, isTyping}) => void
Ondes.Chat.onTyping((data) => {
if (data.isTyping) {
showTypingIndicator(data.username);
} else {
hideTypingIndicator();
}
});
Ondes.Chat.onReceipt(callback)
Écoute les accusés de lecture.
Callback: ({messageId, userId, readAt}) => void
Ondes.Chat.onConnectionChange(callback)
Écoute les changements de connexion.
Callback: (status: 'connected'|'disconnected'|'error') => void
Ondes.Chat.onConnectionChange((status) => {
if (status === 'disconnected') {
showReconnecting();
}
});
Exemple Complet
// Initialisation
document.addEventListener('OndesReady', async () => {
// 1. Initialiser le chat (E2EE automatique)
await Ondes.Chat.init();
// 2. Charger les conversations
const conversations = await Ondes.Chat.getConversations();
displayConversations(conversations);
// 3. Écouter les nouveaux messages
Ondes.Chat.onMessage((msg) => {
// msg.content est déjà déchiffré!
appendMessage(msg);
});
// 4. Écouter les indicateurs de frappe
Ondes.Chat.onTyping((data) => {
if (data.isTyping) {
showTyping(data.username);
}
});
});
// Démarrer une nouvelle conversation
async function startNewChat(username) {
const conv = await Ondes.Chat.startChat(username);
selectConversation(conv);
}
// Envoyer un message
async function sendMessage(text) {
await Ondes.Chat.send(currentConv.id, text);
// C'est tout! Le chiffrement est automatique
}
// Charger l'historique
async function loadHistory(convId) {
const messages = await Ondes.Chat.getMessages(convId);
// Tous les messages sont déjà déchiffrés
messages.forEach(displayMessage);
}
Notes Techniques
Stockage des Clés
Les clés sont stockées de manière persistante via SharedPreferences:
- Clé privée X25519: Générée automatiquement au premier login, réutilisée ensuite
- Clés de conversation: Dérivées via X25519 à partir des clés publiques des membres
Échange de Clés X25519
Le système utilise exclusivement X25519 pour l'échange de clés:
- Au login: Une paire de clés X25519 est générée et la clé publique est enregistrée sur le serveur
- À la création d'une conversation: Le secret partagé est calculé avec la clé publique de l'autre membre
- Résultat identique: Les deux membres dérivent exactement la même clé symétrique (propriété de X25519)
E2EE Garanti
Comme tous les utilisateurs Ondes ont une clé publique dès leur premier login, le chiffrement X25519 fonctionne toujours. Aucun fallback nécessaire!
Performance
- Les clés de conversation sont mises en cache en mémoire
- Le déchiffrement est fait de manière asynchrone
- Les messages sont déchiffrés en batch lors du chargement
Limitations
- Taille max message: 64 KB (avant chiffrement)
- Maximum 256 membres par groupe
- Historique: 10 000 messages par conversation