From e807237dbedbc189230296b81c3aeccc1c04fa77 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 13 Jan 2026 13:13:51 +0100 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F(frontend)=20fix=20pro?= =?UTF-8?q?ps=20vulnerability=20in=20Interlinking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were not properly sanitizing props passed to the InterlinkingLinkInlineContent component, which could lead to XSS attacks. This commit remove most of the props and only keep the necessary ones. --- CHANGELOG.md | 15 ++- src/frontend/apps/impress/package.json | 1 + .../InterlinkingLinkInlineContent.tsx | 121 +++++++++++++----- .../Interlinking/SearchPage.tsx | 1 - .../interlinkingLinkDocx.tsx | 12 +- .../interlinkingLinkODT.tsx | 12 +- .../interlinkingLinkPDF.tsx | 14 +- 7 files changed, 126 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e409e3..5b95b70d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,13 @@ and this project adheres to - ✅(export) add PDF regression tests #1762 - 📝(docs) Add language configuration documentation #1757 - 🔒(helm) Set default security context #1750 -- ✨(backend) use langfuse to monitor AI actions +- ✨(backend) use langfuse to monitor AI actions #1776 + +### Changed + +- ♿(frontend) improve accessibility: + - ♿(frontend) make html export accessible to screen reader users #1743 + - ♿(frontend) add missing label and fix Axes errors to improve a11y #1693 ### Fixed @@ -24,12 +30,7 @@ and this project adheres to ### Security - 🔒️(backend) validate more strictly url used by cors-proxy endpoint #1768 - -### Changed - -- ♿(frontend) improve accessibility: - - ♿(frontend) make html export accessible to screen reader users #1743 - - ♿(frontend) add missing label and fix Axes errors to improve a11y #1693 +- 🔒️(frontend) fix props vulnerability in Interlinking #1792 ## [4.3.0] - 2026-01-05 diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index cb701fc9..a0dcf896 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -68,6 +68,7 @@ "react-select": "5.10.2", "styled-components": "6.1.19", "use-debounce": "10.0.6", + "uuid": "13.0.0", "y-protocols": "1.0.7", "yjs": "*", "zustand": "5.0.9" diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx index 5dc9a2be..be5145dd 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingLinkInlineContent.tsx @@ -1,21 +1,23 @@ -/* eslint-disable react-hooks/rules-of-hooks */ +import { + PartialCustomInlineContentFromConfig, + StyleSchema, +} from '@blocknote/core'; import { createReactInlineContentSpec } from '@blocknote/react'; +import * as Sentry from '@sentry/nextjs'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; import { css } from 'styled-components'; +import { validate as uuidValidate } from 'uuid'; import { BoxButton, Text } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; import SelectedPageIcon from '@/docs/doc-editor/assets/doc-selected.svg'; -import { getEmojiAndTitle, useDoc } from '@/docs/doc-management'; +import { getEmojiAndTitle, useDoc } from '@/docs/doc-management/'; export const InterlinkingLinkInlineContent = createReactInlineContentSpec( { type: 'interlinkingLinkInline', propSchema: { - url: { - default: '', - }, docId: { default: '', }, @@ -27,46 +29,97 @@ export const InterlinkingLinkInlineContent = createReactInlineContentSpec( }, { render: ({ editor, inlineContent, updateInlineContent }) => { - const { data: doc } = useDoc({ id: inlineContent.props.docId }); - const isEditable = editor.isEditable; + if (!inlineContent.props.docId) { + return null; + } /** - * Update the content title if the referenced doc title changes + * Should not happen */ - useEffect(() => { - if ( - isEditable && - doc?.title && - doc.title !== inlineContent.props.title - ) { - updateInlineContent({ - type: 'interlinkingLinkInline', - props: { - ...inlineContent.props, - title: doc.title, - }, - }); - } + if (!uuidValidate(inlineContent.props.docId)) { + Sentry.captureException( + new Error(`Invalid docId: ${inlineContent.props.docId}`), + { + extra: { info: 'InterlinkingLinkInlineContent' }, + }, + ); - /** - * ⚠️ When doing collaborative editing, doc?.title might be out of sync - * causing an infinite loop of updates. - * To prevent this, we only run this effect when doc?.title changes, - * not when inlineContent.props.title changes. - */ - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [doc?.title, isEditable]); + updateInlineContent({ + type: 'interlinkingLinkInline', + props: { + docId: '', + title: '', + }, + }); - return ; + return null; + } + + return ( + + ); }, }, ); interface LinkSelectedProps { - url: string; + docId: string; title: string; + isEditable: boolean; + updateInlineContent: ( + update: PartialCustomInlineContentFromConfig< + { + readonly type: 'interlinkingLinkInline'; + readonly propSchema: { + readonly docId: { + readonly default: ''; + }; + readonly title: { + readonly default: ''; + }; + }; + readonly content: 'none'; + }, + StyleSchema + >, + ) => void; } -const LinkSelected = ({ url, title }: LinkSelectedProps) => { +export const LinkSelected = ({ + docId, + title, + isEditable, + updateInlineContent, +}: LinkSelectedProps) => { + const { data: doc } = useDoc({ id: docId }); + + /** + * Update the content title if the referenced doc title changes + */ + useEffect(() => { + if (isEditable && doc?.title && doc.title !== title) { + updateInlineContent({ + type: 'interlinkingLinkInline', + props: { + docId, + title: doc.title, + }, + }); + } + + /** + * ⚠️ When doing collaborative editing, doc?.title might be out of sync + * causing an infinite loop of updates. + * To prevent this, we only run this effect when doc?.title changes, + * not when inlineContent.props.title changes. + */ + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [doc?.title, docId, isEditable]); + const { colorsTokens } = useCunninghamTheme(); const { emoji, titleWithoutEmoji } = getEmojiAndTitle(title); @@ -74,7 +127,7 @@ const LinkSelected = ({ url, title }: LinkSelectedProps) => { const handleClick = (e: React.MouseEvent) => { e.preventDefault(); - void router.push(url); + void router.push(`/docs/${docId}/`); }; return ( diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/SearchPage.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/SearchPage.tsx index 5ef163cf..47428e75 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/SearchPage.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/SearchPage.tsx @@ -247,7 +247,6 @@ export const SearchPage = ({ { type: 'interlinkingLinkInline', props: { - url: `/docs/${doc.id}`, docId: doc.id, title: doc.title || untitledDocument, }, diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkDocx.tsx b/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkDocx.tsx index afb8c0e7..7da97f08 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkDocx.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkDocx.tsx @@ -1,16 +1,24 @@ import { ExternalHyperlink, TextRun } from 'docx'; +import { getEmojiAndTitle } from '@/docs/doc-management'; + import { DocsExporterDocx } from '../types'; export const inlineContentMappingInterlinkingLinkDocx: DocsExporterDocx['mappings']['inlineContentMapping']['interlinkingLinkInline'] = (inline) => { + if (!inline.props.docId) { + return new TextRun(''); + } + + const { emoji, titleWithoutEmoji } = getEmojiAndTitle(inline.props.title); + return new ExternalHyperlink({ children: [ new TextRun({ - text: `📄${inline.props.title}`, + text: `${emoji || '📄'}${titleWithoutEmoji}`, bold: true, }), ], - link: window.location.origin + inline.props.url, + link: window.location.origin + `/docs/${inline.props.docId}/`, }); }; diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkODT.tsx b/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkODT.tsx index 4ffadf08..ef9d3d9a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkODT.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkODT.tsx @@ -1,11 +1,17 @@ import React from 'react'; +import { getEmojiAndTitle } from '@/docs/doc-management'; + import { DocsExporterODT } from '../types'; export const inlineContentMappingInterlinkingLinkODT: DocsExporterODT['mappings']['inlineContentMapping']['interlinkingLinkInline'] = (inline) => { - const url = window.location.origin + inline.props.url; - const title = inline.props.title; + if (!inline.props.docId) { + return null; + } + + const { emoji, titleWithoutEmoji } = getEmojiAndTitle(inline.props.title); + const url = window.location.origin + `/docs/${inline.props.docId}/`; // Create ODT hyperlink using React.createElement to avoid TypeScript JSX namespace issues // Uses the same structure as BlockNote's default link mapping @@ -18,6 +24,6 @@ export const inlineContentMappingInterlinkingLinkODT: DocsExporterODT['mappings' xlinkShow: 'replace', xlinkHref: url, }, - `📄${title}`, + `${emoji || '📄'}${titleWithoutEmoji}`, ); }; diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkPDF.tsx b/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkPDF.tsx index c2d204b7..87165dfa 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkPDF.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-export/inline-content-mapping/interlinkingLinkPDF.tsx @@ -1,21 +1,29 @@ import { Image, Link, Text } from '@react-pdf/renderer'; +import { getEmojiAndTitle } from '@/docs/doc-management'; + import DocSelectedIcon from '../assets/doc-selected.png'; import { DocsExporterPDF } from '../types'; export const inlineContentMappingInterlinkingLinkPDF: DocsExporterPDF['mappings']['inlineContentMapping']['interlinkingLinkInline'] = (inline) => { + if (!inline.props.docId) { + return <>; + } + + const { emoji, titleWithoutEmoji } = getEmojiAndTitle(inline.props.title); + return ( {' '} - {' '} - {inline.props.title}{' '} + {emoji || }{' '} + {titleWithoutEmoji}{' '} ); }; From 1170bdbfc1fe31d687e92f07f055ea39bcd0bd7d Mon Sep 17 00:00:00 2001 From: AntoLC <25994652+AntoLC@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:18:01 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=8C=90(i18n)=20update=20translated=20?= =?UTF-8?q?strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update translated files with new translations --- src/backend/locale/br_FR/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/de_DE/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/en_US/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/es_ES/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/fr_FR/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/it_IT/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/nl_NL/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/pt_PT/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/ru_RU/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/sl_SI/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/sv_SE/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/tr_TR/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/uk_UA/LC_MESSAGES/django.po | 6 +++--- src/backend/locale/zh_CN/LC_MESSAGES/django.po | 6 +++--- .../apps/impress/src/i18n/translations.json | 15 +++++++++++---- 15 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/backend/locale/br_FR/LC_MESSAGES/django.po b/src/backend/locale/br_FR/LC_MESSAGES/django.po index 3a946232..1c321e74 100644 --- a/src/backend/locale/br_FR/LC_MESSAGES/django.po +++ b/src/backend/locale/br_FR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Breton\n" "Language: br_FR\n" @@ -79,7 +79,7 @@ msgstr "Doare korf" msgid "Format" msgstr "Stumm" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "eilenn {title}" diff --git a/src/backend/locale/de_DE/LC_MESSAGES/django.po b/src/backend/locale/de_DE/LC_MESSAGES/django.po index 8edff316..7215f3d1 100644 --- a/src/backend/locale/de_DE/LC_MESSAGES/django.po +++ b/src/backend/locale/de_DE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -79,7 +79,7 @@ msgstr "Typ" msgid "Format" msgstr "Format" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "Kopie von {title}" diff --git a/src/backend/locale/en_US/LC_MESSAGES/django.po b/src/backend/locale/en_US/LC_MESSAGES/django.po index 8ff076d1..90f6c72c 100644 --- a/src/backend/locale/en_US/LC_MESSAGES/django.po +++ b/src/backend/locale/en_US/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: English\n" "Language: en_US\n" @@ -79,7 +79,7 @@ msgstr "" msgid "Format" msgstr "" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "" diff --git a/src/backend/locale/es_ES/LC_MESSAGES/django.po b/src/backend/locale/es_ES/LC_MESSAGES/django.po index 828a1b41..c4f38cad 100644 --- a/src/backend/locale/es_ES/LC_MESSAGES/django.po +++ b/src/backend/locale/es_ES/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -79,7 +79,7 @@ msgstr "Tipo de Cuerpo" msgid "Format" msgstr "Formato" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "copia de {title}" diff --git a/src/backend/locale/fr_FR/LC_MESSAGES/django.po b/src/backend/locale/fr_FR/LC_MESSAGES/django.po index af9e20d6..a0d47f41 100644 --- a/src/backend/locale/fr_FR/LC_MESSAGES/django.po +++ b/src/backend/locale/fr_FR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -79,7 +79,7 @@ msgstr "Type de corps" msgid "Format" msgstr "Format" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "copie de {title}" diff --git a/src/backend/locale/it_IT/LC_MESSAGES/django.po b/src/backend/locale/it_IT/LC_MESSAGES/django.po index 47dd1dba..10f4a41a 100644 --- a/src/backend/locale/it_IT/LC_MESSAGES/django.po +++ b/src/backend/locale/it_IT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -79,7 +79,7 @@ msgstr "" msgid "Format" msgstr "Formato" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "copia di {title}" diff --git a/src/backend/locale/nl_NL/LC_MESSAGES/django.po b/src/backend/locale/nl_NL/LC_MESSAGES/django.po index d1ebbae3..b52b0a61 100644 --- a/src/backend/locale/nl_NL/LC_MESSAGES/django.po +++ b/src/backend/locale/nl_NL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -79,7 +79,7 @@ msgstr "Text type" msgid "Format" msgstr "Formaat" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "kopie van {title}" diff --git a/src/backend/locale/pt_PT/LC_MESSAGES/django.po b/src/backend/locale/pt_PT/LC_MESSAGES/django.po index fd65edc6..8a997815 100644 --- a/src/backend/locale/pt_PT/LC_MESSAGES/django.po +++ b/src/backend/locale/pt_PT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -79,7 +79,7 @@ msgstr "Tipo de corpo" msgid "Format" msgstr "Formato" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "cópia de {title}" diff --git a/src/backend/locale/ru_RU/LC_MESSAGES/django.po b/src/backend/locale/ru_RU/LC_MESSAGES/django.po index eb5a1c21..8853268c 100644 --- a/src/backend/locale/ru_RU/LC_MESSAGES/django.po +++ b/src/backend/locale/ru_RU/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -79,7 +79,7 @@ msgstr "Тип сообщения" msgid "Format" msgstr "Формат" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "копия {title}" diff --git a/src/backend/locale/sl_SI/LC_MESSAGES/django.po b/src/backend/locale/sl_SI/LC_MESSAGES/django.po index 5ee111c6..a7e7e2b6 100644 --- a/src/backend/locale/sl_SI/LC_MESSAGES/django.po +++ b/src/backend/locale/sl_SI/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Slovenian\n" "Language: sl_SI\n" @@ -79,7 +79,7 @@ msgstr "Vrsta telesa" msgid "Format" msgstr "Oblika" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "" diff --git a/src/backend/locale/sv_SE/LC_MESSAGES/django.po b/src/backend/locale/sv_SE/LC_MESSAGES/django.po index 51d8cc6f..b6c7a980 100644 --- a/src/backend/locale/sv_SE/LC_MESSAGES/django.po +++ b/src/backend/locale/sv_SE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -79,7 +79,7 @@ msgstr "" msgid "Format" msgstr "Format" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "" diff --git a/src/backend/locale/tr_TR/LC_MESSAGES/django.po b/src/backend/locale/tr_TR/LC_MESSAGES/django.po index cdf4bd5d..1e179aee 100644 --- a/src/backend/locale/tr_TR/LC_MESSAGES/django.po +++ b/src/backend/locale/tr_TR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -79,7 +79,7 @@ msgstr "" msgid "Format" msgstr "" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "" diff --git a/src/backend/locale/uk_UA/LC_MESSAGES/django.po b/src/backend/locale/uk_UA/LC_MESSAGES/django.po index 20128a23..b2c08c8d 100644 --- a/src/backend/locale/uk_UA/LC_MESSAGES/django.po +++ b/src/backend/locale/uk_UA/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" @@ -79,7 +79,7 @@ msgstr "Тип вмісту" msgid "Format" msgstr "Формат" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "копія {title}" diff --git a/src/backend/locale/zh_CN/LC_MESSAGES/django.po b/src/backend/locale/zh_CN/LC_MESSAGES/django.po index 7e140f51..d5190b5d 100644 --- a/src/backend/locale/zh_CN/LC_MESSAGES/django.po +++ b/src/backend/locale/zh_CN/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: lasuite-docs\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-16 21:44+0000\n" -"PO-Revision-Date: 2026-01-05 08:21\n" +"POT-Creation-Date: 2026-01-08 15:38+0000\n" +"PO-Revision-Date: 2026-01-13 13:17\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -79,7 +79,7 @@ msgstr "正文类型" msgid "Format" msgstr "格式" -#: build/lib/core/api/viewsets.py:1024 core/api/viewsets.py:1024 +#: build/lib/core/api/viewsets.py:1081 core/api/viewsets.py:1081 #, python-brace-format msgid "copy of {title}" msgstr "{title} 的副本" diff --git a/src/frontend/apps/impress/src/i18n/translations.json b/src/frontend/apps/impress/src/i18n/translations.json index 8a239412..45372811 100644 --- a/src/frontend/apps/impress/src/i18n/translations.json +++ b/src/frontend/apps/impress/src/i18n/translations.json @@ -779,12 +779,12 @@ "Document deleted": "Document supprimé", "Document duplicated successfully!": "Document dupliqué avec succès !", "Document editor": "Éditeur de document", + "Document emoji": "Émoji de document", "Document owner": "Propriétaire du document", "Document role text": "Texte du rôle du document", "Document sections": "Sections du document", "Document title": "Titre du document", "Document tree": "Arborescence du document", - "Document viewer": "Visualiseur de document", "Document visibility": "Visibilité du document", "Documents grid": "Grille des documents", "Docx": "Docx", @@ -826,6 +826,7 @@ "Image 403": "Image 403", "Image: {{title}}": "Image : {{title}}", "Insufficient access rights to view the document.": "Droits d'accès insuffisants pour voir le document.", + "Invalid or missing PDF file.": "Fichier PDF non valide ou manquant.", "Invite": "Inviter", "Invite new members": "Inviter de nouveaux membres", "Invite {{count}} members_many": "Inviter {{count}} membres", @@ -884,6 +885,7 @@ "Others are editing. Your network prevent changes.": "D'autres sont en cours d'édition. Votre réseau empêche les changements.", "Owner": "Propriétaire", "PDF": "PDF", + "PDF document": "Document PDF", "Page Not Found - Error 404": "Page introuvable - Erreur 404", "Pending invitations": "Invitations en attente", "People with access via the parent document": "Personnes ayant accès au document parent", @@ -1222,7 +1224,6 @@ "Document sections": "Document secties", "Document title": "Documenttitel", "Document tree": "Boomstructuur document", - "Document viewer": "Document-viewer", "Document visibility": "Document toegankelijkheid", "Documents grid": "Documenten overzicht", "Docx": "Docx", @@ -1264,6 +1265,7 @@ "Image 403": "Afbeelding 403", "Image: {{title}}": "Afbeelding: {{title}}", "Insufficient access rights to view the document.": "Onvoldoende toegangsrechten om het document te bekijken.", + "Invalid or missing PDF file.": "Ongeldig of ontbrekend PDF-bestand.", "Invite": "Uitnodigen", "Invite new members": "Nieuwe leden uitnodigen", "Invite {{count}} members_many": "Nodig {{count}} leden uit", @@ -1322,6 +1324,7 @@ "Others are editing. Your network prevent changes.": "Anderen zijn aan het bewerken. Uw netwerk voorkomt wijzigingen.", "Owner": "Eigenaar", "PDF": "PDF", + "PDF document": "Pdf-document", "Page Not Found - Error 404": "Pagina niet gevonden - Fout 404", "Pending invitations": "Openstaande uitnodigingen", "People with access via the parent document": "Gebruikers met toegang via het bovenliggend document", @@ -1516,12 +1519,12 @@ "Document deleted": "Документ удалён", "Document duplicated successfully!": "Документ успешно дублирован!", "Document editor": "Редактор документа", + "Document emoji": "Эмодзи документа", "Document owner": "Владелец документа", "Document role text": "Текст роли документа", "Document sections": "Разделы документа", "Document title": "Заголовок документа", "Document tree": "Иерархия документа", - "Document viewer": "Просмотрщик документа", "Document visibility": "Видимость документа", "Documents grid": "Сетка документов", "Docx": "Docx", @@ -1563,6 +1566,7 @@ "Image 403": "Изображение 403", "Image: {{title}}": "Изображение: {{title}}", "Insufficient access rights to view the document.": "Недостаточно прав доступа для просмотра документа.", + "Invalid or missing PDF file.": "Повреждённый или отсутствующий PDF-файл.", "Invite": "Приглашение", "Invite new members": "Пригласить новых участников", "Invite {{count}} members_many": "Пригласить {{count}} участников", @@ -1621,6 +1625,7 @@ "Others are editing. Your network prevent changes.": "Другие участники редактируют этот документ. Ваша сеть не позволяет вам присоединиться.", "Owner": "Владелец", "PDF": "PDF", + "PDF document": "Документ PDF", "Page Not Found - Error 404": "Страница не найдена - ошибка 404", "Pending invitations": "Ожидающие приглашения", "People with access via the parent document": "Люди, имеющие доступ через родительский документ", @@ -1918,12 +1923,12 @@ "Document deleted": "Документ видалено", "Document duplicated successfully!": "Документ успішно продубльовано!", "Document editor": "Редактор документа", + "Document emoji": "Емодзі документу", "Document owner": "Власник документа", "Document role text": "Текст ролі документа", "Document sections": "Розділи документу", "Document title": "Назва документа", "Document tree": "Дерево документа", - "Document viewer": "Переглядач документа", "Document visibility": "Видимість документа", "Documents grid": "Сітка документів", "Docx": "Docx", @@ -1965,6 +1970,7 @@ "Image 403": "Зображення 403", "Image: {{title}}": "Зображення: {{title}}", "Insufficient access rights to view the document.": "Недостатньо прав для перегляду документа.", + "Invalid or missing PDF file.": "Неприпустимий або відсутній PDF-файл.", "Invite": "Запрошення", "Invite new members": "Запросити нових учасників", "Invite {{count}} members_many": "Запросити {{count}} учасників", @@ -2023,6 +2029,7 @@ "Others are editing. Your network prevent changes.": "Інші учасники редагують документ. Ваша мережа не дозволяє вам вносити зміни.", "Owner": "Власник", "PDF": "PDF", + "PDF document": "Документ PDF", "Page Not Found - Error 404": "Сторінку не знайдено - Помилка 404", "Pending invitations": "Запрошення в очікуванні", "People with access via the parent document": "Люди з доступом через батьківський документ", From 5ec58cef99131f5ecfc3e69031c6a4f4d58b47e6 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Tue, 13 Jan 2026 14:15:40 +0100 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=94=96(minor)=20release=204.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added: - ✨(backend) add documents/all endpoint with descendants - ✅(export) add PDF regression tests - 📝(docs) Add language configuration documentation - 🔒(helm) Set default security context - ✨(backend) use langfuse to monitor AI actions Changed: - ♿(frontend) improve accessibility: - ♿(frontend) make html export accessible to screen reader users - ♿(frontend) add missing label and fix Axes errors to improve a11y Fixed: - ✅(backend) reduce flakiness on backend test - 🐛(frontend) fix clickable main content regression - 🐛(backend) fix TRASHBIN_CUTOFF_DAYS type error - 💄(frontend) fix icon position in callout block Security: - 🔒️(backend) validate more strictly url used by cors-proxy endpoint - 🔒️(frontend) fix props vulnerability in Interlinking --- CHANGELOG.md | 5 ++++- src/backend/pyproject.toml | 2 +- src/frontend/apps/e2e/package.json | 2 +- src/frontend/apps/impress/package.json | 2 +- src/frontend/package.json | 2 +- src/frontend/packages/eslint-plugin-docs/package.json | 2 +- src/frontend/packages/i18n/package.json | 2 +- src/frontend/servers/y-provider/package.json | 2 +- src/helm/helmfile.yaml.gotmpl | 4 ++-- src/helm/impress/Chart.yaml | 2 +- src/mail/package.json | 2 +- 11 files changed, 15 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b95b70d..f6390107 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to ## [Unreleased] +## [4.4.0] - 2026-01-13 + ### Added - ✨(backend) add documents/all endpoint with descendants #1553 @@ -988,7 +990,8 @@ and this project adheres to - ✨(frontend) Coming Soon page (#67) - 🚀 Impress, project to manage your documents easily and collaboratively. -[unreleased]: https://github.com/suitenumerique/docs/compare/v4.3.0...main +[unreleased]: https://github.com/suitenumerique/docs/compare/v4.4.0...main +[v4.4.0]: https://github.com/suitenumerique/docs/releases/v4.4.0 [v4.3.0]: https://github.com/suitenumerique/docs/releases/v4.3.0 [v4.2.0]: https://github.com/suitenumerique/docs/releases/v4.2.0 [v4.1.0]: https://github.com/suitenumerique/docs/releases/v4.1.0 diff --git a/src/backend/pyproject.toml b/src/backend/pyproject.toml index f58d055b..5310b723 100644 --- a/src/backend/pyproject.toml +++ b/src/backend/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "impress" -version = "4.3.0" +version = "4.4.0" authors = [{ "name" = "DINUM", "email" = "dev@mail.numerique.gouv.fr" }] classifiers = [ "Development Status :: 5 - Production/Stable", diff --git a/src/frontend/apps/e2e/package.json b/src/frontend/apps/e2e/package.json index 86e3a26b..7328a51b 100644 --- a/src/frontend/apps/e2e/package.json +++ b/src/frontend/apps/e2e/package.json @@ -1,6 +1,6 @@ { "name": "app-e2e", - "version": "4.3.0", + "version": "4.4.0", "repository": "https://github.com/suitenumerique/docs", "author": "DINUM", "license": "MIT", diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index a0dcf896..71646706 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -1,6 +1,6 @@ { "name": "app-impress", - "version": "4.3.0", + "version": "4.4.0", "repository": "https://github.com/suitenumerique/docs", "author": "DINUM", "license": "MIT", diff --git a/src/frontend/package.json b/src/frontend/package.json index 9673dfe6..d1260f69 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -1,6 +1,6 @@ { "name": "impress", - "version": "4.3.0", + "version": "4.4.0", "private": true, "repository": "https://github.com/suitenumerique/docs", "author": "DINUM", diff --git a/src/frontend/packages/eslint-plugin-docs/package.json b/src/frontend/packages/eslint-plugin-docs/package.json index e46a5415..d2a418e5 100644 --- a/src/frontend/packages/eslint-plugin-docs/package.json +++ b/src/frontend/packages/eslint-plugin-docs/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-docs", - "version": "4.3.0", + "version": "4.4.0", "repository": "https://github.com/suitenumerique/docs", "author": "DINUM", "license": "MIT", diff --git a/src/frontend/packages/i18n/package.json b/src/frontend/packages/i18n/package.json index 06270622..a9f7d4e1 100644 --- a/src/frontend/packages/i18n/package.json +++ b/src/frontend/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "packages-i18n", - "version": "4.3.0", + "version": "4.4.0", "repository": "https://github.com/suitenumerique/docs", "author": "DINUM", "license": "MIT", diff --git a/src/frontend/servers/y-provider/package.json b/src/frontend/servers/y-provider/package.json index bc4c9b63..44639fc9 100644 --- a/src/frontend/servers/y-provider/package.json +++ b/src/frontend/servers/y-provider/package.json @@ -1,6 +1,6 @@ { "name": "server-y-provider", - "version": "4.3.0", + "version": "4.4.0", "description": "Y.js provider for docs", "repository": "https://github.com/suitenumerique/docs", "license": "MIT", diff --git a/src/helm/helmfile.yaml.gotmpl b/src/helm/helmfile.yaml.gotmpl index 445601c3..a815ad6e 100644 --- a/src/helm/helmfile.yaml.gotmpl +++ b/src/helm/helmfile.yaml.gotmpl @@ -1,10 +1,10 @@ environments: dev: values: - - version: 4.3.0 + - version: 4.4.0 feature: values: - - version: 4.3.0 + - version: 4.4.0 feature: ci domain: example.com imageTag: demo diff --git a/src/helm/impress/Chart.yaml b/src/helm/impress/Chart.yaml index 57487a2f..4697c5ee 100644 --- a/src/helm/impress/Chart.yaml +++ b/src/helm/impress/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 type: application name: docs -version: 4.3.0 +version: 4.4.0 appVersion: latest diff --git a/src/mail/package.json b/src/mail/package.json index 0b3b6597..0e6829e7 100644 --- a/src/mail/package.json +++ b/src/mail/package.json @@ -1,6 +1,6 @@ { "name": "mail_mjml", - "version": "4.3.0", + "version": "4.4.0", "description": "An util to generate html and text django's templates from mjml templates", "type": "module", "dependencies": { From 0d967aba48c56b6cc405bdf6379eb77f59e0ae84 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Wed, 14 Jan 2026 10:01:22 +0100 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=93=8C(backend)=20pin=20celery=20to?= =?UTF-8?q?=20version<5.6.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since celery version 5.6.0 we have trouble with retrying tasks and it is impactig the malware_detection workflow. We have to use version 5.5.3 while we found the issue. --- renovate.json | 7 +++++++ src/backend/pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index 250dee8e..7f8e9cab 100644 --- a/renovate.json +++ b/renovate.json @@ -31,6 +31,13 @@ "matchPackageNames": ["django"], "allowedVersions": "<6.0.0" }, + { + + "groupName": "allowed celery versions", + "matchManagers": ["pep621"], + "matchPackageNames": ["celery"], + "allowedVersions": "<5.6.0" + }, { "enabled": false, "groupName": "ignored js dependencies", diff --git a/src/backend/pyproject.toml b/src/backend/pyproject.toml index 5310b723..d532906d 100644 --- a/src/backend/pyproject.toml +++ b/src/backend/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "beautifulsoup4==4.14.3", "boto3==1.42.17", "Brotli==1.2.0", - "celery[redis]==5.6.0", + "celery[redis]==5.5.3", "django-configurations==2.5.1", "django-cors-headers==4.9.0", "django-countries==8.2.0", From f9f32db854fe3d7c8348530d410b285134668a43 Mon Sep 17 00:00:00 2001 From: Anto59290 Date: Tue, 13 Jan 2026 19:47:25 +0100 Subject: [PATCH 5/5] =?UTF-8?q?=E2=9C=85(e2e)=20fix=20e2e=20test=20for=20o?= =?UTF-8?q?ther=20browsers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this test the comment is made using the "current" browser which can be Chromium but can also be Firefox or Webkit. This is why the test failed with other browsers. Signed-off-by: Anto59290 --- CHANGELOG.md | 4 ++++ .../apps/e2e/__tests__/app-impress/doc-comments.spec.ts | 2 +- .../e2e/__tests__/app-impress/doc-inherited-share.spec.ts | 2 +- src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts | 4 +++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6390107..68305f62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to ## [Unreleased] +### Fixed + +- ✅(e2e) fix e2e test for other browsers #1799 + ## [4.4.0] - 2026-01-13 ### Added diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts index 665a9f7a..b73814b4 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts @@ -58,7 +58,7 @@ test.describe('Doc Comments', () => { await page.getByRole('button', { name: '👍' }).click(); await expect( - thread.getByRole('img', { name: 'E2E Chromium' }).first(), + thread.getByRole('img', { name: `E2E ${browserName}` }).first(), ).toBeVisible(); await expect(thread.getByText('This is a comment').first()).toBeVisible(); await expect(thread.getByText(`E2E ${browserName}`).first()).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-inherited-share.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-inherited-share.spec.ts index efc19da6..7ad02d31 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-inherited-share.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-inherited-share.spec.ts @@ -21,7 +21,7 @@ test.describe('Inherited share accesses', () => { `doc-share-member-row-user.test@${browserName}.test`, ); await expect(user).toBeVisible(); - await expect(user.getByText('E2E Chromium')).toBeVisible(); + await expect(user.getByText(`E2E ${browserName}`)).toBeVisible(); await expect(user.getByText('Owner')).toBeVisible(); await page diff --git a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts index 67adf44c..da4a722d 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts @@ -224,7 +224,9 @@ export const updateDocTitle = async (page: Page, title: string) => { await expect(input).toHaveText(''); await expect(input).toBeVisible(); await input.click(); - await input.fill(title); + await input.fill(title, { + force: true, + }); await input.click(); await input.blur(); await verifyDocName(page, title);