fix: escape HTML in forms
This commit is contained in:
@@ -20,8 +20,6 @@
|
||||
}
|
||||
"
|
||||
autocomplete="off"
|
||||
@focus="() => togglePopover()"
|
||||
@keydown.delete.capture.stop="removeLastValue"
|
||||
/>
|
||||
</template>
|
||||
<template #body="{ isOpen, close }">
|
||||
@@ -58,7 +56,7 @@
|
||||
<div class="h-10"></div>
|
||||
<div
|
||||
v-if="attrs.onCreate"
|
||||
class="absolute bottom-2 left-1 w-[99%] pt-2 bg-white border-t"
|
||||
class="absolute bottom-2 left-1 w-[95%] pt-2 bg-white border-t"
|
||||
>
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -180,6 +178,7 @@ const filterOptions = createResource({
|
||||
})
|
||||
|
||||
const options = computed(() => {
|
||||
setFocus()
|
||||
return filterOptions.data || []
|
||||
})
|
||||
|
||||
@@ -225,25 +224,6 @@ const removeValue = (value) => {
|
||||
values.value = values.value.filter((v) => v !== value)
|
||||
}
|
||||
|
||||
const removeLastValue = () => {
|
||||
if (query.value) return
|
||||
|
||||
let emailRef = emails.value[emails.value.length - 1]?.$el
|
||||
if (document.activeElement === emailRef) {
|
||||
values.value.pop()
|
||||
nextTick(() => {
|
||||
if (values.value.length) {
|
||||
emailRef = emails.value[emails.value.length - 1].$el
|
||||
emailRef?.focus()
|
||||
} else {
|
||||
setFocus()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
emailRef?.focus()
|
||||
}
|
||||
}
|
||||
|
||||
function setFocus() {
|
||||
search.value.$el.focus()
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
<script setup lang="ts">
|
||||
import { Button, Dialog, FormControl, TextEditor, toast } from 'frappe-ui'
|
||||
import { computed, reactive, watch } from 'vue'
|
||||
import { escapeHTML } from '@/utils'
|
||||
|
||||
const show = defineModel()
|
||||
const assignments = defineModel<Assignments>('assignments')
|
||||
@@ -121,35 +122,48 @@ watch(show, (newVal) => {
|
||||
}
|
||||
})
|
||||
|
||||
const validateTitle = () => {
|
||||
assignment.title = escapeHTML(assignment.title.trim())
|
||||
}
|
||||
|
||||
const saveAssignment = () => {
|
||||
validateTitle()
|
||||
if (props.assignmentID == 'new') {
|
||||
assignments.value.insert.submit(
|
||||
{
|
||||
...assignment,
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
show.value = false
|
||||
toast.success(__('Assignment created successfully'))
|
||||
},
|
||||
}
|
||||
)
|
||||
createAssignment()
|
||||
} else {
|
||||
assignments.value.setValue.submit(
|
||||
{
|
||||
...assignment,
|
||||
name: props.assignmentID,
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
show.value = false
|
||||
toast.success(__('Assignment updated successfully'))
|
||||
},
|
||||
}
|
||||
)
|
||||
updateAssignment()
|
||||
}
|
||||
}
|
||||
|
||||
const createAssignment = () => {
|
||||
assignments.value.insert.submit(
|
||||
{
|
||||
...assignment,
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
show.value = false
|
||||
toast.success(__('Assignment created successfully'))
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const updateAssignment = () => {
|
||||
assignments.value.setValue.submit(
|
||||
{
|
||||
...assignment,
|
||||
name: props.assignmentID,
|
||||
},
|
||||
{
|
||||
onSuccess() {
|
||||
show.value = false
|
||||
toast.success(__('Assignment updated successfully'))
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const assignmentOptions = computed(() => {
|
||||
return [
|
||||
{ label: 'PDF', value: 'PDF' },
|
||||
|
||||
@@ -344,6 +344,7 @@ import {
|
||||
getMetaInfo,
|
||||
updateMetaInfo,
|
||||
validateFile,
|
||||
escapeHTML,
|
||||
} from '@/utils'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -500,7 +501,16 @@ const imageResource = createResource({
|
||||
},
|
||||
})
|
||||
|
||||
const validateFields = () => {
|
||||
Object.keys(batch).forEach((key) => {
|
||||
if (key != 'description' && typeof batch[key] === 'string') {
|
||||
batch[key] = escapeHTML(batch[key])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const saveBatch = () => {
|
||||
validateFields()
|
||||
if (batchDetail.data) {
|
||||
editBatchDetails()
|
||||
} else {
|
||||
|
||||
@@ -357,6 +357,7 @@ import {
|
||||
getMetaInfo,
|
||||
updateMetaInfo,
|
||||
validateFile,
|
||||
escapeHTML,
|
||||
} from '@/utils'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import CourseOutline from '@/components/CourseOutline.vue'
|
||||
@@ -537,7 +538,16 @@ const imageResource = createResource({
|
||||
},
|
||||
})
|
||||
|
||||
const validateFields = () => {
|
||||
Object.keys(course).forEach((key) => {
|
||||
if (key != 'description' && typeof course[key] === 'string') {
|
||||
course[key] = escapeHTML(course[key])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const submitCourse = () => {
|
||||
validateFields()
|
||||
if (courseResource.data) {
|
||||
editCourse()
|
||||
} else {
|
||||
|
||||
@@ -105,6 +105,8 @@
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { escapeHTML } from '@/utils'
|
||||
import {
|
||||
Button,
|
||||
createListResource,
|
||||
@@ -113,14 +115,13 @@ import {
|
||||
TextEditor,
|
||||
toast,
|
||||
} from 'frappe-ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import {
|
||||
ProgrammingExercise,
|
||||
ProgrammingExercises,
|
||||
TestCase,
|
||||
} from '@/types/programming-exercise'
|
||||
import ChildTable from '@/components/Controls/ChildTable.vue'
|
||||
import { ClipboardList, Play, Trash2 } from 'lucide-vue-next'
|
||||
import ChildTable from '@/components/Controls/ChildTable.vue'
|
||||
|
||||
const show = defineModel()
|
||||
const exercises = defineModel<ProgrammingExercises>('exercises')
|
||||
@@ -194,7 +195,12 @@ const fetchTestCases = () => {
|
||||
testCases.reload()
|
||||
}
|
||||
|
||||
const validateTitle = () => {
|
||||
exercise.value.title = escapeHTML(exercise.value.title.trim())
|
||||
}
|
||||
|
||||
const saveExercise = (close: () => void) => {
|
||||
validateTitle()
|
||||
if (props.exerciseID == 'new') createNewExercise(close)
|
||||
else updateExercise(close)
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ import {
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { Plus, Trash2, TrendingUp } from 'lucide-vue-next'
|
||||
import { Programs, Program } from '@/types/programs'
|
||||
import { openSettings } from '@/utils'
|
||||
import { escapeHTML, openSettings } from '@/utils'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import Draggable from 'vuedraggable'
|
||||
import ProgramProgressSummary from '@/pages/Programs/ProgramProgressSummary.vue'
|
||||
@@ -362,7 +362,12 @@ const fetchMembers = () => {
|
||||
programMembers.reload()
|
||||
}
|
||||
|
||||
const validateTitle = () => {
|
||||
program.value.name = escapeHTML(program.value.name.trim())
|
||||
}
|
||||
|
||||
const saveProgram = (close: () => void) => {
|
||||
validateTitle()
|
||||
if (props.programName === 'new') createNewProgram(close)
|
||||
else updateProgram(close)
|
||||
dirty.value = false
|
||||
|
||||
@@ -231,6 +231,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 Question from '@/components/Modals/Question.vue'
|
||||
|
||||
const { brand } = sessionStore()
|
||||
@@ -294,7 +295,12 @@ const quizDetails = createDocumentResource({
|
||||
},
|
||||
})
|
||||
|
||||
const validateTitle = () => {
|
||||
quizDetails.doc.title = escapeHTML(quizDetails.doc.title.trim())
|
||||
}
|
||||
|
||||
const submitQuiz = () => {
|
||||
validateTitle()
|
||||
quizDetails.setValue.submit(
|
||||
{
|
||||
...quizDetails.doc,
|
||||
|
||||
@@ -138,6 +138,7 @@ import { useRouter } 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 EmptyState from '@/components/EmptyState.vue'
|
||||
|
||||
const { brand } = sessionStore()
|
||||
@@ -191,7 +192,12 @@ const quizzes = createListResource({
|
||||
},
|
||||
})
|
||||
|
||||
const validateTitle = () => {
|
||||
title.value = escapeHTML(title.value.trim())
|
||||
}
|
||||
|
||||
const insertQuiz = (close) => {
|
||||
validateTitle()
|
||||
quizzes.insert.submit(
|
||||
{
|
||||
title: title.value,
|
||||
|
||||
Reference in New Issue
Block a user