From 5efa1d179582e5380ed5d1a5cf00581b26718f9d Mon Sep 17 00:00:00 2001 From: Dan Ditomaso Date: Fri, 11 Jul 2025 08:23:47 -0400 Subject: [PATCH] Prevented i18n package from escaping text (#704) * fix: prevented i18n package from escaping text * Update packages/web/vite.config.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: stupid copilot --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/web/index.html | 12 +++++++----- packages/web/public/i18n/locales/en/dialog.json | 2 +- .../src/components/Dialog/LocationResponseDialog.tsx | 1 + .../Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx | 1 + .../web/src/components/Dialog/PKIBackupDialog.tsx | 3 +++ .../Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx | 3 ++- packages/web/src/core/dto/NodeNumToNodeInfoDTO.ts | 7 ++----- packages/web/src/pages/Messages.tsx | 1 + packages/web/vite.config.ts | 4 ++++ 9 files changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/web/index.html b/packages/web/index.html index f21e342e..5c807b35 100644 --- a/packages/web/index.html +++ b/packages/web/index.html @@ -8,16 +8,18 @@ - + - + Meshtastic Web diff --git a/packages/web/public/i18n/locales/en/dialog.json b/packages/web/public/i18n/locales/en/dialog.json index 9b06b33a..56fb372b 100644 --- a/packages/web/public/i18n/locales/en/dialog.json +++ b/packages/web/public/i18n/locales/en/dialog.json @@ -178,6 +178,6 @@ "managedMode": { "confirmUnderstanding": "Yes, I know what I'm doing", "title": "Are you sure?", - "description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration." + "description": "Enabling Managed Mode blocks client applications (including the web client) from writing configurations to a radio. Once enabled, radio configurations can only be changed through Remote Admin messages. This setting is not required for remote node administration." } } diff --git a/packages/web/src/components/Dialog/LocationResponseDialog.tsx b/packages/web/src/components/Dialog/LocationResponseDialog.tsx index eb6d5e25..93b31f57 100644 --- a/packages/web/src/components/Dialog/LocationResponseDialog.tsx +++ b/packages/web/src/components/Dialog/LocationResponseDialog.tsx @@ -47,6 +47,7 @@ export const LocationResponseDialog = ({ {t("locationResponse.title", { + interpolation: { escapeValue: false }, identifier: `${longName} (${shortName})`, })} diff --git a/packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx b/packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx index 356ab3b1..b9e3caad 100644 --- a/packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx +++ b/packages/web/src/components/Dialog/NodeDetailsDialog/NodeDetailsDialog.tsx @@ -169,6 +169,7 @@ export const NodeDetailsDialog = ({ {t("nodeDetails.title", { + interpolation: { escapeValue: false }, identifier: `${node.user?.longName ?? t("unknown.shortName")} (${ node.user?.shortName ?? t("unknown.shortName") })`, diff --git a/packages/web/src/components/Dialog/PKIBackupDialog.tsx b/packages/web/src/components/Dialog/PKIBackupDialog.tsx index 189d5053..51ee96a2 100644 --- a/packages/web/src/components/Dialog/PKIBackupDialog.tsx +++ b/packages/web/src/components/Dialog/PKIBackupDialog.tsx @@ -50,6 +50,7 @@ export const PkiBackupDialog = ({ ${ t("pkiBackup.header", { + interpolation: { escapeValue: false }, shortName: getMyNode()?.user?.shortName ?? t("unknown.shortName"), longName: getMyNode()?.user?.longName ?? t("unknown.longName"), }) @@ -63,6 +64,7 @@ export const PkiBackupDialog = ({ <body> <h1>${ t("pkiBackup.header", { + interpolation: { escapeValue: false }, shortName: getMyNode()?.user?.shortName ?? t("unknown.shortName"), longName: getMyNode()?.user?.longName ?? t("unknown.longName"), }) @@ -103,6 +105,7 @@ export const PkiBackupDialog = ({ const link = document.createElement("a"); link.href = url; link.download = t("pkiBackup.fileName", { + interpolation: { escapeValue: false }, shortName: getMyNode()?.user?.shortName ?? t("unknown.shortName"), longName: getMyNode()?.user?.longName ?? t("unknown.longName"), }); diff --git a/packages/web/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx b/packages/web/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx index 07d4350d..9d5dd5f5 100644 --- a/packages/web/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx +++ b/packages/web/src/components/Dialog/RefreshKeysDialog/RefreshKeysDialog.tsx @@ -10,7 +10,7 @@ import { LockKeyholeOpenIcon } from "lucide-react"; import { useRefreshKeysDialog } from "./useRefreshKeysDialog.ts"; import { useDevice } from "@core/stores/deviceStore.ts"; import { useTranslation } from "react-i18next"; -import { useMessageStore } from "../../../core/stores/messageStore/index.ts"; +import { useMessageStore } from "@core/stores/messageStore/index.ts"; export interface RefreshKeysDialogProps { open: boolean; @@ -35,6 +35,7 @@ export const RefreshKeysDialog = ( const text = { title: t("refreshKeys.title", { + interpolation: { escapeValue: false }, identifier: nodeWithError?.user?.longName ?? "", }), description: `${t("refreshKeys.description.unableToSendDmPrefix")}${ diff --git a/packages/web/src/core/dto/NodeNumToNodeInfoDTO.ts b/packages/web/src/core/dto/NodeNumToNodeInfoDTO.ts index af013633..5902fe4b 100644 --- a/packages/web/src/core/dto/NodeNumToNodeInfoDTO.ts +++ b/packages/web/src/core/dto/NodeNumToNodeInfoDTO.ts @@ -8,14 +8,11 @@ class NodeInfoFactory { const last4 = userIdHex.slice(-4); const longName = `Meshtastic ${last4}`; const shortName = last4; - const hwModel = Protobuf.Mesh.HardwareModel.UNSET; return create(Protobuf.Mesh.UserSchema, { id: userId, - longName: longName, - shortName: shortName, - hwModel: hwModel, - isLicensed: false, + longName: longName.toString(), + shortName: shortName.toString(), }); } diff --git a/packages/web/src/pages/Messages.tsx b/packages/web/src/pages/Messages.tsx index ccea0e0a..2059be3e 100644 --- a/packages/web/src/pages/Messages.tsx +++ b/packages/web/src/pages/Messages.tsx @@ -308,6 +308,7 @@ export const MessagesPage = () => { <PageLayout label={`${ t("page.title", { + interpolation: { escapeValue: false }, chatName: isBroadcast && currentChannel ? getChannelName(currentChannel) : isDirect && otherNode diff --git a/packages/web/vite.config.ts b/packages/web/vite.config.ts index 7bef6349..c0e8d375 100644 --- a/packages/web/vite.config.ts +++ b/packages/web/vite.config.ts @@ -12,6 +12,9 @@ try { hash = "DEV"; } +const CONTENT_SECURITY_POLICY = + "script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' data: https://rsms.me https://cdn.jsdelivr.net; img-src 'self' data:; font-src 'self' data: https://rsms.me https://cdn.jsdelivr.net; worker-src 'self' blob:; object-src 'none'; base-uri 'self';"; + export default defineConfig({ plugins: [ react(), @@ -49,6 +52,7 @@ export default defineConfig({ server: { port: 3000, headers: { + "content-security-policy": CONTENT_SECURITY_POLICY, "Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Embedder-Policy": "require-corp", },