fix(magic): DNS-Token auf 48 hex kürzen (AdGuard 63-char clientid-Limit)

randomBytes(32).hex = 64 Zeichen → AdGuard lehnt clientid ab
('hostname label is too long: got 64, max 63') → 'DNS-Provisioning
fehlgeschlagen' bei jeder Magic-Registrierung. Live gegen AdGuard
reproduziert: 64→HTTP400, 62→HTTP200.

- register: randomBytes(24).hex = 48 Zeichen (192 bit, ≤63)
- status: Token-Regex {64} → {1,63} (Länge nicht hart koppeln)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
chahinebrini 2026-06-07 23:33:56 +02:00
parent 4dfcfc4012
commit db6db547ff
2 changed files with 9 additions and 5 deletions

View File

@ -101,10 +101,12 @@ export default defineEventHandler(async (event) => {
}
}
// 3. Generiere DNS-Token (64 char hex)
// WICHTIG: hex statt base64url — AdGuard's clientid muss DNS-Label-konform sein,
// verbietet `_` (das base64url als Ersatz für `/` generiert) → 400 "bad hostname label rune".
const dnsToken = randomBytes(32).toString("hex");
// 3. Generiere DNS-Token (48 char hex)
// WICHTIG: hex (DNS-Label-konform, kein `_`) UND ≤63 Zeichen. AdGuard nutzt die
// clientid im DoH-Pfad `/dns-query/{id}` und lehnt >63 Zeichen ab
// ("hostname label is too long: got 64, max 63"). randomBytes(32).hex = 64 → 1 zu viel.
// 24 Bytes = 48 hex (192 bit Entropie), wie der historisch funktionierende Client.
const dnsToken = randomBytes(24).toString("hex");
// Hard-Lock: server-gehaltenes Removal-Passwort. Stabil über Re-Registrierungen
// (sonst würde ein laufender Offboarding-Cooldown sein PW wechseln).

View File

@ -16,7 +16,9 @@ export default defineEventHandler(async (event) => {
const query = getQuery(event);
const token = query.token as string | undefined;
if (!token || !/^[0-9a-f]{64}$/.test(token)) {
// Hex-Token, ≤63 Zeichen (AdGuard-clientid-Limit). Länge nicht hart fixieren,
// damit Token-Längen-Änderungen den Tamper-Poll nicht brechen.
if (!token || !/^[0-9a-f]{1,63}$/.test(token)) {
throw createError({
statusCode: 400,
message: "token query parameter required",