Skip to content

Commit 9d33192

Browse files
committed
chore: update @nestjs packages and other dependencies; refactor torrent blocker state management and API config generation
1 parent 739fe84 commit 9d33192

8 files changed

Lines changed: 120 additions & 52 deletions

File tree

‎package-lock.json‎

Lines changed: 20 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,17 @@
3535
"@henrygd/semaphore": "0.1.0",
3636
"@kastov/body-parser-with-zstd": "2.2.2",
3737
"@kastov/node-supervisord": ">=2.0.3",
38-
"@nestjs/common": "11.1.15",
38+
"@nestjs/common": "11.1.16",
3939
"@nestjs/config": "4.0.3",
40-
"@nestjs/core": "11.1.15",
40+
"@nestjs/core": "11.1.16",
4141
"@nestjs/jwt": "11.0.2",
4242
"@nestjs/passport": "11.0.5",
43-
"@nestjs/platform-express": "11.1.15",
43+
"@nestjs/platform-express": "11.1.16",
4444
"@peculiar/webcrypto": "^1.5.0",
4545
"@peculiar/x509": "^1.14.3",
4646
"@remnawave/hashed-set": "^0.0.4",
4747
"@nestjs/cqrs": "11.0.3",
48-
"@remnawave/node-plugins": "0.1.1",
48+
"@remnawave/node-plugins": "0.1.3",
4949
"@remnawave/supervisord-nestjs": "0.3.1",
5050
"@remnawave/xtls-sdk": "0.11.1",
5151
"@remnawave/xtls-sdk-nestjs": "0.6.1",

‎src/common/utils/generate-api-config.ts‎

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,32 @@ import { getServerCerts } from './generate-mtls-certs';
1515
import { getXtlsApiPort } from './get-initial-ports';
1616
import { IPolicyConfig } from './interfaces';
1717

18-
export const generateApiConfig = (
19-
config: Record<string, unknown>,
20-
isTorrentBlockerEnabled: boolean,
18+
interface IRoutingXrayConfig {
19+
rules: {
20+
ruleTag?: string;
21+
webhook?: {
22+
url: string;
23+
deduplication: number;
24+
};
25+
[key: string]: unknown;
26+
}[];
27+
}
28+
29+
interface IGenerateApiConfigParams {
30+
config: Record<string, unknown>;
31+
torrentBlockerState: {
32+
enabled: boolean;
33+
includeRuleTags: Set<string>;
34+
};
2135
internal: {
2236
socketPath: string;
2337
token: string;
24-
},
25-
): Record<string, unknown> => {
38+
};
39+
}
40+
41+
export const generateApiConfig = (args: IGenerateApiConfigParams): Record<string, unknown> => {
42+
const { config, torrentBlockerState, internal } = args;
43+
2644
const policyConfig = config.policy as undefined | IPolicyConfig;
2745
const serverCerts = getServerCerts();
2846
const hasCapNetAdminResult = hasCapNetAdmin();
@@ -39,7 +57,7 @@ export const generateApiConfig = (
3957
system: XRAY_DEFAULT_POLICY_MODEL.policy.system,
4058
};
4159

42-
return {
60+
const result = {
4361
...config,
4462
...XRAY_DEFAULT_STATS_MODEL,
4563
...XRAY_DEFAULT_API_MODEL,
@@ -52,24 +70,44 @@ export const generateApiConfig = (
5270
}),
5371
...(Array.isArray(config.inbounds) ? config.inbounds : []),
5472
],
55-
outbounds: [
56-
...(Array.isArray(config.outbounds) ? config.outbounds : []),
57-
...(isTorrentBlockerEnabled ? [XRAY_TORRENT_BLOCKER_OUTBOUND_MODEL] : []),
58-
],
73+
outbounds: [...(Array.isArray(config.outbounds) ? config.outbounds : [])],
5974
policy: builtPolicy,
6075
routing: {
6176
...(config.routing || {}),
6277
rules: [
6378
XRAY_ROUTING_RULES_MODEL,
64-
...(isTorrentBlockerEnabled
65-
? [
66-
XRAY_TORRENT_BLOCKER_ROUTING_RULES_MODEL({
67-
webhookUrl: `/${internal.socketPath}:${XRAY_INTERNAL_FULL_WEBHOOK_PATH}?token=${internal.token}`,
68-
}),
69-
]
70-
: []),
7179
...((config.routing as { rules?: unknown[] })?.rules || []),
7280
],
7381
},
7482
};
83+
84+
if (torrentBlockerState.enabled) {
85+
const webhookUrl = buildWebhookUrl(internal);
86+
const routing = result.routing as IRoutingXrayConfig;
87+
88+
result.outbounds.push(XRAY_TORRENT_BLOCKER_OUTBOUND_MODEL);
89+
90+
routing.rules.splice(1, 0, XRAY_TORRENT_BLOCKER_ROUTING_RULES_MODEL({ webhookUrl }));
91+
92+
if (torrentBlockerState.includeRuleTags.size > 0) {
93+
for (const rule of routing.rules) {
94+
if (
95+
rule.ruleTag &&
96+
typeof rule.ruleTag === 'string' &&
97+
torrentBlockerState.includeRuleTags.has(rule.ruleTag)
98+
) {
99+
rule.webhook = {
100+
url: webhookUrl,
101+
deduplication: 30,
102+
};
103+
}
104+
}
105+
}
106+
}
107+
108+
return result;
109+
};
110+
111+
const buildWebhookUrl = (internal: { socketPath: string; token: string }): string => {
112+
return `/${internal.socketPath}:${XRAY_INTERNAL_FULL_WEBHOOK_PATH}?token=${internal.token}`;
75113
};

