@rmdes/indiekit-endpoint-activitypub 3.13.8 → 3.13.10

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.
package/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import express from "express";
2
2
  import { waitForReady } from "@rmdes/indiekit-startup-gate";
3
+ import { ACTIVITYPUB_BLOCKS } from "./lib/blocks.js";
3
4
 
4
5
  import { setupFederation, buildPersonActor } from "./lib/federation-setup.js";
5
6
  import { createMastodonRouter } from "./lib/mastodon/router.js";
@@ -173,6 +174,10 @@ export default class ActivityPubEndpoint {
173
174
  this._fedifyMiddleware = null;
174
175
  }
175
176
 
177
+ get blocks() {
178
+ return ACTIVITYPUB_BLOCKS;
179
+ }
180
+
176
181
  get navigationItems() {
177
182
  return [
178
183
  {
package/lib/blocks.js ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * ActivityPub v2 block declaration (Phase 7b — plugin block ownership).
3
+ *
4
+ * The `fediverse-follow` sidebar widget was a site-config BUILTIN_BLOCKS seed
5
+ * (requiresPlugin null, gated only by the theme's legacy widgetPluginRequirements
6
+ * render-map). Declaring it here makes site-config's scanPlugins stamp
7
+ * `sourcePlugin` → `requiresPlugin` ("ActivityPub endpoint"), so the block is
8
+ * properly plugin-gated (theme ENDPOINT_SLUGS maps it to the `activitypub`
9
+ * loadout slug). scanPlugins precedence is `built-in < plugin blocks`, so this
10
+ * entry OVERWRITES the builtin seed on sites where the plugin is loaded; the seed
11
+ * itself is removed from site-config in Phase 7d alongside the legacy-map bridge.
12
+ *
13
+ * activitypub is `default_enabled: false` — on a site without it loaded (e.g.
14
+ * chardonsbleus) the block correctly never appears in that site's catalog once
15
+ * the builtin seed is removed in 7d. Descriptor is byte-faithful to the
16
+ * BUILTIN_BLOCKS entry. Bespoke template: the theme owns
17
+ * `components/widgets/fediverse-follow.njk` (no generic `render.renderer`);
18
+ * `data.source:"config"` documents that it renders from config, not a runtime feed.
19
+ *
20
+ * @module lib/blocks
21
+ */
22
+
23
+ /** @type {Array<object>} */
24
+ export const ACTIVITYPUB_BLOCKS = [
25
+ {
26
+ id: "fediverse-follow",
27
+ version: 1,
28
+ label: "Fediverse Follow",
29
+ description: "Follow button for fediverse instances",
30
+ icon: "globe",
31
+ category: "social",
32
+ placement: { regions: ["sidebar"], surfaces: ["homepage"] },
33
+ multiple: false,
34
+ data: { source: "config" },
35
+ schema: { type: "object", additionalProperties: false, properties: {} },
36
+ },
37
+ ];
@@ -43,6 +43,10 @@ import { getSettings } from "./settings.js";
43
43
  /** @type {string} ActivityStreams Public Collection constant */
44
44
  const PUBLIC = "https://www.w3.org/ns/activitystreams#Public";
45
45
 
46
+ // Pure addressing/visibility helpers are exported for unit testing (see
47
+ // tests/inbox-visibility.test.js). They are not part of the handler API.
48
+ export { isDirectMessage as _isDirectMessage, computeVisibility as _computeVisibility };
49
+
46
50
  // ---------------------------------------------------------------------------
47
51
  // Router
48
52
  // ---------------------------------------------------------------------------
@@ -7,7 +7,9 @@
7
7
  */
8
8
 
9
9
  import { stripQuoteReferenceHtml } from "./og-unfurl.js";
10
- import { replaceCustomEmoji } from "./emoji-utils.js";
10
+ // Use the hardened replaceCustomEmoji (validates http(s) URL schemes + escapes
11
+ // attributes) — the render pipeline processes attacker-controlled remote emoji.
12
+ import { replaceCustomEmoji } from "./timeline-store.js";
11
13
  import { shortenDisplayUrls, collapseHashtagStuffing } from "./content-utils.js";
12
14
 
13
15
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rmdes/indiekit-endpoint-activitypub",
3
- "version": "3.13.8",
3
+ "version": "3.13.10",
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",
@@ -1,38 +0,0 @@
1
- /**
2
- * Custom emoji replacement for fediverse content.
3
- *
4
- * Replaces :shortcode: patterns with <img> tags for custom emoji.
5
- * Must be called AFTER sanitizeContent() — the inserted <img> tags
6
- * would be stripped if run through the sanitizer.
7
- */
8
-
9
- /**
10
- * Escape special regex characters in a string.
11
- * @param {string} str
12
- * @returns {string}
13
- */
14
- function escapeRegex(str) {
15
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
16
- }
17
-
18
- /**
19
- * Replace :shortcode: patterns in HTML with custom emoji <img> tags.
20
- *
21
- * @param {string} html - HTML string (already sanitized)
22
- * @param {Array<{shortcode: string, url: string}>} emojis - Custom emoji list
23
- * @returns {string} HTML with emoji shortcodes replaced by img tags
24
- */
25
- export function replaceCustomEmoji(html, emojis) {
26
- if (!html || !emojis?.length) return html;
27
-
28
- for (const emoji of emojis) {
29
- if (!emoji.shortcode || !emoji.url) continue;
30
- const pattern = new RegExp(`:${escapeRegex(emoji.shortcode)}:`, "g");
31
- html = html.replace(
32
- pattern,
33
- `<img src="${emoji.url}" alt=":${emoji.shortcode}:" title=":${emoji.shortcode}:" class="ap-custom-emoji" loading="lazy">`,
34
- );
35
- }
36
-
37
- return html;
38
- }