Changeset e6c6e6f in Klonkt for test/c2s-direct.test.js


Ignore:
Timestamp:
07/20/2026 10:27:19 PM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
155c24e
Parents:
024f4f8
git-author:
Robin <roboburr@…> (07/20/2026 10:27:18 PM)
git-committer:
Robin <roboburr@…> (07/20/2026 10:27:19 PM)
Message:

Feature: uploadMedia endpoint + attachments on direct notes

The actor has been advertising endpoints.uploadMedia without a route
behind it; this implements it. A bearer scoped to the site POSTs one
image/audio/video (multipart field "file", the AP C2S convention) into
the reply-media store and gets { url, mediaType, name } back. Direct
notes (private mentions) now carry attachments through the same
deliverReply-style validation (own /media/ uploads only, max 4), so
the help-buoy capture rides a DM to the guardians while the note stays
direct: recipients only, empty cc, unboostable.

Changed files:
src/routes/activitypub.js

  • POST /ap/users/:slug/uploadMedia (bearer-gated, multer, 32MB)

src/services/ActivityPubService.js

  • ingest passes AS2 attachments into the direct path (absolute own-base URLs normalized to relative)
  • deliverDirectNote validates + stores attachments

New file: (none)
test/c2s-direct.test.js

  • direct note renders its attachment, addressing stays direct

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/c2s-direct.test.js

    r024f4f8 re6c6e6f  
    2727});
    2828
     29test('a direct note carries its attachments (help-buoy capture)', () => {
     30  db.prepare(`INSERT INTO ap_outbox (id, site_slug, post_id, post_slug, in_reply_to, to_actor, to_handle, content, visibility, to_actors, attachments, created_at)
     31    VALUES ('d2','me','',NULL,NULL,'https://r.test/u/g','@g@r.test','<p>kijk</p>','direct','["https://r.test/u/g"]','[{"url":"/media/reply-media/x.png","mediaType":"image/png","name":"capture"}]',CURRENT_TIMESTAMP)`).run();
     32  const row = db.prepare('SELECT * FROM ap_outbox WHERE id = ?').get('d2');
     33  const note = AP.buildReplyNote('https://test.example', site, row);
     34  assert.equal(note.attachment.length, 1);
     35  assert.equal(note.attachment[0].type, 'Image');
     36  assert.ok(note.attachment[0].url.endsWith('/media/reply-media/x.png'));
     37  assert.deepEqual(note.cc, []);   // still direct
     38});
     39
    2940test('direct without any real recipient is refused (400 no_recipients)', async () => {
    3041  const r = await AP.ingestOutboxActivity(site, user, {
Note: See TracChangeset for help on using the changeset viewer.