UNPKG

@unkey/rbac

Version:
99 lines (92 loc) 4.44 kB
import { z } from 'zod'; import { Result, SchemaError } from '@unkey/error'; /** * Here, the Result type is still a generic type that takes in a type T that extends the Actions * type. It uses a mapped type to iterate over the keys of the T object and create a string literal * union of all the possible combinations of resourceId:action strings. The [keyof T] at the end of * the type definition means that the resulting type is a union of all the possible string literal * unions created by the mapped type. * * In the example, we define a new MyActions type that matches the Actions type from the original * question, and then use the Result type to transform it into the desired MyResult type. The * resulting type is: * "team.read" | "team.write" | "domain.dns.read_record" | "domain.dns.create_record" * * * * @example * type Resources = { * team: 'read' | 'write'; * domain: { * dns: "read_record" | "create_record" * } * }; * * type MyResult = Flatten<Resources>; // type MyResult = "team.read" | "team.write" | "domain.dns.read_record" | "domain.dns.create_record" * * You can also choose a custom delimiter: * @example * Flatten<Resources, "::"> */ type Flatten<T extends Record<string, unknown>, Delimiter extends string = "."> = { [K in keyof T]: T[K] extends Record<string, unknown> ? `${string & K}${Delimiter}${T[K] extends infer U ? U extends Record<string, unknown> ? Flatten<U, Delimiter> : string & U : never}` : `${string & K}${Delimiter}${string & T[K]}`; }[keyof T]; /** * The database takes care of isolating roles between workspaces. * That's why we can assume the highest scope of a role is an `api` or later `gateway` * * role identifiers can look like this: * - `api_id.xxx` * - `gateway_id.xxx` * */ declare function buildIdSchema(prefix: string): z.ZodEffects<z.ZodString, string, string>; declare const apiId: z.ZodEffects<z.ZodString, string, string>; declare const ratelimitNamespaceId: z.ZodEffects<z.ZodString, string, string>; declare const apiActions: z.ZodEnum<["read_api", "create_api", "delete_api", "update_api", "create_key", "update_key", "delete_key", "encrypt_key", "decrypt_key", "read_key"]>; declare const ratelimitActions: z.ZodEnum<["limit", "create_namespace", "read_namespace", "update_namespace", "delete_namespace"]>; type Resources = { [resourceId in `api.${z.infer<typeof apiId>}`]: z.infer<typeof apiActions>; } & { [resourceId in `ratelimit.${z.infer<typeof ratelimitNamespaceId>}`]: z.infer<typeof ratelimitActions>; }; type UnkeyPermission = Flatten<Resources> | "*"; /** * Validation for roles used for our root keys */ declare const unkeyPermissionValidation: z.ZodEffects<z.ZodType<UnkeyPermission, z.ZodTypeDef, UnkeyPermission>, UnkeyPermission, UnkeyPermission>; type PermissionQuery<R extends string = string> = R | { and: Array<PermissionQuery<R> | undefined>; or?: never; } | { and?: never; or: Array<PermissionQuery<R> | undefined>; }; declare const permissionQuerySchema: z.ZodType<PermissionQuery>; declare function or<R extends string = string>(...args: Array<PermissionQuery<R> | undefined>): PermissionQuery<R>; declare function and<R extends string = string>(...args: Array<PermissionQuery<R> | undefined>): PermissionQuery<R>; declare function buildQuery<R extends string = string>(fn: (ops: { or: typeof or<R>; and: typeof and<R>; }) => PermissionQuery<R>): PermissionQuery; /** * buildUnkeyQuery is preloaded with out available roles and ensures typesafety for root key validation */ declare const buildUnkeyQuery: (fn: (ops: { or: (...args: (PermissionQuery<UnkeyPermission> | undefined)[]) => PermissionQuery<UnkeyPermission>; and: (...args: (PermissionQuery<UnkeyPermission> | undefined)[]) => PermissionQuery<UnkeyPermission>; }) => PermissionQuery<UnkeyPermission>) => PermissionQuery; declare class RBAC { evaluatePermissions(q: PermissionQuery, roles: string[]): Result<{ valid: true; message?: never; } | { valid: false; message: string; }, SchemaError>; validateQuery(q: PermissionQuery): Result<{ query: PermissionQuery; }>; private evaluateQueryV1; } export { type Flatten, type PermissionQuery, RBAC, type Resources, type UnkeyPermission, and, apiActions, buildIdSchema, buildQuery, buildUnkeyQuery, or, permissionQuerySchema, ratelimitActions, unkeyPermissionValidation };