Commit Graph

83 Commits

Author SHA1 Message Date
Sven
e52e98c5c5 chore(patches): remove patches now fixed in forks
Fixes implemented upstream in svemagie/indiekit-endpoint-activitypub
and svemagie/indiekit-endpoint-microsub; postinstall patches no longer
needed:

- patch-microsub-feed-discovery (HTML <link> discovery in fetcher.js)
- patch-inbox-skip-view-activity-parse (PeerTube View buffering in federation-bridge.js)
- patch-ap-inbox-raw-body-digest (raw body preservation for HTTP Signature Digest)
- patch-ap-object-url-trailing-slash (trailing slash $in fix in federation-setup.js)
- patch-ap-signature-time-window (12h signatureTimeWindow in federation-setup.js)
- patch-inbox-ignore-view-activity (View no-op handler in inbox-listeners.js)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 12:19:18 +01:00
Sven
dac2411a08 test: delete patch-microsub-reader-ap-dispatch 2026-03-16 11:47:06 +01:00
Sven
5b21fd3ea3 chore(patches): remove obsolete webmention-sender-content-scope patch
@rmdes/indiekit-endpoint-webmention-sender@1.0.8 ships `$.root()` natively.
The old buggy `const scope = contentRoot ?? $` no longer exists upstream.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 00:04:03 +01:00
Sven
4d5b1eba16 fix(i18n): add patch script for /conversations endpoint German locale
Adds missing German translations for indiekit-endpoint-conversations:
- dashboard.activitypubTitle: "ActivityPub"
- dashboard.activitypubHint: ActivityPub auto-enable explanation
- source.activitypub: "ActivityPub"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:21:10 +01:00
Sven
066cc12402 fix(i18n): add patch script for /posts endpoint German locale
Fixes rough translations in de.json for indiekit-endpoint-posts:
- delete.cancel: "zurück zur Post" → "zurück zum Beitrag"
- post.syndicate: "Syndikatsposten" → "Beitrag syndizieren"
- status.unlisted: "Nicht gelistete" → "Nicht gelistet"
- form.summary.label: "Übersicht" → "Zusammenfassung"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:19:32 +01:00
Sven
a9575059a7 chore: allow Fedify to fetch own-site URLs resolving to private IPs
blog.giersig.eu resolves to 10.100.0.10 (private LAN) from the server,
causing Fedify's SSRF guard to block lookupObject() and WebFinger calls
for own posts when processing incoming ActivityPub activities.

Adds patch-ap-allow-private-address.mjs which sets allowPrivateAddress: true
on createFederation(), wired into both postinstall and serve scripts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:16:12 +01:00
Sven
0331271cb5 chore: update to upstream 2026-03-15 19:31:10 +01:00
Sven
abf06565d5 fix: extend Fedify signature time window to 12h for retried deliveries
Before the raw-body digest fix, every Mastodon inbox delivery was
rejected with a Digest mismatch. Mastodon queued those activities for
retry. After the digest fix, the retried deliveries arrive with their
original HTTP Signatures which are now > 1 hour old. Fedify's default
signatureTimeWindow: { hours: 1 } rejects them with "Date is too far
in the past", logged as "Failed to verify the request's HTTP Signatures."

Extending to 12 hours allows those retried deliveries to be accepted.
The signature still must be cryptographically valid — only the replay
window is relaxed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 15:35:55 +01:00
Sven
02919b6e37 fix: patch resolvePost to match post URLs with or without trailing slash
The Fedify object dispatcher constructs the post lookup URL from the
{+id} path variable (e.g. "replies/bd78a"), which has no trailing slash.
Posts in MongoDB store their URL with a trailing slash, so the exact
findOne() match was silently returning null → Fedify serving 404 →
mountains.social showing "Could not connect to the given address".

Fix uses $in to try both variants so the dispatcher works regardless
of whether the request URL has a trailing slash or not.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 15:17:27 +01:00
Sven
a42a6b6d45 fix: add AP inbox digest patch and AP URL lookup API for fediverse interaction
- patch-ap-inbox-raw-body-digest: preserve raw request bytes through the
  AP inbox buffer guard so Fedify's HTTP Signature Digest verification
  passes (JSON.stringify re-encoding broke SHA-256 digest check, causing
  Mastodon likes/replies/boosts to be silently rejected)
- patch-ap-url-lookup-api: add GET /activitypub/api/ap-url endpoint that
  maps a blog post URL to its Fedify-served AP object URL, enabling
  reliable content negotiation for authorize_interaction redirects
