From 24dcae21932e8d01c5df072ea5a6b3330e5a8b39 Mon Sep 17 00:00:00 2001 From: Andrew Rodrigues Date: Wed, 20 Mar 2019 16:34:22 -0400 Subject: [PATCH] feat: manual password expiry. closes #7471 --- public/language/en-GB/admin/manage/users.json | 3 +++ public/src/admin/manage/users.js | 13 +++++++++++++ src/socket.io/admin/user.js | 19 +++++++++++++++++++ src/views/admin/manage/users.tpl | 1 + 4 files changed, 36 insertions(+) diff --git a/public/language/en-GB/admin/manage/users.json b/public/language/en-GB/admin/manage/users.json index 6a17cbf016..05fc3f043f 100644 --- a/public/language/en-GB/admin/manage/users.json +++ b/public/language/en-GB/admin/manage/users.json @@ -6,6 +6,7 @@ "validate-email": "Validate Email", "send-validation-email": "Send Validation Email", "password-reset-email": "Send Password Reset Email", + "force-password-reset": "Force Password Reset & Log User Out", "ban": "Ban User(s)", "temp-ban": "Ban User(s) Temporarily", "unban": "Unban User(s)", @@ -81,7 +82,9 @@ "alerts.confirm-remove-moderator": "Do you really want to remove this moderator?", "alerts.remove-moderator-success": "User is no longer moderator.", "alerts.confirm-validate-email": "Do you want to validate email(s) of these user(s)?", + "alerts.confirm-force-password-reset": "Are you sure you want to force the password reset and log out these user(s)?", "alerts.validate-email-success": "Emails validated", + "alerts.validate-force-password-reset-success": "User(s) passwords have been reset and their existing sessions have been revoked.", "alerts.password-reset-confirm": "Do you want to send password reset email(s) to these user(s)?", "alerts.confirm-delete": "Warning!
Do you really want to delete user(s)?
This action is not reversable! Only the user account will be deleted, their posts and topics will remain.", "alerts.delete-success": "User(s) Deleted!", diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index 9efb1807be..73e33b391b 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -175,6 +175,19 @@ define('admin/manage/users', ['translator', 'benchpress'], function (translator, }); }); + $('.force-password-reset').on('click', function () { + var uids = getSelectedUids(); + if (!uids.length) { + return; + } + + bootbox.confirm('[[admin/manage/users:alerts.confirm-force-password-reset]]', function (confirm) { + if (confirm) { + socket.emit('admin.user.forcePasswordReset', uids, done('[[admin/manage/users:alerts.validate-force-password-reset-success]]')); + } + }); + }); + $('.delete-user').on('click', function () { var uids = getSelectedUids(); if (!uids.length) { diff --git a/src/socket.io/admin/user.js b/src/socket.io/admin/user.js index efd193ede0..02ade56a89 100644 --- a/src/socket.io/admin/user.js +++ b/src/socket.io/admin/user.js @@ -126,6 +126,25 @@ User.sendPasswordResetEmail = function (socket, uids, callback) { }, callback); }; +User.forcePasswordReset = function (socket, uids, callback) { + if (!Array.isArray(uids)) { + return callback(new Error('[[error:invalid-data]]')); + } + + uids = uids.filter(uid => parseInt(uid, 10)); + + async.each(uids, function (uid, next) { + async.waterfall([ + function (next) { + user.setUserField(uid, 'passwordExpiry', Date.now(), next); + }, + function (next) { + user.auth.revokeAllSessions(uid, next); + }, + ], next); + }, callback); +}; + User.deleteUsers = function (socket, uids, callback) { deleteUsers(socket, uids, function (uid, next) { user.deleteAccount(uid, next); diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 1490c8b1c4..4b65102352 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -11,6 +11,7 @@
  • [[admin/manage/users:validate-email]]
  • [[admin/manage/users:send-validation-email]]
  • [[admin/manage/users:password-reset-email]]
  • +
  • [[admin/manage/users:force-password-reset]]
  • [[admin/manage/users:ban]]
  • [[admin/manage/users:temp-ban]]