@nodebb/nodebb-plugin-reactions 3.1.5 → 3.1.7

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/library.js CHANGED
@@ -30,47 +30,35 @@ function parse(name) {
30
30
  return emoji ? emojiParser.buildEmoji(emoji, '') : '';
31
31
  }
32
32
 
33
- async function parseReaction(name, sourceUrl) {
33
+ async function parseReaction(name) {
34
+ // Local emoji: name has no colon, resolve from table
34
35
  const emoji = nameToEmoji(name) || helpers.getEmojiTable()[helpers.getEmojiAliases()[name]];
35
36
  if (emoji) {
36
37
  return emojiParser.buildEmoji(emoji, '');
37
38
  }
38
39
 
39
- // Try to find the custom emoji: first by source URL hostname, then by scanning emoji:ap:lookup
40
- let hostname = null;
41
- if (typeof sourceUrl === 'string') {
42
- try {
43
- hostname = new URL(sourceUrl).hostname;
44
- } catch (e) {
45
- // Not a valid URL (e.g. numeric pid)
40
+ // Custom emoji: name is stored as shortcode:hostname (buildFieldKey format)
41
+ const idx = name.indexOf(':');
42
+ if (idx !== -1) {
43
+ const shortcode = name.slice(0, idx);
44
+ const hostname = name.slice(idx + 1);
45
+ const metadata = await activitypub.emoji.getEmoji(shortcode, hostname);
46
+ if (metadata) {
47
+ const proxyUrl = activitypub.emoji.getProxyUrl(shortcode, hostname);
48
+ return `<img class="not-responsive emoji" src="${proxyUrl}" title=":${shortcode}:" />`;
46
49
  }
47
50
  }
48
51
 
49
- let metadata = null;
50
- if (hostname) {
51
- metadata = await activitypub.emoji.getEmoji(name, hostname);
52
- }
53
-
54
- // Fallback: scan emoji:ap:lookup for any entry matching this shortcode
55
- if (!metadata) {
56
- const allKeys = await db.getObjectKeys('emoji:ap:lookup');
57
- if (allKeys && allKeys.length > 0) {
58
- const matchKey = allKeys.find(k => k.startsWith(`${name}:`));
59
- if (matchKey) {
60
- const idx = matchKey.indexOf(':');
61
- if (idx !== -1) {
62
- hostname = matchKey.slice(idx + 1);
63
- metadata = await activitypub.emoji.getEmoji(name, hostname);
64
- }
65
- }
66
- }
67
- }
52
+ return '';
53
+ }
68
54
 
69
- if (metadata) {
70
- const proxyUrl = activitypub.emoji.getProxyUrl(name, hostname);
71
- return `<img class="not-responsive emoji" src="${proxyUrl}" title=":${name}:" />`;
55
+ async function isValidReaction(name) {
56
+ // Allow local emoji
57
+ if (nameToEmoji(name) || helpers.getEmojiTable()[helpers.getEmojiAliases()[name]]) {
58
+ return true;
72
59
  }
73
- return '';
60
+ // Allow cached custom emoji (shortcode:hostname is the emoji:ap:lookup field key)
61
+ return db.isObjectField('emoji:ap:lookup', name);
74
62
  }
75
63
 
76
64
  const ReactionsPlugin = module.exports;
@@ -193,7 +181,7 @@ ReactionsPlugin.getPostReactions = async function (data) {
193
181
  for (const reaction of reactions) {
194
182
  const reactionSet = `pid:${post.pid}:reaction:${reaction}`;
195
183
  const uids = reactionSetToUsersMap.get(reactionSet);
196
- const reactionImage = await parseReaction(reaction, post.pid);
184
+ const reactionImage = await parseReaction(reaction);
197
185
  if (Array.isArray(uids) && reactionImage) {
198
186
  post.reactions.push({
199
187
  pid: post.pid,
@@ -258,7 +246,7 @@ ReactionsPlugin.getMessageReactions = async function (data) {
258
246
  for (const reaction of reactions) {
259
247
  const reactionSet = `mid:${msg.mid}:reaction:${reaction}`;
260
248
  const uids = reactionSetToUsersMap.get(reactionSet);
261
- const reactionImage = await parseReaction(reaction, msg.mid);
249
+ const reactionImage = await parseReaction(reaction);
262
250
  if (Array.isArray(uids) && reactionImage) {
263
251
  msg.reactions.push({
264
252
  mid: msg.mid,
@@ -333,7 +321,7 @@ async function sendPostEvent(data, eventName) {
333
321
  reaction: data.reaction,
334
322
  reactionCount,
335
323
  totalReactions,
336
- reactionImage: await parseReaction(data.reaction, data.pid),
324
+ reactionImage: await parseReaction(data.reaction),
337
325
  });
338
326
  } catch (e) {
339
327
  console.error(e);
@@ -357,7 +345,7 @@ async function sendMessageEvent(data, eventName) {
357
345
  reaction: data.reaction,
358
346
  reactionCount,
359
347
  totalReactions,
360
- reactionImage: await parseReaction(data.reaction, data.mid),
348
+ reactionImage: await parseReaction(data.reaction),
361
349
  });
362
350
  } catch (e) {
363
351
  console.error(e);
@@ -572,7 +560,16 @@ ReactionsPlugin.applyEmojiReact = async function (activity) {
572
560
  cacheTag = null;
573
561
  }
574
562
  if (cacheTag) {
575
- await activitypub.emoji.cacheEmoji(cacheTag);
563
+ const cached = await activitypub.emoji.cacheEmoji(cacheTag);
564
+ if (cached) {
565
+ // Use the normalized icon from cacheTag to extract hostname
566
+ const hostname = activitypub.emoji.extractHostname(cacheTag.icon);
567
+ if (hostname) {
568
+ // Store reaction as qualified name: shortcode:hostname
569
+ // (matches the emoji:ap:lookup field key for direct lookup)
570
+ reaction = activitypub.emoji.buildFieldKey(reaction, hostname);
571
+ }
572
+ }
576
573
  }
577
574
  }
578
575
 
@@ -602,7 +599,23 @@ ReactionsPlugin.undoEmojiReact = async function (activity) {
602
599
  return false;
603
600
  }
604
601
 
605
- const reaction = typeof resolved === 'object' ? resolved.emoji : resolved;
602
+ let reaction;
603
+ let emojiTag;
604
+ if (typeof resolved === 'object' && resolved.emoji) {
605
+ reaction = resolved.emoji;
606
+ emojiTag = resolved.emojiTag;
607
+ } else {
608
+ reaction = resolved;
609
+ }
610
+
611
+ // Rebuild qualified name for custom emoji (must match the stored name)
612
+ if (emojiTag) {
613
+ const icon = emojiTag.icon || (emojiTag.id ? { url: emojiTag.id } : null);
614
+ const hostname = activitypub.emoji.extractHostname(icon);
615
+ if (hostname) {
616
+ reaction = activitypub.emoji.buildFieldKey(reaction, hostname);
617
+ }
618
+ }
606
619
 
607
620
  activitypub.helpers.log(`[reactions/ap] undo id ${id} (${reaction}) via ${actor}`);
608
621
  await ReactionsPlugin.removePostReaction(id, actor, reaction);
@@ -699,7 +712,7 @@ SocketPlugins.reactions = {
699
712
  throw new Error('[[error:not-logged-in]]');
700
713
  }
701
714
 
702
- if (!nameToEmoji(data.reaction)) {
715
+ if (!(await isValidReaction(data.reaction))) {
703
716
  throw new Error('[[reactions:error.invalid-reaction]]');
704
717
  }
705
718
 
@@ -711,7 +724,7 @@ SocketPlugins.reactions = {
711
724
  throw new Error('[[error:not-logged-in]]');
712
725
  }
713
726
 
714
- if (!nameToEmoji(data.reaction)) {
727
+ if (!(await isValidReaction(data.reaction))) {
715
728
  throw new Error('[[reactions:error.invalid-reaction]]');
716
729
  }
717
730
 
@@ -723,7 +736,7 @@ SocketPlugins.reactions = {
723
736
  throw new Error('[[error:not-logged-in]]');
724
737
  }
725
738
 
726
- if (!nameToEmoji(data.reaction)) {
739
+ if (!(await isValidReaction(data.reaction))) {
727
740
  throw new Error('[[reactions:error.invalid-reaction]]');
728
741
  }
729
742
 
@@ -803,7 +816,7 @@ SocketPlugins.reactions = {
803
816
  throw new Error('[[error:not-logged-in]]');
804
817
  }
805
818
 
806
- if (!nameToEmoji(data.reaction)) {
819
+ if (!(await isValidReaction(data.reaction))) {
807
820
  throw new Error('[[reactions:error.invalid-reaction]]');
808
821
  }
809
822
 
@@ -835,7 +848,7 @@ SocketPlugins.reactions = {
835
848
  if (!socket.uid) {
836
849
  throw new Error('[[error:not-logged-in]]');
837
850
  }
838
- if (!nameToEmoji(data.reaction)) {
851
+ if (!(await isValidReaction(data.reaction))) {
839
852
  throw new Error('[[reactions:error.invalid-reaction]]');
840
853
  }
841
854
  let set;
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "nodebb-plugin-reactions",
3
- "version": "3.1.5",
3
+ "version": "3.1.7",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "nodebb-plugin-reactions",
9
- "version": "3.1.5",
9
+ "version": "3.1.7",
10
10
  "license": "MIT",
11
11
  "devDependencies": {
12
12
  "eslint": "10.6.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodebb/nodebb-plugin-reactions",
3
- "version": "3.1.5",
3
+ "version": "3.1.7",
4
4
  "nbbpm": {
5
5
  "compatibility": "^4.16.0"
6
6
  },