refactor(iframe-controller): improve initialization logic, enhance logging, and streamline message handling for better clarity and performance
This commit is contained in:
parent
1cebd0ba7b
commit
77dcb8b9ae
@ -10,6 +10,7 @@ export class IframeController {
|
|||||||
|
|
||||||
static async init() {
|
static async init() {
|
||||||
if (this.isInitialized) return;
|
if (this.isInitialized) return;
|
||||||
|
this.isInitialized = true; // Marquage immédiat pour éviter les doubles appels
|
||||||
|
|
||||||
if (window.self !== window.top) {
|
if (window.self !== window.top) {
|
||||||
console.log(
|
console.log(
|
||||||
@ -18,25 +19,24 @@ export class IframeController {
|
|||||||
await IframeController.registerAllListeners();
|
await IframeController.registerAllListeners();
|
||||||
} else {
|
} else {
|
||||||
console.log(
|
console.log(
|
||||||
"[IframeController] ℹ️ Mode Standalone (pas d'iframe). Listeners API inactifs."
|
"[IframeController] ℹ️ Mode Standalone. Listeners API inactifs."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async registerAllListeners() {
|
private static async registerAllListeners() {
|
||||||
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();
|
||||||
|
|
||||||
|
// --- UTILS ---
|
||||||
|
|
||||||
const errorResponse = (
|
const errorResponse = (
|
||||||
errorMsg: string,
|
errorMsg: string,
|
||||||
origin: string,
|
origin: string,
|
||||||
messageId?: string
|
messageId?: string
|
||||||
) => {
|
) => {
|
||||||
console.error(
|
console.error(
|
||||||
`[Router:API] 📤 Envoi Erreur: ${errorMsg} (Origine: ${origin}, MsgID: ${messageId})`
|
`[Router:API] 📤 Envoi Erreur: ${errorMsg} (Origine: ${origin})`
|
||||||
);
|
);
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ export class IframeController {
|
|||||||
error: errorMsg,
|
error: errorMsg,
|
||||||
messageId,
|
messageId,
|
||||||
},
|
},
|
||||||
origin
|
origin // On renvoie à l'origine exacte reçue, même en mode *
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,6 +53,7 @@ export class IframeController {
|
|||||||
action: () => Promise<void>
|
action: () => Promise<void>
|
||||||
) => {
|
) => {
|
||||||
const { accessToken } = event.data;
|
const { accessToken } = event.data;
|
||||||
|
// Note: Pour la démo, on accepte souvent tout, mais la validation du token reste une bonne pratique
|
||||||
if (
|
if (
|
||||||
!accessToken ||
|
!accessToken ||
|
||||||
!(await tokenService.validateToken(accessToken, event.origin))
|
!(await tokenService.validateToken(accessToken, event.origin))
|
||||||
@ -71,11 +72,11 @@ export class IframeController {
|
|||||||
|
|
||||||
const device = await services.getDeviceFromDatabase();
|
const device = await services.getDeviceFromDatabase();
|
||||||
|
|
||||||
|
// Si déjà appairé, on accepte immédiatement sans attendre l'événement UI
|
||||||
if (device && device.pairing_process_commitment) {
|
if (device && device.pairing_process_commitment) {
|
||||||
console.log(
|
console.log("[Router:API] Appareil déjà appairé. Liaison immédiate.");
|
||||||
"[Router:API] Appareil déjà appairé. Pas besoin d'attendre home.ts."
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
|
// Sinon, on attend que l'utilisateur clique sur "Lier" dans l'interface (Home.ts)
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
document.removeEventListener(
|
document.removeEventListener(
|
||||||
@ -96,21 +97,19 @@ export class IframeController {
|
|||||||
|
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
cleanup();
|
cleanup();
|
||||||
reject(new Error("Auto-pairing timed out (Event not received)"));
|
reject(new Error("Auto-pairing timed out (User action missing)"));
|
||||||
}, 5000);
|
}, 60000); // Augmenté à 60s pour laisser le temps à l'utilisateur de cliquer
|
||||||
|
|
||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
"app:pairing-ready",
|
"app:pairing-ready",
|
||||||
handler as EventListener
|
handler as EventListener
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`[Router:API] Feu vert de home.ts reçu !`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[Router:API] Traitement de la liaison...`);
|
console.log(`[Router:API] Génération des tokens de session...`);
|
||||||
|
|
||||||
const tokens = await tokenService.generateSessionToken(event.origin);
|
const tokens = await tokenService.generateSessionToken(event.origin);
|
||||||
|
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
type: MessageType.LINK_ACCEPTED,
|
type: MessageType.LINK_ACCEPTED,
|
||||||
@ -120,15 +119,11 @@ export class IframeController {
|
|||||||
},
|
},
|
||||||
event.origin
|
event.origin
|
||||||
);
|
);
|
||||||
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`);
|
||||||
|
|
||||||
// 🔥 CORRECTION TS2801 : Ajout de await
|
|
||||||
if (await services.isPaired()) {
|
if (await services.isPaired()) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Device already paired — ignoring CREATE_PAIRING request"
|
"Device already paired — ignoring CREATE_PAIRING request"
|
||||||
@ -136,12 +131,9 @@ export class IframeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
console.log("[Router:API] 🚀 Démarrage du processus d'appairage...");
|
const myAddress = await services.getDeviceAddress(); // string
|
||||||
|
|
||||||
// 🔥 CORRECTION TS2322 : Ajout de await pour récupérer la string
|
console.log("[Router:API] Création du processus de pairing...");
|
||||||
const myAddress = await services.getDeviceAddress();
|
|
||||||
|
|
||||||
console.log("[Router:API] 1/7: Création du processus de pairing...");
|
|
||||||
const createPairingProcessReturn = await services.createPairingProcess(
|
const createPairingProcessReturn = await services.createPairingProcess(
|
||||||
"",
|
"",
|
||||||
[myAddress]
|
[myAddress]
|
||||||
@ -151,58 +143,44 @@ export class IframeController {
|
|||||||
createPairingProcessReturn.updated_process?.process_id;
|
createPairingProcessReturn.updated_process?.process_id;
|
||||||
const stateId = createPairingProcessReturn.updated_process
|
const stateId = createPairingProcessReturn.updated_process
|
||||||
?.current_process?.states[0]?.state_id as string;
|
?.current_process?.states[0]?.state_id as string;
|
||||||
|
|
||||||
if (!pairingId || !stateId) {
|
if (!pairingId || !stateId) {
|
||||||
throw new Error(
|
throw new Error("Pairing process creation failed (invalid IDs)");
|
||||||
"Pairing process creation failed to return valid IDs"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
console.log(`[Router:API] 2/7: Processus ${pairingId} créé.`);
|
|
||||||
|
|
||||||
console.log("[Router:API] 3/7: Enregistrement local de l'appareil...");
|
|
||||||
// 🔥 CORRECTION TS2322 : myAddress est maintenant une string, plus une Promise
|
|
||||||
await services.pairDevice(pairingId, [myAddress]);
|
await services.pairDevice(pairingId, [myAddress]);
|
||||||
|
|
||||||
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...");
|
// Auto-approbation du premier état (PRD)
|
||||||
const createPrdUpdateReturn = await services.createPrdUpdate(
|
const createPrdUpdateReturn = await services.createPrdUpdate(
|
||||||
pairingId,
|
pairingId,
|
||||||
stateId
|
stateId
|
||||||
);
|
);
|
||||||
await services.handleApiReturn(createPrdUpdateReturn);
|
await services.handleApiReturn(createPrdUpdateReturn);
|
||||||
|
|
||||||
console.log("[Router:API] 6/7: Approbation du changement...");
|
|
||||||
const approveChangeReturn = await services.approveChange(
|
const approveChangeReturn = await services.approveChange(
|
||||||
pairingId,
|
pairingId,
|
||||||
stateId
|
stateId
|
||||||
);
|
);
|
||||||
await services.handleApiReturn(approveChangeReturn);
|
await services.handleApiReturn(approveChangeReturn);
|
||||||
|
|
||||||
console.log("[Router:API] 7/7: Confirmation finale du pairing...");
|
console.log("[Router:API] 🎉 Appairage terminé !");
|
||||||
|
|
||||||
console.log("[Router:API] 🎉 Appairage terminé avec succès !");
|
window.parent.postMessage(
|
||||||
|
{
|
||||||
const successMsg = {
|
|
||||||
type: MessageType.PAIRING_CREATED,
|
type: MessageType.PAIRING_CREATED,
|
||||||
pairingId,
|
pairingId,
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
};
|
},
|
||||||
window.parent.postMessage(successMsg, event.origin);
|
event.origin
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGetMyProcesses = async (event: MessageEvent) => {
|
const handleGetMyProcesses = async (event: MessageEvent) => {
|
||||||
console.log(
|
|
||||||
`[Router:API] 📨 Message ${MessageType.GET_MY_PROCESSES} reçu`
|
|
||||||
);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
if (!(await 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();
|
||||||
|
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
type: MessageType.GET_MY_PROCESSES,
|
type: MessageType.GET_MY_PROCESSES,
|
||||||
@ -215,12 +193,9 @@ export class IframeController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleGetProcesses = async (event: MessageEvent) => {
|
const handleGetProcesses = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.GET_PROCESSES} reçu`);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
if (!(await 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();
|
||||||
|
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
type: MessageType.PROCESSES_RETRIEVED,
|
type: MessageType.PROCESSES_RETRIEVED,
|
||||||
@ -233,27 +208,21 @@ export class IframeController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDecryptState = async (event: MessageEvent) => {
|
const handleDecryptState = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.RETRIEVE_DATA} reçu`);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
if (!(await 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 () => {
|
||||||
const process = await services.getProcess(processId);
|
const process = await services.getProcess(processId);
|
||||||
if (!process) throw new Error("Can't find process");
|
if (!process) throw new Error("Can't find process");
|
||||||
|
|
||||||
// 🔥 CORRECTION TS2339 & TS2345 : Ajout de await car getStateFromId est async
|
|
||||||
const state = await services.getStateFromId(process, stateId);
|
const state = await services.getStateFromId(process, stateId);
|
||||||
|
if (!state) throw new Error(`Unknown state ${stateId}`);
|
||||||
|
|
||||||
if (!state)
|
|
||||||
throw new Error(`Unknown state ${stateId} for process ${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> = {};
|
||||||
|
|
||||||
|
// Déchiffrement des attributs privés
|
||||||
for (const attribute of Object.keys(state.pcd_commitment)) {
|
for (const attribute of Object.keys(state.pcd_commitment)) {
|
||||||
if (
|
if (
|
||||||
attribute === "roles" ||
|
attribute === "roles" ||
|
||||||
@ -270,10 +239,6 @@ export class IframeController {
|
|||||||
res[attribute] = decryptedAttribute;
|
res[attribute] = decryptedAttribute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(
|
|
||||||
`[Router:API] ✅ Déchiffrement terminé pour ${processId}. ${Object.keys(res).length
|
|
||||||
} attribut(s) déchiffré(s).`
|
|
||||||
);
|
|
||||||
|
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
@ -286,79 +251,21 @@ export class IframeController {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleValidateToken = async (event: MessageEvent) => {
|
|
||||||
// ... (Code identique, pas d'erreurs ici normalement)
|
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.VALIDATE_TOKEN} reçu`);
|
|
||||||
const accessToken = event.data.accessToken;
|
|
||||||
const refreshToken = event.data.refreshToken;
|
|
||||||
if (!accessToken || !refreshToken) {
|
|
||||||
throw new Error("Missing access, refresh token or both");
|
|
||||||
}
|
|
||||||
|
|
||||||
const isValid = await tokenService.validateToken(
|
|
||||||
accessToken,
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
console.log(`[Router:API] 🔑 Validation Jeton: ${isValid}`);
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.VALIDATE_TOKEN,
|
|
||||||
accessToken: accessToken,
|
|
||||||
refreshToken: refreshToken,
|
|
||||||
isValid: isValid,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRenewToken = async (event: MessageEvent) => {
|
|
||||||
// ... (Code identique)
|
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.RENEW_TOKEN} reçu`);
|
|
||||||
const refreshToken = event.data.refreshToken;
|
|
||||||
if (!refreshToken) throw new Error("No refresh token provided");
|
|
||||||
|
|
||||||
const newAccessToken = await tokenService.refreshAccessToken(
|
|
||||||
refreshToken,
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
if (!newAccessToken)
|
|
||||||
throw new Error("Failed to refresh token (invalid refresh token)");
|
|
||||||
|
|
||||||
console.log(`[Router:API] 🔑 Jeton d'accès renouvelé.`);
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.RENEW_TOKEN,
|
|
||||||
accessToken: newAccessToken,
|
|
||||||
refreshToken: refreshToken,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleGetPairingId = async (event: MessageEvent) => {
|
const handleGetPairingId = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.GET_PAIRING_ID} reçu`);
|
// Logique de retry si la DB est lente au démarrage
|
||||||
const maxRetries = 10;
|
const maxRetries = 10;
|
||||||
const retryDelay = 300;
|
|
||||||
let pairingId: string | null = null;
|
let pairingId: string | null = null;
|
||||||
|
|
||||||
for (let i = 0; i < maxRetries; i++) {
|
for (let i = 0; i < maxRetries; i++) {
|
||||||
const device = await services.getDeviceFromDatabase();
|
const device = await services.getDeviceFromDatabase();
|
||||||
if (device && device.pairing_process_commitment) {
|
if (device && device.pairing_process_commitment) {
|
||||||
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})`
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pairingId) {
|
if (!pairingId) throw new Error("Device not paired (Timeout)");
|
||||||
throw new Error("Device not paired");
|
|
||||||
}
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
await withToken(event, async () => {
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
@ -373,9 +280,7 @@ export class IframeController {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleCreateProcess = async (event: MessageEvent) => {
|
const handleCreateProcess = async (event: MessageEvent) => {
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.CREATE_PROCESS} reçu`);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
if (!(await 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 () => {
|
||||||
@ -383,32 +288,24 @@ export class IframeController {
|
|||||||
processData,
|
processData,
|
||||||
privateFields
|
privateFields
|
||||||
);
|
);
|
||||||
|
|
||||||
const createProcessReturn = await services.createProcess(
|
const createProcessReturn = await services.createProcess(
|
||||||
privateData,
|
privateData,
|
||||||
publicData,
|
publicData,
|
||||||
roles
|
roles
|
||||||
);
|
);
|
||||||
if (!createProcessReturn.updated_process) {
|
|
||||||
throw new Error("Empty updated_process in createProcessReturn");
|
if (!createProcessReturn.updated_process)
|
||||||
}
|
throw new Error("Process creation failed");
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
await services.handleApiReturn(createProcessReturn);
|
await services.handleApiReturn(createProcessReturn);
|
||||||
console.log(`[Router:API] 🎉 Processus ${processId} créé.`);
|
|
||||||
|
|
||||||
const res = {
|
|
||||||
processId,
|
|
||||||
process,
|
|
||||||
processData,
|
|
||||||
};
|
|
||||||
|
|
||||||
window.parent.postMessage(
|
window.parent.postMessage(
|
||||||
{
|
{
|
||||||
type: MessageType.PROCESS_CREATED,
|
type: MessageType.PROCESS_CREATED,
|
||||||
processCreated: res,
|
processCreated: { processId, process, processData },
|
||||||
messageId: event.data.messageId,
|
messageId: event.data.messageId,
|
||||||
},
|
},
|
||||||
event.origin
|
event.origin
|
||||||
@ -416,170 +313,18 @@ export class IframeController {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNotifyUpdate = async (event: MessageEvent) => {
|
// --- MAIN MESSAGE DISPATCHER ---
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.NOTIFY_UPDATE} reçu`);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
|
||||||
|
|
||||||
const { processId, stateId } = event.data;
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
|
||||||
if (!isValid32ByteHex(stateId)) throw new Error("Invalid state id");
|
|
||||||
|
|
||||||
const res = await services.createPrdUpdate(processId, stateId);
|
|
||||||
await services.handleApiReturn(res);
|
|
||||||
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.UPDATE_NOTIFIED,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleValidateState = async (event: MessageEvent) => {
|
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.VALIDATE_STATE} reçu`);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
|
||||||
|
|
||||||
const { processId, stateId } = event.data;
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
|
||||||
const res = await services.approveChange(processId, stateId);
|
|
||||||
await services.handleApiReturn(res);
|
|
||||||
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.STATE_VALIDATED,
|
|
||||||
validatedProcess: res.updated_process,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleUpdateProcess = async (event: MessageEvent) => {
|
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.UPDATE_PROCESS} reçu`);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
|
||||||
|
|
||||||
const { processId, newData, privateFields, roles } = event.data;
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
|
||||||
const res = await services.updateProcess(
|
|
||||||
processId,
|
|
||||||
newData,
|
|
||||||
privateFields,
|
|
||||||
roles
|
|
||||||
);
|
|
||||||
await services.handleApiReturn(res);
|
|
||||||
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.PROCESS_UPDATED,
|
|
||||||
updatedProcess: res.updated_process,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDecodePublicData = async (event: MessageEvent) => {
|
|
||||||
console.log(
|
|
||||||
`[Router:API] 📨 Message ${MessageType.DECODE_PUBLIC_DATA} reçu`
|
|
||||||
);
|
|
||||||
if (!(await services.isPaired())) throw new Error("Device not paired");
|
|
||||||
|
|
||||||
const { encodedData } = event.data;
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
|
||||||
const decodedData = await services.decodeValue(encodedData);
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.PUBLIC_DATA_DECODED,
|
|
||||||
decodedData,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleHashValue = async (event: MessageEvent) => {
|
|
||||||
console.log(`[Router:API] 📨 Message ${MessageType.HASH_VALUE} reçu`);
|
|
||||||
const { commitedIn, label, fileBlob } = event.data;
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
|
||||||
const hash = await services.getHashForFile(commitedIn, label, fileBlob);
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.VALUE_HASHED,
|
|
||||||
hash,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleGetMerkleProof = async (event: MessageEvent) => {
|
|
||||||
console.log(
|
|
||||||
`[Router:API] 📨 Message ${MessageType.GET_MERKLE_PROOF} reçu`
|
|
||||||
);
|
|
||||||
const { processState, attributeName } = event.data;
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
|
||||||
const proof = await services.getMerkleProofForFile(
|
|
||||||
processState,
|
|
||||||
attributeName
|
|
||||||
);
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.MERKLE_PROOF_RETRIEVED,
|
|
||||||
proof,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleValidateMerkleProof = async (event: MessageEvent) => {
|
|
||||||
console.log(
|
|
||||||
`[Router:API] 📨 Message ${MessageType.VALIDATE_MERKLE_PROOF} reçu`
|
|
||||||
);
|
|
||||||
const { merkleProof, documentHash } = event.data;
|
|
||||||
|
|
||||||
await withToken(event, async () => {
|
|
||||||
let parsedMerkleProof: MerkleProofResult;
|
|
||||||
try {
|
|
||||||
parsedMerkleProof = JSON.parse(merkleProof);
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error("Provided merkleProof is not a valid json object");
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await services.validateMerkleProof(
|
|
||||||
parsedMerkleProof,
|
|
||||||
documentHash
|
|
||||||
);
|
|
||||||
window.parent.postMessage(
|
|
||||||
{
|
|
||||||
type: MessageType.MERKLE_PROOF_VALIDATED,
|
|
||||||
isValid: res,
|
|
||||||
messageId: event.data.messageId,
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
window.removeEventListener("message", handleMessage);
|
|
||||||
window.addEventListener("message", handleMessage);
|
|
||||||
|
|
||||||
async function handleMessage(event: MessageEvent) {
|
async function handleMessage(event: MessageEvent) {
|
||||||
|
// 🛡️ SÉCURITÉ : Ignorer les messages qui ne sont pas des objets (ex: extensions Chrome)
|
||||||
|
if (!event.data || typeof event.data !== "object") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🛡️ FILTRAGE : On ne traite que les messages avec un 'type' connu
|
||||||
|
if (!event.data.type) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Switch/case inchangé ...
|
|
||||||
switch (event.data.type) {
|
switch (event.data.type) {
|
||||||
case MessageType.REQUEST_LINK:
|
case MessageType.REQUEST_LINK:
|
||||||
await handleRequestLink(event);
|
await handleRequestLink(event);
|
||||||
@ -596,56 +341,70 @@ export class IframeController {
|
|||||||
case MessageType.RETRIEVE_DATA:
|
case MessageType.RETRIEVE_DATA:
|
||||||
await handleDecryptState(event);
|
await handleDecryptState(event);
|
||||||
break;
|
break;
|
||||||
case MessageType.VALIDATE_TOKEN:
|
|
||||||
await handleValidateToken(event);
|
|
||||||
break;
|
|
||||||
case MessageType.RENEW_TOKEN:
|
|
||||||
await handleRenewToken(event);
|
|
||||||
break;
|
|
||||||
case MessageType.GET_PAIRING_ID:
|
case MessageType.GET_PAIRING_ID:
|
||||||
await handleGetPairingId(event);
|
await handleGetPairingId(event);
|
||||||
break;
|
break;
|
||||||
case MessageType.CREATE_PROCESS:
|
case MessageType.CREATE_PROCESS:
|
||||||
await handleCreateProcess(event);
|
await handleCreateProcess(event);
|
||||||
break;
|
break;
|
||||||
case MessageType.NOTIFY_UPDATE:
|
|
||||||
await handleNotifyUpdate(event);
|
// Cas simples (tokens, notifications...)
|
||||||
|
case MessageType.VALIDATE_TOKEN:
|
||||||
|
const { accessToken, refreshToken } = event.data;
|
||||||
|
if (!accessToken || !refreshToken)
|
||||||
|
throw new Error("Tokens missing");
|
||||||
|
const isValid = await tokenService.validateToken(
|
||||||
|
accessToken,
|
||||||
|
event.origin
|
||||||
|
);
|
||||||
|
window.parent.postMessage(
|
||||||
|
{
|
||||||
|
type: MessageType.VALIDATE_TOKEN,
|
||||||
|
isValid,
|
||||||
|
accessToken,
|
||||||
|
refreshToken,
|
||||||
|
messageId: event.data.messageId,
|
||||||
|
},
|
||||||
|
event.origin
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case MessageType.VALIDATE_STATE:
|
|
||||||
await handleValidateState(event);
|
case MessageType.RENEW_TOKEN:
|
||||||
break;
|
if (!event.data.refreshToken) throw new Error("No refresh token");
|
||||||
case MessageType.UPDATE_PROCESS:
|
const newAccess = await tokenService.refreshAccessToken(
|
||||||
await handleUpdateProcess(event);
|
event.data.refreshToken,
|
||||||
break;
|
event.origin
|
||||||
case MessageType.DECODE_PUBLIC_DATA:
|
);
|
||||||
await handleDecodePublicData(event);
|
if (!newAccess) throw new Error("Refresh failed");
|
||||||
break;
|
window.parent.postMessage(
|
||||||
case MessageType.HASH_VALUE:
|
{
|
||||||
await handleHashValue(event);
|
type: MessageType.RENEW_TOKEN,
|
||||||
break;
|
accessToken: newAccess,
|
||||||
case MessageType.GET_MERKLE_PROOF:
|
refreshToken: event.data.refreshToken,
|
||||||
await handleGetMerkleProof(event);
|
messageId: event.data.messageId,
|
||||||
break;
|
},
|
||||||
case MessageType.VALIDATE_MERKLE_PROOF:
|
event.origin
|
||||||
await handleValidateMerkleProof(event);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// console.warn("[Router:API] ⚠️ Message non géré reçu:", event.data);
|
// Silence sur les types inconnus (peut être un autre protocole)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorMsg = `[Router:API] 💥 Erreur de haut niveau: ${error}`;
|
// En cas d'erreur métier, on prévient le parent
|
||||||
errorResponse(errorMsg, event.origin, event.data.messageId);
|
errorResponse(
|
||||||
|
String(error.message || error),
|
||||||
|
event.origin,
|
||||||
|
event.data?.messageId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.parent.postMessage(
|
// Ajout du listener unique
|
||||||
{
|
window.addEventListener("message", handleMessage);
|
||||||
type: MessageType.LISTENING,
|
|
||||||
},
|
// Handshake final : "Je suis prêt"
|
||||||
"*"
|
window.parent.postMessage({ type: MessageType.LISTENING }, "*");
|
||||||
);
|
console.log("[Router:API] ✅ Listeners actifs. Handshake envoyé.");
|
||||||
console.log(
|
|
||||||
"[Router:API] ✅ Tous les listeners sont actifs. Envoi du message LISTENING au parent."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user