Skip to content

Commit 21e2d4d

Browse files
authored
fix: avoid numbered top-level domain (#972)
## Description - The regex has been modified to prevent numbers from being included in the top-level domain. - In the Word component, the URL validation for the URL type has been removed. - In the Word component, the use of UUID in the key has been removed. ticket: [CLNP-2262] [CLNP-2262]: https://sendbird.atlassian.net/browse/CLNP-2262?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent d45d7b8 commit 21e2d4d

File tree

3 files changed

+28
-39
lines changed

3 files changed

+28
-39
lines changed

src/modules/Message/utils/tokens/__tests__/tokenizeUtils.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,26 @@ describe('identifyUrlsAndStrings', () => {
146146
]);
147147
});
148148
});
149+
150+
it('should not parse invalid URLs', () => {
151+
const invalidURLs = [
152+
// with number top-level domain
153+
'abcd.1234',
154+
];
155+
156+
invalidURLs.forEach((url) => {
157+
const result = identifyUrlsAndStrings([
158+
{ type: 'undetermined', value: url },
159+
]);
160+
161+
expect(result).toEqual([
162+
{
163+
type: 'string',
164+
value: url,
165+
},
166+
]);
167+
});
168+
});
149169
});
150170

151171
describe('combineNearbyStrings', () => {

src/modules/Message/utils/tokens/tokenize.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function identifyMentions({
5151
}
5252

5353
export function identifyUrlsAndStrings(token: Token[]): Token[] {
54-
const URL_REG = /(?:https?:\/\/|www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.(xn--)?[a-z0-9-]{2,20}\b([-a-zA-Z0-9@:%_+[\],.~#?&/=]*[-a-zA-Z0-9@:%_+~#?&/=])*/g;
54+
const URL_REG = /(?:https?:\/\/|www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.(xn--)?[a-z]{2,20}\b([-a-zA-Z0-9@:%_+[\],.~#?&/=]*[-a-zA-Z0-9@:%_+~#?&/=])*/g;
5555
const results: Token[] = token.map((token) => {
5656
if (token.type !== TOKEN_TYPES.undetermined) {
5757
return token;
@@ -73,15 +73,13 @@ export function identifyUrlsAndStrings(token: Token[]): Token[] {
7373
const head = restText.slice(0, start - cursor);
7474
const mid = text;
7575
const tail = restText.slice(end - cursor);
76-
items.push({ value: head, type: TOKEN_TYPES.string }, { value: mid, type: TOKEN_TYPES.url });
76+
77+
if (head.length > 0) items.push({ value: head, type: TOKEN_TYPES.string });
78+
items.push({ value: mid, type: TOKEN_TYPES.url });
7779
if (tail.length > 0) items.push({ value: tail, type: TOKEN_TYPES.string });
7880
cursor = end;
7981
});
8082

81-
// Remove the first empty string
82-
if (items[0].value === '' && items[0].type === TOKEN_TYPES.string) {
83-
items.shift();
84-
}
8583
return items;
8684
}).flat();
8785

src/ui/Word/index.tsx

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import type { UserMessage } from '@sendbird/chat/message';
88

99
import { LabelTypography } from '../Label';
1010
import LinkLabel from '../LinkLabel';
11-
import uuidv4 from '../../utils/uuid';
1211
import { convertWordToStringObj, StringObjType, StringObj } from '../../utils';
1312
import MentionLabel from '../MentionLabel';
1413

@@ -35,57 +34,29 @@ export default function Word(props: WordProps): JSX.Element {
3534
return (
3635
<span className="sendbird-word">
3736
{
38-
convertWordToStringObj(word, message?.mentionedUsers).map((stringObj) => {
37+
convertWordToStringObj(word, message?.mentionedUsers).map((stringObj, index) => {
3938
const type = stringObj?.type || '';
4039
const value = stringObj?.value || '';
4140
const userId = stringObj?.userId || '';
41+
const key = `${value}-${index}`;
4242
if (renderString && typeof renderString === 'function') {
4343
return renderString(stringObj);
4444
}
4545
if (type === StringObjType.mention) {
4646
return (
4747
<MentionLabel
48+
key={key}
4849
mentionTemplate={mentionTemplate}
4950
mentionedUserId={userId}
5051
mentionedUserNickname={value}
51-
key={uuidv4()}
5252
isByMe={isByMe}
5353
/>
5454
);
5555
} else if (type === StringObjType.url) {
56-
const urlRegex = /([a-zA-Z0-9]+:\/\/)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\.[A-Za-z]{2,4})(:[0-9]+)?(\/.*)?/;
57-
const targetUrl = value.match(urlRegex)?.[0];
58-
const stringUrl = { front: '', url: '', back: '' };
59-
if (targetUrl) {
60-
const targetUrlIndex = value.indexOf(targetUrl);
61-
if (targetUrlIndex > 0) {
62-
stringUrl.front = value.slice(0, targetUrlIndex);
63-
}
64-
stringUrl.url = value.slice(targetUrlIndex, targetUrlIndex + targetUrl.length);
65-
if (targetUrlIndex + targetUrl.length < value.length) {
66-
stringUrl.back = value.slice(targetUrlIndex + targetUrl.length);
67-
}
68-
}
69-
if (targetUrl) {
70-
return [
71-
stringUrl.front ? stringUrl.front : '',
72-
stringUrl.url ? (
73-
<LinkLabel
74-
className="sendbird-word__url"
75-
key={uuidv4()}
76-
src={stringUrl.url}
77-
type={LabelTypography.BODY_1}
78-
>
79-
{stringUrl.url}
80-
</LinkLabel>
81-
) : null,
82-
stringUrl.back ? stringUrl.back : '',
83-
];
84-
}
8556
return (
8657
<LinkLabel
58+
key={key}
8759
className="sendbird-word__url"
88-
key={uuidv4()}
8960
src={word}
9061
type={LabelTypography.BODY_1}
9162
>

0 commit comments

Comments
 (0)