Fix admin authorization and harden chat requests
This commit is contained in:
+20
-12
@@ -2,6 +2,7 @@
|
||||
* @file Verarbeitet Benutzer- und Kontoeinstellungen sowie Export und Import des Arbeitsbereichs.
|
||||
*/
|
||||
import express from "express";
|
||||
import {asyncHandler} from "../middleware/asyncHandler.js";
|
||||
import bcrypt from "bcrypt";
|
||||
import {requireLogin} from "../middleware/auth.js";
|
||||
import {validateBody} from "../middleware/validate.js";
|
||||
@@ -29,7 +30,7 @@ const currentPasswordValidator = (body) => {
|
||||
return {value: {currentPassword}};
|
||||
};
|
||||
|
||||
const destroySession = (req) => new Promise((resolve) => req.session.destroy(() => resolve()));
|
||||
const destroySession = (req) => new Promise((resolve, reject) => req.session.destroy(error => error ? reject(error) : resolve()));
|
||||
|
||||
export function createSettingsRouter({repositories}) {
|
||||
const router = express.Router();
|
||||
@@ -38,10 +39,10 @@ export function createSettingsRouter({repositories}) {
|
||||
router.get("/settings/profile", (req, res) => {
|
||||
const user = repositories.getUser(req.session.user);
|
||||
if (!user) return res.status(404).json({error: "User not found"});
|
||||
return res.json({username: user.username});
|
||||
return res.json({username: user.username, role: user.role});
|
||||
});
|
||||
|
||||
router.put("/settings/username", validateBody(usernameValidator), async (req, res) => {
|
||||
router.put("/settings/username", validateBody(usernameValidator), asyncHandler(async (req, res) => {
|
||||
const currentUsername = req.session.user;
|
||||
const {username: nextUsername, password} = req.validatedBody;
|
||||
if (nextUsername === currentUsername) {
|
||||
@@ -53,15 +54,22 @@ export function createSettingsRouter({repositories}) {
|
||||
const valid = await bcrypt.compare(password, currentUser.password);
|
||||
if (!valid) return res.status(403).json({error: "Current password is incorrect"});
|
||||
if (repositories.getUser(nextUsername)) {
|
||||
return res.status(400).json({error: "Username already exists"});
|
||||
return res.status(409).json({error: "Username already exists", code: "USERNAME_TAKEN"});
|
||||
}
|
||||
|
||||
repositories.renameUser(currentUsername, nextUsername);
|
||||
try {
|
||||
repositories.renameUser(currentUsername, nextUsername);
|
||||
} catch (error) {
|
||||
if (["SQLITE_CONSTRAINT_PRIMARYKEY", "SQLITE_CONSTRAINT_UNIQUE"].includes(error.code)) {
|
||||
return res.status(409).json({error: "Username already exists", code: "USERNAME_TAKEN"});
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
req.session.user = nextUsername;
|
||||
return res.json({username: nextUsername});
|
||||
});
|
||||
}));
|
||||
|
||||
router.put("/settings/password", validateBody(passwordValidator), async (req, res) => {
|
||||
router.put("/settings/password", validateBody(passwordValidator), asyncHandler(async (req, res) => {
|
||||
const username = req.session.user;
|
||||
const {currentPassword, newPassword} = req.validatedBody;
|
||||
const user = repositories.getUser(username);
|
||||
@@ -73,11 +81,11 @@ export function createSettingsRouter({repositories}) {
|
||||
const updatedUser = repositories.incrementSessionVersion(username);
|
||||
req.session.sessionVersion = Number(updatedUser.session_version || 0);
|
||||
return res.json({message: "Password updated"});
|
||||
});
|
||||
}));
|
||||
|
||||
router.post("/settings/logout-all-sessions", (req, res) => {
|
||||
router.post("/settings/logout-all-sessions", (req, res, next) => {
|
||||
repositories.incrementSessionVersion(req.session.user);
|
||||
req.session.destroy(() => res.json({message: "All sessions logged out"}));
|
||||
req.session.destroy(error => error ? next(error) : res.json({message: "All sessions logged out"}));
|
||||
});
|
||||
|
||||
router.get("/settings/export", (req, res) => {
|
||||
@@ -92,7 +100,7 @@ export function createSettingsRouter({repositories}) {
|
||||
});
|
||||
});
|
||||
|
||||
router.delete("/settings/account", validateBody(currentPasswordValidator), async (req, res) => {
|
||||
router.delete("/settings/account", validateBody(currentPasswordValidator), asyncHandler(async (req, res) => {
|
||||
const username = req.session.user;
|
||||
const user = repositories.getUser(username);
|
||||
if (!user) return res.status(404).json({error: "User not found"});
|
||||
@@ -101,7 +109,7 @@ export function createSettingsRouter({repositories}) {
|
||||
repositories.deleteUser(username);
|
||||
await destroySession(req);
|
||||
return res.json({message: "Account deleted"});
|
||||
});
|
||||
}));
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user