Gitea-Repo fix
Dieser Commit ist enthalten in:
committet von
Server Deploy
Ursprung
c21be47428
Commit
623bbdf5dd
@ -31,8 +31,8 @@ router.get('/users', (req, res) => {
|
||||
try {
|
||||
const db = getDb();
|
||||
const users = db.prepare(`
|
||||
SELECT id, username, display_name, color, role, permissions, email,
|
||||
created_at, last_login, failed_attempts, locked_until
|
||||
SELECT id, email, initials, display_name, color, role, permissions,
|
||||
created_at, last_login, failed_attempts, locked_until, custom_initials
|
||||
FROM users
|
||||
ORDER BY id
|
||||
`).all();
|
||||
@ -55,10 +55,10 @@ router.get('/users', (req, res) => {
|
||||
*/
|
||||
router.post('/users', async (req, res) => {
|
||||
try {
|
||||
const { username, password, displayName, email, role, permissions } = req.body;
|
||||
const { initials, password, displayName, email, role, permissions } = req.body;
|
||||
|
||||
// Validierung
|
||||
if (!username || !password || !displayName || !email) {
|
||||
if (!initials || !password || !displayName || !email) {
|
||||
return res.status(400).json({ error: 'Kürzel, Passwort, Anzeigename und E-Mail erforderlich' });
|
||||
}
|
||||
|
||||
@ -69,8 +69,8 @@ router.post('/users', async (req, res) => {
|
||||
}
|
||||
|
||||
// Kürzel muss genau 2 Buchstaben sein
|
||||
const usernameUpper = username.toUpperCase();
|
||||
if (!/^[A-Z]{2}$/.test(usernameUpper)) {
|
||||
const initialsUpper = initials.toUpperCase();
|
||||
if (!/^[A-Z]{2}$/.test(initialsUpper)) {
|
||||
return res.status(400).json({ error: 'Kürzel muss genau 2 Buchstaben sein (z.B. HG)' });
|
||||
}
|
||||
|
||||
@ -80,18 +80,18 @@ router.post('/users', async (req, res) => {
|
||||
|
||||
const db = getDb();
|
||||
|
||||
// Prüfen ob Kürzel bereits existiert
|
||||
const existing = db.prepare('SELECT id FROM users WHERE username = ?').get(usernameUpper);
|
||||
if (existing) {
|
||||
return res.status(400).json({ error: 'Kürzel bereits vergeben' });
|
||||
}
|
||||
|
||||
// Prüfen ob E-Mail bereits existiert
|
||||
const existingEmail = db.prepare('SELECT id FROM users WHERE email = ?').get(email.toLowerCase());
|
||||
if (existingEmail) {
|
||||
return res.status(400).json({ error: 'E-Mail bereits vergeben' });
|
||||
}
|
||||
|
||||
// Prüfen ob Kürzel bereits existiert
|
||||
const existingInitials = db.prepare('SELECT id FROM users WHERE initials = ?').get(initialsUpper);
|
||||
if (existingInitials) {
|
||||
return res.status(400).json({ error: 'Kürzel bereits vergeben' });
|
||||
}
|
||||
|
||||
// Passwort hashen
|
||||
const passwordHash = await bcrypt.hash(password, 12);
|
||||
|
||||
@ -100,23 +100,24 @@ router.post('/users', async (req, res) => {
|
||||
|
||||
// Benutzer erstellen
|
||||
const result = db.prepare(`
|
||||
INSERT INTO users (username, password_hash, display_name, color, role, permissions, email)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
INSERT INTO users (email, initials, password_hash, display_name, color, role, permissions, custom_initials)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`).run(
|
||||
usernameUpper,
|
||||
email.toLowerCase(),
|
||||
initialsUpper,
|
||||
passwordHash,
|
||||
displayName,
|
||||
defaultColor,
|
||||
role || 'user',
|
||||
JSON.stringify(permissions || []),
|
||||
email.toLowerCase()
|
||||
initialsUpper
|
||||
);
|
||||
|
||||
logger.info(`Admin ${req.user.username} hat Benutzer ${usernameUpper} erstellt`);
|
||||
logger.info(`Admin ${req.user.email} hat Benutzer ${initialsUpper} erstellt`);
|
||||
|
||||
res.status(201).json({
|
||||
id: result.lastInsertRowid,
|
||||
username: usernameUpper,
|
||||
initials: initialsUpper,
|
||||
displayName,
|
||||
email: email.toLowerCase(),
|
||||
color: defaultColor,
|
||||
@ -135,7 +136,7 @@ router.post('/users', async (req, res) => {
|
||||
router.put('/users/:id', async (req, res) => {
|
||||
try {
|
||||
const userId = parseInt(req.params.id);
|
||||
const { displayName, color, role, permissions, password, unlockAccount, email } = req.body;
|
||||
const { displayName, color, role, permissions, password, unlockAccount, email, initials } = req.body;
|
||||
|
||||
const db = getDb();
|
||||
|
||||
@ -206,6 +207,24 @@ router.put('/users/:id', async (req, res) => {
|
||||
params.push(email.toLowerCase());
|
||||
}
|
||||
|
||||
if (initials !== undefined) {
|
||||
// Validierung: Genau 2 Buchstaben
|
||||
const initialsUpper = initials.toUpperCase();
|
||||
if (!/^[A-Z]{2}$/.test(initialsUpper)) {
|
||||
return res.status(400).json({ error: 'Kürzel muss genau 2 Buchstaben sein (z.B. HG)' });
|
||||
}
|
||||
// Prüfen ob Kürzel bereits von anderem Benutzer verwendet wird
|
||||
const existingInitials = db.prepare('SELECT id FROM users WHERE initials = ? AND id != ?').get(initialsUpper, userId);
|
||||
if (existingInitials) {
|
||||
return res.status(400).json({ error: 'Kürzel bereits vergeben' });
|
||||
}
|
||||
updates.push('initials = ?');
|
||||
params.push(initialsUpper);
|
||||
// Auch custom_initials aktualisieren für Kompatibilität
|
||||
updates.push('custom_initials = ?');
|
||||
params.push(initialsUpper);
|
||||
}
|
||||
|
||||
if (updates.length === 0) {
|
||||
return res.status(400).json({ error: 'Keine Änderungen angegeben' });
|
||||
}
|
||||
@ -218,7 +237,7 @@ router.put('/users/:id', async (req, res) => {
|
||||
// Aktualisierten Benutzer zurueckgeben
|
||||
const updatedUser = db.prepare(`
|
||||
SELECT id, username, display_name, color, role, permissions, email,
|
||||
created_at, last_login, failed_attempts, locked_until
|
||||
created_at, last_login, failed_attempts, locked_until, custom_initials
|
||||
FROM users WHERE id = ?
|
||||
`).get(userId);
|
||||
|
||||
|
||||
@ -35,10 +35,15 @@ router.post('/login', async (req, res) => {
|
||||
|
||||
const db = getDb();
|
||||
|
||||
// Benutzer suchen: Zuerst nach Username "admin", dann nach E-Mail
|
||||
// Benutzer suchen: Admin kann mit "admin" einloggen, alle anderen mit E-Mail
|
||||
let user;
|
||||
// User per Username suchen (kann E-Mail-Adresse oder admin sein)
|
||||
user = db.prepare('SELECT * FROM users WHERE username = ?').get(username);
|
||||
if (username.toLowerCase() === 'admin') {
|
||||
// Admin-Login über spezielle E-Mail
|
||||
user = db.prepare('SELECT * FROM users WHERE email = ? AND role = ?').get('admin@taskmate.local', 'admin');
|
||||
} else {
|
||||
// Normale User loggen sich mit E-Mail ein
|
||||
user = db.prepare('SELECT * FROM users WHERE email = ?').get(username);
|
||||
}
|
||||
|
||||
// Audit-Log Eintrag vorbereiten
|
||||
const logAttempt = (userId, success) => {
|
||||
@ -131,7 +136,8 @@ router.post('/login', async (req, res) => {
|
||||
csrfToken,
|
||||
user: {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
initials: user.initials,
|
||||
displayName: user.display_name,
|
||||
color: user.color,
|
||||
role: user.role || 'user',
|
||||
@ -345,14 +351,15 @@ router.get('/users', authenticateToken, (req, res) => {
|
||||
const db = getDb();
|
||||
// Nur regulaere Benutzer (nicht Admins) fuer Aufgaben-Zuweisung
|
||||
const users = db.prepare(`
|
||||
SELECT id, username, display_name, color
|
||||
SELECT id, email, initials, display_name, color
|
||||
FROM users
|
||||
WHERE role != 'admin' OR role IS NULL
|
||||
`).all();
|
||||
|
||||
res.json(users.map(u => ({
|
||||
id: u.id,
|
||||
username: u.username,
|
||||
email: u.email,
|
||||
initials: u.initials,
|
||||
displayName: u.display_name,
|
||||
color: u.color
|
||||
})));
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren