From 8b6a0a2f3ade144c928347ed34578ac1b8dee992 Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Thu, 11 Jun 2026 14:04:05 +0200 Subject: [PATCH 01/43] Localisation updates from https://translatewiki.net. --- src/locales/be-tarask.json | 6 +-- src/locales/de.json | 74 +++++++++++++++++++++++++++++-- src/locales/fi.json | 21 +++++++++ src/locales/fr.json | 91 ++++++++++++++++++++++++++++++++++++++ src/locales/mk.json | 11 +++++ src/locales/zh-hans.json | 15 +++++++ src/locales/zh-hant.json | 23 ++++++++++ 7 files changed, 234 insertions(+), 7 deletions(-) diff --git a/src/locales/be-tarask.json b/src/locales/be-tarask.json index 2444f8504..0b1b837b5 100644 --- a/src/locales/be-tarask.json +++ b/src/locales/be-tarask.json @@ -116,7 +116,7 @@ "pad.modals.looping.explanation": "Праблемы далучэньня да сэрвэра сынхранізацыі.", "pad.modals.looping.cause": "Магчыма, вы падключыліся празь несумяшчальны брандмаўэр або проксі.", "pad.modals.initsocketfail": "Сэрвэр недаступны.", - "pad.modals.initsocketfail.explanation": "Не атрымалася падлучыцца да сэрвэра сынхранізацыі.", + "pad.modals.initsocketfail.explanation": "Не ўдалося падлучыцца да сэрвэра сынхранізацыі.", "pad.modals.initsocketfail.cause": "Імаверна, гэта зьвязана з праблемамі з вашым браўзэрам або інтэрнэт-злучэньнем.", "pad.modals.slowcommit.explanation": "Сэрвэр не адказвае.", "pad.modals.slowcommit.cause": "Гэта можа быць выклікана праблемамі зь сеткавым падлучэньнем.", @@ -178,9 +178,9 @@ "pad.impexp.importbutton": "Імпартаваць зараз", "pad.impexp.importing": "Імпартаваньне…", "pad.impexp.confirmimport": "Імпарт файла перазапіша цяперашні тэкст дакумэнту. Вы ўпэўненыя, што хочаце працягваць?", - "pad.impexp.convertFailed": "Не атрымалася імпартаваць гэты файл. Калі ласка, выкарыстайце іншы фармат дакумэнту або скапіюйце ўручную.", + "pad.impexp.convertFailed": "Не ўдалося імпартаваць гэты файл. Калі ласка, выкарыстайце іншы фармат дакумэнту або скапіюйце рукамі.", "pad.impexp.padHasData": "Мы не змаглі імпартаваць гэты файл, бо дакумэнт ужо мае зьмены, калі ласка, імпартуйце ў новы дакумэнт", - "pad.impexp.uploadFailed": "Загрузка не атрымалася, калі ласка, паспрабуйце яшчэ раз", + "pad.impexp.uploadFailed": "Загрузка не ўдалася, калі ласка, паспрабуйце яшчэ раз", "pad.impexp.importfailed": "Памылка імпарту", "pad.impexp.copypaste": "Калі ласка, скапіюйце і ўстаўце", "pad.impexp.exportdisabled": "Экспарт у фармаце {{type}} адключаны. Калі ласка, зьвярніцеся да вашага сыстэмнага адміністратара па падрабязнасьці.", diff --git a/src/locales/de.json b/src/locales/de.json index 8c52d4a96..94b74db0c 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -10,6 +10,7 @@ "Metalhead64", "Mklehr", "Mukeber", + "Nbux", "Nipsky", "Predatorix", "SamTV", @@ -22,6 +23,31 @@ ] }, "admin.page-title": "Admin Dashboard - Etherpad", + "admin.loading": "Lade …", + "admin.loading_description": "Bitte warten, die Seite wird aktualisiert ...", + "admin.toggle_sidebar": "Seitenleiste ein-/ausblenden", + "admin.shout": "Kommunikation", + "admin_shout.online_one": "Es ist derzeit {{count}} Benutzer online", + "admin_shout.online_other": "Es sind aktuell {{count}} Benutzer online", + "admin_shout.sticky_toggle": "Nachricht bleibt angeheftet", + "admin_login.title": "Etherpad", + "admin_login.username": "Benutzername", + "admin_login.password": "Passwort", + "admin_login.submit": "Login", + "admin_login.failed": "Login fehlgeschlagen.", + "admin_pads.all_pads": "Alle Pads", + "admin_pads.bulk.cleanup_history": "Verlauf löschen", + "admin_pads.bulk.clear_selection": "Auswahl löschen", + "admin_pads.bulk.delete": "Löschen", + "admin_pads.cancel": "Abbrechen", + "admin_pads.col.revisions": "Bearbeitungen", + "admin_pads.col.users": "Benutzer", + "admin_pads.confirm_button": "OK", + "admin_pads.create_pad_dialog_description": "Wähle einen Namen für das neue Pad.", + "admin_pads.delete_pad_dialog_description": "Bestätigen oder stornieren Sie die Löschung des Pads.", + "admin_pads.delete_pad_dialog_title": "Pad löschen", + "admin_pads.empty_never_edited": "leer · nie bearbeitet", + "admin_pads.error_dialog_description": "Ein Fehler ist aufgetreten", "admin_plugins": "Pluginverwaltung", "admin_plugins.available": "Verfügbare Plugins", "admin_plugins.available_not-found": "Keine Plugins gefunden.", @@ -75,7 +101,7 @@ "index.labelPad": "Padname (optional)", "index.placeholderPadEnter": "Gib den Namen des Pads ein...", "index.createAndShareDocuments": "Erstelle und teile Dokumente in Echtzeit", - "index.createAndShareDocumentsDescription": "Etherpad ermöglicht die gemeinsame Bearbeitung von Dokumenten in Echtzeit, ähnlich wie ein Live-Multiplayer-Editor, der in Ihrem Browser läuft.", + "index.createAndShareDocumentsDescription": "Etherpad ermöglicht die gemeinsame Bearbeitung von Dokumenten in Echtzeit, ähnlich wie ein Live-Multiplayer-Editor, der in Deinem Browser läuft.", "pad.toolbar.bold.title": "Fett (Strg-B)", "pad.toolbar.italic.title": "Kursiv (Strg-I)", "pad.toolbar.underline.title": "Unterstrichen (Strg-U)", @@ -99,18 +125,31 @@ "pad.loading": "Laden …", "pad.noCookie": "Das Cookie konnte nicht gefunden werden. Bitte erlaube Cookies in deinem Browser! Deine Sitzung und Einstellungen werden zwischen den Besuchen nicht gespeichert. Dies kann darauf zurückzuführen sein, dass Etherpad in einigen Browsern in einem iFrame enthalten ist. Bitte stelle sicher, dass sich Etherpad auf der gleichen Subdomain/Domain wie der übergeordnete iFrame befindet.", "pad.permissionDenied": "Du hast keine Berechtigung, um auf dieses Pad zuzugreifen.", - "pad.settings.padSettings": "Pad-Einstellungen", + "pad.settings.title": "Einstellungen", + "pad.settings.padSettings": "Pad-weite Einstellungen", + "pad.settings.userSettings": "Nutzereinstellungen", "pad.settings.myView": "Eigene Ansicht", + "pad.settings.disablechat": "Chat deaktivieren", + "pad.settings.darkMode": "Dunkler Modus", "pad.settings.stickychat": "Chat immer anzeigen", "pad.settings.chatandusers": "Chat und Benutzer anzeigen", "pad.settings.colorcheck": "Autorenfarben anzeigen", + "pad.settings.fadeInactiveAuthorColors": "Farben inaktiver Autoren ausblenden", "pad.settings.linenocheck": "Zeilennummern", "pad.settings.rtlcheck": "Inhalt von rechts nach links lesen?", + "pad.settings.enforcedNotice": "Diese Einstellungen wurden vom Ersteller des Pads gesperrt. Wenden Sie sich an den Ersteller, wenn Sie diese ändern möchten.", "pad.settings.fontType": "Schriftart:", "pad.settings.fontType.normal": "Normal", "pad.settings.language": "Sprache:", "pad.settings.deletePad": "Pad löschen", "pad.delete.confirm": "Möchtest du dieses Pad wirklich löschen?", + "pad.deletionToken.modalTitle": "Speichere deinen Pad-Löschtoken.", + "pad.deletionToken.modalBody": "Dieses Token ist die einzige Möglichkeit, dieses Pad zu löschen, falls Deine Browsersitzung unterbrochen wird oder Du das Gerät wechselst. Speichere es an einem sicheren Ort – es wird hier nur einmal angezeigt.", + "pad.deletionToken.deleteWithToken": "Pad mit Token löschen", + "pad.deletionToken.tokenFieldLabel": "Pad-Löschtoken", + "pad.deletionToken.tokenValueLabel": "Dein Pad-Löschtoken (schreibgeschützt)", + "pad.deletionToken.invalid": "Das angegebene Token ist für dieses Pad nicht gültig.", + "pad.deletionToken.notCreator": "Sie sind nicht der Ersteller dieses Pads, daher können Sie es nicht löschen.", "pad.settings.about": "Über", "pad.settings.poweredBy": "Betrieben von", "pad.importExport.import_export": "Import/Export", @@ -123,7 +162,13 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.exportetherpada.title": "Export im Etherpad-Format", + "pad.importExport.exporthtmla.title": "Exportieren als HTML", + "pad.importExport.exportplaina.title": "Export als einfacher Text", + "pad.importExport.exportworda.title": "Exportieren als Microsoft Word", "pad.importExport.exportpdfa.title": "Als PDF exportieren", + "pad.importExport.exportopena.title": "Export als ODF (Open Document Format)", + "pad.importExport.noConverter.innerHTML": "Du kannst nur aus reinen Text- oder HTML-Formaten importieren. Für umfangreichere Importfunktionen muss AbiWord oder LibreOffice auf dem Server installiert werden.", "pad.modals.connected": "Verbunden.", "pad.modals.reconnecting": "Dein Pad wird neu verbunden...", "pad.modals.forcereconnect": "Erneutes Verbinden erzwingen", @@ -151,9 +196,11 @@ "pad.modals.rateLimited.explanation": "Sie haben zu viele Nachrichten an dieses Pad gesendet, so dass die Verbindung unterbrochen wurde.", "pad.modals.rejected.explanation": "Der Server hat eine Nachricht abgelehnt, die von deinem Browser gesendet wurde.", "pad.modals.rejected.cause": "Möglicherweise wurde der Server aktualisiert, während du das Pad angesehen hast, oder es existiert ein Fehler in Etherpad. Versuche, die Seite neu zu laden.", - "pad.modals.disconnected": "Ihre Verbindung wurde getrennt.", + "pad.modals.disconnected": "Deine Verbindung wurde getrennt.", "pad.modals.disconnected.explanation": "Die Verbindung zum Server wurde unterbrochen.", "pad.modals.disconnected.cause": "Möglicherweise ist der Server nicht erreichbar. Bitte benachrichtige den Dienstadministrator, falls dies weiterhin passiert.", + "pad.gritter.unacceptedCommit.title": "Nicht gespeicherte Bearbeitung", + "pad.gritter.unacceptedCommit.text": "Deine letzte Änderung wurde noch nicht gespeichert. Stelle die Verbindung wieder her und versuche es erneut.", "pad.share": "Dieses Pad teilen", "pad.share.readonly": "Eingeschränkter Nur-Lese-Zugriff", "pad.share.link": "Verknüpfung", @@ -166,12 +213,29 @@ "timeslider.followContents": "Aktualisierungen des Pad-Inhalts verfolgen", "timeslider.pageTitle": "{{appTitle}} Bearbeitungsverlauf", "timeslider.toolbar.returnbutton": "Zurück zum Pad", + "pad.historyMode.banner": "Versionsgeschichte ansehen", + "pad.historyMode.return": "Zurück zum Live-Modus", + "pad.historyMode.revisionLabel": "Revision {{rev}}", + "pad.historyMode.controlsLabel": "Steuerung Pad-Verlauf", + "pad.historyMode.sliderLabel": "Pad-Version", + "pad.historyMode.settings.title": "Wiedergabe des Bearbeitungsverlaufs", + "pad.historyMode.settings.follow": "Aktualisierungen des Pad-Inhalts verfolgen", + "pad.historyMode.settings.followShort": "Folgen", + "pad.historyMode.followOn": "Pad-Änderungen verfolgen – klicken Sie hier, um die Verfolgung zu beenden.", + "pad.historyMode.followOff": "Änderungen der Pads werden nicht verfolgt – zum Folgen klicken", + "pad.historyMode.settings.playbackSpeed": "Wiedergabegeschwindigkeit:", + "pad.historyMode.chat.replayHeader": "Chat mit Stand von {{time}}", + "pad.historyMode.users.authorsHeader": "Autoren bei dieser Revision", + "pad.editor.keyboardHint": "Drücken Sie die Escape-Taste, um den Editor zu verlassen. Drücken Sie Alt+F9, um die Symbolleiste aufzurufen.", + "pad.editor.toolbar.formatting": "Formatierungsleiste", + "pad.editor.toolbar.showMore": "Weitere Schaltflächen anzeigen", "timeslider.toolbar.authors": "Autoren:", "timeslider.toolbar.authorsList": "Keine Autoren", "timeslider.toolbar.exportlink.title": "Diese Version exportieren", "timeslider.exportCurrent": "Exportiere diese Version als:", "timeslider.version": "Version {{version}}", "timeslider.saved": "Gespeichert am {{day}}. {{month}} {{year}}", + "timeslider.settings.playbackSpeed": "Wiedergabegeschwindigkeit:", "timeslider.playPause": "Padbearbeitung abspielen/pausieren", "timeslider.backRevision": "Eine Version in diesem Pad zurückgehen", "timeslider.forwardRevision": "Eine Version in diesem Pad vorwärtsgehen", @@ -193,6 +257,7 @@ "pad.savedrevs.timeslider": "Du kannst gespeicherte Versionen durch den Aufruf des Bearbeitungsverlaufs ansehen.", "pad.userlist.entername": "Dein Name?", "pad.userlist.unnamed": "unbenannt", + "pad.userlist.onlineCount": "{[ plural(count) one: {{count}} verbundener Benutzer, other: {{count}} verbundene Benutzer ]}", "pad.editbar.clearcolors": "Autorenfarben im gesamten Dokument zurücksetzen? Dies kann nicht rückgängig gemacht werden", "pad.impexp.importbutton": "Jetzt importieren", "pad.impexp.importing": "Importiere …", @@ -203,5 +268,6 @@ "pad.impexp.importfailed": "Import fehlgeschlagen", "pad.impexp.copypaste": "Bitte kopieren und einfügen", "pad.impexp.exportdisabled": "Der Export im {{type}}-Format ist deaktiviert. Für Einzelheiten kontaktiere bitte deinen Systemadministrator.", - "pad.impexp.maxFileSize": "Die Datei ist zu groß. Kontaktiere bitte deinen Administrator, um das Limit für den Dateiimport zu erhöhen." + "pad.impexp.maxFileSize": "Die Datei ist zu groß. Kontaktiere bitte deinen Administrator, um das Limit für den Dateiimport zu erhöhen.", + "pad.social.description": "Ein kollaboratives Dokument, das jeder in Echtzeit bearbeiten kann." } diff --git a/src/locales/fi.json b/src/locales/fi.json index 7ba04c7fd..5fcb846e1 100644 --- a/src/locales/fi.json +++ b/src/locales/fi.json @@ -23,6 +23,27 @@ ] }, "admin.page-title": "Ylläpitäjän kojelauta - Etherpad", + "admin.loading": "Ladataan…", + "admin.loading_description": "Odota. Sivu latautuu.", + "admin.toggle_sidebar": "Näytä/piilota sivupalkki", + "admin.shout": "Viestintä", + "admin_shout.online_one": "Tällä hetkellä {{count}} käyttäjä on paikalla", + "admin_shout.online_other": "Tällä hetkellä {{count}} käyttäjää on paikalla", + "admin_shout.sticky_toggle": "Muuta pysyvää viestiä", + "admin_login.title": "Etherpad", + "admin_login.username": "Käyttäjänimi", + "admin_login.password": "Salasana", + "admin_login.submit": "Kirjaudu sisään", + "admin_login.failed": "Kirjautuminen epäonnistui", + "admin_pads.all_pads": "Kaikki muistiot", + "admin_pads.bulk.cleanup_history": "Tyhjennä historia", + "admin_pads.bulk.delete": "Poista", + "admin_pads.cancel": "Peru", + "admin_pads.col.pad": "Muistio", + "admin_pads.col.revisions": "Muokkaushistoria", + "admin_pads.col.users": "Käyttäjät", + "admin_pads.confirm_button": "OK", + "admin_pads.create_pad_dialog_description": "Valitse nimi uudelle muistiolle.", "admin_plugins": "Lisäosien hallinta", "admin_plugins.available": "Saatavilla olevat liitännäiset", "admin_plugins.available_not-found": "Lisäosia ei löytynyt.", diff --git a/src/locales/fr.json b/src/locales/fr.json index 8e8229241..ae4910385 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -10,6 +10,7 @@ "Derugon", "Envlh", "Framafan", + "Framasky", "Fylip22", "Gomoko", "Goofy", @@ -37,13 +38,73 @@ ] }, "admin.page-title": "Tableau de bord administrateur — Etherpad", + "admin.loading": "Chargement en cours…", + "admin.loading_description": "Veuillez patienter pendant le chargement de la page.", + "admin.toggle_sidebar": "Afficher / masquer la barre latérale", + "admin.shout": "Communication", + "admin_shout.online_one": "Il y a actuellement {{count}} utilisateur·ice en ligne", + "admin_shout.online_other": "Il y a actuellement {{count}} utilisateur·ices en ligne", + "admin_shout.sticky_toggle": "Modifier le message épinglé", + "admin_login.title": "Etherpad", + "admin_login.username": "Nom d’utilisateur", + "admin_login.password": "Mot de passe", + "admin_login.submit": "Connexion", + "admin_login.failed": "Échec de la connexion", + "admin_pads.all_pads": "Tous les blocs-notes", + "admin_pads.bulk.cleanup_history": "Effacer l’historique", + "admin_pads.bulk.clear_selection": "Effacer la sélection", + "admin_pads.bulk.delete": "Supprimer", + "admin_pads.cancel": "Annuler", + "admin_pads.col.pad": "Bloc-notes", + "admin_pads.col.revisions": "Révisions", + "admin_pads.col.users": "Utilisateur·ices", + "admin_pads.confirm_button": "OK", + "admin_pads.create_pad_dialog_description": "Choisissez un nom pour le nouveau bloc-notes.", + "admin_pads.delete_pad_dialog_description": "Confirmer ou annuler la suppression du bloc-notes.", + "admin_pads.delete_pad_dialog_title": "Supprimer le bloc-notes", + "admin_pads.empty_never_edited": "vide · jamais modifié", + "admin_pads.error_dialog_description": "Une erreur s’est produite.", + "admin_pads.error_prefix": "Erreur", + "admin_pads.filter.active": "Actif", + "admin_pads.filter.all": "Tous", + "admin_pads.filter.empty": "Vide", + "admin_pads.filter.recent": "Cette semaine", + "admin_pads.filter.stale": "Sans modifications (> 1 an)", + "admin_pads.open": "Ouvert", + "admin_pads.pagination.next": "Suivant", + "admin_pads.pagination.previous": "Précédent", + "admin_pads.refresh": "Actualiser", + "admin_pads.relative.days": "il y a {{count}} jours", + "admin_pads.relative.hours": "il y a {{count}} heures", + "admin_pads.relative.just_now": "à l’instant", + "admin_pads.show": "Afficher", + "admin_pads.sort.name": "Nom (A–Z)", + "admin_pads.sort.revision_number": "Révisions", + "admin_pads.sort.user_count": "Utilisateur·ices", + "admin_pads.stats.across_pads": "sur tous les bloc-notes", + "admin_pads.stats.active_users": "Utilisateur·ices actif·ves", + "admin_pads.stats.empty_pads": "Bloc-notes vides", + "admin_pads.stats.last_activity": "Dernière activité :", + "admin_pads.stats.no_active_users": "Aucun·e utilisateur·ice actif·ve", + "admin_pads.stats.revisions_zero": "0 révisions", + "admin_pads.stats.total": "Nombre total de bloc-notes", + "admin_pads.stats.users_active": "{{count}} actuellement actifs", + "admin_pads.subtitle": "Aperçu de tous les bloc-notes de cette instance Etherpad. Rechercher, nettoyer, ouvrir.", "admin_plugins": "Gestionnaire de greffons", "admin_plugins.available": "Greffons disponibles", "admin_plugins.available_not-found": "Aucun greffon trouvé.", "admin_plugins.available_fetching": "Récupération en cours...", "admin_plugins.available_install.value": "Installer", "admin_plugins.available_search.placeholder": "Rechercher des greffons à installer", + "admin_plugins.check_updates": "Vérifier les mises à jour", + "admin_plugins.catalog_disabled": "Le catalogue de greffons est désactivé par votre administrateur (privacy.pluginCatalog=false). Pour installer un greffon, exécutez `pnpm run plugins i ep_ ` sur le serveur.", + "admin_plugins.crumbs": "Greffons", "admin_plugins.description": "Description", + "admin_plugins.disables.label": "Désactive :", + "admin_plugins.disables.warning_title": "Ce greffon supprime intentionnellement les fonctionnalités Etherpad listées.", + "admin_plugins.error_retrieving": "Erreur lors de la récupération des greffons", + "admin_plugins.install_error": "Échec de l'installation de {{plugin}} : {{error}}", + "admin_plugins.install_error_requires_newer_etherpad": "Impossible d'installer {{plugin}} : une version plus récente d'Etherpad est requise. Veuillez mettre à jour Etherpad et réessayer.", "admin_plugins.installed": "Greffons installés", "admin_plugins.installed_fetching": "Récupération des greffons installés en cours...", "admin_plugins.installed_nothing": "Vous n’avez encore installé aucun greffon.", @@ -51,8 +112,25 @@ "admin_plugins.last-update": "Dernière mise à jour", "admin_plugins.name": "Nom", "admin_plugins.page-title": "Gestionnaire de greffons — Etherpad", + "admin_plugins.reload_catalog": "Recharger le catalogue", + "admin_plugins.search_npm": "Rechercher sur npm", + "admin_plugins.sort_ascending": "Tri croissant", + "admin_plugins.sort_descending": "Tri décroissant", + "admin_plugins.sort.last_updated": "Dernière mise à jour", + "admin_plugins.sort.name": "Nom (A–Z)", + "admin_plugins.sort.version": "Version", + "admin_plugins.source": "Source du greffon", + "admin_plugins.subtitle": "Installez, mettez à jour et supprimez les greffons d’Etherpad. Toute modification nécessite un redémarrage du serveur.", + "admin_plugins.tag_core": "Cœur", + "admin_plugins.update_tooltip": "Mise à jour", + "admin_plugins.updates_available": "Mises à jour disponibles", + "admin_plugins.update_now": "Mettre à jour", "admin_plugins.version": "Version", "admin_plugins_info": "Informations de résolution de problème", + "admin_plugins_info.bindings_label": "{{count}} liaisons", + "admin_plugins_info.copy_diagnostics": "Copie des diagnostics", + "admin_plugins_info.copy_value": "Copier {{label}}", + "admin_plugins_info.git_sha": "Git SHA", "admin_plugins_info.hooks": "Crochets installés", "admin_plugins_info.hooks_client": "Crochets côté client", "admin_plugins_info.hooks_server": "Crochets côté serveur", @@ -156,6 +234,16 @@ "pad.settings.language": "Langue :", "pad.settings.deletePad": "Supprimer le bloc-notes", "pad.delete.confirm": "Voulez-vous vraiment supprimer ce bloc-notes ?", + "pad.deletionToken.modalTitle": "Enregistrez votre jeton de suppression de bloc-notes", + "pad.deletionToken.modalBody": "Ce jeton est le seul moyen de supprimer ce bloc-notes si vous perdez votre session de navigateur ou si vous changez d'appareil. Conservez-le en lieu sûr — il n'apparaît ici qu'une seule fois.", + "pad.deletionToken.copy": "Copier", + "pad.deletionToken.copied": "Copié", + "pad.deletionToken.acknowledge": "Je l'ai enregistré", + "pad.deletionToken.deleteWithToken": "Supprimer le bloc-notes avec un jeton", + "pad.deletionToken.tokenFieldLabel": "Jeton de suppression de bloc-notes", + "pad.deletionToken.tokenValueLabel": "Votre jeton de suppression du bloc-notes (lecture seule)", + "pad.deletionToken.invalid": "Ce jeton n'est pas valable pour ce bloc-notes.", + "pad.deletionToken.notCreator": "Vous n’êtes pas le créateur du bloc-notes, vous ne pouvez donc pas le supprimer.", "pad.settings.about": "À propos", "pad.settings.poweredBy": "Propulsé par", "pad.importExport.import_export": "Importer/Exporter", @@ -168,6 +256,9 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.exportetherpada.title": "Exporter au format Etherpad", + "pad.importExport.exporthtmla.title": "Exporter au format HTML", + "pad.importExport.exportplaina.title": "Exporter en texte brut", "pad.importExport.noConverter.innerHTML": "Vous pouvez uniquement importer du texte brut ou du HTML. Pour des fonctionnalités d'importation plus avancées, veuillez installer LibreOffice.", "pad.modals.connected": "Connecté.", "pad.modals.reconnecting": "Reconnexion à votre bloc-notes en cours...", diff --git a/src/locales/mk.json b/src/locales/mk.json index 7860177b9..05842c56c 100644 --- a/src/locales/mk.json +++ b/src/locales/mk.json @@ -187,6 +187,8 @@ "update.page.policy.rollback-failed-terminal": "Претходната поднова не успеа и не можеше да се отповика. Стиснете на „Прифати“ откако воспоставката ќе стане задрава за да отклучите.", "update.page.policy.up-to-date": "Ја користите најновата верзија.", "update.page.policy.tier-off": "Подновие се оневозможени (updates.tier = „off“).", + "update.execution.preflight": "Подготвителни проверки", + "update.execution.preflight-failed": "Проверките не успеаја", "index.newPad": "Нова тетратка", "index.settings": "Нагодувања", "index.transferSessionTitle": "Префрли седница", @@ -318,6 +320,14 @@ "timeslider.followContents": "Следи ги подновите во содржината на тетратката", "timeslider.pageTitle": "{{appTitle}} Историски преглед", "timeslider.toolbar.returnbutton": "Назад на тетратката", + "pad.historyMode.banner": "Историја на посети", + "pad.historyMode.return": "Назад во живо", + "pad.historyMode.revisionLabel": "Преработка {{rev}}", + "pad.historyMode.controlsLabel": "Контроли за историја на тетратката", + "pad.historyMode.sliderLabel": "Преработка на тетратката", + "pad.historyMode.settings.followShort": "Следи", + "pad.historyMode.followOn": "Следите промени во тетратката — стиснете за да престанете со следење", + "pad.historyMode.followOff": "Не следите промени во тетратката — стиснете за да следите", "timeslider.toolbar.authors": "Автори:", "timeslider.toolbar.authorsList": "Нема автори", "timeslider.toolbar.exportlink.title": "Извоз", @@ -351,6 +361,7 @@ "pad.savedrevs.timeslider": "Можете да ги погледате зачуваните преработки посетувајќи го времеследниот лизгач", "pad.userlist.entername": "Внесете го вашето име", "pad.userlist.unnamed": "без име", + "pad.userlist.onlineCount": "{[ plural(count) one: {{count}} поврзан корисник, other: {{count}} поврзани корисници ]}", "pad.editbar.clearcolors": "Да ги отстранам авторските бои од целиот документ? Ова е неповратно", "pad.impexp.importbutton": "Увези сега", "pad.impexp.importing": "Увезувам...", diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json index 946490acd..67e1549f4 100644 --- a/src/locales/zh-hans.json +++ b/src/locales/zh-hans.json @@ -18,6 +18,7 @@ "Stang", "TFX202X", "VulpesVulpes825", + "XtexChooser", "Yfdyh000", "乌拉跨氪", "列维劳德", @@ -26,6 +27,20 @@ ] }, "admin.page-title": "管理员面板 - Etherpad", + "admin.loading": "正在加载…", + "admin.loading_description": "页面加载中,请稍安勿躁。", + "admin_login.username": "用户名", + "admin_login.password": "密码", + "admin_login.submit": "登录", + "admin_pads.bulk.delete": "删除", + "admin_pads.cancel": "取消", + "admin_pads.col.users": "用户", + "admin_pads.confirm_button": "确定", + "admin_pads.error_prefix": "错误", + "admin_pads.pagination.next": "下一页", + "admin_pads.pagination.previous": "上一页", + "admin_pads.refresh": "刷新", + "admin_pads.relative.just_now": "刚刚", "admin_plugins": "插件管理器", "admin_plugins.available": "可用插件", "admin_plugins.available_not-found": "找不到插件。", diff --git a/src/locales/zh-hant.json b/src/locales/zh-hant.json index 27c2a8521..e35472efc 100644 --- a/src/locales/zh-hant.json +++ b/src/locales/zh-hant.json @@ -15,6 +15,16 @@ ] }, "admin.page-title": "管理員面板 - Etherpad", + "admin.loading": "載入中…", + "admin_login.title": "Etherpad", + "admin_login.username": "使用者名稱", + "admin_login.password": "密碼", + "admin_login.submit": "登入", + "admin_login.failed": "登入失敗", + "admin_pads.bulk.delete": "刪除", + "admin_pads.cancel": "取消", + "admin_pads.col.users": "使用者", + "admin_pads.error_prefix": "錯誤", "admin_plugins": "外掛程式管理器", "admin_plugins.available": "可用套件", "admin_plugins.available_not-found": "沒有找到套件。", @@ -29,6 +39,9 @@ "admin_plugins.last-update": "最後更新", "admin_plugins.name": "名稱", "admin_plugins.page-title": "套件管理 - Etherpad", + "admin_plugins.update_tooltip": "更新", + "admin_plugins.updates_available": "有可用更新", + "admin_plugins.update_now": "更新", "admin_plugins.version": "版本", "admin_plugins_info": "問題排除資訊", "admin_plugins_info.hooks": "已安裝的掛勾", @@ -37,6 +50,8 @@ "admin_plugins_info.parts": "已安裝部分", "admin_plugins_info.plugins": "已安裝的套件", "admin_plugins_info.page-title": "套件資訊 - Etherpad", + "admin_plugins_info.tab_client": "客戶端", + "admin_plugins_info.tab_server": "伺服器", "admin_plugins_info.version": "Etherpad 版本", "admin_plugins_info.version_latest": "最新可用版本", "admin_plugins_info.version_number": "版本號", @@ -46,6 +61,9 @@ "admin_settings.current_example-prod": "生產設定模板範例", "admin_settings.current_restart.value": "重新啟動 Etherpad", "admin_settings.current_save.value": "儲存設定", + "admin_settings.invalid_json": "無效 JSON", + "admin_settings.current_test.value": "驗證 JSON", + "admin_settings.current_prettify.value": "美化 JSON 格式", "admin_settings.page-title": "設定 - Etherpad", "index.newPad": "新記事本", "index.settings": "設定", @@ -116,6 +134,11 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF(開放文件格式)", + "pad.importExport.exporthtmla.title": "匯出成 HTML", + "pad.importExport.exportplaina.title": "匯出成純文字", + "pad.importExport.exportworda.title": "匯出成 Microsoft Word", + "pad.importExport.exportpdfa.title": "匯出成 PDF", + "pad.importExport.exportopena.title": "匯出成 ODF(開放文件格式)", "pad.modals.connected": "已連線。", "pad.modals.reconnecting": "重新連線到您的記事本…", "pad.modals.forcereconnect": "強制重新連線", From a65e3b75a4524a58871a89a724b3ff38f759054c Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 12 Jun 2026 12:12:36 +0100 Subject: [PATCH 02/43] fix(pad): show saved-revision markers in in-pad history mode (#7946) (#7948) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(pad): show saved-revision markers in in-pad history mode (#7946) When #7659 moved the timeslider into the pad as an embedded iframe, the user-facing control became the outer #history-slider-input range input. The saved-revision stars are still drawn by broadcast_slider.ts into the iframe's #ui-slider-bar, but that DOM is hidden in embed mode, and pad_mode.ts bridged rev/max/value/timer/authors to the outer slider but never the saved revisions. Result: clicking "Save Revision" appeared to work but no markers showed in the timeslider (regression in 3.3.x). Bridge the embedded timeslider's clientVars.savedRevisions onto the outer slider as percentage-positioned star markers, rendered on first sync and re-rendered when the slider max changes. Markers are a purely visual, aria-hidden overlay (keyboard/SR users already reach any revision via the slider + step buttons) with a click-to-seek convenience for mouse users. Adds a frontend-new Playwright spec exercising the real user flow (save a revision in the pad, enter in-pad history mode, assert a visible marker on the outer slider). The only prior coverage lived in the legacy mocha suite (src/tests/frontend/specs/timeslider_revisions.js) which no CI workflow runs, and the modern timeslider specs drive the ?embed=1 iframe directly and never exercise the outer history UI — so this regression was invisible to CI. Co-Authored-By: Claude Opus 4.8 (1M context) * fix(pad): live saved-revision markers + Qodo review fixes (#7946) Address Qodo review on #7948: - Live updates (bug 1): the server's SAVE_REVISION handler never broadcast NEW_SAVEDREV, so the client handler that adds a star was dead and no open timeslider ever updated live. Wire it up: Pad.addSavedRevision returns the new revision (undefined on duplicate); handleSaveRevisionMessage broadcasts NEW_SAVEDREV to the pad room. pad_mode.ts now sources outer markers from the embedded slider's live #ui-slider-bar .star DOM (labels from clientVars) and observes that bar so a revision saved by a collaborator appears on an already-open history slider. Live editors ignore the unknown message type. - Single-revision pad (bug 2): allow max === 0 so a revision saved at rev 0 still renders a marker instead of being cleared by the old max <= 0 guard. - Test rigor (bug 3): assert the marker's inline left percentage directly instead of falling back to a layout coordinate, which let left:0% pass. Adds a two-client Playwright test for the live path (verified it fails with the server broadcast removed). Backend Pad + pad API specs (88) still pass. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- src/node/db/Pad.ts | 3 + src/node/handler/PadMessageHandler.ts | 13 ++- src/static/css/pad.css | 44 ++++++++- src/static/js/pad_mode.ts | 94 ++++++++++++++++++ src/templates/pad.html | 11 ++- .../specs/timeslider_saved_revisions.spec.ts | 97 +++++++++++++++++++ 6 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 src/tests/frontend-new/specs/timeslider_saved_revisions.spec.ts diff --git a/src/node/db/Pad.ts b/src/node/db/Pad.ts index 840770cbc..8ab3ac9d9 100644 --- a/src/node/db/Pad.ts +++ b/src/node/db/Pad.ts @@ -868,6 +868,8 @@ class Pad { await this.saveToDatabase(); } + // Returns the newly created saved revision, or undefined if this revision + // was already saved (so callers can broadcast only genuine additions). async addSavedRevision(revNum: string, savedById: string, label: string) { // if this revision is already saved, return silently for (const i in this.savedRevisions) { @@ -887,6 +889,7 @@ class Pad { // save this new saved revision this.savedRevisions.push(savedRevision); await this.saveToDatabase(); + return savedRevision; } getSavedRevisions() { diff --git a/src/node/handler/PadMessageHandler.ts b/src/node/handler/PadMessageHandler.ts index 0bf559dfd..0837cc7fe 100644 --- a/src/node/handler/PadMessageHandler.ts +++ b/src/node/handler/PadMessageHandler.ts @@ -622,7 +622,18 @@ exports.handleMessage = async (socket:any, message: ClientVarMessage) => { const handleSaveRevisionMessage = async (socket:any, message: ClientSaveRevisionMessage) => { const {padId, author: authorId} = sessioninfos[socket.id]; const pad = await padManager.getPad(padId, null, authorId); - await pad.addSavedRevision(pad.head, authorId); + const savedRevision = await pad.addSavedRevision(pad.head, authorId); + // Notify every client in the pad room — including any open timeslider — + // so saved-revision markers appear live instead of only on the next + // timeslider load (#7946). The client's NEW_SAVEDREV handler existed but + // was never reached because this broadcast was missing; live editors that + // don't handle the type ignore it. Skip the emit for duplicate saves. + if (savedRevision) { + socketio.sockets.in(padId).emit('message', { + type: 'COLLABROOM', + data: {type: 'NEW_SAVEDREV', savedRev: savedRevision}, + }); + } }; /** diff --git a/src/static/css/pad.css b/src/static/css/pad.css index e2bc4c89e..fb43a1154 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -214,12 +214,52 @@ body.history-mode #history-controls { display: flex; } .history-controls button.buttonicon.buttonicon-play.pause::before { content: "\e829"; } -.history-slider-input { +.history-slider-wrap { + position: relative; flex: 1 1 auto; min-width: 80px; margin: 0 6px; + display: flex; + align-items: center; +} +.history-slider-input { + flex: 1 1 auto; + min-width: 0; + width: 100%; cursor: pointer; } +/* Saved-revision markers overlaid on the slider track (issue #7946). Inset + * left/right by ~half the native range thumb so a marker lines up with the + * thumb centre at the track extremes. pointer-events:none on the layer keeps + * slider dragging unobstructed; the stars themselves re-enable clicks to seek. */ +.history-slider-stars { + position: absolute; + left: 8px; + right: 8px; + top: 0; + bottom: 0; + pointer-events: none; +} +.history-slider-stars .history-star { + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: 16px; + height: 16px; + padding: 0; + margin: 0; + border: 0; + background: none; + line-height: 1; + cursor: pointer; + pointer-events: auto; +} +.history-slider-stars .history-star::before { + font-family: fontawesome-etherpad; + content: "\e856"; + color: #da9700; + font-size: 14px; +} .history-timer { flex: 0 0 auto; font-size: 12px; @@ -282,7 +322,7 @@ body.history-mode #history-controls { display: flex; } @media (max-width: 800px) { .history-controls { padding: 0 6px; gap: 4px; min-height: 36px; } .history-controls button.buttonicon { padding: 4px 6px; min-width: 32px; } - .history-slider-input { min-width: 60px; margin: 0 2px; } + .history-slider-wrap { min-width: 60px; margin: 0 2px; } } @media (max-width: 480px) { .history-controls #history-leftstep, diff --git a/src/static/js/pad_mode.ts b/src/static/js/pad_mode.ts index 499d9832b..166344070 100644 --- a/src/static/js/pad_mode.ts +++ b/src/static/js/pad_mode.ts @@ -55,6 +55,10 @@ class PadModeController { private padId: string; private innerHashChangeHandler: (() => void) | null = null; private revObserver: MutationObserver | null = null; + // Watches the embedded slider's #ui-slider-bar so saved revisions added live + // (NEW_SAVEDREV from a collaborator while we're in history mode) get mirrored + // onto the outer slider — clientVars only carries the entry-time snapshot. + private savedRevObserver: MutationObserver | null = null; private syncingHash = false; // History-mode bridges — populated on enter, torn down on exit. @@ -194,6 +198,11 @@ class PadModeController { } this.revLabel.textContent = ''; this.dateLabel.textContent = ''; + const stars = document.getElementById('history-slider-stars'); + if (stars) { + stars.replaceChildren(); + stars.dataset.sig = ''; + } } // Restore everything entry-time we stashed: chat message visibility, the @@ -248,6 +257,10 @@ class PadModeController { this.revObserver.disconnect(); this.revObserver = null; } + if (this.savedRevObserver) { + this.savedRevObserver.disconnect(); + this.savedRevObserver = null; + } if (this.iframe) { try { if (this.innerHashChangeHandler && this.iframe.contentWindow) { @@ -374,6 +387,10 @@ class PadModeController { playBtn.classList.toggle('pause', playing); playBtn.setAttribute('aria-pressed', playing ? 'true' : 'false'); } + // Saved-revision markers depend on the slider max, which is only known + // once the inner slider has reported its length — render them here so we + // pick up the correct positions on first sync and on any max change. + this.renderSavedRevisionStars(innerWin); }; // The hook registered earlier in attachInnerBridges already calls // onRevChange — piggyback on it for slider input/timer updates by @@ -386,10 +403,87 @@ class PadModeController { } BS.onSlider(sync); sync(BS.getSliderPosition?.() ?? 0); + // Now that the inner slider exists, watch it for live NEW_SAVEDREV stars. + this.observeInnerSavedRevisions(innerWin); }; registerSync(); } + // Mirror the embedded timeslider's saved revisions onto the outer slider as + // clickable star markers (issue #7946). The inner slider draws its own stars + // on #ui-slider-bar, but that DOM is hidden in embed mode, so users only see + // the outer #history-slider-input — which had no markers. + // + // The inner #ui-slider-bar .star elements are the live source of truth: the + // timeslider keeps them current as NEW_SAVEDREV messages arrive (each carries + // a `pos` attribute = revNum), whereas clientVars.savedRevisions is only the + // entry-time snapshot. We read positions from those stars and pull labels + // from the snapshot where available. A signature guard keeps this cheap when + // sync() fires on every scrub; positions are percentage-based so they reflow + // on resize for free. + private renderSavedRevisionStars(innerWin: Window): void { + const inner: any = innerWin as any; + const layer = document.getElementById('history-slider-stars'); + const sliderInput = document.getElementById('history-slider-input') as HTMLInputElement | null; + if (!layer || !sliderInput || !innerWin.document) return; + + const max = Number(sliderInput.max) || 0; + const revNums = Array.from(innerWin.document.querySelectorAll('#ui-slider-bar .star')) + .map((el) => Number(el.getAttribute('pos'))) + // max === 0 is a valid single-revision pad: only rev 0 belongs there. + .filter((n) => Number.isFinite(n) && n >= 0 && (max === 0 ? n === 0 : n <= max)); + + if (revNums.length === 0 || max < 0) { + if (layer.childElementCount) layer.replaceChildren(); + layer.dataset.sig = ''; + return; + } + + // Labels live in the clientVars snapshot, keyed by revNum. + const labels = new Map(); + const snapshot = inner.clientVars?.savedRevisions; + if (Array.isArray(snapshot)) { + for (const r of snapshot) { + const n = Number(r && r.revNum); + if (Number.isFinite(n) && r && typeof r.label === 'string' && r.label) labels.set(n, r.label); + } + } + + const sig = `${max}:${[...revNums].sort((a, b) => a - b).join(',')}`; + if (layer.dataset.sig === sig) return; + layer.dataset.sig = sig; + layer.replaceChildren(); + + for (const revNum of revNums) { + const frac = max === 0 ? 0 : revNum / max; + // A purely visual marker (the layer is aria-hidden): keyboard/screen + // reader users already reach any revision via the slider and step + // buttons, so we mirror the legacy timeslider's mouse-only stars rather + // than inject extra tab stops. The hover title aids mouse users; the + // click is a convenience to jump straight to the saved point. + const star = document.createElement('span'); + star.className = 'history-star'; + star.style.left = `${(frac * 100).toFixed(4)}%`; + star.title = labels.get(revNum) || `Revision ${revNum}`; + star.addEventListener('click', () => { + try { inner.BroadcastSlider?.setSliderPosition?.(revNum); } catch (_e) { /* inner gone */ } + }); + layer.appendChild(star); + } + } + + // Re-render the outer markers whenever the embedded slider adds a star + // (NEW_SAVEDREV). Observing the inner #ui-slider-bar covers saved revisions + // created live while history mode is open, which sync()'s scrub-driven + // callback would otherwise miss until the next slider move. + private observeInnerSavedRevisions(innerWin: Window): void { + if (this.savedRevObserver) return; + const bar = innerWin.document && innerWin.document.getElementById('ui-slider-bar'); + if (!bar) return; + this.savedRevObserver = new MutationObserver(() => { this.renderSavedRevisionStars(innerWin); }); + this.savedRevObserver.observe(bar, {childList: true}); + } + // Capture the live state we'll restore on exit: live chat message // visibility (just the timestamps — actual messages stay), live users // panel HTML, and current Export hrefs. diff --git a/src/templates/pad.html b/src/templates/pad.html index 6bbc359c6..ce176a8e3 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -159,8 +159,15 @@ - + + + + + + - <% } %>

