Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/assets/js/model/inbound.js45
-rw-r--r--web/assets/js/model/outbound.js8
-rw-r--r--web/controller/server.go10
-rw-r--r--web/html/form/outbound.html5
-rw-r--r--web/html/form/protocol/vless.html24
-rw-r--r--web/html/form/tls_settings.html8
-rw-r--r--web/html/inbounds.html6
-rw-r--r--web/html/modals/inbound_info_modal.html6
-rw-r--r--web/html/modals/inbound_modal.html48
-rw-r--r--web/service/server.go50
-rw-r--r--web/translation/translate.ar_EG.toml1
-rw-r--r--web/translation/translate.en_US.toml1
-rw-r--r--web/translation/translate.es_ES.toml1
-rw-r--r--web/translation/translate.fa_IR.toml1
-rw-r--r--web/translation/translate.id_ID.toml1
-rw-r--r--web/translation/translate.ja_JP.toml1
-rw-r--r--web/translation/translate.pt_BR.toml1
-rw-r--r--web/translation/translate.ru_RU.toml1
-rw-r--r--web/translation/translate.tr_TR.toml1
-rw-r--r--web/translation/translate.uk_UA.toml1
-rw-r--r--web/translation/translate.vi_VN.toml3
-rw-r--r--web/translation/translate.zh_CN.toml1
-rw-r--r--web/translation/translate.zh_TW.toml1
23 files changed, 190 insertions, 35 deletions
diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js
index c91dbd11..1fc8ea19 100644
--- a/web/assets/js/model/inbound.js
+++ b/web/assets/js/model/inbound.js
@@ -1301,6 +1301,7 @@ class Inbound extends XrayCommonClass {
const security = forceTls == 'same' ? this.stream.security : forceTls;
const params = new Map();
params.set("type", this.stream.network);
+ params.set("encryption", this.settings.encryption);
switch (type) {
case "tcp":
const tcp = this.stream.tcp;
@@ -1859,13 +1860,16 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
constructor(
protocol,
vlesses = [new Inbound.VLESSSettings.VLESS()],
- decryption = 'none',
- fallbacks = []
+ decryption = "none",
+ encryption = "",
+ fallbacks = [],
) {
super(protocol);
this.vlesses = vlesses;
this.decryption = decryption;
+ this.encryption = encryption;
this.fallbacks = fallbacks;
+ this.selectedAuth = "X25519, not Post-Quantum";
}
addFallback() {
@@ -1876,22 +1880,43 @@ Inbound.VLESSSettings = class extends Inbound.Settings {
this.fallbacks.splice(index, 1);
}
- // decryption should be set to static value
static fromJson(json = {}) {
- return new Inbound.VLESSSettings(
+ const obj = new Inbound.VLESSSettings(
Protocols.VLESS,
- json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),
- json.decryption || 'none',
- Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),);
+ (json.clients || []).map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),
+ json.decryption,
+ json.encryption,
+ Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks || [])
+ );
+ obj.selectedAuth = json.selectedAuth || "X25519, not Post-Quantum";
+ return obj;
}
+
toJson() {
- return {
+ const json = {
clients: Inbound.VLESSSettings.toJsonArray(this.vlesses),
- decryption: this.decryption,
- fallbacks: Inbound.VLESSSettings.toJsonArray(this.fallbacks),
};
+
+ if (this.decryption) {
+ json.decryption = this.decryption;
+ }
+
+ if (this.encryption) {
+ json.encryption = this.encryption;
+ }
+
+ if (this.fallbacks && this.fallbacks.length > 0) {
+ json.fallbacks = Inbound.VLESSSettings.toJsonArray(this.fallbacks);
+ }
+ if (this.selectedAuth) {
+ json.selectedAuth = this.selectedAuth;
+ }
+
+ return json;
}
+
+
};
Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js
index ee78795f..2d5660fb 100644
--- a/web/assets/js/model/outbound.js
+++ b/web/assets/js/model/outbound.js
@@ -813,7 +813,7 @@ class Outbound extends CommonClass {
var settings;
switch (protocol) {
case Protocols.VLESS:
- settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? '');
+ settings = new Outbound.VLESSSettings(address, port, userData, url.searchParams.get('flow') ?? '', url.searchParams.get('encryption') ?? 'none');
break;
case Protocols.Trojan:
settings = new Outbound.TrojanSettings(address, port, userData);
@@ -1046,13 +1046,13 @@ Outbound.VmessSettings = class extends CommonClass {
}
};
Outbound.VLESSSettings = class extends CommonClass {
- constructor(address, port, id, flow, encryption = 'none') {
+ constructor(address, port, id, flow, encryption) {
super();
this.address = address;
this.port = port;
this.id = id;
this.flow = flow;
- this.encryption = encryption
+ this.encryption = encryption;
}
static fromJson(json = {}) {
@@ -1071,7 +1071,7 @@ Outbound.VLESSSettings = class extends CommonClass {
vnext: [{
address: this.address,
port: this.port,
- users: [{ id: this.id, flow: this.flow, encryption: 'none', }],
+ users: [{ id: this.id, flow: this.flow, encryption: this.encryption }],
}],
};
}
diff --git a/web/controller/server.go b/web/controller/server.go
index 2d2f741e..b1174b8f 100644
--- a/web/controller/server.go
+++ b/web/controller/server.go
@@ -55,6 +55,7 @@ func (a *ServerController) initRouter(g *gin.RouterGroup) {
g.POST("/getNewX25519Cert", a.getNewX25519Cert)
g.POST("/getNewmldsa65", a.getNewmldsa65)
g.POST("/getNewEchCert", a.getNewEchCert)
+ g.POST("/getNewVlessEnc", a.getNewVlessEnc)
}
func (a *ServerController) refreshStatus() {
@@ -266,3 +267,12 @@ func (a *ServerController) getNewEchCert(c *gin.Context) {
}
jsonObj(c, cert, nil)
}
+
+func (a *ServerController) getNewVlessEnc(c *gin.Context) {
+ out, err := a.serverService.GetNewVlessEnc()
+ if err != nil {
+ jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.getNewVlessEncError"), err)
+ return
+ }
+ jsonObj(c, out, nil)
+}
diff --git a/web/html/form/outbound.html b/web/html/form/outbound.html
index c7a786b7..cfaaafd7 100644
--- a/web/html/form/outbound.html
+++ b/web/html/form/outbound.html
@@ -226,6 +226,11 @@
</template>
<!-- vless settings -->
+ <template v-if="outbound.protocol === Protocols.VLESS">
+ <a-form-item label='encryption'>
+ <a-input v-model.trim="outbound.settings.encryption"></a-input>
+ </a-form-item>
+ </template>
<template v-if="outbound.canEnableTlsFlow()">
<a-form-item label='Flow'>
<a-select v-model="outbound.settings.flow" :dropdown-class-name="themeSwitcher.currentTheme">
diff --git a/web/html/form/protocol/vless.html b/web/html/form/protocol/vless.html
index 3cebda6e..6f421731 100644
--- a/web/html/form/protocol/vless.html
+++ b/web/html/form/protocol/vless.html
@@ -18,7 +18,29 @@
</table>
</a-collapse-panel>
</a-collapse>
-<template v-if="inbound.isTcp">
+<template v-if="!inbound.stream.isTLS || !inbound.stream.isReality">
+ <a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
+ <a-form-item label="Authentication">
+ <a-select v-model="inbound.settings.selectedAuth" @change="getNewVlessEnc" :dropdown-class-name="themeSwitcher.currentTheme">
+ <a-select-option value="X25519, not Post-Quantum">X25519 (not Post-Quantum)</a-select-option>
+ <a-select-option value="ML-KEM-768, Post-Quantum">ML-KEM-768 (Post-Quantum)</a-select-option>
+ </a-select>
+ </a-form-item>
+ <a-form-item label="decryption">
+ <a-input v-model.trim="inbound.settings.decryption"></a-input>
+ </a-form-item>
+ <a-form-item label="encryption">
+ <a-input v-model="inbound.settings.encryption" disabled></a-input>
+ </a-form-item>
+ <a-form-item label=" ">
+ <a-space>
+ <a-button type="primary" icon="import" @click="getNewVlessEnc">Get New keys</a-button>
+ <a-button danger @click="clearKeys">Clear</a-button>
+ </a-space>
+ </a-form-item>
+ </a-form>
+</template>
+<template v-if="inbound.isTcp && !inbound.settings.encryption">
<a-form :colon="false" :label-col="{ md: {span:8} }" :wrapper-col="{ md: {span:14} }">
<a-form-item label="Fallbacks">
<a-button icon="plus" type="primary" size="small" @click="inbound.settings.addFallback()"></a-button>
diff --git a/web/html/form/tls_settings.html b/web/html/form/tls_settings.html
index 3a1802a3..82031bd7 100644
--- a/web/html/form/tls_settings.html
+++ b/web/html/form/tls_settings.html
@@ -5,13 +5,13 @@
<a-form-item label='{{ i18n "security" }}'>
<a-radio-group v-model="inbound.stream.security" button-style="solid">
<a-radio-button value="none">{{ i18n "none" }}</a-radio-button>
- <a-radio-button v-if="inbound.canEnableReality()" value="reality">Reality</a-radio-button>
- <a-radio-button value="tls">TLS</a-radio-button>
+ <a-radio-button v-if="inbound.canEnableReality() && !inbound.settings.encryption" value="reality">Reality</a-radio-button>
+ <a-radio-button v-if="!inbound.settings.encryption" value="tls">TLS</a-radio-button>
</a-radio-group>
</a-form-item>
<!-- tls settings -->
- <template v-if="inbound.stream.isTls">
+ <template v-if="inbound.stream.isTls && !inbound.settings.encryption">
<a-form-item label="SNI" placeholder="Server Name Indication">
<a-input v-model.trim="inbound.stream.tls.sni"></a-input>
</a-form-item>
@@ -121,7 +121,7 @@
</template>
<!-- reality settings -->
- <template v-if="inbound.stream.isReality">
+ <template v-if="inbound.stream.isReality && !inbound.settings.encryption">
{{template "form/realitySettings"}}
</template>
</a-form>
diff --git a/web/html/inbounds.html b/web/html/inbounds.html
index dfccdd70..81ef1b39 100644
--- a/web/html/inbounds.html
+++ b/web/html/inbounds.html
@@ -706,7 +706,7 @@
}, {
title: '{{ i18n "pages.inbounds.enable" }}',
align: 'center',
- width: 30,
+ width: 35,
scopedSlots: { customRender: 'enable' },
}, {
title: '{{ i18n "pages.inbounds.remark" }}',
@@ -770,8 +770,8 @@
const innerColumns = [
{ title: '{{ i18n "pages.inbounds.operate" }}', width: 65, scopedSlots: { customRender: 'actions' } },
- { title: '{{ i18n "pages.inbounds.enable" }}', width: 30, scopedSlots: { customRender: 'enable' } },
- { title: '{{ i18n "online" }}', width: 30, scopedSlots: { customRender: 'online' } },
+ { title: '{{ i18n "pages.inbounds.enable" }}', width: 35, scopedSlots: { customRender: 'enable' } },
+ { title: '{{ i18n "online" }}', width: 32, scopedSlots: { customRender: 'online' } },
{ title: '{{ i18n "pages.inbounds.client" }}', width: 80, scopedSlots: { customRender: 'client' } },
{ title: '{{ i18n "pages.inbounds.traffic" }}', width: 80, align: 'center', scopedSlots: { customRender: 'traffic' } },
{ title: '{{ i18n "pages.inbounds.allTimeTraffic" }}', width: 80, align: 'center', scopedSlots: { customRender: 'allTime' } },
diff --git a/web/html/modals/inbound_info_modal.html b/web/html/modals/inbound_info_modal.html
index a15172f3..4110c244 100644
--- a/web/html/modals/inbound_info_modal.html
+++ b/web/html/modals/inbound_info_modal.html
@@ -101,6 +101,12 @@
{{ i18n "security" }}
<a-tag :color="inbound.stream.security == 'none' ? 'red' : 'green'">[[ inbound.stream.security ]]</a-tag>
<br />
+ <td>Authentication</td>
+ <a-tag :color="inbound.settings.selectedAuth ? 'green' : 'red'">[[ inbound.settings.selectedAuth ? inbound.settings.selectedAuth : '' ]]</a-tag>
+ <br />
+ {{ i18n "encryption" }}
+ <a-tag :color="inbound.settings.encryption ? 'green' : 'red'">[[ inbound.settings.encryption ? inbound.settings.encryption : '' ]]</a-tag>
+ <br />
<template v-if="inbound.stream.security != 'none'">
{{ i18n "domainName" }}
<a-tag v-if="inbound.serverName" :color="inbound.serverName ? 'green' : 'orange'">[[ inbound.serverName ? inbound.serverName : '' ]]</a-tag>
diff --git a/web/html/modals/inbound_modal.html b/web/html/modals/inbound_modal.html
index b77e74e2..a7a59c99 100644
--- a/web/html/modals/inbound_modal.html
+++ b/web/html/modals/inbound_modal.html
@@ -1,9 +1,7 @@
{{define "modals/inboundModal"}}
-<a-modal id="inbound-modal" v-model="inModal.visible" :title="inModal.title"
- :dialog-style="{ top: '20px' }" @ok="inModal.ok"
- :confirm-loading="inModal.confirmLoading" :closable="true" :mask-closable="false"
- :class="themeSwitcher.currentTheme"
- :ok-text="inModal.okText" cancel-text='{{ i18n "close" }}'>
+<a-modal id="inbound-modal" v-model="inModal.visible" :title="inModal.title" :dialog-style="{ top: '20px' }"
+ @ok="inModal.ok" :confirm-loading="inModal.confirmLoading" :closable="true" :mask-closable="false"
+ :class="themeSwitcher.currentTheme" :ok-text="inModal.okText" cancel-text='{{ i18n "close" }}'>
{{template "form/inbound"}}
</a-modal>
<script>
@@ -20,7 +18,7 @@
ok() {
ObjectUtil.execute(inModal.confirm, inModal.inbound, inModal.dbInbound);
},
- show({ title = '', okText = '{{ i18n "sure" }}', inbound = null, dbInbound = null, confirm = (inbound, dbInbound) => {}, isEdit = false }) {
+ show({ title = '', okText = '{{ i18n "sure" }}', inbound = null, dbInbound = null, confirm = (inbound, dbInbound) => { }, isEdit = false }) {
this.title = title;
this.okText = okText;
if (inbound) {
@@ -41,7 +39,7 @@
inModal.visible = false;
inModal.loading(false);
},
- loading(loading=true) {
+ loading(loading = true) {
inModal.confirmLoading = loading;
},
};
@@ -105,9 +103,9 @@
},
SSMethodChange() {
this.inModal.inbound.settings.password = RandomUtil.randomShadowsocksPassword(this.inModal.inbound.settings.method)
-
+
if (this.inModal.inbound.isSSMultiUser) {
- if (this.inModal.inbound.settings.shadowsockses.length ==0){
+ if (this.inModal.inbound.settings.shadowsockses.length == 0) {
this.inModal.inbound.settings.shadowsockses = [new Inbound.ShadowsocksSettings.Shadowsocks()];
}
if (!this.inModal.inbound.isSS2022) {
@@ -123,7 +121,7 @@
client.password = RandomUtil.randomShadowsocksPassword(this.inModal.inbound.settings.method)
})
} else {
- if (this.inModal.inbound.settings.shadowsockses.length > 0){
+ if (this.inModal.inbound.settings.shadowsockses.length > 0) {
this.inModal.inbound.settings.shadowsockses = [];
}
}
@@ -154,7 +152,7 @@
},
async getNewEchCert() {
inModal.loading(true);
- const msg = await HttpUtil.post('/server/getNewEchCert', {sni: inModal.inbound.stream.tls.sni});
+ const msg = await HttpUtil.post('/server/getNewEchCert', { sni: inModal.inbound.stream.tls.sni });
inModal.loading(false);
if (!msg.success) {
return;
@@ -162,8 +160,34 @@
inModal.inbound.stream.tls.echServerKeys = msg.obj.echServerKeys;
inModal.inbound.stream.tls.settings.echConfigList = msg.obj.echConfigList;
},
+ async getNewVlessEnc() {
+ inModal.loading(true);
+ const msg = await HttpUtil.post('/server/getNewVlessEnc');
+ inModal.loading(false);
+
+ if (!msg.success) {
+ return;
+ }
+
+ const auths = msg.obj.auths || [];
+ const selected = inModal.inbound.settings.selectedAuth;
+ const block = auths.find(a => a.label === selected);
+
+ if (!block) {
+ console.error("No auth block for", selected);
+ return;
+ }
+
+ inModal.inbound.settings.decryption = block.decryption;
+ inModal.inbound.settings.encryption = block.encryption;
+ },
+ clearKeys() {
+ this.inbound.settings.decryption = 'none';
+ this.inbound.settings.encryption = '';
+ }
+
},
});
</script>
-{{end}}
+{{end}} \ No newline at end of file
diff --git a/web/service/server.go b/web/service/server.go
index 2dc83d77..3078e88b 100644
--- a/web/service/server.go
+++ b/web/service/server.go
@@ -871,3 +871,53 @@ func (s *ServerService) GetNewEchCert(sni string) (interface{}, error) {
"echConfigList": configList,
}, nil
}
+
+type AuthBlock struct {
+ Label string `json:"label"`
+ Decryption string `json:"decryption"`
+ Encryption string `json:"encryption"`
+}
+
+func (s *ServerService) GetNewVlessEnc() (any, error) {
+ cmd := exec.Command(xray.GetBinaryPath(), "vlessenc")
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ if err := cmd.Run(); err != nil {
+ return nil, err
+ }
+
+ lines := strings.Split(out.String(), "\n")
+
+ var blocks []AuthBlock
+ var current *AuthBlock
+
+ for _, line := range lines {
+ line = strings.TrimSpace(line)
+ if strings.HasPrefix(line, "Authentication:") {
+ if current != nil {
+ blocks = append(blocks, *current)
+ }
+ current = &AuthBlock{Label: strings.TrimSpace(strings.TrimPrefix(line, "Authentication:"))}
+ } else if strings.HasPrefix(line, `"decryption"`) || strings.HasPrefix(line, `"encryption"`) {
+ parts := strings.SplitN(line, ":", 2)
+ if len(parts) == 2 && current != nil {
+ key := strings.Trim(parts[0], `" `)
+ val := strings.Trim(parts[1], `" `)
+ switch key {
+ case "decryption":
+ current.Decryption = val
+ case "encryption":
+ current.Encryption = val
+ }
+ }
+ }
+ }
+
+ if current != nil {
+ blocks = append(blocks, *current)
+ }
+
+ return map[string]any{
+ "auths": blocks,
+ }, nil
+}
diff --git a/web/translation/translate.ar_EG.toml b/web/translation/translate.ar_EG.toml
index dd5618cb..9f11a30c 100644
--- a/web/translation/translate.ar_EG.toml
+++ b/web/translation/translate.ar_EG.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "خطأ في الحصول على حركات المرور"
"getNewX25519CertError" = "حدث خطأ أثناء الحصول على شهادة X25519."
"getNewmldsa65Error" = "حدث خطاء في الحصول على mldsa65."
+"getNewVlessEncError" = "حدث خطأ أثناء الحصول على VlessEnc."
[pages.inbounds.stream.general]
"request" = "طلب"
diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml
index 89f127a8..f802dd6d 100644
--- a/web/translation/translate.en_US.toml
+++ b/web/translation/translate.en_US.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "Error getting traffics."
"getNewX25519CertError" = "Error while obtaining the X25519 certificate."
"getNewmldsa65Error" = "Error while obtaining mldsa65."
+"getNewVlessEncError" = "Error while obtaining VlessEnc."
[pages.inbounds.stream.general]
"request" = "Request"
diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml
index 070b6b57..80ddd98a 100644
--- a/web/translation/translate.es_ES.toml
+++ b/web/translation/translate.es_ES.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "Error al obtener los tráficos"
"getNewX25519CertError" = "Error al obtener el certificado X25519."
"getNewmldsa65Error" = "Error al obtener el certificado mldsa65."
+"getNewVlessEncError" = "Error al obtener el certificado VlessEnc."
[pages.inbounds.stream.general]
"request" = "Pedido"
diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml
index 5c949928..778dd528 100644
--- a/web/translation/translate.fa_IR.toml
+++ b/web/translation/translate.fa_IR.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "خطا در دریافت ترافیک‌ها"
"getNewX25519CertError" = "خطا در دریافت گواهی X25519."
"getNewmldsa65Error" = "خطا در دریافت گواهی mldsa65."
+"getNewVlessEncError" = "خطا در دریافت گواهی VlessEnc."
[pages.inbounds.stream.general]
"request" = "درخواست"
diff --git a/web/translation/translate.id_ID.toml b/web/translation/translate.id_ID.toml
index 4dc8e378..2a5b568b 100644
--- a/web/translation/translate.id_ID.toml
+++ b/web/translation/translate.id_ID.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "Gagal mendapatkan data lalu lintas"
"getNewX25519CertError" = "Terjadi kesalahan saat mendapatkan sertifikat X25519."
"getNewmldsa65Error" = "Terjadi kesalahan saat mendapatkan sertifikat mldsa65."
+"getNewVlessEncError" = "Terjadi kesalahan saat mendapatkan sertifikat VlessEnc."
[pages.inbounds.stream.general]
"request" = "Permintaan"
diff --git a/web/translation/translate.ja_JP.toml b/web/translation/translate.ja_JP.toml
index 54479232..7af0a339 100644
--- a/web/translation/translate.ja_JP.toml
+++ b/web/translation/translate.ja_JP.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "トラフィックの取得中にエラーが発生しました"
"getNewX25519CertError" = "X25519証明書の取得中にエラーが発生しました。"
"getNewmldsa65Error" = "mldsa65証明書の取得中にエラーが発生しました。"
+"getNewVlessEncError" = "VlessEnc証明書の取得中にエラーが発生しました。"
[pages.inbounds.stream.general]
"request" = "リクエスト"
diff --git a/web/translation/translate.pt_BR.toml b/web/translation/translate.pt_BR.toml
index a3aac778..f61f8995 100644
--- a/web/translation/translate.pt_BR.toml
+++ b/web/translation/translate.pt_BR.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "Erro ao obter tráfegos"
"getNewX25519CertError" = "Erro ao obter o certificado X25519."
"getNewmldsa65Error" = "Erro ao obter o certificado mldsa65."
+"getNewVlessEncError" = "Erro ao obter o certificado VlessEnc."
[pages.inbounds.stream.general]
"request" = "Requisição"
diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml
index 718edb51..060b7334 100644
--- a/web/translation/translate.ru_RU.toml
+++ b/web/translation/translate.ru_RU.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "Ошибка получения данных о трафике"
"getNewX25519CertError" = "Ошибка при получении сертификата X25519."
"getNewmldsa65Error" = "Ошибка при получении сертификата mldsa65."
+"getNewVlessEncError" = "Ошибка при получении сертификата VlessEnc."
[pages.inbounds.stream.general]
"request" = "Запрос"
diff --git a/web/translation/translate.tr_TR.toml b/web/translation/translate.tr_TR.toml
index 047d9d57..ac10bf65 100644
--- a/web/translation/translate.tr_TR.toml
+++ b/web/translation/translate.tr_TR.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "Trafik bilgisi alınırken hata oluştu"
"getNewX25519CertError" = "X25519 sertifikası alınırken hata oluştu."
"getNewmldsa65Error" = "mldsa65 sertifikası alınırken hata oluştu."
+"getNewVlessEncError" = "VlessEnc sertifikası alınırken hata oluştu."
[pages.inbounds.stream.general]
"request" = "İstek"
diff --git a/web/translation/translate.uk_UA.toml b/web/translation/translate.uk_UA.toml
index 3dc5b3e7..4005f14f 100644
--- a/web/translation/translate.uk_UA.toml
+++ b/web/translation/translate.uk_UA.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "Помилка отримання даних про трафік"
"getNewX25519CertError" = "Помилка при отриманні сертифіката X25519."
"getNewmldsa65Error" = "Помилка при отриманні сертифіката mldsa65."
+"getNewVlessEncError" = "Помилка при отриманні сертифіката VlessEnc."
[pages.inbounds.stream.general]
"request" = "Запит"
diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml
index aa0009eb..66ed38ce 100644
--- a/web/translation/translate.vi_VN.toml
+++ b/web/translation/translate.vi_VN.toml
@@ -266,7 +266,8 @@
"resetInboundClientTrafficSuccess" = "Đã đặt lại lưu lượng"
"trafficGetError" = "Lỗi khi lấy thông tin lưu lượng"
"getNewX25519CertError" = "Lỗi khi lấy chứng chỉ X25519."
-"getNewmldsa65Error" = "Lỗi khi lấy chúng tôi mldsa65."
+"getNewmldsa65Error" = "Lỗi khi lấy chứng chỉ mldsa65."
+"getNewVlessEncError" = "Lỗi khi lấy chứng chỉ VlessEnc."
[pages.inbounds.stream.general]
"request" = "Lời yêu cầu"
diff --git a/web/translation/translate.zh_CN.toml b/web/translation/translate.zh_CN.toml
index 01844f13..5875add9 100644
--- a/web/translation/translate.zh_CN.toml
+++ b/web/translation/translate.zh_CN.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "获取流量数据时出错"
"getNewX25519CertError" = "获取X25519证书时出错。"
"getNewmldsa65Error" = "获取mldsa65证书时出错。"
+"getNewVlessEncError" = "获取VlessEnc证书时出错。"
[pages.inbounds.stream.general]
"request" = "请求"
diff --git a/web/translation/translate.zh_TW.toml b/web/translation/translate.zh_TW.toml
index f3121c69..6843e9ee 100644
--- a/web/translation/translate.zh_TW.toml
+++ b/web/translation/translate.zh_TW.toml
@@ -267,6 +267,7 @@
"trafficGetError" = "取得流量資料時發生錯誤"
"getNewX25519CertError" = "取得X25519憑證時發生錯誤。"
"getNewmldsa65Error" = "取得mldsa65憑證時發生錯誤。"
+"getNewVlessEncError" = "取得VlessEnc憑證時發生錯誤。"
[pages.inbounds.stream.general]
"request" = "請求"