From e5d0f9871f56a8df1004f92db01392f778e34397 Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Mon, 7 Nov 2022 23:18:29 +1100 Subject: [PATCH] Add text version of secret to twofactor.html for people without/who dont want to use a camera or screenshot the image Add warning to twofactor.html that other sessions will be logged out and they have to log in again Change cache-control header to no-cache, even though private is secure (prevent showing cached page without outdated secret) --- models/pages/twofactor.js | 10 ++++++---- views/pages/twofactor.pug | 6 ++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/models/pages/twofactor.js b/models/pages/twofactor.js index 21088cbe..85bfc2d8 100644 --- a/models/pages/twofactor.js +++ b/models/pages/twofactor.js @@ -26,7 +26,8 @@ module.exports = async (req, res, next) => { const { meta } = config.get; - let qrCodeText = ''; + let qrCodeText = '' + , secretBase32 = ''; try { const totp = new OTPAuth.TOTP({ issuer: meta.url || 'jschan', @@ -34,7 +35,7 @@ module.exports = async (req, res, next) => { algorithm: 'SHA256', }); const secret = totp.secret; - const secretBase32 = secret.base32; + secretBase32 = secret.base32; await redis.set(`twofactor:${username}`, secretBase32, 300); //store validation secret temporarily in redis const qrCodeURL = totp.toString(); qrCodeText = await QRCode.toString(qrCodeURL, { type: 'utf8' }); @@ -43,10 +44,11 @@ module.exports = async (req, res, next) => { } res - .set('Cache-Control', 'private, max-age=5') + .set('Cache-Control', 'no-cache') .render('twofactor', { csrf: req.csrfToken(), - qrCodeText, + qrCodeText, + secretBase32, }); }; diff --git a/views/pages/twofactor.pug b/views/pages/twofactor.pug index 0cf27a14..d65b74b8 100644 --- a/views/pages/twofactor.pug +++ b/views/pages/twofactor.pug @@ -13,6 +13,12 @@ block content h4.mv-5 Scan the QR Code in an authenticator app, and submit the code: .row span.code.hljs.twofactor #{qrCodeText} + .row + h4.no-m-p No camera? Use this secret in your authenticator app instead: + .row + span.code #{secretBase32} + .row + h4.mv-5.ban Enabling 2FA will invalidate all your existing sessions and you will have to login again. .row .label 2FA Code input(type='number' name='twofactor' placeholder='6 digits')