@ecency/render-helper 2.3.2 → 2.3.4

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.2",
3
+ "version": "2.3.4",
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
@@ -22,8 +22,18 @@ export function extractYtStartTime(url:string):string {
22
22
  return '' + parseInt(params.get('t')); //parsing is important as sometimes t is famated '123s';
23
23
  }else if (params.has('start')){
24
24
  return params.get('start');
25
- }
25
+ }
26
26
  } catch (error) {
27
27
  return '';
28
28
  }
29
29
  }
30
+ export function isValidPermlink(permlink: string): boolean {
31
+ // Should not contain image extensions, query params, or fragments
32
+ const isImage = /\.(jpg|jpeg|png|webp|gif|svg)$/i.test(permlink);
33
+ const hasSpecialChars = /[?#]/.test(permlink);
34
+ const isCleanFormat = /^[a-z0-9-]+$/.test(permlink); // Hive standard
35
+
36
+ return isCleanFormat && !isImage && !hasSpecialChars;
37
+ }
38
+
39
+
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ import { getPostBodySummary as postBodySummary } from './post-body-summary'
4
4
  import { setProxyBase, proxifyImageSrc } from './proxify-image-src'
5
5
  import { setCacheSize } from './cache'
6
6
  import { SECTION_LIST } from './consts'
7
+ import { isValidPermlink } from "./helper";
7
8
 
8
9
  export {
9
10
  renderPostBody,
@@ -12,5 +13,6 @@ export {
12
13
  proxifyImageSrc,
13
14
  setProxyBase,
14
15
  setCacheSize,
15
- SECTION_LIST
16
+ SECTION_LIST,
17
+ isValidPermlink
16
18
  }
@@ -910,7 +910,7 @@ describe('Markdown2Html', () => {
910
910
  last_update: '2019-05-10T09:15:21',
911
911
  body: 'direct link https://ecency.com/@ecency/faq?history'
912
912
  }
913
- const expected = '<p dir=\"auto\">direct link <a class=\"markdown-post-link\" data-href=\"https://ecency.com/@ecency/faq?history\" data-is-inline=\"false\" data-tag=\"post\" data-author=\"ecency\" data-permlink=\"faq?history\">@ecency/faq?history</a></p>'
913
+ const expected = '<p dir=\"auto\">direct link <a href=\"https://ecency.com/@ecency/faq?history\" class=\"markdown-post-link\">https://ecency.com/@ecency/faq?history</a></p>'
914
914
 
915
915
  expect(markdown2Html(input)).toBe(expected)
916
916
  })
@@ -922,7 +922,7 @@ describe('Markdown2Html', () => {
922
922
  last_update: '2019-05-10T09:15:21',
923
923
  body: 'direct link https://ecency.com/@ecency/posts?q=games'
924
924
  }
925
- const expected = '<p dir=\"auto\">direct link <a href=\"https://ecency.com/@ecency/posts?q=games\" class=\"markdown-profile-link\">@ecency/posts?q=games</a></p>'
925
+ const expected = '<p dir=\"auto\">direct link <a href=\"https://ecency.com/@ecency/posts?q=games\" class=\"markdown-profile-link\">https://ecency.com/@ecency/posts?q=games</a></p>'
926
926
 
927
927
  expect(markdown2Html(input)).toBe(expected)
928
928
  })
@@ -30,12 +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 } from '../helper'
33
+ import { extractYtStartTime, isValidPermlink } from '../helper'
34
34
 
35
- function isValidPermlink(permlink: string): boolean {
36
- // Reject anything that looks like a file (ends with .jpg/.png/.webp/.jpeg etc)
37
- return !/\.(jpg|jpeg|png|webp|gif|svg)$/i.test(permlink);
38
- }
39
35
 
40
36
  export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
41
37
  let href = el.getAttribute('href')