‎src/modules/_plugin/plugin.service.ts‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,18 @@ export class PluginService {
9595
this.logger.log('[PLUGIN] Plugins changed...');
9696

9797
if (currentTorrentBlocker && !pluginData.torrentBlocker?.enabled) {
98-
await this.commandBus.execute(
99-
new RemoveOutboundCommand(XRAY_TORRENT_BLOCKER_OUTBOUND_TAG),
100-
);
98+
if (!pluginData.torrentBlocker?.includeRuleTags) {
99+
await this.commandBus.execute(
100+
new RemoveOutboundCommand(XRAY_TORRENT_BLOCKER_OUTBOUND_TAG),
101+
);
102+
} else {
103+
await this.commandBus.execute(
104+
new StopXrayCommand({
105+
withOnlineCheck: true,
106+
withPluginCleanup: false,
107+
}),
108+
);
109+
}
101110
} else if (!currentTorrentBlocker && pluginData.torrentBlocker?.enabled) {
102111
await this.commandBus.execute(
103112
new StopXrayCommand({
@@ -158,6 +167,7 @@ export class PluginService {
158167
this.state.torrentBlocker.setIgnoredIps(ips);
159168
this.state.torrentBlocker.setIgnoredUsers(users);
160169
this.state.torrentBlocker.configure(blockDuration);
170+
this.state.torrentBlocker.setIncludeRuleTags(pluginData.torrentBlocker.includeRuleTags);
161171

162172
this.logger.log(
163173
`[PLUGIN] Torrent-Blocker: blockDuration=${blockDuration}s, ${ips.length} ignored IPs, ${users.length} ignored users`,

‎src/modules/_plugin/queries/get-torrent-blocker-state/get-torrent-blocker-state.handler.ts‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,16 @@ export class GetTorrentBlockerStateHandler implements IQueryHandler<GetTorrentBl
1313
try {
1414
const isEnabled = this.pluginState.torrentBlocker.isEnabled;
1515

16-
return isEnabled;
16+
return {
17+
enabled: isEnabled,
18+
includeRuleTags: this.pluginState.torrentBlocker.includeRuleTagsSet,
19+
};
1720
} catch (error) {
1821
this.logger.error(error);
19-
return false;
22+
return {
23+
enabled: false,
24+
includeRuleTags: new Set<string>(),
25+
};
2026
}
2127
}
2228
}

‎src/modules/_plugin/queries/get-torrent-blocker-state/get-torrent-blocker-state.query.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Query } from '@nestjs/cqrs';
22

3-
export class GetTorrentBlockerStateQuery extends Query<boolean> {
3+
export class GetTorrentBlockerStateQuery extends Query<{
4+
enabled: boolean;
5+
includeRuleTags: Set<string>;
6+
}> {
47
constructor() {
58
super();
69
}

‎src/modules/_plugin/services/states/torrent-blocker.state.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export class TorrentBlockerState {
55
private blockDuration: number | null = null;
66
private ignoredIps = new Set<string>();
77
private ignoredUsers = new Set<string>();
8+
private includeRuleTags = new Set<string>();
89
private reports: TorrentBlockerReportModel[] = [];
910

1011
get isEnabled(): boolean {
@@ -55,5 +56,15 @@ export class TorrentBlockerState {
5556
this.blockDuration = null;
5657
this.ignoredIps.clear();
5758
this.ignoredUsers.clear();
59+
this.includeRuleTags.clear();
60+
}
61+
62+
setIncludeRuleTags(tags: string[] | undefined): void {
63+
if (!tags) return;
64+
this.includeRuleTags = new Set(tags);
65+
}
66+
67+
get includeRuleTagsSet(): Set<string> {
68+
return this.includeRuleTags;
5869
}
5970
}

‎src/modules/xray-core/xray.service.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,11 @@ export class XrayService implements OnApplicationBootstrap {
160160
new GetTorrentBlockerStateQuery(),
161161
);
162162

163-
const fullConfig = generateApiConfig(
164-
body.xrayConfig,
165-
isTorrentBlockerEnabled,
166-
this.internal,
167-
);
163+
const fullConfig = generateApiConfig({
164+
config: body.xrayConfig,
165+
torrentBlockerState: isTorrentBlockerEnabled,
166+
internal: this.internal,
167+
});
168168

169169
await this.internalService.extractUsersFromConfig(body.internals.hashes, fullConfig);
170170

0 commit comments

Comments
 (0)