From 8c53764761cb695a58219353e20c64f3e2c00a9d Mon Sep 17 00:00:00 2001 From: Rapougnac Date: Sat, 17 Aug 2024 01:16:02 +0200 Subject: [PATCH] feat: Add support for sanitizing slash commands mentions --- lib/src/utils/sanitizer.dart | 28 ++++++++++++++++++++++++---- test/unit/sanitizer_test.dart | 6 +++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/src/utils/sanitizer.dart b/lib/src/utils/sanitizer.dart index e2a897e..f078f3e 100644 --- a/lib/src/utils/sanitizer.dart +++ b/lib/src/utils/sanitizer.dart @@ -18,6 +18,15 @@ final channelMentionRegex = RegExp(r"<#(\d+)>"); /// A pattern that matches guild emojis in a message. final guildEmojiRegex = RegExp(r"<(a?):(\w+):(\d+)>"); +const _baseCommandNamePattern = r"[-_\p{L}\p{N}\p{sc=Deva}\p{sc=Thai}]+"; + +/// A pattern that matches slash commands in a message. +final commandMentionRegex = RegExp( + '<\\/(?(?:$_baseCommandNamePattern(?:\\s$_baseCommandNamePattern){0,2})):(\\d{17,19})>', + unicode: true, + multiLine: true, +); + /// A type of target [sanitizeContent] can operate on. enum SanitizerTarget { /// Sanitize user mentions that match [userMentionRegex]. @@ -34,6 +43,9 @@ enum SanitizerTarget { /// Sanitize guild emojis that match [guildEmojiRegex]. emojis, + + /// Sanitize slash commands mentions that match [commandMentionRegex]. + commands, } /// An action [sanitizeContent] can take on a target. @@ -77,9 +89,10 @@ Future sanitizeContent( SanitizerTarget.everyone => everyoneMentionRegex, SanitizerTarget.channels => channelMentionRegex, SanitizerTarget.emojis => guildEmojiRegex, + SanitizerTarget.commands => commandMentionRegex, }; - Future name(Match match, SanitizerTarget target) async => switch (target) { + Future name(RegExpMatch match, SanitizerTarget target) async => switch (target) { SanitizerTarget.everyone => match.group(1)!, SanitizerTarget.channels => switch (await client.channels[Snowflake.parse(match.group(1)!)].getOrNull()) { GuildChannel(:final name) || GroupDmChannel(:final name) => name, @@ -99,6 +112,7 @@ Future sanitizeContent( }, }, SanitizerTarget.emojis => match.group(2)!, + SanitizerTarget.commands => match.namedGroup('commandName')!, }; String prefix(SanitizerTarget target) => switch (target) { @@ -106,11 +120,16 @@ Future sanitizeContent( SanitizerTarget.everyone => '@$_whitespaceCharacter', SanitizerTarget.channels => '#', SanitizerTarget.emojis => '', + SanitizerTarget.commands => ' target == SanitizerTarget.emojis ? ':' : ''; + String suffix(SanitizerTarget target) => switch (target) { + SanitizerTarget.emojis => ':', + SanitizerTarget.commands => '>', + _ => '', + }; - Future resolve(Match match, SanitizerTarget target, SanitizerAction action) async => switch (action) { + Future resolve(RegExpMatch match, SanitizerTarget target, SanitizerAction action) async => switch (action) { SanitizerAction.ignore => match.group(0)!, SanitizerAction.remove => '', SanitizerAction.nameNoPrefix => await name(match, target), @@ -120,7 +139,8 @@ Future sanitizeContent( SanitizerTarget.roles => '<@&$_whitespaceCharacter${match.group(1)!}>', SanitizerTarget.everyone => '@$_whitespaceCharacter${match.group(1)!}', SanitizerTarget.channels => '<#$_whitespaceCharacter${match.group(1)!}>', - SanitizerTarget.emojis => '<$_whitespaceCharacter${match.group(1) ?? ''}:${match.group(2)}:${match.group(3)}>', + SanitizerTarget.emojis => '<$_whitespaceCharacter${match.group(1) ?? ''}\\:${match.group(2)}\\:${match.group(3)}>', + SanitizerTarget.commands => '', }, }; diff --git a/test/unit/sanitizer_test.dart b/test/unit/sanitizer_test.dart index c56edb6..3fa6ed7 100644 --- a/test/unit/sanitizer_test.dart +++ b/test/unit/sanitizer_test.dart @@ -5,10 +5,10 @@ import 'package:test/test.dart'; const _whitespaceCharacter = "‎"; -final sampleContent = '<@1234> test <@!2345> test2 <@&3456> test3 <#4567> test4 test5 <:test_emoji:6789>'; -final removed = ' test test2 test3 test4 test5 '; +final sampleContent = '<@1234> test <@!2345> test2 <@&3456> test3 <#4567> test4 test5 <:test_emoji:6789> test6 '; +final removed = ' test test2 test3 test4 test5 test6 '; final sanitized = - '<@${_whitespaceCharacter}1234> test <@${_whitespaceCharacter}2345> test2 <@&${_whitespaceCharacter}3456> test3 <#${_whitespaceCharacter}4567> test4 <${_whitespaceCharacter}a:test_emoji:5678> test5 <$_whitespaceCharacter:test_emoji:6789>'; + '<@${_whitespaceCharacter}1234> test <@${_whitespaceCharacter}2345> test2 <@&${_whitespaceCharacter}3456> test3 <#${_whitespaceCharacter}4567> test4 <${_whitespaceCharacter}a\\:test_emoji\\:5678> test5 <$_whitespaceCharacter\\:test_emoji\\:6789> test6 '; class MockNyxxRest with Mock implements NyxxRest {}