mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Guard flood scope and be better about blocking
This commit is contained in:
@@ -192,6 +192,7 @@ class Message(BaseModel):
|
||||
)
|
||||
txt_type: int = 0
|
||||
signature: str | None = None
|
||||
sender_key: str | None = None
|
||||
outgoing: bool = False
|
||||
acked: int = 0
|
||||
sender_name: str | None = None
|
||||
|
||||
@@ -206,6 +206,8 @@ async def create_message_from_decrypted(
|
||||
sender_timestamp=timestamp,
|
||||
received_at=received,
|
||||
paths=paths,
|
||||
sender_name=sender,
|
||||
sender_key=resolved_sender_key,
|
||||
).model_dump(),
|
||||
)
|
||||
|
||||
|
||||
12
app/radio.py
12
app/radio.py
@@ -258,13 +258,19 @@ class RadioManager:
|
||||
# Sync radio clock with system time
|
||||
await sync_radio_time(mc)
|
||||
|
||||
# Apply flood scope from settings
|
||||
# Apply flood scope from settings (best-effort; older firmware
|
||||
# may not support set_flood_scope)
|
||||
from app.repository import AppSettingsRepository
|
||||
|
||||
app_settings = await AppSettingsRepository.get()
|
||||
scope = app_settings.flood_scope
|
||||
await mc.commands.set_flood_scope(scope if scope else "")
|
||||
logger.info("Applied flood_scope=%r", scope or "(disabled)")
|
||||
try:
|
||||
await mc.commands.set_flood_scope(scope if scope else "")
|
||||
logger.info("Applied flood_scope=%r", scope or "(disabled)")
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"set_flood_scope failed (firmware may not support it): %s", exc
|
||||
)
|
||||
|
||||
# Sync contacts/channels from radio to DB and clear radio
|
||||
logger.info("Syncing and offloading radio data...")
|
||||
|
||||
@@ -154,6 +154,7 @@ class MessageRepository:
|
||||
paths=MessageRepository._parse_paths(row["paths"]),
|
||||
txt_type=row["txt_type"],
|
||||
signature=row["signature"],
|
||||
sender_key=row["sender_key"],
|
||||
outgoing=bool(row["outgoing"]),
|
||||
acked=row["acked"],
|
||||
sender_name=row["sender_name"],
|
||||
|
||||
@@ -270,14 +270,22 @@ export function App() {
|
||||
if (!msg.outgoing) {
|
||||
const bKeys = blockedKeysRef.current;
|
||||
const bNames = blockedNamesRef.current;
|
||||
// Block DMs by key
|
||||
// Block DMs by sender key
|
||||
if (
|
||||
bKeys.length > 0 &&
|
||||
msg.type === 'PRIV' &&
|
||||
bKeys.includes(msg.conversation_key.toLowerCase())
|
||||
)
|
||||
return;
|
||||
// Block by sender name (works for channel messages)
|
||||
// Block channel messages by sender key
|
||||
if (
|
||||
bKeys.length > 0 &&
|
||||
msg.type === 'CHAN' &&
|
||||
msg.sender_key &&
|
||||
bKeys.includes(msg.sender_key.toLowerCase())
|
||||
)
|
||||
return;
|
||||
// Block by sender name (works for both DMs and channel messages)
|
||||
if (bNames.length > 0 && msg.sender_name && bNames.includes(msg.sender_name)) return;
|
||||
}
|
||||
|
||||
|
||||
@@ -193,6 +193,7 @@ describe('Integration: No phantom unreads from mesh echoes (hitlist #8 regressio
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: false,
|
||||
acked: 0,
|
||||
sender_name: null,
|
||||
@@ -214,6 +215,7 @@ describe('Integration: No phantom unreads from mesh echoes (hitlist #8 regressio
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: false,
|
||||
acked: 0,
|
||||
sender_name: null,
|
||||
@@ -354,6 +356,7 @@ describe('Integration: ACK + messageCache propagation', () => {
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: true,
|
||||
acked: 0,
|
||||
sender_name: null,
|
||||
@@ -378,6 +381,7 @@ describe('Integration: ACK + messageCache propagation', () => {
|
||||
paths: [{ path: 'aa', received_at: 1700000001 }],
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: true,
|
||||
acked: 1,
|
||||
sender_name: null,
|
||||
@@ -406,6 +410,7 @@ describe('Integration: ACK + messageCache propagation', () => {
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: true,
|
||||
acked: 5,
|
||||
sender_name: null,
|
||||
@@ -430,6 +435,7 @@ describe('Integration: ACK + messageCache propagation', () => {
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: true,
|
||||
acked: 0,
|
||||
sender_name: null,
|
||||
|
||||
@@ -18,6 +18,7 @@ function createMessage(overrides: Partial<Message> = {}): Message {
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: false,
|
||||
acked: 0,
|
||||
sender_name: null,
|
||||
|
||||
@@ -24,6 +24,7 @@ function createSearchResult(overrides: Partial<Message> = {}): Message {
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: false,
|
||||
acked: 0,
|
||||
sender_name: 'Alice',
|
||||
|
||||
@@ -35,6 +35,7 @@ function createMessage(overrides: Partial<Message> = {}): Message {
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: true,
|
||||
acked: 0,
|
||||
sender_name: null,
|
||||
|
||||
@@ -19,6 +19,7 @@ function createMessage(overrides: Partial<Message> = {}): Message {
|
||||
paths: null,
|
||||
txt_type: 0,
|
||||
signature: null,
|
||||
sender_key: null,
|
||||
outgoing: false,
|
||||
acked: 0,
|
||||
sender_name: null,
|
||||
|
||||
@@ -151,6 +151,7 @@ export interface Message {
|
||||
paths: MessagePath[] | null;
|
||||
txt_type: number;
|
||||
signature: string | null;
|
||||
sender_key: string | null;
|
||||
outgoing: boolean;
|
||||
/** ACK count: 0 = not acked, 1+ = number of acks/flood echoes received */
|
||||
acked: number;
|
||||
|
||||
@@ -320,6 +320,7 @@ class TestContactMessageCLIFiltering:
|
||||
"paths",
|
||||
"txt_type",
|
||||
"signature",
|
||||
"sender_key",
|
||||
"outgoing",
|
||||
"acked",
|
||||
"sender_name",
|
||||
|
||||
Reference in New Issue
Block a user