From 88d4a5f5d52f40ee13cf2be9a995415f484cc922 Mon Sep 17 00:00:00 2001 From: Fovway Date: Sun, 26 Oct 2025 15:01:50 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D0=B0=D1=8F=20mid?= =?UTF-8?q?dleware=20=D0=B4=D0=BB=D1=8F=20=D0=B0=D1=83=D1=82=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Реализована функция `requireApiAuth`, которая проверяет аутентификацию пользователя и возвращает JSON-ответ в случае неаутентифицированного доступа. - Обновлены маршруты API для использования новой middleware вместо старой `requireAuth`, улучшая обработку аутентификации для всех API-запросов. --- server.js | 157 ++++++++++-------------------------------------------- 1 file changed, 29 insertions(+), 128 deletions(-) diff --git a/server.js b/server.js index b085067..882551b 100644 --- a/server.js +++ b/server.js @@ -530,6 +530,15 @@ function requireAuth(req, res, next) { } } +// Middleware для аутентификации API (возвращает JSON вместо редиректа) +function requireApiAuth(req, res, next) { + if (req.session.authenticated) { + return next(); + } else { + return res.status(401).json({ error: "Не аутентифицирован" }); + } +} + // Маршруты // Главная страница с формой входа @@ -680,7 +689,7 @@ app.get("/api/auth/status", (req, res) => { }); // API для получения информации о пользователе -app.get("/api/user", requireAuth, (req, res) => { +app.get("/api/user", requireApiAuth, (req, res) => { if (!req.session.userId) { return res.status(401).json({ error: "Не аутентифицирован" }); } @@ -740,7 +749,7 @@ app.get("/notes", requireAuth, (req, res) => { }); // API для поиска заметок с изображениями (должен быть ПЕРЕД /api/notes/:id) -app.get("/api/notes/search", requireAuth, (req, res) => { +app.get("/api/notes/search", requireApiAuth, (req, res) => { const { q, tag, date } = req.query; let whereClause = "WHERE n.user_id = ?"; @@ -805,7 +814,7 @@ app.get("/api/notes/search", requireAuth, (req, res) => { }); // API для получения всех заметок с изображениями (исключая архивные) -app.get("/api/notes", requireAuth, (req, res) => { +app.get("/api/notes", requireApiAuth, (req, res) => { const sql = ` SELECT n.*, @@ -847,7 +856,7 @@ app.get("/api/notes", requireAuth, (req, res) => { }); // API для создания новой заметки -app.post("/api/notes", requireAuth, (req, res) => { +app.post("/api/notes", requireApiAuth, (req, res) => { const { content, date, time } = req.body; if (!content || !date || !time) { @@ -879,7 +888,7 @@ app.post("/api/notes", requireAuth, (req, res) => { }); // API для обновления заметки -app.put("/api/notes/:id", requireAuth, (req, res) => { +app.put("/api/notes/:id", requireApiAuth, (req, res) => { const { content } = req.body; const { id } = req.params; @@ -931,7 +940,7 @@ app.put("/api/notes/:id", requireAuth, (req, res) => { }); // API для удаления заметки -app.delete("/api/notes/:id", requireAuth, (req, res) => { +app.delete("/api/notes/:id", requireApiAuth, (req, res) => { const { id } = req.params; // Проверяем, что заметка принадлежит текущему пользователю @@ -1087,7 +1096,7 @@ app.post( ); // API для получения изображений заметки -app.get("/api/notes/:id/images", requireAuth, (req, res) => { +app.get("/api/notes/:id/images", requireApiAuth, (req, res) => { const { id } = req.params; // Проверяем, что заметка принадлежит текущему пользователю @@ -1126,7 +1135,7 @@ app.get("/api/notes/:id/images", requireAuth, (req, res) => { }); // API для удаления изображения заметки -app.delete("/api/notes/:noteId/images/:imageId", requireAuth, (req, res) => { +app.delete("/api/notes/:noteId/images/:imageId", requireApiAuth, (req, res) => { const { noteId, imageId } = req.params; // Проверяем, что заметка принадлежит текущему пользователю @@ -1221,7 +1230,7 @@ app.get("/profile", requireAuth, (req, res) => { }); // API для обновления профиля -app.put("/api/user/profile", requireAuth, async (req, res) => { +app.put("/api/user/profile", requireApiAuth, async (req, res) => { const { username, email, currentPassword, newPassword, accent_color } = req.body; const userId = req.session.userId; @@ -1379,7 +1388,7 @@ app.post( ); // API для удаления аватарки -app.delete("/api/user/avatar", requireAuth, (req, res) => { +app.delete("/api/user/avatar", requireApiAuth, (req, res) => { const userId = req.session.userId; // Получаем текущую аватарку @@ -1414,7 +1423,7 @@ app.delete("/api/user/avatar", requireAuth, (req, res) => { }); // API для закрепления заметки -app.put("/api/notes/:id/pin", requireAuth, (req, res) => { +app.put("/api/notes/:id/pin", requireApiAuth, (req, res) => { const { id } = req.params; // Проверяем, что заметка принадлежит текущему пользователю @@ -1458,7 +1467,7 @@ app.put("/api/notes/:id/pin", requireAuth, (req, res) => { }); // API для архивирования заметки -app.put("/api/notes/:id/archive", requireAuth, (req, res) => { +app.put("/api/notes/:id/archive", requireApiAuth, (req, res) => { const { id } = req.params; // Проверяем, что заметка принадлежит текущему пользователю @@ -1501,7 +1510,7 @@ app.put("/api/notes/:id/archive", requireAuth, (req, res) => { }); // API для восстановления заметки из архива -app.put("/api/notes/:id/unarchive", requireAuth, (req, res) => { +app.put("/api/notes/:id/unarchive", requireApiAuth, (req, res) => { const { id } = req.params; // Проверяем, что заметка принадлежит текущему пользователю @@ -1543,7 +1552,7 @@ app.put("/api/notes/:id/unarchive", requireAuth, (req, res) => { }); // API для получения архивных заметок -app.get("/api/notes/archived", requireAuth, (req, res) => { +app.get("/api/notes/archived", requireApiAuth, (req, res) => { const sql = ` SELECT n.*, @@ -1585,7 +1594,7 @@ app.get("/api/notes/archived", requireAuth, (req, res) => { }); // API для окончательного удаления всех архивных заметок пользователя -app.delete("/api/notes/archived/all", requireAuth, async (req, res) => { +app.delete("/api/notes/archived/all", requireApiAuth, async (req, res) => { const { password } = req.body; if (!password) { @@ -1694,7 +1703,7 @@ app.delete("/api/notes/archived/all", requireAuth, async (req, res) => { }); // API для окончательного удаления архивной заметки -app.delete("/api/notes/archived/:id", requireAuth, (req, res) => { +app.delete("/api/notes/archived/:id", requireApiAuth, (req, res) => { const { id } = req.params; // Проверяем, что заметка принадлежит текущему пользователю и архивирована @@ -1762,116 +1771,8 @@ app.delete("/api/notes/archived/:id", requireAuth, (req, res) => { }); }); -// API для окончательного удаления всех архивных заметок пользователя -app.delete("/api/notes/archived/all", requireAuth, async (req, res) => { - const { password } = req.body; - - if (!password) { - return res.status(400).json({ error: "Пароль обязателен" }); - } - - try { - // Получаем хеш пароля пользователя - const userSql = "SELECT password FROM users WHERE id = ?"; - db.get(userSql, [req.session.userId], async (err, user) => { - if (err) { - console.error("Ошибка получения пользователя:", err.message); - return res.status(500).json({ error: "Ошибка сервера" }); - } - - if (!user) { - return res.status(404).json({ error: "Пользователь не найден" }); - } - - // Проверяем пароль - const validPassword = await bcrypt.compare(password, user.password); - if (!validPassword) { - return res.status(401).json({ error: "Неверный пароль" }); - } - - // Получаем все архивные заметки пользователя - const getNotesSql = - "SELECT id FROM notes WHERE user_id = ? AND is_archived = 1"; - db.all(getNotesSql, [req.session.userId], (err, notes) => { - if (err) { - console.error("Ошибка получения архивных заметок:", err.message); - return res.status(500).json({ error: "Ошибка сервера" }); - } - - if (notes.length === 0) { - return res.json({ - success: true, - message: "Архив уже пуст", - deletedCount: 0, - }); - } - - // Удаляем изображения для всех заметок - const noteIds = notes.map((note) => note.id); - const placeholders = noteIds.map(() => "?").join(","); - - const getImagesSql = `SELECT file_path FROM note_images WHERE note_id IN (${placeholders})`; - db.all(getImagesSql, noteIds, (err, images) => { - if (err) { - console.error("Ошибка получения изображений:", err.message); - } else { - // Удаляем файлы изображений - images.forEach((image) => { - const imagePath = path.join(__dirname, "public", image.file_path); - if (fs.existsSync(imagePath)) { - try { - fs.unlinkSync(imagePath); - } catch (err) { - console.error("Ошибка удаления файла изображения:", err); - } - } - }); - } - - // Удаляем записи об изображениях - const deleteImagesSql = `DELETE FROM note_images WHERE note_id IN (${placeholders})`; - db.run(deleteImagesSql, noteIds, (err) => { - if (err) { - console.error("Ошибка удаления изображений:", err.message); - } - - // Удаляем сами заметки - const deleteNotesSql = `DELETE FROM notes WHERE user_id = ? AND is_archived = 1`; - db.run(deleteNotesSql, [req.session.userId], function (err) { - if (err) { - console.error("Ошибка удаления заметок:", err.message); - return res.status(500).json({ error: "Ошибка сервера" }); - } - - const deletedCount = this.changes; - - // Логируем действие - const clientIP = getClientIP(req); - logAction( - req.session.userId, - "note_delete_permanent", - `Удалены все архивные заметки (${deletedCount} шт.)`, - clientIP - ); - - res.json({ - success: true, - message: `Удалено ${deletedCount} архивных заметок`, - deletedCount, - }); - }); - }); - }); - }); - }); - } catch (error) { - console.error("Ошибка при проверке пароля:", error); - res.status(500).json({ error: "Ошибка сервера" }); - } -}); - // API для получения логов пользователя -app.get("/api/logs", requireAuth, (req, res) => { +app.get("/api/logs", requireApiAuth, (req, res) => { const { action_type, limit = 100, offset = 0 } = req.query; let sql = ` @@ -1939,7 +1840,7 @@ app.get("/settings", requireAuth, (req, res) => { }); // API для получения AI настроек -app.get("/api/user/ai-settings", requireAuth, (req, res) => { +app.get("/api/user/ai-settings", requireApiAuth, (req, res) => { if (!req.session.userId) { return res.status(401).json({ error: "Не аутентифицирован" }); } @@ -1961,7 +1862,7 @@ app.get("/api/user/ai-settings", requireAuth, (req, res) => { }); // API для сохранения AI настроек -app.put("/api/user/ai-settings", requireAuth, (req, res) => { +app.put("/api/user/ai-settings", requireApiAuth, (req, res) => { const { openai_api_key, openai_base_url, openai_model } = req.body; const userId = req.session.userId; @@ -1990,7 +1891,7 @@ app.put("/api/user/ai-settings", requireAuth, (req, res) => { }); // API для улучшения текста через AI -app.post("/api/ai/improve", requireAuth, async (req, res) => { +app.post("/api/ai/improve", requireApiAuth, async (req, res) => { const { text } = req.body; if (!text) {