@evanp/activitypub-bot 0.46.0 → 0.46.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.
package/CHANGELOG.md CHANGED
@@ -9,6 +9,18 @@ and this project adheres to
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.46.2] - 2026-05-25
13
+
14
+ ### Fixed
15
+
16
+ - Over-escaped URLs in Transformer.transform()
17
+
18
+ ## [0.46.1] - 2026-05-25
19
+
20
+ ### Fixed
21
+
22
+ - Better escaping for Webfinger, Hashtags, and URLs in HTML output
23
+
12
24
  ## [0.46.0] - 2026-05-25
13
25
 
14
26
  ### Added
@@ -26,12 +26,7 @@ export class Transformer {
26
26
  }
27
27
 
28
28
  async transform (text) {
29
- let html = text
30
- .replace(/&/g, '&')
31
- .replace(/</g, '&lt;')
32
- .replace(/>/g, '&gt;')
33
- .replace(/"/g, '&quot;')
34
- .replace(/'/g, '&apos;')
29
+ let html = this.#escape(text)
35
30
  let tag = [];
36
31
  ({ html, tag } = this.#replaceUrls(html, tag));
37
32
  ({ html, tag } = this.#replaceHashtags(html, tag));
@@ -62,7 +57,9 @@ export class Transformer {
62
57
  segments[i] = segment.replace(hashtag, (match, name) => {
63
58
  const href = this.#tagNamespace + name
64
59
  tag.push({ type: AS2 + 'Hashtag', name: match, href })
65
- return `<a href="${href}">${match}</a>`
60
+ const escaped = this.#escape(href)
61
+ const escapedMatch = this.#escape(match)
62
+ return `<a href="${escaped}">${escapedMatch}</a>`
66
63
  })
67
64
  }
68
65
  return { html: segments.join(''), tag }
@@ -78,8 +75,19 @@ export class Transformer {
78
75
  segments[i] = await this.#replaceAsync(segments[i], webfinger, async (match) => {
79
76
  const href = await self.#homePage(match.slice(1))
80
77
  if (!href) return match
81
- tag.push({ type: 'Mention', name: match, href })
82
- return `<a href="${href}">${match}</a>`
78
+ let url
79
+ try {
80
+ url = new URL(href)
81
+ } catch (err) {
82
+ return match
83
+ }
84
+ if (url.protocol !== 'https:') {
85
+ return match
86
+ }
87
+ tag.push({ type: 'Mention', name: match, href: url.href })
88
+ const escaped = this.#escape(url.href)
89
+ const escapedMatch = this.#escape(match)
90
+ return `<a href="${escaped}">${escapedMatch}</a>`
83
91
  })
84
92
  }
85
93
  return { html: segments.join(''), tag }
@@ -157,4 +165,13 @@ export class Transformer {
157
165
  // Replace the matches with their respective replacements
158
166
  return str.replace(regex, () => replacements.shift())
159
167
  }
168
+
169
+ #escape (text) {
170
+ return text
171
+ .replace(/&/g, '&amp;')
172
+ .replace(/</g, '&lt;')
173
+ .replace(/>/g, '&gt;')
174
+ .replace(/"/g, '&quot;')
175
+ .replace(/'/g, '&apos;')
176
+ }
160
177
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evanp/activitypub-bot",
3
- "version": "0.46.0",
3
+ "version": "0.46.2",
4
4
  "description": "server-side ActivityPub bot framework",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",