Commit Graph

208 Commits

Author SHA1 Message Date
Sven
fc9afa9bff fix(rssapi): flatten feedTitle, sourceTitle and author in item response
The /rssapi transformation was missing feedTitle, sourceTitle and author
fields that the /news page expects. Map them from the nested blog object.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 09:21:23 +01:00
Sven
cb7b525368 fix(patches): extend internal URL rewrite to auth, token, and media endpoints
Add localhost rewrite for three more self-referential fetches:

- indieauth.js: token exchange during login
- token.js: token introspection on every authenticated request
- media.js: file uploads via media endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:40:59 +01:00
Sven
a2e2764108 fix(patches): extend internal URL rewrite to microsub, activitypub, and @rmdes posts
The localhost rewrite only covered endpoint-syndicate and endpoint-share.
Add coverage for 4 more files that also self-fetch via the public URL:

- @rmdes/indiekit-endpoint-microsub reader.js (2 fetch calls)
- @rmdes/indiekit-endpoint-activitypub compose.js (2 fetch calls)
- @rmdes/indiekit-endpoint-posts utils.js and endpoint.js

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:35:50 +01:00
Sven
e3765948e5 fix(patches): silence false warnings for already-applied patches
- patch-ap-allow-private-address: detect allowPrivateAddress in source
- patch-endpoint-posts-ai-cleanup: detect any AI field key variant

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:32:24 +01:00
Sven
733c00b1b3 fix(patches): rewrite micropub self-fetch to localhost for jailed setup
Node can't reach its own public HTTPS URL (ECONNREFUSED 127.0.0.1:443)
because port 443 only exists on the nginx jail. Rewrite self-referential
fetch URLs to http://localhost:3000 in endpoint-posts, endpoint-syndicate,
and endpoint-share.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:24:46 +01:00
Sven
24a9fb8f6b fix(patches): restore PeerTube View patches and add fetch diagnostic
Re-add PeerTube View activity patches that were prematurely removed in
e52e98c5c — the upstream fork doesn't reliably include these fixes on
all server deployments, causing noisy "Unsupported activity type" errors.

Also add fetch diagnostic patch to surface the real cause of
"TypeError: fetch failed" when posting articles via the form controller.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:14:26 +01:00
Sven
117aa2f577 fix(patches): normalize nested tags before syndicating to fediverse
Tags like `on/art/music` are reduced to their last segment (`#music`)
in both buildPlainTags and buildFedifyTags so ActivityPub hashtags are
valid on Mastodon and other platforms.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 13:01:36 +01:00
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
437554cdc9 fix(patches): always strip legacy ai-text-level keys on form save
Hyphenated keys (ai-text-level, ai-code-level, etc.) from the upstream
beta.41 endpoint are now unconditionally deleted on form submission,
preventing them from coexisting with the camelCase equivalents in MongoDB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 00:36:55 +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
757c931408 fix(syndicate): register endpoint-syndicate plugin to enable /syndicate route
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:55:25 +01:00
Sven
3ab6c4caa2 fix(patches): silence false-positive warnings for beta.41 native features
Four patch scripts were warning when they couldn't find their target snippets
in @indiekit/endpoint-posts beta.41, because beta.41 already ships those
features natively:

- patch-endpoint-posts-ai-cleanup: beta.41 form.js has native AI field
  cleanup — detect via "ai-text-level" presence and skip silently
- patch-endpoint-posts-search-tags: beta.41 posts.js/posts.njk have native
  filter/sort/search — detect via buildFilterQuery / posts-filter-row
- patch-endpoint-posts-uid-lookup: beta.41 utils.js uses direct MongoDB
  queries (getPostProperties) — skip silently
- patch-preset-eleventy-ai-frontmatter: add v5 block matching the new
  upstream structure (mpUrl + URL pathname normalization)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:36:55 +01:00
Sven
6c5b003bcf fix(i18n): extend posts locale patch to cover beta.41 and filter/purge/AI keys
- Add @indiekit/endpoint-posts (beta.41) as a second patch target
- Translate new filter.* keys (type, status, sort, search, clear)
- Translate purge.* keys (permanently delete flow)
- Translate form.pinned, form.ai-text-level, form.ai-code-level,
  form.ai-tools, form.ai-description
