ihm_client/docs/INTEGRATION_IFRAME.md
Your Name 2567e2f0da
Some checks failed
CI/CD Pipeline / test (push) Failing after 20s
CI/CD Pipeline / security (push) Has been skipped
CI/CD Pipeline / integration-test (push) Has been skipped
docs: MAJ USAGE/INDEX/INTEGRATION_IFRAME; ROADMAP handshake iframe; template feature_request enrichi; CHANGELOG mis à jour
2025-08-26 12:42:05 +02:00

157 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 nest inclus.
## Principes
- Canal: postMessage entre la page parente et liframe `ihm_client`.
- Découverte: `ihm_client` émet `LISTENING` pour signaler la disponibilité des listeners (côté iframe). En mode E2E (`?e2e=1`) et seulement lorsque lapp tourne en iframe, `LISTENING` est émis périodiquement (jusquà 100 fois) pour éviter les courses de tests. Hors E2E, pas démission périodique.
- 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, lappareil 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 dun consentement utilisateur pour lier lhôte à lappareil.
- 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 lappairage de lappareil.
- 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 lidentifiant dappairage 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 lutilisateur 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<string, Process>, `messageId`
---
### RETRIEVE_DATA (Requête)
- Objet: déchiffrer et retourner les attributs autorisés dun é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<string, any>, `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<string, any> (données brutes à répartir en public/privé)
- `privateFields`: string[] (liste des nouveaux champs à forcer en privé)
- `roles`: Record<string, RoleDefinition>
- `accessToken`, `messageId`
- Réponse succès: `type`: `PROCESS_CREATED`, `processCreated`: { `processId`: string, `process`: Process, `processData`: Record<string, any> }, `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<string, any>, `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 dun 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 dun 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 dun 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 dinté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 dun processus.
- Valider les formats (ids hex 32 bytes, structures de rôles) avant envoi.