fix(qr-login): render QR code server-side using segno instead of CDN JS library
The QR code on /qr-login was not rendering because it depended on loading qrcode@1.5.4 from the jsdelivr CDN, which may be blocked in some network environments. - Add segno>=1.6.0 (pure-Python QR library, no Pillow needed) to requirements.txt - Generate QR code as a base64 SVG data URI server-side in the challenge endpoint - Add qr_code_svg field to CreateChallengeResponse Pydantic model - Replace canvas+CDN script in qr_login.html with an <img :src="qrCodeSvg"> - Remove the $nextTick/QRCode.toCanvas() client-side rendering block - Extract QR rendering parameters (_QR_ERROR_LEVEL, _QR_SCALE) as module constants Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -32,7 +32,13 @@
|
||||
id="qr-container"
|
||||
aria-label="{{ _('qr_login.description') }}"
|
||||
>
|
||||
<canvas id="qr-canvas" width="256" height="256"></canvas>
|
||||
<img
|
||||
:src="qrCodeSvg"
|
||||
width="256"
|
||||
height="256"
|
||||
alt="{{ _('qr_login.description') }}"
|
||||
id="qr-image"
|
||||
/>
|
||||
</div>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 mb-2">
|
||||
{{ _("qr_login.description") }}
|
||||
@@ -110,8 +116,7 @@
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- QR Code library (lightweight, no external deps) -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/qrcode@1.5.4/build/qrcode.min.js"></script>
|
||||
<!-- QR code is rendered server-side; no external QR library needed -->
|
||||
|
||||
<script>
|
||||
function qrLoginPage() {
|
||||
@@ -120,6 +125,7 @@ function qrLoginPage() {
|
||||
challengeId: null,
|
||||
challengeToken: '',
|
||||
qrPayload: '',
|
||||
qrCodeSvg: '',
|
||||
expiresAt: null,
|
||||
countdown: 0,
|
||||
deviceName: '',
|
||||
@@ -157,24 +163,13 @@ function qrLoginPage() {
|
||||
this.challengeId = data.challenge_id;
|
||||
this.challengeToken = data.challenge_token;
|
||||
this.qrPayload = data.qr_payload;
|
||||
this.qrCodeSvg = data.qr_code_svg;
|
||||
this.expiresAt = new Date(data.expires_at);
|
||||
this._ttlSeconds = data.ttl_seconds || 120;
|
||||
this._receivedAt = Date.now();
|
||||
this.status = 'pending';
|
||||
this.deviceName = '';
|
||||
|
||||
// Render QR code
|
||||
this.$nextTick(() => {
|
||||
const canvas = document.getElementById('qr-canvas');
|
||||
if (canvas && typeof QRCode !== 'undefined') {
|
||||
QRCode.toCanvas(canvas, this.qrPayload, {
|
||||
width: 256,
|
||||
margin: 2,
|
||||
color: { dark: '#000000', light: '#ffffff' },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Start polling and countdown
|
||||
this._startPolling();
|
||||
this._startCountdown();
|
||||
|
||||
Reference in New Issue
Block a user