9d3d431416
- Added account types and privileged account types constants. - Created admin user controller for updating user security fields. - Developed role assignment controller for managing user roles. - Implemented validation middleware for request schemas. - Defined user role and auth session models for database interactions. - Created services for authentication, email notifications, and OTP handling. - Developed OAuth service for Google and Apple authentication. - Added JWT utility functions for token generation and verification. - Implemented comprehensive tests for authentication, session management, and password policies. - Created migration for updating user schema and adding new tables for auth sessions and user identities.
25 lines
2.0 KiB
JavaScript
25 lines
2.0 KiB
JavaScript
const db = require("../models");
|
|
const { ACCOUNT_TYPE_VALUES } = require("../constants/accountTypes");
|
|
const { revokeAllUserSessions } = require("../services/auth/session.service");
|
|
const { logActivity } = require("../services/activity.service");
|
|
|
|
const updateSecurityField = (field) => async (req, res, next) => {
|
|
try {
|
|
const value = req.body[field];
|
|
if (field === "accountType" && !ACCOUNT_TYPE_VALUES.includes(value)) return res.status(400).json({ success: false, error: { code: "INVALID_ACCOUNT_TYPE", message: "Invalid account type" } });
|
|
if (field === "accountStatus" && !["PENDING_VERIFICATION", "ACTIVE", "SUSPENDED", "DEACTIVATED"].includes(value)) return res.status(400).json({ success: false, error: { code: "INVALID_ACCOUNT_STATUS", message: "Invalid account status" } });
|
|
if (req.params.id === req.user.id) return res.status(400).json({ success: false, error: { code: "SELF_SECURITY_CHANGE_DENIED", message: "Security-sensitive self changes are not allowed" } });
|
|
let target; let previous;
|
|
await db.sequelize.transaction(async (transaction) => {
|
|
target = await db.User.findByPk(req.params.id, { transaction, lock: transaction.LOCK.UPDATE });
|
|
if (!target) throw Object.assign(new Error("User not found"), { status: 404, code: "USER_NOT_FOUND" });
|
|
previous = target[field]; target[field] = value; target.tokenVersion += 1; await target.save({ transaction });
|
|
await revokeAllUserSessions(target.id, `ADMIN_${field.toUpperCase()}_CHANGE`, transaction);
|
|
});
|
|
await logActivity({ user: req.user, description: `${field} changed for ${target.id} from ${previous} to ${value}; reason: ${req.body.reason || "not supplied"}; request: ${req.id}`, type: field === "accountStatus" ? "ACCOUNT_STATUS_CHANGED" : "ACCOUNT_TYPE_CHANGED", module: "Identity Administration" });
|
|
res.json({ success: true, data: { id: target.id, [field]: target[field] } });
|
|
} catch (error) { next(error); }
|
|
};
|
|
exports.updateStatus = updateSecurityField("accountStatus");
|
|
exports.updateAccountType = updateSecurityField("accountType");
|