2025-12-11 10:40:55 +01:00
|
|
|
/*
|
2026-01-12 15:00:36 +01:00
|
|
|
* Copyright (c) 2026 by Christian Kellner.
|
2025-12-11 10:40:55 +01:00
|
|
|
* Licensed under Apache-2.0 with Commons Clause and Attribution/Naming Clause
|
|
|
|
|
*/
|
|
|
|
|
|
2023-03-13 13:42:43 +01:00
|
|
|
import * as userStorage from '../../services/storage/userStorage.js';
|
|
|
|
|
import * as jobStorage from '../../services/storage/jobStorage.js';
|
2025-12-09 13:56:46 +01:00
|
|
|
import { getSettings } from '../../services/storage/settingsStorage.js';
|
2026-04-27 15:58:41 +02:00
|
|
|
import { isAdmin as isAdminUser } from '../security.js';
|
2026-04-27 16:56:04 +02:00
|
|
|
|
2021-01-21 16:09:23 +01:00
|
|
|
function checkIfAnyAdminAfterRemovingUser(userIdToBeRemoved, allUser) {
|
|
|
|
|
return allUser.filter((user) => user.id !== userIdToBeRemoved && user.isAdmin).length > 0;
|
|
|
|
|
}
|
2026-04-27 16:56:04 +02:00
|
|
|
|
|
|
|
|
function checkIfUserToBeRemovedIsLoggedIn(userIdToBeRemoved, request) {
|
|
|
|
|
return request.session.currentUser === userIdToBeRemoved;
|
2021-01-21 16:09:23 +01:00
|
|
|
}
|
2026-04-27 16:56:04 +02:00
|
|
|
|
2021-01-21 16:09:23 +01:00
|
|
|
const nullOrEmpty = (str) => str == null || str.length === 0;
|
2025-10-07 21:06:59 +02:00
|
|
|
|
2026-04-27 16:56:04 +02:00
|
|
|
/**
|
|
|
|
|
* @param {import('fastify').FastifyInstance} fastify
|
|
|
|
|
*/
|
|
|
|
|
export default async function userPlugin(fastify) {
|
|
|
|
|
fastify.get('/', async () => {
|
|
|
|
|
return userStorage.getUsers(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
fastify.get('/:userId', async (request) => {
|
|
|
|
|
const { userId } = request.params;
|
|
|
|
|
return userStorage.getUser(userId);
|
|
|
|
|
});
|
2025-10-07 21:06:59 +02:00
|
|
|
|
2026-04-27 16:56:04 +02:00
|
|
|
fastify.delete('/', async (request, reply) => {
|
|
|
|
|
const settings = await getSettings();
|
|
|
|
|
if (settings.demoMode && !isAdminUser(request)) {
|
|
|
|
|
return reply.code(403).send({ error: 'In demo mode, it is not allowed to remove user.' });
|
|
|
|
|
}
|
2024-11-22 09:11:10 +01:00
|
|
|
|
2026-04-27 16:56:04 +02:00
|
|
|
const { userId } = request.body;
|
|
|
|
|
const allUser = userStorage.getUsers(false);
|
|
|
|
|
if (!checkIfAnyAdminAfterRemovingUser(userId, allUser)) {
|
|
|
|
|
return reply.code(400).send({ error: 'You are trying to remove the last admin user. This is prohibited.' });
|
|
|
|
|
}
|
|
|
|
|
if (checkIfUserToBeRemovedIsLoggedIn(userId, request)) {
|
|
|
|
|
return reply.code(400).send({ error: 'You are trying to remove yourself. This is prohibited.' });
|
|
|
|
|
}
|
|
|
|
|
jobStorage.removeJobsByUserId(userId);
|
|
|
|
|
userStorage.removeUser(userId);
|
|
|
|
|
return reply.send();
|
|
|
|
|
});
|
2024-11-22 09:11:10 +01:00
|
|
|
|
2026-04-27 16:56:04 +02:00
|
|
|
fastify.post('/', async (request, reply) => {
|
|
|
|
|
const settings = await getSettings();
|
|
|
|
|
if (settings.demoMode && !isAdminUser(request)) {
|
|
|
|
|
return reply.code(403).send({ error: 'In demo mode, it is not allowed to change or add user.' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { username, password, password2, isAdmin, userId } = request.body;
|
|
|
|
|
if (password !== password2) {
|
2026-05-02 20:00:11 +02:00
|
|
|
return reply.code(400).send({ error: 'Passwords do not match.' });
|
2026-04-27 16:56:04 +02:00
|
|
|
}
|
|
|
|
|
if (nullOrEmpty(username) || nullOrEmpty(password) || nullOrEmpty(password2)) {
|
|
|
|
|
return reply.code(400).send({ error: 'Username and password are mandatory.' });
|
|
|
|
|
}
|
|
|
|
|
const allUser = userStorage.getUsers(false);
|
|
|
|
|
if (!isAdmin && !checkIfAnyAdminAfterRemovingUser(userId, allUser)) {
|
|
|
|
|
return reply.code(400).send({
|
|
|
|
|
error: 'You cannot change the admin flag for this user as otherwise, there is no other user in the system',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
userStorage.upsertUser({ userId, username, password, isAdmin });
|
|
|
|
|
return reply.send();
|
2021-01-21 16:09:23 +01:00
|
|
|
});
|
2026-04-27 16:56:04 +02:00
|
|
|
}
|