UNPKG

@taukala/xs-ctrl

Version:

A flexible and powerful access control library for JavaScript applications with dynamic validation support

196 lines (179 loc) 5.98 kB
declare module '@taukala/xs-ctrl' { /** * Session object type (generic to allow custom session types) */ export type Session = any; /** * Claims object structure representing user permissions and attributes * @example * { * role: ['admin', 'user'], * department: ['IT'], * businessOwner: ['business-1', 'business-2'] * } */ export interface Claims { [key: string]: (string | number)[]; } /** * Context object for validation containing session, claims, and custom resources */ export interface ValidationContext { session?: Session; claims?: Claims; resources?: Record<string, any>; [key: string]: any; } /** * Static condition type representing [key, allowedValues] pairs */ export type Condition = [string, (string | number)[]]; /** * Dynamic validator function type for complex authorization rules */ export type DynamicValidator = (context: ValidationContext) => boolean | Promise<boolean>; /** * Access rule structure containing static conditions and dynamic validators */ export interface AccessRule { conditions: Condition[]; dynamicValidators: DynamicValidator[]; } /** * Configuration options for creating a permission validator */ export interface PermissionValidatorOptions { /** * Async function to retrieve the current session * Should return null/undefined if no session exists */ getSession: () => Promise<Session | null | undefined>; /** * Async function to retrieve user claims * Receives the session object and should return claims object * @example * async (session) => ({ * role: ['business'], * businessOwner: ['business-1', 'business-2'] * }) */ getClaims: (session: Session) => Promise<Claims>; /** * Callback for handling unauthenticated users * Usually redirects to login page or returns 401 response */ onUnauthenticated: () => void | Promise<void>; /** * Callback for handling unauthorized access * Usually redirects to home page or returns 403 response */ onUnauthorized: () => void | Promise<void>; } /** * Result object returned by permission validator */ export interface PermissionValidatorResult { session?: Session; claims?: Claims; status: 200 | 401 | 403; } /** * Interface for building access rules using a fluent API */ export interface AccessRuleBuilder { /** * Adds a static condition to the access rule * @param key The condition key (e.g., 'role', 'department') * @param values One or more acceptable values for the condition * @throws {Error} If key is empty or no values are provided */ addCondition(key: string, ...values: (string | number)[]): AccessRuleBuilder; /** * Adds a dynamic condition to the access rule * @param validator Function that performs dynamic validation * @throws {Error} If validator is not a function */ addDynamicCondition(validator: DynamicValidator): AccessRuleBuilder; /** * Builds and returns the final rule object */ build(): AccessRule; } /** * Creates a permission validator that combines authentication and authorization checks. * This factory function generates a validator that can be used to protect routes or resources. * * @param options Configuration options * @returns An async validator function that accepts access rules and context * * @example * // Basic usage with Next.js and static rules * const validatePermission = createPermissionValidator({ * getSession: auth, * getClaims: async (session) => ({ * role: ['admin'], * department: ['IT'] * }), * onUnauthenticated: () => redirect('/auth/signin'), * onUnauthorized: () => redirect('/') * }); * * @example * // Usage with dynamic business rules * const validatePermission = createPermissionValidator({ * getSession: auth, * getClaims: async (session) => ({ * role: ['business'], * businessOwner: ['business-1', 'business-2'] * }), * onUnauthenticated: () => redirect('/auth/signin'), * onUnauthorized: () => redirect('/') * }); */ export function createPermissionValidator( options: PermissionValidatorOptions ): ( criteria: AccessRule[], context?: ValidationContext ) => Promise<PermissionValidatorResult>; /** * Validates user claims against a set of access rules using OR/AND logic. * Supports both static claim validation and dynamic resource-based validation. * * @param accessRules Array of rule groups * @param userClaims Object containing user's claims * @param context Context object passed to dynamic validators * @throws {Error} If accessRules is not an array * @throws {Error} If user's claims don't match any rule group * @returns Returns true if validation passes */ export function validateClaim( accessRules: AccessRule[], userClaims: Claims, context?: ValidationContext ): Promise<boolean>; /** * Creates an access rule builder for constructing authorization rules. * The builder follows a fluent interface pattern allowing method chaining * for creating complex access conditions. * * @returns Rule builder object with methods for building access rules * * @example * // Static only - single condition * const adminRule = createAccessRule() * .addCondition('role', 'admin') * .build(); * * @example * // Mixed - static and dynamic conditions * const complexRule = createAccessRule() * .addCondition('role', 'business') * .addDynamicCondition(({ claims, resources }) => { * const businessIds = claims.businessOwner || []; * return businessIds.includes(resources.business?.id); * }) * .build(); */ export function createAccessRule(): AccessRuleBuilder; }