@volcanicminds/backend 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +45 -1
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -71,6 +71,32 @@ A synthetic overview of the out-of-the-box (OOTB) capabilities of this opinionat
71
71
 
72
72
  ## Changelog
73
73
 
74
+ ### 4.0.1
75
+
76
+ **Authorization redesign (breaking).** Full model in [docs/AUTHORIZATION_MODEL.md](docs/AUTHORIZATION_MODEL.md).
77
+
78
+ - **Roles.** Two protected built-ins remain — `public` and `admin`; **`backoffice` is removed**. A consumer's
79
+ `config/roles.ts` may override only the *labels* of `admin`/`public` (their code and capabilities are locked)
80
+ and add its own roles freely.
81
+ - **Capabilities.** Roles may declare `capabilities: string[]`; a route gates with `requireCapability: 'X'`
82
+ instead of a role list. At boot the allowed set becomes `admin` plus every role that declares the capability.
83
+ The framework reserves **`users`**, **`tokens`** and **`manifest`**, and the native surfaces (`/users/*`,
84
+ `/token/*`, `/admin/manifest`) are re-gated to them — so a non-admin operator can be granted user/token
85
+ management or console access without being `admin`.
86
+ - **Admin apex.** Only an `admin` may grant the `admin` role (to a user *or* a token), and only with
87
+ `options.allow_multiple_admin`; no capability holder may act on an existing admin subject; the **last admin
88
+ cannot be deleted, demoted or blocked** (never-zero-admin).
89
+ - **Boot fail-fast.** A route gated on a role absent from `config/roles.ts` now **aborts startup** (previously it
90
+ was silently disabled).
91
+ - **Sovereign founder & genesis.** `/auth/register` **never** creates an admin. Single-tenant instances provision
92
+ the founder at boot from **`ADMIN_EMAIL`** (create / promote / no-op); with no admin and no `ADMIN_EMAIL`,
93
+ startup fails fast. The founder is undeletable/undemotable/unblockable, its email is immutable via the API, and
94
+ its credentials are self-service only. A generated password is written to stdout only, never the logger.
95
+
96
+ **Migration.** Consumers referencing `backoffice` must re-declare it in `config/roles.ts` (with the capabilities
97
+ they need); stop bootstrapping an admin via `/auth/register` and set `ADMIN_EMAIL`; ensure a single-tenant instance
98
+ has an admin or `ADMIN_EMAIL` at boot.
99
+
74
100
  ### 3.5.0
75
101
 
76
102
  - **Per-route response cache (OOTB).** Opt in per endpoint with a `cache` prop in `routes.ts`
@@ -385,13 +411,18 @@ The framework is configured via `.env` variables. Below is a comprehensive list:
385
411
  | `MFA_APP_NAME` | Name of the application displayed in Authenticator apps. | No | `VolcanicApp` |
386
412
  | `MFA_ADMIN_FORCED_RESET_EMAIL` | Admin email for emergency MFA reset | No | |
387
413
  | `MFA_ADMIN_FORCED_RESET_UNTIL` | ISO Date string until which the reset is active | No | |
388
- | `MFA_ADMIN_FORCED_RESET_UNTIL` | ISO Date string until which the reset is active | No | |
389
414
  | `AUTH_MODE` | Authentication mode: `BEARER` (default) or `COOKIE` | No | `BEARER` |
390
415
  | `COOKIE_SECRET` | Secret for signing cookies (Required if `AUTH_MODE=COOKIE`) | **Yes**² | |
416
+ | `ADMIN_EMAIL` | Sovereign founder email — provisioned as `admin` at boot (single-tenant, see below). | **Yes**³ | |
417
+ | `ADMIN_PASSWORD` | Password for the founder created from `ADMIN_EMAIL`; if unset, a strong one is generated and printed to stdout. | No | |
391
418
  | `HIDE_ERROR_DETAILS` | Prevent error details (message) from being sent in response. | No | `true` (prod) |
392
419
 
393
420
  ² Required if `AUTH_MODE` is `COOKIE`.
394
421
 
422
+ ³ Single-tenant only, and only when no admin exists yet: a fresh instance provisions the sovereign founder
423
+ from `ADMIN_EMAIL`. If an admin already exists it may be omitted; with **no** admin and **no** `ADMIN_EMAIL`,
424
+ startup **fails fast**. See [docs/AUTHORIZATION_MODEL.md](docs/AUTHORIZATION_MODEL.md).
425
+
395
426
  ¹ Required if `JWT_REFRESH` is enabled.
396
427
 
397
428
  ## Logging levels
@@ -661,6 +692,19 @@ You can easily protect routes using Role-Based Access Control (RBAC). The framew
661
692
  }
662
693
  ```
663
694
 
695
+ Alternatively, gate by **capability**: the allowed set becomes `admin` plus every role that declares it. The
696
+ framework reserves `users`, `tokens` and `manifest`; a consumer grants its own capabilities to its roles in
697
+ `config/roles.ts`.
698
+
699
+ ```typescript
700
+ {
701
+ method: 'GET',
702
+ path: '/',
703
+ handler: 'product.find',
704
+ requireCapability: 'catalog' // admin, or any role that declares the `catalog` capability
705
+ }
706
+ ```
707
+
664
708
  **Adding Middleware:**
665
709
  Apply custom logic before your controller is executed using middleware. The framework comes with `global.isAuthenticated` to ensure a user is logged in.
666
710
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volcanicminds/backend",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "type": "module",
5
5
  "codename": "rome",
6
6
  "license": "MIT",