fix(qr): hide the QR only for links carrying post-quantum keys

A share link's QR is suppressed only when it carries a post-quantum key
payload too large to scan: an ML-DSA-65 verify key (pqv) or an ML-KEM-768
VLESS-encryption auth key. isPostQuantumLink substring-matched "mlkem768"
anywhere in the URL, so it misfired on:

- every VLESS/Trojan REALITY link, since ce221c33 added the
  support-x25519mlkem768=true hint (235 chars, QR version 10);
- every VLESS-encryption link authenticated by an X25519 key, whose
  value always starts with mlkem768x25519plus (321 chars, version 11);
- any remark or host containing mlkem768 / mldsa65 / ML-KEM-768.

All four QR surfaces (inbound QR, client QR, client info, public sub
page) lost their QR button for those links. The detector now reads the
query: a non-empty pqv, or an encryption whose auth key
vlessEncryptionAuthKind classifies as ML-KEM-768.

Closes #6730
This commit is contained in:
MHSanaei
2026-10-05 16:30:14 +02:00
parent 2c5fc8e72c
commit d7da64f2f0
2 changed files with 53 additions and 4 deletions
+9 -4
View File
@@ -17,6 +17,7 @@ import { parseGeckoPacketSize } from '@/lib/xray/forms/transport/FinalMaskForm';
import { getHeaderValue } from './headers';
import { canEnableTlsFlow } from './protocol-capabilities';
import { deriveSpiderX } from './spider-x';
import { vlessEncryptionAuthKind } from './vless-encryption';
import { normalizeTuicCongestionController, resolveTuicServerSettings } from '@/lib/tuic';
// Share-link generators. Each per-protocol fn takes a typed inbound plus
@@ -1723,9 +1724,13 @@ function wgPeerCommentSuffix(peer: unknown): string {
return typeof comment === 'string' && comment.trim() !== '' ? ` (${comment.trim()})` : '';
}
// Only the post-quantum key payloads outgrow a QR; the REALITY ML-KEM hint and the
// mlkem768x25519plus prefix of an X25519-authenticated encryption do not (#6730).
export function isPostQuantumLink(link: string): boolean {
if (/[?&]pqv=/.test(link)) return true;
if (link.includes('mlkem768') || link.includes('mldsa65')) return true;
if (link.includes('ML-KEM-768')) return true;
return false;
const withoutRemark = link.split('#', 1)[0];
const queryStart = withoutRemark.indexOf('?');
if (queryStart < 0) return false;
const params = new URLSearchParams(withoutRemark.slice(queryStart + 1));
if (params.get('pqv')) return true;
return vlessEncryptionAuthKind(params.get('encryption') ?? '')?.startsWith('mlkem768') ?? false;
}