mirror of
https://github.com/hex248/sprint.git
synced 2026-02-09 02:33:02 +00:00
backend routes with zod schemas
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { OrgUpdateMemberRoleRequestSchema } from "@issue/shared";
|
||||
import type { AuthedRequest } from "../../auth/middleware";
|
||||
import {
|
||||
getOrganisationById,
|
||||
@@ -5,56 +6,43 @@ import {
|
||||
getUserById,
|
||||
updateOrganisationMemberRole,
|
||||
} from "../../db/queries";
|
||||
import { errorResponse, parseJsonBody } from "../../validation";
|
||||
|
||||
// /organisation/update-member-role?organisationId=1&userId=2&role=admin
|
||||
export default async function organisationUpdateMemberRole(req: AuthedRequest) {
|
||||
const url = new URL(req.url);
|
||||
const organisationId = url.searchParams.get("organisationId");
|
||||
const userId = url.searchParams.get("userId");
|
||||
const role = url.searchParams.get("role");
|
||||
if (!role || !["admin", "member"].includes(role)) {
|
||||
return new Response("Invalid role: must be either 'admin' or 'member'", { status: 400 });
|
||||
const parsed = await parseJsonBody(req, OrgUpdateMemberRoleRequestSchema);
|
||||
if ("error" in parsed) return parsed.error;
|
||||
|
||||
const { organisationId, userId, role } = parsed.data;
|
||||
|
||||
const organisation = await getOrganisationById(organisationId);
|
||||
if (!organisation) {
|
||||
return errorResponse(`organisation with id ${organisationId} not found`, "ORG_NOT_FOUND", 404);
|
||||
}
|
||||
|
||||
if (!organisationId || !userId || !role) {
|
||||
return new Response(
|
||||
`missing parameters: ${!organisationId ? "organisationId " : ""}${!userId ? "userId " : ""}${!role ? "role" : ""}`,
|
||||
{ status: 400 },
|
||||
const user = await getUserById(userId);
|
||||
if (!user) {
|
||||
return errorResponse(`user with id ${userId} not found`, "USER_NOT_FOUND", 404);
|
||||
}
|
||||
|
||||
const requesterMember = await getOrganisationMemberRole(organisationId, req.userId);
|
||||
if (!requesterMember) {
|
||||
return errorResponse("you are not a member of this organisation", "NOT_MEMBER", 403);
|
||||
}
|
||||
|
||||
let member = await getOrganisationMemberRole(organisationId, userId);
|
||||
if (!member) {
|
||||
return errorResponse(
|
||||
`user with id ${userId} is not a member of this organisation`,
|
||||
"NOT_MEMBER",
|
||||
404,
|
||||
);
|
||||
}
|
||||
|
||||
const orgIdNumber = Number(organisationId);
|
||||
const userIdNumber = Number(userId);
|
||||
|
||||
if (!Number.isInteger(orgIdNumber) || !Number.isInteger(userIdNumber)) {
|
||||
return new Response("organisationId and userId must be integers", { status: 400 });
|
||||
}
|
||||
|
||||
const organisation = await getOrganisationById(orgIdNumber);
|
||||
if (!organisation) {
|
||||
return new Response(`organisation with id ${organisationId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const user = await getUserById(userIdNumber);
|
||||
if (!user) {
|
||||
return new Response(`user with id ${userId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const requesterMember = await getOrganisationMemberRole(orgIdNumber, req.userId);
|
||||
if (!requesterMember) {
|
||||
return new Response("You are not a member of this organisation", { status: 403 });
|
||||
}
|
||||
|
||||
let member = await getOrganisationMemberRole(orgIdNumber, userIdNumber);
|
||||
if (!member) {
|
||||
return new Response(`User with id ${userId} is not a member of this organisation`, { status: 404 });
|
||||
}
|
||||
|
||||
if (requesterMember.role !== "owner" && requesterMember.role !== "admin") {
|
||||
return new Response("Only owners and admins can update member roles", { status: 403 });
|
||||
return errorResponse("only owners and admins can update member roles", "PERMISSION_DENIED", 403);
|
||||
}
|
||||
|
||||
member = await updateOrganisationMemberRole(orgIdNumber, userIdNumber, role);
|
||||
member = await updateOrganisationMemberRole(organisationId, userId, role);
|
||||
|
||||
return Response.json(member);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user