import type { EmitterLike } from '@adonisjs/core/types/events'; import { type ContainerResolver } from '@adonisjs/core/container'; import { type Constructor, type LazyImport, type UnWrapLazyImport } from '@adonisjs/core/types/common'; import { AuthorizationResponse } from './response.ts'; import { ability as createAbility } from './ability.ts'; import { AbilitiesBuilder } from './abilities_builder.ts'; import { PolicyAuthorizer } from './policy_authorizer.ts'; import type { BouncerEvents, BouncerAbility, ResponseBuilder, BouncerAuthorizer, AuthorizerResponse, NarrowAbilitiesForAUser } from './types.ts'; /** * Bouncer exposes the API to evaluate bouncer abilities and policies to * verify if a user is authorized to perform the given action. * * @example * ```js * const bouncer = new Bouncer(user, abilities, policies) * * // Check ability * const canEdit = await bouncer.allows('editPost', post) * * // Use policy * const canView = await bouncer.with('PostPolicy').allows('view', post) * * // Authorize (throws on failure) * await bouncer.authorize('deletePost', post) * ``` */ export declare class Bouncer, Abilities extends Record> | undefined = undefined, Policies extends Record>> | undefined = undefined> { #private; /** * Response builder is used to normalize bouncer responses */ static responseBuilder: ResponseBuilder; /** * Define an ability using the AbilityBuilder * * @param name Unique name for the ability * @param authorizer Function that determines if the action is allowed * @param options Optional configuration for the ability * * @example * ```js * const abilities = Bouncer.define('editPost', (user, post) => { * return user.id === post.authorId * }) * ``` */ static define>(name: Name, authorizer: Authorizer, options?: { allowGuest: boolean; }): AbilitiesBuilder<{ [K in Name]: Authorizer extends (user: infer User, ...args: infer Args) => AuthorizerResponse | Promise ? { allowGuest: false; original: Authorizer; execute(user: User | null, ...args: Args): ReturnType; } : never; }>; /** * Emitter to emit events */ static emitter?: EmitterLike; /** * Define a bouncer ability from a callback */ static ability: typeof createAbility; /** * Pre-defined abilities */ abilities?: Abilities; /** * Pre-defined policies */ policies?: Policies; /** * An object with helpers to be shared with Edge for * performing authorization. */ edgeHelpers: { bouncer: { parent: Bouncer; can(action: string, ...args: any[]): Promise; cannot(action: string, ...args: any[]): Promise; }; }; /** * Create a new Bouncer instance * * @param userOrResolver User object or function to resolve the user * @param abilities Pre-defined abilities for authorization * @param policies Pre-defined policies for authorization */ constructor(userOrResolver: User | (() => User | null) | null, abilities?: Abilities, policies?: Policies); /** * Returns an instance of PolicyAuthorizer. PolicyAuthorizer is * used to authorize user and actions using a given policy * * @param policy Policy class or policy name to use for authorization * * @example * ```js * await bouncer.with('PostPolicy').allows('edit', post) * await bouncer.with(PostPolicy).denies('delete', post) * ``` */ with(policy: Policy): Policies extends Record>> ? PolicyAuthorizer> : never; with>(policy: Policy): PolicyAuthorizer; /** * Set a container resolver to use for resolving policies * * @param containerResolver IoC container resolver for constructing policy instances */ setContainerResolver(containerResolver?: ContainerResolver): this; /** * Execute an ability by reference * * @param ability Ability instance to execute * @param args Arguments to pass to the ability * * @example * ```js * const result = await bouncer.execute(editPostAbility, post) * ``` */ execute>(ability: Ability, ...args: Ability extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Execute an ability from the list of pre-defined abilities * * @param ability Name of the pre-defined ability * @param args Arguments to pass to the ability * * @example * ```js * const result = await bouncer.execute('editPost', post) * ``` */ execute>(ability: Ability, ...args: Abilities[Ability] extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Check if a user is allowed to perform an action using * the ability provided by reference * * @param ability Ability instance to check * @param args Arguments to pass to the ability * * @example * ```js * const canEdit = await bouncer.allows(editPostAbility, post) * ``` */ allows>(ability: Ability, ...args: Ability extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Check if a user is allowed to perform an action using * the ability from the pre-defined list of abilities * * @param ability Name of the pre-defined ability * @param args Arguments to pass to the ability * * @example * ```js * const canEdit = await bouncer.allows('editPost', post) * ``` */ allows>(ability: Ability, ...args: Abilities[Ability] extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Check if a user is denied from performing an action using * the ability provided by reference * * @param action Ability instance to check * @param args Arguments to pass to the ability * * @example * ```js * const cannotEdit = await bouncer.denies(editPostAbility, post) * ``` */ denies>(action: Action, ...args: Action extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Check if a user is denied from performing an action using * the ability from the pre-defined list of abilities * * @param action Name of the pre-defined ability * @param args Arguments to pass to the ability * * @example * ```js * const cannotEdit = await bouncer.denies('editPost', post) * ``` */ denies>(action: Action, ...args: Abilities[Action] extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Authorize a user against for a given ability * * @param action Ability instance to authorize * @param args Arguments to pass to the ability * @throws E_AUTHORIZATION_FAILURE * * @example * ```js * await bouncer.authorize(editPostAbility, post) * ``` */ authorize>(action: Action, ...args: Action extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Authorize a user against a given ability * * @param ability Name of the pre-defined ability * @param args Arguments to pass to the ability * @throws E_AUTHORIZATION_FAILURE * * @example * ```js * await bouncer.authorize('editPost', post) * ``` */ authorize>(ability: Ability, ...args: Abilities[Ability] extends { original: (user: User, ...args: infer Args) => AuthorizerResponse | Promise; } ? Args : never): Promise; /** * Create AuthorizationResponse to deny access * * @param message Denial message * @param status Optional HTTP status code * * @example * ```js * return bouncer.deny('Access denied', 403) * ``` */ deny(message: string, status?: number): AuthorizationResponse; }