fedipod-server 0.13.1 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -145,8 +145,13 @@ export async function handle(api, ctx) {
145
145
  if (acct === cfg?.handle || acct === `${cfg?.handle}@${api.host}`) {
146
146
  return send(200, api.selfAccount());
147
147
  }
148
+ // By host with its port, as the account is shown; and by hostname alone,
149
+ // for a client that drops the port from an address it was given.
148
150
  const hit = Object.entries(api.store.getActors()).find(([u, a]) => {
149
- try { return `${a.preferredUsername}@${new URL(u).host}` === acct; } catch { return false; }
151
+ try {
152
+ const at = new URL(u);
153
+ return `${a.preferredUsername}@${at.host}` === acct || `${a.preferredUsername}@${at.hostname}` === acct;
154
+ } catch { return false; }
150
155
  });
151
156
  return hit ? send(200, api.account(hit[0])) : send(404, { error: 'Record not found' });
152
157
  }
@@ -502,5 +502,34 @@ export class PodStore {
502
502
  this.cache.set('ids.json', ids);
503
503
  return id;
504
504
  }
505
- urlFor(id) { return this.getIds()[id] || null; }
505
+ // The map first, for ids minted under an older scheme. Then, because the
506
+ // id IS the hash of the url, whatever this store knows is scanned for the
507
+ // url that hashes to it — actors, posts, contacts, requests, media. The
508
+ // browser build's worker is stopped whenever it idles, and the in-memory
509
+ // map went with it: a client clicking an account it had just been shown
510
+ // reached a fresh worker that held the actor and could not name it.
511
+ urlFor(id) {
512
+ const ids = this.getIds();
513
+ if (ids[id]) return ids[id];
514
+ if (!/^[a-f0-9]{16}$/u.test(String(id))) return null;
515
+ const hash = (u) => crypto.createHash('sha256').update(u).digest('hex').slice(0, 16);
516
+ const seen = new Set();
517
+ const candidates = function* (store) {
518
+ for (const u of Object.keys(store.getActors())) yield u;
519
+ for (const st of store.getStatuses()) {
520
+ yield st.noteId; yield st.actor;
521
+ for (const a of st.attachments || []) if (a?.url) yield a.url;
522
+ }
523
+ const c = store.getContacts();
524
+ for (const f of [...c.followers, ...c.following]) if (f?.actor) yield f.actor;
525
+ for (const r of store.getRequests()) if (r?.actor) yield r.actor;
526
+ for (const u of Object.keys(store.getMedia())) yield u;
527
+ };
528
+ for (const u of candidates(this)) {
529
+ if (typeof u !== 'string' || seen.has(u)) continue;
530
+ seen.add(u);
531
+ if (hash(u) === id) { ids[id] = u; this.cache.set('ids.json', ids); return u; }
532
+ }
533
+ return null;
534
+ }
506
535
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fedipod-server",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "The FediPod Server: a full ActivityPub server as a Community Solid Server component.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -34555,8 +34555,40 @@ var PodStore = class {
34555
34555
  this.cache.set("ids.json", ids);
34556
34556
  return id;
34557
34557
  }
34558
+ // The map first, for ids minted under an older scheme. Then, because the
34559
+ // id IS the hash of the url, whatever this store knows is scanned for the
34560
+ // url that hashes to it — actors, posts, contacts, requests, media. The
34561
+ // browser build's worker is stopped whenever it idles, and the in-memory
34562
+ // map went with it: a client clicking an account it had just been shown
34563
+ // reached a fresh worker that held the actor and could not name it.
34558
34564
  urlFor(id) {
34559
- return this.getIds()[id] || null;
34565
+ const ids = this.getIds();
34566
+ if (ids[id]) return ids[id];
34567
+ if (!/^[a-f0-9]{16}$/u.test(String(id))) return null;
34568
+ const hash = (u) => node_crypto_default.createHash("sha256").update(u).digest("hex").slice(0, 16);
34569
+ const seen = /* @__PURE__ */ new Set();
34570
+ const candidates = function* (store) {
34571
+ for (const u of Object.keys(store.getActors())) yield u;
34572
+ for (const st2 of store.getStatuses()) {
34573
+ yield st2.noteId;
34574
+ yield st2.actor;
34575
+ for (const a of st2.attachments || []) if (a?.url) yield a.url;
34576
+ }
34577
+ const c = store.getContacts();
34578
+ for (const f of [...c.followers, ...c.following]) if (f?.actor) yield f.actor;
34579
+ for (const r of store.getRequests()) if (r?.actor) yield r.actor;
34580
+ for (const u of Object.keys(store.getMedia())) yield u;
34581
+ };
34582
+ for (const u of candidates(this)) {
34583
+ if (typeof u !== "string" || seen.has(u)) continue;
34584
+ seen.add(u);
34585
+ if (hash(u) === id) {
34586
+ ids[id] = u;
34587
+ this.cache.set("ids.json", ids);
34588
+ return u;
34589
+ }
34590
+ }
34591
+ return null;
34560
34592
  }
34561
34593
  };
34562
34594
 
@@ -65431,7 +65463,8 @@ async function handle4(api, ctx) {
65431
65463
  }
65432
65464
  const hit = Object.entries(api.store.getActors()).find(([u, a]) => {
65433
65465
  try {
65434
- return `${a.preferredUsername}@${new URL(u).host}` === acct;
65466
+ const at = new URL(u);
65467
+ return `${a.preferredUsername}@${at.host}` === acct || `${a.preferredUsername}@${at.hostname}` === acct;
65435
65468
  } catch {
65436
65469
  return false;
65437
65470
  }