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()) {
|
||||
await navigate('account');
|
||||
} 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');
|
||||
}
|
||||
} 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.addEventListener('message', handleMessage);
|
||||
|
||||
@ -832,6 +1007,12 @@ export async function registerAllListeners() {
|
||||
case MessageType.VALIDATE_MERKLE_PROOF:
|
||||
await handleValidateMerkleProof(event);
|
||||
break;
|
||||
case MessageType.GET_MEMBER_ADDRESSES:
|
||||
await handleGetMemberAddresses(event);
|
||||
break;
|
||||
case MessageType.ADD_DEVICE:
|
||||
await handleAddDevice(event);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unhandled message type: ${event.data.type}`);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user