Files
Zumri-Backend/app/controllers/adminUser.controller.js
Sathira Sri Sathara 9d3d431416 feat: implement identity and security features
- 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.
2026-09-03 13:56:18 +05:30

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");