mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-10 10:43:01 +02: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
|
│ └── vite.config.ts
|
||||||
├── scripts/
|
├── scripts/
|
||||||
│ ├── all_quality.sh # Run all lint, format, typecheck, tests, build (parallelized)
|
│ ├── all_quality.sh # Run all lint, format, typecheck, tests, build (parallelized)
|
||||||
│ ├── publish.sh # Version bump, changelog, docker build & push
|
│ ├── collect_licenses.sh # Gather third-party license attributions
|
||||||
│ └── deploy.sh # Deploy to production server
|
│ ├── e2e.sh # End-to-end test runner
|
||||||
|
│ └── publish.sh # Version bump, changelog, docker build & push
|
||||||
├── tests/ # Backend tests (pytest)
|
├── tests/ # Backend tests (pytest)
|
||||||
├── data/ # SQLite database (runtime)
|
├── data/ # SQLite database (runtime)
|
||||||
└── pyproject.toml # Python dependencies
|
└── pyproject.toml # Python dependencies
|
||||||
|
|||||||
@@ -153,23 +153,6 @@ Misc: Always flood advertisements
|
|||||||
Misc: Better packet dupe handling
|
Misc: Better packet dupe handling
|
||||||
Misc: Dead code cleanup, test improvements
|
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
|
## [1.7.1] - 2026-02-03
|
||||||
|
|
||||||
Feature: Clickable hyperlinks
|
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 = packet_info.payload_type if packet_info else None
|
||||||
payload_type_name = payload_type.name if payload_type else "Unknown"
|
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
|
# Log packet arrival at debug level
|
||||||
path_hex = packet_info.path.hex() if packet_info and packet_info.path else ""
|
path_hex = packet_info.path.hex() if packet_info and packet_info.path else ""
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
|||||||
@@ -103,18 +103,36 @@ export function SettingsRadioSection({
|
|||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
setError(null);
|
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);
|
setBusy(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const update: RadioConfigUpdate = {
|
const update: RadioConfigUpdate = {
|
||||||
lat: parseFloat(lat),
|
lat: parsedLat,
|
||||||
lon: parseFloat(lon),
|
lon: parsedLon,
|
||||||
tx_power: parseInt(txPower, 10),
|
tx_power: parsedTxPower,
|
||||||
radio: {
|
radio: {
|
||||||
freq: parseFloat(freq),
|
freq: parsedFreq,
|
||||||
bw: parseFloat(bw),
|
bw: parsedBw,
|
||||||
sf: parseInt(sf, 10),
|
sf: parsedSf,
|
||||||
cr: parseInt(cr, 10),
|
cr: parsedCr,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
await onSave(update);
|
await onSave(update);
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import type { StatisticsResponse } from '../../types';
|
|||||||
export function SettingsStatisticsSection({ className }: { className?: string }) {
|
export function SettingsStatisticsSection({ className }: { className?: string }) {
|
||||||
const [stats, setStats] = useState<StatisticsResponse | null>(null);
|
const [stats, setStats] = useState<StatisticsResponse | null>(null);
|
||||||
const [statsLoading, setStatsLoading] = useState(false);
|
const [statsLoading, setStatsLoading] = useState(false);
|
||||||
|
const [statsError, setStatsError] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
setStatsLoading(true);
|
setStatsLoading(true);
|
||||||
|
setStatsError(false);
|
||||||
api.getStatistics().then(
|
api.getStatistics().then(
|
||||||
(data) => {
|
(data) => {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
@@ -18,7 +20,10 @@ export function SettingsStatisticsSection({ className }: { className?: string })
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
if (!cancelled) setStatsLoading(false);
|
if (!cancelled) {
|
||||||
|
setStatsError(true);
|
||||||
|
setStatsLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return () => {
|
return () => {
|
||||||
@@ -145,6 +150,8 @@ export function SettingsStatisticsSection({ className }: { className?: string })
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
) : statsError ? (
|
||||||
|
<div className="py-8 text-center text-muted-foreground">Failed to load statistics.</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</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