Updated to using managed types instead of
hard coded ones.
This commit is contained in:
122
app/api/admin/update-user-scope/route.ts
Normal file
122
app/api/admin/update-user-scope/route.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { type NextRequest, NextResponse } from "next/server"
|
||||
import { safeQuery } from "@/lib/database"
|
||||
|
||||
const hasManagedType = async (type: "field" | "department" | "team", name: string) => {
|
||||
const rows = (await safeQuery("SELECT 1 FROM managed_types WHERE type = ? AND name = ? LIMIT 1", [
|
||||
type,
|
||||
name,
|
||||
])) as any[]
|
||||
if (rows.length > 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
const legacyRows = (await safeQuery(`SELECT 1 FROM users WHERE ${type} = ? LIMIT 1`, [name])) as any[]
|
||||
return legacyRows.length > 0
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const { adminId, targetUserId, field, department, team } = await request.json()
|
||||
|
||||
if (!adminId || !targetUserId || !field || !department || !team) {
|
||||
return NextResponse.json({ error: "Missing required fields." }, { status: 400 })
|
||||
}
|
||||
|
||||
const adminRows = (await safeQuery("SELECT role, field, department, team FROM users WHERE national_id = ?", [
|
||||
adminId,
|
||||
])) as any[]
|
||||
if (adminRows.length === 0) {
|
||||
return NextResponse.json({ error: "Admin not found." }, { status: 404 })
|
||||
}
|
||||
|
||||
const admin = adminRows[0]
|
||||
|
||||
const userRows = (await safeQuery("SELECT national_id, field, department, team FROM users WHERE national_id = ?", [
|
||||
targetUserId,
|
||||
])) as any[]
|
||||
if (userRows.length === 0) {
|
||||
return NextResponse.json({ error: "User not found." }, { status: 404 })
|
||||
}
|
||||
const targetUser = userRows[0]
|
||||
|
||||
const [fieldOk, departmentOk, teamOk] = await Promise.all([
|
||||
hasManagedType("field", field),
|
||||
hasManagedType("department", department),
|
||||
hasManagedType("team", team),
|
||||
])
|
||||
|
||||
if (!fieldOk || !departmentOk || !teamOk) {
|
||||
return NextResponse.json({ error: "Invalid field, department, or team." }, { status: 400 })
|
||||
}
|
||||
|
||||
const fieldRows = (await safeQuery("SELECT id FROM managed_types WHERE type = 'field' AND name = ?", [
|
||||
field,
|
||||
])) as Array<{ id: number }>
|
||||
const departmentRows = (await safeQuery(
|
||||
"SELECT id, parent_id AS parentId FROM managed_types WHERE type = 'department' AND name = ?",
|
||||
[department],
|
||||
)) as Array<{ id: number; parentId: number | null }>
|
||||
const teamRows = (await safeQuery(
|
||||
"SELECT id, parent_id AS parentId FROM managed_types WHERE type = 'team' AND name = ?",
|
||||
[team],
|
||||
)) as Array<{ id: number; parentId: number | null }>
|
||||
|
||||
if (fieldRows.length === 0 || departmentRows.length === 0 || teamRows.length === 0) {
|
||||
return NextResponse.json({ error: "Invalid field, department, or team." }, { status: 400 })
|
||||
}
|
||||
|
||||
if (departmentRows[0].parentId !== fieldRows[0].id) {
|
||||
return NextResponse.json({ error: "Department does not belong to field." }, { status: 400 })
|
||||
}
|
||||
|
||||
if (teamRows[0].parentId !== departmentRows[0].id) {
|
||||
return NextResponse.json({ error: "Team does not belong to department." }, { status: 400 })
|
||||
}
|
||||
|
||||
if (admin.role === "field_admin") {
|
||||
if (targetUser.field !== admin.field) {
|
||||
return NextResponse.json({ error: "Target user is outside your field." }, { status: 403 })
|
||||
}
|
||||
if (field !== admin.field) {
|
||||
return NextResponse.json({ error: "Field admins can only assign within their field." }, { status: 403 })
|
||||
}
|
||||
} else if (admin.role === "department_admin") {
|
||||
if (targetUser.department !== admin.department) {
|
||||
return NextResponse.json({ error: "Target user is outside your department." }, { status: 403 })
|
||||
}
|
||||
if (department !== admin.department) {
|
||||
return NextResponse.json({ error: "Department admins can only assign within their department." }, { status: 403 })
|
||||
}
|
||||
if (admin.field && field !== admin.field) {
|
||||
return NextResponse.json({ error: "Department admins can only assign within their field." }, { status: 403 })
|
||||
}
|
||||
} else if (admin.role === "team_admin") {
|
||||
if (targetUser.team !== admin.team) {
|
||||
return NextResponse.json({ error: "Target user is outside your team." }, { status: 403 })
|
||||
}
|
||||
if (team !== admin.team) {
|
||||
return NextResponse.json({ error: "Team admins can only assign within their team." }, { status: 403 })
|
||||
}
|
||||
if (admin.department && department !== admin.department) {
|
||||
return NextResponse.json({ error: "Team admins can only assign within their department." }, { status: 403 })
|
||||
}
|
||||
if (admin.field && field !== admin.field) {
|
||||
return NextResponse.json({ error: "Team admins can only assign within their field." }, { status: 403 })
|
||||
}
|
||||
} else if (admin.role !== "global_admin") {
|
||||
return NextResponse.json({ error: "Insufficient permissions." }, { status: 403 })
|
||||
}
|
||||
|
||||
await safeQuery("UPDATE users SET field = ?, department = ?, team = ? WHERE national_id = ?", [
|
||||
field,
|
||||
department,
|
||||
team,
|
||||
targetUserId,
|
||||
])
|
||||
|
||||
return NextResponse.json({ success: true, message: "User assignment updated." })
|
||||
} catch (error) {
|
||||
console.error("Update user scope error:", error)
|
||||
return NextResponse.json({ error: "Failed to update user." }, { status: 500 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user