applications: render Application Notes as sanitized HTML
The notes field is authored as HTML (the form says "HTML supported") but the
detail page interpolated it with {{ }}, so tags like <BR> showed as literal
text. Render via v-html through a DOMPurify sanitizer (utils/sanitizeHtml):
allow-list of formatting tags + links only, forces target=_blank
rel=noopener on links, strips scripts/handlers. Promote dompurify to a direct
dependency (was transitive via jspdf).
This commit is contained in:
@@ -79,7 +79,9 @@
|
||||
<!-- Application Notes -->
|
||||
<div class="section-card" v-if="app.applicationnotes">
|
||||
<h3 class="section-title">Application Notes</h3>
|
||||
<div class="notes-text">{{ app.applicationnotes }}</div>
|
||||
<!-- Notes are authored as HTML (form says "HTML supported");
|
||||
render sanitized so scripts/handlers cannot slip in. -->
|
||||
<div class="notes-text" v-html="sanitizedNotes"></div>
|
||||
</div>
|
||||
|
||||
<!-- Versions -->
|
||||
@@ -160,10 +162,11 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { applicationsApi } from '@/api'
|
||||
import { getContactEmailDomain } from '@/utils/siteSettings'
|
||||
import { sanitizeNotesHtml } from '@/utils/sanitizeHtml'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
@@ -173,6 +176,9 @@ const versions = ref([])
|
||||
const installedOn = ref([])
|
||||
const contactEmailDomain = ref('')
|
||||
|
||||
// Application notes are HTML; sanitize before binding with v-html.
|
||||
const sanitizedNotes = computed(() => sanitizeNotesHtml(app.value?.applicationnotes))
|
||||
|
||||
// Build sso@domain for a contact. Assumes contact.sso and domain are set.
|
||||
function contactEmail(contact) {
|
||||
return `${contact.sso}@${contactEmailDomain.value}`
|
||||
@@ -418,7 +424,17 @@ function kbKeywords(keywords) {
|
||||
|
||||
/* Notes styling - rendered as escaped plain text, preserve author line breaks */
|
||||
.notes-text {
|
||||
white-space: pre-wrap;
|
||||
/* Rendered HTML (v-html): block tags handle spacing, so no pre-wrap. */
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.notes-text :first-child { margin-top: 0; }
|
||||
.notes-text :last-child { margin-bottom: 0; }
|
||||
.notes-text p { margin: 0 0 0.6rem; }
|
||||
.notes-text ul,
|
||||
.notes-text ol { margin: 0 0 0.6rem 1.4rem; }
|
||||
.notes-text a { color: var(--link); }
|
||||
.notes-text code,
|
||||
.notes-text pre { background: var(--bg); border-radius: 4px; padding: 0.1rem 0.3rem; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user