diff --git a/app/dashboard/folders/page.tsx b/app/dashboard/folders/page.tsx index 05728fc..0b6429a 100644 --- a/app/dashboard/folders/page.tsx +++ b/app/dashboard/folders/page.tsx @@ -351,39 +351,45 @@ export default function FoldersPage() { }, []); useEffect(() => { - if (isConnected) { + const handleConnectionFlow = async () => { + if (!isConnected) return; + + const userStore = UserStore.getInstance(); const messageBus = MessageBus.getInstance(iframeUrl); - messageBus.isReady().then(() => { - messageBus.getProcesses().then((processes: any) => { - setProcesses(processes); - }); - }); - } + + try { + await messageBus.isReady(); + + let pairingId = userStore.getUserPairingId(); + + // 1️⃣ Créer le pairing si non existant + if (!pairingId) { + console.log("🚀 No pairing found — creating new pairing..."); + pairingId = await messageBus.createUserPairing(); + console.log("✅ Pairing created:", pairingId); + + userStore.pair(pairingId); + setUserPairingId(pairingId); + } else { + console.log("🔗 Already paired with ID:", pairingId); + } + + // 2️⃣ Charger les processes + const processes = await messageBus.getProcesses(); + setProcesses(processes); + + // 3️⃣ Charger les myProcesses + const myProcesses = await messageBus.getMyProcesses(); + setMyProcesses(myProcesses); + + } catch (err) { + console.error("❌ Error during pairing or process loading:", err); + } + }; + + handleConnectionFlow(); }, [isConnected, iframeUrl]); - useEffect(() => { - if (isConnected && processes !== null) { - const messageBus = MessageBus.getInstance(iframeUrl); - messageBus.isReady().then(() => { - messageBus.getMyProcesses().then((res: string[]) => { - setMyProcesses(res); - }) - }); - } - }, [isConnected, processes]); - - useEffect(() => { - if (isConnected && userPairingId === null) { - const messageBus = MessageBus.getInstance(iframeUrl); - messageBus.isReady().then(() => { - messageBus.getUserPairingId().then((userPairingId: string) => { - UserStore.getInstance().pair(userPairingId); - setUserPairingId(UserStore.getInstance().getUserPairingId()); - }) - }); - } - }, [isConnected, userPairingId, processes]); - useEffect(() => { // Simuler le chargement des dossiers const loadFolders = () => { diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index a2b01e4..884922a 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -282,39 +282,45 @@ export default function DashboardPage() { }, []); useEffect(() => { - if (isConnected) { + const handleConnectionFlow = async () => { + if (!isConnected) return; + + const userStore = UserStore.getInstance(); const messageBus = MessageBus.getInstance(iframeUrl); - messageBus.isReady().then(() => { - messageBus.getProcesses().then((processes: any) => { - setProcesses(processes); - }); - }); - } + + try { + await messageBus.isReady(); + + let pairingId = userStore.getUserPairingId(); + + // 1️⃣ Créer le pairing si non existant + if (!pairingId) { + console.log("🚀 No pairing found — creating new pairing..."); + pairingId = await messageBus.createUserPairing(); + console.log("✅ Pairing created:", pairingId); + + userStore.pair(pairingId); + setUserPairingId(pairingId); + } else { + console.log("🔗 Already paired with ID:", pairingId); + } + + // 2️⃣ Charger les processes + const processes = await messageBus.getProcesses(); + setProcesses(processes); + + // 3️⃣ Charger les myProcesses + const myProcesses = await messageBus.getMyProcesses(); + setMyProcesses(myProcesses); + + } catch (err) { + console.error("❌ Error during pairing or process loading:", err); + } + }; + + handleConnectionFlow(); }, [isConnected, iframeUrl]); - useEffect(() => { - if (isConnected && processes !== null) { - const messageBus = MessageBus.getInstance(iframeUrl); - messageBus.isReady().then(() => { - messageBus.getMyProcesses().then((res: string[]) => { - setMyProcesses(res); - }) - }); - } - }, [isConnected, processes]); - - useEffect(() => { - if (isConnected && userPairingId === null) { - const messageBus = MessageBus.getInstance(iframeUrl); - messageBus.isReady().then(() => { - messageBus.getUserPairingId().then((userPairingId: string) => { - UserStore.getInstance().pair(userPairingId); - setUserPairingId(UserStore.getInstance().getUserPairingId()); - }) - }); - } - }, [isConnected, userPairingId, processes]); - const handleOpenModal = (type: FolderType) => { setFolderType(type); setIsModalOpen(true); diff --git a/app/page.tsx b/app/page.tsx index 6be2e6d..1a6d33f 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -20,7 +20,6 @@ export default function HomePage() { setIsConnected(true); setShowAuthModal(false); router.push("/dashboard") - console.log('Auth Connect - Connexion établie, le useEffect se chargera de récupérer le userPairingId'); }, []); const handleAuthClose = useCallback(() => { diff --git a/lib/4nk/MessageBus.ts b/lib/4nk/MessageBus.ts index 59059fe..562c415 100644 --- a/lib/4nk/MessageBus.ts +++ b/lib/4nk/MessageBus.ts @@ -1,7 +1,6 @@ import IframeReference from './IframeReference'; import EventBus from './EventBus'; import UserStore from './UserStore'; -import { isProfileData, type ProfileCreated, type ProfileData } from './models/ProfileData'; import { isFolderData, type FolderCreated, type FolderData } from './models/FolderData'; import { v4 as uuidv4 } from 'uuid'; import type { RoleDefinition } from './models/Roles'; @@ -81,6 +80,48 @@ export default class MessageBus { }); } + public createUserPairing(): Promise { + return new Promise((resolve, reject) => { + this.checkToken().then(async () => { + const userStore = UserStore.getInstance(); + const accessToken = userStore.getAccessToken(); + if (!accessToken) { + return reject('No access token found'); + } + + const correlationId = uuidv4(); + this.initMessageListener(correlationId); + + // ✅ Success listener + const unsubscribeSuccess = EventBus.getInstance().on('PAIRING_CREATED', (responseId: string, pairingId: string) => { + if (responseId !== correlationId) return; + unsubscribeSuccess(); + unsubscribeError(); + this.destroyMessageListener(); + resolve(pairingId); + }); + + // ❌ Error listener + const unsubscribeError = EventBus.getInstance().on('ERROR_CREATE_PAIRING', (responseId: string, error: string) => { + if (responseId !== correlationId) return; + unsubscribeError(); + unsubscribeSuccess(); + this.destroyMessageListener(); + reject(error); + }); + + // 📨 Send CREATE_PAIRING message to iframe + this.sendMessage({ + type: 'CREATE_PAIRING', + accessToken, + messageId: correlationId, + }); + }).catch((err) => { + reject(`Failed to validate token before pairing: ${err}`); + }); + }); + } + public getUserPairingId(): Promise { return new Promise((resolve: (userPairingId: string) => void, reject: (error: string) => void) => { this.checkToken().then(() => { @@ -337,61 +378,6 @@ export default class MessageBus { }); } - public createProfile(profileData: ProfileData, profilePrivateData: string[], roles: Record): Promise { - return new Promise((resolve: (profileCreated: ProfileCreated) => void, reject: (error: string) => void) => { - this.checkToken().then(() => { - const userStore = UserStore.getInstance(); - const accessToken = userStore.getAccessToken()!; - - const correlationId = uuidv4(); - this.initMessageListener(correlationId); - - const unsubscribe = EventBus.getInstance().on('PROCESS_CREATED', (responseId: string, processCreated: any) => { - if (responseId !== correlationId) { - return; - } - unsubscribe(); - this.destroyMessageListener(); - // Return value must contain the data commited in the new process - const profileData = processCreated.processData; - if (!profileData || !isProfileData(profileData)) { - reject('Returned invalid profile data'); - } - if (!processCreated.processId || typeof processCreated.processId !== 'string') { - console.error('Returned invalid process id'); - reject('Returned invalid process id'); - } - // TODO check that process is of type Process - - const profileCreated: ProfileCreated = { - processId: processCreated.processId, - process: processCreated.process, - profileData - }; - - resolve(profileCreated); - }); - - const unsubscribeError = EventBus.getInstance().on('ERROR_PROCESS_CREATED', (responseId: string, error: string) => { - if (responseId !== correlationId) { - return; - } - unsubscribeError(); - this.destroyMessageListener(); - reject(error); - }); - - this.sendMessage({ - type: 'CREATE_PROCESS', - processData: profileData, - privateFields: profilePrivateData, - roles, - accessToken - }); - }).catch(console.error); - }); - } - public createFolder(folderData: FolderData, folderPrivateData: string[], roles: Record): Promise { return new Promise((resolve: (folderData: FolderCreated) => void, reject: (error: string) => void) => { this.checkToken().then(() => { @@ -626,7 +612,7 @@ export default class MessageBus { console.error('[MessageBus] sendMessage: iframe not found'); return; } - + console.log('[MessageBus] sendMessage:', message, 'to', this.origin); iframe.contentWindow?.postMessage(message, this.origin); } @@ -714,7 +700,7 @@ export default class MessageBus { EventBus.getInstance().emit('PROCESSES_RETRIEVED', correlationId, message.processes); break; - case 'GET_MY_PROCESSES': + case 'GET_MY_PROCESSES': if (this.errors[correlationId]) { const error = this.errors[correlationId]; delete this.errors[correlationId]; @@ -756,7 +742,7 @@ export default class MessageBus { EventBus.getInstance().emit('MESSAGE_RECEIVED', message); EventBus.getInstance().emit('UPDATE_NOTIFIED', correlationId); break; - + case 'STATE_VALIDATED': if (this.errors[correlationId]) { const error = this.errors[correlationId]; @@ -789,7 +775,18 @@ export default class MessageBus { EventBus.getInstance().emit('MESSAGE_RECEIVED', message); EventBus.getInstance().emit('PUBLIC_DATA_DECODED', correlationId, message.decodedData); break; - + + case 'PAIRING_CREATED': + if (this.errors[correlationId]) { + const error = this.errors[correlationId]; + delete this.errors[correlationId]; + EventBus.getInstance().emit('ERROR_PAIRING_CREATED', correlationId, error); + return; + } + EventBus.getInstance().emit('MESSAGE_RECEIVED', message); + EventBus.getInstance().emit('PAIRING_CREATED', correlationId, message.decodedData); + break; + case 'ERROR': console.error('Error:', message); this.errors[correlationId] = message.error;