@tak-ps/vue-tabler 4.21.0 → 4.23.1

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.
@@ -7,7 +7,7 @@ on:
7
7
 
8
8
  permissions:
9
9
  id-token: write # Required for OIDC
10
- contents: read
10
+ contents: write
11
11
 
12
12
  jobs:
13
13
  build:
@@ -31,3 +31,11 @@ jobs:
31
31
 
32
32
  - name: Publish package
33
33
  run: npm publish --provenance --access public
34
+
35
+ - name: Generate CHANGELOG
36
+ run: grep -Pzo "### ${{ github.ref_name }}(?s).*?(?=###)" CHANGELOG.md > RELEASE
37
+
38
+ - name: Github Release
39
+ uses: softprops/action-gh-release@v2
40
+ with:
41
+ body_path: RELEASE
package/CHANGELOG.md CHANGED
@@ -10,7 +10,15 @@
10
10
 
11
11
  ## Version History
12
12
 
13
- ### v4.21.0
13
+ ### v4.23.1
14
+
15
+ - :bug: Add sanitize helper fn
16
+
17
+ ### v4.23.0
18
+
19
+ - :pencil2: Add GH Release system
20
+
21
+ ### v4.22.0
14
22
 
15
23
  - :rocket: Migrate to more modern `marked` instead of `showdown`
16
24
 
package/README.md CHANGED
@@ -97,6 +97,7 @@ This library relies on the following core dependencies:
97
97
  - [Vue 3](https://vuejs.org/)
98
98
  - [@tabler/icons-vue](https://www.npmjs.com/package/@tabler/icons-vue)
99
99
  - [marked](https://www.npmjs.com/package/marked) (for Markdown rendering)
100
+ - [DOMPurify](https://www.npmjs.com/package/dompurify) (for HTML sanitization)
100
101
 
101
102
  ## 📄 License
102
103
 
@@ -1,12 +1,15 @@
1
1
  <template>
2
+ <!-- eslint-disable vue/no-v-html -->
2
3
  <div
3
4
  :style='autowrap ? `white-space: pre-wrap;` : ``'
4
5
  v-html='html'
5
6
  />
7
+ <!-- eslint-enable vue/no-v-html -->
6
8
  </template>
7
9
 
8
10
  <script setup lang="ts">
9
11
  import { computed } from 'vue'
12
+ import DOMPurify from 'dompurify'
10
13
  import { marked } from 'marked'
11
14
 
12
15
  export interface MarkdownProps {
@@ -18,10 +21,20 @@ const props = withDefaults(defineProps<MarkdownProps>(), {
18
21
  autowrap: true
19
22
  });
20
23
 
24
+ function sanitizeHtml(html: string): string {
25
+ return DOMPurify.sanitize(html, {
26
+ USE_PROFILES: {
27
+ html: true
28
+ }
29
+ })
30
+ }
31
+
21
32
  const html = computed(() => {
22
- return marked.parse(props.markdown, {
33
+ const rendered = marked.parse(props.markdown, {
23
34
  async: false,
24
35
  gfm: true
25
36
  })
37
+
38
+ return sanitizeHtml(rendered)
26
39
  })
27
40
  </script>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/vue-tabler",
3
3
  "type": "module",
4
- "version": "4.21.0",
4
+ "version": "4.23.1",
5
5
  "lib": "lib.ts",
6
6
  "main": "lib.ts",
7
7
  "module": "lib.ts",
@@ -27,6 +27,7 @@
27
27
  "homepage": "https://github.com/tak-ps/vue-tabler#readme",
28
28
  "dependencies": {
29
29
  "@tabler/icons-vue": "^3.0.0",
30
+ "dompurify": "^3.4.1",
30
31
  "marked": "^18.0.2"
31
32
  },
32
33
  "peerDependencies": {
@@ -0,0 +1,30 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import Markdown from '../components/Markdown.vue'
4
+
5
+ describe('TablerMarkdown', () => {
6
+ it('renders markdown and basic HTML', () => {
7
+ const wrapper = mount(Markdown, {
8
+ props: {
9
+ markdown: '# Title\n\n<div class="note">Allowed HTML</div>'
10
+ }
11
+ })
12
+
13
+ expect(wrapper.html()).toContain('<h1>Title</h1>')
14
+ expect(wrapper.html()).toContain('<div class="note">Allowed HTML</div>')
15
+ })
16
+
17
+ it('sanitizes unsafe HTML before rendering', () => {
18
+ const wrapper = mount(Markdown, {
19
+ props: {
20
+ markdown: '<img src="x" onerror="alert(1)"><script>alert(2)</script><a href="javascript:alert(3)">bad</a>'
21
+ }
22
+ })
23
+
24
+ expect(wrapper.html()).toContain('<img src="x">')
25
+ expect(wrapper.html()).toContain('<a>bad</a>')
26
+ expect(wrapper.html()).not.toContain('onerror')
27
+ expect(wrapper.html()).not.toContain('<script>')
28
+ expect(wrapper.html()).not.toContain('javascript:')
29
+ })
30
+ })