Restrict user management operations to administrators
Enhance user management routes (`/api/users`) to enforce admin-only access for viewing and patching user data, and modify `upsertUser` in `DatabaseStorage` to handle existing users by email. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 99f0fce6-9386-489a-9632-1d81223cab44 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/6d543d2c-20b9-4ea6-93fe-70fe9b1d9f80/99f0fce6-9386-489a-9632-1d81223cab44/TRdpk3a
This commit is contained in:
parent
4443773040
commit
0332eb5481
4
.replit
4
.replit
@ -18,10 +18,6 @@ externalPort = 80
|
||||
localPort = 33035
|
||||
externalPort = 3001
|
||||
|
||||
[[ports]]
|
||||
localPort = 38973
|
||||
externalPort = 3002
|
||||
|
||||
[[ports]]
|
||||
localPort = 41343
|
||||
externalPort = 3000
|
||||
|
||||
@ -24,8 +24,16 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
});
|
||||
|
||||
// ============= 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<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
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" });
|
||||
|
||||
@ -74,19 +74,33 @@ export class DatabaseStorage implements IStorage {
|
||||
}
|
||||
|
||||
async upsertUser(userData: UpsertUser): Promise<User> {
|
||||
// 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(),
|
||||
})
|
||||
.where(eq(users.email, userData.email || ''))
|
||||
.returning();
|
||||
return updated;
|
||||
} else {
|
||||
// Insert new user
|
||||
const [user] = await db
|
||||
.insert(users)
|
||||
.values(userData)
|
||||
.onConflictDoUpdate({
|
||||
target: users.id,
|
||||
set: {
|
||||
...userData,
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
})
|
||||
.returning();
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
async getAllUsers(): Promise<User[]> {
|
||||
return await db.select().from(users).orderBy(desc(users.createdAt));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user