Changeset 8179fdb in Klonkt
- Timestamp:
- 08/08/2026 10:35:28 PM (4 weeks ago)
- Branches:
- main
- Children:
- 060d4a5
- Parents:
- bfd9c73
- git-author:
- Robin <roboburr@…> (08/08/2026 10:34:09 PM)
- git-committer:
- Robin <roboburr@…> (08/08/2026 10:35:28 PM)
- Location:
- src/services
- Files:
-
- 1 added
- 1 edited
-
ActivityPubService.js (modified) (3 diffs)
-
ap-core.js (added)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
rbfd9c73 r8179fdb 29 29 import Blocklist from './BlocklistService.js'; 30 30 import * as Guardianship from './guardianship/index.js'; 31 32 const PUBLIC = 'https://www.w3.org/ns/activitystreams#Public'; 33 // Full JSON-LD context for every AP object we emit: AS2 core + security (publicKey) + the 34 // extension terms we actually use (Mastodon/toot + schema.org), each with a term definition 35 // so a strict JSON-LD processor resolves them instead of dropping them → valid AS2/JSON-LD. 36 // This is the same context shape Mastodon publishes, so Mastodon sees no change. 37 const AP_CONTEXT = [ 38 'https://www.w3.org/ns/activitystreams', 39 'https://w3id.org/security/v1', 40 { 41 toot: 'http://joinmastodon.org/ns#', 42 schema: 'http://schema.org#', 43 sensitive: 'as:sensitive', 44 Hashtag: 'as:Hashtag', 45 manuallyApprovesFollowers: 'as:manuallyApprovesFollowers', 46 discoverable: 'toot:discoverable', 47 // FEP-7628 (account moves): same term declaration Mastodon ships. 48 alsoKnownAs: { '@id': 'as:alsoKnownAs', '@type': '@id' }, 49 movedTo: { '@id': 'as:movedTo', '@type': '@id' }, 50 featured: { '@id': 'toot:featured', '@type': '@id' }, 51 PropertyValue: 'schema:PropertyValue', 52 value: 'schema:value', 53 embedUrl: { '@id': 'schema:embedUrl', '@type': '@id' }, 54 // Wat een track beschrijft en AS2 niet kent (shaer-0nh). Funkwhale zet deze 55 // vier op zijn Audio; het bleken geen eigen verzinsels maar termen die 56 // schema.org gewoon heeft -- en schema.org stond hier al. De SLEUTELS zijn 57 // die van Funkwhale, want daar leest hij op; de BETEKENIS komt van 58 // schema.org, dus we hoeven geen vreemd vocabulaire binnen te halen. 59 license: { '@id': 'schema:license', '@type': '@id' }, 60 position: 'schema:position', 61 bitrate: 'schema:bitrate', 62 size: 'schema:contentSize', 63 // Poll (Question) extension: Question/oneOf/anyOf/endTime/closed are AS2 core, but the 64 // per-poll unique-voter count is a Mastodon (toot) term — declare it so the emitted 65 // Question stays valid JSON-LD (a strict processor would otherwise drop votersCount). 66 votersCount: 'toot:votersCount', 67 // Kanaal-vocabulaire (shaer-0nh). Funkwhale declareert `category` niet 68 // inline maar via zijn eigen remote context https://funkwhale.audio/ns, en 69 // die host is vanaf hier onbereikbaar -- de IRI hieronder is dus AFGELEID 70 // en niet geverifieerd. Wat vandaag telt voor interop is de JSON-sleutel, 71 // want daar matchen lezers op; de declaratie zorgt alleen dat een strikte 72 // JSON-LD-processor hem niet laat vallen. Nakijken zodra die host weer 73 // antwoordt. 74 category: { '@id': 'https://funkwhale.audio/ns#category' }, 75 // FEP-633c (Guardians): the shaer namespace, owned by the guardianship 76 // module (src/services/guardianship/). 77 ...Guardianship.SHAER_CONTEXT, 78 }, 79 ]; 31 import { PUBLIC, AP_CONTEXT, safeUrl, actorId, noteId, guessMediaType } from './ap-core.js'; 32 // Doorgeven wat hier altijd vandaan kwam, zodat elke bestaande aanroep blijft werken. 33 export { AP_CONTEXT, actorId, noteId, guessMediaType }; 34 80 35 81 36 // Short random suffix so two activity ids minted in the same millisecond (e.g. … … 85 40 // Keep only http(s) URLs — drops javascript:/data:/etc so a remote actor can't 86 41 // smuggle a dangerous scheme into a stored href/src (rendered in owner-only views). 87 const safeUrl = (u) => { const s = String(u == null ? '' : u).trim(); return /^https?:\/\//i.test(s) ? s : ''; };88 42 89 43 // ── SSRF guard for outbound fetches ─────────────────────────────── … … 259 213 260 214 // ── document builders ───────────────────────────────────────────── 261 export function actorId(base, slug) { return `${base}/ap/users/${encodeURIComponent(slug)}`; } 262 263 /** 264 * mediaType raden uit een bestandsnaam. Stond twee keer functie-lokaal in dit 265 * bestand, met een commentaar dat ze "dezelfde afleiding" waren -- en dat was 266 * niet zo: de ene kende video, de andere alleen beeld. Nu een kaart, hier. 267 * De terugval is image/jpeg omdat dit alleen op omslagen en bijlagen wordt 268 * losgelaten, nooit op geluid: dat draagt zijn eigen mime_type uit de database. 269 */ 270 export function guessMediaType(u) { 271 const e = ((u || '').split('?')[0].match(/\.(\w+)$/) || [])[1]; 272 return ({ 273 jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif', 274 webp: 'image/webp', avif: 'image/avif', 275 mp4: 'video/mp4', webm: 'video/webm', mov: 'video/quicktime', 276 })[(e || '').toLowerCase()] || 'image/jpeg'; 277 } 278 export function noteId(base, postId) { return `${base}/ap/notes/${encodeURIComponent(postId)}`; } 215 279 216 280 217 /** Eén Link uit een AS2 `url` kiezen op mediaType. Een `url` mag een string,
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)