added admin setup

This commit is contained in:
2025-10-09 00:09:20 +02:00
parent ceb7058d0b
commit 79b3658c5e
22 changed files with 1168 additions and 3353 deletions

View File

@@ -3,8 +3,8 @@ import { Request, Response } from 'express';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { v4 as uuidv4 } from 'uuid';
import { db } from '../services/databaseService';
import { AuthRequest } from '../middleware/auth';
import { db } from '../services/databaseService.js';
import { AuthRequest } from '../middleware/auth.js';
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d';

View File

@@ -0,0 +1,87 @@
// backend/src/controllers/setupController.ts
import { Request, Response } from 'express';
import bcrypt from 'bcryptjs';
import { v4 as uuidv4 } from 'uuid';
import { db } from '../services/databaseService.js';
export const checkSetupStatus = async (req: Request, res: Response): Promise<void> => {
try {
const adminExists = await db.get<{ count: number }>(
'SELECT COUNT(*) as count FROM users WHERE role = ?',
['admin']
);
res.json({
needsSetup: !adminExists || adminExists.count === 0
});
} catch (error) {
console.error('Error checking setup status:', error);
res.status(500).json({ error: 'Internal server error' });
}
};
export const setupAdmin = async (req: Request, res: Response): Promise<void> => {
try {
// Check if admin already exists
const adminExists = await db.get<{ count: number }>(
'SELECT COUNT(*) as count FROM users WHERE role = ?',
['admin']
);
if (adminExists && adminExists.count > 0) {
res.status(400).json({ error: 'Admin user already exists' });
return;
}
const { email, password, name, phone, department } = req.body;
// Validation
if (!email || !password || !name) {
res.status(400).json({ error: 'Email, password, and name are required' });
return;
}
// Email format validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
res.status(400).json({ error: 'Invalid email format' });
return;
}
// Password length validation
if (password.length < 6) {
res.status(400).json({ error: 'Password must be at least 6 characters long' });
return;
}
// Check if email already exists
const existingUser = await db.get<{ id: string }>(
'SELECT id FROM users WHERE email = ?',
[email]
);
if (existingUser) {
res.status(409).json({ error: 'Email already exists' });
return;
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 10);
const adminId = uuidv4();
// Create admin user
await db.run(
`INSERT INTO users (id, email, password, name, role, phone, department, is_active)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
[adminId, email, hashedPassword, name, 'admin', phone || null, department || null, true]
);
res.status(201).json({
message: 'Admin user created successfully',
userId: adminId
});
} catch (error) {
console.error('Error in setup:', error);
res.status(500).json({ error: 'Internal server error' });
}
};

View File

@@ -1,8 +1,8 @@
// backend/src/controllers/shiftPlanController.ts
import { Request, Response } from 'express';
import { v4 as uuidv4 } from 'uuid';
import { db } from '../services/databaseService';
import { AuthRequest } from '../middleware/auth';
import { db } from '../services/databaseService.js';
import { AuthRequest } from '../middleware/auth.js';
export interface ShiftPlan {
id: string;

View File

@@ -1,8 +1,8 @@
// backend/src/controllers/shiftTemplateController.ts
import { Request, Response } from 'express';
import { v4 as uuidv4 } from 'uuid';
import { db } from '../services/databaseService';
import { ShiftTemplate, CreateShiftTemplateRequest, UpdateShiftTemplateRequest } from '../models/ShiftTemplate';
import { db } from '../services/databaseService.js';
import { ShiftTemplate, CreateShiftTemplateRequest, UpdateShiftTemplateRequest } from '../models/ShiftTemplate.js';
export const getTemplates = async (req: Request, res: Response): Promise<void> => {
try {