diff --git a/src/controllers/admin.controller.js b/src/controllers/admin.controller.js index a53dc05..7cb01df 100644 --- a/src/controllers/admin.controller.js +++ b/src/controllers/admin.controller.js @@ -54,7 +54,7 @@ export const createUser = async (req, res, next) => { : 'Používateľ úspešne vytvorený. Email môže byť nastavený neskôr.', }); } catch (error) { - return next(error); + next(error); } }; @@ -72,7 +72,7 @@ export const getAllUsers = async (req, res, next) => { data: allUsers, }); } catch (error) { - return next(error); + next(error); } }; @@ -93,7 +93,7 @@ export const getUser = async (req, res, next) => { }, }); } catch (error) { - return next(error); + next(error); } }; @@ -120,7 +120,7 @@ export const changeUserRole = async (req, res, next) => { message: 'Rola používateľa bola zmenená', }); } catch (error) { - return next(error); + next(error); } }; @@ -140,7 +140,7 @@ export const deleteUser = async (req, res, next) => { deletedEmailAccounts: result.deletedEmailAccounts, }); } catch (error) { - return next(error); + next(error); } }; @@ -157,6 +157,6 @@ export const getServerStatus = async (req, res, next) => { data: status, }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index eac3d24..b47f61c 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -57,7 +57,7 @@ export const login = async (req, res, next) => { // Log failed login await logLoginAttempt(username, false, ipAddress, userAgent, error.message); - return next(error); + next(error); } }; @@ -84,7 +84,7 @@ export const setPassword = async (req, res, next) => { message: 'Heslo úspešne nastavené', }); } catch (error) { - return next(error); + next(error); } }; @@ -114,7 +114,7 @@ export const linkEmail = async (req, res, next) => { message: 'Email účet úspešne pripojený a overený', }); } catch (error) { - return next(error); + next(error); } }; @@ -135,7 +135,7 @@ export const skipEmail = async (req, res, next) => { message: 'Email setup preskočený', }); } catch (error) { - return next(error); + next(error); } }; @@ -164,7 +164,7 @@ export const logout = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -183,7 +183,7 @@ export const getSession = async (req, res, next) => { }, }); } catch (error) { - return next(error); + next(error); } }; @@ -201,6 +201,6 @@ export const getMe = async (req, res, next) => { }, }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/company.controller.js b/src/controllers/company.controller.js index 3ce84b4..27be284 100644 --- a/src/controllers/company.controller.js +++ b/src/controllers/company.controller.js @@ -20,7 +20,7 @@ export const getAllCompanies = async (req, res, next) => { data: companies, }); } catch (error) { - return next(error); + next(error); } }; @@ -39,7 +39,7 @@ export const getCompanyById = async (req, res, next) => { data: company, }); } catch (error) { - return next(error); + next(error); } }; @@ -62,7 +62,7 @@ export const getCompanyEmailThreads = async (req, res, next) => { data: result, }); } catch (error) { - return next(error); + next(error); } }; @@ -80,7 +80,7 @@ export const getCompanyUnreadCounts = async (req, res, next) => { data: counts, }); } catch (error) { - return next(error); + next(error); } }; @@ -99,7 +99,7 @@ export const getCompanyWithRelations = async (req, res, next) => { data: company, }); } catch (error) { - return next(error); + next(error); } }; @@ -124,7 +124,7 @@ export const createCompany = async (req, res, next) => { message: 'Firma bola vytvorená', }); } catch (error) { - return next(error); + next(error); } }; @@ -146,7 +146,7 @@ export const updateCompany = async (req, res, next) => { message: 'Firma bola aktualizovaná', }); } catch (error) { - return next(error); + next(error); } }; @@ -173,7 +173,7 @@ export const deleteCompany = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -193,7 +193,7 @@ export const getCompanyNotes = async (req, res, next) => { data: notes, }); } catch (error) { - return next(error); + next(error); } }; @@ -218,7 +218,7 @@ export const addCompanyNote = async (req, res, next) => { message: 'Poznámka bola pridaná', }); } catch (error) { - return next(error); + next(error); } }; @@ -241,7 +241,7 @@ export const updateCompanyNote = async (req, res, next) => { message: 'Poznámka bola aktualizovaná', }); } catch (error) { - return next(error); + next(error); } }; @@ -260,7 +260,7 @@ export const deleteCompanyNote = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -280,7 +280,7 @@ export const getCompanyReminders = async (req, res, next) => { data: reminders, }); } catch (error) { - return next(error); + next(error); } }; @@ -297,7 +297,7 @@ export const createCompanyReminder = async (req, res, next) => { message: 'Reminder bol pridaný', }); } catch (error) { - return next(error); + next(error); } }; @@ -314,7 +314,7 @@ export const updateCompanyReminder = async (req, res, next) => { message: 'Reminder bol aktualizovaný', }); } catch (error) { - return next(error); + next(error); } }; @@ -329,7 +329,7 @@ export const deleteCompanyReminder = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -341,7 +341,7 @@ export const getReminderSummary = async (_req, res, next) => { data: summary, }); } catch (error) { - return next(error); + next(error); } }; @@ -353,7 +353,7 @@ export const getReminderCountsByCompany = async (_req, res, next) => { data: counts, }); } catch (error) { - return next(error); + next(error); } }; @@ -366,6 +366,6 @@ export const getUpcomingReminders = async (_req, res, next) => { data: reminders, }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/contact.controller.js b/src/controllers/contact.controller.js index 2341b01..cae9719 100644 --- a/src/controllers/contact.controller.js +++ b/src/controllers/contact.controller.js @@ -33,7 +33,7 @@ export const getContacts = async (req, res, next) => { data: contacts, }); } catch (error) { - return next(error); + next(error); } }; @@ -79,7 +79,7 @@ export const discoverContacts = async (req, res, next) => { data: potentialContacts, }); } catch (error) { - return next(error); + next(error); } }; @@ -138,7 +138,7 @@ export const addContact = async (req, res, next) => { message: 'Kontakt pridaný a emaily synchronizované', }); } catch (error) { - return next(error); + next(error); } }; @@ -172,7 +172,7 @@ export const removeContact = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -208,7 +208,7 @@ export const updateContact = async (req, res, next) => { message: 'Kontakt aktualizovaný', }); } catch (error) { - return next(error); + next(error); } }; @@ -255,7 +255,7 @@ export const linkCompanyToContact = async (req, res, next) => { message: 'Firma bola linknutá ku kontaktu', }); } catch (error) { - return next(error); + next(error); } }; @@ -290,7 +290,7 @@ export const unlinkCompanyFromContact = async (req, res, next) => { message: 'Firma bola odlinknutá od kontaktu', }); } catch (error) { - return next(error); + next(error); } }; @@ -327,6 +327,6 @@ export const createCompanyFromContact = async (req, res, next) => { message: 'Firma bola vytvorená z kontaktu', }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/crm-email.controller.js b/src/controllers/crm-email.controller.js index 31875b3..f5b597b 100644 --- a/src/controllers/crm-email.controller.js +++ b/src/controllers/crm-email.controller.js @@ -12,17 +12,7 @@ import { logger } from '../utils/logger.js'; export const getEmails = async (req, res, next) => { try { const userId = req.userId; - const { accountId } = req.query; - - if (!accountId) { - return res.status(400).json({ - success: false, - error: { - message: 'accountId je povinný parameter', - statusCode: 400, - }, - }); - } + const { accountId } = req; // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); @@ -35,7 +25,7 @@ export const getEmails = async (req, res, next) => { data: emails, }); } catch (error) { - return next(error); + next(error); } }; @@ -47,17 +37,7 @@ export const getThread = async (req, res, next) => { try { const userId = req.userId; const { threadId } = req.params; - const { accountId } = req.query; - - if (!accountId) { - return res.status(400).json({ - success: false, - error: { - message: 'accountId je povinný parameter', - statusCode: 400, - }, - }); - } + const { accountId } = req; // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); @@ -70,7 +50,7 @@ export const getThread = async (req, res, next) => { data: thread, }); } catch (error) { - return next(error); + next(error); } }; @@ -81,17 +61,8 @@ export const getThread = async (req, res, next) => { export const searchEmails = async (req, res, next) => { try { const userId = req.userId; - const { q, accountId } = req.query; - - if (!accountId) { - return res.status(400).json({ - success: false, - error: { - message: 'accountId je povinný parameter', - statusCode: 400, - }, - }); - } + const { q } = req.query; + const { accountId } = req; // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); @@ -104,7 +75,7 @@ export const searchEmails = async (req, res, next) => { data: results, }); } catch (error) { - return next(error); + next(error); } }; @@ -135,7 +106,7 @@ export const getUnreadCount = async (req, res, next) => { }); } catch (error) { logger.error('ERROR in getUnreadCount', { error: error.message }); - return next(error); + next(error); } }; @@ -198,7 +169,7 @@ export const syncEmails = async (req, res, next) => { } } - return res.status(200).json({ + res.status(200).json({ success: true, message: 'Emaily synchronizované', data: { @@ -208,7 +179,7 @@ export const syncEmails = async (req, res, next) => { }, }); } catch (error) { - return next(error); + next(error); } }; @@ -220,7 +191,8 @@ export const markAsRead = async (req, res, next) => { try { const userId = req.userId; const { jmapId } = req.params; - const { isRead, accountId } = req.body; + const { isRead } = req.body; + const accountId = req.accountId || req.body.accountId; if (!accountId) { return res.status(400).json({ @@ -243,7 +215,7 @@ export const markAsRead = async (req, res, next) => { message: `Email označený ako ${isRead ? 'prečítaný' : 'neprečítaný'}`, }); } catch (error) { - return next(error); + next(error); } }; @@ -255,17 +227,7 @@ export const markContactEmailsRead = async (req, res, next) => { try { const userId = req.userId; const { contactId } = req.params; - const { accountId } = req.query; - - if (!accountId) { - return res.status(400).json({ - success: false, - error: { - message: 'accountId je povinný parameter', - statusCode: 400, - }, - }); - } + const { accountId } = req; // Verify user has access to this email account const emailAccount = await emailAccountService.getEmailAccountWithCredentials(accountId, userId); @@ -287,9 +249,8 @@ export const markContactEmailsRead = async (req, res, next) => { } try { await markEmailAsRead(jmapConfig, userId, email.jmapId, true); - logger.debug(`✅ Marked JMAP email as read: ${email.jmapId}`); } catch (jmapError) { - logger.error('Failed to mark JMAP email as read', { jmapId: email.jmapId, error: jmapError.message }); + logger.error('Nepodarilo sa označiť JMAP email ako prečítaný', { jmapId: email.jmapId, error: jmapError.message }); } } } @@ -301,7 +262,7 @@ export const markContactEmailsRead = async (req, res, next) => { }); } catch (error) { logger.error('ERROR in markContactEmailsRead', { error: error.message }); - return next(error); + next(error); } }; @@ -313,17 +274,7 @@ export const markThreadRead = async (req, res, next) => { try { const userId = req.userId; const { threadId } = req.params; - const { accountId } = req.query; - - if (!accountId) { - return res.status(400).json({ - success: false, - error: { - message: 'accountId je povinný parameter', - statusCode: 400, - }, - }); - } + const { accountId } = req; // Verify user has access to this email account const emailAccount = await emailAccountService.getEmailAccountWithCredentials(accountId, userId); @@ -340,7 +291,7 @@ export const markThreadRead = async (req, res, next) => { try { await markEmailAsRead(jmapConfig, userId, email.jmapId, true); } catch (jmapError) { - logger.error('Failed to mark JMAP email as read', { jmapId: email.jmapId, error: jmapError.message }); + logger.error('Nepodarilo sa označiť JMAP email ako prečítaný', { jmapId: email.jmapId, error: jmapError.message }); } } @@ -353,7 +304,7 @@ export const markThreadRead = async (req, res, next) => { count, }); } catch (error) { - return next(error); + next(error); } }; @@ -405,7 +356,7 @@ export const replyToEmail = async (req, res, next) => { data: result, }); } catch (error) { - return next(error); + next(error); } }; @@ -417,7 +368,7 @@ export const getContactEmails = async (req, res, next) => { try { const userId = req.userId; const { contactId } = req.params; - const { accountId } = req.query; + const accountId = req.accountId || req.query.accountId; if (!accountId) { return res.status(400).json({ @@ -440,7 +391,7 @@ export const getContactEmails = async (req, res, next) => { data: emails, }); } catch (error) { - return next(error); + next(error); } }; @@ -494,6 +445,6 @@ export const searchEmailsJMAP = async (req, res, next) => { }); } catch (error) { logger.error('ERROR in searchEmailsJMAP', { error: error.message }); - return next(error); + next(error); } }; diff --git a/src/controllers/email-account.controller.js b/src/controllers/email-account.controller.js index 348a39e..a8ead3f 100644 --- a/src/controllers/email-account.controller.js +++ b/src/controllers/email-account.controller.js @@ -17,7 +17,7 @@ export const getEmailAccounts = async (req, res, next) => { data: accounts, }); } catch (error) { - return next(error); + next(error); } }; @@ -37,7 +37,7 @@ export const getEmailAccount = async (req, res, next) => { data: account, }); } catch (error) { - return next(error); + next(error); } }; @@ -67,7 +67,7 @@ export const createEmailAccount = async (req, res, next) => { message: 'Email účet úspešne pripojený', }); } catch (error) { - return next(error); + next(error); } }; @@ -93,7 +93,7 @@ export const updateEmailAccountPassword = async (req, res, next) => { message: 'Heslo k emailovému účtu bolo aktualizované', }); } catch (error) { - return next(error); + next(error); } }; @@ -119,7 +119,7 @@ export const toggleEmailAccountStatus = async (req, res, next) => { message: `Email účet ${isActive ? 'aktivovaný' : 'deaktivovaný'}`, }); } catch (error) { - return next(error); + next(error); } }; @@ -140,7 +140,7 @@ export const setPrimaryEmailAccount = async (req, res, next) => { message: 'Primárny email účet bol nastavený', }); } catch (error) { - return next(error); + next(error); } }; @@ -161,6 +161,6 @@ export const deleteEmailAccount = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/meeting.controller.js b/src/controllers/meeting.controller.js index 47b7b01..fb0b537 100644 --- a/src/controllers/meeting.controller.js +++ b/src/controllers/meeting.controller.js @@ -20,7 +20,7 @@ export const getMeetingsByMonth = async (req, res, next) => { data: meetings, }); } catch (error) { - return next(error); + next(error); } }; @@ -39,7 +39,7 @@ export const getMeetingById = async (req, res, next) => { data: meeting, }); } catch (error) { - return next(error); + next(error); } }; @@ -60,7 +60,7 @@ export const createMeeting = async (req, res, next) => { message: 'Meeting bol vytvorený', }); } catch (error) { - return next(error); + next(error); } }; @@ -81,7 +81,7 @@ export const updateMeeting = async (req, res, next) => { message: 'Meeting bol upravený', }); } catch (error) { - return next(error); + next(error); } }; @@ -100,6 +100,6 @@ export const deleteMeeting = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/note.controller.js b/src/controllers/note.controller.js index e88ed3d..6e15ccd 100644 --- a/src/controllers/note.controller.js +++ b/src/controllers/note.controller.js @@ -24,7 +24,7 @@ export const getAllNotes = async (req, res, next) => { data: notes, }); } catch (error) { - return next(error); + next(error); } }; @@ -43,7 +43,7 @@ export const getNoteById = async (req, res, next) => { data: note, }); } catch (error) { - return next(error); + next(error); } }; @@ -65,7 +65,7 @@ export const createNote = async (req, res, next) => { message: 'Poznámka bola vytvorená', }); } catch (error) { - return next(error); + next(error); } }; @@ -87,7 +87,7 @@ export const updateNote = async (req, res, next) => { message: 'Poznámka bola aktualizovaná', }); } catch (error) { - return next(error); + next(error); } }; @@ -106,7 +106,7 @@ export const deleteNote = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -126,7 +126,7 @@ export const getMyReminders = async (req, res, next) => { data: reminders, }); } catch (error) { - return next(error); + next(error); } }; @@ -146,6 +146,6 @@ export const markReminderSent = async (req, res, next) => { message: 'Reminder označený ako odoslaný', }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/project.controller.js b/src/controllers/project.controller.js index 9585e66..d79440f 100644 --- a/src/controllers/project.controller.js +++ b/src/controllers/project.controller.js @@ -18,7 +18,7 @@ export const getAllProjects = async (req, res, next) => { data: projects, }); } catch (error) { - return next(error); + next(error); } }; @@ -37,7 +37,7 @@ export const getProjectById = async (req, res, next) => { data: project, }); } catch (error) { - return next(error); + next(error); } }; @@ -56,7 +56,7 @@ export const getProjectWithRelations = async (req, res, next) => { data: project, }); } catch (error) { - return next(error); + next(error); } }; @@ -81,7 +81,7 @@ export const createProject = async (req, res, next) => { message: 'Projekt bol vytvorený', }); } catch (error) { - return next(error); + next(error); } }; @@ -103,7 +103,7 @@ export const updateProject = async (req, res, next) => { message: 'Projekt bol aktualizovaný', }); } catch (error) { - return next(error); + next(error); } }; @@ -130,7 +130,7 @@ export const deleteProject = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -150,7 +150,7 @@ export const getProjectNotes = async (req, res, next) => { data: notes, }); } catch (error) { - return next(error); + next(error); } }; @@ -176,7 +176,7 @@ export const addProjectNote = async (req, res, next) => { message: 'Poznámka bola pridaná', }); } catch (error) { - return next(error); + next(error); } }; @@ -200,7 +200,7 @@ export const updateProjectNote = async (req, res, next) => { message: 'Poznámka bola aktualizovaná', }); } catch (error) { - return next(error); + next(error); } }; @@ -219,7 +219,7 @@ export const deleteProjectNote = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -239,7 +239,7 @@ export const getProjectUsers = async (req, res, next) => { data: users, }); } catch (error) { - return next(error); + next(error); } }; @@ -267,7 +267,7 @@ export const assignUserToProject = async (req, res, next) => { message: 'Používateľ bol priradený k projektu', }); } catch (error) { - return next(error); + next(error); } }; @@ -286,7 +286,7 @@ export const removeUserFromProject = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -308,6 +308,6 @@ export const updateUserRoleOnProject = async (req, res, next) => { message: 'Rola používateľa bola aktualizovaná', }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/time-tracking.controller.js b/src/controllers/time-tracking.controller.js index c83d3a8..66bd7dc 100644 --- a/src/controllers/time-tracking.controller.js +++ b/src/controllers/time-tracking.controller.js @@ -26,7 +26,7 @@ export const startTimeEntry = async (req, res, next) => { message: 'Časovač bol spustený', }); } catch (error) { - return next(error); + next(error); } }; @@ -56,7 +56,7 @@ export const stopTimeEntry = async (req, res, next) => { message: 'Časovač bol zastavený', }); } catch (error) { - return next(error); + next(error); } }; @@ -75,7 +75,7 @@ export const getRunningTimeEntry = async (req, res, next) => { data: entry, }); } catch (error) { - return next(error); + next(error); } }; @@ -92,7 +92,7 @@ export const getAllRunningTimeEntries = async (req, res, next) => { data: entries, }); } catch (error) { - return next(error); + next(error); } }; @@ -121,7 +121,7 @@ export const getAllTimeEntries = async (req, res, next) => { data: entries, }); } catch (error) { - return next(error); + next(error); } }; @@ -148,7 +148,7 @@ export const getMonthlyTimeEntries = async (req, res, next) => { data: entries, }); } catch (error) { - return next(error); + next(error); } }; @@ -175,7 +175,7 @@ export const generateMonthlyTimesheet = async (req, res, next) => { message: 'Timesheet bol vygenerovaný', }); } catch (error) { - return next(error); + next(error); } }; @@ -194,7 +194,7 @@ export const getTimeEntryById = async (req, res, next) => { data: entry, }); } catch (error) { - return next(error); + next(error); } }; @@ -213,7 +213,7 @@ export const getTimeEntryWithRelations = async (req, res, next) => { data: entry, }); } catch (error) { - return next(error); + next(error); } }; @@ -244,7 +244,7 @@ export const updateTimeEntry = async (req, res, next) => { message: 'Záznam bol aktualizovaný', }); } catch (error) { - return next(error); + next(error); } }; @@ -263,7 +263,7 @@ export const deleteTimeEntry = async (req, res, next) => { res.status(200).json(result); } catch (error) { - return next(error); + next(error); } }; @@ -289,6 +289,6 @@ export const getMonthlyStats = async (req, res, next) => { data: stats, }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/timesheet.controller.js b/src/controllers/timesheet.controller.js index 7b4b215..c62dc3c 100644 --- a/src/controllers/timesheet.controller.js +++ b/src/controllers/timesheet.controller.js @@ -33,7 +33,7 @@ export const uploadTimesheet = async (req, res, next) => { message: 'Timesheet bol úspešne nahraný', }); } catch (error) { - return next(error); + next(error); } }; @@ -55,7 +55,7 @@ export const getMyTimesheets = async (req, res, next) => { }, }); } catch (error) { - return next(error); + next(error); } }; @@ -77,7 +77,7 @@ export const getAllTimesheets = async (req, res, next) => { }, }); } catch (error) { - return next(error); + next(error); } }; @@ -95,7 +95,7 @@ export const downloadTimesheet = async (req, res, next) => { res.download(filePath, fileName); } catch (error) { - return next(error); + next(error); } }; @@ -117,6 +117,6 @@ export const deleteTimesheet = async (req, res, next) => { message: 'Timesheet bol zmazaný', }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/controllers/todo.controller.js b/src/controllers/todo.controller.js index fca493e..f85eaea 100644 --- a/src/controllers/todo.controller.js +++ b/src/controllers/todo.controller.js @@ -32,7 +32,7 @@ export const getAllTodos = async (req, res, next) => { data: todos, }); } catch (error) { - return next(error); + next(error); } }; @@ -58,7 +58,7 @@ export const getMyTodos = async (req, res, next) => { data: todos, }); } catch (error) { - return next(error); + next(error); } }; @@ -77,7 +77,7 @@ export const getTodoById = async (req, res, next) => { data: todo, }); } catch (error) { - return next(error); + next(error); } }; @@ -96,7 +96,7 @@ export const getTodoWithRelations = async (req, res, next) => { data: todo, }); } catch (error) { - return next(error); + next(error); } }; @@ -121,7 +121,7 @@ export const createTodo = async (req, res, next) => { message: 'Todo bolo vytvorené', }); } catch (error) { - return next(error); + next(error); } }; @@ -143,7 +143,7 @@ export const updateTodo = async (req, res, next) => { message: 'Todo bolo aktualizované', }); } catch (error) { - return next(error); + next(error); } }; @@ -170,7 +170,7 @@ export const deleteTodo = async (req, res, next) => { message: result.message, }); } catch (error) { - return next(error); + next(error); } }; @@ -203,6 +203,6 @@ export const toggleTodo = async (req, res, next) => { message: 'Todo status aktualizovaný', }); } catch (error) { - return next(error); + next(error); } }; diff --git a/src/middlewares/global/validateBody.js b/src/middlewares/global/validateBody.js index 462b9a2..619b3d6 100644 --- a/src/middlewares/global/validateBody.js +++ b/src/middlewares/global/validateBody.js @@ -13,7 +13,7 @@ export function validateBody(req, res, next) { for (const pattern of dangerousPatterns) { if (pattern.test(data)) { logger.warn('Suspicious input detected', { data: data.substring(0, 100) }); - return res.status(400).json({ message: 'Malicious content detected in request data' }); + return res.status(400).json({ message: 'Detegovaný škodlivý obsah v požiadavke' }); } } next(); diff --git a/src/middlewares/security/requireAccountId.js b/src/middlewares/security/requireAccountId.js new file mode 100644 index 0000000..bed1cfd --- /dev/null +++ b/src/middlewares/security/requireAccountId.js @@ -0,0 +1,20 @@ +/** + * Middleware na validáciu accountId parametra + * Kontroluje query alebo body a nastaví req.accountId + */ +export const requireAccountId = (req, res, next) => { + const accountId = req.query.accountId || req.body.accountId; + + if (!accountId) { + return res.status(400).json({ + success: false, + error: { + message: 'accountId je povinný parameter', + statusCode: 400, + }, + }); + } + + req.accountId = accountId; + next(); +}; diff --git a/src/routes/company.routes.js b/src/routes/company.routes.js index 3a57a66..5d787e5 100644 --- a/src/routes/company.routes.js +++ b/src/routes/company.routes.js @@ -1,6 +1,7 @@ import express from 'express'; import * as companyController from '../controllers/company.controller.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js'; +import { requireAdmin } from '../middlewares/auth/roleMiddleware.js'; import { validateBody, validateParams } from '../middlewares/security/validateInput.js'; import { createCompanySchema, updateCompanySchema, createCompanyReminderSchema, updateCompanyReminderSchema } from '../validators/crm.validators.js'; import { z } from 'zod'; @@ -39,24 +40,27 @@ router.get( companyController.getCompanyById ); -// Create new company +// Create new company (admin only) router.post( '/', + requireAdmin, validateBody(createCompanySchema), companyController.createCompany ); -// Update company +// Update company (admin only) router.patch( '/:companyId', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid() })), validateBody(updateCompanySchema), companyController.updateCompany ); -// Delete company +// Delete company (admin only) router.delete( '/:companyId', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid() })), companyController.deleteCompany ); @@ -70,6 +74,7 @@ router.get( router.post( '/:companyId/notes', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid() })), validateBody(z.object({ content: z.string().min(1), @@ -79,6 +84,7 @@ router.post( router.patch( '/:companyId/notes/:noteId', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid(), noteId: z.string().uuid() @@ -91,6 +97,7 @@ router.patch( router.delete( '/:companyId/notes/:noteId', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid(), noteId: z.string().uuid() @@ -107,6 +114,7 @@ router.get( router.post( '/:companyId/reminders', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid() })), validateBody(createCompanyReminderSchema), companyController.createCompanyReminder @@ -114,6 +122,7 @@ router.post( router.patch( '/:companyId/reminders/:reminderId', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid(), reminderId: z.string().uuid() @@ -124,6 +133,7 @@ router.patch( router.delete( '/:companyId/reminders/:reminderId', + requireAdmin, validateParams(z.object({ companyId: z.string().uuid(), reminderId: z.string().uuid() diff --git a/src/routes/crm-email.routes.js b/src/routes/crm-email.routes.js index 3712910..b399b8f 100644 --- a/src/routes/crm-email.routes.js +++ b/src/routes/crm-email.routes.js @@ -1,6 +1,7 @@ import express from 'express'; import * as crmEmailController from '../controllers/crm-email.controller.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js'; +import { requireAccountId } from '../middlewares/security/requireAccountId.js'; import { validateBody, validateParams } from '../middlewares/security/validateInput.js'; import { z } from 'zod'; @@ -13,11 +14,11 @@ router.use(authenticate); * Email management */ -// Get all emails -router.get('/', crmEmailController.getEmails); +// Get all emails (accountId required) +router.get('/', requireAccountId, crmEmailController.getEmails); -// Search emails (DB search - searches in stored emails only) -router.get('/search', crmEmailController.searchEmails); +// Search emails (DB search - searches in stored emails only, accountId required) +router.get('/search', requireAccountId, crmEmailController.searchEmails); // Search emails using JMAP full-text search (searches in all emails via JMAP) router.get('/search-jmap', crmEmailController.searchEmailsJMAP); @@ -28,23 +29,26 @@ router.get('/unread-count', crmEmailController.getUnreadCount); // Sync latest emails from JMAP router.post('/sync', crmEmailController.syncEmails); -// Get email thread (conversation) +// Get email thread (conversation, accountId required) router.get( '/thread/:threadId', + requireAccountId, validateParams(z.object({ threadId: z.string() })), crmEmailController.getThread ); -// Mark thread as read +// Mark thread as read (accountId required) router.post( '/thread/:threadId/read', + requireAccountId, validateParams(z.object({ threadId: z.string() })), crmEmailController.markThreadRead ); -// Mark all emails from contact as read +// Mark all emails from contact as read (accountId required) router.post( '/contact/:contactId/read', + requireAccountId, validateParams(z.object({ contactId: z.string().uuid() })), crmEmailController.markContactEmailsRead ); diff --git a/src/routes/project.routes.js b/src/routes/project.routes.js index 4188ee3..2e89d63 100644 --- a/src/routes/project.routes.js +++ b/src/routes/project.routes.js @@ -1,6 +1,7 @@ import express from 'express'; import * as projectController from '../controllers/project.controller.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js'; +import { requireAdmin } from '../middlewares/auth/roleMiddleware.js'; import { validateBody, validateParams } from '../middlewares/security/validateInput.js'; import { createProjectSchema, updateProjectSchema } from '../validators/crm.validators.js'; import { z } from 'zod'; @@ -24,24 +25,27 @@ router.get( projectController.getProjectById ); -// Create new project +// Create new project (admin only) router.post( '/', + requireAdmin, validateBody(createProjectSchema), projectController.createProject ); -// Update project +// Update project (admin only) router.patch( '/:projectId', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid() })), validateBody(updateProjectSchema), projectController.updateProject ); -// Delete project +// Delete project (admin only) router.delete( '/:projectId', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid() })), projectController.deleteProject ); @@ -55,6 +59,7 @@ router.get( router.post( '/:projectId/notes', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid() })), validateBody(z.object({ content: z.string().min(1), @@ -65,6 +70,7 @@ router.post( router.patch( '/:projectId/notes/:noteId', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid(), noteId: z.string().uuid() @@ -78,6 +84,7 @@ router.patch( router.delete( '/:projectId/notes/:noteId', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid(), noteId: z.string().uuid() @@ -94,6 +101,7 @@ router.get( router.post( '/:projectId/users', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid() })), validateBody(z.object({ userId: z.string().uuid('Neplatný formát user ID'), @@ -104,6 +112,7 @@ router.post( router.patch( '/:projectId/users/:userId', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid(), userId: z.string().uuid() @@ -116,6 +125,7 @@ router.patch( router.delete( '/:projectId/users/:userId', + requireAdmin, validateParams(z.object({ projectId: z.string().uuid(), userId: z.string().uuid() diff --git a/src/services/crm-email.service.js b/src/services/crm-email.service.js index 4b42324..dc3f0e2 100644 --- a/src/services/crm-email.service.js +++ b/src/services/crm-email.service.js @@ -65,7 +65,7 @@ export const getEmailThread = async (emailAccountId, threadId) => { */ export const searchEmails = async (emailAccountId, query) => { if (!query || query.trim().length < 2) { - throw new Error('Search term must be at least 2 characters'); + throw new Error('Vyhľadávací výraz musí mať aspoň 2 znaky'); } const searchPattern = `%${query}%`; diff --git a/src/services/jmap.service.js b/src/services/jmap.service.js index 570cba4..7b527df 100644 --- a/src/services/jmap.service.js +++ b/src/services/jmap.service.js @@ -371,7 +371,7 @@ export const syncEmailsFromSender = async ( if (!inboxMailbox) { logger.error('Inbox mailbox not found'); - throw new Error('Inbox mailbox not found'); + throw new Error('Priečinok Inbox nebol nájdený'); } logger.info(`Using mailboxes: Inbox (${inboxMailbox.id})${sentMailbox ? `, Sent (${sentMailbox.id})` : ''}`); @@ -572,7 +572,7 @@ export const markEmailAsRead = async (jmapConfig, userId, jmapId, isRead) => { if (!email) { // Update local DB even if JMAP fails await db.update(emails).set({ isRead }).where(eq(emails.jmapId, jmapId)); - throw new Error('Email not found in JMAP'); + throw new Error('Email nebol nájdený v JMAP'); } // Build new keywords @@ -637,7 +637,7 @@ export const sendEmail = async (jmapConfig, userId, emailAccountId, to, subject, const sentMailbox = mailboxes.find((m) => m.role === 'sent' || m.name === 'Sent'); if (!sentMailbox) { - throw new Error('Sent mailbox not found'); + throw new Error('Priečinok Odoslané nebol nájdený'); } // Create email draft @@ -675,7 +675,7 @@ export const sendEmail = async (jmapConfig, userId, emailAccountId, to, subject, const createdEmailId = createResponse.methodResponses[0][1].created?.draft?.id; if (!createdEmailId) { - throw new Error('Failed to create email draft'); + throw new Error('Nepodarilo sa vytvoriť koncept emailu'); } // Get user identity @@ -683,7 +683,7 @@ export const sendEmail = async (jmapConfig, userId, emailAccountId, to, subject, const identity = identities.find((i) => i.email === jmapConfig.username) || identities[0]; if (!identity) { - throw new Error('No identity found for sending email'); + throw new Error('Nenašla sa identita pre odosielanie emailov'); } // Submit the email @@ -706,7 +706,7 @@ export const sendEmail = async (jmapConfig, userId, emailAccountId, to, subject, const submissionId = submitResponse.methodResponses[0][1].created?.submission?.id; if (!submissionId) { - throw new Error('Failed to submit email'); + throw new Error('Nepodarilo sa odoslať email'); } logger.success(`Email sent successfully to ${to}`);