diff --git a/server/socket-handlers/user-management-socket-handler.js b/server/socket-handlers/user-management-socket-handler.js index 352d075cb..f324b8c55 100644 --- a/server/socket-handlers/user-management-socket-handler.js +++ b/server/socket-handlers/user-management-socket-handler.js @@ -2,6 +2,19 @@ const { checkLogin } = require("../util-server"); const { R } = require("redbean-node"); const passwordHash = require("../password-hash"); const { log } = require("../../src/util"); +const { passwordStrength } = require("check-password-strength"); + +/** + * Validates password strength + * @param {string} password Password to validate + * @returns {void} + * @throws {Error} If password is too weak + */ +function validatePasswordStrength(password) { + if (passwordStrength(password).value === "Too weak") { + throw new Error("Password is too weak. It should contain alphabetic and numeric characters. It must be at least 6 characters in length."); + } +} /** * Handlers for user management @@ -45,6 +58,9 @@ module.exports.userManagementSocketHandler = (socket, server) => { throw new Error("Username and password are required"); } + // Validate password strength + validatePasswordStrength(userData.password); + // Check if username already exists const existingUser = await R.findOne("user", " username = ? ", [ userData.username.trim() ]); if (existingUser) { @@ -64,6 +80,7 @@ module.exports.userManagementSocketHandler = (socket, server) => { callback({ ok: true, msg: "User created successfully", + msgi18n: true, userId: user.id, }); } catch (e) { @@ -71,6 +88,7 @@ module.exports.userManagementSocketHandler = (socket, server) => { callback({ ok: false, msg: e.message, + msgi18n: true, }); } }); @@ -89,6 +107,11 @@ module.exports.userManagementSocketHandler = (socket, server) => { const isEditingSelf = Number(userId) === Number(socket.userID); const usernameChanged = userData.username && userData.username.trim() !== user.username; + // Don't allow deactivating yourself + if (isEditingSelf && typeof userData.active !== "undefined" && !userData.active) { + throw new Error("Cannot deactivate your own account"); + } + // Update user fields if (userData.username && userData.username.trim() !== user.username) { // Check if new username already exists @@ -108,6 +131,8 @@ module.exports.userManagementSocketHandler = (socket, server) => { // Update password if provided if (userData.password) { + // Validate password strength + validatePasswordStrength(userData.password); user.password = await passwordHash.generate(userData.password); } @@ -118,6 +143,7 @@ module.exports.userManagementSocketHandler = (socket, server) => { callback({ ok: true, msg: "User updated successfully", + msgi18n: true, requiresLogout: isEditingSelf && usernameChanged, }); } catch (e) { @@ -125,6 +151,7 @@ module.exports.userManagementSocketHandler = (socket, server) => { callback({ ok: false, msg: e.message, + msgi18n: true, }); } }); @@ -155,11 +182,13 @@ module.exports.userManagementSocketHandler = (socket, server) => { callback({ ok: true, msg: "User deleted successfully", + msgi18n: true, }); } catch (error) { callback({ ok: false, msg: error.message, + msgi18n: true, }); } }); diff --git a/src/components/settings/Users.vue b/src/components/settings/Users.vue index 58dc2251e..1c00f6e5b 100644 --- a/src/components/settings/Users.vue +++ b/src/components/settings/Users.vue @@ -51,18 +51,18 @@ - {{ $t("Are you sure you want to delete this user?") }} + {{ $t("deleteUserWarning") }} -