mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Add more warnings around radio config, stats loading, and packet decrypt (and remove accidentally committed script whoops)
This commit is contained in:
@@ -171,8 +171,9 @@ This message-layer echo/path handling is independent of raw-packet storage dedup
|
||||
│ └── vite.config.ts
|
||||
├── scripts/
|
||||
│ ├── all_quality.sh # Run all lint, format, typecheck, tests, build (parallelized)
|
||||
│ ├── publish.sh # Version bump, changelog, docker build & push
|
||||
│ └── deploy.sh # Deploy to production server
|
||||
│ ├── collect_licenses.sh # Gather third-party license attributions
|
||||
│ ├── e2e.sh # End-to-end test runner
|
||||
│ └── publish.sh # Version bump, changelog, docker build & push
|
||||
├── tests/ # Backend tests (pytest)
|
||||
├── data/ # SQLite database (runtime)
|
||||
└── pyproject.toml # Python dependencies
|
||||
|
||||
17
CHANGELOG.md
17
CHANGELOG.md
@@ -153,23 +153,6 @@ Misc: Always flood advertisements
|
||||
Misc: Better packet dupe handling
|
||||
Misc: Dead code cleanup, test improvements
|
||||
|
||||
## [1.8.0] - 2026-02-07
|
||||
|
||||
Feature: Single hop ping
|
||||
Feature: PWA viewport fixes(thanks @rgregg)
|
||||
Feature (?): No frontend distribution; build it yourself ;P
|
||||
Bugfix: Fix channel message send race condition (concurrent sends could corrupt shared radio slot)
|
||||
Bugfix: Fix TOCTOU race in radio reconnect (duplicate connections under contention)
|
||||
Bugfix: Better guarding around reconnection
|
||||
Bugfix: Duplicate websocket connection fixes
|
||||
Bugfix: Settings tab error cleanliness on tab swap
|
||||
Bugfix: Fix path traversal vuln
|
||||
UI: Swap visualizer legend ordering (yay prettier)
|
||||
Misc: Perf and locking improvements
|
||||
Misc: Always flood advertisements
|
||||
Misc: Better packet dupe handling
|
||||
Misc: Dead code cleanup, test improvements
|
||||
|
||||
## [1.7.1] - 2026-02-03
|
||||
|
||||
Feature: Clickable hyperlinks
|
||||
|
||||
@@ -518,6 +518,13 @@ async def process_raw_packet(
|
||||
payload_type = packet_info.payload_type if packet_info else None
|
||||
payload_type_name = payload_type.name if payload_type else "Unknown"
|
||||
|
||||
if packet_info is None and len(raw_bytes) > 2:
|
||||
logger.warning(
|
||||
"Failed to parse %d-byte packet (id=%d); stored undecrypted",
|
||||
len(raw_bytes),
|
||||
packet_id,
|
||||
)
|
||||
|
||||
# Log packet arrival at debug level
|
||||
path_hex = packet_info.path.hex() if packet_info and packet_info.path else ""
|
||||
logger.debug(
|
||||
|
||||
@@ -103,18 +103,36 @@ export function SettingsRadioSection({
|
||||
|
||||
const handleSave = async () => {
|
||||
setError(null);
|
||||
|
||||
const parsedLat = parseFloat(lat);
|
||||
const parsedLon = parseFloat(lon);
|
||||
const parsedTxPower = parseInt(txPower, 10);
|
||||
const parsedFreq = parseFloat(freq);
|
||||
const parsedBw = parseFloat(bw);
|
||||
const parsedSf = parseInt(sf, 10);
|
||||
const parsedCr = parseInt(cr, 10);
|
||||
|
||||
if (
|
||||
[parsedLat, parsedLon, parsedTxPower, parsedFreq, parsedBw, parsedSf, parsedCr].some(
|
||||
(v) => isNaN(v)
|
||||
)
|
||||
) {
|
||||
setError('All numeric fields must have valid values');
|
||||
return;
|
||||
}
|
||||
|
||||
setBusy(true);
|
||||
|
||||
try {
|
||||
const update: RadioConfigUpdate = {
|
||||
lat: parseFloat(lat),
|
||||
lon: parseFloat(lon),
|
||||
tx_power: parseInt(txPower, 10),
|
||||
lat: parsedLat,
|
||||
lon: parsedLon,
|
||||
tx_power: parsedTxPower,
|
||||
radio: {
|
||||
freq: parseFloat(freq),
|
||||
bw: parseFloat(bw),
|
||||
sf: parseInt(sf, 10),
|
||||
cr: parseInt(cr, 10),
|
||||
freq: parsedFreq,
|
||||
bw: parsedBw,
|
||||
sf: parsedSf,
|
||||
cr: parsedCr,
|
||||
},
|
||||
};
|
||||
await onSave(update);
|
||||
|
||||
@@ -6,10 +6,12 @@ import type { StatisticsResponse } from '../../types';
|
||||
export function SettingsStatisticsSection({ className }: { className?: string }) {
|
||||
const [stats, setStats] = useState<StatisticsResponse | null>(null);
|
||||
const [statsLoading, setStatsLoading] = useState(false);
|
||||
const [statsError, setStatsError] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
setStatsLoading(true);
|
||||
setStatsError(false);
|
||||
api.getStatistics().then(
|
||||
(data) => {
|
||||
if (!cancelled) {
|
||||
@@ -18,7 +20,10 @@ export function SettingsStatisticsSection({ className }: { className?: string })
|
||||
}
|
||||
},
|
||||
() => {
|
||||
if (!cancelled) setStatsLoading(false);
|
||||
if (!cancelled) {
|
||||
setStatsError(true);
|
||||
setStatsLoading(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
return () => {
|
||||
@@ -145,6 +150,8 @@ export function SettingsStatisticsSection({ className }: { className?: string })
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
) : statsError ? (
|
||||
<div className="py-8 text-center text-muted-foreground">Failed to load statistics.</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${YELLOW}Deploying to production server...${NC}"
|
||||
ssh jack@192.168.1.199 "\
|
||||
cd /opt/remoteterm/ && \
|
||||
sudo -u remoteterm git checkout main && \
|
||||
sudo -u remoteterm git pull && \
|
||||
cd frontend && \
|
||||
sudo -u remoteterm bash -c 'source ~/.nvm/nvm.sh && npm install && npm run build' && \
|
||||
sudo systemctl restart remoteterm && \
|
||||
sudo journalctl -u remoteterm -f"
|
||||
|
||||
echo -e "${GREEN}=== Deploy complete! ===${NC}"
|
||||
Reference in New Issue
Block a user