1
0
mirror of git://f0xx.org/ac/ac-ms-identity synced 2026-07-30 02:37:39 +03:00

fix(2fa): use shortener QR PNG URL and otpauth fallback

AuthTwoFactorPage was setting img src to the short link URL (HTML), not
the /api/v1/qr/*.png endpoint. Always expose a PNG via qr_url.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Anton Afanasyeu
2026-07-05 19:12:53 +02:00
parent bb03237963
commit 635cc36dd5

View File

@@ -9,7 +9,7 @@ final class AuthTwoFactorPage {
* Returns an array with:
* long_url approval URL (fallback if shortener unavailable)
* short_url shortened URL (s.f0xx.org)
* qr_url URL of the QR PNG image (short_url + ?src=qr)
* qr_url PNG image URL (url-shortener /api/v1/qr/… or otpauth QR fallback)
* raw_token the approval token to store in session for polling
*
* @return array{long_url:string,short_url?:string,qr_url?:string,raw_token:string}|null
@@ -28,29 +28,35 @@ final class AuthTwoFactorPage {
$approveUrl = 'https://apps.f0xx.org' . $project . '/two-factor/approve?token=' . urlencode($rawToken);
$payload = [
'long_url' => $approveUrl,
'raw_token' => $rawToken,
'qr_url' => AuthTotp::qrImageUrl($approveUrl),
];
if (!UrlShortenerDatabase::enabled() || !UrlShortenerDatabase::ping()) {
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
return $payload;
}
$bearers = ShortLinksRepository::listBearers();
if ($bearers === []) {
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
return $payload;
}
$bearerId = (int) ($bearers[0]['id'] ?? 0);
if ($bearerId <= 0) {
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
return $payload;
}
$mint = ShortLinksRepository::createLink($bearerId, $approveUrl, 900);
if (empty($mint['ok'])) {
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
return $payload;
}
$shortUrl = (string) ($mint['short_url'] ?? '');
// QR image encodes the short URL with ?src=qr so mobile scans are tracked
$qrUrl = $shortUrl . (str_contains($shortUrl, '?') ? '&src=qr' : '?src=qr');
return [
'long_url' => $approveUrl,
'short_url' => $shortUrl,
'qr_url' => $qrUrl,
'raw_token' => $rawToken,
];
$qrUrl = (string) ($mint['qr_url'] ?? '');
if ($qrUrl !== '') {
$payload['qr_url'] = $qrUrl;
}
if ($shortUrl !== '') {
$payload['short_url'] = $shortUrl;
}
return $payload;
}
}