Changeset 0cea12b in Klonkt


Ignore:
Timestamp:
07/20/2026 08:19:20 PM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
81b2e1e
Parents:
513ba82
git-author:
Robin <roboburr@…> (07/20/2026 08:18:21 PM)
git-committer:
Robin <roboburr@…> (07/20/2026 08:19:20 PM)
Message:

Feature: owner inbox read over C2S (GET, bearer-gated)

GET /ap/users/:slug/inbox with a bearer scoped to that site returns the
recent timeline (accounts the owner follows) as an OrderedCollection of
Create(Note) items with content, url, published, sensitive and summary
(CW). Anyone else gets 403: the inbox stays write-only for the public.
This is the missing read half for a connected app's unified feed
(Shaer HomeBase, bead shaer-n4h); same gate pattern as the owner
followers/following read.

Changed files:
src/routes/activitypub.js

  • GET /ap/users/:slug/inbox (owner only) mapping ap_timeline rows

New file:
test/c2s-inbox.test.js

  • data-path coverage for the fields the mapping relies on

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG.de.md

    r513ba82 r0cea12b  
    77
    88### Hinzugefügt
     9- **Die Inhaberin kann ihre Inbox über C2S lesen.** Ein GET auf die Inbox mit
     10  dem eigenen Bearer liefert aktuelle eingegangene Beiträge (die Konten, denen
     11  du folgst) als Create(Note)-Einträge, damit eine verbundene App (Shaer) einen
     12  vereinten Feed bauen kann. Für alle anderen bleibt die Inbox write-only.
    913- **"Mehr laden" in den Feeds.** Solo (Start), Zirkel, Zeitung und Nachrichten
    1014  laden jetzt in Blöcken von 72 mit einem "Mehr laden"-Button statt einer harten
  • CHANGELOG.md

    r513ba82 r0cea12b  
    77
    88### Added
     9- **The owner can read their inbox over C2S.** A GET on the inbox with the
     10  account's own bearer returns recent inbound posts (the accounts you follow)
     11  as Create(Note) items, so a connected app (Shaer) can build a unified feed.
     12  For everyone else the inbox stays write-only.
    913- **"Load more" on the feeds.** Solo (home), Cirkel, News and Messages now page
    1014  in blocks of 72 with a "Load more" button instead of a hard cap, so older
  • CHANGELOG.nl.md

    r513ba82 r0cea12b  
    77
    88### Toegevoegd
     9- **De eigenaar kan zijn inbox lezen via C2S.** Een GET op de inbox met de
     10  eigen bearer geeft recente binnengekomen posts (de accounts die je volgt) als
     11  Create(Note)-items, zodat een gekoppelde app (Shaer) een unified feed kan
     12  bouwen. Voor alle anderen blijft de inbox write-only.
    913- **"Meer laden" op de feeds.** Solo (home), Cirkel, Krant en Berichten laden nu
    1014  in blokken van 72 met een "Meer laden"-knop in plaats van een harde limiet, dus
  • src/routes/activitypub.js

    r513ba82 r0cea12b  
    8484});
    8585
     86// ── Inbox read (owner only, AP C2S) ───────────────────────────────
     87// GET on the inbox is part of ActivityPub C2S: the account owner (a bearer
     88// scoped to this site) reads recent inbound posts (the timeline: accounts
     89// they follow) as Create(Note) items, so an app (Shaer) can build a unified
     90// feed. Anyone else gets 403; the inbox stays write-only for the public.
     91router.get('/ap/users/:slug/inbox', (req, res) => {
     92  const auth = OAuth.verifyBearer(req.headers.authorization);
     93  if (!auth || auth.site.slug !== req.params.slug) return res.status(403).end();
     94  const base = baseUrl(req);
     95  const items = AP.getTimeline(auth.site.slug, 60).map((t) => ({
     96    id: `${t.id}#create`,
     97    type: 'Create',
     98    actor: t.author_uri,
     99    published: t.published || t.created_at || undefined,
     100    object: {
     101      id: t.id,
     102      type: 'Note',
     103      attributedTo: t.author_uri,
     104      content: t.content,
     105      url: t.url || undefined,
     106      published: t.published || t.created_at || undefined,
     107      sensitive: !!t.nsfw,
     108      summary: t.cw || undefined,
     109    },
     110  }));
     111  AP.sendAP(res, {
     112    '@context': AP.AP_CONTEXT,
     113    id: `${base}/ap/users/${auth.site.slug}/inbox`,
     114    type: 'OrderedCollection',
     115    totalItems: items.length,
     116    orderedItems: items,
     117  });
     118});
     119
    86120// ── Followers (count-only public, full for the owner) ─────────────
    87121// A C2S bearer scoped to this site (the account owner) gets the real actor
Note: See TracChangeset for help on using the changeset viewer.