🐛 fix: Added the enabled field in the protocol configuration, updated the related type definition and default configuration
This commit is contained in:
parent
d6854076fe
commit
2b0cf9a46d
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,16 +1,16 @@
|
|||||||
<a name="readme-top"></a>
|
<a name="readme-top"></a>
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [1.4.3](https://github.com/perfect-panel/ppanel-web/compare/v1.4.2...v1.4.3) (2025-09-16)
|
## [1.4.3](https://github.com/perfect-panel/ppanel-web/compare/v1.4.2...v1.4.3) (2025-09-16)
|
||||||
|
|
||||||
|
|
||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
* Add success toast message for sorting in nodes and servers pages ([2d5175d](https://github.com/perfect-panel/ppanel-web/commit/2d5175d))
|
- Add success toast message for sorting in nodes and servers pages ([2d5175d](https://github.com/perfect-panel/ppanel-web/commit/2d5175d))
|
||||||
* Implement encryption and obfuscation features in protocol configuration ([54de16b](https://github.com/perfect-panel/ppanel-web/commit/54de16b))
|
- Implement encryption and obfuscation features in protocol configuration ([54de16b](https://github.com/perfect-panel/ppanel-web/commit/54de16b))
|
||||||
* Refactor toB64 function to toB64Url for URL-safe base64 encoding in VlessX25519Pair generation ([8700cf6](https://github.com/perfect-panel/ppanel-web/commit/8700cf6))
|
- Refactor toB64 function to toB64Url for URL-safe base64 encoding in VlessX25519Pair generation ([8700cf6](https://github.com/perfect-panel/ppanel-web/commit/8700cf6))
|
||||||
* Simplify initialValues assignment and update node submission logic in NodesPage ([05d6c89](https://github.com/perfect-panel/ppanel-web/commit/05d6c89))
|
- Simplify initialValues assignment and update node submission logic in NodesPage ([05d6c89](https://github.com/perfect-panel/ppanel-web/commit/05d6c89))
|
||||||
* Update bun.lockb to reflect dependency changes ([ebcebd7](https://github.com/perfect-panel/ppanel-web/commit/ebcebd7))
|
- Update bun.lockb to reflect dependency changes ([ebcebd7](https://github.com/perfect-panel/ppanel-web/commit/ebcebd7))
|
||||||
|
|
||||||
<a name="readme-top"></a>
|
<a name="readme-top"></a>
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { XHTTP_MODES } from './constants';
|
||||||
import type { ProtocolType } from './types';
|
import type { ProtocolType } from './types';
|
||||||
|
|
||||||
export function getProtocolDefaultConfig(proto: ProtocolType) {
|
export function getProtocolDefaultConfig(proto: ProtocolType) {
|
||||||
@ -5,6 +6,7 @@ export function getProtocolDefaultConfig(proto: ProtocolType) {
|
|||||||
case 'shadowsocks':
|
case 'shadowsocks':
|
||||||
return {
|
return {
|
||||||
type: 'shadowsocks',
|
type: 'shadowsocks',
|
||||||
|
enable: false,
|
||||||
port: null,
|
port: null,
|
||||||
cipher: 'chacha20-ietf-poly1305',
|
cipher: 'chacha20-ietf-poly1305',
|
||||||
server_key: null,
|
server_key: null,
|
||||||
@ -13,14 +15,36 @@ export function getProtocolDefaultConfig(proto: ProtocolType) {
|
|||||||
obfs_path: null,
|
obfs_path: null,
|
||||||
} as any;
|
} as any;
|
||||||
case 'vmess':
|
case 'vmess':
|
||||||
return { type: 'vmess', port: null, transport: 'tcp', security: 'none' } as any;
|
return {
|
||||||
|
type: 'vmess',
|
||||||
|
enable: false,
|
||||||
|
port: null,
|
||||||
|
transport: 'tcp',
|
||||||
|
security: 'none',
|
||||||
|
} as any;
|
||||||
case 'vless':
|
case 'vless':
|
||||||
return { type: 'vless', port: null, transport: 'tcp', security: 'none', flow: 'none' } as any;
|
return {
|
||||||
|
type: 'vless',
|
||||||
|
enable: false,
|
||||||
|
port: null,
|
||||||
|
transport: 'tcp',
|
||||||
|
security: 'none',
|
||||||
|
flow: 'none',
|
||||||
|
xhttp_mode: XHTTP_MODES[0], // 'auto'
|
||||||
|
xhttp_extra: null,
|
||||||
|
} as any;
|
||||||
case 'trojan':
|
case 'trojan':
|
||||||
return { type: 'trojan', port: null, transport: 'tcp', security: 'tls' } as any;
|
return {
|
||||||
|
type: 'trojan',
|
||||||
|
enable: false,
|
||||||
|
port: null,
|
||||||
|
transport: 'tcp',
|
||||||
|
security: 'tls',
|
||||||
|
} as any;
|
||||||
case 'hysteria2':
|
case 'hysteria2':
|
||||||
return {
|
return {
|
||||||
type: 'hysteria2',
|
type: 'hysteria2',
|
||||||
|
enable: false,
|
||||||
port: null,
|
port: null,
|
||||||
hop_ports: null,
|
hop_ports: null,
|
||||||
hop_interval: null,
|
hop_interval: null,
|
||||||
@ -33,6 +57,7 @@ export function getProtocolDefaultConfig(proto: ProtocolType) {
|
|||||||
case 'tuic':
|
case 'tuic':
|
||||||
return {
|
return {
|
||||||
type: 'tuic',
|
type: 'tuic',
|
||||||
|
enable: false,
|
||||||
port: null,
|
port: null,
|
||||||
disable_sni: false,
|
disable_sni: false,
|
||||||
reduce_rtt: false,
|
reduce_rtt: false,
|
||||||
@ -46,17 +71,20 @@ export function getProtocolDefaultConfig(proto: ProtocolType) {
|
|||||||
case 'socks':
|
case 'socks':
|
||||||
return {
|
return {
|
||||||
type: 'socks',
|
type: 'socks',
|
||||||
|
enable: false,
|
||||||
port: null,
|
port: null,
|
||||||
} as any;
|
} as any;
|
||||||
case 'naive':
|
case 'naive':
|
||||||
return {
|
return {
|
||||||
type: 'naive',
|
type: 'naive',
|
||||||
|
enable: false,
|
||||||
port: null,
|
port: null,
|
||||||
security: 'none',
|
security: 'none',
|
||||||
} as any;
|
} as any;
|
||||||
case 'http':
|
case 'http':
|
||||||
return {
|
return {
|
||||||
type: 'http',
|
type: 'http',
|
||||||
|
enable: false,
|
||||||
port: null,
|
port: null,
|
||||||
security: 'none',
|
security: 'none',
|
||||||
} as any;
|
} as any;
|
||||||
|
|||||||
@ -211,7 +211,7 @@ export const PROTOCOL_FIELDS: Record<string, FieldConfig[]> = {
|
|||||||
condition: (p) => p.transport === 'grpc',
|
condition: (p) => p.transport === 'grpc',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'mode',
|
name: 'xhttp_mode',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
label: 'mode',
|
label: 'mode',
|
||||||
options: XHTTP_MODES,
|
options: XHTTP_MODES,
|
||||||
@ -220,7 +220,7 @@ export const PROTOCOL_FIELDS: Record<string, FieldConfig[]> = {
|
|||||||
condition: (p) => p.transport === 'xhttp',
|
condition: (p) => p.transport === 'xhttp',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'extra',
|
name: 'xhttp_extra',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
label: 'extra',
|
label: 'extra',
|
||||||
placeholder: '{}',
|
placeholder: '{}',
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
TRANSPORTS,
|
TRANSPORTS,
|
||||||
TUIC_CONGESTION,
|
TUIC_CONGESTION,
|
||||||
TUIC_UDP_RELAY_MODES,
|
TUIC_UDP_RELAY_MODES,
|
||||||
|
XHTTP_MODES,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
const nullableString = z.string().nullish();
|
const nullableString = z.string().nullish();
|
||||||
@ -18,9 +19,10 @@ const nullablePort = z.number().int().min(0).max(65535).nullish();
|
|||||||
|
|
||||||
const ss = z.object({
|
const ss = z.object({
|
||||||
type: z.literal('shadowsocks'),
|
type: z.literal('shadowsocks'),
|
||||||
|
enable: nullableBool,
|
||||||
host: nullableString,
|
host: nullableString,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
cipher: z.enum(SS_CIPHERS as any).nullish(),
|
cipher: z.enum(SS_CIPHERS).nullish(),
|
||||||
server_key: nullableString,
|
server_key: nullableString,
|
||||||
obfs: z.enum(['none', 'http', 'tls'] as const).nullish(),
|
obfs: z.enum(['none', 'http', 'tls'] as const).nullish(),
|
||||||
obfs_host: nullableString,
|
obfs_host: nullableString,
|
||||||
@ -29,10 +31,11 @@ const ss = z.object({
|
|||||||
|
|
||||||
const vmess = z.object({
|
const vmess = z.object({
|
||||||
type: z.literal('vmess'),
|
type: z.literal('vmess'),
|
||||||
|
enable: nullableBool,
|
||||||
host: nullableString,
|
host: nullableString,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
transport: z.enum(TRANSPORTS.vmess as any).nullish(),
|
transport: z.enum(TRANSPORTS.vmess).nullish(),
|
||||||
security: z.enum(SECURITY.vmess as any).nullish(),
|
security: z.enum(SECURITY.vmess).nullish(),
|
||||||
path: nullableString,
|
path: nullableString,
|
||||||
service_name: nullableString,
|
service_name: nullableString,
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
@ -42,13 +45,14 @@ const vmess = z.object({
|
|||||||
|
|
||||||
const vless = z.object({
|
const vless = z.object({
|
||||||
type: z.literal('vless'),
|
type: z.literal('vless'),
|
||||||
|
enable: nullableBool,
|
||||||
host: nullableString,
|
host: nullableString,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
transport: z.enum(TRANSPORTS.vless as any).nullish(),
|
transport: z.enum(TRANSPORTS.vless).nullish(),
|
||||||
security: z.enum(SECURITY.vless as any).nullish(),
|
security: z.enum(SECURITY.vless).nullish(),
|
||||||
path: nullableString,
|
path: nullableString,
|
||||||
service_name: nullableString,
|
service_name: nullableString,
|
||||||
flow: z.enum(FLOWS.vless as any).nullish(),
|
flow: z.enum(FLOWS.vless).nullish(),
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
allow_insecure: nullableBool,
|
allow_insecure: nullableBool,
|
||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
@ -57,11 +61,11 @@ const vless = z.object({
|
|||||||
reality_private_key: nullableString,
|
reality_private_key: nullableString,
|
||||||
reality_public_key: nullableString,
|
reality_public_key: nullableString,
|
||||||
reality_short_id: nullableString,
|
reality_short_id: nullableString,
|
||||||
mode: nullableString,
|
xhttp_mode: z.enum(XHTTP_MODES).nullish(),
|
||||||
extra: nullableString,
|
xhttp_extra: nullableString,
|
||||||
encryption: z.enum(ENCRYPTION_TYPES as any).nullish(),
|
encryption: z.enum(ENCRYPTION_TYPES).nullish(),
|
||||||
encryption_mode: z.enum(ENCRYPTION_MODES as any).nullish(),
|
encryption_mode: z.enum(ENCRYPTION_MODES).nullish(),
|
||||||
encryption_rtt: z.enum(ENCRYPTION_RTT as any).nullish(),
|
encryption_rtt: z.enum(ENCRYPTION_RTT).nullish(),
|
||||||
encryption_ticket: nullableString,
|
encryption_ticket: nullableString,
|
||||||
encryption_server_padding: nullableString,
|
encryption_server_padding: nullableString,
|
||||||
encryption_private_key: nullableString,
|
encryption_private_key: nullableString,
|
||||||
@ -71,10 +75,11 @@ const vless = z.object({
|
|||||||
|
|
||||||
const trojan = z.object({
|
const trojan = z.object({
|
||||||
type: z.literal('trojan'),
|
type: z.literal('trojan'),
|
||||||
|
enable: nullableBool,
|
||||||
host: nullableString,
|
host: nullableString,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
transport: z.enum(TRANSPORTS.trojan as any).nullish(),
|
transport: z.enum(TRANSPORTS.trojan).nullish(),
|
||||||
security: z.enum(SECURITY.trojan as any).nullish(),
|
security: z.enum(SECURITY.trojan).nullish(),
|
||||||
path: nullableString,
|
path: nullableString,
|
||||||
service_name: nullableString,
|
service_name: nullableString,
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
@ -84,12 +89,13 @@ const trojan = z.object({
|
|||||||
|
|
||||||
const hysteria2 = z.object({
|
const hysteria2 = z.object({
|
||||||
type: z.literal('hysteria2'),
|
type: z.literal('hysteria2'),
|
||||||
|
enable: nullableBool,
|
||||||
hop_ports: nullableString,
|
hop_ports: nullableString,
|
||||||
hop_interval: z.number().nullish(),
|
hop_interval: z.number().nullish(),
|
||||||
obfs_password: nullableString,
|
obfs_password: nullableString,
|
||||||
obfs: z.enum(['none', 'salamander'] as const).nullish(),
|
obfs: z.enum(['none', 'salamander'] as const).nullish(),
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
security: z.enum(SECURITY.hysteria2 as any).nullish(),
|
security: z.enum(SECURITY.hysteria2).nullish(),
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
allow_insecure: nullableBool,
|
allow_insecure: nullableBool,
|
||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
@ -99,13 +105,14 @@ const hysteria2 = z.object({
|
|||||||
|
|
||||||
const tuic = z.object({
|
const tuic = z.object({
|
||||||
type: z.literal('tuic'),
|
type: z.literal('tuic'),
|
||||||
|
enable: nullableBool,
|
||||||
host: nullableString,
|
host: nullableString,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
disable_sni: z.boolean().nullish(),
|
disable_sni: z.boolean().nullish(),
|
||||||
reduce_rtt: z.boolean().nullish(),
|
reduce_rtt: z.boolean().nullish(),
|
||||||
udp_relay_mode: z.enum(TUIC_UDP_RELAY_MODES as any).nullish(),
|
udp_relay_mode: z.enum(TUIC_UDP_RELAY_MODES).nullish(),
|
||||||
congestion_controller: z.enum(TUIC_CONGESTION as any).nullish(),
|
congestion_controller: z.enum(TUIC_CONGESTION).nullish(),
|
||||||
security: z.enum(SECURITY.tuic as any).nullish(),
|
security: z.enum(SECURITY.tuic).nullish(),
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
allow_insecure: nullableBool,
|
allow_insecure: nullableBool,
|
||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
@ -113,8 +120,9 @@ const tuic = z.object({
|
|||||||
|
|
||||||
const anytls = z.object({
|
const anytls = z.object({
|
||||||
type: z.literal('anytls'),
|
type: z.literal('anytls'),
|
||||||
|
enable: nullableBool,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
security: z.enum(SECURITY.anytls as any).nullish(),
|
security: z.enum(SECURITY.anytls).nullish(),
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
allow_insecure: nullableBool,
|
allow_insecure: nullableBool,
|
||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
@ -123,13 +131,15 @@ const anytls = z.object({
|
|||||||
|
|
||||||
const socks = z.object({
|
const socks = z.object({
|
||||||
type: z.literal('socks'),
|
type: z.literal('socks'),
|
||||||
|
enable: nullableBool,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
});
|
});
|
||||||
|
|
||||||
const naive = z.object({
|
const naive = z.object({
|
||||||
type: z.literal('naive'),
|
type: z.literal('naive'),
|
||||||
|
enable: nullableBool,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
security: z.enum(SECURITY.naive as any).nullish(),
|
security: z.enum(SECURITY.naive).nullish(),
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
allow_insecure: nullableBool,
|
allow_insecure: nullableBool,
|
||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
@ -137,8 +147,9 @@ const naive = z.object({
|
|||||||
|
|
||||||
const http = z.object({
|
const http = z.object({
|
||||||
type: z.literal('http'),
|
type: z.literal('http'),
|
||||||
|
enable: nullableBool,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
security: z.enum(SECURITY.http as any).nullish(),
|
security: z.enum(SECURITY.http).nullish(),
|
||||||
sni: nullableString,
|
sni: nullableString,
|
||||||
allow_insecure: nullableBool,
|
allow_insecure: nullableBool,
|
||||||
fingerprint: nullableString,
|
fingerprint: nullableString,
|
||||||
@ -146,9 +157,10 @@ const http = z.object({
|
|||||||
|
|
||||||
const mieru = z.object({
|
const mieru = z.object({
|
||||||
type: z.literal('mieru'),
|
type: z.literal('mieru'),
|
||||||
|
enable: nullableBool,
|
||||||
port: nullablePort,
|
port: nullablePort,
|
||||||
multiplex: z.enum(multiplexLevels).nullish(),
|
multiplex: z.enum(multiplexLevels).nullish(),
|
||||||
transport: z.enum(TRANSPORTS.mieru as any).nullish(),
|
transport: z.enum(TRANSPORTS.mieru).nullish(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const protocolApiScheme = z.discriminatedUnion('type', [
|
export const protocolApiScheme = z.discriminatedUnion('type', [
|
||||||
|
|||||||
@ -14,21 +14,3 @@ export async function generateMLKEM768KeyPair() {
|
|||||||
privateKey: toB64Url(new Uint8Array(mlkemPrivateKeyRaw)),
|
privateKey: toB64Url(new Uint8Array(mlkemPrivateKeyRaw)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const test = await generateMLKEM768KeyPair();
|
|
||||||
|
|
||||||
console.log('生成的密钥信息:');
|
|
||||||
console.log('私钥长度:', test.privateKey.length);
|
|
||||||
console.log('公钥长度:', test.publicKey.length);
|
|
||||||
console.log(test);
|
|
||||||
|
|
||||||
// 从 VLESS 配置字符串中提取的密钥
|
|
||||||
const extractedKeys = {
|
|
||||||
decryptionKey:
|
|
||||||
'B2qLcDHhiztvBaB4BhMCnU-fM-axE4DZowMK9TIvL5qma2M5fVAmFswPdfej2N1SmlJa5ppidC1ksHLVfoEvjw',
|
|
||||||
encryptionKey:
|
|
||||||
'FgEI5sTIzBgZS4psemcdGDCRb5JvdDFqzOeVvLJYEmmZFSgxG1SkYxx8DUO-txGqvYdhFruja-ZzmIQoGOCQEMd0RbK4BhYRm4jE96GXTytu7Hi7pYo9-2SEuKC10righ2ceqis0LoggubajmAFvkop6igZfcmEA3MJ9aHpjGiUszDWy0pA99WY7c1ebTom8xQetW2J2OnkrA_UE8Cuy8AhMPvSBQrsFNmBqnttfVlmKzPS3RWBkIpAZIie1XMGk76nDEXgEsBulEhmYO2Mc-oRfirQfGmYfD1ybYBs9gAKgzQixTrkJtOuRU4GjkwQpxuyeVuww8Pin19IzAlVpUdeEJPVlRHwQDNJ__YsZDJB6rSIaY4tM4ysSs3N-1mmYvkVs1WSa0uy14KRheqMIPfsw_KxLBvp2_ZdZeQIrW3dDxgOuxXWip-g78desyONwwkx0bQK-JDcELHEH0TVmTOe4mSqW1fPI6jJI_ZChmQwBxZKpp2RN2xKmw6W3z4ETdUQDTZgePEkXDveneltNHrGT73WJQ7uEs6hwfXwD2vGcuFx6DKybfYAzgWh9t4IM3mBI7OiGqDItigqIDgaBF6LPTXwby3VxgfEVXXqXzMVdc0BL4da1BPGF-lAtvVJtbpBp7_O_JlB1wWajv8eLCpKjRiKGQey7oLZyRROQ3loNFyRDBjoBVSa2etCmFRCV1wegIBqmJRImJQxPsIV_kkIxeWmPfUIik1GpSTtrWkAFCXZAl4oSFiNhLwlmW_g_s_glGeqcZBNAkiw-OlssPESmqLti-bSJPbmoJMNE0poJXCYX27YyPKVyCtJKM5pzOkUBqMIVsxliU4N2IaWHb8uMYKW8U0tQ8aaeR3Bf5ll0fza78aY3lSQw7At21XkN9LhugzWv-_CPGZQpStGCWtJl5dChLPlmZbRddmekp7UEfXAPW6ONyNrFZ9WUvBCwsdmXcChTXwkg-FIMFHpU25c6IwWqyveuZrQmpvZYEQSgyWhsUBMPywI1vqiLfuhnaqBNU9wPbGA0IrG-w9UGpQErl9ssqPdZRjaIbiM-PKKooehp34QzU3ENj5h944gC4yHMkMzOPUaFl8YUWwmkGCsTNnJyq7NLucTOdQSUsLM2QWEkxWk9c6YyQkwx2mUsR1eGmrsbo8BGK6ppbgotpzMjGZfPOQRdHYh0lzGQ28HGetJ97Vei8Vxxl2u4j6CfHTPET4EHZ_uTuPtRIaaMegKOtUgyKqKj4BqsB5tatIECz8N1H_LP5qlRvUxYqrU-JikuRCoAdfl7VFYLLhe_80cny2UoWFpJ1iovprnALDbIIKZ03LG0OXI8dfEolQijO1xhwoUb7Ci3Xma-wKyEWHhSw0e600SRT0RhDuOh5hVg4KVLILUDDuMIJQyiPRBW3qwAMCk1SzCeXvFqbWFU-TQnVoLGNboaygQ6aumgP_B4DBcmEdyVqAMHIOdAPENvLauALKSiBHVjEHgeB7KpVCGsIGOjdCgb4UmKdsxnXBxC7peXspcmGgmHL-VU6KdMhwHwq1mYeNVEzeshb5mWYj5fgysp_e5U--geYKefs5Y',
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('提取的密钥信息:');
|
|
||||||
console.log('私钥长度:', extractedKeys.decryptionKey.length);
|
|
||||||
console.log('公钥长度:', extractedKeys.encryptionKey.length);
|
|
||||||
|
|||||||
@ -364,24 +364,18 @@ export default function ServerForm(props: {
|
|||||||
}, [initialValues]);
|
}, [initialValues]);
|
||||||
|
|
||||||
async function handleSubmit(values: Record<string, any>) {
|
async function handleSubmit(values: Record<string, any>) {
|
||||||
const filtered = (values?.protocols || []).filter((p: any, index: number) => {
|
const filteredProtocols = (values?.protocols || []).filter((protocol: any) => {
|
||||||
const port = Number(p?.port);
|
const port = Number(protocol?.port);
|
||||||
const protocolType = PROTOCOLS[index];
|
return protocol && Number.isFinite(port) && port > 0 && port <= 65535;
|
||||||
return protocolType && p && Number.isFinite(port) && port > 0 && port <= 65535;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (filtered.length === 0) {
|
|
||||||
toast.error(t('validation_failed'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
name: values.name,
|
name: values.name,
|
||||||
country: values.country,
|
country: values.country,
|
||||||
city: values.city,
|
city: values.city,
|
||||||
ratio: Number(values.ratio || 1),
|
ratio: values.ratio || 1,
|
||||||
address: values.address,
|
address: values.address,
|
||||||
protocols: filtered,
|
protocols: filteredProtocols,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ok = await onSubmit(result);
|
const ok = await onSubmit(result);
|
||||||
@ -507,6 +501,7 @@ export default function ServerForm(props: {
|
|||||||
{t('protocol_configurations_desc')}
|
{t('protocol_configurations_desc')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Accordion
|
<Accordion
|
||||||
type='single'
|
type='single'
|
||||||
collapsible
|
collapsible
|
||||||
@ -520,39 +515,45 @@ export default function ServerForm(props: {
|
|||||||
PROTOCOLS.findIndex((t) => t === type),
|
PROTOCOLS.findIndex((t) => t === type),
|
||||||
);
|
);
|
||||||
const current = (protocolsValues[i] || {}) as Record<string, any>;
|
const current = (protocolsValues[i] || {}) as Record<string, any>;
|
||||||
const isEnabled = current.port && Number(current.port) > 0;
|
|
||||||
const fields = PROTOCOL_FIELDS[type] || [];
|
const fields = PROTOCOL_FIELDS[type] || [];
|
||||||
return (
|
return (
|
||||||
<AccordionItem key={type} value={type} className='mb-2 rounded-lg border'>
|
<AccordionItem key={type} value={type} className='mb-2 rounded-lg border'>
|
||||||
<AccordionTrigger className='px-4 py-3 hover:no-underline'>
|
<AccordionTrigger className='px-4 py-3 hover:no-underline'>
|
||||||
<div className='flex w-full items-center justify-between'>
|
<div className='flex w-full items-center justify-between'>
|
||||||
<div className='flex flex-col items-start'>
|
<div className='flex flex-col items-start gap-1'>
|
||||||
<div className='flex items-center gap-2'>
|
<div className='flex items-center gap-1'>
|
||||||
<span className='font-medium capitalize'>{type}</span>
|
<span className='font-medium capitalize'>{type}</span>
|
||||||
</div>
|
{current.transport && (
|
||||||
<span
|
<Badge variant='secondary' className='text-xs'>
|
||||||
className={cn(
|
{current.transport.toUpperCase()}
|
||||||
'text-muted-foreground text-xs',
|
</Badge>
|
||||||
isEnabled && 'text-green-500',
|
|
||||||
)}
|
)}
|
||||||
>
|
{current.security && current.security !== 'none' && (
|
||||||
{isEnabled ? t('enabled') : t('disabled')}
|
<Badge variant='outline' className='text-xs'>
|
||||||
</span>
|
{current.security.toUpperCase()}
|
||||||
</div>
|
</Badge>
|
||||||
<div className='mr-2 flex items-center gap-1'>
|
)}
|
||||||
{current.transport && (
|
{current.port && <Badge className='text-xs'>{current.port}</Badge>}
|
||||||
<Badge variant='secondary' className='text-xs'>
|
</div>
|
||||||
{current.transport.toUpperCase()}
|
<div className='flex items-center gap-1'>
|
||||||
</Badge>
|
<span
|
||||||
)}
|
className={cn(
|
||||||
{current.security && current.security !== 'none' && (
|
'text-xs',
|
||||||
<Badge variant='outline' className='text-xs'>
|
current.enable ? 'text-green-500' : 'text-muted-foreground',
|
||||||
{current.security.toUpperCase()}
|
)}
|
||||||
</Badge>
|
>
|
||||||
)}
|
{current.enable ? t('enabled') : t('disabled')}
|
||||||
|
</span>
|
||||||
{current.port && <Badge className='text-xs'>{current.port}</Badge>}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Switch
|
||||||
|
className='mr-2'
|
||||||
|
checked={!!current.enable}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
form.setValue(`protocols.${i}.enable`, checked);
|
||||||
|
}}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
<AccordionContent className='px-4 pb-4 pt-0'>
|
<AccordionContent className='px-4 pb-4 pt-0'>
|
||||||
@ -621,7 +622,8 @@ export default function ServerForm(props: {
|
|||||||
return false;
|
return false;
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{loading && <Icon icon='mdi:loading' className='mr-2 animate-spin' />} {t('confirm')}
|
{loading && <Icon icon='mdi:loading' className='mr-2 animate-spin' />}
|
||||||
|
{t('confirm')}
|
||||||
</Button>
|
</Button>
|
||||||
</SheetFooter>
|
</SheetFooter>
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
|
|||||||
31
apps/admin/services/admin/typings.d.ts
vendored
31
apps/admin/services/admin/typings.d.ts
vendored
@ -1496,6 +1496,7 @@ declare namespace API {
|
|||||||
type Protocol = {
|
type Protocol = {
|
||||||
type: string;
|
type: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
enable: boolean;
|
||||||
security?: string;
|
security?: string;
|
||||||
sni?: string;
|
sni?: string;
|
||||||
allow_insecure?: boolean;
|
allow_insecure?: boolean;
|
||||||
@ -1519,10 +1520,6 @@ declare namespace API {
|
|||||||
reduce_rtt?: boolean;
|
reduce_rtt?: boolean;
|
||||||
udp_relay_mode?: string;
|
udp_relay_mode?: string;
|
||||||
congestion_controller?: string;
|
congestion_controller?: string;
|
||||||
/** obfs, v2ray-plugin, simple-obfs */
|
|
||||||
plugin?: string;
|
|
||||||
/** plugin options, eg: obfs=http;obfs-host=www.bing.com */
|
|
||||||
plugin_options?: string;
|
|
||||||
/** mux, eg: off/low/medium/high */
|
/** mux, eg: off/low/medium/high */
|
||||||
multiplex?: string;
|
multiplex?: string;
|
||||||
/** padding scheme */
|
/** padding scheme */
|
||||||
@ -1531,6 +1528,32 @@ declare namespace API {
|
|||||||
up_mbps?: number;
|
up_mbps?: number;
|
||||||
/** download speed limit */
|
/** download speed limit */
|
||||||
down_mbps?: number;
|
down_mbps?: number;
|
||||||
|
/** obfs, 'none', 'http', 'tls' */
|
||||||
|
obfs?: string;
|
||||||
|
/** obfs host */
|
||||||
|
obfs_host?: string;
|
||||||
|
/** obfs path */
|
||||||
|
obfs_path?: string;
|
||||||
|
/** xhttp mode */
|
||||||
|
xhttp_mode?: string;
|
||||||
|
/** xhttp extra path */
|
||||||
|
xhttp_extra?: string;
|
||||||
|
/** encryption,'none', 'mlkem768x25519plus' */
|
||||||
|
encryption?: string;
|
||||||
|
/** encryption mode,'native', 'xorpub', 'random' */
|
||||||
|
encryption_mode?: string;
|
||||||
|
/** encryption rtt,'0rtt', '1rtt' */
|
||||||
|
encryption_rtt?: string;
|
||||||
|
/** encryption ticket */
|
||||||
|
encryption_ticket?: string;
|
||||||
|
/** encryption server padding */
|
||||||
|
encryption_server_padding?: string;
|
||||||
|
/** encryption private key */
|
||||||
|
encryption_private_key?: string;
|
||||||
|
/** encryption client padding */
|
||||||
|
encryption_client_padding?: string;
|
||||||
|
/** encryption password */
|
||||||
|
encryption_password?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PubilcRegisterConfig = {
|
type PubilcRegisterConfig = {
|
||||||
|
|||||||
31
apps/admin/services/common/typings.d.ts
vendored
31
apps/admin/services/common/typings.d.ts
vendored
@ -504,6 +504,7 @@ declare namespace API {
|
|||||||
type Protocol = {
|
type Protocol = {
|
||||||
type: string;
|
type: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
enable: boolean;
|
||||||
security?: string;
|
security?: string;
|
||||||
sni?: string;
|
sni?: string;
|
||||||
allow_insecure?: boolean;
|
allow_insecure?: boolean;
|
||||||
@ -527,10 +528,6 @@ declare namespace API {
|
|||||||
reduce_rtt?: boolean;
|
reduce_rtt?: boolean;
|
||||||
udp_relay_mode?: string;
|
udp_relay_mode?: string;
|
||||||
congestion_controller?: string;
|
congestion_controller?: string;
|
||||||
/** obfs, v2ray-plugin, simple-obfs */
|
|
||||||
plugin?: string;
|
|
||||||
/** plugin options, eg: obfs=http;obfs-host=www.bing.com */
|
|
||||||
plugin_options?: string;
|
|
||||||
/** mux, eg: off/low/medium/high */
|
/** mux, eg: off/low/medium/high */
|
||||||
multiplex?: string;
|
multiplex?: string;
|
||||||
/** padding scheme */
|
/** padding scheme */
|
||||||
@ -539,6 +536,32 @@ declare namespace API {
|
|||||||
up_mbps?: number;
|
up_mbps?: number;
|
||||||
/** download speed limit */
|
/** download speed limit */
|
||||||
down_mbps?: number;
|
down_mbps?: number;
|
||||||
|
/** obfs, 'none', 'http', 'tls' */
|
||||||
|
obfs?: string;
|
||||||
|
/** obfs host */
|
||||||
|
obfs_host?: string;
|
||||||
|
/** obfs path */
|
||||||
|
obfs_path?: string;
|
||||||
|
/** xhttp mode */
|
||||||
|
xhttp_mode?: string;
|
||||||
|
/** xhttp extra path */
|
||||||
|
xhttp_extra?: string;
|
||||||
|
/** encryption,'none', 'mlkem768x25519plus' */
|
||||||
|
encryption?: string;
|
||||||
|
/** encryption mode,'native', 'xorpub', 'random' */
|
||||||
|
encryption_mode?: string;
|
||||||
|
/** encryption rtt,'0rtt', '1rtt' */
|
||||||
|
encryption_rtt?: string;
|
||||||
|
/** encryption ticket */
|
||||||
|
encryption_ticket?: string;
|
||||||
|
/** encryption server padding */
|
||||||
|
encryption_server_padding?: string;
|
||||||
|
/** encryption private key */
|
||||||
|
encryption_private_key?: string;
|
||||||
|
/** encryption client padding */
|
||||||
|
encryption_client_padding?: string;
|
||||||
|
/** encryption password */
|
||||||
|
encryption_password?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PubilcRegisterConfig = {
|
type PubilcRegisterConfig = {
|
||||||
|
|||||||
31
apps/user/services/common/typings.d.ts
vendored
31
apps/user/services/common/typings.d.ts
vendored
@ -504,6 +504,7 @@ declare namespace API {
|
|||||||
type Protocol = {
|
type Protocol = {
|
||||||
type: string;
|
type: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
enable: boolean;
|
||||||
security?: string;
|
security?: string;
|
||||||
sni?: string;
|
sni?: string;
|
||||||
allow_insecure?: boolean;
|
allow_insecure?: boolean;
|
||||||
@ -527,10 +528,6 @@ declare namespace API {
|
|||||||
reduce_rtt?: boolean;
|
reduce_rtt?: boolean;
|
||||||
udp_relay_mode?: string;
|
udp_relay_mode?: string;
|
||||||
congestion_controller?: string;
|
congestion_controller?: string;
|
||||||
/** obfs, v2ray-plugin, simple-obfs */
|
|
||||||
plugin?: string;
|
|
||||||
/** plugin options, eg: obfs=http;obfs-host=www.bing.com */
|
|
||||||
plugin_options?: string;
|
|
||||||
/** mux, eg: off/low/medium/high */
|
/** mux, eg: off/low/medium/high */
|
||||||
multiplex?: string;
|
multiplex?: string;
|
||||||
/** padding scheme */
|
/** padding scheme */
|
||||||
@ -539,6 +536,32 @@ declare namespace API {
|
|||||||
up_mbps?: number;
|
up_mbps?: number;
|
||||||
/** download speed limit */
|
/** download speed limit */
|
||||||
down_mbps?: number;
|
down_mbps?: number;
|
||||||
|
/** obfs, 'none', 'http', 'tls' */
|
||||||
|
obfs?: string;
|
||||||
|
/** obfs host */
|
||||||
|
obfs_host?: string;
|
||||||
|
/** obfs path */
|
||||||
|
obfs_path?: string;
|
||||||
|
/** xhttp mode */
|
||||||
|
xhttp_mode?: string;
|
||||||
|
/** xhttp extra path */
|
||||||
|
xhttp_extra?: string;
|
||||||
|
/** encryption,'none', 'mlkem768x25519plus' */
|
||||||
|
encryption?: string;
|
||||||
|
/** encryption mode,'native', 'xorpub', 'random' */
|
||||||
|
encryption_mode?: string;
|
||||||
|
/** encryption rtt,'0rtt', '1rtt' */
|
||||||
|
encryption_rtt?: string;
|
||||||
|
/** encryption ticket */
|
||||||
|
encryption_ticket?: string;
|
||||||
|
/** encryption server padding */
|
||||||
|
encryption_server_padding?: string;
|
||||||
|
/** encryption private key */
|
||||||
|
encryption_private_key?: string;
|
||||||
|
/** encryption client padding */
|
||||||
|
encryption_client_padding?: string;
|
||||||
|
/** encryption password */
|
||||||
|
encryption_password?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PubilcRegisterConfig = {
|
type PubilcRegisterConfig = {
|
||||||
|
|||||||
31
apps/user/services/user/typings.d.ts
vendored
31
apps/user/services/user/typings.d.ts
vendored
@ -543,6 +543,7 @@ declare namespace API {
|
|||||||
type Protocol = {
|
type Protocol = {
|
||||||
type: string;
|
type: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
enable: boolean;
|
||||||
security?: string;
|
security?: string;
|
||||||
sni?: string;
|
sni?: string;
|
||||||
allow_insecure?: boolean;
|
allow_insecure?: boolean;
|
||||||
@ -566,10 +567,6 @@ declare namespace API {
|
|||||||
reduce_rtt?: boolean;
|
reduce_rtt?: boolean;
|
||||||
udp_relay_mode?: string;
|
udp_relay_mode?: string;
|
||||||
congestion_controller?: string;
|
congestion_controller?: string;
|
||||||
/** obfs, v2ray-plugin, simple-obfs */
|
|
||||||
plugin?: string;
|
|
||||||
/** plugin options, eg: obfs=http;obfs-host=www.bing.com */
|
|
||||||
plugin_options?: string;
|
|
||||||
/** mux, eg: off/low/medium/high */
|
/** mux, eg: off/low/medium/high */
|
||||||
multiplex?: string;
|
multiplex?: string;
|
||||||
/** padding scheme */
|
/** padding scheme */
|
||||||
@ -578,6 +575,32 @@ declare namespace API {
|
|||||||
up_mbps?: number;
|
up_mbps?: number;
|
||||||
/** download speed limit */
|
/** download speed limit */
|
||||||
down_mbps?: number;
|
down_mbps?: number;
|
||||||
|
/** obfs, 'none', 'http', 'tls' */
|
||||||
|
obfs?: string;
|
||||||
|
/** obfs host */
|
||||||
|
obfs_host?: string;
|
||||||
|
/** obfs path */
|
||||||
|
obfs_path?: string;
|
||||||
|
/** xhttp mode */
|
||||||
|
xhttp_mode?: string;
|
||||||
|
/** xhttp extra path */
|
||||||
|
xhttp_extra?: string;
|
||||||
|
/** encryption,'none', 'mlkem768x25519plus' */
|
||||||
|
encryption?: string;
|
||||||
|
/** encryption mode,'native', 'xorpub', 'random' */
|
||||||
|
encryption_mode?: string;
|
||||||
|
/** encryption rtt,'0rtt', '1rtt' */
|
||||||
|
encryption_rtt?: string;
|
||||||
|
/** encryption ticket */
|
||||||
|
encryption_ticket?: string;
|
||||||
|
/** encryption server padding */
|
||||||
|
encryption_server_padding?: string;
|
||||||
|
/** encryption private key */
|
||||||
|
encryption_private_key?: string;
|
||||||
|
/** encryption client padding */
|
||||||
|
encryption_client_padding?: string;
|
||||||
|
/** encryption password */
|
||||||
|
encryption_password?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PubilcRegisterConfig = {
|
type PubilcRegisterConfig = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user