Skip to content

Commit 3164e63

Browse files
committed
feat: add flow configuration to VLESS settings and update flow handling in related services
- Enhanced `getVlessFlow` function to utilize the new `flow` property for determining flow settings based on inbound configurations. - Updated various generator services to incorporate flow settings from hosts, improving flexibility in flow management. - Refactored existing flow handling logic to remove hardcoded values and utilize the new configuration.
1 parent 011f748 commit 3164e63

File tree

9 files changed

+69
-76
lines changed

9 files changed

+69
-76
lines changed

src/common/helpers/xray-config/interfaces/protocol-settings.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export interface VLessSettings {
4646
clients: VLessUser[];
4747
decryption: 'none' | string;
4848
fallbacks?: VLessFallback[];
49+
flow?: 'xtls-rprx-vision' | '' | 'none';
4950
}
5051

5152
export interface VLessUser extends UserObject {
Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,64 @@
1+
import { VLessSettings } from '@common/helpers/xray-config/interfaces/protocol-settings.config';
12
import { InboundObject } from '@common/helpers/xray-config/interfaces/protocols.config';
23

34
import { ConfigProfileInboundEntity } from '@modules/config-profiles/entities';
45

5-
export const getVlessFlow = (inbound: InboundObject) => {
6-
if (
7-
(inbound.streamSettings?.network === 'tcp' || inbound.streamSettings?.network === 'raw') &&
8-
(inbound.streamSettings?.security === 'reality' ||
9-
inbound.streamSettings?.security === 'tls')
10-
) {
11-
return 'xtls-rprx-vision';
6+
interface VlessSettingsWithFlow {
7+
settings: {
8+
flow: 'xtls-rprx-vision' | '' | 'none';
9+
};
10+
}
11+
12+
export const hasVlessSettingsWithFlow = (obj: unknown): obj is VlessSettingsWithFlow => {
13+
return (
14+
typeof obj === 'object' &&
15+
obj !== null &&
16+
'settings' in obj &&
17+
typeof (obj as VlessSettingsWithFlow).settings === 'object' &&
18+
(obj as VlessSettingsWithFlow).settings !== null &&
19+
'flow' in (obj as VlessSettingsWithFlow).settings &&
20+
typeof (obj as VlessSettingsWithFlow).settings.flow === 'string'
21+
);
22+
};
23+
24+
export const getVlessFlow = (inbound: InboundObject): 'xtls-rprx-vision' | '' | undefined => {
25+
if (inbound.protocol !== 'vless') {
26+
return undefined;
27+
}
28+
29+
if ((inbound.settings as VLessSettings).flow !== undefined) {
30+
if ((inbound.settings as VLessSettings).flow === 'xtls-rprx-vision') {
31+
return 'xtls-rprx-vision';
32+
} else {
33+
return '';
34+
}
35+
}
36+
37+
if (inbound.streamSettings) {
38+
if (
39+
['reality', 'tls'].includes(inbound.streamSettings.security || '') &&
40+
['raw', 'tcp'].includes(inbound.streamSettings.network)
41+
) {
42+
return 'xtls-rprx-vision';
43+
}
1244
}
1345

1446
return '';
1547
};
1648

17-
export const getVlessFlowFromDbInbound = (inbound: ConfigProfileInboundEntity) => {
49+
export function getVlessFlowFromDbInbound(
50+
inbound: ConfigProfileInboundEntity,
51+
): 'xtls-rprx-vision' | '' {
52+
if (inbound.type === 'vless') {
53+
if (inbound.rawInbound && hasVlessSettingsWithFlow(inbound.rawInbound)) {
54+
if (inbound.rawInbound.settings.flow === 'xtls-rprx-vision') {
55+
return 'xtls-rprx-vision';
56+
} else {
57+
return '';
58+
}
59+
}
60+
}
61+
1862
if (
1963
(inbound.network === 'tcp' || inbound.network === 'raw') &&
2064
(inbound.security === 'reality' || inbound.security === 'tls')
@@ -23,4 +67,4 @@ export const getVlessFlowFromDbInbound = (inbound: ConfigProfileInboundEntity) =
2367
}
2468

2569
return '';
26-
};
70+
}

src/modules/subscription-template/generators/format-hosts.service.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { TemplateEngine } from '@common/utils/templates/replace-templates-values
2424
import { ICommandResponse } from '@common/types/command-response.type';
2525
import { InboundObject } from '@common/helpers/xray-config/interfaces';
2626
import { setVlessRouteForUuid } from '@common/utils/vless-route';
27+
import { getVlessFlow } from '@common/utils/flow';
2728
import { SECURITY_LAYERS, USERS_STATUS } from '@libs/contracts/constants';
2829

2930
import { SubscriptionSettingsEntity } from '@modules/subscription-settings/entities/subscription-settings.entity';
@@ -45,6 +46,8 @@ interface IGenerateFormattedHostsOptions {
4546
export class FormatHostsService {
4647
private readonly nanoid: ReturnType<typeof customAlphabet>;
4748
private readonly subPublicDomain: string;
49+
private readonly domainRegex =
50+
/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
4851

4952
constructor(
5053
private readonly queryBus: QueryBus,
@@ -368,9 +371,7 @@ export class FormatHostsService {
368371
const tls = tlsFromConfig;
369372

370373
const isDomain = (str: string): boolean => {
371-
const domainRegex =
372-
/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
373-
return domainRegex.test(str);
374+
return this.domainRegex.test(str);
374375
};
375376

376377
let sni = inputHost.sni || sniFromConfig;
@@ -460,6 +461,7 @@ export class FormatHostsService {
460461
dbData,
461462
mldsa65Verify: mldsa65PublicKeyFromConfig,
462463
encryption: encryptionMap.get(inputHost.inboundTag),
464+
flow: getVlessFlow(inbound),
463465
});
464466
}
465467

src/modules/subscription-template/generators/interfaces/formatted-hosts.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ export interface IFormattedHost {
3838
dbData?: IDbHostData;
3939
mldsa65Verify?: string;
4040
encryption?: string;
41+
flow?: 'xtls-rprx-vision' | '';
4142
}

src/modules/subscription-template/generators/mihomo.generator.service.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,22 +227,10 @@ export class MihomoGeneratorService {
227227
node.uuid = host.password.vlessPassword;
228228
node['packet-encoding'] = 'xudp';
229229

230-
if (
231-
['raw', 'tcp'].includes(host.network) &&
232-
host.headerType !== 'http' &&
233-
['reality', 'tls'].includes(host.tls)
234-
) {
235-
node.flow = 'xtls-rprx-vision';
230+
if (host.flow === 'xtls-rprx-vision') {
231+
node.flow = host.flow;
236232
}
237233

238-
// if (
239-
// ['tcp', 'raw', 'kcp'].includes(host.network) &&
240-
// host.headerType !== 'http' &&
241-
// inbound.tls !== 'none'
242-
// ) {
243-
// node.flow = settings.flow || '';
244-
// }
245-
246234
if (host.encryption && host.encryption !== 'none') {
247235
node.encryption = host.encryption;
248236
}

src/modules/subscription-template/generators/raw-hosts.generator.service.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,8 @@ export class RawHostsGeneratorService {
1919

2020
const rawHost: IRawHost = {
2121
...host,
22-
flow: 'xtls-rprx-vision',
2322
};
2423

25-
if (
26-
!(
27-
['reality', 'tls'].includes(host.tls) &&
28-
['raw', 'tcp'].includes(host.network) &&
29-
host.headerType !== 'http'
30-
)
31-
) {
32-
rawHost.flow = undefined;
33-
}
34-
3524
if (host.protocol === 'shadowsocks') {
3625
rawHost.protocolOptions = {
3726
ss: {

src/modules/subscription-template/generators/singbox.generator.service.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,8 @@ export class SingBoxGeneratorService {
255255
server_port: params.port,
256256
};
257257

258-
if (
259-
['raw', 'tcp'].includes(params.network) &&
260-
params.headerType !== 'http' &&
261-
['reality', 'tls'].includes(params.tls) &&
262-
params.protocol === 'vless'
263-
) {
264-
config.flow = 'xtls-rprx-vision';
258+
if (params.flow === 'xtls-rprx-vision') {
259+
config.flow = params.flow;
265260
}
266261

267262
if (params.protocol === 'shadowsocks') {

src/modules/subscription-template/generators/xray-json.generator.service.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export class XrayJsonGeneratorService {
149149
private createOutboundSettings(host: IFormattedHost): OutboundSettings {
150150
switch (host.protocol) {
151151
case 'vless':
152-
const vnextWithoutFlow = {
152+
return {
153153
vnext: [
154154
{
155155
address: host.address,
@@ -158,25 +158,13 @@ export class XrayJsonGeneratorService {
158158
{
159159
id: host.password.vlessPassword,
160160
encryption: host.encryption || 'none',
161-
flow: 'xtls-rprx-vision' as string | undefined,
161+
flow: host.flow,
162162
},
163163
],
164164
},
165165
],
166166
};
167167

168-
if (
169-
!(
170-
['reality', 'tls'].includes(host.tls) &&
171-
['raw', 'tcp'].includes(host.network) &&
172-
host.headerType !== 'http'
173-
)
174-
) {
175-
vnextWithoutFlow.vnext[0].users[0].flow = undefined;
176-
}
177-
178-
return vnextWithoutFlow;
179-
180168
case 'trojan':
181169
return {
182170
servers: [

src/modules/subscription-template/generators/xray.generator.service.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,6 @@ export class XrayGeneratorService {
124124
);
125125
}
126126

127-
if (
128-
['reality', 'tls'].includes(params.tls) &&
129-
['raw', 'tcp'].includes(params.network) &&
130-
params.protocol !== 'trojan' &&
131-
params.headerType !== 'http'
132-
) {
133-
Object.assign(payload, {
134-
flow: 'xtls-rprx-vision',
135-
});
136-
}
137-
138127
if (params.network === 'xhttp') {
139128
Object.assign(payload, {
140129
path: params.path,
@@ -198,21 +187,17 @@ export class XrayGeneratorService {
198187
headerType: params.headerType || '',
199188
};
200189

201-
const network = params.network || 'tcp';
190+
const network = params.network;
202191
if (network in NETWORK_CONFIGS) {
203192
Object.assign(
204193
payload,
205194
NETWORK_CONFIGS[network as StreamSettingsObject['network']](params),
206195
);
207196
}
208197

209-
if (
210-
['reality', 'tls'].includes(params.tls) &&
211-
['raw', 'tcp'].includes(params.network) &&
212-
params.headerType !== 'http'
213-
) {
198+
if (params.flow !== undefined) {
214199
Object.assign(payload, {
215-
flow: 'xtls-rprx-vision',
200+
flow: params.flow,
216201
});
217202
}
218203

0 commit comments

Comments
 (0)