@rmdes/indiekit-endpoint-activitypub 3.6.1 → 3.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -310,7 +310,7 @@ router.post("/oauth/authorize", async (req, res, next) => {
310
310
  "error_description",
311
311
  "The resource owner denied the request",
312
312
  );
313
- return res.redirect(url.toString());
313
+ return redirectToUri(res, redirect_uri, url.toString());
314
314
  }
315
315
  return res.status(403).json({
316
316
  error: "access_denied",
@@ -362,7 +362,7 @@ router.post("/oauth/authorize", async (req, res, next) => {
362
362
  // Redirect with code
363
363
  const url = new URL(redirect_uri);
364
364
  url.searchParams.set("code", code);
365
- res.redirect(url.toString());
365
+ redirectToUri(res, redirect_uri, url.toString());
366
366
  } catch (error) {
367
367
  next(error);
368
368
  }
@@ -600,4 +600,36 @@ function extractClientCredentials(req) {
600
600
  };
601
601
  }
602
602
 
603
+ /**
604
+ * Redirect to a URI, handling custom schemes for native apps.
605
+ *
606
+ * HTTP(S) redirect URIs use a standard 302 redirect (web clients).
607
+ * Custom scheme URIs (fedilab://, moshidon-android-auth://) use an
608
+ * HTML page with JavaScript + meta refresh. Android Chrome Custom Tabs
609
+ * block 302 redirects to non-HTTP schemes but allow client-side navigation.
610
+ *
611
+ * @param {object} res - Express response
612
+ * @param {string} originalUri - The registered redirect_uri (to detect scheme)
613
+ * @param {string} fullUrl - The complete redirect URL with query params
614
+ */
615
+ function redirectToUri(res, originalUri, fullUrl) {
616
+ if (originalUri.startsWith("http://") || originalUri.startsWith("https://")) {
617
+ return res.redirect(fullUrl);
618
+ }
619
+
620
+ // Native app — HTML page with JS redirect + meta refresh fallback
621
+ res.type("html").send(`<!DOCTYPE html>
622
+ <html lang="en">
623
+ <head>
624
+ <meta charset="utf-8">
625
+ <meta http-equiv="refresh" content="0;url=${fullUrl}">
626
+ <title>Redirecting…</title>
627
+ </head>
628
+ <body>
629
+ <p>Redirecting to application…</p>
630
+ <script>window.location.href = ${JSON.stringify(fullUrl)};</script>
631
+ </body>
632
+ </html>`);
633
+ }
634
+
603
635
  export default router;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-activitypub",
3
- "version": "3.6.1",
3
+ "version": "3.6.2",
4
4
  "description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
5
5
  "keywords": [
6
6
  "indiekit",