From c418959e5d68d8ff507afc61de011a6f299b4c80 Mon Sep 17 00:00:00 2001 From: yellowcooln Date: Fri, 6 Mar 2026 12:35:39 -0500 Subject: [PATCH] Use patch-package file for meshcore-decoder Docker compatibility patch --- Dockerfile | 68 +++---------------- README.md | 1 + .../@michaelhart+meshcore-decoder+0.2.7.patch | 58 ++++++++++++++++ 3 files changed, 67 insertions(+), 60 deletions(-) create mode 100644 patches/@michaelhart+meshcore-decoder+0.2.7.patch diff --git a/Dockerfile b/Dockerfile index 9c083e2..3fb65db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -71,70 +71,18 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* \ && mkdir -p /data -# Install meshcore-decoder CLI and patch ESM compatibility for Node 18 runtime. +# Install meshcore-decoder CLI. RUN mkdir -p /opt/letsmesh-decoder \ && cd /opt/letsmesh-decoder \ && npm init -y >/dev/null 2>&1 \ - && npm install --omit=dev @michaelhart/meshcore-decoder@0.2.7 \ - && python - <<'PY' -from pathlib import Path + && npm install --omit=dev @michaelhart/meshcore-decoder@0.2.7 patch-package -path = Path( - "/opt/letsmesh-decoder/node_modules/@michaelhart/meshcore-decoder/" - "dist/crypto/ed25519-verifier.js" -) -content = path.read_text(encoding="utf-8") - -old_import = 'const ed25519 = __importStar(require("@noble/ed25519"));' -new_import = """let _ed25519 = null; -async function getEd25519() { - if (_ed25519) { - return _ed25519; - } - const mod = await import("@noble/ed25519"); - _ed25519 = mod.default ? mod.default : mod; - try { - _ed25519.etc.sha512Async = sha512Hash; - } - catch (error) { - console.debug("Could not set async SHA-512:", error); - } - try { - _ed25519.etc.sha512Sync = sha512HashSync; - } - catch (error) { - console.debug("Could not set up synchronous SHA-512:", error); - } - return _ed25519; -}""" -if old_import not in content: - raise RuntimeError("meshcore-decoder patch failed: import line not found") -content = content.replace(old_import, new_import, 1) - -old_setup = """// Set up SHA-512 for @noble/ed25519 -ed25519.etc.sha512Async = sha512Hash; -// Always set up sync version - @noble/ed25519 requires it -// It will throw in browser environments, which @noble/ed25519 can handle -try { - ed25519.etc.sha512Sync = sha512HashSync; -} -catch (error) { - console.debug('Could not set up synchronous SHA-512:', error); -} -""" -if old_setup not in content: - raise RuntimeError("meshcore-decoder patch failed: sha512 setup block not found") -content = content.replace(old_setup, "", 1) - -old_verify = " return await ed25519.verify(signature, message, publicKey);" -new_verify = """ const ed25519 = await getEd25519(); - return await ed25519.verify(signature, message, publicKey);""" -if old_verify not in content: - raise RuntimeError("meshcore-decoder patch failed: verify line not found") -content = content.replace(old_verify, new_verify, 1) - -path.write_text(content, encoding="utf-8") -PY +# Apply maintained meshcore-decoder compatibility patch. +COPY patches/@michaelhart+meshcore-decoder+0.2.7.patch /opt/letsmesh-decoder/patches/@michaelhart+meshcore-decoder+0.2.7.patch +RUN cd /opt/letsmesh-decoder \ + && npx patch-package --error-on-fail \ + && npm uninstall patch-package \ + && npm prune --omit=dev RUN ln -s /opt/letsmesh-decoder/node_modules/.bin/meshcore-decoder /usr/local/bin/meshcore-decoder # Copy virtual environment from builder diff --git a/README.md b/README.md index c604331..6f9615b 100644 --- a/README.md +++ b/README.md @@ -329,6 +329,7 @@ Normalization behavior: - Packets without decryptable message text are kept as informational `letsmesh_packet` events and are not shown in the messages feed; when decode succeeds the decoded JSON is attached to those packet log events. - When decoder output includes a human sender (`payload.decoded.decrypted.sender`), message text is normalized to `Name: Message` before storage; receiver/observer names are never used as sender fallback. - The collector keeps built-in keys for `Public` and `#test`, and merges any additional keys from `COLLECTOR_LETSMESH_DECODER_KEYS`. +- Docker runtime installs `@michaelhart/meshcore-decoder@0.2.7` and applies `patches/@michaelhart+meshcore-decoder+0.2.7.patch` via `patch-package` for Node compatibility. ### Webhooks diff --git a/patches/@michaelhart+meshcore-decoder+0.2.7.patch b/patches/@michaelhart+meshcore-decoder+0.2.7.patch new file mode 100644 index 0000000..4b0a779 --- /dev/null +++ b/patches/@michaelhart+meshcore-decoder+0.2.7.patch @@ -0,0 +1,58 @@ +diff --git a/node_modules/@michaelhart/meshcore-decoder/dist/crypto/ed25519-verifier.js b/node_modules/@michaelhart/meshcore-decoder/dist/crypto/ed25519-verifier.js +index d33ffd6..8d040d0 100644 +--- a/node_modules/@michaelhart/meshcore-decoder/dist/crypto/ed25519-verifier.js ++++ b/node_modules/@michaelhart/meshcore-decoder/dist/crypto/ed25519-verifier.js +@@ -36,7 +36,27 @@ var __importStar = (this && this.__importStar) || (function () { + })(); + Object.defineProperty(exports, "__esModule", { value: true }); + exports.Ed25519SignatureVerifier = void 0; +-const ed25519 = __importStar(require("@noble/ed25519")); ++let _ed25519 = null; ++async function getEd25519() { ++ if (_ed25519) { ++ return _ed25519; ++ } ++ const mod = await import("@noble/ed25519"); ++ _ed25519 = mod.default ? mod.default : mod; ++ try { ++ _ed25519.etc.sha512Async = sha512Hash; ++ } ++ catch (error) { ++ console.debug("Could not set async SHA-512:", error); ++ } ++ try { ++ _ed25519.etc.sha512Sync = sha512HashSync; ++ } ++ catch (error) { ++ console.debug("Could not set up synchronous SHA-512:", error); ++ } ++ return _ed25519; ++} + const hex_1 = require("../utils/hex"); + const orlp_ed25519_wasm_1 = require("./orlp-ed25519-wasm"); + // Cross-platform SHA-512 implementation +@@ -90,16 +110,6 @@ function sha512HashSync(data) { + throw new Error('No SHA-512 implementation available for synchronous operation'); + } + } +-// Set up SHA-512 for @noble/ed25519 +-ed25519.etc.sha512Async = sha512Hash; +-// Always set up sync version - @noble/ed25519 requires it +-// It will throw in browser environments, which @noble/ed25519 can handle +-try { +- ed25519.etc.sha512Sync = sha512HashSync; +-} +-catch (error) { +- console.debug('Could not set up synchronous SHA-512:', error); +-} + class Ed25519SignatureVerifier { + /** + * Verify an Ed25519 signature for MeshCore advertisement packets +@@ -116,6 +126,7 @@ class Ed25519SignatureVerifier { + // Construct the signed message according to MeshCore format + const message = this.constructAdvertSignedMessage(publicKeyHex, timestamp, appData); + // Verify the signature using noble-ed25519 ++ const ed25519 = await getEd25519(); + return await ed25519.verify(signature, message, publicKey); + } + catch (error) {