- wire both patches into postinstall and serve scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 15:00:13 +01:00
Sven
d2573146a7 feat: default ActivityPub syndication when force-syndicating from backend
When the backend Syndicate button is pressed on a post with no
mp-syndicate-to and no prior syndication URLs, fall back to targets
with checked:true (e.g. ActivityPub) instead of no-oping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 14:02:52 +01:00
Sven
a52d93392f feat: add search and tag filtering to /posts list
- patch-endpoint-micropub-source-filter: support ?category= and ?search=
  query params in the Micropub ?q=source endpoint, filtering MongoDB
  documents by properties.category and a case-insensitive regex across
  name/content fields
- patch-endpoint-posts-search-tags: forward category/search params from
  the posts controller to Micropub, expose tagLinks on each item, and
  replace the posts.njk cardGrid with a custom loop that renders clickable
  tag chips and a search form above the grid

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 11:58:36 +01:00
Sven
b6bf84dcd4 fix: patch webmention-sender scope.find crash when post has no h-entry
Replace `contentRoot ?? $` with `contentRoot ?? $.root()` in webmention.js.
When a post has no .h-entry, <article>, or <main>, contentRoot is null and
`$` is a Cheerio constructor function — not a Cheerio object — so .find()
throws "scope.find is not a function". $.root() returns the document root
as a proper Cheerio object that supports .find().

