mirror of
git://f0xx.org/ac/ac-ms-identity
synced 2026-07-30 03:18:00 +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:
@@ -9,7 +9,7 @@ final class AuthTwoFactorPage {
|
|||||||
* Returns an array with:
|
* Returns an array with:
|
||||||
* long_url – approval URL (fallback if shortener unavailable)
|
* long_url – approval URL (fallback if shortener unavailable)
|
||||||
* short_url – shortened URL (s.f0xx.org)
|
* 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
|
* 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
|
* @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);
|
$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()) {
|
if (!UrlShortenerDatabase::enabled() || !UrlShortenerDatabase::ping()) {
|
||||||
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
|
return $payload;
|
||||||
}
|
}
|
||||||
$bearers = ShortLinksRepository::listBearers();
|
$bearers = ShortLinksRepository::listBearers();
|
||||||
if ($bearers === []) {
|
if ($bearers === []) {
|
||||||
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
|
return $payload;
|
||||||
}
|
}
|
||||||
$bearerId = (int) ($bearers[0]['id'] ?? 0);
|
$bearerId = (int) ($bearers[0]['id'] ?? 0);
|
||||||
if ($bearerId <= 0) {
|
if ($bearerId <= 0) {
|
||||||
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
|
return $payload;
|
||||||
}
|
}
|
||||||
$mint = ShortLinksRepository::createLink($bearerId, $approveUrl, 900);
|
$mint = ShortLinksRepository::createLink($bearerId, $approveUrl, 900);
|
||||||
if (empty($mint['ok'])) {
|
if (empty($mint['ok'])) {
|
||||||
return ['long_url' => $approveUrl, 'raw_token' => $rawToken];
|
return $payload;
|
||||||
}
|
}
|
||||||
$shortUrl = (string) ($mint['short_url'] ?? '');
|
$shortUrl = (string) ($mint['short_url'] ?? '');
|
||||||
// QR image encodes the short URL with ?src=qr so mobile scans are tracked
|
$qrUrl = (string) ($mint['qr_url'] ?? '');
|
||||||
$qrUrl = $shortUrl . (str_contains($shortUrl, '?') ? '&src=qr' : '?src=qr');
|
if ($qrUrl !== '') {
|
||||||
return [
|
$payload['qr_url'] = $qrUrl;
|
||||||
'long_url' => $approveUrl,
|
}
|
||||||
'short_url' => $shortUrl,
|
if ($shortUrl !== '') {
|
||||||
'qr_url' => $qrUrl,
|
$payload['short_url'] = $shortUrl;
|
||||||
'raw_token' => $rawToken,
|
}
|
||||||
];
|
return $payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user