mirror of https://gitgud.io/fatchan/jschan.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.5 KiB
54 lines
1.5 KiB
'use strict';
|
|
|
|
const redis = require(__dirname+'/../../lib/redis/redis.js')
|
|
, { Ratelimits } = require(__dirname+'/../../db/')
|
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js')
|
|
, config = require(__dirname+'/../../lib/misc/config.js')
|
|
, OTPAuth = require('otpauth')
|
|
, QRCode = require('qrcode');
|
|
|
|
module.exports = async (req, res, next) => {
|
|
|
|
if (res.locals.user.twofactor) {
|
|
// User already has 2fa enabled
|
|
return res.redirect('/account.html');
|
|
}
|
|
|
|
// Ratelimit QR code generation
|
|
const username = res.locals.user.username;
|
|
const ratelimit = await Ratelimits.incrmentQuota(username, '2fa', 50);
|
|
if (ratelimit > 100) {
|
|
return dynamicResponse(req, res, 429, 'message', {
|
|
'title': 'Ratelimited',
|
|
'message': 'Please wait before generating another 2FA QR code.',
|
|
});
|
|
}
|
|
|
|
const { meta } = config.get;
|
|
|
|
let qrCodeText = ''
|
|
, secretBase32 = '';
|
|
try {
|
|
const totp = new OTPAuth.TOTP({
|
|
issuer: meta.url || 'jschan',
|
|
label: meta.siteName || 'jschan',
|
|
algorithm: 'SHA256',
|
|
});
|
|
const secret = totp.secret;
|
|
secretBase32 = secret.base32;
|
|
await redis.set(`twofactor_tempsecret:${username}`, secretBase32, 300); //store validation secret temporarily in redis
|
|
const qrCodeURL = totp.toString();
|
|
qrCodeText = await QRCode.toString(qrCodeURL, { type: 'utf8' });
|
|
} catch (err) {
|
|
return next(err);
|
|
}
|
|
|
|
res
|
|
.set('Cache-Control', 'no-cache')
|
|
.render('twofactor', {
|
|
csrf: req.csrfToken(),
|
|
qrCodeText,
|
|
secretBase32,
|
|
});
|
|
|
|
};
|
|
|