@ecency/render-helper 2.3.6 → 2.3.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/lib/helper.d.ts +1 -0
- package/lib/helper.js +20 -1
- package/lib/helper.js.map +1 -1
- package/lib/methods/a.method.js +8 -2
- package/lib/methods/a.method.js.map +1 -1
- package/lib/methods/linkify.method.js +1 -1
- package/lib/methods/linkify.method.js.map +1 -1
- package/lib/methods/text.method.js +2 -0
- package/lib/methods/text.method.js.map +1 -1
- package/lib/render-helper.js +1 -1
- package/package.json +1 -1
- package/src/helper.ts +22 -0
- package/src/markdown-2-html.spec.ts +1 -1
- package/src/methods/a.method.ts +11 -4
- package/src/methods/linkify.method.ts +3 -3
- package/src/methods/text.method.ts +5 -3
package/package.json
CHANGED
package/src/helper.ts
CHANGED
|
@@ -36,4 +36,26 @@ export function isValidPermlink(permlink: string): boolean {
|
|
|
36
36
|
return isCleanFormat && !isImage && !hasSpecialChars;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
// Reference: https://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax
|
|
40
|
+
// Hive account names must follow similar rules to DNS (RFC 1035)
|
|
41
|
+
const LABEL_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
42
|
+
|
|
43
|
+
export function isValidUsername(username: string): boolean {
|
|
44
|
+
if (!username || typeof username !== 'string') return false;
|
|
45
|
+
if (username.length > 16) return false;
|
|
46
|
+
|
|
47
|
+
const labels = username.split('.');
|
|
48
|
+
|
|
49
|
+
return labels.every(label => {
|
|
50
|
+
return (
|
|
51
|
+
label.length >= 3 &&
|
|
52
|
+
label.length <= 16 &&
|
|
53
|
+
/^[a-z]/.test(label) && // must start with a letter
|
|
54
|
+
LABEL_REGEX.test(label) && // a-z0-9, hyphens, no start/end hyphen
|
|
55
|
+
!label.includes('..') // double dots are impossible after split, but just in case
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
39
61
|
|
|
@@ -270,7 +270,7 @@ describe('Markdown2Html', () => {
|
|
|
270
270
|
body: '@lorem @ipsum @dolor \n @Sit amet'
|
|
271
271
|
}
|
|
272
272
|
expected =
|
|
273
|
-
'<p dir=\"auto\"><span><a class="markdown-author-link" data-author="lorem">@lorem</a> <a class="markdown-author-link" data-author="ipsum">@ipsum</a> <a class="markdown-author-link" data-author="dolor">@dolor</a></span><br
|
|
273
|
+
'<p dir=\"auto\"><span><a class="markdown-author-link" data-author="lorem">@lorem</a> <a class="markdown-author-link" data-author="ipsum">@ipsum</a> <a class="markdown-author-link" data-author="dolor">@dolor</a></span><br />\n@Sit amet</p>'
|
|
274
274
|
expect(markdown2Html(input)).toBe(expected)
|
|
275
275
|
})
|
|
276
276
|
|
package/src/methods/a.method.ts
CHANGED
|
@@ -30,8 +30,8 @@ import {
|
|
|
30
30
|
import { getSerializedInnerHTML } from './get-inner-html.method'
|
|
31
31
|
import { proxifyImageSrc } from '../proxify-image-src'
|
|
32
32
|
import { removeChildNodes } from './remove-child-nodes.method'
|
|
33
|
-
import { extractYtStartTime, isValidPermlink } from '../helper'
|
|
34
|
-
import {createImageHTML} from "./img.method";
|
|
33
|
+
import { extractYtStartTime, isValidPermlink, isValidUsername } from '../helper'
|
|
34
|
+
import { createImageHTML } from "./img.method";
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
@@ -128,8 +128,12 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
128
128
|
// If a hive user with url
|
|
129
129
|
const mentionMatch = href.match(MENTION_REGEX)
|
|
130
130
|
if (mentionMatch && WHITE_LIST.includes(mentionMatch[1].replace(/www./,'')) && mentionMatch.length === 3) {
|
|
131
|
+
const _author = mentionMatch[2].replace('@', '')
|
|
132
|
+
if (!isValidUsername(_author)) return
|
|
133
|
+
const author = _author.toLowerCase()
|
|
134
|
+
|
|
131
135
|
el.setAttribute('class', 'markdown-author-link')
|
|
132
|
-
|
|
136
|
+
|
|
133
137
|
if (author.indexOf('/')===-1) {
|
|
134
138
|
if (el.textContent === href) {
|
|
135
139
|
el.textContent = `@${author}`
|
|
@@ -213,8 +217,11 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
213
217
|
// If a hive user with internal url
|
|
214
218
|
const imentionMatch = href.match(INTERNAL_MENTION_REGEX)
|
|
215
219
|
if (imentionMatch) {
|
|
220
|
+
const _author = imentionMatch[0].replace('/@', '')
|
|
221
|
+
if (!isValidUsername(_author)) return
|
|
222
|
+
const author = _author.toLowerCase()
|
|
223
|
+
|
|
216
224
|
el.setAttribute('class', 'markdown-author-link')
|
|
217
|
-
const author = imentionMatch[0].replace('/@', '').toLowerCase()
|
|
218
225
|
if (author.indexOf('/')===-1) {
|
|
219
226
|
if (el.textContent === href) {
|
|
220
227
|
el.textContent = `@${author}`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IMG_REGEX, SECTION_LIST } from '../consts'
|
|
2
2
|
import { proxifyImageSrc } from '../proxify-image-src'
|
|
3
|
-
import {isValidPermlink} from "../helper";
|
|
4
|
-
import {createImageHTML} from "./img.method";
|
|
3
|
+
import { isValidPermlink, isValidUsername } from "../helper";
|
|
4
|
+
import { createImageHTML } from "./img.method";
|
|
5
5
|
|
|
6
6
|
export function linkify(content: string, forApp: boolean, webp: boolean): string {
|
|
7
7
|
// Tags
|
|
@@ -22,7 +22,7 @@ export function linkify(content: string, forApp: boolean, webp: boolean): string
|
|
|
22
22
|
(match, preceeding1, preceeding2, user) => {
|
|
23
23
|
const userLower = user.toLowerCase()
|
|
24
24
|
const preceedings = (preceeding1 || '') + (preceeding2 || '')
|
|
25
|
-
if (userLower.indexOf('/') === -1) {
|
|
25
|
+
if (userLower.indexOf('/') === -1 && isValidUsername(user)) {
|
|
26
26
|
const attrs = forApp ? `data-author="${userLower}"` : `href="/@${userLower}"`
|
|
27
27
|
return `${preceedings}<a class="markdown-author-link" ${attrs}>@${user}</a>`
|
|
28
28
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IMG_REGEX, YOUTUBE_REGEX, WHITE_LIST, DOMParser, POST_REGEX
|
|
2
|
-
import { extractYtStartTime, isValidPermlink } from '../helper'
|
|
1
|
+
import { IMG_REGEX, YOUTUBE_REGEX, WHITE_LIST, DOMParser, POST_REGEX } from '../consts'
|
|
2
|
+
import { extractYtStartTime, isValidPermlink, isValidUsername } from '../helper'
|
|
3
3
|
import { proxifyImageSrc } from '../proxify-image-src'
|
|
4
4
|
import { linkify } from './linkify.method'
|
|
5
5
|
import {createImageHTML} from "./img.method";
|
|
@@ -58,7 +58,9 @@ export function text(node: HTMLElement, forApp: boolean, webp: boolean): void {
|
|
|
58
58
|
const tag = postMatch[2]
|
|
59
59
|
const author = postMatch[3].replace('@', '')
|
|
60
60
|
const permlink = postMatch[4]
|
|
61
|
-
|
|
61
|
+
|
|
62
|
+
if (!isValidUsername(author)) return
|
|
63
|
+
if (!isValidPermlink(permlink)) return
|
|
62
64
|
|
|
63
65
|
const attrs = forApp ? `data-tag="${tag}" data-author="${author}" data-permlink="${permlink}" class="markdown-post-link"` : `class="markdown-post-link" href="/${tag}/@${author}/${permlink}"`
|
|
64
66
|
const replaceNode = DOMParser.parseFromString(
|