import { ActionError, defineAction, type ActionAccept, type ActionAPIContext, type ActionHandler, } from 'astro:actions' import type { MaybePromise } from 'astro/actions/runtime/utils.js' import type { z } from 'astro/zod' type SpecialUserPermission = 'admin' | 'moderator' | 'verified' type Permission = SpecialUserPermission | 'guest' | 'not-spammer' | 'user' type ActionAPIContextWithUser = ActionAPIContext & { locals: { user: NonNullable } } type ActionHandlerWithUser = TInputSchema extends z.ZodType ? (input: z.infer, context: ActionAPIContextWithUser) => MaybePromise : ( // eslint-disable-next-line @typescript-eslint/no-explicit-any input: any, context: ActionAPIContextWithUser ) => MaybePromise export function defineProtectedAction< P extends Permission | SpecialUserPermission[], TOutput, TAccept extends ActionAccept | undefined = undefined, TInputSchema extends z.ZodType | undefined = TAccept extends 'form' ? z.ZodType : undefined, >({ accept, input: inputSchema, handler, permissions, }: { input?: TInputSchema accept?: TAccept handler: P extends 'guest' ? ActionHandler : ActionHandlerWithUser permissions: P }) { return defineAction({ accept, input: inputSchema, handler: ((input, context) => { if (permissions === 'guest' || (Array.isArray(permissions) && permissions.length === 0)) { return handler( input, // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any context as any ) } if (!context.locals.user) { throw new ActionError({ code: 'UNAUTHORIZED', message: 'You must be logged in to perform this action.', }) } if (permissions === 'not-spammer' && context.locals.user.spammer) { throw new ActionError({ code: 'FORBIDDEN', message: 'Spammer users are not allowed to perform this action.', }) } if ( (permissions === 'verified' || (Array.isArray(permissions) && permissions.includes('verified'))) && !context.locals.user.verified ) { if (context.locals.user.spammer) { throw new ActionError({ code: 'FORBIDDEN', message: 'Spammer users are not allowed to perform this action.', }) } throw new ActionError({ code: 'FORBIDDEN', message: 'Verified user privileges required.', }) } if ( (permissions === 'moderator' || (Array.isArray(permissions) && permissions.includes('moderator'))) && !context.locals.user.moderator ) { if (context.locals.user.spammer) { throw new ActionError({ code: 'FORBIDDEN', message: 'Spammer users are not allowed to perform this action.', }) } throw new ActionError({ code: 'FORBIDDEN', message: 'Moderator privileges required.', }) } if ( (permissions === 'admin' || (Array.isArray(permissions) && permissions.includes('admin'))) && !context.locals.user.admin ) { if (context.locals.user.spammer) { throw new ActionError({ code: 'FORBIDDEN', message: 'Spammer users are not allowed to perform this action.', }) } throw new ActionError({ code: 'FORBIDDEN', message: 'Admin privileges required.', }) } return handler(input, context as ActionAPIContextWithUser) }) as ActionHandler, }) }