About

Powered by Etherpad diff --git a/src/tests/backend/specs/api/deletePad.ts b/src/tests/backend/specs/api/deletePad.ts index fe118aa4e..1268f4e9a 100644 --- a/src/tests/backend/specs/api/deletePad.ts +++ b/src/tests/backend/specs/api/deletePad.ts @@ -80,6 +80,17 @@ describe(__filename, function () { await callApi('deletePad', {padID: padId}); }); + it('createPad returns null deletionToken when allowPadDeletionByAllUsers is on', async function () { + // Anyone can delete the pad with no token at all, so the recovery token is + // pointless — matches the socket/UI path (issue #7926). + settings.allowPadDeletionByAllUsers = true; + const padId = makeId(); + const res = await callApi('createPad', {padID: padId}); + assert.equal(res.body.code, 0, JSON.stringify(res.body)); + assert.equal(res.body.data.deletionToken, null); + await callApi('deletePad', {padID: padId}); + }); + it('JWT admin call (no deletionToken) still works — admins stay trusted', async function () { const padId = makeId(); await callApi('createPad', {padID: padId}); diff --git a/src/tests/backend/specs/socketio.ts b/src/tests/backend/specs/socketio.ts index 84a306282..441f8110e 100644 --- a/src/tests/backend/specs/socketio.ts +++ b/src/tests/backend/specs/socketio.ts @@ -493,6 +493,8 @@ describe(__filename, function () { }); describe('Pad deletion token issuance (#7926)', function () { + let getAuthorIdBackup: any; + const removeIfExists = async (padId: string) => { if (await padManager.doesPadExist(padId)) { const p = await padManager.getPad(padId); @@ -500,14 +502,32 @@ describe(__filename, function () { } }; + // A getAuthorId hook that pins authorID to the authenticated username — the + // documented way (doc/api/hooks_server-side) to give a user a stable + // identity across cookie clears and devices. Its mere presence is what makes + // an authenticated session "durable" for token-suppression purposes. + const installStableIdentityHook = () => { + plugins.hooks.getAuthorId = [{hook_fn: async (hookName: string, context: any) => { + const username = context.user && context.user.username; + if (!username) return; + context.dbKey = `username=${username}`; + return ''; + }}]; + }; + beforeEach(async function () { // @ts-ignore - public setting toggled per test settings.allowPadDeletionByAllUsers = false; + // The outer harness only backs up preAuthorize/authenticate/authorize, so + // manage getAuthorId ourselves to avoid leaking it into later specs. + getAuthorIdBackup = plugins.hooks.getAuthorId; + plugins.hooks.getAuthorId = []; await removeIfExists('pad'); }); afterEach(async function () { if (socket) socket.close(); socket = null; + plugins.hooks.getAuthorId = getAuthorIdBackup; await removeIfExists('pad'); }); @@ -519,6 +539,7 @@ describe(__filename, function () { assert.equal(typeof cv.data.padDeletionToken, 'string', 'creator should get a token so the client can show the save-token modal'); assert.ok(cv.data.padDeletionToken.length >= 32); + assert.equal(cv.data.canDeleteWithoutToken, false); }); it('no token (and so no modal) when allowPadDeletionByAllUsers is true', async function () { @@ -532,7 +553,33 @@ describe(__filename, function () { // client, so the "Save your pad deletion token" modal never appears. Anyone // can already delete the pad without a token in this configuration. assert.equal(cv.data.padDeletionToken, null); + assert.equal(cv.data.canDeleteWithoutToken, true); }); + + it('authenticated creator WITHOUT a getAuthorId hook still gets a token', async function () { + // requireAuthentication alone is NOT durable: the authorID still comes from + // the per-browser token cookie, so this user would be stranded on a second + // device if the token were withheld. They must keep getting one. + settings.requireAuthentication = true; + const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200); + socket = await common.connect(res); + const cv: any = await common.handshake(socket, 'pad'); + assert.equal(cv.type, 'CLIENT_VARS'); + assert.equal(typeof cv.data.padDeletionToken, 'string'); + assert.equal(cv.data.canDeleteWithoutToken, false); + }); + + it('authenticated creator WITH a getAuthorId hook gets no token (durable identity)', + async function () { + settings.requireAuthentication = true; + installStableIdentityHook(); + const res = await agent.get('/p/pad').auth('user', 'user-password').expect(200); + socket = await common.connect(res); + const cv: any = await common.handshake(socket, 'pad'); + assert.equal(cv.type, 'CLIENT_VARS'); + assert.equal(cv.data.padDeletionToken, null); + assert.equal(cv.data.canDeleteWithoutToken, true); + }); }); describe('SocketIORouter.js', function () { From 4371af77c2417d0ecfeb0c559ff006458506ca29 Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Mon, 15 Jun 2026 14:03:51 +0200 Subject: [PATCH 13/43] Localisation updates from https://translatewiki.net. --- src/locales/de.json | 86 +++++++++++++++++++++++++++++++++++++++++++++ src/locales/mk.json | 50 +++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/src/locales/de.json b/src/locales/de.json index 94b74db0c..fda6f9bc1 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -40,6 +40,7 @@ "admin_pads.bulk.clear_selection": "Auswahl löschen", "admin_pads.bulk.delete": "Löschen", "admin_pads.cancel": "Abbrechen", + "admin_pads.col.pad": "Pad", "admin_pads.col.revisions": "Bearbeitungen", "admin_pads.col.users": "Benutzer", "admin_pads.confirm_button": "OK", @@ -48,13 +49,54 @@ "admin_pads.delete_pad_dialog_title": "Pad löschen", "admin_pads.empty_never_edited": "leer · nie bearbeitet", "admin_pads.error_dialog_description": "Ein Fehler ist aufgetreten", + "admin_pads.error_prefix": "Fehler", + "admin_pads.filter.active": "Aktiv", + "admin_pads.filter.all": "Alle", + "admin_pads.filter.empty": "Leer", + "admin_pads.filter.recent": "Diese Woche", + "admin_pads.filter.stale": "Veraltet (> 1 Jahr)", + "admin_pads.open": "Offen", + "admin_pads.pagination.next": "Weiter", + "admin_pads.pagination.previous": "Zurück", + "admin_pads.refresh": "Aktualisieren", + "admin_pads.relative.days": "vor {{count}} Tag(en)", + "admin_pads.relative.hours": "vor {{count}} Stunde(n)", + "admin_pads.relative.just_now": "Soeben", + "admin_pads.relative.minutes": "vor {{count}} Minute(n)", + "admin_pads.relative.months": "vor {{count}} Monat(en)", + "admin_pads.relative.weeks": "vor {{count}} Woche(n)", + "admin_pads.relative.years": "vor {{count}} Jahr(en)", + "admin_pads.revisions_count": "{{count}} Bearbeitungen", + "admin_pads.selected_count": "{{count}} ausgewählt", + "admin_pads.show": "Anzeigen", + "admin_pads.sort.name": "Name (A–Z)", + "admin_pads.sort.revision_number": "Bearbeitungen", + "admin_pads.sort.user_count": "Nutzer", + "admin_pads.stats.across_pads": "über alle Pads", + "admin_pads.stats.active_users": "Aktive Nutzer", + "admin_pads.stats.empty_pads": "Leere Pads", + "admin_pads.stats.last_activity": "Letzte Aktivität", + "admin_pads.stats.no_active_users": "Keine aktiven Benutzer", + "admin_pads.stats.revisions_zero": "0 Bearbeitungen", + "admin_pads.stats.total": "Gesamtanzahl Pads", + "admin_pads.stats.users_active": "{{count}} aktuell aktiv", + "admin_pads.subtitle": "Überblick über alle Pads auf dieser Etherpad-Instanz. Suchen, aufräumen, öffnen.", "admin_plugins": "Pluginverwaltung", "admin_plugins.available": "Verfügbare Plugins", "admin_plugins.available_not-found": "Keine Plugins gefunden.", "admin_plugins.available_fetching": "Wird abgerufen...", "admin_plugins.available_install.value": "Installieren", "admin_plugins.available_search.placeholder": "Suche nach Plugins zum Installieren", + "admin_plugins.check_updates": "Nach Updates suchen", + "admin_plugins.core_count": "{{count}} Kern(e)", + "admin_plugins.catalog_disabled": "Plugin-Katalog wurde vom Betreiber deaktiviert (privacy.pluginCatalog=false). Um ein Plugin zu installieren, führen Sie `pnpm run plugins i ep_` auf dem Server aus.", + "admin_plugins.crumbs": "Plugins", "admin_plugins.description": "Beschreibung", + "admin_plugins.disables.label": "Deaktiviert:", + "admin_plugins.disables.warning_title": "Dieses Plugin entfernt absichtlich die aufgeführten Etherpad-Funktionen.", + "admin_plugins.error_retrieving": "Fehler beim Abrufen von Plugins", + "admin_plugins.install_error": "Installation von {{plugin}} fehlgeschlagen: {{error}}", + "admin_plugins.install_error_requires_newer_etherpad": "Installation von {{plugin}} nicht möglich: hierfür ist neuere Version von Etherpad notwendig. Bitte führe ein Upgrade von Etherpad durch und versuche es erneut.", "admin_plugins.installed": "Installierte Plugins", "admin_plugins.installed_fetching": "Rufe installierte Plugins ab...", "admin_plugins.installed_nothing": "Du hast bisher noch keine Plugins installiert.", @@ -62,23 +104,67 @@ "admin_plugins.last-update": "Letze Aktualisierung", "admin_plugins.name": "Name", "admin_plugins.page-title": "Plugin Manager - Etherpad", + "admin_plugins.reload_catalog": "Katalog neu laden", + "admin_plugins.search_npm": "Suche auf npm", + "admin_plugins.sort_ascending": "Aufsteigend sortieren", + "admin_plugins.sort_descending": "Absteigend sortieren", + "admin_plugins.sort.last_updated": "Zuletzt aktualisiert", + "admin_plugins.sort.name": "Name (A–Z)", + "admin_plugins.sort.version": "Version", + "admin_plugins.source": "Plugin-Quelle", + "admin_plugins.subtitle": "Installieren, aktualisieren und entfernen Sie Etherpad-Plugins. Änderungen erfordern einen Server-Neustart.", + "admin_plugins.tag_core": "Kern", + "admin_plugins.update_tooltip": "Update", + "admin_plugins.updates_available": "Updates verfügbar", + "admin_plugins.update_now": "Update", "admin_plugins.version": "Version", "admin_plugins_info": "Hilfestellung", + "admin_plugins_info.copy_diagnostics": "Kopiere Diagnose-Daten", + "admin_plugins_info.copy_value": "Kopiere {{label}}", + "admin_plugins_info.git_sha": "Git SHA", + "admin_plugins_info.hook_bindings": "Hook-Bindungen", "admin_plugins_info.hooks": "Installierte Hooks", "admin_plugins_info.hooks_client": "Client-seitige Hooks", "admin_plugins_info.hooks_server": "Server-seitige Hooks", + "admin_plugins_info.no_hooks": "Keine Hooks gefunden", "admin_plugins_info.parts": "Installierte Teile", "admin_plugins_info.plugins": "Installierte Plugins", "admin_plugins_info.page-title": "Plugin Informationen - Etherpad", + "admin_plugins_info.search_placeholder": "Suche Hook oder Teil…", + "admin_plugins_info.subtitle": "Systemdiagnose: installierte Version, registrierte Teile und Hooks.", + "admin_plugins_info.tab_client": "Client", + "admin_plugins_info.tab_server": "Server", + "admin_plugins_info.up_to_date": "Aktuell", + "admin_plugins_info.update_available": "Update verfügbar: {{version}}", "admin_plugins_info.version": "Etherpad Version", "admin_plugins_info.version_latest": "Neueste verfügbare Version", "admin_plugins_info.version_number": "Versionsnummer", "admin_settings": "Einstellungen", + "admin_settings.create_pad": "Pad erstellen", "admin_settings.current": "Derzeitige Konfiguration", "admin_settings.current_example-devel": "Beispielhafte Entwicklungseinstellungs-Templates", "admin_settings.current_example-prod": "Beispiel eines produktiven Templates", "admin_settings.current_restart.value": "Etherpad neustarten", "admin_settings.current_save.value": "Einstellungen speichern", + "admin_settings.invalid_json": "Ungültiges JSON", + "admin_settings.current_test.value": "Validiere JSON", + "admin_settings.current_prettify.value": "Prettify JSON", + "admin_settings.toast.saved": "Einstellungen erfolgreich gespeichert.", + "admin_settings.toast.save_failed": "Speichern fehlgeschlagen: settings.json konnte nicht geschrieben werden.", + "admin_settings.toast.json_invalid": "Syntaxfehler: Überprüfen Sie Kommas, Klammern und Anführungszeichen.", + "admin_settings.toast.disconnected": "Nicht gespeichert: Nicht mit dem Server verbunden.", + "admin_settings.toast.validation_ok": "JSON ist gültig.", + "admin_settings.toast.validation_failed": "JSON ist ungültig: Bitte beheben Sie Syntaxfehler.", + "admin_settings.toast.prettify_failed": "Prettify nicht möglich: Bitte beheben Sie zunächst Syntaxfehler.", + "admin_settings.prettify_confirm": "Prettify entfernt alle Kommentare. Weiter?", + "admin_settings.mode.form": "Formular", + "admin_settings.mode.effective_tooltip": "Read-only-Ansicht der Werte, die Etherpad tatsächlich verwendet, nach Umgebungsvariablen-Ersetzung. Secrets sind geschwärzt.", + "admin_settings.mode.aria_label": "Editor-Modus", + "admin_settings.envvar_banner.title": "Diese Datei ist eine Vorlage, nicht die Live-Konfiguration.", + "admin_settings.envvar_banner.body": "Platzhalter wie ${VAR:default} werden beim Start in den Speicher eingesetzt; sie werden nie in diese Datei zurückgeschrieben. Bearbeiten Sie env vars in Ihrer Umgebung (Docker compose, systemd, .env), um den aufgelösten Wert zu ändern, oder ersetzen Sie den Platzhalter hier durch ein Literal. Wechseln Sie auf die Registerkarte \"Effective\", um zu sehen, was Etherpad gerade verwendet.", + "admin_settings.toast.auth_error": "Sie sind nicht als Administrator authentifiziert. Bitte melden Sie sich erneut an.", + "admin_settings.section.general": "Allgemein", + "admin_settings.parse_error.title": "Parsen von settings.json nicht möglich", "admin_settings.page-title": "Einstellungen - Etherpad", "index.newPad": "Neues Pad", "index.settings": "Einstellungen", diff --git a/src/locales/mk.json b/src/locales/mk.json index 05842c56c..f81114465 100644 --- a/src/locales/mk.json +++ b/src/locales/mk.json @@ -187,8 +187,39 @@ "update.page.policy.rollback-failed-terminal": "Претходната поднова не успеа и не можеше да се отповика. Стиснете на „Прифати“ откако воспоставката ќе стане задрава за да отклучите.", "update.page.policy.up-to-date": "Ја користите најновата верзија.", "update.page.policy.tier-off": "Подновие се оневозможени (updates.tier = „off“).", + "update.page.policy.maintenance-window-missing": "Ниво 4 (автономно) бара период на одржување. Задајте го updates.maintenanceWindow во settings.json за да овозможите автономни поднови.", + "update.page.policy.maintenance-window-invalid": "Ниво 4 (автономно) е оневозможено бидејќи updates.maintenanceWindow е погрешно срочен. Се очекуваше {start, end, tz} со времиња ЧЧ:ММ и tz да биде „local“ или „utc“.", + "update.page.last_result.verified": "Потврдена последната поднова на {{tag}}.", + "update.page.last_result.rolled-back": "Отповикан последниот обид за поднова на {{tag}}: {{reason}}.", + "update.page.last_result.rollback-failed": "Последниот обид за поднова не успеа И отповикувањето не успеа: {{reason}}. Потребна е рачна интервенција.", + "update.page.last_result.preflight-failed": "Не успеа последниот обид за поднова на {{tag}} во подготовката: {{reason}}.", + "update.page.last_result.cancelled": "Последниот обид за поднова на {{tag}} е откажан од администратор.", + "update.execution.idle": "Неактивно", + "update.execution.scheduled": "Подновата е закажана", "update.execution.preflight": "Подготвителни проверки", "update.execution.preflight-failed": "Проверките не успеаја", + "update.execution.draining": "Исцрпувачки седници", + "update.execution.executing": "Подновувам...", + "update.execution.pending-verification": "Чека на потврда", + "update.execution.verified": "Потврдено", + "update.execution.rolling-back": "Отповикување", + "update.execution.rolled-back": "Отповикано", + "update.execution.rollback-failed": "Отповикувањето не успеа", + "update.banner.terminal.rollback-failed": "Не успеа обидот за поднова и не можеше да биде отповикан. Потребна е рачна интервенција.", + "update.banner.scheduled": "Автоподновата на {{tag}} е закажана — на сила за {{remaining}}.", + "update.banner.maintenance-window-missing": "Автономните поднови се оневозможени додека не се постави период на одржување.", + "update.banner.maintenance-window-invalid": "Автономните поднови се оневозможени бидејќи периодот на одржување е погрешно срочен.", + "update.page.scheduled.title": "Подновата е закажана", + "update.page.scheduled.countdown": "Etherpad ќе почне со подновување на {{tag}} за {{remaining}}.", + "update.page.scheduled.deferred_until": "Вон периодот на одржување. Подновата ќе почне кога периодот ќе започне во {{at}}.", + "update.page.scheduled.apply_now": "Примени сега", + "update.window.title": "Период на одржување", + "update.window.summary": "{{start}}–{{end}} ({{tz}})", + "update.window.unset": "Не е наместено.", + "update.window.next_opens_at": "Следниот период почнува на {{at}}.", + "update.drain.t60": "Etherpad ќе се превклучи за 60 секунди за да направи примена и поднова.", + "update.drain.t30": "Etherpad ќе се превклучи за 30 секунди за да направи примена и поднова.", + "update.drain.t10": "Etherpad ќе се превклучи за 10 секунди за да направи примена и поднова.", "index.newPad": "Нова тетратка", "index.settings": "Нагодувања", "index.transferSessionTitle": "Префрли седница", @@ -201,6 +232,7 @@ "index.copyLinkButton": "Копирај врска во меѓускладот", "index.transferToSystem": "3. Копирај седница во нов систем", "index.transferToSystemDescription": "Отворете ја ископираната врска во целниот прелистувач или уред за да ја префрлите вашата седница.", + "index.code": "Код", "index.transferSessionDescription": "Префрлете ја вашата тековна седница на прелистувач или уред стискајќи на копчето подолу. Ова ќе ја прекопира врската во страница која ќе ви ја префрли седницата кога ќе се отвори во целниот прелистувач или уред.", "index.createOpenPad": "Отвори тетратка по име", "index.openPad": "отвори постоечка тетратка наречена:", @@ -275,6 +307,12 @@ "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.exportetherpada.title": "Извези како Etherpad", + "pad.importExport.exporthtmla.title": "Извези како HTML", + "pad.importExport.exportplaina.title": "Извези како прост текст", + "pad.importExport.exportworda.title": "Извези како Microsoft Word", + "pad.importExport.exportpdfa.title": "Извези како PDF", + "pad.importExport.exportopena.title": "Извези како ODF (Open Document Format)", "pad.importExport.noConverter.innerHTML": "Можете да увезувате само од прост текст или HTML-форматти. Понапредни можности за увоз ќе добиете ако го воспоставите LibreOffice.", "pad.modals.connected": "Поврзано.", "pad.modals.reconnecting": "Ве преповрзувам со тетратката...", @@ -325,16 +363,26 @@ "pad.historyMode.revisionLabel": "Преработка {{rev}}", "pad.historyMode.controlsLabel": "Контроли за историја на тетратката", "pad.historyMode.sliderLabel": "Преработка на тетратката", + "pad.historyMode.settings.title": "Преглед на историјата", + "pad.historyMode.settings.follow": "Следи поднови на содржини тетратки", "pad.historyMode.settings.followShort": "Следи", "pad.historyMode.followOn": "Следите промени во тетратката — стиснете за да престанете со следење", "pad.historyMode.followOff": "Не следите промени во тетратката — стиснете за да следите", + "pad.historyMode.settings.playbackSpeed": "Брзина на прегледувањето:", + "pad.historyMode.chat.replayHeader": "Разговор од {{time}}", + "pad.historyMode.users.authorsHeader": "Авроти на оваа преработка", + "pad.editor.skipToContent": "Прејди на уредувачот", + "pad.editor.keyboardHint": "Стиснете Escape за да излезете од уредувачот. Стиснете Alt+F9 за алатникот.", + "pad.editor.toolbar.formatting": "Алатник за форматирање", + "pad.editor.toolbar.actions": "Алатник за дејства врз тетратка", + "pad.editor.toolbar.showMore": "Покажи повеќе копчиња на алатникот", "timeslider.toolbar.authors": "Автори:", "timeslider.toolbar.authorsList": "Нема автори", "timeslider.toolbar.exportlink.title": "Извоз", "timeslider.exportCurrent": "Извези ја тековната верзија како:", "timeslider.version": "Верзија {{version}}", "timeslider.saved": "Зачувано на {{day}} {{month}} {{year}} г.", - "timeslider.settings.playbackSpeed": "Брзина на репродукција:", + "timeslider.settings.playbackSpeed": "Брзина на прегледување:", "timeslider.settings.playbackSpeed.original": "Изворна брзина", "timeslider.settings.playbackSpeed.realtime": "Реално време", "timeslider.settings.playbackSpeed.200ms": "200 мс", From c8e3248bcd4886bd701362755e502ca7e2a48e81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:38:06 +0100 Subject: [PATCH 14/43] build(deps-dev): bump the dev-dependencies group with 6 updates (#7964) Bumps the dev-dependencies group with 6 updates: | Package | From | To | | --- | --- | --- | | [@playwright/test](https://github.com/microsoft/playwright) | `1.60.0` | `1.61.0` | | [eslint](https://github.com/eslint/eslint) | `10.4.1` | `10.5.0` | | [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.8` | `4.1.9` | | [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) | `0.5.2` | `0.5.3` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.78.0` | `7.79.0` | | [oxc-minify](https://github.com/oxc-project/oxc/tree/HEAD/napi/minify) | `0.135.0` | `0.136.0` | Updates `@playwright/test` from 1.60.0 to 1.61.0 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.60.0...v1.61.0) Updates `eslint` from 10.4.1 to 10.5.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.4.1...v10.5.0) Updates `vitest` from 4.1.8 to 4.1.9 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/HEAD/packages/vitest) Updates `eslint-plugin-react-refresh` from 0.5.2 to 0.5.3 - [Release notes](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/releases) - [Changelog](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/CHANGELOG.md) - [Commits](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/compare/v0.5.2...v0.5.3) Updates `react-hook-form` from 7.78.0 to 7.79.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.78.0...v7.79.0) Updates `oxc-minify` from 0.135.0 to 0.136.0 - [Release notes](https://github.com/oxc-project/oxc/releases) - [Changelog](https://github.com/oxc-project/oxc/blob/main/napi/minify/CHANGELOG.md) - [Commits](https://github.com/oxc-project/oxc/commits/crates_v0.136.0/napi/minify) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-version: 1.61.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies - dependency-name: eslint dependency-version: 10.5.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies - dependency-name: vitest dependency-version: 4.1.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies - dependency-name: eslint-plugin-react-refresh dependency-version: 0.5.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies - dependency-name: react-hook-form dependency-version: 7.79.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies - dependency-name: oxc-minify dependency-version: 0.136.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- admin/package.json | 6 +- doc/package.json | 2 +- pnpm-lock.yaml | 563 ++++++++++++++++++++++++--------------------- src/package.json | 6 +- 4 files changed, 308 insertions(+), 269 deletions(-) diff --git a/admin/package.json b/admin/package.json index 81037d47b..738d06010 100644 --- a/admin/package.json +++ b/admin/package.json @@ -31,16 +31,16 @@ "@typescript-eslint/parser": "^8.61.0", "@vitejs/plugin-react": "^6.0.2", "babel-plugin-react-compiler": "19.1.0-rc.3", - "eslint": "^10.4.1", + "eslint": "^10.5.0", "eslint-plugin-react-hooks": "^7.1.1", - "eslint-plugin-react-refresh": "^0.5.2", + "eslint-plugin-react-refresh": "^0.5.3", "i18next": "^26.3.1", "i18next-browser-languagedetector": "^8.2.1", "lucide-react": "^1.18.0", "openapi-typescript": "^7.13.0", "react": "^19.2.7", "react-dom": "^19.2.7", - "react-hook-form": "^7.78.0", + "react-hook-form": "^7.79.0", "react-i18next": "^17.0.8", "react-router-dom": "^7.17.0", "socket.io-client": "^4.8.3", diff --git a/doc/package.json b/doc/package.json index 4113fabf1..ee32f9db7 100644 --- a/doc/package.json +++ b/doc/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "oxc-minify": "^0.135.0", + "oxc-minify": "^0.136.0", "vitepress": "^2.0.0-alpha.17" }, "scripts": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b46e3ddae..4547c5e7a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -79,10 +79,10 @@ importers: version: 19.2.3(@types/react@19.2.17) '@typescript-eslint/eslint-plugin': specifier: ^8.61.0 - version: 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.4.1)(typescript@6.0.3))(eslint@10.4.1)(typescript@6.0.3) + version: 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3) '@typescript-eslint/parser': specifier: ^8.61.0 - version: 8.61.0(eslint@10.4.1)(typescript@6.0.3) + version: 8.61.0(eslint@10.5.0)(typescript@6.0.3) '@vitejs/plugin-react': specifier: ^6.0.2 version: 6.0.2(babel-plugin-react-compiler@19.1.0-rc.3)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) @@ -90,14 +90,14 @@ importers: specifier: 19.1.0-rc.3 version: 19.1.0-rc.3 eslint: - specifier: ^10.4.1 - version: 10.4.1 + specifier: ^10.5.0 + version: 10.5.0 eslint-plugin-react-hooks: specifier: ^7.1.1 - version: 7.1.1(eslint@10.4.1) + version: 7.1.1(eslint@10.5.0) eslint-plugin-react-refresh: - specifier: ^0.5.2 - version: 0.5.2(eslint@10.4.1) + specifier: ^0.5.3 + version: 0.5.3(eslint@10.5.0) i18next: specifier: ^26.3.1 version: 26.3.1(typescript@6.0.3) @@ -117,8 +117,8 @@ importers: specifier: ^19.2.7 version: 19.2.7(react@19.2.7) react-hook-form: - specifier: ^7.78.0 - version: 7.78.0(react@19.2.7) + specifier: ^7.79.0 + version: 7.79.0(react@19.2.7) react-i18next: specifier: ^17.0.8 version: 17.0.8(i18next@26.3.1(typescript@6.0.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3) @@ -179,11 +179,11 @@ importers: version: 2.17.3 devDependencies: oxc-minify: - specifier: ^0.135.0 - version: 0.135.0 + specifier: ^0.136.0 + version: 0.136.0 vitepress: specifier: ^2.0.0-alpha.17 - version: 2.0.0-alpha.17(@types/node@25.9.3)(change-case@5.4.4)(esbuild@0.28.1)(jwt-decode@4.0.0)(oxc-minify@0.135.0)(postcss@8.5.15)(tsx@4.22.4)(typescript@6.0.3) + version: 2.0.0-alpha.17(@types/node@25.9.3)(change-case@5.4.4)(esbuild@0.28.1)(jwt-decode@4.0.0)(oxc-minify@0.136.0)(postcss@8.5.15)(tsx@4.22.4)(typescript@6.0.3) src: dependencies: @@ -375,8 +375,8 @@ importers: version: 0.10.1 devDependencies: '@playwright/test': - specifier: ^1.60.0 - version: 1.60.0 + specifier: ^1.61.0 + version: 1.61.0 '@types/async': specifier: ^3.2.25 version: 3.2.25 @@ -453,11 +453,11 @@ importers: specifier: ^5.0.0 version: 5.0.0 eslint: - specifier: ^10.4.1 - version: 10.4.1 + specifier: ^10.5.0 + version: 10.5.0 eslint-config-etherpad: specifier: ^4.0.5 - version: 4.0.5(eslint@10.4.1)(typescript@6.0.3) + version: 4.0.5(eslint@10.5.0)(typescript@6.0.3) etherpad-cli-client: specifier: ^4.0.3 version: 4.0.3 @@ -489,8 +489,8 @@ importers: specifier: ^6.0.3 version: 6.0.3 vitest: - specifier: ^4.1.8 - version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(jsdom@29.1.1(@noble/hashes@1.8.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) + specifier: ^4.1.9 + version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(jsdom@29.1.1(@noble/hashes@1.8.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) ui: devDependencies: @@ -752,12 +752,21 @@ packages: '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} @@ -1186,6 +1195,12 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} engines: {node: ^14.21.3 || >=16} @@ -1268,129 +1283,129 @@ packages: resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} - '@oxc-minify/binding-android-arm-eabi@0.135.0': - resolution: {integrity: sha512-T2nxjePN4kYHSPnrfol3rD2XmaWoAsfxSYKS4oKA68OxaZzBtzyXzFmJVVTl5JfY1UlHhvuWYZgMO+175+pZAw==} + '@oxc-minify/binding-android-arm-eabi@0.136.0': + resolution: {integrity: sha512-gk1jzky1vLeOcK7w9Ib2RT/UooZ7O21s8YSeXCsy4tzsmguKb3Cbsv/Ra2fKhMp4mKeKCzvC1Xa41OfSBWfWdQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-minify/binding-android-arm64@0.135.0': - resolution: {integrity: sha512-FAI3D/aVLijnCANnRI2U/12R21r4nZRibnxpKuTUj9SluClqa9PyClUqfwq3kgKVigGoxx8I+lYqFQrCL29Iwg==} + '@oxc-minify/binding-android-arm64@0.136.0': + resolution: {integrity: sha512-5GIYanqud/ohXEcg2dsdn0+eSKXqclw5qlRUkvSM1sKEa4ZQ7hqOk8XPJBNPh3LXXw+Qw85B6jkmOFLKsCHp5w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-minify/binding-darwin-arm64@0.135.0': - resolution: {integrity: sha512-BSy+OE97ceuWZGafOmusNmvfyJ+f0d0J72EQ1Gh2fq05j8jOJxd7G0z962LcJAO0TJO5Z5CP9sB2VcARIjRAWQ==} + '@oxc-minify/binding-darwin-arm64@0.136.0': + resolution: {integrity: sha512-QAMpHKXWOoMCTenSZjQjVT5YmMooujlCKAf1T3PHFl2LuaA6ukQFXba0bgSLgAxRrAeX/itkwi4lzVQXtYmnRg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-minify/binding-darwin-x64@0.135.0': - resolution: {integrity: sha512-WrK+5JXw9D25bmk7FpweZx5UkRZWHYL26Qd0wEpb3uzNFWKBP+vBsYdNrD5//Rxorln0CTsbGok/1KP/BXoMcg==} + '@oxc-minify/binding-darwin-x64@0.136.0': + resolution: {integrity: sha512-rDnoPj8hztiU8C1VNKuzujh7SgTJlgiUvUCiWQjTnVSLsABsLW9ZWd1l1Ji0VN3UW39wGpptgvahIWTrHnGH/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-minify/binding-freebsd-x64@0.135.0': - resolution: {integrity: sha512-t5LkOuhm4ArRElIDbg0MK3TRMDXHneb84UL+MmF8rzYxKtdiONZP6cKFRFj1knDyWUSM3yGG8wzUrp44r5uYww==} + '@oxc-minify/binding-freebsd-x64@0.136.0': + resolution: {integrity: sha512-9fGSgP7uyPLCTjMx9z3AUV4UjnfOVoGTH5JzamLegPwGLJ97Gr1jht1437CRk8ZNabGmxQR6qNn3e+Tox2lswg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-minify/binding-linux-arm-gnueabihf@0.135.0': - resolution: {integrity: sha512-hnLoI0yR/r4I7PaX9YNtFuu+uXJkrYxKh1+dp1YnDqpx1KMDJKWfbc9iUXokgg9YC/gKvWc2snORW0J64tAh3A==} + '@oxc-minify/binding-linux-arm-gnueabihf@0.136.0': + resolution: {integrity: sha512-k0QvZS+x6ROI4O5Ikqn9dDU2dmkEJ46Yh6baZJI/eUk/a1k1GOs9/vyXItLZrKlwYrSgdEx2BFXbKgyd1NyRPw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-minify/binding-linux-arm-musleabihf@0.135.0': - resolution: {integrity: sha512-SwIlKSpvAQ9TMCYf2rQR6tmIS9IzptpgqQuR628cNkM6+j/MhOOUq8v1aCcW9NEoANMGXngpaUT/lt6XunVeQg==} + '@oxc-minify/binding-linux-arm-musleabihf@0.136.0': + resolution: {integrity: sha512-iRFxUc8ubotVfuyq3e4LPGbHrjvWd1/B3499a55GueMLc1EDJ0fHzNXJiCx2eMQGfzHtHodjmvrJ2BSvSXBNhQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-minify/binding-linux-arm64-gnu@0.135.0': - resolution: {integrity: sha512-SGx+Nz0KecvrKZbpa2/99+acKJZhm7wOBO1oS4ysfjZg5b9ziHUMqG3tds1C+tM+cjbBO6mfx5HFbHQJg0+Ngw==} + '@oxc-minify/binding-linux-arm64-gnu@0.136.0': + resolution: {integrity: sha512-hbKxNCXJsULrb6EyG5SumzJKuPfP8Y0UQ/TElRgXVUhyyPf6cBPlF8HMq+MAylF98ACBzV8jBp2Mm62lJyTo+w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-arm64-musl@0.135.0': - resolution: {integrity: sha512-fwZl0Fe7+KSJZIHgQG7XFXq8WKOr0ZUenzQt/MWmhxxbHx2u4Dkp1G//SUgrl6+jPoB2SsKvvGgRk8D0G6/rxw==} + '@oxc-minify/binding-linux-arm64-musl@0.136.0': + resolution: {integrity: sha512-T+u/CGKW0UXemJeVux4ix6rK+ug3bQCUEbu5hFlX9K61KQNd44rOcrM15mDK99L7USaXwmiwHeIkEDvmmyDMSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-minify/binding-linux-ppc64-gnu@0.135.0': - resolution: {integrity: sha512-WsZXnXeTjDqLHnKq2qdf/JTucrgYRd/dBImE/ezDUd1Y8k13FolYV2axBXvS5w7hRvIkyhr4EkVgWM1/oGbW2w==} + '@oxc-minify/binding-linux-ppc64-gnu@0.136.0': + resolution: {integrity: sha512-WNPTN2F448tb49BoqjV9IMRzZWa0WB8GHzrB+bnxKQPOyzz07T6rmDKrr4Hjl81ADGjDYSsr1fgXcjyLQFdMdw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-riscv64-gnu@0.135.0': - resolution: {integrity: sha512-L+Q2CfBf/DQqU3gCv3qjPBfkuYpjZXnvMGPSaB5gpw9vjWXBn8AbJsD3kYi19tAqImJ784ARGFdXQxkglH5CDQ==} + '@oxc-minify/binding-linux-riscv64-gnu@0.136.0': + resolution: {integrity: sha512-MvcCfu8OeabrmNN9wqhh8Gqizg68RQ3iOvXBJmlLMy5p1PC6az9bAwqOk98lsCmKI4I5LpULekOlfxRYh3o5Kw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-riscv64-musl@0.135.0': - resolution: {integrity: sha512-AW4VB30ev8dYZNSiFv7suWoc7/0L6Z2SXktPkdHUaSw0kNvncEBzfihDuCaNIpcrc9sqP7fn9UDUIRBBk0HsPQ==} + '@oxc-minify/binding-linux-riscv64-musl@0.136.0': + resolution: {integrity: sha512-rwJXFUFFA0egAULtOOgfW8YhhLhtWrr2qFxftvZ7/U6Xtxiev8i+eCwSNW1RpHiX74QMsJVpRE3ykoefqb1MtQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-minify/binding-linux-s390x-gnu@0.135.0': - resolution: {integrity: sha512-18ld7mO76R4cDGtoNgZuxJb8QhrBBowYGCsdcf35g4kk+Hbv7rtsdYpguQaolpT6w8/IqcW+T6VI8LyAFhvjIA==} + '@oxc-minify/binding-linux-s390x-gnu@0.136.0': + resolution: {integrity: sha512-qizAxHmj7VHm5/D5qiIlvzxAS2tlmadDOJ5XFI7zx/wfnk/+fdk5iVaHOv+C4tDE/4wLQyMoBYVIs6R1LeN91w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-x64-gnu@0.135.0': - resolution: {integrity: sha512-36MQ5girodh40vwdoOEhvJeGlj1lADYq1+s8vQuS3GPqTXNwdV3A8dwSsciaNEPMXf192f6m2e0IXJSSs1I0qw==} + '@oxc-minify/binding-linux-x64-gnu@0.136.0': + resolution: {integrity: sha512-gcyLAad0UblkEhGjVfx5Mwq63OSx8r04IbcfwzpZYpHisO/vioMsrs4GkDsQZ2Ejc8cdUk6YMIrf9FwNBzh+Dw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-minify/binding-linux-x64-musl@0.135.0': - resolution: {integrity: sha512-k4mBDakQOlVP1Ycfv5N+4flyEgvbK20KVuYRKQWAM0E2DzU/7lOjRKJ5qJGzDl0dPtDYBCPRY5gxHLQLCoprwA==} + '@oxc-minify/binding-linux-x64-musl@0.136.0': + resolution: {integrity: sha512-QAK6kwBjljX6luYzeppVdRP3gTaFNFfp9iS/V0cCvU43wUZay5xFXBgmzBHYrzZV2MhzURNnXfEZRo9poAxyvA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-minify/binding-openharmony-arm64@0.135.0': - resolution: {integrity: sha512-9Epc1tAMG/VxFi0iH42IGLu5M4IB7wAgQB7WEJeRgCdL+CQTgR9qXC4GORUk2AxTKrr5KR4VOrYvrdXrsmv0UQ==} + '@oxc-minify/binding-openharmony-arm64@0.136.0': + resolution: {integrity: sha512-nIGxkTOnN9GwslmooxbZ3Ti2RgbX9QLHy0X9uO0pslOT+4dsNVUawBU/6r4M5cWM+ZdRD2tOF4V+n0l8tS59nQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-minify/binding-wasm32-wasi@0.135.0': - resolution: {integrity: sha512-WRqZg9rRlujv2FkfLGoe92bvPy7ODpX5nQ7WqybkaDxNVyvFgSBOHRznNx7LeABQxWkYU2EG/36qzg/mAFJQCw==} + '@oxc-minify/binding-wasm32-wasi@0.136.0': + resolution: {integrity: sha512-YB3G8AHT6PpDS8/DfjlJrQjywj+/6gCkNBcAJdYzcYbQRIZE6SaTNowiGuZPR1m1jOl1WjcjefniKSmVxzhvRA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@oxc-minify/binding-win32-arm64-msvc@0.135.0': - resolution: {integrity: sha512-NYKM0Ga+a8TH5n0lNydIlDbNJX2blRAjDCFVb/GTCUQ9ij92S9JIA+QNfzoFzn7KCWX/hMcvIdQza5yTkgfjbQ==} + '@oxc-minify/binding-win32-arm64-msvc@0.136.0': + resolution: {integrity: sha512-UVRH3BlNc2rmla+sbSd5xTF/u+esCqZS6VSWPolZybcBh3TlVe1Sf5MOuHQWUaFoyv5uFOvee4hOfS/14nPvZw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-minify/binding-win32-ia32-msvc@0.135.0': - resolution: {integrity: sha512-dj/ZR3yQbZr7tKxZpysvEebJc0X+qxaTyTwNb4bC1xUzbXa63n8LGpt/kF2KoCucPeAcrBgAsFnsgFv47QKYig==} + '@oxc-minify/binding-win32-ia32-msvc@0.136.0': + resolution: {integrity: sha512-zFGkUd82jci0E+isc2O36lVmmXVUDXyEMN2RYIyez+MBNqhdjPLIGx62FCsrJtLKeuiPf/8XkFv977aUtndUng==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-minify/binding-win32-x64-msvc@0.135.0': - resolution: {integrity: sha512-OXsk27fpAvC6giKglT7AtXoYHAaFY+2yrpUlerAeJZ+eWHA1AK2Ev2xsJJGEdMb6ef7tr5S6m2t2AsK7CdrMYQ==} + '@oxc-minify/binding-win32-x64-msvc@0.136.0': + resolution: {integrity: sha512-VHgPwd5xibC9UYxBeq7nURTjY+wxhdumllij6JaCIUVfD9IRcrA66SVlJ5fPNoUXcRp8ZXhJfoIZwVz9wAEGJw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1401,8 +1416,8 @@ packages: '@paralleldrive/cuid2@2.2.2': resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} - '@playwright/test@1.60.0': - resolution: {integrity: sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==} + '@playwright/test@1.61.0': + resolution: {integrity: sha512-cKA5B6lpFEMyMGjxF54QihfYpB4FkEGH+qZhtArDEG+wezQAJY8Pq6C7T1SjWz+FFzt3TbyoXBQYk/0292TdJA==} engines: {node: '>=18'} hasBin: true @@ -2315,11 +2330,11 @@ packages: vite: '>=7.3.2' vue: ^3.2.25 - '@vitest/expect@4.1.8': - resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} + '@vitest/expect@4.1.9': + resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} - '@vitest/mocker@4.1.8': - resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} + '@vitest/mocker@4.1.9': + resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} peerDependencies: msw: ^2.4.9 vite: '>=7.3.2' @@ -2329,20 +2344,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.8': - resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} + '@vitest/pretty-format@4.1.9': + resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} - '@vitest/runner@4.1.8': - resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} + '@vitest/runner@4.1.9': + resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} - '@vitest/snapshot@4.1.8': - resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} + '@vitest/snapshot@4.1.9': + resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} - '@vitest/spy@4.1.8': - resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} + '@vitest/spy@4.1.9': + resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} - '@vitest/utils@4.1.8': - resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} + '@vitest/utils@4.1.9': + resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} '@vue/compiler-core@3.5.30': resolution: {integrity: sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==} @@ -2458,8 +2473,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true @@ -3280,8 +3295,8 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 - eslint-plugin-react-refresh@0.5.2: - resolution: {integrity: sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==} + eslint-plugin-react-refresh@0.5.3: + resolution: {integrity: sha512-5EMmLCV98Pi4o/f/3DP/v/tNqLHMIc9I8LKClNDWhZ9JTho89/kQcitCXQBMG7sAfVRK0Ie3T2EDOzp1YXYiVA==} peerDependencies: eslint: ^9 || ^10 @@ -3311,8 +3326,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.4.1: - resolution: {integrity: sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==} + eslint@10.5.0: + resolution: {integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -4524,8 +4539,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} oidc-provider@9.8.4: resolution: {integrity: sha512-i8qe+wvhUQ7BSj6DxssIFAdpREouuqK91j2jGdAN78NIxTB5rxvU4ZniXELhUHIM4mzABeSGlp5wE6WTa8CY1Q==} @@ -4596,8 +4612,8 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} - oxc-minify@0.135.0: - resolution: {integrity: sha512-K5+P/ZZ4GnY5WgsiEIVg6YZkBAnKu+yArDM3KgkHhQDHlJ9bnIGkrl31kBy8hRJ0F4pPptEqO21ZbaAxY45IWg==} + oxc-minify@0.136.0: + resolution: {integrity: sha512-u9UvPFTYVwQ/i1kpp/c20S/SbvLaLV0Ngzyhgi0YV4B1SlxM7RgnnePl4vY9N3Z9sTRcozL1MRStI3PlUN9RFA==} engines: {node: ^20.19.0 || >=22.12.0} p-limit@3.1.0: @@ -4716,13 +4732,13 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - playwright-core@1.60.0: - resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} + playwright-core@1.61.0: + resolution: {integrity: sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==} engines: {node: '>=18'} hasBin: true - playwright@1.60.0: - resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==} + playwright@1.61.0: + resolution: {integrity: sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==} engines: {node: '>=18'} hasBin: true @@ -4837,8 +4853,8 @@ packages: peerDependencies: react: ^19.2.7 - react-hook-form@7.78.0: - resolution: {integrity: sha512-EEZqc+N23moyzTlz61Pj+JvcXo76ICkpfOZo8JZw+sM4+wLQGh6nI2Ms+PdMOYNluFu0ghlM7B8mCzhRYtJCnA==} + react-hook-form@7.79.0: + resolution: {integrity: sha512-mhYp/MTmXvzYX6AJcJVko0rktoIhhmRnEouObj4wF5i/tCttgJvnp1+9wRkpITZjDTqpo4IOSJqu0dBlPlV/Lw==} engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -5772,20 +5788,20 @@ packages: postcss: optional: true - vitest@4.1.8: - resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} + vitest@4.1.9: + resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.8 - '@vitest/browser-preview': 4.1.8 - '@vitest/browser-webdriverio': 4.1.8 - '@vitest/coverage-istanbul': 4.1.8 - '@vitest/coverage-v8': 4.1.8 - '@vitest/ui': 4.1.8 + '@vitest/browser-playwright': 4.1.9 + '@vitest/browser-preview': 4.1.9 + '@vitest/browser-webdriverio': 4.1.9 + '@vitest/coverage-istanbul': 4.1.9 + '@vitest/coverage-v8': 4.1.9 + '@vitest/ui': 4.1.9 happy-dom: '*' jsdom: '*' vite: '>=7.3.2' @@ -6362,16 +6378,32 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + '@epic-web/invariant@1.0.0': {} '@esbuild/aix-ppc64@0.28.0': @@ -6530,9 +6562,9 @@ snapshots: '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.4.1)': + '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0)': dependencies: - eslint: 10.4.1 + eslint: 10.5.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -6633,8 +6665,8 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 '@tybys/wasm-util': 0.10.2 optional: true @@ -6645,6 +6677,13 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.2 + optional: true + '@noble/ciphers@1.3.0': {} '@noble/hashes@1.8.0': {} @@ -6709,68 +6748,68 @@ snapshots: '@opentelemetry/semantic-conventions@1.41.1': {} - '@oxc-minify/binding-android-arm-eabi@0.135.0': + '@oxc-minify/binding-android-arm-eabi@0.136.0': optional: true - '@oxc-minify/binding-android-arm64@0.135.0': + '@oxc-minify/binding-android-arm64@0.136.0': optional: true - '@oxc-minify/binding-darwin-arm64@0.135.0': + '@oxc-minify/binding-darwin-arm64@0.136.0': optional: true - '@oxc-minify/binding-darwin-x64@0.135.0': + '@oxc-minify/binding-darwin-x64@0.136.0': optional: true - '@oxc-minify/binding-freebsd-x64@0.135.0': + '@oxc-minify/binding-freebsd-x64@0.136.0': optional: true - '@oxc-minify/binding-linux-arm-gnueabihf@0.135.0': + '@oxc-minify/binding-linux-arm-gnueabihf@0.136.0': optional: true - '@oxc-minify/binding-linux-arm-musleabihf@0.135.0': + '@oxc-minify/binding-linux-arm-musleabihf@0.136.0': optional: true - '@oxc-minify/binding-linux-arm64-gnu@0.135.0': + '@oxc-minify/binding-linux-arm64-gnu@0.136.0': optional: true - '@oxc-minify/binding-linux-arm64-musl@0.135.0': + '@oxc-minify/binding-linux-arm64-musl@0.136.0': optional: true - '@oxc-minify/binding-linux-ppc64-gnu@0.135.0': + '@oxc-minify/binding-linux-ppc64-gnu@0.136.0': optional: true - '@oxc-minify/binding-linux-riscv64-gnu@0.135.0': + '@oxc-minify/binding-linux-riscv64-gnu@0.136.0': optional: true - '@oxc-minify/binding-linux-riscv64-musl@0.135.0': + '@oxc-minify/binding-linux-riscv64-musl@0.136.0': optional: true - '@oxc-minify/binding-linux-s390x-gnu@0.135.0': + '@oxc-minify/binding-linux-s390x-gnu@0.136.0': optional: true - '@oxc-minify/binding-linux-x64-gnu@0.135.0': + '@oxc-minify/binding-linux-x64-gnu@0.136.0': optional: true - '@oxc-minify/binding-linux-x64-musl@0.135.0': + '@oxc-minify/binding-linux-x64-musl@0.136.0': optional: true - '@oxc-minify/binding-openharmony-arm64@0.135.0': + '@oxc-minify/binding-openharmony-arm64@0.136.0': optional: true - '@oxc-minify/binding-wasm32-wasi@0.135.0': + '@oxc-minify/binding-wasm32-wasi@0.136.0': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@oxc-minify/binding-win32-arm64-msvc@0.135.0': + '@oxc-minify/binding-win32-arm64-msvc@0.136.0': optional: true - '@oxc-minify/binding-win32-ia32-msvc@0.135.0': + '@oxc-minify/binding-win32-ia32-msvc@0.136.0': optional: true - '@oxc-minify/binding-win32-x64-msvc@0.135.0': + '@oxc-minify/binding-win32-x64-msvc@0.136.0': optional: true '@oxc-project/types@0.133.0': {} @@ -6779,9 +6818,9 @@ snapshots: dependencies: '@noble/hashes': 1.8.0 - '@playwright/test@1.60.0': + '@playwright/test@1.61.0': dependencies: - playwright: 1.60.0 + playwright: 1.61.0 '@radix-ui/primitive@1.1.4': {} @@ -7430,15 +7469,15 @@ snapshots: dependencies: '@types/webidl-conversions': 7.0.3 - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3))(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 7.18.0(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/parser': 7.18.0(eslint@10.5.0)(typescript@6.0.3) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@10.4.1)(typescript@6.0.3) - '@typescript-eslint/utils': 7.18.0(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/type-utils': 7.18.0(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/utils': 7.18.0(eslint@10.5.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 10.4.1 + eslint: 10.5.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -7448,15 +7487,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.4.1)(typescript@6.0.3))(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.61.0(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0)(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/type-utils': 8.61.0(eslint@10.4.1)(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.0(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.61.0(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.61.0 - eslint: 10.4.1 + eslint: 10.5.0 ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -7464,27 +7503,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@6.0.3) '@typescript-eslint/visitor-keys': 7.18.0 debug: 4.4.3(supports-color@8.1.1) - eslint: 10.4.1 + eslint: 10.5.0 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.61.0(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3(supports-color@8.1.1) - eslint: 10.4.1 + eslint: 10.5.0 typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -7512,25 +7551,25 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@7.18.0(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/type-utils@7.18.0(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@6.0.3) - '@typescript-eslint/utils': 7.18.0(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/utils': 7.18.0(eslint@10.5.0)(typescript@6.0.3) debug: 4.4.3(supports-color@8.1.1) - eslint: 10.4.1 + eslint: 10.5.0 ts-api-utils: 1.4.3(typescript@6.0.3) optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.61.0(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.61.0(eslint@10.5.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.61.0 '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.0(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0)(typescript@6.0.3) debug: 4.4.3(supports-color@8.1.1) - eslint: 10.4.1 + eslint: 10.5.0 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -7570,24 +7609,24 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/utils@7.18.0(eslint@10.5.0)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 '@typescript-eslint/typescript-estree': 7.18.0(typescript@6.0.3) - eslint: 10.4.1 + eslint: 10.5.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.61.0(eslint@10.4.1)(typescript@6.0.3)': + '@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0) '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) - eslint: 10.4.1 + eslint: 10.5.0 typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -7672,44 +7711,44 @@ snapshots: vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4) vue: 3.5.30(typescript@6.0.3) - '@vitest/expect@4.1.8': + '@vitest/expect@4.1.9': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4))': + '@vitest/mocker@4.1.9(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4))': dependencies: - '@vitest/spy': 4.1.8 + '@vitest/spy': 4.1.9 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4) - '@vitest/pretty-format@4.1.8': + '@vitest/pretty-format@4.1.9': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.8': + '@vitest/runner@4.1.9': dependencies: - '@vitest/utils': 4.1.8 + '@vitest/utils': 4.1.9 pathe: 2.0.3 - '@vitest/snapshot@4.1.8': + '@vitest/snapshot@4.1.9': dependencies: - '@vitest/pretty-format': 4.1.8 - '@vitest/utils': 4.1.8 + '@vitest/pretty-format': 4.1.9 + '@vitest/utils': 4.1.9 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.8': {} + '@vitest/spy@4.1.9': {} - '@vitest/utils@4.1.8': + '@vitest/utils@4.1.9': dependencies: - '@vitest/pretty-format': 4.1.8 + '@vitest/pretty-format': 4.1.9 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -7819,11 +7858,11 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 - acorn-jsx@5.3.2(acorn@8.16.0): + acorn-jsx@5.3.2(acorn@8.17.0): dependencies: - acorn: 8.16.0 + acorn: 8.17.0 - acorn@8.16.0: {} + acorn@8.17.0: {} adm-zip@0.5.17: {} @@ -8606,24 +8645,24 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-compat-utils@0.5.1(eslint@10.4.1): + eslint-compat-utils@0.5.1(eslint@10.5.0): dependencies: - eslint: 10.4.1 + eslint: 10.5.0 semver: 7.8.4 - eslint-config-etherpad@4.0.5(eslint@10.4.1)(typescript@6.0.3): + eslint-config-etherpad@4.0.5(eslint@10.5.0)(typescript@6.0.3): dependencies: '@rushstack/eslint-patch': 1.16.1 - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3))(eslint@10.4.1)(typescript@6.0.3) - '@typescript-eslint/parser': 7.18.0(eslint@10.4.1)(typescript@6.0.3) - eslint-import-resolver-typescript: 3.9.1(eslint-plugin-import@2.32.0)(eslint@10.4.1) - eslint-plugin-cypress: 2.15.2(eslint@10.4.1) - eslint-plugin-eslint-comments: 3.2.0(eslint@10.4.1) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3))(eslint-import-resolver-typescript@3.9.1)(eslint@10.4.1) - eslint-plugin-mocha: 10.5.0(eslint@10.4.1) - eslint-plugin-n: 17.24.0(eslint@10.4.1)(typescript@6.0.3) - eslint-plugin-prefer-arrow: 1.2.3(eslint@10.4.1) - eslint-plugin-promise: 6.6.0(eslint@10.4.1) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3))(eslint@10.5.0)(typescript@6.0.3) + '@typescript-eslint/parser': 7.18.0(eslint@10.5.0)(typescript@6.0.3) + eslint-import-resolver-typescript: 3.9.1(eslint-plugin-import@2.32.0)(eslint@10.5.0) + eslint-plugin-cypress: 2.15.2(eslint@10.5.0) + eslint-plugin-eslint-comments: 3.2.0(eslint@10.5.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.9.1)(eslint@10.5.0) + eslint-plugin-mocha: 10.5.0(eslint@10.5.0) + eslint-plugin-n: 17.24.0(eslint@10.5.0)(typescript@6.0.3) + eslint-plugin-prefer-arrow: 1.2.3(eslint@10.5.0) + eslint-plugin-promise: 6.6.0(eslint@10.5.0) eslint-plugin-you-dont-need-lodash-underscore: 6.14.0 transitivePeerDependencies: - eslint @@ -8640,51 +8679,51 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.32.0)(eslint@10.4.1): + eslint-import-resolver-typescript@3.9.1(eslint-plugin-import@2.32.0)(eslint@10.5.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3(supports-color@8.1.1) - eslint: 10.4.1 + eslint: 10.5.0 get-tsconfig: 4.14.0 is-bun-module: 1.3.0 rspack-resolver: 1.3.0 stable-hash: 0.0.5 tinyglobby: 0.2.17 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3))(eslint-import-resolver-typescript@3.9.1)(eslint@10.4.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.9.1)(eslint@10.5.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.9.1)(eslint@10.4.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.9.1)(eslint@10.5.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.18.0(eslint@10.4.1)(typescript@6.0.3) - eslint: 10.4.1 + '@typescript-eslint/parser': 7.18.0(eslint@10.5.0)(typescript@6.0.3) + eslint: 10.5.0 eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.9.1(eslint-plugin-import@2.32.0)(eslint@10.4.1) + eslint-import-resolver-typescript: 3.9.1(eslint-plugin-import@2.32.0)(eslint@10.5.0) transitivePeerDependencies: - supports-color - eslint-plugin-cypress@2.15.2(eslint@10.4.1): + eslint-plugin-cypress@2.15.2(eslint@10.5.0): dependencies: - eslint: 10.4.1 + eslint: 10.5.0 globals: 13.24.0 - eslint-plugin-es-x@7.8.0(eslint@10.4.1): + eslint-plugin-es-x@7.8.0(eslint@10.5.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0) '@eslint-community/regexpp': 4.12.2 - eslint: 10.4.1 - eslint-compat-utils: 0.5.1(eslint@10.4.1) + eslint: 10.5.0 + eslint-compat-utils: 0.5.1(eslint@10.5.0) - eslint-plugin-eslint-comments@3.2.0(eslint@10.4.1): + eslint-plugin-eslint-comments@3.2.0(eslint@10.5.0): dependencies: escape-string-regexp: 1.0.5 - eslint: 10.4.1 + eslint: 10.5.0 ignore: 5.3.2 - eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3))(eslint-import-resolver-typescript@3.9.1)(eslint@10.4.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3))(eslint-import-resolver-typescript@3.9.1)(eslint@10.5.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -8693,9 +8732,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 10.4.1 + eslint: 10.5.0 eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@7.18.0(eslint@10.4.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.9.1)(eslint@10.4.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@7.18.0(eslint@10.5.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.9.1)(eslint@10.5.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -8707,25 +8746,25 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.18.0(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/parser': 7.18.0(eslint@10.5.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-mocha@10.5.0(eslint@10.4.1): + eslint-plugin-mocha@10.5.0(eslint@10.5.0): dependencies: - eslint: 10.4.1 - eslint-utils: 3.0.0(eslint@10.4.1) + eslint: 10.5.0 + eslint-utils: 3.0.0(eslint@10.5.0) globals: 13.24.0 rambda: 7.5.0 - eslint-plugin-n@17.24.0(eslint@10.4.1)(typescript@6.0.3): + eslint-plugin-n@17.24.0(eslint@10.5.0)(typescript@6.0.3): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0) enhanced-resolve: 5.20.1 - eslint: 10.4.1 - eslint-plugin-es-x: 7.8.0(eslint@10.4.1) + eslint: 10.5.0 + eslint-plugin-es-x: 7.8.0(eslint@10.5.0) get-tsconfig: 4.14.0 globals: 15.15.0 globrex: 0.1.2 @@ -8735,28 +8774,28 @@ snapshots: transitivePeerDependencies: - typescript - eslint-plugin-prefer-arrow@1.2.3(eslint@10.4.1): + eslint-plugin-prefer-arrow@1.2.3(eslint@10.5.0): dependencies: - eslint: 10.4.1 + eslint: 10.5.0 - eslint-plugin-promise@6.6.0(eslint@10.4.1): + eslint-plugin-promise@6.6.0(eslint@10.5.0): dependencies: - eslint: 10.4.1 + eslint: 10.5.0 - eslint-plugin-react-hooks@7.1.1(eslint@10.4.1): + eslint-plugin-react-hooks@7.1.1(eslint@10.5.0): dependencies: '@babel/core': 7.29.0 '@babel/parser': 7.29.2 - eslint: 10.4.1 + eslint: 10.5.0 hermes-parser: 0.25.1 zod: 4.3.6 zod-validation-error: 4.0.2(zod@4.3.6) transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.5.2(eslint@10.4.1): + eslint-plugin-react-refresh@0.5.3(eslint@10.5.0): dependencies: - eslint: 10.4.1 + eslint: 10.5.0 eslint-plugin-you-dont-need-lodash-underscore@6.14.0: dependencies: @@ -8769,9 +8808,9 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-utils@3.0.0(eslint@10.4.1): + eslint-utils@3.0.0(eslint@10.5.0): dependencies: - eslint: 10.4.1 + eslint: 10.5.0 eslint-visitor-keys: 2.1.0 eslint-visitor-keys@2.1.0: {} @@ -8780,9 +8819,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.4.1: + eslint@10.5.0: dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.6.0 @@ -8817,8 +8856,8 @@ snapshots: espree@11.2.0: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 5.0.1 esprima@4.0.1: {} @@ -10133,7 +10172,7 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - obug@2.1.1: {} + obug@2.1.3: {} oidc-provider@9.8.4: dependencies: @@ -10244,28 +10283,28 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-minify@0.135.0: + oxc-minify@0.136.0: optionalDependencies: - '@oxc-minify/binding-android-arm-eabi': 0.135.0 - '@oxc-minify/binding-android-arm64': 0.135.0 - '@oxc-minify/binding-darwin-arm64': 0.135.0 - '@oxc-minify/binding-darwin-x64': 0.135.0 - '@oxc-minify/binding-freebsd-x64': 0.135.0 - '@oxc-minify/binding-linux-arm-gnueabihf': 0.135.0 - '@oxc-minify/binding-linux-arm-musleabihf': 0.135.0 - '@oxc-minify/binding-linux-arm64-gnu': 0.135.0 - '@oxc-minify/binding-linux-arm64-musl': 0.135.0 - '@oxc-minify/binding-linux-ppc64-gnu': 0.135.0 - '@oxc-minify/binding-linux-riscv64-gnu': 0.135.0 - '@oxc-minify/binding-linux-riscv64-musl': 0.135.0 - '@oxc-minify/binding-linux-s390x-gnu': 0.135.0 - '@oxc-minify/binding-linux-x64-gnu': 0.135.0 - '@oxc-minify/binding-linux-x64-musl': 0.135.0 - '@oxc-minify/binding-openharmony-arm64': 0.135.0 - '@oxc-minify/binding-wasm32-wasi': 0.135.0 - '@oxc-minify/binding-win32-arm64-msvc': 0.135.0 - '@oxc-minify/binding-win32-ia32-msvc': 0.135.0 - '@oxc-minify/binding-win32-x64-msvc': 0.135.0 + '@oxc-minify/binding-android-arm-eabi': 0.136.0 + '@oxc-minify/binding-android-arm64': 0.136.0 + '@oxc-minify/binding-darwin-arm64': 0.136.0 + '@oxc-minify/binding-darwin-x64': 0.136.0 + '@oxc-minify/binding-freebsd-x64': 0.136.0 + '@oxc-minify/binding-linux-arm-gnueabihf': 0.136.0 + '@oxc-minify/binding-linux-arm-musleabihf': 0.136.0 + '@oxc-minify/binding-linux-arm64-gnu': 0.136.0 + '@oxc-minify/binding-linux-arm64-musl': 0.136.0 + '@oxc-minify/binding-linux-ppc64-gnu': 0.136.0 + '@oxc-minify/binding-linux-riscv64-gnu': 0.136.0 + '@oxc-minify/binding-linux-riscv64-musl': 0.136.0 + '@oxc-minify/binding-linux-s390x-gnu': 0.136.0 + '@oxc-minify/binding-linux-x64-gnu': 0.136.0 + '@oxc-minify/binding-linux-x64-musl': 0.136.0 + '@oxc-minify/binding-openharmony-arm64': 0.136.0 + '@oxc-minify/binding-wasm32-wasi': 0.136.0 + '@oxc-minify/binding-win32-arm64-msvc': 0.136.0 + '@oxc-minify/binding-win32-ia32-msvc': 0.136.0 + '@oxc-minify/binding-win32-x64-msvc': 0.136.0 p-limit@3.1.0: dependencies: @@ -10384,11 +10423,11 @@ snapshots: picomatch@4.0.4: {} - playwright-core@1.60.0: {} + playwright-core@1.61.0: {} - playwright@1.60.0: + playwright@1.61.0: dependencies: - playwright-core: 1.60.0 + playwright-core: 1.61.0 optionalDependencies: fsevents: 2.3.2 @@ -10493,7 +10532,7 @@ snapshots: react: 19.2.7 scheduler: 0.27.0 - react-hook-form@7.78.0(react@19.2.7): + react-hook-form@7.79.0(react@19.2.7): dependencies: react: 19.2.7 @@ -11025,7 +11064,7 @@ snapshots: streamroller@3.1.5: dependencies: date-format: 4.0.14 - debug: 4.4.0 + debug: 4.4.3(supports-color@8.1.1) fs-extra: 8.1.0 transitivePeerDependencies: - supports-color @@ -11472,7 +11511,7 @@ snapshots: fsevents: 2.3.3 tsx: 4.22.4 - vitepress@2.0.0-alpha.17(@types/node@25.9.3)(change-case@5.4.4)(esbuild@0.28.1)(jwt-decode@4.0.0)(oxc-minify@0.135.0)(postcss@8.5.15)(tsx@4.22.4)(typescript@6.0.3): + vitepress@2.0.0-alpha.17(@types/node@25.9.3)(change-case@5.4.4)(esbuild@0.28.1)(jwt-decode@4.0.0)(oxc-minify@0.136.0)(postcss@8.5.15)(tsx@4.22.4)(typescript@6.0.3): dependencies: '@docsearch/css': 4.6.0 '@docsearch/js': 4.6.0 @@ -11494,7 +11533,7 @@ snapshots: vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4) vue: 3.5.30(typescript@6.0.3) optionalDependencies: - oxc-minify: 0.135.0 + oxc-minify: 0.136.0 postcss: 8.5.15 transitivePeerDependencies: - '@types/node' @@ -11522,19 +11561,19 @@ snapshots: - universal-cookie - yaml - vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(jsdom@29.1.1(@noble/hashes@1.8.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)): + vitest@4.1.9(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(jsdom@29.1.1(@noble/hashes@1.8.0))(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)): dependencies: - '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) - '@vitest/pretty-format': 4.1.8 - '@vitest/runner': 4.1.8 - '@vitest/snapshot': 4.1.8 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 + '@vitest/expect': 4.1.9 + '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) + '@vitest/pretty-format': 4.1.9 + '@vitest/runner': 4.1.9 + '@vitest/snapshot': 4.1.9 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.3 pathe: 2.0.3 picomatch: 4.0.4 std-env: 4.1.0 diff --git a/src/package.json b/src/package.json index 3f044c5bb..283459e43 100644 --- a/src/package.json +++ b/src/package.json @@ -98,7 +98,7 @@ "etherpad-lite": "node/server.ts" }, "devDependencies": { - "@playwright/test": "^1.60.0", + "@playwright/test": "^1.61.0", "@types/async": "^3.2.25", "@types/cookie-parser": "^1.4.10", "@types/cross-spawn": "^6.0.6", @@ -124,7 +124,7 @@ "@types/underscore": "^1.13.0", "@types/whatwg-mimetype": "^5.0.0", "chokidar": "^5.0.0", - "eslint": "^10.4.1", + "eslint": "^10.5.0", "eslint-config-etherpad": "^4.0.5", "etherpad-cli-client": "^4.0.3", "mocha": "^11.7.6", @@ -136,7 +136,7 @@ "split-grid": "^1.0.11", "supertest": "^7.2.2", "typescript": "^6.0.3", - "vitest": "^4.1.8" + "vitest": "^4.1.9" }, "engines": { "node": ">=24.0.0", From abdfa03f847b18338eec0741f2a2b44ffc77e5f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 19:07:47 +0100 Subject: [PATCH 15/43] build(deps): bump ueberdb2 from 6.1.9 to 6.1.12 (#7966) Bumps [ueberdb2](https://github.com/ether/ueberDB) from 6.1.9 to 6.1.12. - [Changelog](https://github.com/ether/ueberDB/blob/main/CHANGELOG.md) - [Commits](https://github.com/ether/ueberDB/compare/v6.1.9...v6.1.12) --- updated-dependencies: - dependency-name: ueberdb2 dependency-version: 6.1.12 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- bin/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- src/package.json | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bin/package.json b/bin/package.json index 8320a9c8d..7127c19ff 100644 --- a/bin/package.json +++ b/bin/package.json @@ -11,7 +11,7 @@ "log4js": "^6.9.1", "semver": "^7.8.4", "tsx": "^4.22.4", - "ueberdb2": "^6.1.9" + "ueberdb2": "^6.1.12" }, "devDependencies": { "@types/node": "^25.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4547c5e7a..29eb91791 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -159,8 +159,8 @@ importers: specifier: ^4.22.4 version: 4.22.4 ueberdb2: - specifier: ^6.1.9 - version: 6.1.9(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) + specifier: ^6.1.12 + version: 6.1.12(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) devDependencies: '@types/node': specifier: ^25.9.3 @@ -359,8 +359,8 @@ importers: specifier: 4.22.4 version: 4.22.4 ueberdb2: - specifier: ^6.1.9 - version: 6.1.9(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) + specifier: ^6.1.12 + version: 6.1.12(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) underscore: specifier: 1.13.8 version: 1.13.8 @@ -5542,8 +5542,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - ueberdb2@6.1.9: - resolution: {integrity: sha512-AOifNHJT0A9c52eEQqcm77d3/RUZVIvGFN1KFbXEPpfI89fa5c9lS8z7piu6m+CwBgWD+Fq5wAmP7W3LVZ4MwA==} + ueberdb2@6.1.12: + resolution: {integrity: sha512-LxW4He5ZWhRzSldB105T/z9L7ljPJJeQ2VkM7tAhh0hj2TZ0zz6DItdBwDA5CQPab5QhiJ7BZC1OgkDqNDL53w==} engines: {node: '>=24.0.0'} peerDependencies: '@elastic/elasticsearch': ^9.0.0 @@ -11334,7 +11334,7 @@ snapshots: typescript@6.0.3: {} - ueberdb2@6.1.9(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)): + ueberdb2@6.1.12(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)): optionalDependencies: '@elastic/elasticsearch': 9.4.2 async: 3.2.6 diff --git a/src/package.json b/src/package.json index 283459e43..053ab847f 100644 --- a/src/package.json +++ b/src/package.json @@ -87,7 +87,7 @@ "surrealdb": "^2.0.3", "tinycon": "0.6.8", "tsx": "4.22.4", - "ueberdb2": "^6.1.9", + "ueberdb2": "^6.1.12", "underscore": "1.13.8", "undici": "^8.4.1", "unorm": "1.6.0", From 2fdf2020893de61654f477a8683a4c344873e516 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 19:08:00 +0100 Subject: [PATCH 16/43] build(deps): bump nodemailer from 8.0.11 to 9.0.0 (#7965) Bumps [nodemailer](https://github.com/nodemailer/nodemailer) from 8.0.11 to 9.0.0. - [Release notes](https://github.com/nodemailer/nodemailer/releases) - [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodemailer/nodemailer/compare/v8.0.11...v9.0.0) --- updated-dependencies: - dependency-name: nodemailer dependency-version: 9.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 10 +++++----- src/package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29eb91791..acd21217d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -293,8 +293,8 @@ importers: specifier: ^11.0.5 version: 11.0.5 nodemailer: - specifier: ^8.0.11 - version: 8.0.11 + specifier: ^9.0.0 + version: 9.0.0 oidc-provider: specifier: 9.8.4 version: 9.8.4 @@ -4503,8 +4503,8 @@ packages: nodeify@1.0.1: resolution: {integrity: sha512-n7C2NyEze8GCo/z73KdbjRsBiLbv6eBn1FxwYKQ23IqGo7pQY3mhQan61Sv7eEDJCiyUjTVrVkXTzJCo1dW7Aw==} - nodemailer@8.0.11: - resolution: {integrity: sha512-nrO/pDAUKl+wXX+lx16tDLbnm0fW6sK/x8mgohaCpg+CdCEl482bD4tCuAZk2DyliruiNTIZxRCoWkDqJEnAiA==} + nodemailer@9.0.0: + resolution: {integrity: sha512-tbPTid7d/p9jAA8CRZ3iomvrMaST0o6NYuY7v6JQZHpPRZ61mLFSPKYd7342NtOFuej9/+L48SOIxwfu2uDvtw==} engines: {node: '>=6.0.0'} object-assign@4.1.1: @@ -10128,7 +10128,7 @@ snapshots: is-promise: 1.0.1 promise: 1.3.0 - nodemailer@8.0.11: {} + nodemailer@9.0.0: {} object-assign@4.1.1: {} diff --git a/src/package.json b/src/package.json index 053ab847f..aba4e2b13 100644 --- a/src/package.json +++ b/src/package.json @@ -65,7 +65,7 @@ "mssql": "^12.5.5", "mysql2": "^3.22.5", "nano": "^11.0.5", - "nodemailer": "^8.0.11", + "nodemailer": "^9.0.0", "oidc-provider": "9.8.4", "openapi-backend": "^5.17.0", "pdfkit": "^0.19.1", From 8a4e1feed83d35ba590a576dc55867d7bb27c5de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 19:08:07 +0100 Subject: [PATCH 17/43] build(deps): bump awalsh128/cache-apt-pkgs-action from 1.6.0 to 1.6.1 (#7963) Bumps [awalsh128/cache-apt-pkgs-action](https://github.com/awalsh128/cache-apt-pkgs-action) from 1.6.0 to 1.6.1. - [Release notes](https://github.com/awalsh128/cache-apt-pkgs-action/releases) - [Commits](https://github.com/awalsh128/cache-apt-pkgs-action/compare/v1.6.0...v1.6.1) --- updated-dependencies: - dependency-name: awalsh128/cache-apt-pkgs-action dependency-version: 1.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/backend-tests.yml | 4 ++-- .github/workflows/upgrade-from-latest-release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml index c076a3542..2ae20e528 100644 --- a/.github/workflows/backend-tests.yml +++ b/.github/workflows/backend-tests.yml @@ -51,7 +51,7 @@ jobs: cache: pnpm - name: Install libreoffice - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: libreoffice libreoffice-pdfimport version: 1.0 @@ -107,7 +107,7 @@ jobs: cache: pnpm - name: Install libreoffice - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: libreoffice libreoffice-pdfimport version: 1.0 diff --git a/.github/workflows/upgrade-from-latest-release.yml b/.github/workflows/upgrade-from-latest-release.yml index c3ef545f5..495f3b3cb 100644 --- a/.github/workflows/upgrade-from-latest-release.yml +++ b/.github/workflows/upgrade-from-latest-release.yml @@ -55,7 +55,7 @@ jobs: node-version: ${{ matrix.node }} cache: pnpm - name: Install libreoffice - uses: awalsh128/cache-apt-pkgs-action@v1.6.0 + uses: awalsh128/cache-apt-pkgs-action@v1.6.1 with: packages: libreoffice libreoffice-pdfimport version: 1.0 From 099de84cd18c48aeb3854ad1f503e388f7c81348 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 15 Jun 2026 22:32:06 +0100 Subject: [PATCH 18/43] deps: resolve open Dependabot security alerts (#7967) * deps: resolve open Dependabot security alerts Bump transitive dependencies flagged by Dependabot via pnpm-workspace overrides. Refreshes stale override floors that the advisory ranges have since grown past, and adds overrides for newly-flagged packages: - form-data -> >=4.0.6 (GHSA-hmw2-7cc7-3qxx, high) - ws -> >=8.21.0 (GHSA-96hv-2xvq-fx4p / GHSA-58qx-3vcg-4xpx, high/med) - esbuild -> >=0.28.1 (GHSA-gv7w-rqvm-qjhr / GHSA-g7r4-m6w7-qqqr, high/low) - basic-ftp -> >=5.3.1 (GHSA-rpmf-866q-6p89, high) [stale floor: 5.3.0 still vuln] - tar -> >=7.5.16 (GHSA-vmf3-w455-68vh, med) [stale floor: 7.5.11] - js-yaml -> >=4.2.0 (GHSA-h67p-54hq-rp68, med) [stale floor: 4.1.1 now vuln] - qs -> >=6.15.2 (GHSA-q8mj-m7cp-5q26, med) [stale floor: 6.14.2 still vuln] - ip-address -> >=10.1.1 (GHSA-v2v4-37r5-5v8g, med) - @babel/core-> >=7.29.6 (GHSA-4x5r-pxfx-6jf8, low) ts-check, backend test-utils, and the vite/esbuild production build all pass locally on Node 24. Co-Authored-By: Claude Opus 4.8 (1M context) * deps: cap basic-ftp override to 5.x to avoid major bump Qodo flagged the open-ended `basic-ftp@<5.3.1: '>=5.3.1'` override as resolving to 6.0.1 (a surprise major) on the runtime plugin-install path (live-plugin-manager -> proxy-agent -> get-uri -> basic-ftp). The CVE fix (5.3.1) exists on the 5.x line, so bound the override to '>=5.3.1 <6.0.0' for the minimal, lowest-risk patch. Now resolves to basic-ftp@5.3.1. Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- pnpm-lock.yaml | 557 +++++++++++++------------------------------- pnpm-workspace.yaml | 13 +- 2 files changed, 169 insertions(+), 401 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index acd21217d..81f80aa59 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,23 +5,28 @@ settings: excludeLinksFromLockfile: false overrides: - basic-ftp: '>=5.3.0' + '@babel/core@<7.29.6': '>=7.29.6' + basic-ftp@<5.3.1: '>=5.3.1 <6.0.0' brace-expansion@>=2.0.0 <2.0.3: '>=2.0.3' diff@>=6.0.0 <8.0.3: '>=8.0.3' + esbuild@<0.28.1: '>=0.28.1' flatted: '>=3.4.2' follow-redirects: '>=1.16.0' + form-data@>=4.0.0 <4.0.6: '>=4.0.6' glob@>=10.2.0 <10.5.0: '>=10.5.0' - js-yaml@>=4.0.0 <4.1.1: '>=4.1.1' + ip-address@<10.1.1: '>=10.1.1' + js-yaml@>=4.0.0 <4.2.0: '>=4.2.0' lodash: '>=4.18.0' minimatch@>=9.0.0 <9.0.7: '>=9.0.7' path-to-regexp@>=8.0.0 <8.4.0: '>=8.4.0' picomatch@>=4.0.0 <4.0.4: '>=4.0.4' - qs@>=6.7.0 <6.14.2: '>=6.14.2' + qs@>=6.7.0 <6.15.2: '>=6.15.2' serialize-javascript@<7.0.5: '>=7.0.5' socket.io-parser@>=4.0.0 <4.2.6: '>=4.2.6' - tar@<7.5.11: '>=7.5.11' + tar@<7.5.16: '>=7.5.16' uuid@<14.0.0: '>=14.0.0' vite@>=7.0.0 <7.3.2: '>=7.3.2' + ws@>=8.0.0 <8.21.0: '>=8.21.0' importers: @@ -139,7 +144,7 @@ importers: version: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4) vite-plugin-babel: specifier: ^1.7.3 - version: 1.7.3(@babel/core@7.29.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) + version: 1.7.3(@babel/core@7.29.7)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)) zustand: specifier: ^5.0.14 version: 5.0.14(@types/react@19.2.17)(react@19.2.7)(use-sync-external-store@1.6.0(react@19.2.7)) @@ -608,40 +613,48 @@ packages: resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + '@babel/generator@7.29.7': + resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} engines: {node: '>=6.9.0'} - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': '>=7.29.6' '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.27.1': resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} @@ -650,12 +663,16 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.29.2': - resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} engines: {node: '>=6.9.0'} '@babel/parser@7.29.2': @@ -663,6 +680,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.7': + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/runtime@7.28.6': resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} @@ -671,12 +693,12 @@ packages: resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + '@babel/traverse@7.29.7': + resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} engines: {node: '>=6.9.0'} '@babel/types@7.28.4': @@ -687,6 +709,10 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} + '@babel/types@7.29.7': + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} + engines: {node: '>=6.9.0'} + '@bramus/specificity@2.4.2': resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} hasBin: true @@ -770,312 +796,156 @@ packages: '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} - '@esbuild/aix-ppc64@0.28.0': - resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.28.1': resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.28.0': - resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.28.1': resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.28.0': - resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.28.1': resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.28.0': - resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.28.1': resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.28.0': - resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.28.1': resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.28.0': - resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.28.1': resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.28.0': - resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.28.1': resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.28.0': - resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.28.1': resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.28.0': - resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.28.1': resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.28.0': - resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.28.1': resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.28.0': - resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.28.1': resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.28.0': - resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.28.1': resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.28.0': - resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.28.1': resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.28.0': - resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.28.1': resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.28.0': - resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.28.1': resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.28.0': - resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.28.1': resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.28.0': - resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.28.1': resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.28.0': - resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-arm64@0.28.1': resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.28.0': - resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.28.1': resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.28.0': - resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-arm64@0.28.1': resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.28.0': - resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.28.1': resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.28.0': - resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/openharmony-arm64@0.28.1': resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.28.0': - resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.28.1': resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.28.0': - resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.28.1': resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.28.0': - resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.28.1': resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.28.0': - resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.28.1': resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} engines: {node: '>=18'} @@ -2612,8 +2482,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - basic-ftp@5.3.0: - resolution: {integrity: sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==} + basic-ftp@5.3.1: + resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} engines: {node: '>=10.0.0'} bath-es5@3.0.3: @@ -3162,11 +3032,6 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild@0.28.0: - resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} - engines: {node: '>=18'} - hasBin: true - esbuild@0.28.1: resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} @@ -3491,8 +3356,8 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} formdata-polyfill@4.0.10: @@ -3656,6 +3521,10 @@ packages: resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + hast-util-embedded@3.0.0: resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} @@ -3805,10 +3674,6 @@ packages: resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} engines: {node: '>= 12'} - ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} - engines: {node: '>= 12'} - ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -3993,13 +3858,10 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} hasBin: true - jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - jsdom@29.1.1: resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==} engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} @@ -4812,10 +4674,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.15.0: - resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} - engines: {node: '>=0.6'} - qs@6.15.2: resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} engines: {node: '>=0.6'} @@ -5389,8 +5247,8 @@ packages: resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} engines: {node: '>=6'} - tar@7.5.13: - resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} + tar@7.5.16: + resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} tarn@3.0.2: @@ -5727,7 +5585,7 @@ packages: vite-plugin-babel@1.7.3: resolution: {integrity: sha512-PsomVbH74/XyqMzXSwBDqb/1o5sAqE68gPlHLfx4FiMGbvKDhaZVQNv/gj/7oRQ5BvuIlyTKBtNEA9MnirGwRA==} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': '>=7.29.6' vite: '>=7.3.2' vite@8.0.16: @@ -5737,7 +5595,7 @@ packages: peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 '@vitejs/devtools': ^0.1.18 - esbuild: ^0.27.0 || ^0.28.0 + esbuild: '>=0.28.1' jiti: '>=1.21.0' less: ^4.0.0 sass: ^1.70.0 @@ -5918,8 +5776,8 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -6042,7 +5900,7 @@ snapshots: dependencies: '@jsdevtools/ono': 7.1.3 '@types/json-schema': 7.0.15 - js-yaml: 4.1.1 + js-yaml: 4.2.0 '@asamuzakjp/css-color@5.1.11': dependencies: @@ -6213,19 +6071,25 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.29.0': {} - - '@babel/core@7.29.0': + '@babel/code-frame@7.29.7': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.29.2 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.3(supports-color@8.1.1) @@ -6235,75 +6099,83 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.29.1': + '@babel/generator@7.29.7': dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.28.6': + '@babel/helper-compilation-targets@7.29.7': dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 browserslist: 4.28.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-globals@7.28.0': {} + '@babel/helper-globals@7.29.7': {} - '@babel/helper-module-imports@7.28.6': + '@babel/helper-module-imports@7.29.7': dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-string-parser@7.29.7': {} + '@babel/helper-validator-identifier@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-option@7.27.1': {} + '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helpers@7.29.2': + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.7': dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 '@babel/parser@7.29.2': dependencies: '@babel/types': 7.29.0 + '@babel/parser@7.29.7': + dependencies: + '@babel/types': 7.29.7 + '@babel/runtime@7.28.6': {} '@babel/runtime@7.29.2': {} - '@babel/template@7.28.6': + '@babel/template@7.29.7': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 - '@babel/traverse@7.29.0': + '@babel/traverse@7.29.7': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -6318,6 +6190,11 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@babel/types@7.29.7': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@bramus/specificity@2.4.2': dependencies: css-tree: 3.2.1 @@ -6406,159 +6283,81 @@ snapshots: '@epic-web/invariant@1.0.0': {} - '@esbuild/aix-ppc64@0.28.0': - optional: true - '@esbuild/aix-ppc64@0.28.1': optional: true - '@esbuild/android-arm64@0.28.0': - optional: true - '@esbuild/android-arm64@0.28.1': optional: true - '@esbuild/android-arm@0.28.0': - optional: true - '@esbuild/android-arm@0.28.1': optional: true - '@esbuild/android-x64@0.28.0': - optional: true - '@esbuild/android-x64@0.28.1': optional: true - '@esbuild/darwin-arm64@0.28.0': - optional: true - '@esbuild/darwin-arm64@0.28.1': optional: true - '@esbuild/darwin-x64@0.28.0': - optional: true - '@esbuild/darwin-x64@0.28.1': optional: true - '@esbuild/freebsd-arm64@0.28.0': - optional: true - '@esbuild/freebsd-arm64@0.28.1': optional: true - '@esbuild/freebsd-x64@0.28.0': - optional: true - '@esbuild/freebsd-x64@0.28.1': optional: true - '@esbuild/linux-arm64@0.28.0': - optional: true - '@esbuild/linux-arm64@0.28.1': optional: true - '@esbuild/linux-arm@0.28.0': - optional: true - '@esbuild/linux-arm@0.28.1': optional: true - '@esbuild/linux-ia32@0.28.0': - optional: true - '@esbuild/linux-ia32@0.28.1': optional: true - '@esbuild/linux-loong64@0.28.0': - optional: true - '@esbuild/linux-loong64@0.28.1': optional: true - '@esbuild/linux-mips64el@0.28.0': - optional: true - '@esbuild/linux-mips64el@0.28.1': optional: true - '@esbuild/linux-ppc64@0.28.0': - optional: true - '@esbuild/linux-ppc64@0.28.1': optional: true - '@esbuild/linux-riscv64@0.28.0': - optional: true - '@esbuild/linux-riscv64@0.28.1': optional: true - '@esbuild/linux-s390x@0.28.0': - optional: true - '@esbuild/linux-s390x@0.28.1': optional: true - '@esbuild/linux-x64@0.28.0': - optional: true - '@esbuild/linux-x64@0.28.1': optional: true - '@esbuild/netbsd-arm64@0.28.0': - optional: true - '@esbuild/netbsd-arm64@0.28.1': optional: true - '@esbuild/netbsd-x64@0.28.0': - optional: true - '@esbuild/netbsd-x64@0.28.1': optional: true - '@esbuild/openbsd-arm64@0.28.0': - optional: true - '@esbuild/openbsd-arm64@0.28.1': optional: true - '@esbuild/openbsd-x64@0.28.0': - optional: true - '@esbuild/openbsd-x64@0.28.1': optional: true - '@esbuild/openharmony-arm64@0.28.0': - optional: true - '@esbuild/openharmony-arm64@0.28.1': optional: true - '@esbuild/sunos-x64@0.28.0': - optional: true - '@esbuild/sunos-x64@0.28.1': optional: true - '@esbuild/win32-arm64@0.28.0': - optional: true - '@esbuild/win32-arm64@0.28.1': optional: true - '@esbuild/win32-ia32@0.28.0': - optional: true - '@esbuild/win32-ia32@0.28.1': optional: true - '@esbuild/win32-x64@0.28.0': - optional: true - '@esbuild/win32-x64@0.28.1': optional: true @@ -7071,7 +6870,7 @@ snapshots: colorette: 1.4.0 https-proxy-agent: 7.0.6(supports-color@10.2.2) js-levenshtein: 1.1.6 - js-yaml: 4.1.1 + js-yaml: 4.2.0 minimatch: 5.1.9 pluralize: 8.0.0 yaml-ast-parser: 0.0.43 @@ -7373,7 +7172,7 @@ snapshots: '@types/node-fetch@2.6.12': dependencies: '@types/node': 25.9.3 - form-data: 4.0.5 + form-data: 4.0.6 '@types/node@18.19.130': dependencies: @@ -7439,7 +7238,7 @@ snapshots: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 '@types/node': 25.9.2 - form-data: 4.0.5 + form-data: 4.0.6 '@types/supertest@7.2.0': dependencies: @@ -7996,7 +7795,7 @@ snapshots: baseline-browser-mapping@2.10.21: {} - basic-ftp@5.3.0: {} + basic-ftp@5.3.1: {} bath-es5@3.0.3: {} @@ -8029,7 +7828,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.2 on-finished: 2.4.1 - qs: 6.15.0 + qs: 6.15.2 raw-body: 3.0.2 type-is: 2.0.1 transitivePeerDependencies: @@ -8434,7 +8233,7 @@ snapshots: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@8.1.1) engine.io-parser: 5.2.3 - ws: 8.18.3 + ws: 8.21.0 xmlhttprequest-ssl: 2.1.2 transitivePeerDependencies: - bufferutil @@ -8453,7 +8252,7 @@ snapshots: cors: 2.8.5 debug: 4.4.3(supports-color@8.1.1) engine.io-parser: 5.2.3 - ws: 8.18.3 + ws: 8.21.0 transitivePeerDependencies: - bufferutil - supports-color @@ -8571,35 +8370,6 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 - esbuild@0.28.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.0 - '@esbuild/android-arm': 0.28.0 - '@esbuild/android-arm64': 0.28.0 - '@esbuild/android-x64': 0.28.0 - '@esbuild/darwin-arm64': 0.28.0 - '@esbuild/darwin-x64': 0.28.0 - '@esbuild/freebsd-arm64': 0.28.0 - '@esbuild/freebsd-x64': 0.28.0 - '@esbuild/linux-arm': 0.28.0 - '@esbuild/linux-arm64': 0.28.0 - '@esbuild/linux-ia32': 0.28.0 - '@esbuild/linux-loong64': 0.28.0 - '@esbuild/linux-mips64el': 0.28.0 - '@esbuild/linux-ppc64': 0.28.0 - '@esbuild/linux-riscv64': 0.28.0 - '@esbuild/linux-s390x': 0.28.0 - '@esbuild/linux-x64': 0.28.0 - '@esbuild/netbsd-arm64': 0.28.0 - '@esbuild/netbsd-x64': 0.28.0 - '@esbuild/openbsd-arm64': 0.28.0 - '@esbuild/openbsd-x64': 0.28.0 - '@esbuild/openharmony-arm64': 0.28.0 - '@esbuild/sunos-x64': 0.28.0 - '@esbuild/win32-arm64': 0.28.0 - '@esbuild/win32-ia32': 0.28.0 - '@esbuild/win32-x64': 0.28.0 - esbuild@0.28.1: optionalDependencies: '@esbuild/aix-ppc64': 0.28.1 @@ -8784,7 +8554,7 @@ snapshots: eslint-plugin-react-hooks@7.1.1(eslint@10.5.0): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/parser': 7.29.2 eslint: 10.5.0 hermes-parser: 0.25.1 @@ -8943,7 +8713,7 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.0 + qs: 6.15.2 range-parser: 1.2.1 router: 2.2.0 send: 1.2.0 @@ -9046,12 +8816,12 @@ snapshots: dependencies: is-callable: 1.2.7 - form-data@4.0.5: + form-data@4.0.6: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.3 + hasown: 2.0.4 mime-types: 2.1.35 formdata-polyfill@4.0.10: @@ -9143,7 +8913,7 @@ snapshots: get-uri@6.0.4: dependencies: - basic-ftp: 5.3.0 + basic-ftp: 5.3.1 data-uri-to-buffer: 6.0.2 debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: @@ -9222,6 +8992,10 @@ snapshots: dependencies: function-bind: 1.1.2 + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + hast-util-embedded@3.0.0: dependencies: '@types/hast': 3.0.4 @@ -9442,11 +9216,6 @@ snapshots: ip-address@10.2.0: {} - ip-address@9.0.5: - dependencies: - jsbn: 1.1.0 - sprintf-js: 1.1.3 - ipaddr.js@1.9.1: {} is-array-buffer@3.0.5: @@ -9609,12 +9378,10 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@4.1.1: + js-yaml@4.2.0: dependencies: argparse: 2.0.1 - jsbn@1.1.0: {} - jsdom@29.1.1(@noble/hashes@1.8.0): dependencies: '@asamuzakjp/css-color': 5.1.11 @@ -9823,7 +9590,7 @@ snapshots: node-fetch-commonjs: 3.3.2 proxy-agent: 6.5.0 semver: 7.8.4 - tar: 7.5.13 + tar: 7.5.16 url-join: 4.0.1 transitivePeerDependencies: - supports-color @@ -10024,7 +9791,7 @@ snapshots: glob: 13.0.6 he: 1.2.0 is-path-inside: 3.0.3 - js-yaml: 4.1.1 + js-yaml: 4.2.0 log-symbols: 4.1.0 minimatch: 10.2.5 ms: 2.1.3 @@ -10496,10 +10263,6 @@ snapshots: punycode@2.3.1: {} - qs@6.15.0: - dependencies: - side-channel: 1.1.0 - qs@6.15.2: dependencies: side-channel: 1.1.0 @@ -10974,7 +10737,7 @@ snapshots: socket.io-adapter@2.5.6: dependencies: debug: 4.4.3(supports-color@8.1.1) - ws: 8.18.3 + ws: 8.21.0 transitivePeerDependencies: - bufferutil - supports-color @@ -11022,7 +10785,7 @@ snapshots: socks@2.8.5: dependencies: - ip-address: 9.0.5 + ip-address: 10.2.0 smart-buffer: 4.2.0 source-map-js@1.2.1: {} @@ -11127,11 +10890,11 @@ snapshots: cookiejar: 2.1.4 debug: 4.4.3(supports-color@8.1.1) fast-safe-stringify: 2.1.1 - form-data: 4.0.5 + form-data: 4.0.6 formidable: 3.5.4 methods: 1.1.2 mime: 2.6.0 - qs: 6.15.0 + qs: 6.15.2 transitivePeerDependencies: - supports-color @@ -11170,7 +10933,7 @@ snapshots: tapable@2.3.2: {} - tar@7.5.13: + tar@7.5.16: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -11271,7 +11034,7 @@ snapshots: tsx@4.22.4: dependencies: - esbuild: 0.28.0 + esbuild: 0.28.1 optionalDependencies: fsevents: 2.3.3 @@ -11493,9 +11256,9 @@ snapshots: x-is-array: 0.1.0 x-is-string: 0.1.0 - vite-plugin-babel@1.7.3(@babel/core@7.29.0)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)): + vite-plugin-babel@1.7.3(@babel/core@7.29.7)(vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4)): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 vite: 8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4) vite@8.0.16(@types/node@25.9.3)(esbuild@0.28.1)(tsx@4.22.4): @@ -11698,7 +11461,7 @@ snapshots: wrappy@1.0.2: {} - ws@8.18.3: {} + ws@8.21.0: {} wsl-utils@0.1.0: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3063e4296..0fdd60282 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -21,20 +21,25 @@ strictDepBuilds: false # As of pnpm 11, overrides must live here (root package.json's pnpm.overrides # is no longer read). Force-bump transitive deps with known CVEs. overrides: - basic-ftp: '>=5.3.0' + '@babel/core@<7.29.6': '>=7.29.6' + basic-ftp@<5.3.1: '>=5.3.1 <6.0.0' brace-expansion@>=2.0.0 <2.0.3: '>=2.0.3' diff@>=6.0.0 <8.0.3: '>=8.0.3' + esbuild@<0.28.1: '>=0.28.1' flatted: '>=3.4.2' follow-redirects: '>=1.16.0' + form-data@>=4.0.0 <4.0.6: '>=4.0.6' glob@>=10.2.0 <10.5.0: '>=10.5.0' - js-yaml@>=4.0.0 <4.1.1: '>=4.1.1' + ip-address@<10.1.1: '>=10.1.1' + js-yaml@>=4.0.0 <4.2.0: '>=4.2.0' lodash: '>=4.18.0' minimatch@>=9.0.0 <9.0.7: '>=9.0.7' path-to-regexp@>=8.0.0 <8.4.0: '>=8.4.0' picomatch@>=4.0.0 <4.0.4: '>=4.0.4' - qs@>=6.7.0 <6.14.2: '>=6.14.2' + qs@>=6.7.0 <6.15.2: '>=6.15.2' serialize-javascript@<7.0.5: '>=7.0.5' socket.io-parser@>=4.0.0 <4.2.6: '>=4.2.6' - tar@<7.5.11: '>=7.5.11' + tar@<7.5.16: '>=7.5.16' uuid@<14.0.0: '>=14.0.0' vite@>=7.0.0 <7.3.2: '>=7.3.2' + ws@>=8.0.0 <8.21.0: '>=8.21.0' From 0c0f5a8ec473efc59a75e3e57e649da2365bc512 Mon Sep 17 00:00:00 2001 From: forkivan <157495907+forkivan@users.noreply.github.com> Date: Tue, 16 Jun 2026 12:13:02 +0200 Subject: [PATCH 19/43] PadManager: reject unreachable '.' and '..' pad ids (#7962) * PadManager: reject unreachable '.' and '..' pad ids isValidPadId accepted pad ids that consist only of URL dot-segments ('.' and '..'). Per the WHATWG URL standard a browser normalises "/p/." to "/p/" and "/p/.." to "/", so such a pad can never be opened or exported: the request arrives at "/p/" and Etherpad answers "Cannot GET /p/". The pad is created in the database but is forever unreachable. Reject these ids in isValidPadId so the broken pads can no longer be created, and add a regression test that fails without the fix. * adminsettings: allow deleting legacy '.'/'..' pads The isValidPadId tightening makes getPad() reject the pad ids '.' and '..', which also blocks their deletion: a pad with such an id created before the change still exists (doesPadExists is true), so the admin deletePad handler takes the "healthy" branch where getPad() now throws. The outer catch swallowed that error without emitting a terminal results:deletePad, leaving an undeletable orphan in the admin UI. Fall back to the existing raw key purge when getPad() throws, so these pads can still be removed. Adds a regression test. * tests: run the isValidPadId regression under the mocha suite The original unit test lived in the vitest backend-new suite, but PadManager loads DB, Pad and customError with CommonJS require() at import time. Under vitest those require() calls are resolved by Node natively and fail on the .ts sources ("Cannot find module '../utils/customError'"); vi.mock could not intercept them, so the suite errored before any test ran. It also used a top-level `await import`, which tripped tsc TS1378 under the project tsconfig. Move the test to the mocha backend suite, which runs with --import=tsx and resolves the .ts requires natively, so PadManager can be required directly with no mocking. isValidPadId is a pure function and DB only connects lazily in DB.init(), so loading the module has no side effects and no database is needed. --- src/node/db/PadManager.ts | 10 +++- src/node/hooks/express/adminsettings.ts | 23 ++++++--- src/tests/backend/specs/PadManager.ts | 48 +++++++++++++++++++ .../backend/specs/admin/padLoadResilience.ts | 23 +++++++++ 4 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 src/tests/backend/specs/PadManager.ts diff --git a/src/node/db/PadManager.ts b/src/node/db/PadManager.ts index 292261531..28b0588fe 100644 --- a/src/node/db/PadManager.ts +++ b/src/node/db/PadManager.ts @@ -192,7 +192,15 @@ exports.sanitizePadId = async (padId: string) => { return padId; }; -exports.isValidPadId = (padId: string) => /^(g.[a-zA-Z0-9]{16}\$)?[^$]{1,50}$/.test(padId); +// Pad IDs consisting only of URL "dot-segments" ('.' or '..') are unreachable: +// per the WHATWG URL standard a browser normalises "/p/." to "/p/" and "/p/.." +// to "/", so the pad can never be opened or exported — the request arrives as +// "/p/" and Etherpad answers "Cannot GET /p/". Reject them so such (broken) pads +// can never be created. +const dotSegmentPadId = /^\.{1,2}$/; + +exports.isValidPadId = (padId: string) => + /^(g.[a-zA-Z0-9]{16}\$)?[^$]{1,50}$/.test(padId) && !dotSegmentPadId.test(padId); /** * Removes the pad from database and unloads it. diff --git a/src/node/hooks/express/adminsettings.ts b/src/node/hooks/express/adminsettings.ts index 678da2568..d52b07a68 100644 --- a/src/node/hooks/express/adminsettings.ts +++ b/src/node/hooks/express/adminsettings.ts @@ -305,13 +305,22 @@ exports.socketio = (hookName: string, {io}: any) => { socket.on('deletePad', async (padId: string) => { try { if (await padManager.doesPadExists(padId)) { - // Healthy pad — full relational cleanup (revs, chat, readonly, - // authors, deletion token, hooks). - logger.info(`Deleting pad: ${padId}`); - const pad = await padManager.getPad(padId); - await pad.remove(); - socket.emit('results:deletePad', padId); - return; + try { + // Healthy pad — full relational cleanup (revs, chat, readonly, + // authors, deletion token, hooks). + logger.info(`Deleting pad: ${padId}`); + const pad = await padManager.getPad(padId); + await pad.remove(); + socket.emit('results:deletePad', padId); + return; + } catch (err) { + // getPad() runs isValidPadId() and rejects ids that are no longer + // valid — e.g. legacy '.'/'..' pads created before that validation + // was tightened. Don't give up: fall through to the raw key purge + // below so the orphan can still be deleted from the admin UI. + logger.warn(`Relational cleanup failed for "${padId}" ` + + `(${safeErr(err)}); falling back to raw key purge`); + } } // doesPadExists() is false either because nothing is stored under diff --git a/src/tests/backend/specs/PadManager.ts b/src/tests/backend/specs/PadManager.ts new file mode 100644 index 000000000..c4ddf79a0 --- /dev/null +++ b/src/tests/backend/specs/PadManager.ts @@ -0,0 +1,48 @@ +'use strict'; + +// Unit coverage for PadManager.isValidPadId. +// +// isValidPadId is a pure function (a regex test), so this spec just requires +// PadManager and exercises it directly — no running database is needed. +// PadManager's import-time `require`s (DB, Pad, customError) only *define* +// things; the database connection happens lazily in DB.init(), so loading the +// module here has no side effects. This runs under the mocha backend suite +// (`--import=tsx`), where `require()` resolves the `.ts` sources natively. + +import {strict as assert} from 'assert'; + +const padManager = require('../../../node/db/PadManager'); + +describe(__filename, function () { + describe('isValidPadId', function () { + it('accepts ordinary pad ids', async function () { + for (const id of [ + 'foo', + 'TF-EVC', + 'TF-LEC_IP03-EMS-CSM', + 'a.b', + '.foo', + 'foo.', + "a'b", + 'g.s8oes9dhwrvt0zif$bar', // group pad + ]) { + assert.equal(padManager.isValidPadId(id), true, `expected "${id}" to be valid`); + } + }); + + // Regression test for "Cannot GET /p/": a pad id that is a URL dot-segment + // ('.' or '..') is normalised away by the browser per the WHATWG URL + // standard ('/p/.' -> '/p/', '/p/..' -> '/'), so the pad can never be + // opened or exported. Such ids must be rejected. Before the fix + // isValidPadId returned true for both, so this test would fail. + it('rejects URL dot-segment pad ids that would be unreachable', async function () { + assert.equal(padManager.isValidPadId('.'), false); + assert.equal(padManager.isValidPadId('..'), false); + }); + + it('still rejects empty ids and ids containing "$"', async function () { + assert.equal(padManager.isValidPadId(''), false); + assert.equal(padManager.isValidPadId('a$b'), false); + }); + }); +}); diff --git a/src/tests/backend/specs/admin/padLoadResilience.ts b/src/tests/backend/specs/admin/padLoadResilience.ts index 28c5d284f..b69517d74 100644 --- a/src/tests/backend/specs/admin/padLoadResilience.ts +++ b/src/tests/backend/specs/admin/padLoadResilience.ts @@ -177,4 +177,27 @@ describe(__filename, function () { assert.ok(!names.includes(corruptId), `corrupt pad still listed: ${JSON.stringify(names)}`); assert.ok(names.includes(goodId), `good pad missing after delete: ${JSON.stringify(names)}`); }); + + // Regression for the isValidPadId tightening that rejects '.' and '..': a + // legacy pad with such an id predates the validation, so it still exists in + // the DB (doesPadExists is true → deletePad takes the "healthy" branch) but + // getPad() now throws on it. deletePad must fall back to the raw key purge + // instead of failing silently, otherwise the orphan is undeletable from the + // admin UI. Before the fallback this `ask()` never gets `results:deletePad` + // and times out. + it("a legacy '.' pad (now an invalid id) can still be deleted", async function () { + this.timeout(30000); + const dotId = '.'; + // getPad('.') would now throw, so seed the record directly with a truthy + // `atext` so doesPadExists() returns true and the handler enters the branch + // where getPad() throws. + await db.set(`pad:${dotId}`, {atext: {text: '\n', attribs: ''}, pool: {}, head: -1, savedRevisions: []}); + try { + const ack = await ask(socket, 'deletePad', dotId, 'results:deletePad'); + assert.equal(ack, dotId, `expected deletePad to ack "${dotId}", got ${JSON.stringify(ack)}`); + } finally { + try { await db.remove(`pad:${dotId}`); } catch { /* ignore */ } + try { padManager.unloadPad(dotId); } catch { /* ignore */ } + } + }); }); From a59b310dbfe3084daf88ba743cd59b19ecea32a8 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 16 Jun 2026 11:39:37 +0100 Subject: [PATCH 20/43] deps: pin ueberdb2 to 6.1.9 (fixes standalone-server startup exit) + run deb smoke on PRs (#7969) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ueberdb2 6.1.10 rewrote the cache/buffer layer (CacheAndBufferLayer.ts), replacing the constructor's always-on, *referenced* `setInterval` flush timer with a lazily-armed `setTimeout` that is `.unref()`'d and only created when there are dirty keys. On a fresh, empty dirty DB there are no dirty keys, so no flush timer is ever armed and ueberdb2 no longer anchors Node's event loop. In the packaged (.deb/systemd) production boot this exposes a startup window where the loop has no referenced handle and the process exits cleanly (code 0) before `server.listen()` binds the port — so the server never serves /health. Symptom on develop: the Debian-package amd64 smoke test failed on three consecutive pushes (#7966 ueberdb2 6.1.9->6.1.12, then #7965, #7967), with the service logging the version banner then "Deactivated successfully" and the health check on :9001 never connecting. Backend/Docker/downstream-smoke stayed green because they keep the loop alive by other means; only the bare fresh-empty-dirty-DB packaged boot hits the gap. ueberdb2 6.1.12 is the latest published release, so there is no fixed version to roll forward to yet — pin back to the last green release (6.1.9) on both src/ and bin/. Also add a `pull_request` trigger to the Debian-package workflow (scoped to the same production-footprint paths). The smoke step is the only check that catches this "boots then exits before binding" class of regression, but it previously ran only on push to develop — i.e. *after* merge — which is exactly why the Dependabot bump turned develop red instead of being blocked at PR time. The release/apt-publish jobs are tag-guarded, so PRs run the build+smoke job only. Co-authored-by: Claude Opus 4.8 (1M context) --- .github/workflows/deb-package.yml | 18 ++++++++++++++++++ bin/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- src/package.json | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deb-package.yml b/.github/workflows/deb-package.yml index 603089c26..95aecd0b3 100644 --- a/.github/workflows/deb-package.yml +++ b/.github/workflows/deb-package.yml @@ -15,6 +15,24 @@ on: - 'src/node/utils/run_cmd.ts' - 'src/static/js/pluginfw/**' - 'settings.json.template' + # Also build + smoke-test the package on PRs that touch the production + # footprint. The smoke step boots the packaged server and waits for /health, + # which is the only check that catches "server starts then exits before + # binding the port" startup regressions (e.g. a dependency bump whose change + # lets the event loop drain mid-boot). Previously this workflow ran only on + # push to develop, so such a regression was caught *after* merge — by which + # point develop was already red. Running it pre-merge blocks the PR instead. + # The release/apt-publish jobs are tag-guarded, so PRs run the build job only. + pull_request: + paths: + - 'packaging/**' + - '.github/workflows/deb-package.yml' + - 'src/package.json' + - 'pnpm-lock.yaml' + - 'src/node/server.ts' + - 'src/node/utils/run_cmd.ts' + - 'src/static/js/pluginfw/**' + - 'settings.json.template' workflow_dispatch: inputs: ref: diff --git a/bin/package.json b/bin/package.json index 7127c19ff..aaff5049a 100644 --- a/bin/package.json +++ b/bin/package.json @@ -11,7 +11,7 @@ "log4js": "^6.9.1", "semver": "^7.8.4", "tsx": "^4.22.4", - "ueberdb2": "^6.1.12" + "ueberdb2": "6.1.9" }, "devDependencies": { "@types/node": "^25.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81f80aa59..618cfc054 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -164,8 +164,8 @@ importers: specifier: ^4.22.4 version: 4.22.4 ueberdb2: - specifier: ^6.1.12 - version: 6.1.12(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) + specifier: 6.1.9 + version: 6.1.9(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) devDependencies: '@types/node': specifier: ^25.9.3 @@ -364,8 +364,8 @@ importers: specifier: 4.22.4 version: 4.22.4 ueberdb2: - specifier: ^6.1.12 - version: 6.1.12(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) + specifier: 6.1.9 + version: 6.1.9(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)) underscore: specifier: 1.13.8 version: 1.13.8 @@ -5400,8 +5400,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - ueberdb2@6.1.12: - resolution: {integrity: sha512-LxW4He5ZWhRzSldB105T/z9L7ljPJJeQ2VkM7tAhh0hj2TZ0zz6DItdBwDA5CQPab5QhiJ7BZC1OgkDqNDL53w==} + ueberdb2@6.1.9: + resolution: {integrity: sha512-AOifNHJT0A9c52eEQqcm77d3/RUZVIvGFN1KFbXEPpfI89fa5c9lS8z7piu6m+CwBgWD+Fq5wAmP7W3LVZ4MwA==} engines: {node: '>=24.0.0'} peerDependencies: '@elastic/elasticsearch': ^9.0.0 @@ -11097,7 +11097,7 @@ snapshots: typescript@6.0.3: {} - ueberdb2@6.1.12(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)): + ueberdb2@6.1.9(@elastic/elasticsearch@9.4.2)(async@3.2.6)(cassandra-driver@4.8.0)(dirty-ts@1.1.8)(mongodb@7.3.0)(mssql@12.5.5(@azure/core-client@1.10.1))(mysql2@3.22.5(@types/node@25.9.3))(nano@11.0.5)(pg@8.21.0)(redis@6.0.0(@opentelemetry/api@1.9.1))(rethinkdb@2.4.2)(rusty-store-kv@1.3.1)(surrealdb@2.0.3(tslib@2.8.1)(typescript@6.0.3)): optionalDependencies: '@elastic/elasticsearch': 9.4.2 async: 3.2.6 diff --git a/src/package.json b/src/package.json index aba4e2b13..b69064f63 100644 --- a/src/package.json +++ b/src/package.json @@ -87,7 +87,7 @@ "surrealdb": "^2.0.3", "tinycon": "0.6.8", "tsx": "4.22.4", - "ueberdb2": "^6.1.12", + "ueberdb2": "6.1.9", "underscore": "1.13.8", "undici": "^8.4.1", "unorm": "1.6.0", From 3e53962fb522a6e55bff99465fd0f6c3fa1c2571 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 17 Jun 2026 08:53:20 +0100 Subject: [PATCH 21/43] fix(deps): force @opentelemetry/core >=2.8.0 (CVE-2026-54285) (#7975) Pin the transitive @opentelemetry/core dep (pulled in via @elastic/elasticsearch -> @elastic/transport) to >=2.8.0 to clear GHSA-8988-4f7v-96qf / CVE-2026-54285: W3CBaggagePropagator.extract() did not enforce W3C size limits on inbound baggage headers, allowing unbounded memory allocation. @elastic/transport declares the dep as "2.x" so 2.8.0 satisfies the existing range with no parent bump, and 2.8.0's @opentelemetry/api peer range (>=1.0.0 <1.10.0) is satisfied by the 1.9.1 already in the tree. Override added to pnpm-workspace.yaml alongside the other CVE force-bumps (pnpm 11 ignores root package.json pnpm.overrides). Co-authored-by: Claude Opus 4.8 (1M context) --- pnpm-lock.yaml | 9 +++++---- pnpm-workspace.yaml | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 618cfc054..999457d78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,7 @@ settings: overrides: '@babel/core@<7.29.6': '>=7.29.6' + '@opentelemetry/core@<2.8.0': '>=2.8.0' basic-ftp@<5.3.1: '>=5.3.1 <6.0.0' brace-expansion@>=2.0.0 <2.0.3: '>=2.0.3' diff@>=6.0.0 <8.0.3: '>=8.0.3' @@ -1143,8 +1144,8 @@ packages: resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} - '@opentelemetry/core@2.7.1': - resolution: {integrity: sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==} + '@opentelemetry/core@2.8.0': + resolution: {integrity: sha512-hd1Lfh8p545nNz+jq1Ejfz+Mn1hyLuxYn1YzTfFNrxr8urEWMNQLPf1Th8kjOH+HxwawCrtgBp8JpBUR4ZSgww==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -6239,7 +6240,7 @@ snapshots: '@elastic/transport@9.3.6': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.8.0(@opentelemetry/api@1.9.1) debug: 4.4.3(supports-color@8.1.1) hpagent: 1.2.0 ms: 2.1.3 @@ -6540,7 +6541,7 @@ snapshots: '@opentelemetry/api@1.9.1': {} - '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': + '@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/semantic-conventions': 1.41.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0fdd60282..3e6b40fbf 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -22,6 +22,7 @@ strictDepBuilds: false # is no longer read). Force-bump transitive deps with known CVEs. overrides: '@babel/core@<7.29.6': '>=7.29.6' + '@opentelemetry/core@<2.8.0': '>=2.8.0' basic-ftp@<5.3.1: '>=5.3.1 <6.0.0' brace-expansion@>=2.0.0 <2.0.3: '>=2.0.3' diff@>=6.0.0 <8.0.3: '>=8.0.3' From bfe3fad256d37fe01837ed4498b65e40450fa84c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:17:10 +0100 Subject: [PATCH 22/43] build(deps): bump @radix-ui/react-switch from 1.3.0 to 1.3.1 (#7974) Bumps [@radix-ui/react-switch](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/switch) from 1.3.0 to 1.3.1. - [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/switch/CHANGELOG.md) - [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/switch) --- updated-dependencies: - dependency-name: "@radix-ui/react-switch" dependency-version: 1.3.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- admin/package.json | 2 +- pnpm-lock.yaml | 50 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/admin/package.json b/admin/package.json index 738d06010..b471044f4 100644 --- a/admin/package.json +++ b/admin/package.json @@ -14,7 +14,7 @@ "test": "pnpm gen:api && tsx --test 'src/**/__tests__/*.test.ts' 'src/**/__tests__/*.test.tsx'" }, "dependencies": { - "@radix-ui/react-switch": "^1.3.0", + "@radix-ui/react-switch": "^1.3.1", "@tanstack/react-query": "^5.101.0", "@tanstack/react-query-devtools": "^5.101.0", "jsonc-parser": "^3.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 999457d78..4e839baef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: admin: dependencies: '@radix-ui/react-switch': - specifier: ^1.3.0 - version: 1.3.0(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + specifier: ^1.3.1 + version: 1.3.1(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/react-query': specifier: ^5.101.0 version: 5.101.0(react@19.2.7) @@ -1422,6 +1422,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-primitive@2.1.6': + resolution: {integrity: sha512-wetd0QI77DbvrPpTAvH1SqOxsYF2wZe5TNxqwOd5Ty4XDpV3dpV0s8K/1MGMJBeY5o7lg8ub5VIt1Ub+yVen6g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.2.5': resolution: {integrity: sha512-rCMO3QsIVKv5JTY5CVbo2MvO77SpEqqYc8AvRE7OWqRDOIqAKjsp+DrmnY9uc8NPdxB5E2z47HTYGeE2+NTptg==} peerDependencies: @@ -1431,8 +1444,17 @@ packages: '@types/react': optional: true - '@radix-ui/react-switch@1.3.0': - resolution: {integrity: sha512-GP1EZwhoZO/GGnhM1P5/2Vpm8iN8EnngyU0oezn2l78kN8tj25pyrvjIaT7azBhK615KSt+P2w39y57YV5jVkA==} + '@radix-ui/react-slot@1.3.0': + resolution: {integrity: sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.3.1': + resolution: {integrity: sha512-55bQtCnOB0BohomSHi6qvQXpJEEqUGDm6hRrM0Bph5OXwhSegqkd8IqgBAQkM1IlgUlWZIxpxRcpOEfRIgimyw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -6735,6 +6757,15 @@ snapshots: '@types/react': 19.2.17 '@types/react-dom': 19.2.3(@types/react@19.2.17) + '@radix-ui/react-primitive@2.1.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@radix-ui/react-slot': 1.3.0(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + '@radix-ui/react-slot@1.2.5(@types/react@19.2.17)(react@19.2.7)': dependencies: '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) @@ -6742,12 +6773,19 @@ snapshots: optionalDependencies: '@types/react': 19.2.17 - '@radix-ui/react-switch@1.3.0(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@radix-ui/react-slot@1.3.0(@types/react@19.2.17)(react@19.2.7)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) + react: 19.2.7 + optionalDependencies: + '@types/react': 19.2.17 + + '@radix-ui/react-switch@1.3.1(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@radix-ui/primitive': 1.1.4 '@radix-ui/react-compose-refs': 1.1.3(@types/react@19.2.17)(react@19.2.7) '@radix-ui/react-context': 1.1.4(@types/react@19.2.17)(react@19.2.7) - '@radix-ui/react-primitive': 2.1.5(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@radix-ui/react-primitive': 2.1.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@radix-ui/react-use-controllable-state': 1.2.3(@types/react@19.2.17)(react@19.2.7) '@radix-ui/react-use-previous': 1.1.2(@types/react@19.2.17)(react@19.2.7) '@radix-ui/react-use-size': 1.1.2(@types/react@19.2.17)(react@19.2.7) From 4ba72b39195fa5f1c29de3e09ae893956b4c37b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:17:36 +0100 Subject: [PATCH 23/43] build(deps): bump oidc-provider from 9.8.4 to 9.8.5 (#7973) Bumps [oidc-provider](https://github.com/panva/node-oidc-provider) from 9.8.4 to 9.8.5. - [Release notes](https://github.com/panva/node-oidc-provider/releases) - [Changelog](https://github.com/panva/node-oidc-provider/blob/main/CHANGELOG.md) - [Commits](https://github.com/panva/node-oidc-provider/compare/v9.8.4...v9.8.5) --- updated-dependencies: - dependency-name: oidc-provider dependency-version: 9.8.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 12 ++++++------ src/package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e839baef..efd47add0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -302,8 +302,8 @@ importers: specifier: ^9.0.0 version: 9.0.0 oidc-provider: - specifier: 9.8.4 - version: 9.8.4 + specifier: 9.8.5 + version: 9.8.5 openapi-backend: specifier: ^5.17.0 version: 5.17.0 @@ -4428,8 +4428,8 @@ packages: resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} engines: {node: '>=12.20.0'} - oidc-provider@9.8.4: - resolution: {integrity: sha512-i8qe+wvhUQ7BSj6DxssIFAdpREouuqK91j2jGdAN78NIxTB5rxvU4ZniXELhUHIM4mzABeSGlp5wE6WTa8CY1Q==} + oidc-provider@9.8.5: + resolution: {integrity: sha512-07Wqkea8jdfPI8GvbVwf9rMNNitLUzzDqPua7hWbqZreFNpfnlNVdqmllaripVmgDZS2tHHLYQYLW0Ay7yux9w==} on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -9980,7 +9980,7 @@ snapshots: obug@2.1.3: {} - oidc-provider@9.8.4: + oidc-provider@9.8.5: dependencies: '@koa/cors': 5.0.0 '@koa/router': 15.6.0(koa@3.2.1) @@ -10286,7 +10286,7 @@ snapshots: proxy-agent@6.5.0: dependencies: agent-base: 7.1.3 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.1 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 lru-cache: 7.18.3 diff --git a/src/package.json b/src/package.json index b69064f63..d33398cd4 100644 --- a/src/package.json +++ b/src/package.json @@ -66,7 +66,7 @@ "mysql2": "^3.22.5", "nano": "^11.0.5", "nodemailer": "^9.0.0", - "oidc-provider": "9.8.4", + "oidc-provider": "9.8.5", "openapi-backend": "^5.17.0", "pdfkit": "^0.19.1", "pg": "^8.21.0", From d67aa3ebd3eb6a9e6ededf45e52a4f27e25e4a50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:17:49 +0100 Subject: [PATCH 24/43] build(deps): bump undici from 8.4.1 to 8.5.0 (#7972) Bumps [undici](https://github.com/nodejs/undici) from 8.4.1 to 8.5.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v8.4.1...v8.5.0) --- updated-dependencies: - dependency-name: undici dependency-version: 8.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 10 +++++----- src/package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index efd47add0..1781ac7d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -371,8 +371,8 @@ importers: specifier: 1.13.8 version: 1.13.8 undici: - specifier: ^8.4.1 - version: 8.4.1 + specifier: ^8.5.0 + version: 8.5.0 unorm: specifier: 1.6.0 version: 1.6.0 @@ -5495,8 +5495,8 @@ packages: resolution: {integrity: sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==} engines: {node: '>=20.18.1'} - undici@8.4.1: - resolution: {integrity: sha512-RNHlB4fxZK0IrkhBsxhlbx7s8kFWwr7rzzOqj5nvZugw3ig3RsB7KW3zVlV0eu8POl+rx5d1hmL7rRg0z1owow==} + undici@8.5.0: + resolution: {integrity: sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==} engines: {node: '>=22.19.0'} unicode-properties@1.4.1: @@ -11173,7 +11173,7 @@ snapshots: undici@7.27.2: {} - undici@8.4.1: {} + undici@8.5.0: {} unicode-properties@1.4.1: dependencies: diff --git a/src/package.json b/src/package.json index d33398cd4..579a794c5 100644 --- a/src/package.json +++ b/src/package.json @@ -89,7 +89,7 @@ "tsx": "4.22.4", "ueberdb2": "6.1.9", "underscore": "1.13.8", - "undici": "^8.4.1", + "undici": "^8.5.0", "unorm": "1.6.0", "wtfnode": "^0.10.1" }, From ce038b0b0f4d12926650181f6a001912ae9769ff Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 17 Jun 2026 15:18:23 +0100 Subject: [PATCH 25/43] fix(pad): keep token-less Delete pad reachable without pad-wide settings (#7959) (#7960) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(pad): keep token-less Delete pad reachable without pad-wide settings (#7959) The token-less "Delete pad" button (#delete-pad) was nested inside the enablePadWideSettings-gated pad-settings section, so disabling pad-wide settings removed the only way to delete a pad without a recovery token. Combined with #7926 hiding the token disclosure when deletion needs no token (e.g. allowPadDeletionByAllUsers), a user who was allowed to delete could be left with no deletion UI at all. Pad deletion is unrelated to pad-wide settings, so: - Move #delete-pad out of the enablePadWideSettings block in pad.html; it is now always rendered and hidden by default. - Add a canDeletePad clientVar (isCreator || allowPadDeletionByAllUsers) and drive the button's visibility from it in pad_editor.ts, mirroring the existing canDeleteWithoutToken handling for the token disclosure. The two controls are now mutually coherent and neither depends on enablePadWideSettings: the plain button shows when this session can delete without a token, the recovery-token disclosure shows otherwise. Tests: - backend padDeletionUiPlacement.ts: #delete-pad is rendered with enablePadWideSettings both on and off (fails without the template move). - backend socketio.ts: canDeletePad reflects the creator/allow-all matrix, including a non-creator who only gains it under allowPadDeletionByAllUsers. - frontend pad_settings.spec.ts: asserts #delete-pad is no longer a descendant of #pad-settings-section. Co-Authored-By: Claude Opus 4.8 (1M context) * fix(pad): never let readonly sessions delete via token-less paths (#7959) Qodo review of #7960: `canDeletePad` was `isCreator || allowPadDeletionByAllUsers`, so under allowPadDeletionByAllUsers a readonly viewer received canDeletePad=true and the relocated #delete-pad button unhid for them. Worse, the server-side handlePadDelete `flagOk`/`creatorOk` branches never checked session.readonly either, so a readonly-link holder could actually delete the pad without a token — a data-loss hole that the new always-rendered button would expose. Exclude readonly sessions from both the clientVar and the server's token-less authorization paths. A valid recovery token (tokenOk) stays a sufficient credential regardless of session mode. Test: socketio.ts asserts a readonly viewer gets canDeletePad=false and that a token-less PAD_DELETE from a readonly session leaves the pad intact (red before this change on the clientVar assertion). Co-Authored-By: Claude Opus 4.8 (1M context) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- src/node/handler/PadMessageHandler.ts | 20 ++++- src/static/js/pad_editor.ts | 7 ++ src/templates/pad.html | 14 ++-- .../backend/specs/padDeletionUiPlacement.ts | 44 +++++++++++ src/tests/backend/specs/socketio.ts | 74 +++++++++++++++++++ .../frontend-new/specs/pad_settings.spec.ts | 5 +- 6 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 src/tests/backend/specs/padDeletionUiPlacement.ts diff --git a/src/node/handler/PadMessageHandler.ts b/src/node/handler/PadMessageHandler.ts index 4f18693cc..7ede7d391 100644 --- a/src/node/handler/PadMessageHandler.ts +++ b/src/node/handler/PadMessageHandler.ts @@ -305,8 +305,13 @@ const handlePadDelete = async (socket: any, padDeleteMessage: PadDeleteMessage) // back to the creator-cookie path, otherwise a creator pasting a wrong // recovery token into the disclosure field would still succeed — masking a // typo and contradicting the UI. - const creatorOk = !tokenSupplied && isCreator; - const flagOk = !tokenSupplied && !isCreator && settings.allowPadDeletionByAllUsers; + // Readonly sessions can never delete via the token-less paths: they cannot + // edit the pad, so they must not be able to destroy it just because + // allowPadDeletionByAllUsers is on (issue #7959). A valid recovery token + // (tokenOk) remains a sufficient credential regardless of session mode. + const writable = !session.readonly; + const creatorOk = !tokenSupplied && isCreator && writable; + const flagOk = !tokenSupplied && !isCreator && settings.allowPadDeletionByAllUsers && writable; if (creatorOk || tokenOk || flagOk) { await retrievedPad.remove(); @@ -1321,6 +1326,16 @@ const handleClientReady = async (socket:any, message: ClientReadyMessage) => { const hasGetAuthorIdHook = (plugins.hooks.getAuthorId || []).length > 0; const hasDurableIdentity = hasGetAuthorIdHook && !!(user && user.username); const canDeleteWithoutToken = settings.allowPadDeletionByAllUsers || hasDurableIdentity; + // Whether this session may delete the pad with no token at all: the creator + // on this device (creator-cookie still present), or any user when the + // instance opted everyone in. Drives the plain "Delete pad" button, which is + // independent of enablePadWideSettings (issue #7959) — deletion is not a + // pad-wide setting and must stay reachable when that section is disabled. + // Readonly viewers are excluded: they cannot edit, let alone delete, so + // allowPadDeletionByAllUsers must not hand them a delete button (the server + // enforces the same in handlePadDelete). + const canDeletePad = + !sessionInfo.readonly && (isCreator || settings.allowPadDeletionByAllUsers); const padDeletionToken = isCreator && !canDeleteWithoutToken ? await padDeletionManager.createDeletionTokenIfAbsent(sessionInfo.padId) @@ -1346,6 +1361,7 @@ const handleClientReady = async (socket:any, message: ClientReadyMessage) => { // redundant, so the client labels the action "Delete Pad" instead of // "Delete with token" (issue #7926). See showDeletionTokenModalIfPresent. canDeleteWithoutToken, + canDeletePad, // Allow-listed copy — settings.privacyBanner could carry extra nested // keys from a hand-edited settings.json; sending those by reference // would leak them to every browser. See getPublicPrivacyBanner(). diff --git a/src/static/js/pad_editor.ts b/src/static/js/pad_editor.ts index 0382a813a..bd721e62c 100644 --- a/src/static/js/pad_editor.ts +++ b/src/static/js/pad_editor.ts @@ -159,6 +159,13 @@ const padeditor = (() => { $('#delete-pad-with-token').prop( 'hidden', !!(window as any).clientVars?.canDeleteWithoutToken); + // The plain "Delete pad" button is shown whenever this session can delete + // without a token (creator on this device, or allowPadDeletionByAllUsers). + // It is independent of pad-wide settings so it stays reachable when that + // section is disabled (issue #7959). + $('#delete-pad').prop( + 'hidden', !(window as any).clientVars?.canDeletePad); + // delete pad using a recovery token (second device / no creator cookie) $('#delete-pad-token-submit').on('click', () => { const token = String($('#delete-pad-token-input').val() || '').trim(); diff --git a/src/templates/pad.html b/src/templates/pad.html index 27f21948c..1a1efe19b 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -391,13 +391,17 @@

<% e.end_block(); %> - <% } %> - + +