/** * `permissionGate` — minimal route-level RBAC for extensions. * * Default-deny: if no Casbin policy grants the resource/action, the request * is rejected with 403. The god role bypasses the gate (handled by the * engine's `checkPermission`). * * Action is derived from the HTTP method using the standard CRUD mapping * (GET → read, POST → create, PATCH/PUT → update, DELETE → delete). The * `resource` is the extension's logical name (e.g. `'crm'`, `'invoices'`); * operators grant access by adding a Casbin policy: * * INSERT INTO zvd_permissions (ptype, v0, v1, v2) * VALUES ('p', 'user_role', 'crm', 'read'); * * Why this exists: many extensions historically only checked * `auth.api.getSession(...)` — i.e. any authenticated user could * read/write the entire extension. That's the right default for a * single-tenant deployment but unacceptable in multi-tenant or * role-segmented installs. The gate gives operators a single knob to * tighten access without each extension having to roll its own RBAC. * * Usage in an extension's `routes.ts`: * * app.use('*', permissionGate(ctx, 'crm')); * * Place AFTER the auth-guard middleware that sets `c.set('user', ...)`. */ type MaybePromise = T | Promise; interface GateContext { checkPermission: (userId: string, resource: string, action: string) => Promise; } export declare function permissionGate(ctx: GateContext, resource: string, opts?: { actionOverrides?: Record; }): (c: any, next: () => MaybePromise) => Promise; export {}; //# sourceMappingURL=permission-gate.d.ts.map