@@ -2936,6 +3001,12 @@ export default {
"app.inbound_stamp_description",
"app.inbound_stamps_required_title",
"app.inbound_stamps_required_description",
+ "app.flood_protection",
+ "app.flood_protection_description",
+ "app.flood_protection_enabled",
+ "app.flood_threshold",
+ "app.flood_max_stamp_cost",
+ "app.flood_cooldown",
],
propagation: [
"LXMF",
@@ -3609,6 +3680,47 @@ export default {
);
}, 1000);
},
+ async onLxmfFloodProtectionEnabledChange(value) {
+ await this.updateConfig({
+ lxmf_flood_protection_enabled: value,
+ });
+ },
+ async onLxmfFloodThresholdChange() {
+ if (this.saveTimeouts.flood_threshold) clearTimeout(this.saveTimeouts.flood_threshold);
+ this.saveTimeouts.flood_threshold = setTimeout(async () => {
+ let v = Number(this.config.lxmf_flood_threshold_per_minute);
+ if (!v || v < 1) v = 30;
+ else if (v > 1000) v = 1000;
+ this.config.lxmf_flood_threshold_per_minute = v;
+ await this.updateConfig({
+ lxmf_flood_threshold_per_minute: v,
+ });
+ }, 1000);
+ },
+ async onLxmfFloodMaxStampCostChange() {
+ if (this.saveTimeouts.flood_max_cost) clearTimeout(this.saveTimeouts.flood_max_cost);
+ this.saveTimeouts.flood_max_cost = setTimeout(async () => {
+ let v = Number(this.config.lxmf_flood_max_stamp_cost);
+ if (!v || v < 1) v = 24;
+ else if (v > 254) v = 254;
+ this.config.lxmf_flood_max_stamp_cost = v;
+ await this.updateConfig({
+ lxmf_flood_max_stamp_cost: v,
+ });
+ }, 1000);
+ },
+ async onLxmfFloodCooldownChange() {
+ if (this.saveTimeouts.flood_cooldown) clearTimeout(this.saveTimeouts.flood_cooldown);
+ this.saveTimeouts.flood_cooldown = setTimeout(async () => {
+ let v = Number(this.config.lxmf_flood_cooldown_seconds);
+ if (!v || v < 30) v = 30;
+ else if (v > 3600) v = 3600;
+ this.config.lxmf_flood_cooldown_seconds = v;
+ await this.updateConfig({
+ lxmf_flood_cooldown_seconds: v,
+ });
+ }, 1000);
+ },
async onPageArchiverEnabledChangeWrapper(value) {
this.config.page_archiver_enabled = value;
await this.updateConfig(
diff --git a/meshchatx/src/frontend/locales/en.json b/meshchatx/src/frontend/locales/en.json
index ceca817..504b020 100644
--- a/meshchatx/src/frontend/locales/en.json
+++ b/meshchatx/src/frontend/locales/en.json
@@ -146,6 +146,12 @@
"inbound_stamps_required_description": "When off, direct messages to you do not require proof-of-work stamps. When on, set the stamp cost below. Higher values mean more work for senders.",
"inbound_stamp_cost": "Inbound Message Stamp Cost",
"inbound_stamp_description": "Proof-of-work difficulty for direct messages. Range: 1-254. Default: 8.",
+ "flood_protection": "Flood Protection",
+ "flood_protection_description": "Automatically raise the inbound stamp cost when receiving too many messages per minute from many sources. This makes coordinated spam attacks computationally expensive while keeping normal conversations affordable.",
+ "flood_protection_enabled": "Enable auto-adjusting stamp cost",
+ "flood_threshold": "Messages per minute threshold",
+ "flood_max_stamp_cost": "Maximum stamp cost during flood",
+ "flood_cooldown": "Cooldown before lowering cost (seconds)",
"local_message_auto_delete_title": "Delete old messages on this device",
"local_message_auto_delete_description": "Removes messages from the local database after the age you set. This only affects this device and no data is deleted from the network.",
"local_message_auto_delete_age": "Delete messages older than",