Merge pull request #2264 from pateljannat/issues-217

fix: better sanitization of form fields
This commit is contained in:
Jannat Patel
2026-03-27 12:15:52 +05:30
committed by GitHub
10 changed files with 23 additions and 51 deletions

View File

@@ -72,7 +72,7 @@
<script setup lang="ts">
import { Button, Dialog, FormControl, TextEditor, toast } from 'frappe-ui'
import { computed, reactive, watch } from 'vue'
import { escapeHTML, sanitizeHTML } from '@/utils'
import { sanitizeHTML } from '@/utils'
import Link from '@/components/Controls/Link.vue'
const show = defineModel()
@@ -133,7 +133,7 @@ watch(show, (newVal) => {
})
const validateFields = () => {
assignment.title = escapeHTML(assignment.title.trim())
assignment.title = sanitizeHTML(assignment.title.trim())
assignment.question = sanitizeHTML(assignment.question)
}

View File

@@ -321,7 +321,6 @@ import {
} from 'frappe-ui'
import {
createLMSCategory,
escapeHTML,
getMetaInfo,
openSettings,
sanitizeHTML,
@@ -460,15 +459,9 @@ const formatTime = (timeStr) => {
}
const validateFields = () => {
batchDetail.doc.description = sanitizeHTML(batchDetail.doc.description)
batchDetail.doc.batch_details = sanitizeHTML(batchDetail.doc.batch_details)
Object.keys(batchDetail.doc).forEach((key) => {
if (
!['description', 'batch_details'].includes(key) &&
typeof batchDetail.doc[key] === 'string'
) {
batchDetail.doc[key] = escapeHTML(batchDetail.doc[key])
if (typeof batchDetail.doc[key] === 'string') {
batchDetail.doc[key] = sanitizeHTML(batchDetail.doc[key])
}
})
}

View File

@@ -120,7 +120,7 @@ import { Button, Dialog, FormControl, TextEditor, toast } from 'frappe-ui'
import { useOnboarding, useTelemetry } from 'frappe-ui/frappe'
import { computed, inject, onMounted, onBeforeUnmount, ref } from 'vue'
import { useRouter } from 'vue-router'
import { sanitizeHTML, escapeHTML, createLMSCategory } from '@/utils'
import { sanitizeHTML, createLMSCategory } from '@/utils'
import MultiSelect from '@/components/Controls/MultiSelect.vue'
import Link from '@/components/Controls/Link.vue'
import NewMemberModal from '@/components/Modals/NewMemberModal.vue'
@@ -179,16 +179,9 @@ const onInstructorCreated = (user: any) => {
}
const validateFields = () => {
batch.value.description = sanitizeHTML(batch.value.description)
batch.value.batch_details = sanitizeHTML(batch.value.batch_details)
Object.keys(batch.value).forEach((key) => {
if (
key != 'description' &&
key != 'batch_details' &&
typeof batch.value[key as keyof Batch] === 'string'
) {
batch.value[key as keyof Batch] = escapeHTML(
if (typeof batch.value[key as keyof Batch] === 'string') {
batch.value[key as keyof Batch] = sanitizeHTML(
batch.value[key as keyof Batch] as string
)
}

View File

@@ -355,7 +355,6 @@ import {
getCurrentInstance,
} from 'vue'
import {
escapeHTML,
getMetaInfo,
sanitizeHTML,
updateMetaInfo,
@@ -473,11 +472,9 @@ const onMemberCreated = (user) => {
}
const validateFields = () => {
courseResource.doc.description = sanitizeHTML(courseResource.doc.description)
Object.keys(courseResource.doc).forEach((key) => {
if (key != 'description' && typeof courseResource.doc[key] === 'string') {
courseResource.doc[key] = escapeHTML(courseResource.doc[key])
if (typeof courseResource.doc[key] === 'string') {
courseResource.doc[key] = sanitizeHTML(courseResource.doc[key])
}
})
}

View File

@@ -83,12 +83,7 @@ import { useOnboarding, useTelemetry } from 'frappe-ui/frappe'
import { inject, onMounted, onBeforeUnmount, ref } from 'vue'
import { useRouter } from 'vue-router'
import Link from '@/components/Controls/Link.vue'
import {
cleanError,
sanitizeHTML,
escapeHTML,
createLMSCategory,
} from '@/utils'
import { cleanError, sanitizeHTML, createLMSCategory } from '@/utils'
import MultiSelect from '@/components/Controls/MultiSelect.vue'
import Uploader from '@/components/Controls/Uploader.vue'
import NewMemberModal from '@/components/Modals/NewMemberModal.vue'
@@ -136,14 +131,9 @@ const onInstructorCreated = (user: any) => {
}
const validateFields = () => {
course.value.description = sanitizeHTML(course.value.description)
Object.keys(course.value).forEach((key) => {
if (
key != 'description' &&
typeof course.value[key as keyof Course] === 'string'
) {
course.value[key as keyof Course] = escapeHTML(
if (typeof course.value[key as keyof Course] === 'string') {
course.value[key as keyof Course] = sanitizeHTML(
course.value[key as keyof Course] as string
)
}

View File

@@ -135,7 +135,7 @@ import {
} from 'vue'
import { sessionStore } from '@/stores/session'
import { useRouter } from 'vue-router'
import { escapeHTML, sanitizeHTML } from '@/utils'
import { sanitizeHTML } from '@/utils'
import Uploader from '@/components/Controls/Uploader.vue'
const user = inject('$user')
@@ -269,10 +269,9 @@ const editJobDetails = () => {
}
const validateJobFields = () => {
job.description = sanitizeHTML(job.description)
Object.keys(job).forEach((key) => {
if (key != 'description' && typeof job[key] === 'string') {
job[key] = escapeHTML(job[key])
if (typeof job[key] === 'string') {
job[key] = sanitizeHTML(job[key])
}
})
}

View File

@@ -112,7 +112,7 @@
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { escapeHTML } from '@/utils'
import { sanitizeHTML } from '@/utils'
import {
Badge,
Button,
@@ -213,7 +213,7 @@ const fetchTestCases = () => {
}
const validateTitle = () => {
exercise.value.title = escapeHTML(exercise.value.title.trim())
exercise.value.title = sanitizeHTML(exercise.value.title.trim())
}
watch(

View File

@@ -254,7 +254,7 @@ import {
import { computed, ref, watch, getCurrentInstance } from 'vue'
import { Plus, Trash2, TrendingUp } from 'lucide-vue-next'
import { Programs, Program } from '@/types/programs'
import { escapeHTML, openSettings } from '@/utils'
import { sanitizeHTML, openSettings } from '@/utils'
import Link from '@/components/Controls/Link.vue'
import Draggable from 'vuedraggable'
import ProgramProgressSummary from '@/pages/Programs/ProgramProgressSummary.vue'
@@ -365,7 +365,7 @@ const fetchMembers = () => {
}
const validateTitle = () => {
program.value.name = escapeHTML(program.value.name.trim())
program.value.name = sanitizeHTML(program.value.name.trim())
}
const saveProgram = (close: () => void) => {

View File

@@ -235,7 +235,7 @@ import {
import { sessionStore } from '../stores/session'
import { ClipboardList, ListChecks, Plus, Trash2 } from 'lucide-vue-next'
import { useRouter } from 'vue-router'
import { escapeHTML } from '@/utils'
import { sanitizeHTML } from '@/utils'
import Question from '@/components/Modals/Question.vue'
const { brand } = sessionStore()
@@ -286,7 +286,7 @@ const quizDetails = createDocumentResource({
})
const validateTitle = () => {
quizDetails.doc.title = escapeHTML(quizDetails.doc.title.trim())
quizDetails.doc.title = sanitizeHTML(quizDetails.doc.title.trim())
}
const submitQuiz = () => {

View File

@@ -146,7 +146,7 @@ import { useRouter, useRoute } from 'vue-router'
import { computed, inject, onMounted, ref, watch } from 'vue'
import { Plus } from 'lucide-vue-next'
import { sessionStore } from '@/stores/session'
import { escapeHTML } from '@/utils'
import { sanitizeHTML } from '@/utils'
import { useTelemetry } from 'frappe-ui/frappe'
import EmptyState from '@/components/EmptyState.vue'
@@ -226,7 +226,7 @@ const totalQuizzes = createResource({
})
const validateTitle = () => {
title.value = escapeHTML(title.value.trim())
title.value = sanitizeHTML(title.value.trim())
}
const insertQuiz = (close) => {