mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-04-18 13:35:56 +00:00
feat: add support for 'extra' field in VLESS clients with XHTTP transmission
- Persist 'extra' field in the database. - Update UI to include 'XHTTP Extra raw JSON' input in single and bulk client forms. - Include 'extra' parameter in VLESS client URLs generated in the panel. - Support 'extra' parameter in subscription link generation on the backend.
This commit is contained in:
parent
38d87230d3
commit
e28efa7adc
5 changed files with 27 additions and 3 deletions
|
|
@ -121,4 +121,5 @@ type Client struct {
|
||||||
Reset int `json:"reset" form:"reset"` // Reset period in days
|
Reset int `json:"reset" form:"reset"` // Reset period in days
|
||||||
CreatedAt int64 `json:"created_at,omitempty"` // Creation timestamp
|
CreatedAt int64 `json:"created_at,omitempty"` // Creation timestamp
|
||||||
UpdatedAt int64 `json:"updated_at,omitempty"` // Last update timestamp
|
UpdatedAt int64 `json:"updated_at,omitempty"` // Last update timestamp
|
||||||
|
Extra string `json:"extra,omitempty" form:"extra"` // XHTTP extra raw JSON
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -406,6 +406,9 @@ func (s *SubService) genVlessLink(inbound *model.Inbound, email string) string {
|
||||||
params["host"] = searchHost(headers)
|
params["host"] = searchHost(headers)
|
||||||
}
|
}
|
||||||
params["mode"] = xhttp["mode"].(string)
|
params["mode"] = xhttp["mode"].(string)
|
||||||
|
if clients[clientIndex].Extra != "" {
|
||||||
|
params["extra"] = clients[clientIndex].Extra
|
||||||
|
}
|
||||||
}
|
}
|
||||||
security, _ := stream["security"].(string)
|
security, _ := stream["security"].(string)
|
||||||
if security == "tls" {
|
if security == "tls" {
|
||||||
|
|
|
||||||
|
|
@ -1418,7 +1418,7 @@ class Inbound extends XrayCommonClass {
|
||||||
return 'vmess://' + Base64.encode(JSON.stringify(obj, null, 2));
|
return 'vmess://' + Base64.encode(JSON.stringify(obj, null, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
genVLESSLink(address = '', port = this.port, forceTls, remark = '', clientId, flow) {
|
genVLESSLink(address = '', port = this.port, forceTls, remark = '', clientId, flow, extra = '') {
|
||||||
const uuid = clientId;
|
const uuid = clientId;
|
||||||
const type = this.stream.network;
|
const type = this.stream.network;
|
||||||
const security = forceTls == 'same' ? this.stream.security : forceTls;
|
const security = forceTls == 'same' ? this.stream.security : forceTls;
|
||||||
|
|
@ -1465,6 +1465,12 @@ class Inbound extends XrayCommonClass {
|
||||||
params.set("path", xhttp.path);
|
params.set("path", xhttp.path);
|
||||||
params.set("host", xhttp.host?.length > 0 ? xhttp.host : this.getHeader(xhttp, 'host'));
|
params.set("host", xhttp.host?.length > 0 ? xhttp.host : this.getHeader(xhttp, 'host'));
|
||||||
params.set("mode", xhttp.mode);
|
params.set("mode", xhttp.mode);
|
||||||
|
if (extra && extra.trim() !== "") {
|
||||||
|
// xray handles it but let's make sure it's valid json structure.
|
||||||
|
// The client already inputs it or handles it.
|
||||||
|
// We just pass the string.
|
||||||
|
params.set("extra", extra.trim());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1716,7 +1722,7 @@ class Inbound extends XrayCommonClass {
|
||||||
case Protocols.VMESS:
|
case Protocols.VMESS:
|
||||||
return this.genVmessLink(address, port, forceTls, remark, client.id, client.security);
|
return this.genVmessLink(address, port, forceTls, remark, client.id, client.security);
|
||||||
case Protocols.VLESS:
|
case Protocols.VLESS:
|
||||||
return this.genVLESSLink(address, port, forceTls, remark, client.id, client.flow);
|
return this.genVLESSLink(address, port, forceTls, remark, client.id, client.flow, client.extra);
|
||||||
case Protocols.SHADOWSOCKS:
|
case Protocols.SHADOWSOCKS:
|
||||||
return this.genSSLink(address, port, forceTls, remark, this.isSSMultiUser ? client.password : '');
|
return this.genSSLink(address, port, forceTls, remark, this.isSSMultiUser ? client.password : '');
|
||||||
case Protocols.TROJAN:
|
case Protocols.TROJAN:
|
||||||
|
|
@ -2059,7 +2065,8 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
||||||
comment = '',
|
comment = '',
|
||||||
reset = 0,
|
reset = 0,
|
||||||
created_at = undefined,
|
created_at = undefined,
|
||||||
updated_at = undefined
|
updated_at = undefined,
|
||||||
|
extra = ''
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
@ -2075,6 +2082,7 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
||||||
this.reset = reset;
|
this.reset = reset;
|
||||||
this.created_at = created_at;
|
this.created_at = created_at;
|
||||||
this.updated_at = updated_at;
|
this.updated_at = updated_at;
|
||||||
|
this.extra = extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJson(json = {}) {
|
static fromJson(json = {}) {
|
||||||
|
|
@ -2092,6 +2100,7 @@ Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
|
||||||
json.reset,
|
json.reset,
|
||||||
json.created_at,
|
json.created_at,
|
||||||
json.updated_at,
|
json.updated_at,
|
||||||
|
json.extra
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,9 @@
|
||||||
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item v-if="inbound.protocol === Protocols.VLESS && inbound.network === 'xhttp'" label='XHTTP Extra raw JSON'>
|
||||||
|
<a-textarea v-model.trim="client.extra" :auto-size="{ minRows: 2, maxRows: 5 }" placeholder='{"xmux":{"maxConnections":1}}'></a-textarea>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@
|
||||||
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
<a-select-option v-for="key in TLS_FLOW_CONTROL" :value="key">[[ key ]]</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item v-if="clientsBulkModal.inbound.protocol === Protocols.VLESS && clientsBulkModal.inbound.network === 'xhttp'" label='XHTTP Extra raw JSON'>
|
||||||
|
<a-textarea v-model.trim="clientsBulkModal.extra" :auto-size="{ minRows: 2, maxRows: 5 }" placeholder='{"xmux":{"maxConnections":1}}'></a-textarea>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item v-if="app.subSettings?.enable">
|
<a-form-item v-if="app.subSettings?.enable">
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
|
|
@ -147,6 +150,7 @@
|
||||||
tgId: '',
|
tgId: '',
|
||||||
security: "auto",
|
security: "auto",
|
||||||
flow: "",
|
flow: "",
|
||||||
|
extra: "",
|
||||||
delayedStart: false,
|
delayedStart: false,
|
||||||
reset: 0,
|
reset: 0,
|
||||||
ok() {
|
ok() {
|
||||||
|
|
@ -175,6 +179,9 @@
|
||||||
if (clientsBulkModal.inbound.canEnableTlsFlow()) {
|
if (clientsBulkModal.inbound.canEnableTlsFlow()) {
|
||||||
newClient.flow = clientsBulkModal.flow;
|
newClient.flow = clientsBulkModal.flow;
|
||||||
}
|
}
|
||||||
|
if (clientsBulkModal.inbound.protocol === Protocols.VLESS && clientsBulkModal.inbound.network === 'xhttp') {
|
||||||
|
newClient.extra = clientsBulkModal.extra;
|
||||||
|
}
|
||||||
newClient.reset = clientsBulkModal.reset;
|
newClient.reset = clientsBulkModal.reset;
|
||||||
clients.push(newClient);
|
clients.push(newClient);
|
||||||
}
|
}
|
||||||
|
|
@ -203,6 +210,7 @@
|
||||||
this.tgId = '';
|
this.tgId = '';
|
||||||
this.security = "auto";
|
this.security = "auto";
|
||||||
this.flow = "";
|
this.flow = "";
|
||||||
|
this.extra = "";
|
||||||
this.dbInbound = new DBInbound(dbInbound);
|
this.dbInbound = new DBInbound(dbInbound);
|
||||||
this.inbound = dbInbound.toInbound();
|
this.inbound = dbInbound.toInbound();
|
||||||
this.delayedStart = false;
|
this.delayedStart = false;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue