diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ae20cf..2d9ff61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ et ce projet adhère au [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Tests unitaires pour `sp-address.utils` et `html.utils` - Documentation: `docs/API.md`, `docs/TESTING.md`, `docs/CONFIGURATION.md` - Documentation fonctionnelle: `docs/FONCTIONNEL.md` et index mis à jour +- Spécification d’intégration iframe: `docs/INTEGRATION_IFRAME.md` et index mis à jour - Tests pour `TokenService` et fallback d’environnement pour tests ### Fixed diff --git a/docs/INDEX.md b/docs/INDEX.md index 60ec0ee..74e82ad 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -150,6 +150,8 @@ Guide pour les migrations et mises à jour. ## 🌐 Guides d'Intégration ### 🔗 [Intégration 4NK_node](INTEGRATION_4NK_NODE.md) +### 🧩 [Intégration iframe](INTEGRATION_IFRAME.md) +Spécification de messagerie postMessage (requêtes/réponses, erreurs, prérequis). Guide d'intégration avec l'infrastructure 4NK_node. - **Configuration Docker** - **Variables d'environnement** diff --git a/docs/INTEGRATION_IFRAME.md b/docs/INTEGRATION_IFRAME.md new file mode 100644 index 0000000..9e2d665 --- /dev/null +++ b/docs/INTEGRATION_IFRAME.md @@ -0,0 +1,156 @@ +# Intégration iframe – Spécification de messagerie + +Ce document définit les échanges entre un site hôte et `ihm_client` intégré en iframe, via `window.postMessage`. Aucun exemple de code exécutable n’est inclus. + +## Principes + +- Canal: postMessage entre la page parente et l’iframe `ihm_client`. +- Découverte: `ihm_client` émet `LISTENING` à l’initialisation (côté iframe). +- Sécurité: + - Utiliser la cible `event.origin` pour les réponses. + - De nombreuses opérations exigent un `accessToken` valide (lié à `origin`). + - `messageId` recommandé pour corréler requêtes/réponses. +- Pré-requis: pour la plupart des actions de processus, l’appareil doit être appairé. + +## Types de message + +Référence: `src/models/process.model.ts` (enum `MessageType`). + +### LISTENING +- Émis par `ihm_client` au parent pour signaler la disponibilité des listeners. +- Réception côté parent (aucune requête attendue). Pas de payload spécifique. + +--- + +### REQUEST_LINK (Requête) +- Objet: ouverture d’un consentement utilisateur pour lier l’hôte à l’appareil. +- Requête (parent → iframe): + - `type`: `REQUEST_LINK` + - `messageId`: string (optionnel mais recommandé) +- Réponses (iframe → parent): + - Succès: `type`: `LINK_ACCEPTED`, `accessToken`: string, `refreshToken`: string, `messageId` + - Erreur: `type`: `ERROR`, `error`: string, `messageId` + +### VALIDATE_TOKEN (Requête) +- Objet: vérifier la validité du couple `{accessToken, refreshToken}`. +- Requête: `type`, `accessToken`, `refreshToken`, `messageId` +- Réponse: `type`: `VALIDATE_TOKEN`, `isValid`: boolean, `accessToken`, `refreshToken`, `messageId` + +### RENEW_TOKEN (Requête) +- Objet: obtenir un nouveau `accessToken` depuis un `refreshToken`. +- Requête: `type`, `refreshToken`, `messageId` +- Réponses: + - Succès: `type`: `RENEW_TOKEN`, `accessToken`, `refreshToken`, `messageId` + - Erreur: `ERROR` + +--- + +### CREATE_PAIRING (Requête) +- Objet: initier l’appairage de l’appareil. +- Pré-requis: `accessToken` valide; appareil non appairé. +- Requête: `type`, `accessToken`, `messageId` +- Réponses: + - Succès: `type`: `PAIRING_CREATED`, `pairingId`: string, `messageId` + - Erreur: `ERROR` + +### GET_PAIRING_ID (Requête) +- Objet: récupérer l’identifiant d’appairage utilisateur. +- Pré-requis: appairé + `accessToken` valide. +- Requête: `type`, `accessToken`, `messageId` +- Réponse: `type`: `GET_PAIRING_ID`, `userPairingId`: string, `messageId` + +--- + +### GET_MY_PROCESSES (Requête) +- Objet: lister les processus auxquels l’utilisateur participe. +- Pré-requis: appairé + `accessToken` valide. +- Requête: `type`, `accessToken`, `messageId` +- Réponse: `type`: `GET_MY_PROCESSES`, `myProcesses`: string[] | null, `messageId` + +### GET_PROCESSES (Requête) +- Objet: récupérer tous les processus connus localement. +- Pré-requis: appairé + `accessToken` valide. +- Requête: `type`, `accessToken`, `messageId` +- Réponse: `type`: `PROCESSES_RETRIEVED`, `processes`: Record, `messageId` + +--- + +### RETRIEVE_DATA (Requête) +- Objet: déchiffrer et retourner les attributs autorisés d’un état de processus. +- Pré-requis: appairé + `accessToken` valide. +- Requête: `type`, `processId`: string, `stateId`: string (32 bytes hex), `accessToken`, `messageId` +- Réponse: `type`: `DATA_RETRIEVED`, `data`: Record, `messageId` + +### DECODE_PUBLIC_DATA (Requête) +- Objet: décoder des données publiques encodées. +- Pré-requis: appairé + `accessToken` valide. +- Requête: `type`, `accessToken`, `encodedData`: number[], `messageId` +- Réponse: `type`: `PUBLIC_DATA_DECODED`, `decodedData`: any, `messageId` + +--- + +### CREATE_PROCESS (Requête) +- Objet: créer un nouveau processus. +- Pré-requis: appairé + `accessToken` valide. +- Requête: + - `type` + - `processData`: Record (données brutes à répartir en public/privé) + - `privateFields`: string[] (liste des nouveaux champs à forcer en privé) + - `roles`: Record + - `accessToken`, `messageId` +- Réponse succès: `type`: `PROCESS_CREATED`, `processCreated`: { `processId`: string, `process`: Process, `processData`: Record }, `messageId` +- Réponse erreur: `ERROR` + +### UPDATE_PROCESS (Requête) +- Objet: créer un nouvel état avec des mises à jour (champs publics/privés déterminés automatiquement, `privateFields` pour les nouveaux champs privés). +- Pré-requis: appairé + `accessToken` valide + processus existant avec état committé. +- Requête: `type`, `processId`, `newData`: Record, `privateFields`: string[], `roles` (ou null pour conserver), `accessToken`, `messageId` +- Réponse: `type`: `PROCESS_UPDATED`, `updatedProcess`: Process, `messageId` + +--- + +### NOTIFY_UPDATE (Requête) +- Objet: demander l’émission d’un PRD Update pour un état précis. +- Pré-requis: appairé + `accessToken` valide. +- Requête: `type`, `processId`, `stateId` (32 bytes hex), `accessToken`, `messageId` +- Réponse: `type`: `UPDATE_NOTIFIED`, `messageId` + +### VALIDATE_STATE (Requête) +- Objet: valider un état (selon règles/permissions WASM). +- Pré-requis: appairé + `accessToken` valide. +- Requête: `type`, `processId`, `stateId` (32 bytes hex), `accessToken`, `messageId` +- Réponse: `type`: `STATE_VALIDATED`, `validatedProcess`: Process, `messageId` + +--- + +### HASH_VALUE (Requête) +- Objet: obtenir le hash d’un blob (document) pour un engagement donné. +- Requête: `type`, `accessToken`, `commitedIn`: string, `label`: string, `fileBlob`: { type: string; data: Uint8Array }, `messageId` +- Réponse: `type`: `VALUE_HASHED`, `hash`: string, `messageId` + +### GET_MERKLE_PROOF (Requête) +- Objet: récupérer la preuve Merkle d’un attribut dans un état. +- Requête: `type`, `accessToken`, `processState`: ProcessState, `attributeName`: string, `messageId` +- Réponse: `type`: `MERKLE_PROOF_RETRIEVED`, `proof`: MerkleProofResult, `messageId` + +### VALIDATE_MERKLE_PROOF (Requête) +- Objet: valider une preuve Merkle pour un document donné. +- Requête: `type`, `accessToken`, `merkleProof`: string (JSON sérialisé), `documentHash`: string, `messageId` +- Réponse: `type`: `MERKLE_PROOF_VALIDATED`, `isValid`: boolean, `messageId` + +--- + +## Erreurs communes (`ERROR`) +- Conditions typiques: + - `Device not paired` (opération nécessitant appairage) + - `Invalid or expired session token` + - `Failed to ...` (création/lecture/validation) + - `Invalid state id` / `Process not found` +- Payload générique: `{ type: 'ERROR', error: string, messageId?: string }` + +## Bonnes pratiques d’intégration +- Toujours préciser et propager `messageId` pour tracer les échanges. +- Conserver `origin` côté parent et utiliser la même valeur dans les requêtes suivantes. +- Renouveler régulièrement le `accessToken` via `RENEW_TOKEN`. +- Séparer données publiques/privées dès la création d’un processus. +- Valider les formats (ids hex 32 bytes, structures de rôles) avant envoi.