diff --git a/package.json b/package.json index ea5a4169..79020d5f 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "crypto-random-string": "^5.0.0", "immer": "^10.1.1", "lucide-react": "^0.363.0", - "mapbox-gl": "npm:empty-npm-package@^1.0.0", + "mapbox-gl": "^3.6.0", "maplibre-gl": "4.1.2", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -64,7 +64,7 @@ }, "devDependencies": { "@biomejs/biome": "^1.8.2", - "@buf/meshtastic_protobufs.bufbuild_es": "1.10.0-20240820152623-fac6975bbc78.1", + "@buf/meshtastic_protobufs.bufbuild_es": "1.10.0-20240906232734-3da561588c55.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 8c520c9b..58131bb7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,8 +93,8 @@ importers: specifier: ^0.363.0 version: 0.363.0(react@18.3.1) mapbox-gl: - specifier: npm:empty-npm-package@^1.0.0 - version: empty-npm-package@1.0.0 + specifier: ^3.6.0 + version: 3.6.0 maplibre-gl: specifier: 4.1.2 version: 4.1.2 @@ -109,7 +109,7 @@ importers: version: 7.52.0(react@18.3.1) react-map-gl: specifier: 7.1.7 - version: 7.1.7(empty-npm-package@1.0.0)(maplibre-gl@4.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 7.1.7(mapbox-gl@3.6.0)(maplibre-gl@4.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-qrcode-logo: specifier: ^2.10.0 version: 2.10.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -133,8 +133,8 @@ importers: specifier: ^1.8.2 version: 1.8.2 '@buf/meshtastic_protobufs.bufbuild_es': - specifier: 1.10.0-20240820152623-fac6975bbc78.1 - version: 1.10.0-20240820152623-fac6975bbc78.1(@bufbuild/protobuf@1.10.0) + specifier: 1.10.0-20240906232734-3da561588c55.1 + version: 1.10.0-20240906232734-3da561588c55.1(@bufbuild/protobuf@1.10.0) '@types/chrome': specifier: ^0.0.263 version: 0.0.263 @@ -357,8 +357,8 @@ packages: cpu: [x64] os: [win32] - '@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} + '@buf/meshtastic_protobufs.bufbuild_es@1.10.0-20240906232734-3da561588c55.1': + resolution: {tarball: https://buf.build/gen/npm/v1/@buf/meshtastic_protobufs.bufbuild_es/-/meshtastic_protobufs.bufbuild_es-1.10.0-20240906232734-3da561588c55.1.tgz} peerDependencies: '@bufbuild/protobuf': ^1.10.0 @@ -560,6 +560,9 @@ packages: resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==} engines: {node: '>= 0.6'} + '@mapbox/mapbox-gl-supported@3.0.0': + resolution: {integrity: sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==} + '@mapbox/point-geometry@0.1.0': resolution: {integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==} @@ -1833,6 +1836,9 @@ packages: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} + cheap-ruler@4.0.0: + resolution: {integrity: sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -1918,6 +1924,9 @@ packages: resolution: {integrity: sha512-KWjTXWwxFd6a94m5CdRGW/t82Tr8DoBc9dNnPCAbFI1EBweN6v1tv8y4Y1m7ndkp/nkIBRxUxAzpaBnR2k3bcQ==} engines: {node: '>=14.16'} + csscolorparser@1.0.3: + resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -1985,6 +1994,9 @@ packages: earcut@2.2.4: resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + earcut@3.0.0: + resolution: {integrity: sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1997,9 +2009,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - empty-npm-package@1.0.0: - resolution: {integrity: sha512-q4Mq/+XO7UNDdMiPpR/LIBIW1Zl4V0Z6UT9aKGqIAnBCtCb3lvZJM1KbDbdzdC8fKflwflModfjR29Nt0EpcwA==} - end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -2042,6 +2051,9 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -2084,6 +2096,9 @@ packages: geojson-vt@3.2.1: resolution: {integrity: sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==} + geojson-vt@4.0.2: + resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2131,6 +2146,9 @@ packages: gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + grid-index@1.1.0: + resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==} + gzipper@7.2.0: resolution: {integrity: sha512-qwYQr7GWBXIm9Cdzud+tyM/s9N+QFzGDZoF9YR8RYJbDKOYowzjMDPEinFtm78EQeeYMC/FJW2FXY0bHkyUgsA==} engines: {node: '>=14'} @@ -2371,6 +2389,9 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 + mapbox-gl@3.6.0: + resolution: {integrity: sha512-xjYHHIJDh6haYcKY+/9jh1eywwYfIOWCgT5Fowj4JriZexx/oOtg2S7BQDMZtpFyg9IN4VLCysmUWxY0pFNRWA==} + maplibre-gl@4.1.2: resolution: {integrity: sha512-98T+3BesL4w/N39q/rgs9q6HzHLG6pgbS9UaTqg6fMISfzy2WGKokjK205ENFDDmEljj54/LTfdXgqg2XfYU4A==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} @@ -2585,6 +2606,9 @@ packages: quickselect@2.0.0: resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} + quickselect@3.0.0: + resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==} + quotemeta@0.0.0: resolution: {integrity: sha512-1XGObUh7RN5b58vKuAsrlfqT+Rc4vmw8N4pP9gFCq1GFlTdV0Ex/D2Ro1Drvrqj++HPi3ig0Np17XPslELeMRA==} @@ -2758,6 +2782,10 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + serialize-to-js@3.1.2: + resolution: {integrity: sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==} + engines: {node: '>=4.0.0'} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2917,6 +2945,9 @@ packages: tinyqueue@2.0.3: resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==} + tinyqueue@3.0.0: + resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -2946,6 +2977,9 @@ packages: turf-jsts@1.2.3: resolution: {integrity: sha512-Ja03QIJlPuHt4IQ2FfGex4F4JAr8m3jpaHbFbQrgwr7s7L6U8ocrHiF3J1+wf9jzhGKxvDeaCAnGDot8OjGFyA==} + tweakpane@4.0.4: + resolution: {integrity: sha512-RkWD54zDlEbnN01wQPk0ANHGbdCvlJx/E8A1QxhTfCbX+ROWos1Ws2MnhOm39aUGMOh+36TjUwpDmLfmwTr1Fg==} + type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} @@ -3316,7 +3350,7 @@ snapshots: '@biomejs/cli-win32-x64@1.8.2': optional: true - '@buf/meshtastic_protobufs.bufbuild_es@1.10.0-20240820152623-fac6975bbc78.1(@bufbuild/protobuf@1.10.0)': + '@buf/meshtastic_protobufs.bufbuild_es@1.10.0-20240906232734-3da561588c55.1(@bufbuild/protobuf@1.10.0)': dependencies: '@bufbuild/protobuf': 1.10.0 @@ -3455,6 +3489,8 @@ snapshots: '@mapbox/jsonlint-lines-primitives@2.0.2': {} + '@mapbox/mapbox-gl-supported@3.0.0': {} + '@mapbox/point-geometry@0.1.0': {} '@mapbox/tiny-sdf@2.0.6': {} @@ -5237,6 +5273,8 @@ snapshots: escape-string-regexp: 1.0.5 supports-color: 5.5.0 + cheap-ruler@4.0.0: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -5324,6 +5362,8 @@ snapshots: dependencies: type-fest: 2.19.0 + csscolorparser@1.0.3: {} + cssesc@3.0.0: {} csstype@3.1.3: {} @@ -5403,6 +5443,8 @@ snapshots: earcut@2.2.4: {} + earcut@3.0.0: {} + eastasianwidth@0.2.0: {} electron-to-chromium@1.4.812: {} @@ -5411,8 +5453,6 @@ snapshots: emoji-regex@9.2.2: {} - empty-npm-package@1.0.0: {} - end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -5486,6 +5526,8 @@ snapshots: dependencies: reusify: 1.0.4 + fflate@0.8.2: {} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -5528,6 +5570,8 @@ snapshots: geojson-vt@3.2.1: {} + geojson-vt@4.0.2: {} + get-caller-file@2.0.5: {} get-intrinsic@1.2.4: @@ -5575,6 +5619,8 @@ snapshots: dependencies: get-intrinsic: 1.2.4 + grid-index@1.1.0: {} + gzipper@7.2.0: dependencies: '@gfx/zopfli': 1.0.15 @@ -5770,6 +5816,36 @@ snapshots: dependencies: react: 18.3.1 + mapbox-gl@3.6.0: + dependencies: + '@mapbox/jsonlint-lines-primitives': 2.0.2 + '@mapbox/mapbox-gl-supported': 3.0.0 + '@mapbox/point-geometry': 0.1.0 + '@mapbox/tiny-sdf': 2.0.6 + '@mapbox/unitbezier': 0.0.1 + '@mapbox/vector-tile': 1.3.1 + '@mapbox/whoots-js': 3.1.0 + '@types/geojson': 7946.0.14 + '@types/mapbox__vector-tile': 1.3.4 + cheap-ruler: 4.0.0 + csscolorparser: 1.0.3 + earcut: 3.0.0 + fflate: 0.8.2 + geojson-vt: 4.0.2 + gl-matrix: 3.4.3 + grid-index: 1.1.0 + kdbush: 4.0.2 + murmurhash-js: 1.0.0 + pbf: 3.2.1 + potpack: 2.0.0 + quickselect: 3.0.0 + rw: 1.3.3 + serialize-to-js: 3.1.2 + supercluster: 8.0.1 + tinyqueue: 3.0.0 + tweakpane: 4.0.4 + vt-pbf: 3.1.3 + maplibre-gl@4.1.2: dependencies: '@mapbox/geojson-rewind': 0.5.2 @@ -5979,6 +6055,8 @@ snapshots: quickselect@2.0.0: {} + quickselect@3.0.0: {} + quotemeta@0.0.0: {} rbush@2.0.2: @@ -6001,14 +6079,14 @@ snapshots: react-is@16.13.1: {} - react-map-gl@7.1.7(empty-npm-package@1.0.0)(maplibre-gl@4.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-map-gl@7.1.7(mapbox-gl@3.6.0)(maplibre-gl@4.1.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@maplibre/maplibre-gl-style-spec': 19.3.3 '@types/mapbox-gl': 3.1.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - mapbox-gl: empty-npm-package@1.0.0 + mapbox-gl: 3.6.0 maplibre-gl: 4.1.2 react-qrcode-logo@2.10.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -6169,6 +6247,8 @@ snapshots: semver@6.3.1: {} + serialize-to-js@3.1.2: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -6374,6 +6454,8 @@ snapshots: tinyqueue@2.0.3: {} + tinyqueue@3.0.0: {} + to-fast-properties@2.0.0: {} to-regex-range@5.0.1: @@ -6396,6 +6478,8 @@ snapshots: turf-jsts@1.2.3: {} + tweakpane@4.0.4: {} + type-fest@2.19.0: {} typescript@5.5.2: {} diff --git a/src/components/PageComponents/Config/LoRa.tsx b/src/components/PageComponents/Config/LoRa.tsx index 8556f880..79e7b810 100644 --- a/src/components/PageComponents/Config/LoRa.tsx +++ b/src/components/PageComponents/Config/LoRa.tsx @@ -56,6 +56,13 @@ export const LoRa = (): JSX.Element => { label: "Ignore MQTT", description: "Don't forward MQTT messages over the mesh", }, + { + type: "toggle", + name: "configOkToMqtt", + label: "OK to MQTT", + description: + "When set to true, this configuration indicates that the user approves the packet to be uploaded to MQTT. If set to false, remote nodes are requested not to forward packets to MQTT", + }, ], }, { diff --git a/src/components/PageComponents/Config/Security.tsx b/src/components/PageComponents/Config/Security.tsx index bb0a24e0..9848f491 100644 --- a/src/components/PageComponents/Config/Security.tsx +++ b/src/components/PageComponents/Config/Security.tsx @@ -27,7 +27,7 @@ export const Security = (): JSX.Element => { fromByteArray(config.security?.publicKey ?? new Uint8Array(0)), ); const [adminKey, setAdminKey] = useState( - fromByteArray(config.security?.adminKey ?? new Uint8Array(0)), + fromByteArray(config.security?.adminKey[0] ?? new Uint8Array(0)), ); const [adminKeyValidationText, setAdminKeyValidationText] = useState(); @@ -42,7 +42,7 @@ export const Security = (): JSX.Element => { case: "security", value: { ...data, - adminKey: toByteArray(adminKey), + adminKey: [toByteArray(adminKey)], privateKey: toByteArray(privateKey), publicKey: toByteArray(publicKey), }, @@ -129,8 +129,6 @@ export const Security = (): JSX.Element => { publicKey: publicKey, adminChannelEnabled: config.security?.adminChannelEnabled ?? false, isManaged: config.security?.isManaged ?? false, - bluetoothLoggingEnabled: - config.security?.bluetoothLoggingEnabled ?? false, debugLogApiEnabled: config.security?.debugLogApiEnabled ?? false, serialEnabled: config.security?.serialEnabled ?? false, }, @@ -212,18 +210,12 @@ export const Security = (): JSX.Element => { label: "Logging Settings", description: "Settings for Logging", fields: [ - { - type: "toggle", - name: "bluetoothLoggingEnabled", - label: "Allow Bluetooth Logging", - description: - "Enables device (serial style logs) over Bluetooth", - }, { type: "toggle", name: "debugLogApiEnabled", label: "Enable Debug Log API", - description: "Output live debug logging over serial", + description: + "Output live debug logging over serial, view and export position-redacted device logs over Bluetooth", }, { type: "toggle", diff --git a/src/components/PageLayout.tsx b/src/components/PageLayout.tsx index 1a2e4dd7..f6698b97 100644 --- a/src/components/PageLayout.tsx +++ b/src/components/PageLayout.tsx @@ -8,6 +8,7 @@ export interface PageLayoutProps { children: React.ReactNode; actions?: { icon: LucideIcon; + iconClasses?: string; onClick: () => void; }[]; } @@ -39,7 +40,7 @@ export const PageLayout = ({ className="transition-all hover:text-accent" onClick={action.onClick} > - + ))} diff --git a/src/pages/Messages.tsx b/src/pages/Messages.tsx index c25f24a7..c308743d 100644 --- a/src/pages/Messages.tsx +++ b/src/pages/Messages.tsx @@ -8,7 +8,7 @@ import { useDevice } from "@core/stores/deviceStore.js"; import { Hashicon } from "@emeraldpay/hashicon-react"; import { Protobuf, Types } from "@meshtastic/js"; import { getChannelName } from "@pages/Channels.js"; -import { HashIcon, WaypointsIcon } from "lucide-react"; +import { HashIcon, LockIcon, LockOpenIcon, WaypointsIcon } from "lucide-react"; import { useState } from "react"; export const MessagesPage = (): JSX.Element => { @@ -79,6 +79,23 @@ export const MessagesPage = (): JSX.Element => { actions={ chatType === "direct" ? [ + { + icon: nodes.get(activeChat)?.user?.publicKey.length + ? LockIcon + : LockOpenIcon, + iconClasses: nodes.get(activeChat)?.user?.publicKey.length + ? "text-green-600" + : "text-yellow-300", + async onClick() { + const targetNode = nodes.get(activeChat)?.num; + if (targetNode === undefined) return; + toast({ + title: nodes.get(activeChat)?.user?.publicKey.length + ? "Chat is using PKI encryption." + : "Chat is using PSK encryption.", + }); + }, + }, { icon: WaypointsIcon, async onClick() { diff --git a/src/pages/Nodes.tsx b/src/pages/Nodes.tsx index c7682f59..10c51f19 100644 --- a/src/pages/Nodes.tsx +++ b/src/pages/Nodes.tsx @@ -8,7 +8,7 @@ import { TimeAgo } from "@components/generic/Table/tmp/TimeAgo.js"; import { useDevice } from "@core/stores/deviceStore.js"; import { Hashicon } from "@emeraldpay/hashicon-react"; import { Protobuf } from "@meshtastic/js"; -import { TrashIcon } from "lucide-react"; +import { LockIcon, LockOpenIcon, TrashIcon } from "lucide-react"; import { Fragment } from "react"; import { base16 } from "rfc4648"; @@ -38,6 +38,7 @@ export const NodesPage = (): JSX.Element => { { title: "MAC Address", type: "normal", sortable: true }, { title: "Last Heard", type: "normal", sortable: true }, { title: "SNR", type: "normal", sortable: true }, + { title: "Encryption", type: "normal", sortable: false }, { title: "Connection", type: "normal", sortable: true }, { title: "Remove", type: "normal", sortable: false }, ]} @@ -73,6 +74,13 @@ export const NodesPage = (): JSX.Element => { {Math.min(Math.max((node.snr + 10) * 5, 0), 100)}%/ {(node.snr + 10) * 5}raw , + + {node.user?.publicKey && node.user?.publicKey.length > 0 ? ( + + ) : ( + + )} + , {node.lastHeard !== 0 ? node.viaMqtt === false && node.hopsAway === 0 diff --git a/src/validation/config/lora.ts b/src/validation/config/lora.ts index f5ef49d6..e8ff5cef 100644 --- a/src/validation/config/lora.ts +++ b/src/validation/config/lora.ts @@ -60,4 +60,7 @@ export class LoRaValidation @IsBoolean() ignoreMqtt: boolean; + + @IsBoolean() + configOkToMqtt: boolean; }