From 049f3de919d79e71fefd4da077d6b9b58d083c1a Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Mon, 19 Aug 2024 23:50:10 +0200 Subject: [PATCH 01/14] Added security tab --- src/components/PageComponents/Config/Security.tsx | 5 +++++ src/pages/Config/DeviceConfig.tsx | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 src/components/PageComponents/Config/Security.tsx diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx new file mode 100644 index 00000000..71346d1a --- /dev/null +++ b/src/components/PageComponents/Config/Security.tsx @@ -0,0 +1,5 @@ +export const Security = (): JSX.Element => { + return ( +

Security

+ ) +}; \ No newline at end of file diff --git a/src/pages/Config/DeviceConfig.tsx b/src/pages/Config/DeviceConfig.tsx index 66b8559d..45973e60 100644 --- a/src/pages/Config/DeviceConfig.tsx +++ b/src/pages/Config/DeviceConfig.tsx @@ -5,6 +5,7 @@ import { LoRa } from "@components/PageComponents/Config/LoRa.js"; import { Network } from "@components/PageComponents/Config/Network.js"; import { Position } from "@components/PageComponents/Config/Position.js"; import { Power } from "@components/PageComponents/Config/Power.js"; +import { Security } from "@components/PageComponents/Config/Security.js"; import { Tabs, TabsContent, @@ -47,6 +48,10 @@ export const DeviceConfig = (): JSX.Element => { label: "Bluetooth", element: Bluetooth, }, + { + label: "Security", + element: Security, + }, ]; return ( From a8dcab0844cde6f3a8a3467b0980cb195ce3f787 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 00:07:32 +0200 Subject: [PATCH 02/14] Added security input fields --- .../PageComponents/Config/Security.tsx | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index 71346d1a..4adb899e 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -1,5 +1,38 @@ +import { DynamicForm } from "@app/components/Form/DynamicForm"; + export const Security = (): JSX.Element => { + const onSubmit = (data: any) => { + console.log(data); + }; return ( -

Security

+ ) }; \ No newline at end of file From f6be57224e2e11704a222420185a00acd96f159f Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 15:04:10 +0200 Subject: [PATCH 03/14] Updated inputs --- .../PageComponents/Config/Security.tsx | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index 4adb899e..b2f7d5f5 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -1,4 +1,4 @@ -import { DynamicForm } from "@app/components/Form/DynamicForm"; +import { DynamicForm } from "@app/components/Form/DynamicForm.js"; export const Security = (): JSX.Element => { const onSubmit = (data: any) => { @@ -9,26 +9,68 @@ export const Security = (): JSX.Element => { onSubmit={onSubmit} fieldGroups={[ { - label: "Security", - description: "Admin and direct messages keys", + label: "Security Settings", + description: "Settings for the Security module", fields: [ { type: "text", name: "publicKey", label: "Public Key", - description: "Sent out to other nodes on the mesh to allow them to compute a shared secret key.", + description: "Sent out to other nodes on the mesh to allow them to compute a shared secret key", }, { type: "text", name: "privateKey", label: "Private Key", - description: "Used to create a shared key with a remote device." + description: "Used to create a shared key with a remote device", + }, + ], + }, + { + label: "Admin Settings", + description: "Settings for Admin ", + fields: [ + { + type: "toggle", + name: "adminChannelEnabled", + label: "Admin Channel", + description: "Enable 'admin' channel", + }, + { + type: "toggle", + name: "isManaged", + label: "Is Managed", + description: "Enable if you want to manage this node from other nodes", }, { type: "text", name: "adminKey", label: "Admin Key", - description: "The public key authorized to send admin messages to this node." + description: "The public key authorized to send admin messages to this node", + } + ], + }, + { + label: "Logging Settings", + description: "Settings for Logging", + fields: [ + { + type: "toggle", + name: "bluetoothLoggingEnabled", + label: "Bluetooth Logging", + description: "Enable Bluetooth Logging", + }, + { + type: "toggle", + name: "debugLogApiEnabled", + label: "Debug Log API", + description: "Enable Log API", + }, + { + type: "toggle", + name: "serialEnabled", + label: "Serial", + description: "Enable Serial" } ], }, From be9169f56f0f370d12ebdade5ab980f7046841d2 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 15:08:13 +0200 Subject: [PATCH 04/14] Use protobuf pki branch, tmp for dev --- package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index e56bdaed..b49b2041 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "devDependencies": { "@biomejs/biome": "^1.8.2", - "@buf/meshtastic_protobufs.bufbuild_es": "1.10.0-20240613143006-244927bc441a.1", + "@buf/meshtastic_protobufs.bufbuild_es": "2.0.0-00000000000000-aaea594f36a5.2", "@types/chrome": "^0.0.263", "@types/node": "^20.14.9", "@types/react": "^18.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 938ea82e..6bb4dad7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -130,8 +130,8 @@ importers: specifier: ^1.8.2 version: 1.8.2 '@buf/meshtastic_protobufs.bufbuild_es': - specifier: 1.10.0-20240613143006-244927bc441a.1 - version: 1.10.0-20240613143006-244927bc441a.1(@bufbuild/protobuf@1.10.0) + specifier: 2.0.0-00000000000000-aaea594f36a5.2 + version: 2.0.0-00000000000000-aaea594f36a5.2(@bufbuild/protobuf@1.10.0) '@types/chrome': specifier: ^0.0.263 version: 0.0.263 @@ -354,10 +354,10 @@ packages: cpu: [x64] os: [win32] - '@buf/meshtastic_protobufs.bufbuild_es@1.10.0-20240613143006-244927bc441a.1': - resolution: {tarball: https://buf.build/gen/npm/v1/@buf/meshtastic_protobufs.bufbuild_es/-/meshtastic_protobufs.bufbuild_es-1.10.0-20240613143006-244927bc441a.1.tgz} + '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-00000000000000-aaea594f36a5.2': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/meshtastic_protobufs.bufbuild_es/-/meshtastic_protobufs.bufbuild_es-2.0.0-00000000000000-aaea594f36a5.2.tgz} peerDependencies: - '@bufbuild/protobuf': ^1.10.0 + '@bufbuild/protobuf': ^2.0.0 '@bufbuild/protobuf@1.10.0': resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==} @@ -3306,7 +3306,7 @@ snapshots: '@biomejs/cli-win32-x64@1.8.2': optional: true - '@buf/meshtastic_protobufs.bufbuild_es@1.10.0-20240613143006-244927bc441a.1(@bufbuild/protobuf@1.10.0)': + '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-00000000000000-aaea594f36a5.2(@bufbuild/protobuf@1.10.0)': dependencies: '@bufbuild/protobuf': 1.10.0 From f64b96527e0806d9dce99f7d3bf7c1872117a6c8 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 17:18:55 +0200 Subject: [PATCH 05/14] Add security to device config store --- src/core/stores/deviceStore.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts index 29ac6ee0..a716a85b 100644 --- a/src/core/stores/deviceStore.ts +++ b/src/core/stores/deviceStore.ts @@ -191,6 +191,9 @@ export const useDeviceStore = create((set, get) => ({ device.config.bluetooth = config.payloadVariant.value; break; } + case "security": { + device.config.security = config.payloadVariant.value; + } } } }), From d3836a7250ffc909bbf005b65dc975678b2518b5 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 17:19:36 +0200 Subject: [PATCH 06/14] Add class SecurityValidation --- src/validation/config/security.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/validation/config/security.ts diff --git a/src/validation/config/security.ts b/src/validation/config/security.ts new file mode 100644 index 00000000..4d501537 --- /dev/null +++ b/src/validation/config/security.ts @@ -0,0 +1,31 @@ +import type { Message } from "@bufbuild/protobuf"; +import type { Protobuf } from "@meshtastic/js"; +import { IsBoolean, IsString } from "class-validator"; + +export class SecurityValidation + implements Omit +{ + @IsBoolean() + adminChannelEnabled: boolean; + + @IsString() + adminKey: string; + + @IsBoolean() + bluetoothLoggingEnabled: boolean; + + @IsBoolean() + debugLogApiEnabled: boolean; + + @IsBoolean() + isManaged: boolean; + + @IsString() + privateKey: string; + + @IsString() + publicKey: string; + + @IsBoolean() + serialEnabled: boolean; +} \ No newline at end of file From 7d5950d6cc127237a637bd550c1ba3b1589d9615 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 17:23:42 +0200 Subject: [PATCH 07/14] Add SecurityValidation to security channel --- .../PageComponents/Config/Security.tsx | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index b2f7d5f5..8553cf33 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -1,12 +1,47 @@ +import type { SecurityValidation } from "@app/validation/config/security.js" import { DynamicForm } from "@app/components/Form/DynamicForm.js"; +import { useDevice } from "@core/stores/deviceStore.js"; +import { Protobuf } from "@meshtastic/js"; +import { fromByteArray, toByteArray } from "base64-js"; +import { useState } from "react"; export const Security = (): JSX.Element => { - const onSubmit = (data: any) => { - console.log(data); + const { config, nodes, hardware, setWorkingConfig } = useDevice(); + + const [adminKey, setAdminKey] = useState( + fromByteArray(config.security?.adminKey ?? new Uint8Array(0)) + ); + const [privateKey, setPrivateKey] = useState( + fromByteArray(config.security?.privateKey ?? new Uint8Array(0)) + ); + const [publicKey, setPublicKey] = useState( + fromByteArray(config.security?.publicKey ?? new Uint8Array(0)) + ); + + const onSubmit = (data: SecurityValidation) => { + setWorkingConfig( + new Protobuf.Config.Config({ + payloadVariant: { + case: "security", + value: { + ...data, + adminKey: toByteArray(adminKey), + privateKey: toByteArray(privateKey), + publicKey: toByteArray(publicKey), + } + }, + }) + ) }; return ( - onSubmit={onSubmit} + defaultValues={{ + ...config.security, + adminKey: adminKey, + privateKey: privateKey, + publicKey: publicKey + }} fieldGroups={[ { label: "Security Settings", @@ -77,4 +112,4 @@ export const Security = (): JSX.Element => { ]} /> ) -}; \ No newline at end of file +}; From 6d3bf39b76542e61edad4f6e9c650f1e99016baa Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 18:06:27 +0200 Subject: [PATCH 08/14] Updated @buf/meshtastic_protobufs.bufbuild_es to lastest --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index b49b2041..5c260975 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "devDependencies": { "@biomejs/biome": "^1.8.2", - "@buf/meshtastic_protobufs.bufbuild_es": "2.0.0-00000000000000-aaea594f36a5.2", + "@buf/meshtastic_protobufs.bufbuild_es": "2.0.0-20240820152623-fac6975bbc78.2", "@types/chrome": "^0.0.263", "@types/node": "^20.14.9", "@types/react": "^18.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6bb4dad7..605247d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -130,8 +130,8 @@ importers: specifier: ^1.8.2 version: 1.8.2 '@buf/meshtastic_protobufs.bufbuild_es': - specifier: 2.0.0-00000000000000-aaea594f36a5.2 - version: 2.0.0-00000000000000-aaea594f36a5.2(@bufbuild/protobuf@1.10.0) + specifier: 2.0.0-20240820152623-fac6975bbc78.2 + version: 2.0.0-20240820152623-fac6975bbc78.2(@bufbuild/protobuf@1.10.0) '@types/chrome': specifier: ^0.0.263 version: 0.0.263 @@ -354,8 +354,8 @@ packages: cpu: [x64] os: [win32] - '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-00000000000000-aaea594f36a5.2': - resolution: {tarball: https://buf.build/gen/npm/v1/@buf/meshtastic_protobufs.bufbuild_es/-/meshtastic_protobufs.bufbuild_es-2.0.0-00000000000000-aaea594f36a5.2.tgz} + '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-20240820152623-fac6975bbc78.2': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/meshtastic_protobufs.bufbuild_es/-/meshtastic_protobufs.bufbuild_es-2.0.0-20240820152623-fac6975bbc78.2.tgz} peerDependencies: '@bufbuild/protobuf': ^2.0.0 @@ -3306,7 +3306,7 @@ snapshots: '@biomejs/cli-win32-x64@1.8.2': optional: true - '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-00000000000000-aaea594f36a5.2(@bufbuild/protobuf@1.10.0)': + '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-20240820152623-fac6975bbc78.2(@bufbuild/protobuf@1.10.0)': dependencies: '@bufbuild/protobuf': 1.10.0 From f0eae444c7ca2391c3b291cd12b496729276c0c6 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 18:10:39 +0200 Subject: [PATCH 09/14] Update descriptions in Security --- src/components/PageComponents/Config/Security.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index 8553cf33..17ec99fa 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -45,7 +45,7 @@ export const Security = (): JSX.Element => { fieldGroups={[ { label: "Security Settings", - description: "Settings for the Security module", + description: "Settings for the Security configuration", fields: [ { type: "text", @@ -69,13 +69,13 @@ export const Security = (): JSX.Element => { type: "toggle", name: "adminChannelEnabled", label: "Admin Channel", - description: "Enable 'admin' channel", + description: "Allow incoming device control over the insecure legacy admin channel", }, { type: "toggle", name: "isManaged", label: "Is Managed", - description: "Enable if you want to manage this node from other nodes", + description: 'If true, device is considered to be "managed" by a mesh administrator via admin messages', }, { type: "text", @@ -93,19 +93,19 @@ export const Security = (): JSX.Element => { type: "toggle", name: "bluetoothLoggingEnabled", label: "Bluetooth Logging", - description: "Enable Bluetooth Logging", + description: "Enables device (serial style logs) over Bluetooth", }, { type: "toggle", name: "debugLogApiEnabled", label: "Debug Log API", - description: "Enable Log API", + description: "Output live debug logging over serial", }, { type: "toggle", name: "serialEnabled", label: "Serial", - description: "Enable Serial" + description: "Serial Console over the Stream API" } ], }, From af51659e71b6ce43856db93e7fcbc906289b7abe Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 18:50:19 +0200 Subject: [PATCH 10/14] Add always to disabled by in dynamics form --- src/components/Form/DynamicForm.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Form/DynamicForm.tsx b/src/components/Form/DynamicForm.tsx index 61c4c0e7..9affc0c7 100644 --- a/src/components/Form/DynamicForm.tsx +++ b/src/components/Form/DynamicForm.tsx @@ -16,7 +16,7 @@ import { } from "react-hook-form"; interface DisabledBy { - fieldName: Path; + fieldName: Path | "always"; selector?: number; invert?: boolean; } @@ -66,7 +66,9 @@ export function DynamicForm({ if (!disabledBy) return false; return disabledBy.some((field) => { + if (field.fieldName === "always") return true const value = getValues(field.fieldName); + if (value === "always") return true; if (typeof value === "boolean") return field.invert ? value : !value; if (typeof value === "number") return field.invert From 65247c4f351bb7f41268298d8b3ac5b84acef0ec Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Tue, 20 Aug 2024 18:51:02 +0200 Subject: [PATCH 11/14] Update Security tab --- src/components/PageComponents/Config/Security.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index 17ec99fa..ea3b2f17 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -47,18 +47,19 @@ export const Security = (): JSX.Element => { label: "Security Settings", description: "Settings for the Security configuration", fields: [ - { - type: "text", - name: "publicKey", - label: "Public Key", - description: "Sent out to other nodes on the mesh to allow them to compute a shared secret key", - }, { type: "text", name: "privateKey", label: "Private Key", description: "Used to create a shared key with a remote device", }, + { + type: "text", + name: "publicKey", + label: "Public Key", + description: "Sent out to other nodes on the mesh to allow them to compute a shared secret key", + disabledBy: [ { fieldName: "always" } ] + }, ], }, { From 8bb0a9674479b9dda9d023fca416f1c547d11007 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Wed, 21 Aug 2024 13:13:42 +0200 Subject: [PATCH 12/14] Downgraded @buf/meshtastic_protobufs.bufbuild_es from 2.0 to 1.10 --- package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 5c260975..b65359d9 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ }, "devDependencies": { "@biomejs/biome": "^1.8.2", - "@buf/meshtastic_protobufs.bufbuild_es": "2.0.0-20240820152623-fac6975bbc78.2", + "@buf/meshtastic_protobufs.bufbuild_es": "1.10.0-20240820152623-fac6975bbc78.1", "@types/chrome": "^0.0.263", "@types/node": "^20.14.9", "@types/react": "^18.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 605247d7..62578557 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -130,8 +130,8 @@ importers: specifier: ^1.8.2 version: 1.8.2 '@buf/meshtastic_protobufs.bufbuild_es': - specifier: 2.0.0-20240820152623-fac6975bbc78.2 - version: 2.0.0-20240820152623-fac6975bbc78.2(@bufbuild/protobuf@1.10.0) + specifier: 1.10.0-20240820152623-fac6975bbc78.1 + version: 1.10.0-20240820152623-fac6975bbc78.1(@bufbuild/protobuf@1.10.0) '@types/chrome': specifier: ^0.0.263 version: 0.0.263 @@ -354,10 +354,10 @@ packages: cpu: [x64] os: [win32] - '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-20240820152623-fac6975bbc78.2': - resolution: {tarball: https://buf.build/gen/npm/v1/@buf/meshtastic_protobufs.bufbuild_es/-/meshtastic_protobufs.bufbuild_es-2.0.0-20240820152623-fac6975bbc78.2.tgz} + '@buf/meshtastic_protobufs.bufbuild_es@1.10.0-20240820152623-fac6975bbc78.1': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/meshtastic_protobufs.bufbuild_es/-/meshtastic_protobufs.bufbuild_es-1.10.0-20240820152623-fac6975bbc78.1.tgz} peerDependencies: - '@bufbuild/protobuf': ^2.0.0 + '@bufbuild/protobuf': ^1.10.0 '@bufbuild/protobuf@1.10.0': resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==} @@ -3306,7 +3306,7 @@ snapshots: '@biomejs/cli-win32-x64@1.8.2': optional: true - '@buf/meshtastic_protobufs.bufbuild_es@2.0.0-20240820152623-fac6975bbc78.2(@bufbuild/protobuf@1.10.0)': + '@buf/meshtastic_protobufs.bufbuild_es@1.10.0-20240820152623-fac6975bbc78.1(@bufbuild/protobuf@1.10.0)': dependencies: '@bufbuild/protobuf': 1.10.0 From cf423620c4e7a8da32d1b1484f8122fc07593172 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Wed, 21 Aug 2024 17:41:24 +0200 Subject: [PATCH 13/14] Error & formating fixes --- src/components/Form/DynamicForm.tsx | 2 +- .../PageComponents/Config/Security.tsx | 40 ++++++++++--------- src/components/Sidebar.tsx | 2 +- src/pages/Map.tsx | 8 ++-- src/validation/config/bluetooth.ts | 6 ++- src/validation/config/lora.ts | 3 +- src/validation/config/power.ts | 3 +- src/validation/config/security.ts | 8 +++- src/validation/moduleConfig/storeForward.ts | 5 ++- 9 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/components/Form/DynamicForm.tsx b/src/components/Form/DynamicForm.tsx index 9affc0c7..58bf241e 100644 --- a/src/components/Form/DynamicForm.tsx +++ b/src/components/Form/DynamicForm.tsx @@ -66,7 +66,7 @@ export function DynamicForm({ if (!disabledBy) return false; return disabledBy.some((field) => { - if (field.fieldName === "always") return true + if (field.fieldName === "always") return true; const value = getValues(field.fieldName); if (value === "always") return true; if (typeof value === "boolean") return field.invert ? value : !value; diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index ea3b2f17..2834574c 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -1,5 +1,5 @@ -import type { SecurityValidation } from "@app/validation/config/security.js" import { DynamicForm } from "@app/components/Form/DynamicForm.js"; +import type { SecurityValidation } from "@app/validation/config/security.js"; import { useDevice } from "@core/stores/deviceStore.js"; import { Protobuf } from "@meshtastic/js"; import { fromByteArray, toByteArray } from "base64-js"; @@ -9,13 +9,13 @@ export const Security = (): JSX.Element => { const { config, nodes, hardware, setWorkingConfig } = useDevice(); const [adminKey, setAdminKey] = useState( - fromByteArray(config.security?.adminKey ?? new Uint8Array(0)) + fromByteArray(config.security?.adminKey ?? new Uint8Array(0)), ); const [privateKey, setPrivateKey] = useState( - fromByteArray(config.security?.privateKey ?? new Uint8Array(0)) + fromByteArray(config.security?.privateKey ?? new Uint8Array(0)), ); const [publicKey, setPublicKey] = useState( - fromByteArray(config.security?.publicKey ?? new Uint8Array(0)) + fromByteArray(config.security?.publicKey ?? new Uint8Array(0)), ); const onSubmit = (data: SecurityValidation) => { @@ -28,10 +28,10 @@ export const Security = (): JSX.Element => { adminKey: toByteArray(adminKey), privateKey: toByteArray(privateKey), publicKey: toByteArray(publicKey), - } + }, }, - }) - ) + }), + ); }; return ( @@ -40,7 +40,7 @@ export const Security = (): JSX.Element => { ...config.security, adminKey: adminKey, privateKey: privateKey, - publicKey: publicKey + publicKey: publicKey, }} fieldGroups={[ { @@ -57,8 +57,9 @@ export const Security = (): JSX.Element => { type: "text", name: "publicKey", label: "Public Key", - description: "Sent out to other nodes on the mesh to allow them to compute a shared secret key", - disabledBy: [ { fieldName: "always" } ] + description: + "Sent out to other nodes on the mesh to allow them to compute a shared secret key", + disabledBy: [{ fieldName: "always" }], }, ], }, @@ -70,20 +71,23 @@ export const Security = (): JSX.Element => { type: "toggle", name: "adminChannelEnabled", label: "Admin Channel", - description: "Allow incoming device control over the insecure legacy admin channel", + description: + "Allow incoming device control over the insecure legacy admin channel", }, { type: "toggle", name: "isManaged", label: "Is Managed", - description: 'If true, device is considered to be "managed" by a mesh administrator via admin messages', + description: + 'If true, device is considered to be "managed" by a mesh administrator via admin messages', }, { type: "text", name: "adminKey", label: "Admin Key", - description: "The public key authorized to send admin messages to this node", - } + description: + "The public key authorized to send admin messages to this node", + }, ], }, { @@ -106,11 +110,11 @@ export const Security = (): JSX.Element => { type: "toggle", name: "serialEnabled", label: "Serial", - description: "Serial Console over the Stream API" - } + description: "Serial Console over the Stream API", + }, ], }, ]} - /> - ) + /> + ); }; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 96d820bb..116b6647 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -85,7 +85,7 @@ export const Sidebar = ({ children }: SidebarProps): JSX.Element => {
- {myNode?.deviceMetrics?.voltage.toPrecision(3) ?? "UNK"} volts + {myNode?.deviceMetrics?.voltage?.toPrecision(3) ?? "UNK"} volts
diff --git a/src/pages/Map.tsx b/src/pages/Map.tsx index 8c86480e..53df0cd4 100644 --- a/src/pages/Map.tsx +++ b/src/pages/Map.tsx @@ -144,8 +144,8 @@ export const MapPage = (): JSX.Element => { {waypoints.map((wp) => (
@@ -163,8 +163,8 @@ export const MapPage = (): JSX.Element => { return ( { diff --git a/src/validation/config/bluetooth.ts b/src/validation/config/bluetooth.ts index 65a0d0be..efaca6e9 100644 --- a/src/validation/config/bluetooth.ts +++ b/src/validation/config/bluetooth.ts @@ -3,7 +3,11 @@ import { Protobuf } from "@meshtastic/js"; import { IsBoolean, IsEnum, IsInt } from "class-validator"; export class BluetoothValidation - implements Omit + implements + Omit< + Protobuf.Config.Config_BluetoothConfig, + keyof Message | "deviceLoggingEnabled" + > { @IsBoolean() enabled: boolean; diff --git a/src/validation/config/lora.ts b/src/validation/config/lora.ts index 291a42d0..f5ef49d6 100644 --- a/src/validation/config/lora.ts +++ b/src/validation/config/lora.ts @@ -3,7 +3,8 @@ import { Protobuf } from "@meshtastic/js"; import { IsArray, IsBoolean, IsEnum, IsInt, Max, Min } from "class-validator"; export class LoRaValidation - implements Omit + implements + Omit { @IsBoolean() usePreset: boolean; diff --git a/src/validation/config/power.ts b/src/validation/config/power.ts index 3f3d097a..67bd1cd0 100644 --- a/src/validation/config/power.ts +++ b/src/validation/config/power.ts @@ -3,7 +3,8 @@ import type { Protobuf } from "@meshtastic/js"; import { IsBoolean, IsInt, IsNumber, Max, Min } from "class-validator"; export class PowerValidation - implements Omit + implements + Omit { @IsBoolean() isPowerSaving: boolean; diff --git a/src/validation/config/security.ts b/src/validation/config/security.ts index 4d501537..d1a35808 100644 --- a/src/validation/config/security.ts +++ b/src/validation/config/security.ts @@ -3,7 +3,11 @@ import type { Protobuf } from "@meshtastic/js"; import { IsBoolean, IsString } from "class-validator"; export class SecurityValidation - implements Omit + implements + Omit< + Protobuf.Config.Config_SecurityConfig, + keyof Message | "adminKey" | "privateKey" | "publicKey" + > { @IsBoolean() adminChannelEnabled: boolean; @@ -28,4 +32,4 @@ export class SecurityValidation @IsBoolean() serialEnabled: boolean; -} \ No newline at end of file +} diff --git a/src/validation/moduleConfig/storeForward.ts b/src/validation/moduleConfig/storeForward.ts index 82d9f4c2..773a2539 100644 --- a/src/validation/moduleConfig/storeForward.ts +++ b/src/validation/moduleConfig/storeForward.ts @@ -4,7 +4,10 @@ import { IsBoolean, IsInt } from "class-validator"; export class StoreForwardValidation implements - Omit + Omit< + Protobuf.ModuleConfig.ModuleConfig_StoreForwardConfig, + keyof Message | "isServer" + > { @IsBoolean() enabled: boolean; From 66fb3005758f565c89c5e9477da9f176d08b9ba1 Mon Sep 17 00:00:00 2001 From: Tilen Komel Date: Wed, 21 Aug 2024 18:52:03 +0200 Subject: [PATCH 14/14] Moved prop. from Device to Security & Hide PKI Eye --- .../PageComponents/Config/Device.tsx | 19 --------- .../PageComponents/Config/Security.tsx | 42 ++++++++++++++----- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/components/PageComponents/Config/Device.tsx b/src/components/PageComponents/Config/Device.tsx index c0f3bfc4..ce2b5ce1 100644 --- a/src/components/PageComponents/Config/Device.tsx +++ b/src/components/PageComponents/Config/Device.tsx @@ -36,19 +36,6 @@ export const Device = (): JSX.Element => { formatEnumName: true, }, }, - { - type: "toggle", - name: "serialEnabled", - label: "Serial Output Enabled", - description: "Enable the device's serial console", - }, - { - type: "toggle", - name: "debugLogEnabled", - label: "Enabled Debug Log", - description: - "Output debugging information to the device's serial port (auto disables when serial client is connected)", - }, { type: "number", name: "buttonGpio", @@ -86,12 +73,6 @@ export const Device = (): JSX.Element => { label: "Double Tap as Button Press", description: "Treat double tap as button press", }, - { - type: "toggle", - name: "isManaged", - label: "Managed", - description: "Is this device managed by a mesh administator", - }, { type: "toggle", name: "disableTripleClick", diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index 2834574c..c9e1175c 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -3,20 +3,23 @@ import type { SecurityValidation } from "@app/validation/config/security.js"; import { useDevice } from "@core/stores/deviceStore.js"; import { Protobuf } from "@meshtastic/js"; import { fromByteArray, toByteArray } from "base64-js"; +import { Eye, EyeOff } from "lucide-react"; import { useState } from "react"; export const Security = (): JSX.Element => { const { config, nodes, hardware, setWorkingConfig } = useDevice(); - const [adminKey, setAdminKey] = useState( - fromByteArray(config.security?.adminKey ?? new Uint8Array(0)), - ); const [privateKey, setPrivateKey] = useState( fromByteArray(config.security?.privateKey ?? new Uint8Array(0)), ); + const [privateKeyVisible, setPrivateKeyVisible] = useState(false); const [publicKey, setPublicKey] = useState( fromByteArray(config.security?.publicKey ?? new Uint8Array(0)), ); + const [adminKey, setAdminKey] = useState( + fromByteArray(config.security?.adminKey ?? new Uint8Array(0)), + ); + const [adminKeyVisible, setAdminKeyVisible] = useState(false); const onSubmit = (data: SecurityValidation) => { setWorkingConfig( @@ -48,10 +51,22 @@ export const Security = (): JSX.Element => { description: "Settings for the Security configuration", fields: [ { - type: "text", + type: privateKeyVisible ? "text" : "password", name: "privateKey", label: "Private Key", description: "Used to create a shared key with a remote device", + disabledBy: [ + { + fieldName: "adminChannelEnabled", + invert: true, + }, + ], + properties: { + action: { + icon: privateKeyVisible ? EyeOff : Eye, + onClick: () => setPrivateKeyVisible(!privateKeyVisible), + }, + }, }, { type: "text", @@ -70,21 +85,28 @@ export const Security = (): JSX.Element => { { type: "toggle", name: "adminChannelEnabled", - label: "Admin Channel", + label: "Allow Legacy Admin", description: "Allow incoming device control over the insecure legacy admin channel", }, { type: "toggle", name: "isManaged", - label: "Is Managed", + label: "Managed", description: 'If true, device is considered to be "managed" by a mesh administrator via admin messages', }, { - type: "text", + type: adminKeyVisible ? "text" : "password", name: "adminKey", label: "Admin Key", + disabledBy: [{ fieldName: "adminChannelEnabled" }], + properties: { + action: { + icon: adminKeyVisible ? EyeOff : Eye, + onClick: () => setAdminKeyVisible(!adminKeyVisible), + }, + }, description: "The public key authorized to send admin messages to this node", }, @@ -97,19 +119,19 @@ export const Security = (): JSX.Element => { { type: "toggle", name: "bluetoothLoggingEnabled", - label: "Bluetooth Logging", + label: "Allow Bluetooth Logging", description: "Enables device (serial style logs) over Bluetooth", }, { type: "toggle", name: "debugLogApiEnabled", - label: "Debug Log API", + label: "Enable Debug Log API", description: "Output live debug logging over serial", }, { type: "toggle", name: "serialEnabled", - label: "Serial", + label: "Serial Output Enabled", description: "Serial Console over the Stream API", }, ],