aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js15
1 files changed, 12 insertions, 3 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js b/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
index 3d56f69..5c6adef 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport-devices.js
@@ -227,15 +227,24 @@ extendTransport(class {
const listed = await this._sendAndWait({ type: 'device_lookup', v: '0.1' });
if (listed.type === 'error') throw new Error(listed.detail || 'Not found');
- let match = null;
+ // Every match, not the first: a request is filed with the account's token
+ // alone, so somebody holding the passphrase who saw the code on screen can
+ // file a second one with the same code and keys of their own. Neither is
+ // approved then — the person's device asks again, with a new code.
+ const matches = [];
for (const req of listed.requests || []) {
const expect = await C.deviceCodeHash(
normalized, req.pk_ed25519, req.pk_x25519);
- if (expect === req.code_hash) { match = req; break; }
+ if (expect === req.code_hash) matches.push(req);
}
- if (!match) {
+ if (!matches.length) {
throw new Error('No device is waiting with that code');
}
+ if (matches.length > 1) {
+ throw new Error('More than one device is waiting with that code, so none was '
+ + 'approved. Get a new code on the device you are linking.');
+ }
+ const match = matches[0];
return this._countersign(userId, match.code_hash,
match.pk_ed25519, match.pk_x25519);
}