init commit for iPAL-kit plugin

This commit is contained in:
2026-07-18 20:30:23 +02:00
parent 10638127a9
commit 5733a9c8bf
119 changed files with 6892 additions and 411 deletions
+44
View File
@@ -0,0 +1,44 @@
import type { Role } from './types.js'
import { ROLE_HIERARCHY } from './types.js'
/**
* The plugin can't know the client's generated User type, and Payload types
* `req.user` loosely (UntypedUser | null). Predicates therefore accept an
* unknown-ish user and read `roles` defensively — no assumptions about shape
* beyond an optional roles array.
*/
type MaybeUser = { roles?: null | Role[] } | null | Record<string, unknown> | undefined
/** Safely extracts the roles array from a loosely-typed user. */
function getRoles(user: MaybeUser): Role[] {
if (!user || typeof user !== 'object') {return []}
const roles = (user as { roles?: unknown }).roles
if (!Array.isArray(roles)) {return []}
return roles.filter((role): role is Role => ROLE_HIERARCHY.includes(role as Role))
}
/** Highest-privilege role index the user holds, or -1 if none. */
function highestRoleIndex(user: MaybeUser): number {
const roles = getRoles(user)
if (!roles.length) {return -1}
return Math.max(...roles.map((role) => ROLE_HIERARCHY.indexOf(role)))
}
/**
* True if the user holds at least the given role in the hierarchy.
* admin satisfies 'editor' and 'user'; editor satisfies 'user'.
*/
export function hasMinimumRole(user: MaybeUser, minimum: Role): boolean {
return highestRoleIndex(user) >= ROLE_HIERARCHY.indexOf(minimum)
}
/** True if the user is an admin. */
export function isAdmin(user: MaybeUser): boolean {
return hasMinimumRole(user, 'admin')
}
/** True if the user is an editor or higher (editor, admin). */
export function isEditor(user: MaybeUser): boolean {
return hasMinimumRole(user, 'editor')
}