refactor(iframe-controller): standardize import statements, enhance logging, and improve error handling in IframeController service
This commit is contained in:
parent
8a87fe38c5
commit
96ee5b03e6
@ -1,9 +1,9 @@
|
|||||||
import { MessageType } from '../types/index';
|
import { MessageType } from "../types/index";
|
||||||
import Services from './service';
|
import Services from "./service";
|
||||||
import TokenService from './token.service';
|
import TokenService from "./token.service";
|
||||||
import { cleanSubscriptions } from '../utils/subscription.utils';
|
import { cleanSubscriptions } from "../utils/subscription.utils";
|
||||||
import { splitPrivateData, isValid32ByteHex } from '../utils/service.utils';
|
import { splitPrivateData, isValid32ByteHex } from "../utils/service.utils";
|
||||||
import { MerkleProofResult } from '../../pkg/sdk_client';
|
import { MerkleProofResult } from "../../pkg/sdk_client";
|
||||||
|
|
||||||
export class IframeController {
|
export class IframeController {
|
||||||
private static isInitialized = false; // <--- VERROU
|
private static isInitialized = false; // <--- VERROU
|
||||||
@ -13,39 +13,57 @@ export class IframeController {
|
|||||||
|
|
||||||
// On ne lance l'écoute que si on est dans une iframe
|
// On ne lance l'écoute que si on est dans une iframe
|
||||||
if (window.self !== window.top) {
|
if (window.self !== window.top) {
|
||||||
console.log('[IframeController] 📡 Mode Iframe détecté. Démarrage des listeners API...');
|
console.log(
|
||||||
|
"[IframeController] 📡 Mode Iframe détecté. Démarrage des listeners API..."
|
||||||
|
);
|
||||||
await IframeController.registerAllListeners();
|
await IframeController.registerAllListeners();
|
||||||
} else {
|
} else {
|
||||||
console.log("[IframeController] ℹ️ Mode Standalone (pas d'iframe). Listeners API inactifs.");
|
console.log(
|
||||||
|
"[IframeController] ℹ️ Mode Standalone (pas d'iframe). Listeners API inactifs."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async registerAllListeners() {
|
private static async registerAllListeners() {
|
||||||
console.log('[Router:API] 🎧 Enregistrement des gestionnaires de messages (postMessage)...');
|
console.log(
|
||||||
|
"[Router:API] 🎧 Enregistrement des gestionnaires de messages (postMessage)..."
|
||||||
|
);
|
||||||
const services = await Services.getInstance();
|
const services = await Services.getInstance();
|
||||||
const tokenService = await TokenService.getInstance();
|
const tokenService = await TokenService.getInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fonction centralisée pour envoyer des réponses d'erreur à la fenêtre parente (l'application A).
|
* Fonction centralisée pour envoyer des réponses d'erreur à la fenêtre parente (l'application A).
|
||||||
*/
|
*/
|
||||||
const errorResponse = (errorMsg: string, origin: string, messageId?: string) => {
|
const errorResponse = (
|
||||||
console.error(`[Router:API] 📤 Envoi Erreur: ${errorMsg} (Origine: ${origin}, MsgID: ${messageId})`);
|
errorMsg: string,
|
||||||
|
origin: string,
|
||||||
|
messageId?: string
|
||||||
|
) => {
|
||||||
|
console.error(
|
||||||
|
`[Router:API] 📤 Envoi Erreur: ${errorMsg} (Origine: ${origin}, MsgID: ${messageId})`
|
||||||
|
);
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
type: MessageType.ERROR,
|
type: MessageType.ERROR,
|
||||||
error: errorMsg,
|
error: errorMsg,
|
||||||
messageId,
|
messageId,
|
||||||
},
|
},
|
||||||
origin,
|
origin
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper pour vérifier le token avant chaque action sensible
|
// Helper pour vérifier le token avant chaque action sensible
|
||||||
const withToken = async (event: MessageEvent, action: () => Promise<void>) => {
|
const withToken = async (
|
||||||
|
event: MessageEvent,
|
||||||
|
action: () => Promise<void>
|
||||||
|
) => {
|
||||||
const { accessToken } = event.data;
|
const { accessToken } = event.data;
|
||||||
// On vérifie si le token est présent ET valide pour l'origine de l'iframe
|
// On vérifie si le token est présent ET valide pour l'origine de l'iframe
|
||||||
if (!accessToken || !(await tokenService.validateToken(accessToken, event.origin))) {
|
if (
|
||||||
throw new Error('Invalid or expired session token');
|
!accessToken ||
|
||||||
|
!(await tokenService.validateToken(accessToken, event.origin))
|
||||||
|
) {
|
||||||
|
throw new Error("Invalid or expired session token");
|
||||||
}
|
}
|
||||||
// Si tout est bon, on exécute l'action
|
// Si tout est bon, on exécute l'action
|
||||||
await action();
|
await action();
|
||||||
@ -54,35 +72,53 @@ export class IframeController {
|
|||||||
// --- Définitions des gestionnaires (Handlers) ---
|
// --- Définitions des gestionnaires (Handlers) ---
|
||||||
|
|
||||||
const handleRequestLink = async (event: MessageEvent) => {
|
const handleRequestLink = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.REQUEST_LINK} reçu de ${event.origin}`);
|
console.log(
|
||||||
|
`[Router:API] 📨 Message ${MessageType.REQUEST_LINK} reçu de ${event.origin}`
|
||||||
|
);
|
||||||
|
|
||||||
// 1. Vérifier si l'appareil est DÉJÀ appairé (cas de la 2ème connexion)
|
// 1. Vérifier si l'appareil est DÉJÀ appairé (cas de la 2ème connexion)
|
||||||
const device = await services.getDeviceFromDatabase();
|
const device = await services.getDeviceFromDatabase();
|
||||||
|
|
||||||
if (device && device.pairing_process_commitment) {
|
if (device && device.pairing_process_commitment) {
|
||||||
console.log("[Router:API] Appareil déjà appairé. Pas besoin d'attendre home.ts.");
|
console.log(
|
||||||
|
"[Router:API] Appareil déjà appairé. Pas besoin d'attendre home.ts."
|
||||||
|
);
|
||||||
// On saute l'attente et on passe directement à la suite.
|
// On saute l'attente et on passe directement à la suite.
|
||||||
} else {
|
} else {
|
||||||
// 2. Cas de la 1ère connexion (appareil non appairé)
|
// 2. Cas de la 1ère connexion (appareil non appairé)
|
||||||
// On doit attendre que home.ts (auto-pairing) ait fini son travail.
|
// On doit attendre que home.ts (auto-pairing) ait fini son travail.
|
||||||
console.log('[Router:API] Appareil non appairé. En attente du feu vert de home.ts...');
|
await new Promise<void>((resolve, reject) => {
|
||||||
const maxWait = 5000; // 5 sec
|
// Fonction de nettoyage pour éviter les fuites de mémoire
|
||||||
let waited = 0;
|
const cleanup = () => {
|
||||||
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
document.removeEventListener(
|
||||||
|
"app:pairing-ready",
|
||||||
|
handler as EventListener
|
||||||
|
);
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
};
|
||||||
|
|
||||||
// On attend le drapeau global
|
// Le gestionnaire de l'événement
|
||||||
while (!(window as any).__PAIRING_READY && waited < maxWait) {
|
const handler = (e: CustomEvent) => {
|
||||||
await delay(100);
|
cleanup();
|
||||||
waited += 100;
|
if (e.detail && e.detail.success) {
|
||||||
}
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(new Error(e.detail?.error || "Auto-pairing failed"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 3. Vérifier le résultat de l'attente
|
// Timeout de sécurité (5 secondes)
|
||||||
if ((window as any).__PAIRING_READY === 'error') {
|
const timeoutId = setTimeout(() => {
|
||||||
throw new Error('Auto-pairing failed');
|
cleanup();
|
||||||
}
|
reject(new Error("Auto-pairing timed out (Event not received)"));
|
||||||
if (!(window as any).__PAIRING_READY) {
|
}, 5000);
|
||||||
throw new Error('Auto-pairing timed out');
|
|
||||||
}
|
// On écoute l'événement qu'on a créé dans Home.ts
|
||||||
|
document.addEventListener(
|
||||||
|
"app:pairing-ready",
|
||||||
|
handler as EventListener
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
console.log(`[Router:API] Feu vert de home.ts reçu !`);
|
console.log(`[Router:API] Feu vert de home.ts reçu !`);
|
||||||
}
|
}
|
||||||
@ -98,50 +134,69 @@ export class IframeController {
|
|||||||
refreshToken: tokens.refreshToken,
|
refreshToken: tokens.refreshToken,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
`[Router:API] ✅ ${MessageType.REQUEST_LINK} accepté et jetons envoyés.`
|
||||||
);
|
);
|
||||||
console.log(`[Router:API] ✅ ${MessageType.REQUEST_LINK} accepté et jetons envoyés.`);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCreatePairing = async (event: MessageEvent) => {
|
const handleCreatePairing = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.CREATE_PAIRING} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.CREATE_PAIRING} reçu`);
|
||||||
|
|
||||||
if (services.isPaired()) {
|
if (services.isPaired()) {
|
||||||
throw new Error('Device already paired — ignoring CREATE_PAIRING request');
|
throw new Error(
|
||||||
|
"Device already paired — ignoring CREATE_PAIRING request"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
console.log("[Router:API] 🚀 Démarrage du processus d'appairage...");
|
console.log("[Router:API] 🚀 Démarrage du processus d'appairage...");
|
||||||
|
|
||||||
const myAddress = services.getDeviceAddress();
|
const myAddress = services.getDeviceAddress();
|
||||||
console.log('[Router:API] 1/7: Création du processus de pairing...');
|
console.log("[Router:API] 1/7: Création du processus de pairing...");
|
||||||
const createPairingProcessReturn = await services.createPairingProcess('', [myAddress]);
|
const createPairingProcessReturn = await services.createPairingProcess(
|
||||||
|
"",
|
||||||
|
[myAddress]
|
||||||
|
);
|
||||||
|
|
||||||
const pairingId = createPairingProcessReturn.updated_process?.process_id;
|
const pairingId =
|
||||||
const stateId = createPairingProcessReturn.updated_process?.current_process?.states[0]?.state_id as string;
|
createPairingProcessReturn.updated_process?.process_id;
|
||||||
|
const stateId = createPairingProcessReturn.updated_process
|
||||||
|
?.current_process?.states[0]?.state_id as string;
|
||||||
if (!pairingId || !stateId) {
|
if (!pairingId || !stateId) {
|
||||||
throw new Error('Pairing process creation failed to return valid IDs');
|
throw new Error(
|
||||||
|
"Pairing process creation failed to return valid IDs"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
console.log(`[Router:API] 2/7: Processus ${pairingId} créé.`);
|
console.log(`[Router:API] 2/7: Processus ${pairingId} créé.`);
|
||||||
|
|
||||||
console.log("[Router:API] 3/7: Enregistrement local de l'appareil...");
|
console.log("[Router:API] 3/7: Enregistrement local de l'appareil...");
|
||||||
services.pairDevice(pairingId, [myAddress]);
|
services.pairDevice(pairingId, [myAddress]);
|
||||||
|
|
||||||
console.log('[Router:API] 4/7: Traitement du retour (handleApiReturn)...');
|
console.log(
|
||||||
|
"[Router:API] 4/7: Traitement du retour (handleApiReturn)..."
|
||||||
|
);
|
||||||
await services.handleApiReturn(createPairingProcessReturn);
|
await services.handleApiReturn(createPairingProcessReturn);
|
||||||
|
|
||||||
console.log('[Router:API] 5/7: Création de la mise à jour PRD...');
|
console.log("[Router:API] 5/7: Création de la mise à jour PRD...");
|
||||||
const createPrdUpdateReturn = await services.createPrdUpdate(pairingId, stateId);
|
const createPrdUpdateReturn = await services.createPrdUpdate(
|
||||||
|
pairingId,
|
||||||
|
stateId
|
||||||
|
);
|
||||||
await services.handleApiReturn(createPrdUpdateReturn);
|
await services.handleApiReturn(createPrdUpdateReturn);
|
||||||
|
|
||||||
console.log('[Router:API] 6/7: Approbation du changement...');
|
console.log("[Router:API] 6/7: Approbation du changement...");
|
||||||
const approveChangeReturn = await services.approveChange(pairingId, stateId);
|
const approveChangeReturn = await services.approveChange(
|
||||||
|
pairingId,
|
||||||
|
stateId
|
||||||
|
);
|
||||||
await services.handleApiReturn(approveChangeReturn);
|
await services.handleApiReturn(approveChangeReturn);
|
||||||
|
|
||||||
console.log('[Router:API] 7/7: Confirmation finale du pairing...');
|
console.log("[Router:API] 7/7: Confirmation finale du pairing...");
|
||||||
// await services.confirmPairing();
|
// await services.confirmPairing();
|
||||||
|
|
||||||
console.log('[Router:API] 🎉 Appairage terminé avec succès !');
|
console.log("[Router:API] 🎉 Appairage terminé avec succès !");
|
||||||
|
|
||||||
const successMsg = {
|
const successMsg = {
|
||||||
type: MessageType.PAIRING_CREATED,
|
type: MessageType.PAIRING_CREATED,
|
||||||
@ -153,8 +208,10 @@ export class IframeController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleGetMyProcesses = async (event: MessageEvent) => {
|
const handleGetMyProcesses = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.GET_MY_PROCESSES} reçu`);
|
console.log(
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
`[Router:API] 📨 Message ${MessageType.GET_MY_PROCESSES} reçu`
|
||||||
|
);
|
||||||
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
const myProcesses = await services.getMyProcesses();
|
const myProcesses = await services.getMyProcesses();
|
||||||
@ -165,14 +222,14 @@ export class IframeController {
|
|||||||
myProcesses,
|
myProcesses,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGetProcesses = async (event: MessageEvent) => {
|
const handleGetProcesses = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.GET_PROCESSES} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.GET_PROCESSES} reçu`);
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
const processes = await services.getProcesses();
|
const processes = await services.getProcesses();
|
||||||
@ -183,14 +240,14 @@ export class IframeController {
|
|||||||
processes,
|
processes,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDecryptState = async (event: MessageEvent) => {
|
const handleDecryptState = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.RETRIEVE_DATA} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.RETRIEVE_DATA} reçu`);
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
const { processId, stateId } = event.data;
|
const { processId, stateId } = event.data;
|
||||||
|
|
||||||
@ -199,22 +256,36 @@ export class IframeController {
|
|||||||
if (!process) throw new Error("Can't find process");
|
if (!process) throw new Error("Can't find process");
|
||||||
|
|
||||||
const state = services.getStateFromId(process, stateId);
|
const state = services.getStateFromId(process, stateId);
|
||||||
if (!state) throw new Error(`Unknown state ${stateId} for process ${processId}`);
|
if (!state)
|
||||||
|
throw new Error(`Unknown state ${stateId} for process ${processId}`);
|
||||||
|
|
||||||
console.log(`[Router:API] 🔐 Démarrage du déchiffrement pour ${processId}`);
|
console.log(
|
||||||
|
`[Router:API] 🔐 Démarrage du déchiffrement pour ${processId}`
|
||||||
|
);
|
||||||
await services.ensureConnections(process, stateId);
|
await services.ensureConnections(process, stateId);
|
||||||
|
|
||||||
const res: Record<string, any> = {};
|
const res: Record<string, any> = {};
|
||||||
for (const attribute of Object.keys(state.pcd_commitment)) {
|
for (const attribute of Object.keys(state.pcd_commitment)) {
|
||||||
if (attribute === 'roles' || (state.public_data && state.public_data[attribute])) {
|
if (
|
||||||
|
attribute === "roles" ||
|
||||||
|
(state.public_data && state.public_data[attribute])
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const decryptedAttribute = await services.decryptAttribute(processId, state, attribute);
|
const decryptedAttribute = await services.decryptAttribute(
|
||||||
|
processId,
|
||||||
|
state,
|
||||||
|
attribute
|
||||||
|
);
|
||||||
if (decryptedAttribute) {
|
if (decryptedAttribute) {
|
||||||
res[attribute] = decryptedAttribute;
|
res[attribute] = decryptedAttribute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`[Router:API] ✅ Déchiffrement terminé pour ${processId}. ${Object.keys(res).length} attribut(s) déchiffré(s).`);
|
console.log(
|
||||||
|
`[Router:API] ✅ Déchiffrement terminé pour ${processId}. ${
|
||||||
|
Object.keys(res).length
|
||||||
|
} attribut(s) déchiffré(s).`
|
||||||
|
);
|
||||||
|
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
@ -222,7 +293,7 @@ export class IframeController {
|
|||||||
data: res,
|
data: res,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -232,10 +303,13 @@ export class IframeController {
|
|||||||
const accessToken = event.data.accessToken;
|
const accessToken = event.data.accessToken;
|
||||||
const refreshToken = event.data.refreshToken;
|
const refreshToken = event.data.refreshToken;
|
||||||
if (!accessToken || !refreshToken) {
|
if (!accessToken || !refreshToken) {
|
||||||
throw new Error('Missing access, refresh token or both');
|
throw new Error("Missing access, refresh token or both");
|
||||||
}
|
}
|
||||||
|
|
||||||
const isValid = await tokenService.validateToken(accessToken, event.origin);
|
const isValid = await tokenService.validateToken(
|
||||||
|
accessToken,
|
||||||
|
event.origin
|
||||||
|
);
|
||||||
console.log(`[Router:API] 🔑 Validation Jeton: ${isValid}`);
|
console.log(`[Router:API] 🔑 Validation Jeton: ${isValid}`);
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
@ -245,17 +319,21 @@ export class IframeController {
|
|||||||
isValid: isValid,
|
isValid: isValid,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRenewToken = async (event: MessageEvent) => {
|
const handleRenewToken = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.RENEW_TOKEN} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.RENEW_TOKEN} reçu`);
|
||||||
const refreshToken = event.data.refreshToken;
|
const refreshToken = event.data.refreshToken;
|
||||||
if (!refreshToken) throw new Error('No refresh token provided');
|
if (!refreshToken) throw new Error("No refresh token provided");
|
||||||
|
|
||||||
const newAccessToken = await tokenService.refreshAccessToken(refreshToken, event.origin);
|
const newAccessToken = await tokenService.refreshAccessToken(
|
||||||
if (!newAccessToken) throw new Error('Failed to refresh token (invalid refresh token)');
|
refreshToken,
|
||||||
|
event.origin
|
||||||
|
);
|
||||||
|
if (!newAccessToken)
|
||||||
|
throw new Error("Failed to refresh token (invalid refresh token)");
|
||||||
|
|
||||||
console.log(`[Router:API] 🔑 Jeton d'accès renouvelé.`);
|
console.log(`[Router:API] 🔑 Jeton d'accès renouvelé.`);
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
@ -265,7 +343,7 @@ export class IframeController {
|
|||||||
refreshToken: refreshToken,
|
refreshToken: refreshToken,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -285,19 +363,29 @@ export class IframeController {
|
|||||||
if (device && device.pairing_process_commitment) {
|
if (device && device.pairing_process_commitment) {
|
||||||
// SUCCÈS ! L'ID est dans la BDD
|
// SUCCÈS ! L'ID est dans la BDD
|
||||||
pairingId = device.pairing_process_commitment;
|
pairingId = device.pairing_process_commitment;
|
||||||
console.log(`[Router:API] GET_PAIRING_ID: ID trouvé en BDD (tentative ${i + 1}/${maxRetries})`);
|
console.log(
|
||||||
|
`[Router:API] GET_PAIRING_ID: ID trouvé en BDD (tentative ${
|
||||||
|
i + 1
|
||||||
|
}/${maxRetries})`
|
||||||
|
);
|
||||||
break; // On sort de la boucle
|
break; // On sort de la boucle
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si non trouvé, on patiente
|
// Si non trouvé, on patiente
|
||||||
console.warn(`[Router:API] GET_PAIRING_ID: Non trouvé en BDD, nouvelle tentative... (${i + 1}/${maxRetries})`);
|
console.warn(
|
||||||
|
`[Router:API] GET_PAIRING_ID: Non trouvé en BDD, nouvelle tentative... (${
|
||||||
|
i + 1
|
||||||
|
}/${maxRetries})`
|
||||||
|
);
|
||||||
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si la boucle se termine sans succès
|
// Si la boucle se termine sans succès
|
||||||
if (!pairingId) {
|
if (!pairingId) {
|
||||||
console.error(`[Router:API] GET_PAIRING_ID: Échec final, non trouvé en BDD après ${maxRetries} tentatives.`);
|
console.error(
|
||||||
throw new Error('Device not paired');
|
`[Router:API] GET_PAIRING_ID: Échec final, non trouvé en BDD après ${maxRetries} tentatives.`
|
||||||
|
);
|
||||||
|
throw new Error("Device not paired");
|
||||||
}
|
}
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
@ -307,31 +395,42 @@ export class IframeController {
|
|||||||
userPairingId: pairingId,
|
userPairingId: pairingId,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCreateProcess = async (event: MessageEvent) => {
|
const handleCreateProcess = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.CREATE_PROCESS} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.CREATE_PROCESS} reçu`);
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
const { processData, privateFields, roles } = event.data;
|
const { processData, privateFields, roles } = event.data;
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
console.log('[Router:API] 🚀 Démarrage de la création de processus standard...');
|
console.log(
|
||||||
const { privateData, publicData } = splitPrivateData(processData, privateFields);
|
"[Router:API] 🚀 Démarrage de la création de processus standard..."
|
||||||
|
);
|
||||||
|
const { privateData, publicData } = splitPrivateData(
|
||||||
|
processData,
|
||||||
|
privateFields
|
||||||
|
);
|
||||||
|
|
||||||
console.log('[Router:API] 1/2: Création du processus...');
|
console.log("[Router:API] 1/2: Création du processus...");
|
||||||
const createProcessReturn = await services.createProcess(privateData, publicData, roles);
|
const createProcessReturn = await services.createProcess(
|
||||||
|
privateData,
|
||||||
|
publicData,
|
||||||
|
roles
|
||||||
|
);
|
||||||
if (!createProcessReturn.updated_process) {
|
if (!createProcessReturn.updated_process) {
|
||||||
throw new Error('Empty updated_process in createProcessReturn');
|
throw new Error("Empty updated_process in createProcessReturn");
|
||||||
}
|
}
|
||||||
|
|
||||||
const processId = createProcessReturn.updated_process.process_id;
|
const processId = createProcessReturn.updated_process.process_id;
|
||||||
const process = createProcessReturn.updated_process.current_process;
|
const process = createProcessReturn.updated_process.current_process;
|
||||||
const stateId = process.states[0].state_id;
|
const stateId = process.states[0].state_id;
|
||||||
console.log(`[Router:API] 2/2: Processus ${processId} créé. Traitement...`);
|
console.log(
|
||||||
|
`[Router:API] 2/2: Processus ${processId} créé. Traitement...`
|
||||||
|
);
|
||||||
await services.handleApiReturn(createProcessReturn);
|
await services.handleApiReturn(createProcessReturn);
|
||||||
|
|
||||||
console.log(`[Router:API] 🎉 Processus ${processId} créé.`);
|
console.log(`[Router:API] 🎉 Processus ${processId} créé.`);
|
||||||
@ -348,19 +447,19 @@ export class IframeController {
|
|||||||
processCreated: res,
|
processCreated: res,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNotifyUpdate = async (event: MessageEvent) => {
|
const handleNotifyUpdate = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.NOTIFY_UPDATE} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.NOTIFY_UPDATE} reçu`);
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
const { processId, stateId } = event.data;
|
const { processId, stateId } = event.data;
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
if (!isValid32ByteHex(stateId)) throw new Error('Invalid state id');
|
if (!isValid32ByteHex(stateId)) throw new Error("Invalid state id");
|
||||||
|
|
||||||
const res = await services.createPrdUpdate(processId, stateId);
|
const res = await services.createPrdUpdate(processId, stateId);
|
||||||
await services.handleApiReturn(res);
|
await services.handleApiReturn(res);
|
||||||
@ -370,14 +469,14 @@ export class IframeController {
|
|||||||
type: MessageType.UPDATE_NOTIFIED,
|
type: MessageType.UPDATE_NOTIFIED,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleValidateState = async (event: MessageEvent) => {
|
const handleValidateState = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.VALIDATE_STATE} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.VALIDATE_STATE} reçu`);
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
const { processId, stateId } = event.data;
|
const { processId, stateId } = event.data;
|
||||||
|
|
||||||
@ -391,22 +490,29 @@ export class IframeController {
|
|||||||
validatedProcess: res.updated_process,
|
validatedProcess: res.updated_process,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateProcess = async (event: MessageEvent) => {
|
const handleUpdateProcess = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.UPDATE_PROCESS} reçu`);
|
console.log(`[Router:API] 📨 Message ${MessageType.UPDATE_PROCESS} reçu`);
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
const { processId, newData, privateFields, roles } = event.data;
|
const { processId, newData, privateFields, roles } = event.data;
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
console.log(`[Router:API] 🔄 Transfert de la mise à jour de ${processId} au service...`);
|
console.log(
|
||||||
|
`[Router:API] 🔄 Transfert de la mise à jour de ${processId} au service...`
|
||||||
|
);
|
||||||
|
|
||||||
// Le service gère maintenant tout : récupération, réparation d'état, et mise à jour.
|
// Le service gère maintenant tout : récupération, réparation d'état, et mise à jour.
|
||||||
const res = await services.updateProcess(processId, newData, privateFields, roles);
|
const res = await services.updateProcess(
|
||||||
|
processId,
|
||||||
|
newData,
|
||||||
|
privateFields,
|
||||||
|
roles
|
||||||
|
);
|
||||||
|
|
||||||
// Nous appelons handleApiReturn ici, comme avant.
|
// Nous appelons handleApiReturn ici, comme avant.
|
||||||
await services.handleApiReturn(res);
|
await services.handleApiReturn(res);
|
||||||
@ -418,14 +524,16 @@ export class IframeController {
|
|||||||
updatedProcess: res.updated_process, // res vient directement de l'appel service
|
updatedProcess: res.updated_process, // res vient directement de l'appel service
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDecodePublicData = async (event: MessageEvent) => {
|
const handleDecodePublicData = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.DECODE_PUBLIC_DATA} reçu`);
|
console.log(
|
||||||
if (!services.isPaired()) throw new Error('Device not paired');
|
`[Router:API] 📨 Message ${MessageType.DECODE_PUBLIC_DATA} reçu`
|
||||||
|
);
|
||||||
|
if (!services.isPaired()) throw new Error("Device not paired");
|
||||||
|
|
||||||
const { encodedData } = event.data;
|
const { encodedData } = event.data;
|
||||||
|
|
||||||
@ -437,7 +545,7 @@ export class IframeController {
|
|||||||
decodedData,
|
decodedData,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -454,30 +562,37 @@ export class IframeController {
|
|||||||
hash,
|
hash,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGetMerkleProof = async (event: MessageEvent) => {
|
const handleGetMerkleProof = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.GET_MERKLE_PROOF} reçu`);
|
console.log(
|
||||||
|
`[Router:API] 📨 Message ${MessageType.GET_MERKLE_PROOF} reçu`
|
||||||
|
);
|
||||||
const { processState, attributeName } = event.data;
|
const { processState, attributeName } = event.data;
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
const proof = services.getMerkleProofForFile(processState, attributeName);
|
const proof = services.getMerkleProofForFile(
|
||||||
|
processState,
|
||||||
|
attributeName
|
||||||
|
);
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
type: MessageType.MERKLE_PROOF_RETRIEVED,
|
type: MessageType.MERKLE_PROOF_RETRIEVED,
|
||||||
proof,
|
proof,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleValidateMerkleProof = async (event: MessageEvent) => {
|
const handleValidateMerkleProof = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.VALIDATE_MERKLE_PROOF} reçu`);
|
console.log(
|
||||||
|
`[Router:API] 📨 Message ${MessageType.VALIDATE_MERKLE_PROOF} reçu`
|
||||||
|
);
|
||||||
const { merkleProof, documentHash } = event.data;
|
const { merkleProof, documentHash } = event.data;
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
@ -485,25 +600,28 @@ export class IframeController {
|
|||||||
try {
|
try {
|
||||||
parsedMerkleProof = JSON.parse(merkleProof);
|
parsedMerkleProof = JSON.parse(merkleProof);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error('Provided merkleProof is not a valid json object');
|
throw new Error("Provided merkleProof is not a valid json object");
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = services.validateMerkleProof(parsedMerkleProof, documentHash);
|
const res = services.validateMerkleProof(
|
||||||
|
parsedMerkleProof,
|
||||||
|
documentHash
|
||||||
|
);
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
type: MessageType.MERKLE_PROOF_VALIDATED,
|
type: MessageType.MERKLE_PROOF_VALIDATED,
|
||||||
isValid: res,
|
isValid: res,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin,
|
event.origin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Le "Switchyard" : il reçoit tous les messages et les dispatche ---
|
// --- Le "Switchyard" : il reçoit tous les messages et les dispatche ---
|
||||||
|
|
||||||
window.removeEventListener('message', handleMessage);
|
window.removeEventListener("message", handleMessage);
|
||||||
window.addEventListener('message', handleMessage);
|
window.addEventListener("message", handleMessage);
|
||||||
|
|
||||||
async function handleMessage(event: MessageEvent) {
|
async function handleMessage(event: MessageEvent) {
|
||||||
try {
|
try {
|
||||||
@ -557,7 +675,7 @@ export class IframeController {
|
|||||||
await handleValidateMerkleProof(event);
|
await handleValidateMerkleProof(event);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn('[Router:API] ⚠️ Message non géré reçu:', event.data);
|
console.warn("[Router:API] ⚠️ Message non géré reçu:", event.data);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorMsg = `[Router:API] 💥 Erreur de haut niveau: ${error}`;
|
const errorMsg = `[Router:API] 💥 Erreur de haut niveau: ${error}`;
|
||||||
@ -569,9 +687,10 @@ export class IframeController {
|
|||||||
{
|
{
|
||||||
type: MessageType.LISTENING,
|
type: MessageType.LISTENING,
|
||||||
},
|
},
|
||||||
'*',
|
"*"
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
"[Router:API] ✅ Tous les listeners sont actifs. Envoi du message LISTENING au parent."
|
||||||
);
|
);
|
||||||
console.log('[Router:API] ✅ Tous les listeners sont actifs. Envoi du message LISTENING au parent.');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user