From 33ae574b3e9ccd18358d900f6bcd833242c104e9 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sun, 29 Mar 2026 17:15:50 +0200 Subject: [PATCH] fix: bridge IndieAuth token into Mastodon OAuth for media uploads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store the IndieAuth session token (req.session.access_token) on the OAuth authorization code document during POST /oauth/authorize. This token persists through the code→token exchange and is available as req.mastodonToken.indieauthToken when Mastodon clients make API calls. Media upload routes now use this bridged token to call the Micropub media endpoint, which requires IndieAuth authentication. --- lib/mastodon/routes/media.js | 14 ++++++++++++-- lib/mastodon/routes/oauth.js | 3 +++ package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/mastodon/routes/media.js b/lib/mastodon/routes/media.js index b948a1d..d7f1e7f 100644 --- a/lib/mastodon/routes/media.js +++ b/lib/mastodon/routes/media.js @@ -98,8 +98,13 @@ router.post( try { const { application } = req.app.locals; const collections = req.app.locals.mastodonCollections; + // Use IndieAuth token stored during OAuth authorization, falling back + // to session token (native reader) or Mastodon token (won't work for + // Micropub media endpoint but covers direct internal calls). const token = - req.session?.access_token || req.mastodonToken?.accessToken; + req.session?.access_token || + req.mastodonToken?.indieauthToken || + req.mastodonToken?.accessToken; const file = req.files?.file; if (!file) { @@ -142,8 +147,13 @@ router.post( try { const { application } = req.app.locals; const collections = req.app.locals.mastodonCollections; + // Use IndieAuth token stored during OAuth authorization, falling back + // to session token (native reader) or Mastodon token (won't work for + // Micropub media endpoint but covers direct internal calls). const token = - req.session?.access_token || req.mastodonToken?.accessToken; + req.session?.access_token || + req.mastodonToken?.indieauthToken || + req.mastodonToken?.accessToken; const file = req.files?.file; if (!file) { diff --git a/lib/mastodon/routes/oauth.js b/lib/mastodon/routes/oauth.js index 20cd096..1748ee8 100644 --- a/lib/mastodon/routes/oauth.js +++ b/lib/mastodon/routes/oauth.js @@ -388,6 +388,9 @@ router.post("/oauth/authorize", async (req, res, next) => { redirectUri: redirect_uri, codeChallenge: code_challenge || null, codeChallengeMethod: code_challenge_method || null, + // Store the IndieAuth session token so Mastodon API routes can call + // Micropub/media endpoints on behalf of this user (single-user server). + indieauthToken: req.session?.access_token || null, createdAt: new Date(), expiresAt: new Date(Date.now() + 10 * 60 * 1000), // 10 minutes }); diff --git a/package-lock.json b/package-lock.json index c0b9672..a5b256e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@rmdes/indiekit-endpoint-activitypub", - "version": "3.11.3", + "version": "3.11.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@rmdes/indiekit-endpoint-activitypub", - "version": "3.11.3", + "version": "3.11.4", "license": "MIT", "dependencies": { "@fedify/debugger": "^2.1.0", diff --git a/package.json b/package.json index c0d91b5..13752d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rmdes/indiekit-endpoint-activitypub", - "version": "3.11.3", + "version": "3.11.4", "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.", "keywords": [ "indiekit",