diff --git a/packages/utils/src/Domain/Utils/Utils.ts b/packages/utils/src/Domain/Utils/Utils.ts index e5f921dbe..7325b9c92 100644 --- a/packages/utils/src/Domain/Utils/Utils.ts +++ b/packages/utils/src/Domain/Utils/Utils.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { sanitize } from 'dompurify' -import { find, isArray, mergeWith, remove, uniq, uniqWith } from 'lodash' +import { escape, find, isArray, mergeWith, remove, uniq, uniqWith } from 'lodash' import { AnyRecord } from '@standardnotes/common' const collator = typeof Intl !== 'undefined' ? new Intl.Collator('en', { numeric: true }) : undefined @@ -612,6 +612,10 @@ export function sanitizeHtmlString(html: string): string { return sanitize(html) } +export function escapeHtmlString(html: string): string { + return escape(html) +} + let sharedDateFormatter: unknown export function dateToLocalizedString(date: Date): string { if (typeof Intl !== 'undefined' && Intl.DateTimeFormat && typeof navigator !== 'undefined') { diff --git a/packages/web/src/javascripts/Constants/Strings.ts b/packages/web/src/javascripts/Constants/Strings.ts index 3ec6d5c99..770b36868 100644 --- a/packages/web/src/javascripts/Constants/Strings.ts +++ b/packages/web/src/javascripts/Constants/Strings.ts @@ -1,4 +1,4 @@ -import { Platform, SNApplication } from '@standardnotes/snjs' +import { escapeHtmlString, Platform, SNApplication } from '@standardnotes/snjs' import { getPlatform, isDesktopApplication } from '../Utils' /** @generic */ @@ -39,9 +39,10 @@ export const STRING_EDIT_LOCKED_ATTEMPT = export const STRING_RESTORE_LOCKED_ATTEMPT = "This note has editing disabled. If you'd like to restore it to a previous revision, enable editing and try again." export function StringDeleteNote(title: string, permanently: boolean) { + const escapedTitle = escapeHtmlString(title) return permanently - ? `Are you sure you want to permanently delete ${title}?` - : `Are you sure you want to move ${title} to the trash?` + ? `Are you sure you want to permanently delete ${escapedTitle}?` + : `Are you sure you want to move ${escapedTitle} to the trash?` } export function StringEmptyTrash(count: number) { return `Are you sure you want to permanently delete ${count} note(s)?` @@ -135,9 +136,10 @@ export const StringUtils = { }, deleteNotes(permanently: boolean, notesCount = 1, title?: string): string { if (notesCount === 1) { + const escapedTitle = escapeHtmlString(title || '') return permanently - ? `Are you sure you want to permanently delete ${title}?` - : `Are you sure you want to move ${title} to the trash?` + ? `Are you sure you want to permanently delete ${escapedTitle}?` + : `Are you sure you want to move ${escapedTitle} to the trash?` } else { return permanently ? 'Are you sure you want to permanently delete these notes?' @@ -145,7 +147,8 @@ export const StringUtils = { } }, deleteFile(title: string): string { - return `Are you sure you want to permanently delete ${title}?` + const escapedTitle = escapeHtmlString(title) + return `Are you sure you want to permanently delete ${escapedTitle}?` }, archiveLockedNotesAttempt(archive: boolean, notesCount = 1): string { const archiveString = archive ? 'archive' : 'unarchive' @@ -158,4 +161,12 @@ export const StringUtils = { ? "This note has editing disabled. If you'd like to delete it, enable editing, and try again." : "One or more of these notes have editing disabled. If you'd like to delete them, make sure editing is enabled on all of them, and try again." }, + deleteTag(title: string): string { + const escapedTitle = escapeHtmlString(title) + return `Delete tag "${escapedTitle}"?` + }, + cannotUploadFile(name: string): string { + const escapedName = escapeHtmlString(name) + return `Cannot upload file "${escapedName}"` + }, } diff --git a/packages/web/src/javascripts/Controllers/FilesController.ts b/packages/web/src/javascripts/Controllers/FilesController.ts index 591ddf1f3..0101111a1 100644 --- a/packages/web/src/javascripts/Controllers/FilesController.ts +++ b/packages/web/src/javascripts/Controllers/FilesController.ts @@ -168,7 +168,7 @@ export class FilesController extends AbstractViewController { const shouldDelete = await confirmDialog({ - text: `Are you sure you want to permanently delete "${file.name}"?`, + text: StringUtils.deleteFile(file.name), confirmButtonStyle: 'danger', }) if (shouldDelete) { @@ -440,7 +440,7 @@ export class FilesController extends AbstractViewController