OverviewFilesCommitsIssuesDocsReleasesPeers

favela-host commits / 083ee24

0.1.3: honour the designated credential — hpp's byDid is a Map
pickNode indexed hpp.byDid like an object, but bootMultiDevice returns a Map (device-node.js:879), so a designated credential never matched: after the operator designated wj62 on tabertron (two DIDs, bsky on) every pass still refused — now visibly, thanks to 0.1.2. The existing test built byDid as a plain object, a shape hpp never returns; the new one uses a Map (red first). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
083ee244d35552f276dc4abdc9c0473ffaac5e44
by plankatron <fleeky@gmail.com> · 2026-10-13T18:12:23.000Z

Changed files (4) +22 -4

lib/project.js +6 -1
……@@ -114,7 +114,12 @@ export function peerClient (node) {
114114export function pickNode (hpp, credential = null) {
115115 const nodes = (hpp && hpp.nodes) || []
116116 if (nodes.length === 0) return { node: null, error: 'this device has no booted atproto identity' }
117 if (credential && hpp.byDid && hpp.byDid[credential]) return { node: hpp.byDid[credential], error: null }
117 // ⛔ hpp returns `byDid` as a MAP (device-node.js:879). Indexing it like an object never matched, so a
118 // designated credential was ignored and a two-DID node refused every pass (tabertron, 2026-10-13).
119 const designated = credential && hpp.byDid
120 ? (typeof hpp.byDid.get === 'function' ? hpp.byDid.get(credential) : hpp.byDid[credential])
121 : null
122 if (designated) return { node: designated, error: null }
118123 if (nodes.length === 1) return { node: nodes[0], error: null }
119124 return { node: null, error: 'this device holds several identities and none is designated — choose one in settings' }
120125}
package-lock.json +2 -2
……@@ -1,12 +1,12 @@
11{
22 "name": "favela-host",
3 "version": "0.1.2",
3 "version": "0.1.3",
44 "lockfileVersion": 3,
55 "requires": true,
66 "packages": {
77 "": {
88 "name": "favela-host",
9 "version": "0.1.2",
9 "version": "0.1.3",
1010 "dependencies": {
1111 "anproto": "file:../anproto",
1212 "atproto-identity": "file:../atproto-identity",
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "favela-host",
3 "version": "0.1.2",
3 "version": "0.1.3",
44 "description": "THE favela app on a desktop, home node or server: a favela-peer node, favela-surface rendering it, the atproto signer and the bsky projection, in one process.",
55 "type": "module",
66 "main": "index.js",
test/project.test.js +13 -0
……@@ -83,3 +83,16 @@ test('★★★ with several identities and none designated it refuses rather th
8383 t.is(pickNode({ nodes: [a], byDid: { 'did:plc:aaa': a } }, null).node, a, 'one identity needs no designation')
8484 t.ok(/no booted atproto identity/.test(pickNode({ nodes: [] }, null).error), 'and none is said plainly')
8585})
86
87// ⛔ hpp's bootMultiDevice returns `byDid` as a MAP (device-node.js:879). pickNode indexed it like an
88// object, so a designated credential never matched and a node with two DIDs refused every pass even after
89// the operator designated one (tabertron, 2026-10-13).
90test('pickNode honours the designated credential when byDid is a Map, as hpp returns it', async (t) => {
91 const a = { did: 'did:plc:aaa' }
92 const b = { did: 'did:plc:bbb' }
93 const hpp = { nodes: [a, b], byDid: new Map([[a.did, a], [b.did, b]]) }
94 const r = pickNode(hpp, 'did:plc:bbb')
95 t.is(r.error, null)
96 t.is(r.node, b, 'the designated identity, not a refusal')
97 t.ok(pickNode(hpp, null).error, 'still refuses with several and none designated')
98})