Replace handleSource by registeringAllListeners
This commit is contained in:
parent
824a0b88f6
commit
eca4d4de85
@ -1,2 +1,4 @@
|
||||
export { default as Services } from './services/service';
|
||||
export { default as Database } from './services/database.service';
|
||||
export { MessageType } from './models/process.model';
|
||||
export type { ProfileData, ProfileMessage } from './models/process.model';
|
||||
|
@ -21,3 +21,77 @@ export interface INotification {
|
||||
sendToNotificationPage?: boolean;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
export enum MessageType {
|
||||
LISTENING = 'LISTENING',
|
||||
REQUEST_LINK = 'REQUEST_LINK',
|
||||
LINK_ACCEPTED = 'LINK_ACCEPTED',
|
||||
CREATE_PROFILE = 'CREATE_PROFILE',
|
||||
PROFILE_CREATED = 'PROFILE_CREATED',
|
||||
CREATE_FOLDER = 'CREATE_FOLDER',
|
||||
FOLDER_CREATED = 'FOLDER_CREATED',
|
||||
RETRIEVE_DATA = 'RETRIEVE_DATA',
|
||||
DATA_RETRIEVED = 'DATA_RETRIEVED',
|
||||
ERROR = 'ERROR',
|
||||
RENEW_TOKEN = 'RENEW_TOKEN',
|
||||
}
|
||||
|
||||
export interface ProfileData {
|
||||
name: string;
|
||||
surname: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
address: string;
|
||||
postalCode: string;
|
||||
city: string;
|
||||
country: string;
|
||||
idDocument?: string;
|
||||
}
|
||||
|
||||
export interface ProfileMessage {
|
||||
type: MessageType.CREATE_PROFILE;
|
||||
data: ProfileData;
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface FolderData {
|
||||
folderNumber: string;
|
||||
name: string;
|
||||
deedType: string;
|
||||
description: string;
|
||||
archived_description: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
customers: string[];
|
||||
documents: string[];
|
||||
motes: string[];
|
||||
stakeholders: string[];
|
||||
}
|
||||
|
||||
export interface FolderMessage {
|
||||
type: MessageType.CREATE_FOLDER;
|
||||
data: FolderData;
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface RetrieveMessage {
|
||||
type: MessageType.RETRIEVE_DATA;
|
||||
processId: string,
|
||||
stateId: string,
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface DecryptedDataMessage {
|
||||
type: MessageType.DATA_RETRIEVED;
|
||||
data: string,
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface TokenData {
|
||||
token: string;
|
||||
origin: string;
|
||||
expiration: number;
|
||||
createdAt: number;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { addSubscription } from '../../utils/subscription.utils';
|
||||
import { displayEmojis, generateQRCode, generateCreateBtn, addressToEmoji} from '../../utils/sp-address.utils';
|
||||
import { getCorrectDOM } from '../../utils/html.utils';
|
||||
import QrScannerComponent from '../../components/qrcode-scanner/qrcode-scanner-component';
|
||||
import { navigate, handleSource } from '../../router';
|
||||
import { navigate, registerAllListeners } from '../../router';
|
||||
|
||||
export { QrScannerComponent };
|
||||
export async function initHomePage(): Promise<void> {
|
||||
@ -29,17 +29,7 @@ export async function initHomePage(): Promise<void> {
|
||||
// Add this line to populate the select when the page loads
|
||||
await populateMemberSelect();
|
||||
|
||||
const endpoint = window.location.pathname;
|
||||
console.log('endpoint', endpoint);
|
||||
|
||||
if (endpoint && endpoint !== '/') {
|
||||
try {
|
||||
await handleSource(endpoint);
|
||||
console.log('handleSource', endpoint);
|
||||
} catch (error) {
|
||||
console.error('Error handling endpoint:', error);
|
||||
}
|
||||
}
|
||||
await registerAllListeners();
|
||||
}
|
||||
|
||||
//// Modal
|
||||
|
360
src/router.ts
360
src/router.ts
@ -3,11 +3,12 @@ import { initHeader } from '../src/components/header/header';
|
||||
/*import { initChat } from '../src/pages/chat/chat';*/
|
||||
import Database from './services/database.service';
|
||||
import Services from './services/service';
|
||||
import TokenService from './services/token';
|
||||
import { cleanSubscriptions } from './utils/subscription.utils';
|
||||
import { LoginComponent } from './pages/home/home-component';
|
||||
import { prepareAndSendPairingTx } from './utils/sp-address.utils';
|
||||
import ModalService from './services/modal.service';
|
||||
export { Services };
|
||||
import { MessageType, ProfileData, FolderData } from './models/process.model';
|
||||
const routes: { [key: string]: string } = {
|
||||
home: '/src/pages/home/home.html',
|
||||
process: '/src/pages/process/process.html',
|
||||
@ -147,14 +148,8 @@ export async function init(): Promise<void> {
|
||||
await services.restoreProcessesFromDB();
|
||||
await services.restoreSecretsFromDB();
|
||||
|
||||
// If we have a service redirection flag, we intercept it here
|
||||
const endpoint = window.location.pathname;
|
||||
|
||||
if (endpoint) {
|
||||
await handleSource(endpoint);
|
||||
} else {
|
||||
console.log('No endpoint provided');
|
||||
}
|
||||
// We register all the event listeners
|
||||
await registerAllListeners();
|
||||
|
||||
if (services.isPaired()) {
|
||||
await navigate('account');
|
||||
@ -167,82 +162,293 @@ export async function init(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleSource(endpoint: string) {
|
||||
export async function registerAllListeners() {
|
||||
const services = await Services.getInstance();
|
||||
|
||||
const errorResponse = (errorMsg: string, origin: string) => {
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: MessageType.ERROR,
|
||||
error: errorMsg
|
||||
},
|
||||
origin
|
||||
);
|
||||
}
|
||||
|
||||
const handleRequestLink = async (event: MessageEvent) => {
|
||||
if (event.data.type !== MessageType.REQUEST_LINK) {
|
||||
return;
|
||||
}
|
||||
const modalService = await ModalService.getInstance();
|
||||
const result = await modalService.showConfirmationModal({
|
||||
title: 'Confirmation de liaison',
|
||||
content: `
|
||||
<div class="modal-confirmation">
|
||||
<h3>Liaison avec ${event.origin}</h3>
|
||||
<p>Vous êtes sur le point de lier l'identité numérique de la clé securisée propre à votre appareil avec ${event.origin}.</p>
|
||||
<p>Cette action permettra à ${event.origin} d'intéragir avec votre appareil.</p>
|
||||
<p>Voulez-vous continuer ?</p>
|
||||
</div>
|
||||
`,
|
||||
confirmText: 'Ajouter un service',
|
||||
cancelText: 'Annuler'
|
||||
});
|
||||
|
||||
try {
|
||||
if (!result) {
|
||||
throw new Error('User refused to link');
|
||||
}
|
||||
|
||||
const tokenService = await TokenService.getInstance();
|
||||
const sessionToken = tokenService.generateSessionToken(event.origin);
|
||||
|
||||
switch (endpoint) {
|
||||
case '/link-service':
|
||||
window.addEventListener('message', async (event: MessageEvent) => {
|
||||
console.log("Received message:", event.data);
|
||||
if (event.data.type === 'REQUEST_LINK') {
|
||||
console.log("Received link request, showing confirmation modal");
|
||||
|
||||
const modalService = await ModalService.getInstance();
|
||||
const result = await modalService.showConfirmationModal({
|
||||
title: 'Confirmation de liaison',
|
||||
content: `
|
||||
<div class="modal-confirmation">
|
||||
<h3>Liaison avec ${event.origin}</h3>
|
||||
<p>Vous êtes sur le point de lier votre identité 4NK avec ${event.origin}.</p>
|
||||
<p>Cette action permettra à ${event.origin} d'intéragir avec votre identité 4NK.</p>
|
||||
<p>Voulez-vous continuer ?</p>
|
||||
</div>
|
||||
`,
|
||||
confirmText: 'Ajouter un service',
|
||||
cancelText: 'Annuler'
|
||||
});
|
||||
if (services.isPaired()) {
|
||||
// Device already paired - just renew token
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: MessageType.RENEW_TOKEN,
|
||||
sessionToken
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} else {
|
||||
// New device - do pairing process
|
||||
await prepareAndSendPairingTx();
|
||||
await services.confirmPairing();
|
||||
const neuteredDevice = services.dumpNeuteredDevice();
|
||||
|
||||
if (!neuteredDevice) {
|
||||
throw new Error('Failed to get neutered device');
|
||||
}
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: MessageType.LINK_ACCEPTED,
|
||||
payload: JSON.stringify(neuteredDevice),
|
||||
sessionToken
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMsg = `Failed to link service: ${error}`;
|
||||
errorResponse(errorMsg, event.origin);
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
try {
|
||||
if (!services.isPaired()) {
|
||||
await prepareAndSendPairingTx();
|
||||
await services.confirmPairing();
|
||||
}
|
||||
const handleAddProfile = async (event: MessageEvent) => {
|
||||
if (event.data.type !== MessageType.CREATE_PROFILE) {
|
||||
return;
|
||||
}
|
||||
const tokenService = await TokenService.getInstance();
|
||||
const services = await Services.getInstance();
|
||||
|
||||
const neuteredDevice = services.dumpNeuteredDevice();
|
||||
if (neuteredDevice) {
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: 'RESPONSE',
|
||||
success: true,
|
||||
payload: JSON.stringify(neuteredDevice)
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} else {
|
||||
throw new Error('Failed to get a neutered device');
|
||||
}
|
||||
} catch (error) {
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: 'RESPONSE',
|
||||
success: false,
|
||||
error: 'Failed to complete pairing process'
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// The user canceled the link request
|
||||
console.log("User canceled the linking process");
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: 'RESPONSE',
|
||||
success: false,
|
||||
error: 'User canceled linking'
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
if (!services.isPaired()) {
|
||||
const errorMsg = 'Device not paired';
|
||||
errorResponse(errorMsg, event.origin);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { profileData, token } = event.data;
|
||||
|
||||
// Validate the session token
|
||||
if (!token || !tokenService.validateToken(token, event.origin)) {
|
||||
throw new Error('Invalid or expired session token');
|
||||
}
|
||||
|
||||
// Create profile
|
||||
await services.createAndSendProfileTx(profileData);
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: MessageType.PROFILE_CREATED,
|
||||
token // Resend the same token
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} catch (e) {
|
||||
const errorMsg = `Failed to create profile: ${e}`;
|
||||
errorResponse(errorMsg, event.origin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handleAddFolder = async (event: MessageEvent) => {
|
||||
if (event.data.type !== MessageType.CREATE_FOLDER) {
|
||||
return;
|
||||
}
|
||||
const tokenService = await TokenService.getInstance();
|
||||
const services = await Services.getInstance();
|
||||
|
||||
if (!services.isPaired()) {
|
||||
const errorMsg = 'Device not paired';
|
||||
errorResponse(errorMsg, event.origin);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { data, token } = event.data;
|
||||
|
||||
if (!token || !tokenService.validateToken(token, event.origin)) {
|
||||
throw new Error('Invalid or expired session token');
|
||||
}
|
||||
|
||||
await services.createAndSendFolderTx(data);
|
||||
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: MessageType.FOLDER_CREATED,
|
||||
token
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} catch (e) {
|
||||
const errorMsg = `Failed to create folder: ${e}`;
|
||||
errorResponse(errorMsg, event.origin);
|
||||
}
|
||||
}
|
||||
|
||||
/// 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();
|
||||
const services = await Services.getInstance();
|
||||
|
||||
if (!services.isPaired()) {
|
||||
const errorMsg = 'Device not paired';
|
||||
errorResponse(errorMsg, event.origin);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { processId, stateId, token } = event.data;
|
||||
|
||||
if (!token || !tokenService.validateToken(token, event.origin)) {
|
||||
throw new Error('Invalid or expired session token');
|
||||
}
|
||||
|
||||
// Retrieve the state for the process
|
||||
const process = await services.getProcess(processId);
|
||||
const state = services.getStateFromId(process, stateId);
|
||||
|
||||
let res: Record<string, string> = {};
|
||||
if (state) {
|
||||
// Decrypt all the data we have the key for
|
||||
for (const attribute of Object.keys(state.pcd_commitment)) {
|
||||
const decryptedAttribute = await services.decryptAttribute(processId, state, attribute);
|
||||
if (decryptedAttribute) {
|
||||
res[attribute] = decryptedAttribute;
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log('sending message from link-service');
|
||||
window.parent.postMessage({ type: 'LISTENING', endpoint: endpoint }, '*');
|
||||
break;
|
||||
} else {
|
||||
throw new Error('Unknown state for process', processId);
|
||||
}
|
||||
|
||||
default:
|
||||
console.log('Unknown endpoint:', endpoint);
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: MessageType.DATA_RETRIEVED,
|
||||
data: JSON.stringify(res),
|
||||
token
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} catch (e) {
|
||||
const errorMsg = `Failed to retrieve data: ${e}`;
|
||||
errorResponse(errorMsg, event.origin);
|
||||
}
|
||||
}
|
||||
|
||||
const handleGetProfile = async (event: MessageEvent) => {
|
||||
if (event.data.type !== MessageType.RETRIEVE_DATA) {
|
||||
return;
|
||||
}
|
||||
const tokenService = await TokenService.getInstance();
|
||||
const services = await Services.getInstance();
|
||||
|
||||
if (!services.isPaired()) {
|
||||
const errorMsg = 'Device not paired';
|
||||
errorResponse(errorMsg, event.origin);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('📥 [GetProfile] Réception de la demande');
|
||||
const { sessionToken } = event.data;
|
||||
|
||||
if (!sessionToken || !tokenService.validateToken(sessionToken, event.origin)) {
|
||||
throw new Error('Invalid or expired session token');
|
||||
}
|
||||
|
||||
console.log('🔍 [GetProfile] Récupération des profils');
|
||||
const processes = await services.getProcesses();
|
||||
console.log('Processes après résolution:', processes);
|
||||
|
||||
let decryptedData: Record<string, string> = {};
|
||||
|
||||
const processArray = Array.isArray(processes) ? processes : Object.values(processes);
|
||||
|
||||
if (processArray && processArray.length > 0) {
|
||||
console.log(`📋 Traitement de ${processArray.length} processus`);
|
||||
|
||||
for (const process of processArray) {
|
||||
try {
|
||||
console.log('Process en cours:', process);
|
||||
if (process && process.id && !process.certified) {
|
||||
console.log(`🔄 Traitement du processus non certifié ${process.id}`);
|
||||
const states = process.states;
|
||||
|
||||
if (states && states.length > 0) {
|
||||
for (const state of states) {
|
||||
if (state && state.pcd_commitment) {
|
||||
console.log(`📝 Attributs trouvés dans l'état:`, Object.keys(state.pcd_commitment));
|
||||
for (const attribute of Object.keys(state.pcd_commitment)) {
|
||||
try {
|
||||
const decryptedValue = await services.decryptAttribute(process.id, state, attribute);
|
||||
if (decryptedValue) {
|
||||
decryptedData[attribute] = decryptedValue;
|
||||
console.log(`✅ Attribut déchiffré: ${attribute} = ${decryptedValue}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ Échec du déchiffrement de ${attribute}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (processError) {
|
||||
console.error(`❌ Erreur lors du traitement du processus:`, processError);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn('❌ Aucun processus trouvé ou tableau vide');
|
||||
}
|
||||
|
||||
console.log('📤 [GetProfile] Données déchiffrées:', decryptedData);
|
||||
window.parent.postMessage(
|
||||
{
|
||||
type: MessageType.DATA_RETRIEVED,
|
||||
data: decryptedData,
|
||||
sessionToken
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} catch (e) {
|
||||
console.error('❌ Erreur:', e);
|
||||
errorResponse(`Failed to get profile: ${e}`, event.origin);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', handleRequestLink);
|
||||
window.addEventListener('message', handleAddProfile);
|
||||
window.addEventListener('message', handleAddFolder);
|
||||
window.addEventListener('message', handleDecryptState);
|
||||
window.addEventListener('message', handleGetProfile);
|
||||
|
||||
window.parent.postMessage({ type: 'LISTENING' }, '*');
|
||||
}
|
||||
|
||||
async function cleanPage() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user