Add device basic flow
This commit is contained in:
parent
5a98fac745
commit
a467c45401
181
src/router.ts
181
src/router.ts
@ -159,6 +159,62 @@ export async function init(): Promise<void> {
|
|||||||
if (services.isPaired()) {
|
if (services.isPaired()) {
|
||||||
await navigate('account');
|
await navigate('account');
|
||||||
} else {
|
} else {
|
||||||
|
// Check for device addition URL parameter
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const addToId = urlParams.get('add_to_id');
|
||||||
|
|
||||||
|
if (addToId) {
|
||||||
|
try {
|
||||||
|
// This is a new device trying to join an existing pairing process
|
||||||
|
const pairingProcess = await services.getProcess(addToId);
|
||||||
|
console.debug(pairingProcess);
|
||||||
|
if (!pairingProcess) throw new Error('Non existent process'); // We were given a non existent process
|
||||||
|
const lastCommitedState = services.getLastCommitedState(pairingProcess!);
|
||||||
|
if (!lastCommitedState) throw new Error('Uncommited process'); // We were given an uncommited process
|
||||||
|
console.debug(lastCommitedState);
|
||||||
|
const currentPairedAddresses = lastCommitedState?.public_data['pairedAddresses'];
|
||||||
|
if (!currentPairedAddresses) throw new Error('Not a pairing process'); // We were given probably not a pairing process
|
||||||
|
const decodedAddresses = services.decodeValue(currentPairedAddresses!);
|
||||||
|
console.debug(decodedAddresses);
|
||||||
|
const modalService = await ModalService.getInstance();
|
||||||
|
const result = await modalService.showConfirmationModal({
|
||||||
|
title: 'Ajout d\'appareil',
|
||||||
|
content: `
|
||||||
|
<div class="modal-confirmation">
|
||||||
|
<h3>Ajouter cet appareil à votre compte</h3>
|
||||||
|
<p>Vous êtes sur le point d'ajouter cet appareil à votre compte existant.</p>
|
||||||
|
<p>Cette action permettra à cet appareil d'accéder à vos données et processus.</p>
|
||||||
|
<p>Voulez-vous continuer ?</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
confirmText: 'Ajouter l\'appareil',
|
||||||
|
cancelText: 'Annuler'
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
console.log('User refused to add device');
|
||||||
|
await navigate('home');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const myAddress = services.getDeviceAddress();
|
||||||
|
const updatedPairedAddresses = [...decodedAddresses, myAddress];
|
||||||
|
const updateProcessReturn = await services.updateProcess(pairingProcess!, {}, { pairedAddresses: updatedPairedAddresses }, null);
|
||||||
|
await services.handleApiReturn(updateProcessReturn);
|
||||||
|
// Now make the prd update and approve the change
|
||||||
|
const newStateId = updateProcessReturn.updated_process!.diffs[0].state_id;
|
||||||
|
console.debug(newStateId);
|
||||||
|
const prdUpdateReturn = await services.createPrdUpdate(addToId, newStateId);
|
||||||
|
await services.handleApiReturn(prdUpdateReturn);
|
||||||
|
const approveChangeReturn = await services.approveChange(addToId, newStateId); //Actually useless since this device is not a member of the process
|
||||||
|
await services.handleApiReturn(approveChangeReturn);
|
||||||
|
await navigate('account');
|
||||||
|
return;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
await navigate('home');
|
||||||
|
}
|
||||||
|
}
|
||||||
await navigate('home');
|
await navigate('home');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -781,6 +837,125 @@ export async function registerAllListeners() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleGetMemberAddresses = async (event: MessageEvent) => {
|
||||||
|
if (event.data.type !== MessageType.GET_MEMBER_ADDRESSES) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { accessToken, processId } = event.data;
|
||||||
|
|
||||||
|
if (!accessToken || !(await tokenService.validateToken(accessToken, event.origin))) {
|
||||||
|
throw new Error('Invalid or expired session token');
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = services.getAddressesForMemberId(processId);
|
||||||
|
|
||||||
|
window.parent.postMessage(
|
||||||
|
{
|
||||||
|
type: MessageType.MEMBER_ADDRESSES_RETRIEVED,
|
||||||
|
memberAddresses: res,
|
||||||
|
messageId: event.data.messageId
|
||||||
|
},
|
||||||
|
event.origin
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
const errorMsg = `Failed to get member addresses: ${e}`;
|
||||||
|
errorResponse(errorMsg, event.origin, event.data.messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddDevice = async (event: MessageEvent) => {
|
||||||
|
if (event.data.type !== MessageType.ADD_DEVICE) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { accessToken } = event.data;
|
||||||
|
|
||||||
|
if (!accessToken || !(await tokenService.validateToken(accessToken, event.origin))) {
|
||||||
|
throw new Error('Invalid or expired session token');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current device address for the pairing URL
|
||||||
|
const myPairingProcessId = services.getPairingProcessId();
|
||||||
|
const currentUrl = window.location.origin;
|
||||||
|
const pairingUrl = `${currentUrl}?add_to_id=${myPairingProcessId}`;
|
||||||
|
|
||||||
|
// TODO get the current number of devices
|
||||||
|
|
||||||
|
const modalService = await ModalService.getInstance();
|
||||||
|
const result = await modalService.showConfirmationModal({
|
||||||
|
title: 'Ajout d\'un nouvel appareil',
|
||||||
|
content: `
|
||||||
|
<div class="modal-confirmation">
|
||||||
|
<h3>Ajouter un nouvel appareil</h3>
|
||||||
|
<p>Pour ajouter un nouvel appareil à votre compte, partagez l'URL suivante avec le nouvel appareil :</p>
|
||||||
|
<div style="margin: 15px 0; padding: 10px; background-color: #f5f5f5; border-radius: 4px; word-break: break-all; font-family: monospace; font-size: 12px;">
|
||||||
|
${pairingUrl}
|
||||||
|
</div>
|
||||||
|
<p><small>Gardez cette URL secrète, elle permettra à l'appareil de se connecter à votre compte.</small></p>
|
||||||
|
<p>Ou scannez ce QR code avec le nouvel appareil :</p>
|
||||||
|
<div style="text-align: center; margin: 15px 0;">
|
||||||
|
<img src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(pairingUrl)}"
|
||||||
|
alt="QR Code pour l'ajout d'appareil"
|
||||||
|
style="border: 1px solid #ddd; border-radius: 4px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
confirmText: 'Terminer',
|
||||||
|
cancelText: 'Annuler'
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
throw new Error('User cancelled device addition');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the pairing process to be updated with the new device
|
||||||
|
const maxWaitTime = 300000; // 5 minutes
|
||||||
|
const pollInterval = 2000; // 2 seconds
|
||||||
|
const startTime = Date.now();
|
||||||
|
let deviceAdded = false;
|
||||||
|
|
||||||
|
while (Date.now() - startTime < maxWaitTime && !deviceAdded) {
|
||||||
|
console.debug('Polling for device addition');
|
||||||
|
try {
|
||||||
|
const pairingProcess = await services.getProcess(myPairingProcessId);
|
||||||
|
if (pairingProcess) {
|
||||||
|
const uncommitedStates = services.getUncommitedStates(pairingProcess);
|
||||||
|
for (const state of uncommitedStates) {
|
||||||
|
const pairedAddresses = state.public_data['pairedAddresses'];
|
||||||
|
if (pairedAddresses) {
|
||||||
|
const decodedAddresses = services.decodeValue(pairedAddresses);
|
||||||
|
if (decodedAddresses.length > 1) {
|
||||||
|
console.log('New device detected in pairing process');
|
||||||
|
deviceAdded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('Process not found');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Error while polling for device addition:', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
||||||
|
}
|
||||||
|
|
||||||
|
window.parent.postMessage(
|
||||||
|
{
|
||||||
|
type: MessageType.DEVICE_ADDED,
|
||||||
|
pairingUrl: pairingUrl,
|
||||||
|
deviceAdded: deviceAdded,
|
||||||
|
messageId: event.data.messageId
|
||||||
|
},
|
||||||
|
event.origin
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
const errorMsg = `Failed to add device: ${e}`;
|
||||||
|
errorResponse(errorMsg, event.origin, event.data.messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window.removeEventListener('message', handleMessage);
|
window.removeEventListener('message', handleMessage);
|
||||||
window.addEventListener('message', handleMessage);
|
window.addEventListener('message', handleMessage);
|
||||||
|
|
||||||
@ -832,6 +1007,12 @@ export async function registerAllListeners() {
|
|||||||
case MessageType.VALIDATE_MERKLE_PROOF:
|
case MessageType.VALIDATE_MERKLE_PROOF:
|
||||||
await handleValidateMerkleProof(event);
|
await handleValidateMerkleProof(event);
|
||||||
break;
|
break;
|
||||||
|
case MessageType.GET_MEMBER_ADDRESSES:
|
||||||
|
await handleGetMemberAddresses(event);
|
||||||
|
break;
|
||||||
|
case MessageType.ADD_DEVICE:
|
||||||
|
await handleAddDevice(event);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.warn(`Unhandled message type: ${event.data.type}`);
|
console.warn(`Unhandled message type: ${event.data.type}`);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user