@decentnetwork/lan 0.1.219 → 0.1.220
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/carrier/peer-manager.d.ts +2 -0
- package/dist/carrier/peer-manager.js +4 -0
- package/dist/cli/commands.d.ts +9 -0
- package/dist/cli/commands.js +32 -0
- package/dist/cli/index.js +10 -1
- package/dist/daemon/server.d.ts +1 -0
- package/dist/daemon/server.js +24 -1
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -90,6 +90,8 @@ export declare class PeerManager extends EventEmitter {
|
|
|
90
90
|
isNativeFriend(userid: string): boolean;
|
|
91
91
|
/** Accept an incoming file offer. */
|
|
92
92
|
acceptFile(userid: string, fileNumber: number): void;
|
|
93
|
+
/** Reject/cancel an incoming file offer before accepting it. */
|
|
94
|
+
cancelFile(userid: string, fileNumber: number): void;
|
|
93
95
|
/** Cancel an in-flight send by content fileId. Returns true if it was found. */
|
|
94
96
|
cancelSend(userid: string, fileId: string): boolean;
|
|
95
97
|
/** Cancel in-flight sends matching size/name when activeSends lost the fileId. */
|
|
@@ -205,6 +205,10 @@ export class PeerManager extends EventEmitter {
|
|
|
205
205
|
acceptFile(userid, fileNumber) {
|
|
206
206
|
this.peer?.acceptFile(userid, fileNumber);
|
|
207
207
|
}
|
|
208
|
+
/** Reject/cancel an incoming file offer before accepting it. */
|
|
209
|
+
cancelFile(userid, fileNumber) {
|
|
210
|
+
this.peer?.cancelFile(userid, fileNumber, false);
|
|
211
|
+
}
|
|
208
212
|
/** Cancel an in-flight send by content fileId. Returns true if it was found. */
|
|
209
213
|
cancelSend(userid, fileId) {
|
|
210
214
|
return this.peer?.cancelFileById(userid, fileId, true) ?? false;
|
package/dist/cli/commands.d.ts
CHANGED
|
@@ -215,6 +215,15 @@ export declare function cmdProxyWhitelist(args: {
|
|
|
215
215
|
userid?: string;
|
|
216
216
|
configDir?: string;
|
|
217
217
|
}): Promise<void>;
|
|
218
|
+
/**
|
|
219
|
+
* Exit bandwidth guard for Messenger file receiving. Default is OFF: friends can
|
|
220
|
+
* send files normally. When ON, this node only accepts incoming file offers from
|
|
221
|
+
* peers present in the existing proxy whitelist. Applies live to the daemon.
|
|
222
|
+
*/
|
|
223
|
+
export declare function cmdProxyFileWhitelist(args: {
|
|
224
|
+
mode: "on" | "off" | "status";
|
|
225
|
+
configDir?: string;
|
|
226
|
+
}): Promise<void>;
|
|
218
227
|
/**
|
|
219
228
|
* Set (or clear, with 0) the exit's busy threshold in Mbps. Above this smoothed
|
|
220
229
|
* egress rate the exit serves only whitelisted peers; 0 = free for all.
|
package/dist/cli/commands.js
CHANGED
|
@@ -1004,6 +1004,9 @@ export async function cmdProxyWhitelist(args) {
|
|
|
1004
1004
|
console.log(busy > 0
|
|
1005
1005
|
? `Busy threshold: ${busy}Mbps (above this, only whitelisted peers get new tunnels).`
|
|
1006
1006
|
: `Busy threshold: OFF — exit is free for all. Set one with 'agentnet proxy busy-mbps <N>'.`);
|
|
1007
|
+
console.log(proxy.fileWhitelistOnly === true
|
|
1008
|
+
? `File receive guard: ON — incoming files are accepted only from this whitelist.`
|
|
1009
|
+
: `File receive guard: OFF — friend file receiving is open. Enable with 'agentnet proxy file-whitelist on'.`);
|
|
1007
1010
|
return;
|
|
1008
1011
|
}
|
|
1009
1012
|
if (!args.userid) {
|
|
@@ -1025,6 +1028,35 @@ export async function cmdProxyWhitelist(args) {
|
|
|
1025
1028
|
await ConfigLoader.save(config, configPath);
|
|
1026
1029
|
await applyProxyReloadIfRunning(config);
|
|
1027
1030
|
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Exit bandwidth guard for Messenger file receiving. Default is OFF: friends can
|
|
1033
|
+
* send files normally. When ON, this node only accepts incoming file offers from
|
|
1034
|
+
* peers present in the existing proxy whitelist. Applies live to the daemon.
|
|
1035
|
+
*/
|
|
1036
|
+
export async function cmdProxyFileWhitelist(args) {
|
|
1037
|
+
const dir = args.configDir || ConfigLoader.defaultConfigDir();
|
|
1038
|
+
const configPath = resolve(dir, "config.yaml");
|
|
1039
|
+
const config = await ConfigLoader.load(configPath);
|
|
1040
|
+
const proxy = config.proxy ?? { enabled: false, port: 8888 };
|
|
1041
|
+
const whitelist = proxy.whitelist ?? [];
|
|
1042
|
+
const enabled = proxy.fileWhitelistOnly === true;
|
|
1043
|
+
if (args.mode === "status") {
|
|
1044
|
+
console.log(enabled
|
|
1045
|
+
? `File receive guard: ON — incoming files are accepted only from proxy.whitelist (${whitelist.length} entr${whitelist.length === 1 ? "y" : "ies"}).`
|
|
1046
|
+
: `File receive guard: OFF — friend file receiving is open.`);
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
const next = args.mode === "on";
|
|
1050
|
+
config.proxy = { ...proxy, fileWhitelistOnly: next };
|
|
1051
|
+
await ConfigLoader.save(config, configPath);
|
|
1052
|
+
console.log(next
|
|
1053
|
+
? `File receive guard ON — incoming files from friends outside proxy.whitelist will be rejected.`
|
|
1054
|
+
: `File receive guard OFF — friends can send files normally.`);
|
|
1055
|
+
if (next && whitelist.length === 0) {
|
|
1056
|
+
console.log(`Warning: proxy.whitelist is empty, so all incoming file offers will be rejected until you add peers.`);
|
|
1057
|
+
}
|
|
1058
|
+
await applyProxyReloadIfRunning(config);
|
|
1059
|
+
}
|
|
1028
1060
|
/**
|
|
1029
1061
|
* Set (or clear, with 0) the exit's busy threshold in Mbps. Above this smoothed
|
|
1030
1062
|
* egress rate the exit serves only whitelisted peers; 0 = free for all.
|
package/dist/cli/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { hideBin } from "yargs/helpers";
|
|
|
10
10
|
// Belt-and-braces — also raise it here in case the CLI is run directly
|
|
11
11
|
// (e.g. `node dist/cli/index.js` rather than via dist/index.js).
|
|
12
12
|
EventEmitter.defaultMaxListeners = 100;
|
|
13
|
-
import { cmdInit, cmdIdentityShow, cmdPeersList, cmdIpamAssign, cmdGrant, cmdRevoke, cmdResolve, cmdStatus, cmdUp, cmdAuditLog, cmdFriendRequest, cmdFriendAccept, cmdFriendsList, cmdFriendsPending, cmdFriendsAccept, cmdFriendsAutoAccept, cmdFriendsReject, cmdProxyEnable, cmdProxyDisable, cmdProxyStatus, cmdProxyWho, cmdProxyAccess, cmdProxyAllowHost, cmdProxyRevokeHost, cmdProxyListHosts, cmdProxyWhitelist, cmdProxyBusyMbps, cmdProxyUse, cmdProxyRouter, cmdProxyTrustCa, cmdDoraEnable, cmdDoraDisable, cmdDoraStatus, cmdDoraAutofriend, cmdDiag, cmdDoctor, cmdDnsInstall, cmdDnsHosts, cmdServiceInstall, cmdRestart, cmdServiceStatus, cmdServiceRestart, cmdUi, cmdConsole, cmdFileSend, cmdChatSend, cmdChatHistory, cmdFriendRemove, cmdFriendAlias, } from "./commands.js";
|
|
13
|
+
import { cmdInit, cmdIdentityShow, cmdPeersList, cmdIpamAssign, cmdGrant, cmdRevoke, cmdResolve, cmdStatus, cmdUp, cmdAuditLog, cmdFriendRequest, cmdFriendAccept, cmdFriendsList, cmdFriendsPending, cmdFriendsAccept, cmdFriendsAutoAccept, cmdFriendsReject, cmdProxyEnable, cmdProxyDisable, cmdProxyStatus, cmdProxyWho, cmdProxyAccess, cmdProxyAllowHost, cmdProxyRevokeHost, cmdProxyListHosts, cmdProxyWhitelist, cmdProxyFileWhitelist, cmdProxyBusyMbps, cmdProxyUse, cmdProxyRouter, cmdProxyTrustCa, cmdDoraEnable, cmdDoraDisable, cmdDoraStatus, cmdDoraAutofriend, cmdDiag, cmdDoctor, cmdDnsInstall, cmdDnsHosts, cmdServiceInstall, cmdRestart, cmdServiceStatus, cmdServiceRestart, cmdUi, cmdConsole, cmdFileSend, cmdChatSend, cmdChatHistory, cmdFriendRemove, cmdFriendAlias, } from "./commands.js";
|
|
14
14
|
async function main() {
|
|
15
15
|
await yargs(hideBin(process.argv))
|
|
16
16
|
.scriptName("agentnet")
|
|
@@ -327,6 +327,15 @@ async function main() {
|
|
|
327
327
|
return;
|
|
328
328
|
}
|
|
329
329
|
await cmdProxyWhitelist({ action: argv.action, userid: argv.userid, configDir: argv["config-dir"] });
|
|
330
|
+
})
|
|
331
|
+
.command("file-whitelist <mode>", "Incoming files: accept only from proxy whitelist when on (on|off|status)", (yy) => yy
|
|
332
|
+
.positional("mode", { type: "string", demandOption: true })
|
|
333
|
+
.option("config-dir", { type: "string" }), async (argv) => {
|
|
334
|
+
if (argv.mode !== "on" && argv.mode !== "off" && argv.mode !== "status") {
|
|
335
|
+
console.log("Usage: agentnet proxy file-whitelist <on|off|status>");
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
await cmdProxyFileWhitelist({ mode: argv.mode, configDir: argv["config-dir"] });
|
|
330
339
|
})
|
|
331
340
|
.command("busy-mbps <mbps>", "Set the exit's busy threshold (Mbps); above it, only whitelisted peers get new tunnels. 0 = free for all", (yy) => yy
|
|
332
341
|
.positional("mbps", { type: "number", demandOption: true })
|
package/dist/daemon/server.d.ts
CHANGED
package/dist/daemon/server.js
CHANGED
|
@@ -207,6 +207,20 @@ export class DaemonServer {
|
|
|
207
207
|
}
|
|
208
208
|
this.tunRebuildInProgress = false;
|
|
209
209
|
}
|
|
210
|
+
isFileSenderWhitelisted(userid) {
|
|
211
|
+
const proxy = this.config.proxy;
|
|
212
|
+
if (!proxy?.fileWhitelistOnly)
|
|
213
|
+
return true;
|
|
214
|
+
const whitelist = new Set((proxy.whitelist ?? []).map((s) => String(s).trim()).filter(Boolean));
|
|
215
|
+
if (whitelist.size === 0)
|
|
216
|
+
return false;
|
|
217
|
+
if (whitelist.has(userid))
|
|
218
|
+
return true;
|
|
219
|
+
const rec = this.ipam?.resolveCarrierId(userid);
|
|
220
|
+
if (!rec)
|
|
221
|
+
return false;
|
|
222
|
+
return whitelist.has(rec.virtualIp) || whitelist.has(rec.name) || whitelist.has(rec.carrierId);
|
|
223
|
+
}
|
|
210
224
|
async start() {
|
|
211
225
|
if (this.isRunning) {
|
|
212
226
|
throw new Error("Daemon already running");
|
|
@@ -704,6 +718,7 @@ export class DaemonServer {
|
|
|
704
718
|
// and `proxy busy-mbps` apply live without a restart.
|
|
705
719
|
const whitelist = fresh.proxy?.whitelist ?? [];
|
|
706
720
|
const busyMbps = fresh.proxy?.busyMbps;
|
|
721
|
+
const fileWhitelistOnly = fresh.proxy?.fileWhitelistOnly === true;
|
|
707
722
|
this.connectProxy.updateAdmission({ whitelist, busyMbps });
|
|
708
723
|
// Keep the in-memory config in sync so a later diag reflects it.
|
|
709
724
|
if (this.config.proxy) {
|
|
@@ -712,8 +727,9 @@ export class DaemonServer {
|
|
|
712
727
|
this.config.proxy.allowConnectPorts = allowConnectPorts;
|
|
713
728
|
this.config.proxy.whitelist = whitelist;
|
|
714
729
|
this.config.proxy.busyMbps = busyMbps;
|
|
730
|
+
this.config.proxy.fileWhitelistOnly = fileWhitelistOnly;
|
|
715
731
|
}
|
|
716
|
-
return { applied: true, allowHosts, whitelist, busyMbps };
|
|
732
|
+
return { applied: true, allowHosts, whitelist, busyMbps, fileWhitelistOnly };
|
|
717
733
|
},
|
|
718
734
|
proxyAccess: async (userid, allow) => {
|
|
719
735
|
// Live block/allow a peer's access to THIS node's exit proxy port.
|
|
@@ -1014,6 +1030,13 @@ export class DaemonServer {
|
|
|
1014
1030
|
// File transfer (toxcore-standard): auto-accept offers from friends and
|
|
1015
1031
|
// save completed files under <configDir>/downloads/.
|
|
1016
1032
|
this.peerManager.on("file-offer", (o) => {
|
|
1033
|
+
if (!this.isFileSenderWhitelisted(o.friendId)) {
|
|
1034
|
+
const rec = this.ipam?.resolveCarrierId(o.friendId);
|
|
1035
|
+
const who = rec ? `${rec.name}/${rec.virtualIp}` : o.friendId.slice(0, 8);
|
|
1036
|
+
this.logger.warn(`Incoming file "${o.name}" (${o.size}B) from ${who} rejected — proxy.fileWhitelistOnly=true and sender is not in proxy.whitelist`);
|
|
1037
|
+
this.peerManager?.cancelFile(o.friendId, o.fileNumber);
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1017
1040
|
this.logger.info(`Incoming file "${o.name}" (${o.size}B) from ${o.friendId.slice(0, 8)} — accepting`);
|
|
1018
1041
|
this.peerManager?.acceptFile(o.friendId, o.fileNumber);
|
|
1019
1042
|
});
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/lan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.220",
|
|
4
4
|
"description": "Private virtual LAN for self-hosted services and AI agents, built on Elastos Carrier. NAT-traversal, name service, ACL, all over a peer-to-peer mesh — no public IP required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|