Improve centralized error handling
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { db } from '../config/database.js';
|
||||
import { users } from '../db/schema.js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { users, userEmailAccounts, emailAccounts } from '../db/schema.js';
|
||||
import { eq, inArray } from 'drizzle-orm';
|
||||
import { hashPassword, generateTempPassword } from '../utils/password.js';
|
||||
import { logUserCreation, logRoleChange } from '../services/audit.service.js';
|
||||
import { formatErrorResponse, ConflictError, NotFoundError } from '../utils/errors.js';
|
||||
import { ConflictError, NotFoundError } from '../utils/errors.js';
|
||||
import * as emailAccountService from '../services/email-account.service.js';
|
||||
|
||||
/**
|
||||
@@ -11,7 +11,7 @@ import * as emailAccountService from '../services/email-account.service.js';
|
||||
* Ak je poskytnutý email a emailPassword, automaticky sa fetchne JMAP account ID
|
||||
* POST /api/admin/users
|
||||
*/
|
||||
export const createUser = async (req, res) => {
|
||||
export const createUser = async (req, res, next) => {
|
||||
const { username, email, emailPassword, firstName, lastName, role } = req.body;
|
||||
const adminId = req.userId;
|
||||
const ipAddress = req.ip || req.connection.remoteAddress;
|
||||
@@ -100,8 +100,7 @@ export const createUser = async (req, res) => {
|
||||
: 'Používateľ úspešne vytvorený. Email môže byť nastavený neskôr.',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
return next(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -109,7 +108,7 @@ export const createUser = async (req, res) => {
|
||||
* Zoznam všetkých userov (admin only)
|
||||
* GET /api/admin/users
|
||||
*/
|
||||
export const getAllUsers = async (req, res) => {
|
||||
export const getAllUsers = async (req, res, next) => {
|
||||
try {
|
||||
const allUsers = await db
|
||||
.select({
|
||||
@@ -130,8 +129,7 @@ export const getAllUsers = async (req, res) => {
|
||||
data: allUsers,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
return next(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -139,7 +137,7 @@ export const getAllUsers = async (req, res) => {
|
||||
* Získanie konkrétneho usera (admin only)
|
||||
* GET /api/admin/users/:userId
|
||||
*/
|
||||
export const getUser = async (req, res) => {
|
||||
export const getUser = async (req, res, next) => {
|
||||
const { userId } = req.params;
|
||||
|
||||
try {
|
||||
@@ -176,8 +174,7 @@ export const getUser = async (req, res) => {
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
return next(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -185,7 +182,7 @@ export const getUser = async (req, res) => {
|
||||
* Zmena role usera (admin only)
|
||||
* PATCH /api/admin/users/:userId/role
|
||||
*/
|
||||
export const changeUserRole = async (req, res) => {
|
||||
export const changeUserRole = async (req, res, next) => {
|
||||
const { userId } = req.params;
|
||||
const { role } = req.body;
|
||||
const adminId = req.userId;
|
||||
@@ -228,8 +225,7 @@ export const changeUserRole = async (req, res) => {
|
||||
message: 'Rola používateľa bola zmenená',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
return next(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -237,7 +233,7 @@ export const changeUserRole = async (req, res) => {
|
||||
* Zmazanie usera (admin only)
|
||||
* DELETE /api/admin/users/:userId
|
||||
*/
|
||||
export const deleteUser = async (req, res) => {
|
||||
export const deleteUser = async (req, res, next) => {
|
||||
const { userId } = req.params;
|
||||
|
||||
try {
|
||||
@@ -263,14 +259,38 @@ export const deleteUser = async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Get user's email account IDs before deletion
|
||||
const userEmailAccountLinks = await db
|
||||
.select({ emailAccountId: userEmailAccounts.emailAccountId })
|
||||
.from(userEmailAccounts)
|
||||
.where(eq(userEmailAccounts.userId, userId));
|
||||
|
||||
const emailAccountIds = userEmailAccountLinks.map(link => link.emailAccountId);
|
||||
|
||||
// Delete user (cascades userEmailAccounts links)
|
||||
await db.delete(users).where(eq(users.id, userId));
|
||||
|
||||
// Delete orphaned email accounts (no users linked)
|
||||
// This will cascade delete contacts and emails
|
||||
let deletedEmailAccounts = 0;
|
||||
for (const emailAccountId of emailAccountIds) {
|
||||
const [remainingLinks] = await db
|
||||
.select({ count: db.$count(userEmailAccounts) })
|
||||
.from(userEmailAccounts)
|
||||
.where(eq(userEmailAccounts.emailAccountId, emailAccountId));
|
||||
|
||||
if (remainingLinks.count === 0) {
|
||||
await db.delete(emailAccounts).where(eq(emailAccounts.id, emailAccountId));
|
||||
deletedEmailAccounts++;
|
||||
}
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Používateľ bol zmazaný',
|
||||
deletedEmailAccounts,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
return next(error);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user