harden admin api authorization and add authz regression tests
This commit is contained in:
1 parent
272c9b36dd
commit
10b58245f5
28 files changed
+1336
-240
No files matched your search
@@ -38,17 +38,110 @@ export async function GET(request: NextRequest) {
|
||||
const trainerId = searchParams.get("trainerId");
|
||||
const clientId = searchParams.get("clientId");
|
||||
|
||||
let assignments;
|
||||
if (trainerId && clientId) {
|
||||
const [trainer, client] = await Promise.all([
|
||||
db.getUserById(trainerId),
|
||||
db.getUserById(clientId),
|
||||
]);
|
||||
|
||||
if (trainerId) {
|
||||
assignments = await db.getTrainerClientAssignments(trainerId);
|
||||
// Filter by clientId if provided
|
||||
if (clientId) {
|
||||
assignments = assignments.filter((a) => a.clientId === clientId);
|
||||
if (!trainer || !client) {
|
||||
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||
}
|
||||
} else {
|
||||
// Get all assignments (for admins, filtered by gym)
|
||||
assignments = await db.getAllTrainerClientAssignments();
|
||||
|
||||
if (
|
||||
currentUser.role !== "superAdmin" &&
|
||||
(!currentUser.gymId ||
|
||||
trainer.gymId !== currentUser.gymId ||
|
||||
client.gymId !== currentUser.gymId)
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Cannot access assignments from other gyms" },
|
||||
{ status: 403 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (trainerId && !clientId) {
|
||||
const trainer = await db.getUserById(trainerId);
|
||||
if (!trainer) {
|
||||
return NextResponse.json(
|
||||
{ error: "Trainer not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
currentUser.role !== "superAdmin" &&
|
||||
(!currentUser.gymId || trainer.gymId !== currentUser.gymId)
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Cannot access assignments from other gyms" },
|
||||
{ status: 403 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!trainerId && clientId) {
|
||||
const client = await db.getUserById(clientId);
|
||||
if (!client) {
|
||||
return NextResponse.json(
|
||||
{ error: "Client not found" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
currentUser.role !== "superAdmin" &&
|
||||
(!currentUser.gymId || client.gymId !== currentUser.gymId)
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Cannot access assignments from other gyms" },
|
||||
{ status: 403 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let assignments = trainerId
|
||||
? await db.getTrainerClientAssignments(trainerId)
|
||||
: await db.getAllTrainerClientAssignments();
|
||||
|
||||
if (clientId) {
|
||||
assignments = assignments.filter((a) => a.clientId === clientId);
|
||||
}
|
||||
|
||||
if (currentUser.role !== "superAdmin") {
|
||||
if (!currentUser.gymId) {
|
||||
return NextResponse.json({ error: "No gym assigned" }, { status: 403 });
|
||||
}
|
||||
|
||||
const involvedUserIds = Array.from(
|
||||
new Set(
|
||||
assignments.flatMap((assignment) => [
|
||||
assignment.trainerId,
|
||||
assignment.clientId,
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
||||
const users = await Promise.all(
|
||||
involvedUserIds.map((userId) => db.getUserById(userId)),
|
||||
);
|
||||
|
||||
const gymByUserId = new Map(
|
||||
users
|
||||
.filter((user): user is NonNullable<typeof user> => !!user)
|
||||
.map((user) => [user.id, user.gymId]),
|
||||
);
|
||||
|
||||
assignments = assignments.filter((assignment) => {
|
||||
const trainerGymId = gymByUserId.get(assignment.trainerId);
|
||||
const clientGymId = gymByUserId.get(assignment.clientId);
|
||||
|
||||
return (
|
||||
trainerGymId === currentUser.gymId &&
|
||||
clientGymId === currentUser.gymId
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json({ assignments });
|
||||
@@ -121,6 +214,18 @@ export async function POST(request: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
currentUser.role !== "superAdmin" &&
|
||||
(!currentUser.gymId ||
|
||||
trainer.gymId !== currentUser.gymId ||
|
||||
client.gymId !== currentUser.gymId)
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Cannot assign users from other gyms" },
|
||||
{ status: 403 },
|
||||
);
|
||||
}
|
||||
|
||||
// Check if assignment already exists
|
||||
const existingAssignments = await db.getTrainerClientAssignments(trainerId);
|
||||
const existingAssignment = existingAssignments.find(
|
||||
|
||||
Reference in new issue
Block a user