Files
2026-05-27 23:47:53 +01:00

2.6 KiB

permission-middleware

(no submodules)

Purpose

Provides framework-agnostic permission checking middleware for @suaveplan/permissions. The createPermissionMiddleware factory returns a (req, res, next) function that reads the authenticated user from req.user, checks the configured permission via the adapter, and calls next(PermissionsError) on denial.

The checkPermission function provides a one-off convenience check without creating a full engine instance, useful for route handlers that need a single inline permission assertion.

Features

  • createPermissionMiddleware(options) — factory returning MiddlewareFn
  • checkPermission(userId, resource, action, adapter) — one-off policy evaluation
  • User extraction from req.user.userId or req.user.sub (JWT-compatible)
  • ResourceExtractor and UserExtractor type exports

Usage: Basic Example

import { createPermissionMiddleware, MemoryAdapter } from "@suaveplan/permissions";

const adapter = new MemoryAdapter();
const mw = createPermissionMiddleware({
  resource: "posts",
  action: "delete",
  adapter,
});
// Attach to route: app.delete("/posts/:id", verifyJwt, mw, handler)

Usage: Advanced Example

import { checkPermission } from "@suaveplan/permissions";
import { MemoryAdapter } from "@suaveplan/permissions";

const adapter = new MemoryAdapter();

// Route handler inline check
async function deletePost(userId: string, postId: string) {
  const result = await checkPermission(userId, "posts", "delete", adapter);
  if (!result.allowed) throw new Error(result.reason);
  // ... proceed with deletion
}

API Reference

createPermissionMiddleware(options): MiddlewareFn

Options: resource, action, adapter?.

Reads user from req.user.userId or req.user.sub. Calls next(PermissionsError) if no user, no adapter, or permission denied.

checkPermission(userId, resource, action, adapter): Promise<PolicyResult>

Creates a transient PolicyEngine and evaluates one permission check.

ResourceExtractor

(req: unknown) => string — type alias.

UserExtractor

(req: unknown) => string | null — type alias.

Implementation Notes

The middleware user extraction checks both userId (from a UserContext) and sub (from a JWTPayload) to support both @suaveplan/auth's verifyTokenMiddleware (which attaches req.user as JWTPayload) and custom middleware that attaches req.user as UserContext. No adapter means the middleware fails closed with a PERM_CODES.ADAPTER_ERROR, preventing accidental open access when misconfigured.