@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecency/render-helper",
3
- "version": "2.3.6",
3
+ "version": "2.3.7",
4
4
  "description": "Markdown+Html Render helper",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
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 /><span>\n<a class="markdown-author-link" data-author="sit">@Sit</a> amet</span></p>'
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
 
@@ -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
- const author = mentionMatch[2].replace('@', '').toLowerCase()
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, } from '../consts'
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
- if (!isValidPermlink(permlink)) return;
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(