fix: don't allow unnecessary attributes in profile bio

This commit is contained in:
Jannat Patel
2025-09-16 11:34:09 +05:30
parent e16cecd149
commit ed162e2546
6 changed files with 46 additions and 4 deletions
+1
View File
@@ -30,6 +30,7 @@
"chart.js": "^4.4.1", "chart.js": "^4.4.1",
"codemirror": "^6.0.1", "codemirror": "^6.0.1",
"dayjs": "^1.11.6", "dayjs": "^1.11.6",
"dompurify": "^3.2.6",
"feather-icons": "^4.28.0", "feather-icons": "^4.28.0",
"frappe-ui": "0.1.173", "frappe-ui": "0.1.173",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
+18 -1
View File
@@ -97,7 +97,8 @@ import {
} from 'frappe-ui' } from 'frappe-ui'
import { reactive, watch } from 'vue' import { reactive, watch } from 'vue'
import { FileText, X } from 'lucide-vue-next' import { FileText, X } from 'lucide-vue-next'
import { getFileSize } from '@/utils' import { getFileSize, decodeEntities } from '@/utils'
import DOMPurify from 'dompurify'
const reloadProfile = defineModel('reloadProfile') const reloadProfile = defineModel('reloadProfile')
@@ -147,6 +148,22 @@ const updateProfile = createResource({
}) })
const saveProfile = (close) => { const saveProfile = (close) => {
profile.bio = DOMPurify.sanitize(decodeEntities(profile.bio), {
ALLOWED_TAGS: [
'b',
'i',
'em',
'strong',
'a',
'p',
'br',
'ul',
'ol',
'li',
'img',
],
ALLOWED_ATTR: ['href', 'target', 'src'],
})
updateProfile.submit( updateProfile.submit(
{}, {},
{ {
+20 -1
View File
@@ -5,7 +5,24 @@
</h2> </h2>
<div <div
v-if="profile.data.bio" v-if="profile.data.bio"
v-html="profile.data.bio" v-html="
DOMPurify.sanitize(decodeEntities(profile.data.bio), {
ALLOWED_TAGS: [
'b',
'i',
'em',
'strong',
'a',
'p',
'br',
'ul',
'ol',
'li',
'img',
],
ALLOWED_ATTR: ['href', 'target', 'rel', 'src'],
})
"
class="ProseMirror prose prose-table:table-fixed prose-td:p-2 prose-th:p-2 prose-td:border prose-th:border prose-td:border-outline-gray-2 prose-th:border-outline-gray-2 prose-td:relative prose-th:relative prose-th:bg-surface-gray-2 prose-sm max-w-none !whitespace-normal" class="ProseMirror prose prose-table:table-fixed prose-td:p-2 prose-th:p-2 prose-td:border prose-th:border prose-td:border-outline-gray-2 prose-th:border-outline-gray-2 prose-td:relative prose-th:relative prose-th:bg-surface-gray-2 prose-sm max-w-none !whitespace-normal"
></div> ></div>
<div v-else class="text-ink-gray-7 text-sm italic"> <div v-else class="text-ink-gray-7 text-sm italic">
@@ -101,6 +118,8 @@ import { inject } from 'vue'
import { createResource, Popover, Button } from 'frappe-ui' import { createResource, Popover, Button } from 'frappe-ui'
import { X, LinkedinIcon, Twitter } from 'lucide-vue-next' import { X, LinkedinIcon, Twitter } from 'lucide-vue-next'
import { sessionStore } from '@/stores/session' import { sessionStore } from '@/stores/session'
import { decodeEntities } from '@/utils'
import DOMPurify from 'dompurify'
const dayjs = inject('$dayjs') const dayjs = inject('$dayjs')
const { branding } = sessionStore() const { branding } = sessionStore()
+1 -1
View File
@@ -119,7 +119,7 @@
<FormControl <FormControl
v-if="quizDetails.doc.enable_negative_marking" v-if="quizDetails.doc.enable_negative_marking"
v-model="quizDetails.doc.marks_to_cut" v-model="quizDetails.doc.marks_to_cut"
:label="__('Marks to Cut')" :label="__('Marks to Deduct')"
/> />
</div> </div>
</div> </div>
+6
View File
@@ -799,3 +799,9 @@ export const blockQuotesClick = () => {
}) })
}) })
} }
export const decodeEntities = (encodedString) => {
const textarea = document.createElement('textarea')
textarea.innerHTML = encodedString
return textarea.value
}
-1
View File
@@ -1975,7 +1975,6 @@ def get_program_details(program_name):
"member_count", "member_count",
"course_count", "course_count",
"published", "published",
"allow_self_enrollment",
"enforce_course_order", "enforce_course_order",
], ],
as_dict=1, as_dict=1,