- Fix mp-syndicate-to label: "Syndikat zu" → "Syndizieren nach"
- Fix posts.posts.title: "Veröffentlichte Beiträge" → "Beiträge"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 23:28:56 +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
15fb4bb914 chore: application.locale:de 2026-03-15 22:46:23 +01:00
Sven
0898df1b66 chore: rss back out 2026-03-15 22:23:02 +01:00
Sven
98f059614e chore: rss back in 2026-03-15 22:15:11 +01:00
Sven
7104094ce0 chore: no rss reader for now 2026-03-15 19:46:37 +01:00
Sven
ff0a8759a8 chore: upd package-lock.json 2026-03-15 19:34:01 +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
4af7c49c6a feat: inline card template in /posts to show tags inside cards
Non-garden tags shown as small chips in the card body (above footer).
The 'garden' tag shown in the card footer on the right side of the
publish-state badge, using margin-left:auto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 12:14:32 +01:00
Sven
65f94da71c fix: remove broken regex-escape snippet from micropub source-filter patch
The template-literal double-backslash escaping produced malformed JS in
the injected code, causing a SyntaxError at startup. Replace the
regex-escape helper with a direct String(searchParam) pass-through —
safe for an admin-only search interface.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 12:03:53 +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
ee1313fb26 ci: upgrade to actions/checkout@v5 and setup-node@v5, node 18→22 2026-03-15 08:52:30 +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
b24d38ba74 docs: add changelog section to README for last 20 commits
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 23:19:45 +01:00
Sven
d3fb055df4 chore: upgrade checkout and setup-node actions to v4
Addresses Node.js 20 deprecation warning in GitHub Actions runners.
actions/checkout and actions/setup-node v4 use Node.js 24-compatible
runtimes, ahead of the June 2026 forced migration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 23:17:18 +01:00
Sven
53b40a5edc chore: update comments-locales patch for 1.0.10 template, drop livefetch patch
patch-endpoint-comments-locales: remove viewReplacements and sourceOverrides
since comments.njk was rewritten with Nunjucks macros and badge() — the old
HTML snippets no longer exist. Also drop obsolete locale keys (hiddenBadge,
targetPrefix, paginationLabel, page, of) that the new template doesn't use.

patch-webmention-sender-livefetch: delete — was orphaned (not in postinstall)
and the behavior is intentionally accepted as-is.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 23:12:57 +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
314a08542b fix: buffer ActivityPub body before checking for PeerTube View activities
The previous patch checked req.body?.type === "View" but Express's JSON
body parser ignores application/activity+json, so req.body was always
undefined and the guard never fired.

Fix in two parts:
1. In createFedifyMiddleware: manually buffer and JSON-parse the raw
   request stream for activity+json/ld+json POSTs, storing the result on
   req.body before the type check.
2. In fromExpressRequest: extend the content-type check to include
   activity+json/ld+json so non-View activities are correctly forwarded
   to Fedify with the buffered body.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 22:40:54 +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
Sven
37ac8c0ce9 Revert "chore: remove all occurrences of https://troet.cafe and https://troet.cafe/svemagie"
This reverts commit 5c137f01f3.
2026-03-14 22:00:59 +01:00
Sven
5c137f01f3 chore: remove all occurrences of https://troet.cafe and https://troet.cafe/svemagie 2026-03-14 20:58:42 +01:00
Sven
304c75f64a feat: add gardenStage and ai fields to all post type presets
- gardenStage: added to all post types (article, note, bookmark, like,
  repost, photo, reply, page) so Indiekit preserves it in frontmatter
- aiTextLevel/aiCodeLevel/aiTools/aiDescription: extended from article+note
  to all content post types (bookmark, repost, photo, reply, page)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 18:49:35 +01:00
svemagie
3781503abc fix: register bluesky cursor-fix patch in postinstall and serve scripts 2026-03-14 14:46:51 +01:00
svemagie
655bc736f2 fix: clear stale Bluesky polling cursor to restore interaction ingestion 2026-03-14 14:46:43 +01:00
svemagie
4f1440a634 fix: filter out self-interactions from own Bluesky account 2026-03-14 14:01:44 +01:00
svemagie
f8f595fe8d fix: filter out self-interactions from own Bluesky account 2026-03-14 14:01:38 +01:00
Sven
af7c89b2c5 update: fix npm 2026-03-14 13:56:54 +01:00
Sven
d3c094f91f update: activitypub 2026-03-14 13:53:40 +01:00
Sven
b632af9564 fix(webmention): scope link extraction to .h-entry not .e-content
u-in-reply-to, u-like-of, u-repost-of etc. are rendered in an aside
before the .e-content div, not inside it. Scoping to .h-entry .e-content
caused these microformat links to be missed entirely.

Also bump reset-stale migration to v3 so posts already marked sent with
zero results (like /replies/88feb/) are retried with the corrected scope.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 09:40:48 +01:00