@@ -162,6 +158,7 @@ export function a(el: HTMLElement, forApp: boolean, webp: boolean): void {
162
158
  const author = tpostMatch[2].replace('@', '').toLowerCase()
163
159
  const section = tpostMatch[3]
164
160
 
161
+ if (!isValidPermlink(section)) return;
165
162
  if (el.textContent === href) {
166
163
  el.textContent = `@${author}/${section}`
167
164
  }
@@ -18,10 +18,10 @@ export function img(el: HTMLElement, webp: boolean): void {
18
18
  src = ""
19
19
  }
20
20
 
21
- // ❌ Skip relative paths (e.g., `photo.jpg`)
21
+ // ❌ Skip relative paths (e.g., `photo.jpg`, `./photo.png`, `assets/pic.jpeg`)
22
22
  const isRelative = !/^https?:\/\//i.test(src) && !src.startsWith("/");
23
23
  if (isRelative) {
24
- console.warn("Skipped relative image:", src);
24
+ //console.warn("Skipped relative image:", src);
25
25
  src = ""
26
26
  }
27
27
 
@@ -1,5 +1,6 @@
1
1
  import { IMG_REGEX, SECTION_LIST } from '../consts'
2
2
  import { proxifyImageSrc } from '../proxify-image-src'
3
+ import {isValidPermlink} from "../helper";
3
4
 
4
5
  export function linkify(content: string, forApp: boolean, webp: boolean): string {
5
6
  // Tags
@@ -33,13 +34,15 @@ export function linkify(content: string, forApp: boolean, webp: boolean): string
33
34
  content = content.replace(
34
35
  /((^|\s)(\/|)@[\w.\d-]+)\/(\S+)/gi, (match, u, p1, p2, p3) => {
35
36
  const uu = u.trim().toLowerCase().replace('/@', '').replace('@', '');
36
- const perm = p3;
37
+ const permlink = p3;
38
+ if (!isValidPermlink(permlink)) return match;
39
+
37
40
  if (SECTION_LIST.some(v => p3.includes(v))) {
38
- const attrs = forApp ? `https://ecency.com/@${uu}/${perm}` : `href="/@${uu}/${perm}"`
39
- return ` <a class="markdown-profile-link" ${attrs}>@${uu}/${perm}</a>`
41
+ const attrs = forApp ? `https://ecency.com/@${uu}/${permlink}` : `href="/@${uu}/${permlink}"`
42
+ return ` <a class="markdown-profile-link" ${attrs}>@${uu}/${permlink}</a>`
40
43
  } else {
41
- const attrs = forApp ? `data-author="${uu}" data-tag="post" data-permlink="${perm}"` : `href="/post/@${uu}/${perm}"`
42
- return ` <a class="markdown-post-link" ${attrs}>@${uu}/${perm}</a>`
44
+ const attrs = forApp ? `data-author="${uu}" data-tag="post" data-permlink="${permlink}"` : `href="/post/@${uu}/${permlink}"`
45
+ return ` <a class="markdown-post-link" ${attrs}>@${uu}/${permlink}</a>`
43
46
  }
44
47
  }
45
48
  )
@@ -1,5 +1,5 @@
1
1
  import { IMG_REGEX, YOUTUBE_REGEX, WHITE_LIST, DOMParser, POST_REGEX, } from '../consts'
2
- import { extractYtStartTime } from '../helper'
2
+ import { extractYtStartTime, isValidPermlink } from '../helper'
3
3
  import { proxifyImageSrc } from '../proxify-image-src'
4
4
  import { linkify } from './linkify.method'
5
5
 
@@ -59,6 +59,7 @@ export function text(node: HTMLElement, forApp: boolean, webp: boolean): void {
59
59
  const tag = postMatch[2]
60
60
  const author = postMatch[3].replace('@', '')
61
61
  const permlink = postMatch[4]
62
+ if (!isValidPermlink(permlink)) return;
62
63
 
63
64
  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
65
  const replaceNode = DOMParser.parseFromString(