Skip to content

Commit 58ad0b6

Browse files
committed
feat(waitlist): add admin role verification and session middleware
1 parent d7098ed commit 58ad0b6

File tree

1 file changed

+92
-29
lines changed

1 file changed

+92
-29
lines changed

src/server.ts

Lines changed: 92 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { APIError, createAuthEndpoint } from "better-auth/api";
1+
import { APIError, createAuthEndpoint, sessionMiddleware } from "better-auth/api";
22
import type { BetterAuthPlugin, BetterAuthPluginDBSchema } from "better-auth";
33
import { z } from "zod";
44
import type { WaitlistPluginOptions, WaitlistStatus, WaitlistEntry, WaitlistStats } from "./types";
@@ -246,17 +246,26 @@ export const waitlist = (options: WaitlistPluginOptions = {}) => {
246246
"/waitlist/list",
247247
{
248248
method: "GET",
249+
use: [sessionMiddleware],
249250
query: z.object({
250251
status: z.enum(["pending", "approved", "rejected"]).optional(),
251252
limit: z.number().int().min(1).max(100).default(20),
252253
offset: z.number().int().min(0).default(0),
253254
}),
254255
},
255256
async (ctx) => {
256-
if (requireAdmin && !ctx.context.session) {
257-
throw new APIError("UNAUTHORIZED", {
258-
message: "Authentication required",
259-
});
257+
if (requireAdmin) {
258+
if (!ctx.context.session) {
259+
throw new APIError("UNAUTHORIZED", {
260+
message: "You must be signed in",
261+
});
262+
}
263+
const userRole = (ctx.context.session as any).user?.role;
264+
if (userRole !== "admin") {
265+
throw new APIError("FORBIDDEN", {
266+
message: "You must have admin privileges",
267+
});
268+
}
260269
}
261270

262271
const adapter = ctx.context.adapter;
@@ -288,12 +297,21 @@ export const waitlist = (options: WaitlistPluginOptions = {}) => {
288297
"/waitlist/stats",
289298
{
290299
method: "GET",
300+
use: [sessionMiddleware],
291301
},
292302
async (ctx) => {
293-
if (requireAdmin && !ctx.context.session) {
294-
throw new APIError("UNAUTHORIZED", {
295-
message: "Authentication required",
296-
});
303+
if (requireAdmin) {
304+
if (!ctx.context.session) {
305+
throw new APIError("UNAUTHORIZED", {
306+
message: "You must be signed in",
307+
});
308+
}
309+
const userRole = (ctx.context.session as any).user?.role;
310+
if (userRole !== "admin") {
311+
throw new APIError("FORBIDDEN", {
312+
message: "You must have admin privileges",
313+
});
314+
}
297315
}
298316

299317
const adapter = ctx.context.adapter;
@@ -318,16 +336,25 @@ export const waitlist = (options: WaitlistPluginOptions = {}) => {
318336
"/waitlist/approve",
319337
{
320338
method: "POST",
339+
use: [sessionMiddleware],
321340
body: z.object({
322341
email: z.string().email(),
323342
sendInvite: z.boolean().optional(),
324343
}),
325344
},
326345
async (ctx) => {
327-
if (requireAdmin && !ctx.context.session) {
328-
throw new APIError("UNAUTHORIZED", {
329-
message: "Authentication required",
330-
});
346+
if (requireAdmin) {
347+
if (!ctx.context.session) {
348+
throw new APIError("UNAUTHORIZED", {
349+
message: "You must be signed in",
350+
});
351+
}
352+
const userRole = (ctx.context.session as any).user?.role;
353+
if (userRole !== "admin") {
354+
throw new APIError("FORBIDDEN", {
355+
message: "You must have admin privileges",
356+
});
357+
}
331358
}
332359

333360
const email = ctx.body.email.toLowerCase().trim();
@@ -402,15 +429,24 @@ export const waitlist = (options: WaitlistPluginOptions = {}) => {
402429
"/waitlist/reject",
403430
{
404431
method: "POST",
432+
use: [sessionMiddleware],
405433
body: z.object({
406434
email: z.string().email(),
407435
}),
408436
},
409437
async (ctx) => {
410-
if (requireAdmin && !ctx.context.session) {
411-
throw new APIError("UNAUTHORIZED", {
412-
message: "Authentication required",
413-
});
438+
if (requireAdmin) {
439+
if (!ctx.context.session) {
440+
throw new APIError("UNAUTHORIZED", {
441+
message: "You must be signed in",
442+
});
443+
}
444+
const userRole = (ctx.context.session as any).user?.role;
445+
if (userRole !== "admin") {
446+
throw new APIError("FORBIDDEN", {
447+
message: "You must have admin privileges",
448+
});
449+
}
414450
}
415451

416452
const email = ctx.body.email.toLowerCase().trim();
@@ -479,15 +515,24 @@ export const waitlist = (options: WaitlistPluginOptions = {}) => {
479515
"/waitlist/promote",
480516
{
481517
method: "POST",
518+
use: [sessionMiddleware],
482519
body: z.object({
483520
email: z.string().email(),
484521
}),
485522
},
486523
async (ctx) => {
487-
if (requireAdmin && !ctx.context.session) {
488-
throw new APIError("UNAUTHORIZED", {
489-
message: "Authentication required",
490-
});
524+
if (requireAdmin) {
525+
if (!ctx.context.session) {
526+
throw new APIError("UNAUTHORIZED", {
527+
message: "You must be signed in",
528+
});
529+
}
530+
const userRole = (ctx.context.session as any).user?.role;
531+
if (userRole !== "admin") {
532+
throw new APIError("FORBIDDEN", {
533+
message: "You must have admin privileges",
534+
});
535+
}
491536
}
492537

493538
const email = ctx.body.email.toLowerCase().trim();
@@ -536,15 +581,24 @@ export const waitlist = (options: WaitlistPluginOptions = {}) => {
536581
"/waitlist/promote-all",
537582
{
538583
method: "POST",
584+
use: [sessionMiddleware],
539585
body: z.object({
540586
status: z.enum(["pending", "approved"]).optional().default("approved"),
541587
}),
542588
},
543589
async (ctx) => {
544-
if (requireAdmin && !ctx.context.session) {
545-
throw new APIError("UNAUTHORIZED", {
546-
message: "Authentication required",
547-
});
590+
if (requireAdmin) {
591+
if (!ctx.context.session) {
592+
throw new APIError("UNAUTHORIZED", {
593+
message: "You must be signed in",
594+
});
595+
}
596+
const userRole = (ctx.context.session as any).user?.role;
597+
if (userRole !== "admin") {
598+
throw new APIError("FORBIDDEN", {
599+
message: "You must have admin privileges",
600+
});
601+
}
548602
}
549603

550604
const status = ctx.body.status;
@@ -584,15 +638,24 @@ export const waitlist = (options: WaitlistPluginOptions = {}) => {
584638
"/waitlist/complete",
585639
{
586640
method: "POST",
641+
use: [sessionMiddleware],
587642
body: z.object({
588643
email: z.string().email(),
589644
}),
590645
},
591646
async (ctx) => {
592-
if (requireAdmin && !ctx.context.session) {
593-
throw new APIError("UNAUTHORIZED", {
594-
message: "Authentication required",
595-
});
647+
if (requireAdmin) {
648+
if (!ctx.context.session) {
649+
throw new APIError("UNAUTHORIZED", {
650+
message: "You must be signed in",
651+
});
652+
}
653+
const userRole = (ctx.context.session as any).user?.role;
654+
if (userRole !== "admin") {
655+
throw new APIError("FORBIDDEN", {
656+
message: "You must have admin privileges",
657+
});
658+
}
596659
}
597660

598661
const email = ctx.body.email.toLowerCase().trim();

0 commit comments

Comments
 (0)