Rewrites patch-webmention-sender-content-scope.mjs for the new 1.0.7 package
shape (content-scope logic already baked in, only the $.root() fix needed)
and registers it in postinstall + serve.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 23:23:46 +01:00
Sven
53bb7d363b chore: update @indiekit/* to beta.27, bump endpoint-comments and webmention-sender
- @indiekit/indiekit, @indiekit/store-github: ^1.0.0-beta.25 → ^1.0.0-beta.27
- @rmdes/indiekit-endpoint-comments: 1.0.0 → 1.0.10
- @rmdes/indiekit-endpoint-webmention-sender: 1.0.6 → 1.0.7

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 23:12:50 +01:00
Sven
3708dd92c3 chore: remove Mastodon syndicator and related patches
Blog is now a native ActivityPub actor; Mastodon syndication via
troet.cafe is no longer needed. Removes the syndicator package,
config vars, patch script, and env example entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:31:37 +01:00
Sven
296745fcf8 fix: skip PeerTube View activities before Fedify JSON-LD parse
The .on(View) inbox handler from the previous commit is never reached
because Fedify crashes parsing PeerTube's View activity before dispatch —
its JSON-LD deserialiser doesn't recognise Schema.org InteractionCounter,
throwing "Failed to parse activity: TypeError: Invalid type".

Add a guard at the top of createFedifyMiddleware that short-circuits any
POST with body.type === "View" and returns 200 immediately, bypassing
federation.fetch() entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:21:25 +01:00
Sven
f004ecdbcc fix: silently ignore PeerTube View activities in ActivityPub inbox
PeerTube broadcasts non-standard View (WatchAction) activities to all
followers on every video watch. Fedify has no handler for this type,
causing noisy "Unsupported activity type" errors in the federation log.

Adds a no-op .on(View, ...) handler at the end of the inbox listener
chain via the existing patch script mechanism.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:12:38 +01:00
svemagie
3781503abc fix: register bluesky cursor-fix patch in postinstall and serve scripts 2026-03-14 14:46:51 +01:00
svemagie
f8f595fe8d fix: filter out self-interactions from own Bluesky account 2026-03-14 14:01:38 +01:00
Sven
d3c094f91f update: activitypub 2026-03-14 13:53:40 +01:00
Sven
3ca920089b fix: improve microsub feed discovery via <link rel="alternate"> tags
When a bookmarked URL is an HTML page whose feed is not at a common
path (/feed, /rss.xml etc.), fetchAndParseFeed would throw and store
no items in microsub_items.  Sites like econsoc.mpifg.de or signal.org
post pages advertise their feed via a standard
  <link rel="alternate" type="application/rss+xml" href="...">
element, which discoverFeeds() already parses but was never called
from the fetch/parse pipeline.

Now, before probing common paths, fetchAndParseFeed calls discoverFeeds()
on the fetched HTML and uses any typed RSS/Atom/JSONFeed link it finds.
Common-path probing remains as the final fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 09:27:22 +01:00
Sven
0dc71d1922 fix: pre-fill reference URL when creating post from /news entry
share-post.js opens /posts/create?type=like&url=<link>&name=<title>
but postData.create only reads request.body, ignoring the query params.

Patch postData.create: when properties is empty and ?url= is present,
seed properties with the correct field name per post type:
  like     → like-of
  bookmark → bookmark-of  (also seeds name from ?name=)
  reply    → in-reply-to
  repost   → repost-of

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 07:23:36 +01:00
Sven
1d28df8d04 fix: post edit 404 — query micropub source by _id not paginated scan
getPostProperties queries ?q=source (no filter, default limit=40) then
scans items for a uid match. Posts outside the 40 most recent return
undefined → IndiekitError.notFound (404).

Fix:
- Patch micropub query controller: when ?q=source&uid=<objectId> is
  present, findOne({ _id: getObjectId(uid) }) directly and return
  { items: [mf2] } so it is compatible with getPostProperties.
- Patch getPostProperties to append uid= to the micropub source URL,
  so any post can be fetched regardless of recency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 20:45:12 +01:00
Sven
974d76b988 chore: switch activitypub to npm registry ^2.8.2
The github: source was pinned to 2.8.0 in the lock file but the repo
HEAD is now at 2.8.2, causing npm ci to fail. Switch to the versioned
npm package to keep the lock file stable.

Lock file needs regeneration: run npm install locally and commit
the updated package-lock.json.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 18:58:48 +01:00
Sven
64e5f99526 fix: mount blogroll at /rssapi and add /api/feeds alias
The /news/ page fetches /rssapi/api/items, /rssapi/api/feeds and
/rssapi/api/status. The blogroll endpoint was mounted at /blogrollapi,
so all three requests returned a 404 HTML page — causing the
"Unexpected token '<'" JSON parse error.

- Change blogroll mountPath from /blogrollapi to /rssapi
- Add patch-endpoint-blogroll-feeds-alias.mjs: injects a /api/feeds
  route alias pointing to listBlogs (page expects /feeds, endpoint
  only had /blogs)
- Wire new patch into postinstall and serve scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 18:54:24 +01:00
svemagie
5df7314f8d chore: integrate AP patches into fork — remove 3 scripts, trim federation-unlisted-guards
Deleted scripts (logic now built into the fork):
- patch-endpoint-activitypub-docloader-loglevel.mjs
- patch-endpoint-activitypub-migrate-alias-clear.mjs
- patch-endpoint-activitypub-like-boost-methods.mjs

Trimmed patch-federation-unlisted-guards.mjs to only cover
endpoint-syndicate (separate package). AP unlisted guards are
now in the fork's federation-setup.js.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 08:07:36 +01:00
svemagie
d9566919fc chore: remove like/repost content-negotiation patch (now in fork)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 07:51:45 +01:00
svemagie
593665bcbd feat: switch activitypub endpoint to svemagie fork with DM support
Use svemagie/indiekit-endpoint-activitypub instead of the upstream npm
package to get direct message receive and native AP reply support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 06:33:35 +01:00
svemagie
d35e7b7b28 fix: disable Mastodon external like/repost status posts
Serve like/repost posts as Note objects for AP content negotiation.
Returning a bare Like/Announce activity broke Mastodon's
authorize_interaction because it expects a content object (Note/Article).
Now like posts are served as ❤️ Note and reposts as 🔁 Note.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 14:59:04 +01:00
svemagie
ad0492ef64 feat: dispatch native AP Like/Announce from fediverse identity on like/repost
- Add likePost() and boostPost() programmatic methods to the ActivityPub
  plugin, sending native Like and Announce activities as @svemagie@blog.giersig.eu
- Wire up AP dispatch in submitCompose (microsub reader) after a successful
  Micropub post creation — fire-and-forget, non-blocking
- Fix detectProtocol to recognise troet.cafe, hachyderm.io, infosec.exchange,
  chaos.social and other fediverse domains not in the original pattern list
- Fix Mastodon syndication target auto-selection to match by service.name
  ("mastodon") and by configured instance hostname, not just uid string

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 13:44:09 +01:00
svemagie
3f367610f5 fix: force one-time ai: block resync for posts with stale files
The v3 patch bug allowed Micropub to update MongoDB with aiTextLevel/
aiCodeLevel values but write post files without the ai: frontmatter
block (supportsAiDisclosure was always false). Re-saving with the same
values correctly returned "no properties changed" — but the file on disk
remained stale.

New patch (patch-micropub-ai-block-resync.mjs) adds _aiBlockVersion to
each post document in MongoDB. On update, if a post has AI fields but
_aiBlockVersion != "v4", the no-change check is bypassed and the file
is force-rewritten exactly once. Subsequent no-change saves behave
normally.

Also adds AI transparency section to README documenting the full
implementation, patch chain, v4 root cause, and re-save instructions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 09:03:22 +01:00
svemagie
cb1418bae5 feat: replace @rmdes/indiekit-endpoint-microsub with svemagie fork
Switches to github:svemagie/indiekit-endpoint-microsub#bookmarks-import
which adds a contentNegotiationRoutes hook to auto-follow bookmarked
URLs as Microsub feed subscriptions when a bookmark-of post is created.

Mirrors the same pattern already in place for the blogroll fork.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 08:36:55 +01:00
svemagie
5f4d8ca5e8 fix: detect article/note post type via permalink for AI frontmatter
Indiekit's getPostTemplateProperties() explicitly removes the post-type
property before passing JF2 to postTemplate(). The v3 patch relied on
post-type to set supportsAiDisclosure, which was therefore always false —
causing the ai: frontmatter block to never be written regardless of what
was selected in the backend form.

v4 patch falls back to permalink URL pattern (/articles/, /notes/) to
correctly detect the post type when post-type is absent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 08:11:28 +01:00
svemagie
c591b6fe37 feat(auth): add IndieAuth endpoint plugin and config for /auth 2026-03-10 20:47:20 +01:00
svemagie
c1a4eb2404 feat(blogroll): auto-import bookmark sites into blogroll
When a micropub bookmark post is created, the bookmarked site's
origin URL is discovered for RSS/Atom feeds and added to the blogroll
under category "bookmarks".

Integration is self-contained in the blogroll plugin via
contentNegotiationRoutes — no micropub patches needed.

Source: github:svemagie/indiekit-endpoint-blogroll#bookmark-import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 19:31:15 +01:00
svemagie
617a8f92b2 feat: patch changelog endpoint to categorize by commit message
Replaces repo-name-based category logic with commit-message parsing:
- feat: / feat(...): → Features
- fix: / fix(...): / Fix... → Fixes
- everything else → Other

Drops unused categories (Deployment, Theme, Endpoints, Syndicators,
Post Types, Presets). Patch runs on postinstall and serve.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 10:17:05 +01:00
svemagie
1be5baa60f feat: install and configure @rmdes/indiekit-endpoint-microsub
Adds Microsub social reader endpoint at /microsub, enabling feed
subscription and management via the Microsub protocol.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 10:17:04 +01:00
svemagie
038b94a606 feat: install and configure @rmdes/indiekit-endpoint-blogroll
Mounts blogroll API at /blogrollapi — syncs RSS/Atom feeds hourly,
caches 50 items per blog, deletes items after 7 days.
Public endpoints: /blogrollapi/api/blogs, /items, /categories, /status, /opml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 10:17:03 +01:00
svemagie
ab2c248344 feat: Add @rmdes/indiekit-syndicator-indienews plugin and config block 2026-03-10 10:17:02 +01:00
svemagie
99b7966722 feat: update package files for indiekit-endpoint-youtube 2026-03-10 00:07:31 +01:00
svemagie
13d662cff6 Add comments endpoint locale patch and translations 2026-03-09 22:13:39 +01:00
svemagie
4eb7c07eb3 Fix homepage SITE_SOCIAL identity defaults parsing 2026-03-09 21:23:50 +01:00
svemagie
1365f696f0 fix(activitypub): handle publication host private DNS lookups 2026-03-09 19:39:04 +01:00
svemagie
d237dac539 Optimize AI metadata pipeline for editor and frontmatter 2026-03-09 18:50:24 +01:00
svemagie
7d13d5dbfa Add and configure comments endpoint 2026-03-09 18:23:32 +01:00
svemagie
ad17b697c7 Allow clearing Mastodon migration alias 2026-03-09 18:15:46 +01:00
svemagie
5836d05d86 Add Podroll OPML file upload support 2026-03-09 16:13:27 +01:00
svemagie
c2a24b9162 Expose AI fields in /posts article editor 2026-03-09 15:24:00 +01:00
svemagie
fed5657957 Add webmentions proxy endpoint integration 2026-03-09 14:10:59 +01:00
svemagie
8d77f0d259 Configure syndicate endpoint with Bluesky and Mastodon syndicators 2026-03-09 13:48:49 +01:00