diff --git a/.replit b/.replit index ebeaf96..03709f0 100644 --- a/.replit +++ b/.replit @@ -18,10 +18,6 @@ externalPort = 80 localPort = 33035 externalPort = 3001 -[[ports]] -localPort = 38973 -externalPort = 3002 - [[ports]] localPort = 41343 externalPort = 3000 diff --git a/server/routes.ts b/server/routes.ts index 6bb1a6f..683d24d 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -24,8 +24,16 @@ export async function registerRoutes(app: Express): Promise { }); // ============= USER MANAGEMENT ROUTES ============= - app.get("/api/users", isAuthenticated, async (req, res) => { + app.get("/api/users", isAuthenticated, async (req: any, res) => { try { + const currentUserId = req.user.claims.sub; + const currentUser = await storage.getUser(currentUserId); + + // Only admins can view all users + if (currentUser?.role !== "admin") { + return res.status(403).json({ message: "Forbidden: Admin access required" }); + } + const allUsers = await storage.getAllUsers(); res.json(allUsers); } catch (error) { @@ -34,8 +42,21 @@ export async function registerRoutes(app: Express): Promise { } }); - app.patch("/api/users/:id", isAuthenticated, async (req, res) => { + app.patch("/api/users/:id", isAuthenticated, async (req: any, res) => { try { + const currentUserId = req.user.claims.sub; + const currentUser = await storage.getUser(currentUserId); + + // Only admins can update user roles + if (currentUser?.role !== "admin") { + return res.status(403).json({ message: "Forbidden: Admin access required" }); + } + + // Prevent admins from changing their own role + if (req.params.id === currentUserId) { + return res.status(403).json({ message: "Cannot change your own role" }); + } + const { role } = req.body; if (!role || !["admin", "coordinator", "guard", "client"].includes(role)) { return res.status(400).json({ message: "Invalid role" }); diff --git a/server/storage.ts b/server/storage.ts index 1a15a9d..7cfde7b 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -74,18 +74,32 @@ export class DatabaseStorage implements IStorage { } async upsertUser(userData: UpsertUser): Promise { - const [user] = await db - .insert(users) - .values(userData) - .onConflictDoUpdate({ - target: users.id, - set: { + // Check if user already exists by email (unique constraint) + const existingUser = await db + .select() + .from(users) + .where(eq(users.email, userData.email || '')) + .limit(1); + + if (existingUser.length > 0) { + // Update existing user + const [updated] = await db + .update(users) + .set({ ...userData, updatedAt: new Date(), - }, - }) - .returning(); - return user; + }) + .where(eq(users.email, userData.email || '')) + .returning(); + return updated; + } else { + // Insert new user + const [user] = await db + .insert(users) + .values(userData) + .returning(); + return user; + } } async getAllUsers(): Promise {