mirror of
https://hk.gh-proxy.com/https://github.com/NodeBB/nodebb-plugin-2factor.git
synced 2025-10-03 09:11:01 +08:00
fix: #80, notify user if 2fa challenge fails
This commit is contained in:
parent
b5a0d6aa3f
commit
948984010a
4 changed files with 66 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
"notification.backupCode.generated": "A set of backup codes have just been generated for this account.",
|
||||
"notification.backupCode.used": "A backup code was just used to log into this account",
|
||||
"notification.failure": "Someone attempted to access your account but could not pass the second factor.",
|
||||
|
||||
"user.force_2fa": "The administrator has required you to setup 2FA for your account for security purposes",
|
||||
|
||||
|
@ -58,6 +59,12 @@
|
|||
"backup.generate.one": "These backup codes have been generated in order to help you re-gain access to your account in the event your authentication device (typically a mobile phone) is lost or damaged.",
|
||||
"backup.generate.two": "Your codes are shown below, and will not be shown again. Write them down on a piece of paper and secure it!",
|
||||
|
||||
"failureInfo.lead": "If you are on this page, then you may be wondering what this notification means.",
|
||||
"failureInfo.when": "We processed a login attempt at %1 on %2, and as your account is configured with a second factor, issued a second-factor challenge.",
|
||||
"failureInfo.explanation": "The user who attempted this login did not successfully pass that second factor, which is why you have been notified. If this was you, then you can safely disregard this message.",
|
||||
"failureInfo.remediation": "However — if this was not you, then it is likely that whoever attempted to access your account <strong>has your password, and so your password is now compromised</strong>. <a href=\"../me/edit/password\">You should change your password immediately</a>.",
|
||||
"failureInfo.cta": "Change your password →",
|
||||
|
||||
"admin.intro.one": "<strong>Two-Factor Authentication</strong> (2FA) is a security protocol that works by adding a second layer of authentication before granting access. Typically, these two layers are \"something you know\" (e.g. your password), and \"something you have\" (e.g. a token generated by your mobile device). This plugin introduces the second layer of security allowing users to enable and pair their phones or other suitable devices to your forum's authentication protocols.",
|
||||
"admin.intro.two": "While this plugin is active, users will be able to see a new profile menu item called \"Two-Factor Authentication\". They will be able to set up their tokens from this page.",
|
||||
"admin.users.title": "Two-Factor Authentication Users",
|
||||
|
|
|
@ -75,6 +75,10 @@ Controllers.renderTotpChallenge = async (req, res, next) => {
|
|||
}
|
||||
|
||||
const error = req.flash('error');
|
||||
if (error.includes('[[2factor:login.failure]]')) {
|
||||
const main = require('..');
|
||||
main.handle2faFailure(uid);
|
||||
}
|
||||
|
||||
if (!await parent.hasTotp(uid)) {
|
||||
return next();
|
||||
|
@ -233,4 +237,17 @@ Controllers.renderSettings = async (req, res) => {
|
|||
});
|
||||
};
|
||||
|
||||
Controllers.renderAccessNotificationHelp = (req, res, next) => {
|
||||
const { when } = req.query;
|
||||
if (!when) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const date = new Date(parseInt(when, 10));
|
||||
res.render('2fa-access-notification', {
|
||||
timeString: date.toLocaleTimeString(date),
|
||||
dateString: date.toLocaleDateString(date),
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = Controllers;
|
||||
|
|
15
library.js
15
library.js
|
@ -41,6 +41,9 @@ plugin.init = async (params) => {
|
|||
const controllers = require('./lib/controllers');
|
||||
const middlewares = require('./lib/middlewares');
|
||||
|
||||
// Public-facing pages
|
||||
hostHelpers.setupPageRoute(router, '/2factor/access-notification', controllers.renderAccessNotificationHelp);
|
||||
|
||||
// ACP
|
||||
hostHelpers.setupAdminPageRoute(router, '/admin/plugins/2factor', [hostMiddleware.pluginHooks], controllers.renderAdminPage);
|
||||
|
||||
|
@ -413,6 +416,18 @@ plugin.adjustRelogin = async ({ req, res }) => {
|
|||
}
|
||||
};
|
||||
|
||||
plugin.handle2faFailure = async (uid) => {
|
||||
const notification = await notifications.create({
|
||||
bodyShort: '[[2factor:notification.failure]]',
|
||||
bodyLong: '',
|
||||
nid: `2factor.failure.${uid}-${Date.now()}`,
|
||||
from: uid,
|
||||
path: `/2factor/access-notification?when=${Date.now()}`,
|
||||
});
|
||||
|
||||
await notifications.push(notification, [uid]);
|
||||
}
|
||||
|
||||
plugin.integrations = {};
|
||||
|
||||
plugin.integrations.writeApi = async (data) => {
|
||||
|
|
27
static/templates/2fa-access-notification.tpl
Normal file
27
static/templates/2fa-access-notification.tpl
Normal file
|
@ -0,0 +1,27 @@
|
|||
<div class="flex-fill">
|
||||
<div class="mx-auto">
|
||||
<div class="d-flex flex-column gap-3 justify-content-center text-center">
|
||||
<div class="mx-auto p-4 bg-light border rounded">
|
||||
<i class="text-secondary fa fa-fw fa-4x fa-lock"></i>
|
||||
</div>
|
||||
|
||||
<p class="lead">[[2factor:failureInfo.lead]]</p>
|
||||
|
||||
<blockquote>
|
||||
[[2factor:notification.failure]]
|
||||
</blockquote>
|
||||
|
||||
<div class="text-start col-sm-6 offset-sm-3">
|
||||
<p>[[2factor:failureInfo.when, {timeString}, {dateString}]]</p>
|
||||
<p>[[2factor:failureInfo.explanation]]</p>
|
||||
<p>[[2factor:failureInfo.remediation]]</p>
|
||||
|
||||
<div class="d-grid">
|
||||
<a href="{config.relative_path}/me/edit/password" class="btn btn-primary">[[2factor:failureInfo.cta]]</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue