Feat: clarify VLESS encryption auth selection (#4271)

* feat(traffic_writer): enhance traffic writer with concurrency safety and state management

* Revert "feat(traffic_writer): enhance traffic writer with concurrency safety and state management"

This reverts commit e6760ae39629a592dec293197768f27ff0f5a578.

* feat(vless): clarify VLESS encryption auth selection and enhance parsing logic
This commit is contained in:
Farhad H. P. Shirvan
2026-05-12 11:39:28 +02:00
committed by GitHub
parent d86e87ed30
commit fdaa65ad7e
4 changed files with 151 additions and 17 deletions
+1 -1
View File
@@ -325,7 +325,7 @@ export const sections = [
{
method: 'GET',
path: '/panel/api/server/getNewVlessEnc',
summary: 'Generate a new VLESS encryption keypair.',
summary: 'Generate VLESS encryption auth options. Returns auths with id, label, decryption, and encryption.',
},
{
method: 'POST',
@@ -393,16 +393,29 @@ async function fetchDefaultCertSettings() {
}
// === VLESS encryption helpers =======================================
// `xray vlessenc` returns both X25519 and ML-KEM-768 variants every
// call; the user clicks one of two buttons to pick which block goes
// into decryption/encryption.
async function getNewVlessEnc(authLabel) {
if (!authLabel || !inbound.value?.settings) return;
// `xray vlessenc` returns both X25519 and ML-KEM-768 auth variants every
// call; the user clicks one button to pick which block goes into
// decryption/encryption. Both generated strings share the same hybrid
// mlkem768x25519plus prefix; the auth choice is the final key block.
function normalizeVlessAuthLabel(label = '') {
return label.toLowerCase().replace(/[-_\s]/g, '');
}
function matchesVlessAuth(block, authId) {
if (block?.id === authId) return true;
const label = normalizeVlessAuthLabel(block?.label);
if (authId === 'mlkem768') return label.includes('mlkem768');
if (authId === 'x25519') return label.includes('x25519');
return false;
}
async function getNewVlessEnc(authId) {
if (!authId || !inbound.value?.settings) return;
saving.value = true;
try {
const msg = await HttpUtil.get('/panel/api/server/getNewVlessEnc');
if (!msg?.success) return;
const block = (msg.obj?.auths || []).find((a) => a.label === authLabel);
const block = (msg.obj?.auths || []).find((a) => matchesVlessAuth(a, authId));
if (!block) return;
inbound.value.settings.decryption = block.decryption;
inbound.value.settings.encryption = block.encryption;
@@ -417,6 +430,17 @@ function clearVlessEnc() {
inbound.value.settings.encryption = 'none';
}
const selectedVlessAuth = computed(() => {
const encryption = inbound.value?.settings?.encryption;
if (!encryption || encryption === 'none') return 'None';
const parts = encryption.split('.').filter(Boolean);
const authKey = parts[parts.length - 1] || '';
if (!authKey) return 'Custom';
return authKey.length > 300 ? 'ML-KEM-768 auth' : 'X25519 auth';
});
// === SS method change tracks legacy semantics =========================
function onSSMethodChange() {
inbound.value.settings.password = RandomUtil.randomShadowsocksPassword(inbound.value.settings.method);
@@ -731,14 +755,17 @@ watch(
</a-form-item>
<a-form-item label=" ">
<a-space :size="8" wrap>
<a-button type="primary" :loading="saving" @click="getNewVlessEnc('X25519, not Post-Quantum')">
X25519
<a-button type="primary" :loading="saving" @click="getNewVlessEnc('x25519')">
X25519 auth
</a-button>
<a-button type="primary" :loading="saving" @click="getNewVlessEnc('ML-KEM-768, Post-Quantum')">
ML-KEM-768
<a-button type="primary" :loading="saving" @click="getNewVlessEnc('mlkem768')">
ML-KEM-768 auth
</a-button>
<a-button danger @click="clearVlessEnc">Clear</a-button>
</a-space>
<a-typography-text type="secondary" class="vless-auth-state">
Selected: {{ selectedVlessAuth }}
</a-typography-text>
</a-form-item>
</a-form>
@@ -1741,6 +1768,11 @@ watch(
color: #ff4d4f;
}
.vless-auth-state {
display: block;
margin-top: 6px;
}
.json-editor {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 12px;