add searching, total unread message, create user

This commit is contained in:
richardtekula
2025-11-19 08:45:37 +01:00
parent da01d586fc
commit 97f437c1c4
8 changed files with 1338 additions and 90 deletions

View File

@@ -1,16 +1,18 @@
import { db } from '../config/database.js';
import { users } from '../db/schema.js';
import { eq } from 'drizzle-orm';
import { hashPassword, generateTempPassword } from '../utils/password.js';
import { hashPassword, generateTempPassword, encryptPassword } from '../utils/password.js';
import { logUserCreation, logRoleChange } from '../services/audit.service.js';
import { formatErrorResponse, ConflictError, NotFoundError } from '../utils/errors.js';
import { validateJmapCredentials } from '../services/email.service.js';
/**
* Vytvorenie nového usera s temporary password (admin only)
* Vytvorenie nového usera s automatic temporary password (admin only)
* Ak je poskytnutý email a emailPassword, automaticky sa fetchne JMAP account ID
* POST /api/admin/users
*/
export const createUser = async (req, res) => {
const { username, tempPassword, role, firstName, lastName } = req.body;
const { username, email, emailPassword, firstName, lastName } = req.body;
const adminId = req.userId;
const ipAddress = req.ip || req.connection.remoteAddress;
const userAgent = req.headers['user-agent'];
@@ -27,16 +29,34 @@ export const createUser = async (req, res) => {
throw new ConflictError('Username už existuje');
}
// Hash temporary password
// Automaticky vygeneruj temporary password
const tempPassword = generateTempPassword(12);
const hashedTempPassword = await hashPassword(tempPassword);
// Ak sú poskytnuté email credentials, validuj ich a získaj JMAP account ID
let jmapAccountId = null;
let encryptedEmailPassword = null;
if (email && emailPassword) {
try {
const { accountId } = await validateJmapCredentials(email, emailPassword);
jmapAccountId = accountId;
encryptedEmailPassword = encryptPassword(emailPassword);
} catch (emailError) {
throw new ConflictError(`Nepodarilo sa overiť emailový účet: ${emailError.message}`);
}
}
// Vytvor usera
const [newUser] = await db
.insert(users)
.values({
username,
email: email || null,
emailPassword: encryptedEmailPassword,
jmapAccountId,
tempPassword: hashedTempPassword,
role: role || 'member',
role: 'member', // Vždy member, nie admin
firstName: firstName || null,
lastName: lastName || null,
changedPassword: false,
@@ -44,7 +64,7 @@ export const createUser = async (req, res) => {
.returning();
// Log user creation
await logUserCreation(adminId, newUser.id, username, role || 'member', ipAddress, userAgent);
await logUserCreation(adminId, newUser.id, username, 'member', ipAddress, userAgent);
res.status(201).json({
success: true,
@@ -52,11 +72,18 @@ export const createUser = async (req, res) => {
user: {
id: newUser.id,
username: newUser.username,
email: newUser.email,
firstName: newUser.firstName,
lastName: newUser.lastName,
role: newUser.role,
tempPassword: tempPassword, // Vráti plain text password pre admina
jmapAccountId: newUser.jmapAccountId,
emailSetup: !!newUser.jmapAccountId,
tempPassword: tempPassword, // Vráti plain text password pre admina aby ho mohol poslať userovi
},
},
message: 'Používateľ úspešne vytvorený',
message: newUser.jmapAccountId
? 'Používateľ úspešne vytvorený s emailovým účtom.'
: 'Používateľ úspešne vytvorený. Email môže byť nastavený neskôr.',
});
} catch (error) {
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');