UNPKG

@tmlmobilidade/types

Version:
555 lines (554 loc) • 22.2 kB
import { z } from 'zod'; export declare const PermissionSchema: z.ZodDiscriminatedUnion<"scope", [z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; scope: z.ZodLiteral<"agencies">; }, "strip", z.ZodTypeAny, { scope: "agencies"; action: "create" | "delete" | "read" | "lock" | "update"; }, { scope: "agencies"; action: "create" | "delete" | "read" | "lock" | "update"; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update", "update_texts", "update_dates", "update_publish_status"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; reference_types: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; reference_types: string[]; }, { agency_ids?: string[] | undefined; reference_types?: string[] | undefined; }>>; scope: z.ZodLiteral<"alerts">; }, "strip", z.ZodTypeAny, { scope: "alerts"; action: "create" | "delete" | "read" | "lock" | "update" | "update_texts" | "update_dates" | "update_publish_status"; resources: { agency_ids: string[]; reference_types: string[]; }; }, { scope: "alerts"; action: "create" | "delete" | "read" | "lock" | "update" | "update_texts" | "update_dates" | "update_publish_status"; resources?: { agency_ids?: string[] | undefined; reference_types?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["acceptance_change_status", "acceptance_justify", "acceptance_lock", "acceptance_read", "analsys_lock", "analysis_lock", "analysis_read", "analysis_reprocess", "analysis_update", "audit_lock", "audit_read", "audit_update", "acceptance_comment_activity"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"rides">; }, "strip", z.ZodTypeAny, { scope: "rides"; action: "acceptance_change_status" | "acceptance_justify" | "acceptance_lock" | "acceptance_read" | "analsys_lock" | "analysis_lock" | "analysis_read" | "analysis_reprocess" | "analysis_update" | "audit_lock" | "audit_read" | "audit_update" | "acceptance_comment_activity"; resources: { agency_ids: string[]; }; }, { scope: "rides"; action: "acceptance_change_status" | "acceptance_justify" | "acceptance_lock" | "acceptance_read" | "analsys_lock" | "analysis_lock" | "analysis_read" | "analysis_reprocess" | "analysis_update" | "audit_lock" | "audit_read" | "audit_update" | "acceptance_comment_activity"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["read", "export"]>; scope: z.ZodLiteral<"sams">; }, "strip", z.ZodTypeAny, { scope: "sams"; action: "read" | "export"; }, { scope: "sams"; action: "read" | "export"; }>, z.ZodObject<{ action: z.ZodEnum<["create", "read", "lock", "request_approval", "update_processing_status"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"gtfs_validations">; }, "strip", z.ZodTypeAny, { scope: "gtfs_validations"; action: "create" | "read" | "lock" | "request_approval" | "update_processing_status"; resources: { agency_ids: string[]; }; }, { scope: "gtfs_validations"; action: "create" | "read" | "lock" | "request_approval" | "update_processing_status"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["read_links", "read_wiki"]>; scope: z.ZodLiteral<"home">; }, "strip", z.ZodTypeAny, { scope: "home"; action: "read_links" | "read_wiki"; }, { scope: "home"; action: "read_links" | "read_wiki"; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; scope: z.ZodLiteral<"organizations">; }, "strip", z.ZodTypeAny, { scope: "organizations"; action: "create" | "delete" | "read" | "lock" | "update"; }, { scope: "organizations"; action: "create" | "delete" | "read" | "lock" | "update"; }>, z.ZodObject<{ action: z.ZodEnum<["read"]>; scope: z.ZodLiteral<"performance">; }, "strip", z.ZodTypeAny, { scope: "performance"; action: "read"; }, { scope: "performance"; action: "read"; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "read_controller", "read_pcgi_legacy", "lock", "update", "update_controller", "update_feed_info_dates", "update_gtfs_plan", "update_pcgi_legacy", "read_apex_file", "update_apex_file", "delete_apex_file"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"plans">; }, "strip", z.ZodTypeAny, { scope: "plans"; action: "create" | "delete" | "read" | "lock" | "update" | "read_controller" | "read_pcgi_legacy" | "update_controller" | "update_feed_info_dates" | "update_gtfs_plan" | "update_pcgi_legacy" | "read_apex_file" | "update_apex_file" | "delete_apex_file"; resources: { agency_ids: string[]; }; }, { scope: "plans"; action: "create" | "delete" | "read" | "lock" | "update" | "read_controller" | "read_pcgi_legacy" | "update_controller" | "update_feed_info_dates" | "update_gtfs_plan" | "update_pcgi_legacy" | "read_apex_file" | "update_apex_file" | "delete_apex_file"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; scope: z.ZodLiteral<"roles">; }, "strip", z.ZodTypeAny, { scope: "roles"; action: "create" | "delete" | "read" | "lock" | "update"; }, { scope: "roles"; action: "create" | "delete" | "read" | "lock" | "update"; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update", "export", "edit_coordinates", "edit_name"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; municipality_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { municipality_ids: string[]; agency_ids: string[]; }, { municipality_ids?: string[] | undefined; agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"stops">; }, "strip", z.ZodTypeAny, { scope: "stops"; action: "create" | "delete" | "read" | "lock" | "update" | "export" | "edit_coordinates" | "edit_name"; resources: { municipality_ids: string[]; agency_ids: string[]; }; }, { scope: "stops"; action: "create" | "delete" | "read" | "lock" | "update" | "export" | "edit_coordinates" | "edit_name"; resources?: { municipality_ids?: string[] | undefined; agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; scope: z.ZodLiteral<"users">; }, "strip", z.ZodTypeAny, { scope: "users"; action: "create" | "delete" | "read" | "lock" | "update"; }, { scope: "users"; action: "create" | "delete" | "read" | "lock" | "update"; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"vehicles">; }, "strip", z.ZodTypeAny, { scope: "vehicles"; action: "create" | "delete" | "read" | "lock" | "update"; resources: { agency_ids: string[]; }; }, { scope: "vehicles"; action: "create" | "delete" | "read" | "lock" | "update"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "lock", "nav", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"fares">; }, "strip", z.ZodTypeAny, { scope: "fares"; action: "create" | "delete" | "lock" | "update" | "nav"; resources: { agency_ids: string[]; }; }, { scope: "fares"; action: "create" | "delete" | "lock" | "update" | "nav"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"annotations">; }, "strip", z.ZodTypeAny, { scope: "annotations"; action: "create" | "delete" | "read" | "lock" | "update"; resources: { agency_ids: string[]; }; }, { scope: "annotations"; action: "create" | "delete" | "read" | "lock" | "update"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"year_periods">; }, "strip", z.ZodTypeAny, { scope: "year_periods"; action: "create" | "delete" | "read" | "lock" | "update"; resources: { agency_ids: string[]; }; }, { scope: "year_periods"; action: "create" | "delete" | "read" | "lock" | "update"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"holidays">; }, "strip", z.ZodTypeAny, { scope: "holidays"; action: "create" | "delete" | "read" | "lock" | "update"; resources: { agency_ids: string[]; }; }, { scope: "holidays"; action: "create" | "delete" | "read" | "lock" | "update"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"events">; }, "strip", z.ZodTypeAny, { scope: "events"; action: "create" | "delete" | "read" | "lock" | "update"; resources: { agency_ids: string[]; }; }, { scope: "events"; action: "create" | "delete" | "read" | "lock" | "update"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "lock", "nav", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"zones">; }, "strip", z.ZodTypeAny, { scope: "zones"; action: "create" | "delete" | "lock" | "update" | "nav"; resources: { agency_ids: string[]; }; }, { scope: "zones"; action: "create" | "delete" | "lock" | "update" | "nav"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "lock", "nav", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"typologies">; }, "strip", z.ZodTypeAny, { scope: "typologies"; action: "create" | "delete" | "lock" | "update" | "nav"; resources: { agency_ids: string[]; }; }, { scope: "typologies"; action: "create" | "delete" | "lock" | "update" | "nav"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>, z.ZodObject<{ action: z.ZodEnum<["create", "delete", "read", "lock", "update"]>; resources: z.ZodDefault<z.ZodObject<{ agency_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>; }, "strip", z.ZodTypeAny, { agency_ids: string[]; }, { agency_ids?: string[] | undefined; }>>; scope: z.ZodLiteral<"lines">; }, "strip", z.ZodTypeAny, { scope: "lines"; action: "create" | "delete" | "read" | "lock" | "update"; resources: { agency_ids: string[]; }; }, { scope: "lines"; action: "create" | "delete" | "read" | "lock" | "update"; resources?: { agency_ids?: string[] | undefined; } | undefined; }>]>; export type Permission = z.infer<typeof PermissionSchema>; export type ActionsOf<S extends Permission['scope']> = Extract<Permission, { scope: S; }>['action']; export type PermissionCatalogType = { [S in Permission['scope']]: { actions: { [A in ActionsOf<S>]: A; }; scope: S; }; }; /** * Arguments for hasPermissionResource function. * @param T The type of the resource. */ export interface HasPermissionResourceArgs { action: string; permissions: Permission[]; resource_key: string; scope: string; value: unknown; } /** * A scope/action pair used to collect resource access from one or more permissions. */ export interface PermissionResourceCheck<S extends Permission['scope'] = Permission['scope']> { action: ActionsOf<S>; scope: S; } /** * Arguments for getPermissionResourceAccess function. */ export interface GetPermissionResourceAccessArgs { checks: PermissionResourceCheck[]; permissions: Permission[]; resource_key: string; } /** * Aggregated access to a permission resource key. * When allowAll is true, callers should ignore values and treat the user * as having access to every value for that resource key. */ export interface PermissionResourceAccess<TValue = string> { allowAll: boolean; values: TValue[]; } /** * Arguments for getScopePermissions function. */ export interface GetScopePermissionsArgs<S extends Permission['scope']> { actions: PermissionCatalogType[S]['actions']; permissions: Permission[]; resource?: { key: string; requireAll?: boolean; value: unknown; }; scope: S; } /** * Result object containing permission checks for a scope. * Maps each action of the scope to a boolean indicating if the user has that permission. */ export type ScopePermissions<S extends Permission['scope']> = Record<ActionsOf<S>, boolean>; /** * PermissionCatalog provides a structured catalog of all available permissions * in the system, categorized by scope and their respective actions. * Use it to reference required permissions in components and services. */ export declare class PermissionCatalog { static readonly ALLOW_ALL_FLAG = "allow_all"; /** * Generates the complete permission catalog by extracting * scopes and actions from the defined PermissionSchema. * @return A catalog object mapping scopes to their actions. */ static get all(): PermissionCatalogType; /** * Get a specific permission from a full list by scope and action. * @param permissionEntries The full list of permissions of the user. * @param scope The resource scope of the permission to filter by. * @param action The action of the permission to filter by. * @returns The filtered Permission object or undefined if not found. */ static get<S extends Permission['scope']>(permissionEntries: Permission[], scope: S, action: ActionsOf<S>): Extract<Permission, { action: ActionsOf<S>; scope: S; }> | undefined; /** * Get all permissions for a given scope and set of actions in one call. * More efficient than calling hasPermission or hasPermissionResource multiple times. * @param args Arguments object containing permissions, scope, actions, and optional resource. * @param args.resource.requireAll If true, uses hasPermissionResourceAll (user must have permission for ALL values in array). If false/undefined, uses hasPermissionResource (user needs permission for ANY value). * @returns Object with boolean values for each action in the scope. */ static getScopePermissions<S extends Permission['scope']>({ actions, permissions, resource, scope }: GetScopePermissionsArgs<S>): ScopePermissions<S>; /** * Check if a list of permission entries has the requested scope/action pair. * @param permissionEntries The list of permission entries to check against. * @param scope The required scope to check. * @param action The required action to check. * @returns The permission object or undefined if not found. */ static hasPermission<S extends Permission['scope']>(permissionEntries: Permission[], scope: S, action: ActionsOf<S>): boolean; /** * Collect allowed values for a resource key across multiple scope/action checks. * * Use this when a caller needs to build a database filter before loading * documents. For example, a list endpoint can combine `lines.read`, * `lines.update`, and `zones.nav` permissions into a single set of * allowed `agency_ids`, then query MongoDB with `{ agency_ids: { $in: values } }`. * * This complements `hasPermissionResource`: that method answers whether * a user can access a known resource value, while this method answers which * resource values the user can access for a set of allowed permissions. * * If any matching permission contains PermissionCatalog.ALLOW_ALL_FLAG for * the resource key, this returns `{ allowAll: true, values: [] }`. * * @param permissions The list of permissions from a user or request. * @param checks The scope/action pairs whose resource values should be merged. * @param resource_key The permission resource key to collect, e.g. `agency_ids`. * @returns The aggregated resource access for the requested checks. */ static getPermissionResourceAccess<TValue = string>(args: GetPermissionResourceAccessArgs): PermissionResourceAccess<TValue>; /** * Check if a permission exists in a list of permissions, with additional check for a given resource value. * If a `value` exists in a `resource` of a User `permissions` object that * matches the given `action` and `scope`. For example, if you want to check if * a user has access to a specific `agency_id`, you set `value=43` and `resource_key='agency_ids'`. * If the provided `permissions` object contains the value `43` inside the `scope='plans'`, * `action='create'` and `resource_key='agency_ids'` the function will return true. * @param permissions The list of permissions (from a user or request). * @param value The permission value to check against. * @param resource_key The key of the resource. * @param scope The scope of the permission. * @param action The action of the permission. * @returns The permission. */ static hasPermissionResource({ action, permissions, resource_key, scope, value }: HasPermissionResourceArgs): boolean; /** * Checks whether the user has permission to perform a specific action * within a specific scope for ALL values in an array. * This is stricter than `hasPermissionResource` which only requires permission for ANY value. * Use this for operations like update/delete where the user must have permission for all agencies involved. * @param permissions The list of permissions (from a user or request). * @param value The permission value(s) to check against - if array, ALL values must be permitted. * @param resource_key The key of the resource. * @param scope The scope of the permission. * @param action The action of the permission. * @returns True if user has permission for ALL values, false otherwise. */ static hasPermissionResourceAll({ action, permissions, resource_key, scope, value }: HasPermissionResourceArgs): boolean; /** * Sanitizes a list of permissions by removing any entries * that do not correspond to valid scopes and actions * defined in the PermissionCatalog. * @param existingEntries Array of Permission objects to sanitize. * @return A cleaned array containing only valid permissions. */ static sanitize(existingEntries: Permission[]): Permission[]; /** * Sanitizes a list of permissions by removing any entries * that do not correspond to valid scopes and actions * defined in the PermissionCatalog. * @param existingEntries Array of Permission objects to sanitize. * @return A cleaned array containing only valid permissions. */ static updatePermissionResource<S extends Permission['scope']>(permissionEntries: Permission[], scope: S, action: ActionsOf<S>, resources: Record<string, unknown>): Permission[]; }