-
Notifications
You must be signed in to change notification settings - Fork 0
BSL-39-AdminEventsAPI #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,28 +1,75 @@ | ||
| import { NextResponse } from "next/server"; | ||
| import { prisma } from "@/lib/prisma"; | ||
| import { auth } from "@/auth"; | ||
|
|
||
| function isAmbassadorOrHigher(role: string) { | ||
| return role === "AMBASSADOR" || role === "SUPER_ADMIN"; | ||
| } | ||
|
Comment on lines
+5
to
+7
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can remove this and replace with |
||
|
|
||
| async function requireAmbassadorOrHigher() { | ||
| const session = await auth(); | ||
| const email = session?.user?.email; | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The rols is already in the session token set by auth.ts so you do not need to query the DB for it on every request. Can use session?.user?.role directly and only query the DB for the user id (which is needed for createdByUserID in POST) |
||
| if (!email) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make this |
||
| return { ok: false as const, status: 401 as const, error: "Unauthorized" }; | ||
| } | ||
|
|
||
| const user = await prisma.user.findUnique({ | ||
| where: { email }, | ||
| select: { id: true, role: true }, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can remove |
||
| }); | ||
|
|
||
| if (!user) { | ||
| return { ok: false as const, status: 401 as const, error: "Unauthorized" }; | ||
| } | ||
|
|
||
| if (!isAmbassadorOrHigher(user.role)) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replace this with
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So delete the
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also move this |
||
| return { ok: false as const, status: 403 as const, error: "Forbidden" }; | ||
| } | ||
|
|
||
| return { ok: true as const, user }; | ||
| } | ||
|
|
||
| // GET /api/admin/events (admin list) | ||
| export async function GET() { | ||
| // TODO: require admin (RBAC) | ||
| const gate = await requireAmbassadorOrHigher(); | ||
| if (!gate.ok) { | ||
| return NextResponse.json({ error: gate.error }, { status: gate.status }); | ||
| } | ||
|
|
||
| const events = await prisma.event.findMany({ | ||
| orderBy: { startAt: "asc" }, | ||
| }); | ||
|
|
||
| return NextResponse.json(events); | ||
| } | ||
|
Comment on lines
40
to
45
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add try/catch here.. it would look something like this: (Also have to do it for POST below.. ill leave comment) |
||
|
|
||
| // POST /api/admin/events (create) | ||
| export async function POST(req: Request) { | ||
| // TODO: require admin (RBAC) | ||
| const gate = await requireAmbassadorOrHigher(); | ||
| if (!gate.ok) { | ||
| return NextResponse.json({ error: gate.error }, { status: gate.status }); | ||
| } | ||
|
|
||
| const body = await req.json(); | ||
|
|
||
| if (!body.title || !body.startAt || !body.createdByUserId) { | ||
|
|
||
| if (!body.title || !body.startAt) { | ||
| return NextResponse.json( | ||
| { error: "title, startAt, createdByUserId are required" }, | ||
| { error: "title and startAt are required" }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
|
|
||
| const startAt = new Date(body.startAt); | ||
| const endAt = body.endAt ? new Date(body.endAt) : null; | ||
|
|
||
| if (isNaN(startAt.getTime())) { | ||
| return NextResponse.json({ error: "Invalid startAt" }, { status: 400 }); | ||
| } | ||
| if (endAt && isNaN(endAt.getTime())) { | ||
| return NextResponse.json({ error: "Invalid endAt" }, { status: 400 }); | ||
| } | ||
| if (endAt && endAt < startAt) { | ||
| return NextResponse.json( | ||
| { error: "endAt cannot be before startAt" }, | ||
|
|
@@ -38,7 +85,7 @@ export async function POST(req: Request) { | |
| endAt, | ||
| location: body.location ?? null, | ||
| link: body.link ?? null, | ||
| createdByUserId: body.createdByUserId, // later: get from session | ||
| createdByUserId: gate.user.id, // imported from db | ||
| }, | ||
| }); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import { hasRole } from "@/lib/rbac";this logic already exists in
lib/rbac.ts, you can use thehasRolefunction