Liaison avec ${event.origin}
Vous êtes sur le point de lier l'identité numérique de la clé securisée propre à votre appareil avec ${event.origin}.
Cette action permettra à ${event.origin} d'intéragir avec votre appareil.
Voulez-vous continuer ?
`,
confirmText: 'Ajouter un service',
cancelText: 'Annuler',
},
true
);
if (!result) {
const errorMsg = 'Failed to pair device: User refused to link';
secureLogger.error(errorMsg, { component: 'Router' });
// Error handling - no response needed
}
try {
const tokens = await tokenService.generateSessionToken(event.origin);
const acceptedMsg = {
type: MessageType.LINK_ACCEPTED,
accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken,
messageId: event.data.messageId,
};
window.parent.postMessage(acceptedMsg, event.origin);
} catch (error) {
const errorMsg = `Failed to generate tokens: ${error}`;
secureLogger.error(errorMsg, { component: 'Router' });
// Error handling - no response needed
}
};
const handleCreatePairing = async (event: MessageEvent) => {
if (event.data.type !== MessageType.CREATE_PAIRING) {
return;
}
secureLogger.info('📨 [Router] Received CREATE_PAIRING request', { component: 'Router' });
if (services.isPaired()) {
const errorMsg = '⚠️ Device already paired — ignoring CREATE_PAIRING request';
secureLogger.warn(errorMsg, { component: 'Router' });
// Error handling - no response needed
return;
}
try {
const { accessToken } = event.data;
secureLogger.debug('🔐 Checking access token validity...', { component: 'Router' });
const validToken =
accessToken && (await tokenService.validateToken(accessToken, event.origin));
if (!validToken) {
throw new Error('❌ Invalid or expired session token');
}
secureLogger.info('✅ Token validated successfully', { component: 'Router' });
secureLogger.info('🚀 Starting pairing process', { component: 'Router' });
const myAddress = await services.getDeviceAddress();
secureLogger.info('📍 Device address:', { component: 'Router', data: myAddress });
secureLogger.info('🧱 Creating pairing process...', { component: 'Router' });
const createPairingProcessReturn = await services.createPairingProcess('', [myAddress]);
secureLogger.info('🧾 Pairing process created:', {
component: 'Router',
data: createPairingProcessReturn,
});
const pairingId = createPairingProcessReturn.updated_process?.process_id;
const stateId = createPairingProcessReturn.updated_process?.current_process?.states[0]
?.state_id as string;
secureLogger.info('🔗 Pairing ID:', { component: 'Router', data: pairingId });
secureLogger.info('🧩 State ID:', { component: 'Router', data: stateId });
secureLogger.info('🔒 Registering device as paired...', { component: 'Router' });
services.pairDevice(pairingId, [myAddress]);
secureLogger.info('🧠 Handling API return for createPairingProcess...', {
component: 'Router',
});
await services.handleApiReturn(createPairingProcessReturn);
secureLogger.debug('🔍 DEBUG: About to create PRD update...', { component: 'Router' });
secureLogger.info('🧰 Creating PRD update...', { component: 'Router' });
const createPrdUpdateReturn = await services.createPrdUpdate(pairingId, stateId);
secureLogger.info('🧾 PRD update result:', {
component: 'Router',
data: createPrdUpdateReturn,
});
await services.handleApiReturn(createPrdUpdateReturn);
secureLogger.debug('✅ DEBUG: PRD update completed successfully!', { component: 'Router' });
secureLogger.debug('🔍 DEBUG: About to approve change...', { component: 'Router' });
secureLogger.info('✅ Approving change...', { component: 'Router' });
const approveChangeReturn = await services.approveChange(pairingId, stateId);
secureLogger.info('📜 Approve change result:', {
component: 'Router',
data: approveChangeReturn,
});
await services.handleApiReturn(approveChangeReturn);
secureLogger.debug('✅ DEBUG: approveChange completed successfully!', {
component: 'Router',
});
secureLogger.debug(
'🔍 DEBUG: approveChange completed, about to call waitForPairingCommitment...',
{ component: 'Router' }
);
secureLogger.info('⏳ Waiting for pairing process to be committed...', {
component: 'Router',
});
await services.waitForPairingCommitment(pairingId);
secureLogger.debug('✅ DEBUG: waitForPairingCommitment completed successfully!', {
component: 'Router',
});
secureLogger.debug('🔍 DEBUG: About to call confirmPairing...', { component: 'Router' });
secureLogger.info('🔁 Confirming pairing...', { component: 'Router' });
await services.confirmPairing(pairingId);
secureLogger.debug('✅ DEBUG: confirmPairing completed successfully!', {
component: 'Router',
});
secureLogger.info('🎉 Pairing successfully completed!', { component: 'Router' });
// ✅ Send success response to frontend
const successMsg = {
type: MessageType.PAIRING_CREATED,
pairingId,
messageId: event.data.messageId,
};
secureLogger.info('📤 Sending PAIRING_CREATED message to UI:', {
component: 'Router',
data: successMsg,
});
window.parent.postMessage(successMsg, event.origin);
} catch (e) {
const errorMsg = `❌ Failed to create pairing process: ${e}`;
secureLogger.error(errorMsg, { component: 'Router' });
// Error handling - no response needed
}
};
const handleGetMyProcesses = async (event: MessageEvent) => {
if (event.data.type !== MessageType.GET_MY_PROCESSES) {
return;
}
if (!services.isPaired()) {
const errorMsg = 'Device not paired';
secureLogger.warn(errorMsg, { component: 'Router' });
// Error handling - no response needed
return;
}
try {
const { accessToken } = event.data;
if (!accessToken || !(await tokenService.validateToken(accessToken, event.origin))) {
throw new Error('Invalid or expired session token');
}
const myProcesses = await services.getMyProcesses();
window.parent.postMessage(
{
type: MessageType.GET_MY_PROCESSES,
myProcesses,
messageId: event.data.messageId,
},
event.origin
);
} catch (e) {
const errorMsg = `Failed to get processes: ${e}`;
secureLogger.error(errorMsg, { component: 'Router' });
// Error handling - no response needed
}
};
const handleGetProcesses = async (event: MessageEvent) => {
if (event.data.type !== MessageType.GET_PROCESSES) {
return;
}
const tokenService = await TokenService.getInstance();
if (!services.isPaired()) {
const errorMsg = 'Device not paired';
secureLogger.warn(errorMsg, { component: 'Router' });
// Error handling - no response needed
return;
}
try {
const { accessToken } = event.data;
// Validate the session token
if (!accessToken || !(await tokenService.validateToken(accessToken, event.origin))) {
throw new Error('Invalid or expired session token');
}
const processes = await services.getProcesses();
window.parent.postMessage(
{
type: MessageType.PROCESSES_RETRIEVED,
processes,
messageId: event.data.messageId,
},
event.origin
);
} catch (e) {
const errorMsg = `Failed to get processes: ${e}`;
secureLogger.error(errorMsg, { component: 'Router' });
// Error handling - no response needed
}
};
/// We got a state for some process and return as many clear attributes as we can
const handleDecryptState = async (event: MessageEvent) => {
if (event.data.type !== MessageType.RETRIEVE_DATA) {
return;
}
const tokenService = await TokenService.getInstance();
if (!services.isPaired()) {
const errorMsg = 'Device not paired';
secureLogger.warn(errorMsg, { component: 'Router' });
// Error handling - no response needed
return;
}
try {
const { processId, stateId, accessToken } = event.data;
if (!accessToken || !(await tokenService.validateToken(accessToken, event.origin))) {
throw new Error('Invalid or expired session token');
}
// Retrieve the state for the process
const process = await services.getProcess(processId);
if (!process) {
throw new Error("Can't find process");
}
const state = services.getStateFromId(process, stateId);
await services.checkConnections(process, stateId);
const res: Record