ddd-ts-kit 0.19.0 → 0.20.0

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 (69) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.fr.md +10 -6
  3. package/README.md +8 -5
  4. package/dist/check/authz/is-granted.d.ts +8 -0
  5. package/dist/check/authz/is-granted.d.ts.map +1 -0
  6. package/dist/check/authz/is-granted.js +11 -0
  7. package/dist/check/authz/is-granted.js.map +1 -0
  8. package/dist/check/authz/permission-sets.d.ts +13 -0
  9. package/dist/check/authz/permission-sets.d.ts.map +1 -0
  10. package/dist/check/authz/permission-sets.js +19 -0
  11. package/dist/check/authz/permission-sets.js.map +1 -0
  12. package/dist/check/catalogue/architecture-rules.d.ts.map +1 -1
  13. package/dist/check/catalogue/architecture-rules.js +2 -0
  14. package/dist/check/catalogue/architecture-rules.js.map +1 -1
  15. package/dist/check/catalogue/default-severities.d.ts.map +1 -1
  16. package/dist/check/catalogue/default-severities.js +1 -0
  17. package/dist/check/catalogue/default-severities.js.map +1 -1
  18. package/dist/check/explain/authz-docs.d.ts.map +1 -1
  19. package/dist/check/explain/authz-docs.js +15 -0
  20. package/dist/check/explain/authz-docs.js.map +1 -1
  21. package/dist/check/fixtures/authz-granted-fixtures.d.ts +3 -0
  22. package/dist/check/fixtures/authz-granted-fixtures.d.ts.map +1 -0
  23. package/dist/check/fixtures/authz-granted-fixtures.js +71 -0
  24. package/dist/check/fixtures/authz-granted-fixtures.js.map +1 -0
  25. package/dist/check/fixtures/fixtures.d.ts.map +1 -1
  26. package/dist/check/fixtures/fixtures.js +2 -0
  27. package/dist/check/fixtures/fixtures.js.map +1 -1
  28. package/dist/check/fixtures/vocabulary-fixtures.d.ts.map +1 -1
  29. package/dist/check/fixtures/vocabulary-fixtures.js +4 -0
  30. package/dist/check/fixtures/vocabulary-fixtures.js.map +1 -1
  31. package/dist/check/language/declared-vocabularies.d.ts.map +1 -1
  32. package/dist/check/language/declared-vocabularies.js +8 -28
  33. package/dist/check/language/declared-vocabularies.js.map +1 -1
  34. package/dist/check/rules/authz-granted.d.ts +11 -0
  35. package/dist/check/rules/authz-granted.d.ts.map +1 -0
  36. package/dist/check/rules/authz-granted.js +45 -0
  37. package/dist/check/rules/authz-granted.js.map +1 -0
  38. package/dist/check/text/depth-at.d.ts +3 -0
  39. package/dist/check/text/depth-at.d.ts.map +1 -0
  40. package/dist/check/text/depth-at.js +11 -0
  41. package/dist/check/text/depth-at.js.map +1 -0
  42. package/dist/commands/generate.js +2 -0
  43. package/dist/commands/generate.js.map +1 -1
  44. package/dist/generate/access-vars.d.ts.map +1 -1
  45. package/dist/generate/access-vars.js +5 -0
  46. package/dist/generate/access-vars.js.map +1 -1
  47. package/dist/generate/grant-permission.d.ts +9 -0
  48. package/dist/generate/grant-permission.d.ts.map +1 -0
  49. package/dist/generate/grant-permission.js +111 -0
  50. package/dist/generate/grant-permission.js.map +1 -0
  51. package/dist/generate/kind.d.ts +2 -0
  52. package/dist/generate/kind.d.ts.map +1 -1
  53. package/dist/generate/kinds/command-kind.js +1 -1
  54. package/dist/generate/kinds/command-kind.js.map +1 -1
  55. package/dist/generate/kinds/file-upload-kind.js +2 -2
  56. package/dist/generate/kinds/file-upload-kind.js.map +1 -1
  57. package/dist/generate/kinds/query-kind.js +2 -2
  58. package/dist/generate/kinds/query-kind.js.map +1 -1
  59. package/dist/generate/shared-writes.d.ts.map +1 -1
  60. package/dist/generate/shared-writes.js +10 -3
  61. package/dist/generate/shared-writes.js.map +1 -1
  62. package/dist/init/manifest/versions.js +24 -24
  63. package/dist/init/run-init.js +1 -1
  64. package/dist/init/run-init.js.map +1 -1
  65. package/dist/version.d.ts +1 -1
  66. package/dist/version.js +1 -1
  67. package/package.json +3 -3
  68. package/templates/init/rules/application.md.tpl +2 -2
  69. package/templates/pipeline/package-scripts.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,27 @@ What each version changes for someone who uses the kit. The packages of `package
4
4
  together, under one version; the notes of each [GitHub release](https://github.com/gbourgeat/ddd-ts-kit/releases)
5
5
  list the pull requests behind it.
6
6
 
7
+ ## 0.20.0
8
+
9
+ **A permission no role holds is said.** In a project whose rights are roles (`stack.authz`
10
+ `rbac`), `authz/granted` (`ddd-ts-kit check`) reports each permission a context declares that no
11
+ role names in `platform/auth/roles.ts`, nor `platform/auth/signed-in-grants.ts`: the super-admin
12
+ `*` was the only one to reach it, so the checks stayed green and every other person was refused
13
+ at run time. It is a warning: `check` does not fail on it. A grant counts by the entry of the set
14
+ (`billingPermissions['invoice.issue']`), by the id (`'billing:invoice.issue'`) or by the wildcard
15
+ of the context (`'billing:*'`); a grant to `Role.System`, written by `generate job`, counts too.
16
+ The rule is silent under attributes, relationships or an authorizer of the project's own.
17
+
18
+ **`generate command`, `query` and `file-upload` take `--grant <role>`.** With `--permission`, it
19
+ writes the grant in `platform/auth/roles.ts` and adds the role to `platform/auth/role.ts` when it
20
+ is new. It is refused with `--public`, and when the rights are not roles. Without it, a `next`
21
+ step points at the roles to edit. `init --force` writes the roles from their template again, and
22
+ the warning names the grants to give back. To move, run `ddd-ts-kit check --rule authz/granted`
23
+ and grant each permission it lists to the roles that hold it, by the entry of its set, in
24
+ `roles.ts`; a permission meant for administrators only is granted to `Role.Admin` by name. A
25
+ context worker never passes `--grant` (`--local-only` refuses it): the conductor grants on the
26
+ trunk.
27
+
7
28
  ## 0.19.0
8
29
 
9
30
  **`status` and `worker-scope` read every slices table.** `docs/architecture/slices.md` may plan
package/README.fr.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [English](README.md) · **Français**
2
- <!-- translation-of: README.md sha256:fa841c4ea81f2c5d -->
2
+ <!-- translation-of: README.md sha256:18321b84fdc49821 -->
3
3
 
4
4
  # ddd-ts-kit
5
5
 
@@ -30,7 +30,7 @@ Aucune dépendance d'exécution. Node 22.12 ou ultérieur.
30
30
  npx ddd-ts-kit init
31
31
  npx ddd-ts-kit generate context billing --classification core --term "Invoice=A request for payment"
32
32
  npx ddd-ts-kit generate aggregate billing Invoice
33
- npx ddd-ts-kit generate command billing IssueInvoice --aggregate Invoice --permission invoice.issue --term "Issue=To make an invoice final"
33
+ npx ddd-ts-kit generate command billing IssueInvoice --aggregate Invoice --permission invoice.issue --grant accountant --term "Issue=To make an invoice final"
34
34
  npx ddd-ts-kit generate route billing IssueInvoice --method POST --path /invoices
35
35
  npx ddd-ts-kit check
36
36
  ```
@@ -642,12 +642,12 @@ Next, in this order: the language of the context first, then the business decisi
642
642
  | `domain-service` | `<context> <Name>` | service, *spec* |
643
643
  | `state-machine` | `<context> <Aggregate> [--value <state>]... [--transition "<intention>:<from>[,<from>]...[><to>]"]...` | le vocabulaire `<Aggregate>Status` (créé depuis `--value`, deux états au moins, ou complété des valeurs qui lui manquent), `domain/state-machines/<aggregate>.state-machine.ts` (`<aggregate>Lifecycle` : chaque valeur un état, la première initiale, les transitions demandées, un `TODO(domain)` pour le refus de l'erreur du concept) et `test/unit/<aggregate>.state-machine.spec.ts` (chaque transition là où elle mène, un refus depuis un état qu'elle ne quitte pas) ; c'est à l'agrégat de l'utiliser |
644
644
  | `repository` | `<context> <Aggregate> [--tenant-scoped]` | le port `domain/repositories/<name>.repository.ts` (`abstract class <Name>Repository extends Repository<<Name>>`), l'adaptateur de l'ORM du projet (qui `implements` le port) avec son *mapper* et sa table (ou son modèle), un *fake*, une *spec* `repositoryContract` exécutée sur les deux, l'enregistrement |
645
- | `command` | `<context> <UseCaseName> (--permission <aggregate>.<action> \| --public) [--aggregate <Name>]` | `<use-case>.command.ts` sur `AuthorizedCommand` (simple `Command` quand elle est publique), `<use-case>.handler.ts` (il construit l'agrégat, le sauvegarde et répond : les événements partent avec la sauvegarde), une *spec* par le bus avec le refus d'un acteur à qui manque la permission, l'enregistrement avec `.requires(...)` ou `.public()` (et le *repository* s'il manque). Une commande générée répond `void` ou l'identifiant de son agrégat, si bien qu'aucun `<use-case>.result.ts` n'est écrit |
646
- | `query` | `<context> <UseCaseName> (--permission <aggregate>.<action> \| --public) [--search]` | `<use-case>.query.ts` sur `AuthorizedQuery` (simple `Query` quand elle est publique), `<use-case>.result.ts`, `<use-case>.handler.ts`, le port de lecture `application/ports/<use-case>-reader.port.ts` (une classe abstraite), son adaptateur en mémoire, un *fake*, une *spec*, l'enregistrement sur le bus de requêtes. Avec `--search` (demande `--permission`) : une `PageRequest` du kernel dans la requête, l'élément, le tri et `Page<Item>` dans le fichier de résultat, un gestionnaire qui demande `Access.scope` et remet le périmètre au port de lecture, un lecteur en mémoire qui pagine par décalage ou par curseur |
645
+ | `command` | `<context> <UseCaseName> (--permission <aggregate>.<action> [--grant <role>] \| --public) [--aggregate <Name>]` | `<use-case>.command.ts` sur `AuthorizedCommand` (simple `Command` quand elle est publique), `<use-case>.handler.ts` (il construit l'agrégat, le sauvegarde et répond : les événements partent avec la sauvegarde), une *spec* par le bus avec le refus d'un acteur à qui manque la permission, l'enregistrement avec `.requires(...)` ou `.public()` (et le *repository* s'il manque). Une commande générée répond `void` ou l'identifiant de son agrégat, si bien qu'aucun `<use-case>.result.ts` n'est écrit |
646
+ | `query` | `<context> <UseCaseName> (--permission <aggregate>.<action> [--grant <role>] \| --public) [--search]` | `<use-case>.query.ts` sur `AuthorizedQuery` (simple `Query` quand elle est publique), `<use-case>.result.ts`, `<use-case>.handler.ts`, le port de lecture `application/ports/<use-case>-reader.port.ts` (une classe abstraite), son adaptateur en mémoire, un *fake*, une *spec*, l'enregistrement sur le bus de requêtes. Avec `--search` (demande `--permission`) : une `PageRequest` du kernel dans la requête, l'élément, le tri et `Page<Item>` dans le fichier de résultat, un gestionnaire qui demande `Access.scope` et remet le périmètre au port de lecture, un lecteur en mémoire qui pagine par décalage ou par curseur |
647
647
  | `port` | `<context> <Name>` | `application/ports/<name>.port.ts`, une classe abstraite, et son *fake* |
648
648
  | `route` | `<context> <UseCaseName> --method <GET\|POST\|PUT\|PATCH\|DELETE> --path <p> [--command\|--query] [--group <Name>] [--mapper] [--serializer] [--cache public\|private\|no-store]` | sous `"stack.routes": "controllers"` : une classe contrôleur dans `presentation/http/<resource>/<use-case>/` (la ressource est le premier segment du chemin), qui dépend de `CommandBus` ou de `QueryBus`, derrière le groupe de routes de sa ressource, écrit avec elle quand il est nouveau (`<resource>.routes.ts` : préfixe, étiquette, `Authenticated`) ; un cas d'usage public ne se tient dans aucun groupe et dit `guards: [Public]` ; avec class-validator, une classe par fichier (`<use-case>.params.ts`, `.body.ts`, `.answer.ts`, `.accepted.ts`, `.line.ts`) ; `--mapper` et `--serializer` ajoutent un *mapper* de requête HTTP et un sérialiseur que reçoit le contrôleur ; une *spec* ; aucun enregistrement dans un projet déclaré, un contrôleur construit à la main dans `<context>.routes.ts` (le fichier de module en câblage manuel) dans un projet explicite. Sous `"functions"` : une fonction `defineRoute`, sa *spec*, son enregistrement dans `<context>.routes.ts`, et des classes `<use-case>-<role>.dto.ts` |
649
649
  | `controller` | les mêmes arguments que `route` | la classe contrôleur, quoi que dise `stack.routes` : pour un projet de routes en fonctions qui écrit sa prochaine route comme une classe. `--cache` écrit sa politique de cache : `private` (un `GET` d'un appelant, `max-age=0`, `must-revalidate`, `ETag` fort), `public` (un `GET` d'un cas d'usage public, `max-age` 1m, `s-maxage` 5m, étiqueté avec les ressources de son chemin), `no-store` ; refusé sur une écriture, et `public` derrière un groupe de routes |
650
- | `file-upload` | `<context> <UseCaseName> --path <p> (--permission <aggregate>.<action> \| --public) [--method POST\|PUT] [--group <Name>]` | un téléversement : un contrôleur qui déclare le fichier qu'il reçoit (sa taille et ses types de média dans le contrat, vérifiés au fil du flux), la commande qui le porte comme un `FileUpload`, mis en attente par le bus de commandes avant la transaction, le gestionnaire qui l'enregistre et le promeut avec la validation (commit), et leurs *specs*. Refusé sans `stack.storage` ou sans *stack* HTTP, avec le `init --force --storage local` à lancer |
650
+ | `file-upload` | `<context> <UseCaseName> --path <p> (--permission <aggregate>.<action> [--grant <role>] \| --public) [--method POST\|PUT] [--group <Name>]` | un téléversement : un contrôleur qui déclare le fichier qu'il reçoit (sa taille et ses types de média dans le contrat, vérifiés au fil du flux), la commande qui le porte comme un `FileUpload`, mis en attente par le bus de commandes avant la transaction, le gestionnaire qui l'enregistre et le promeut avec la validation (commit), et leurs *specs*. Refusé sans `stack.storage` ou sans *stack* HTTP, avec le `init --force --storage local` à lancer |
651
651
  | `route-group` (`group`) | `<context> <Name> [--prefix <path>] [--group <ParentName>] [--public \| --role <role>]` | `presentation/http/<name>.routes.ts` : une classe vide qui porte `@RouteGroup`, derrière `Authenticated` sauf si `--public` ou `--role` dit autre chose (`HasRole(Role.Admin)`, le rôle lu dans le vocabulaire de la plateforme, `<platformDir>/auth/role.ts`, qui le reçoit s'il ne le contient pas) ; avec `--group`, il affine ce groupe et en hérite |
652
652
  | `guard` | `<context> <Name>` | `presentation/http/guards/<name>.guard.ts` : une classe de garde déclarée à remplir, et sa *spec* |
653
653
  | `representation` | `<context> <UseCase> <xml\|csv\|media/type>[,...]` | ajoute `produces` au `@Controller` du cas d'usage, et `consumes: ['application/xml']` à celui qui reçoit un corps quand XML est demandé ; dit quand CSV a besoin d'une page ou d'une liste en flux, et quand `stack.representations` n'est pas `negotiated` |
@@ -739,7 +739,10 @@ Next, in this order: the language of the context first, then the business decisi
739
739
  - **Refus par défaut.** `command` et `query` sont refusés sans `--permission` ou `--public`. Une
740
740
  nouvelle permission rejoint `<context>.permissions.ts` ; ses mots sont vérifiés dans le
741
741
  glossaire comme tout autre nom. Avec `--authz rebac`, l'exigence nomme le contexte comme sa
742
- ressource, un point de départ à remplacer par l'élément sur lequel porte le droit.
742
+ ressource, un point de départ à remplacer par l'élément sur lequel porte le droit. Avec
743
+ `--authz rbac`, `--grant <role>` accorde la permission au rôle dans `platform/auth/roles.ts`
744
+ (le rôle rejoint `role.ts` s'il est nouveau) ; sans lui, une étape `next` dit que
745
+ l'attribution reste à faire (`authz/granted`).
743
746
  - `route` remet `actorOf(context.principal)` à un cas d'usage protégé et pose `security` (le
744
747
  schéma de `--authn`, ou `false` pour un cas d'usage public). `integration-handler` porte
745
748
  `systemActor('<context>.<name>')` pour la commande qu'il construit ; derrière un *broker*, il
@@ -1291,6 +1294,7 @@ règle.
1291
1294
  | `config/valid` | un amont, une classification, une relation, un identifiant de règle, un mode de `guard` ou un `importExtension` inconnu ; un contexte absent du disque ou de la configuration ; une limite de `commit` qui n'est pas un entier positif |
1292
1295
  | `config/suppression-needs-reason` | une désactivation sans identifiant de règle ou sans raison (gardée comme alias à côté de `governance/recorded-deviation`, qui juge la raison) |
1293
1296
  | `authz/declared` | dans un fichier de module, `builder.command(X)` ou `builder.query(X)` sans `.requires(` ni `.public(` dans sa chaîne, sauf si la classe du message porte `@Requires` ou `@Public` de `@ddd-ts-kit/kernel/declarations` ; en câblage manuel ou nest, une classe de commande ou de requête absente de tous les `requires(X, ...)` et `publicUseCase(X)` du fichier de module et de `application/authorization/` ; un `defineRoute` sans `security` (le type de la route le refuse déjà, et une liste vide aussi : c'est le filet au niveau du texte pour une définition construite de façon lâche) ; dans le style déclaré, la classe exportée d'un fichier `*.command.ts` ou `*.query.ts` qui ne porte ni `@Requires` ni `@Public` |
1297
+ | `authz/granted` | avec `stack.authz` `rbac`, une permission du `definePermissions` d'un contexte que ni `platform/auth/roles.ts` ni `platform/auth/signed-in-grants.ts` n'accorde par son nom (par l'entrée de son ensemble, son identifiant ou `<contexte>:*`) ; le `*` du super-administrateur ne compte pas (un avertissement) |
1294
1298
  | `authz/in-application` | `presentation/` : un test sur les rôles, `isAdmin`, l'import d'un autorisateur ou de `Access` ; `infrastructure/` : `authorize(` ou `check(` sur un autorisateur ou un accès, `ForbiddenError` ; `domain/` : tout import de `@ddd-ts-kit/auth`, des types d'acteur du kernel (`Actor`, `ActorContext`, `Session`, `ExecutionContext`, les messages autorisés), une lecture de `.roles` ou `.permissions` sur un acteur. La glu de requête HTTP de `@ddd-ts-kit/auth` (`actorOf`, `sessionOf`, `resolveSession`, `SessionAuthenticator`) est libre dans `presentation/`. `presentation/` et `infrastructure/` : l'import de `Requires`, `Public` ou `Policy` depuis `@ddd-ts-kit/kernel/declarations`, ou des ports `Access` et `PolicyAccess` depuis `@ddd-ts-kit/auth` ; ils sont libres dans `application/` |
1295
1299
  | `authz/actor-explicit` | dans `domain/` et `application/` : `ActorContext`, `ExecutionScope` (comme type ou comme valeur : la classe est le jeton d'une liste de dépendances), `AsyncLocalStorageExecutionScope`, `ScopedActorContext`, `AsyncLocalStorage` ; `.current()` ou `.require()` sur un contexte d'acteur ou sur quelque chose nommé `scope`, `scopes` ou `...executionScope` ; un import de `stampCreation`, `stampUpdate` ou `tenantScopeOf` |
1296
1300
  | `authz/fields-by-schema` | sous `application/queries/` : `roles.includes(`, `.some(`, `.every(`, `.find(`, `.indexOf(`, une comparaison avec un `role`, `isAdmin` |
package/README.md CHANGED
@@ -28,7 +28,7 @@ No runtime dependency. Node 22.12 or later.
28
28
  npx ddd-ts-kit init
29
29
  npx ddd-ts-kit generate context billing --classification core --term "Invoice=A request for payment"
30
30
  npx ddd-ts-kit generate aggregate billing Invoice
31
- npx ddd-ts-kit generate command billing IssueInvoice --aggregate Invoice --permission invoice.issue --term "Issue=To make an invoice final"
31
+ npx ddd-ts-kit generate command billing IssueInvoice --aggregate Invoice --permission invoice.issue --grant accountant --term "Issue=To make an invoice final"
32
32
  npx ddd-ts-kit generate route billing IssueInvoice --method POST --path /invoices
33
33
  npx ddd-ts-kit check
34
34
  ```
@@ -622,12 +622,12 @@ Next, in this order: the language of the context first, then the business decisi
622
622
  | `domain-service` | `<context> <Name>` | service, spec |
623
623
  | `state-machine` | `<context> <Aggregate> [--value <state>]... [--transition "<intention>:<from>[,<from>]...[><to>]"]...` | the vocabulary `<Aggregate>Status` (created from `--value`, two states at least, or given the values it misses), `domain/state-machines/<aggregate>.state-machine.ts` (`<aggregate>Lifecycle`: every value a state, the first one initial, the transitions asked, a `TODO(domain)` for the refusal of the concept error) and `test/unit/<aggregate>.state-machine.spec.ts` (each transition where it leads, a refusal from a state it does not leave); the aggregate is left to use it |
624
624
  | `repository` | `<context> <Aggregate> [--tenant-scoped]` | the port `domain/repositories/<name>.repository.ts` (`abstract class <Name>Repository extends Repository<<Name>>`), the adapter of the project's ORM (`implements` the port) with its mapper and table (or model), a fake, one `repositoryContract` spec run on both, registration |
625
- | `command` | `<context> <UseCaseName> (--permission <aggregate>.<action> \| --public) [--aggregate <Name>]` | `<use-case>.command.ts` on `AuthorizedCommand` (plain `Command` when public), `<use-case>.handler.ts` (it builds the aggregate, saves it and answers: the events leave with the save), spec through the bus with the refusal of an actor who lacks the permission, registration with `.requires(...)` or `.public()` (and the repository when missing). A generated command answers `void` or the identifier of its aggregate, so no `<use-case>.result.ts` is written |
626
- | `query` | `<context> <UseCaseName> (--permission <aggregate>.<action> \| --public) [--search]` | `<use-case>.query.ts` on `AuthorizedQuery` (plain `Query` when public), `<use-case>.result.ts`, `<use-case>.handler.ts`, the read port `application/ports/<use-case>-reader.port.ts` (an abstract class), its in-memory adapter, fake, spec, registration on the query bus. With `--search` (needs `--permission`): a kernel `PageRequest` in the query, the item, the sort and `Page<Item>` in the result file, a handler that asks `Access.scope` and hands the scope to the read port, an in-memory reader paging by offset or cursor |
625
+ | `command` | `<context> <UseCaseName> (--permission <aggregate>.<action> [--grant <role>] \| --public) [--aggregate <Name>]` | `<use-case>.command.ts` on `AuthorizedCommand` (plain `Command` when public), `<use-case>.handler.ts` (it builds the aggregate, saves it and answers: the events leave with the save), spec through the bus with the refusal of an actor who lacks the permission, registration with `.requires(...)` or `.public()` (and the repository when missing). A generated command answers `void` or the identifier of its aggregate, so no `<use-case>.result.ts` is written |
626
+ | `query` | `<context> <UseCaseName> (--permission <aggregate>.<action> [--grant <role>] \| --public) [--search]` | `<use-case>.query.ts` on `AuthorizedQuery` (plain `Query` when public), `<use-case>.result.ts`, `<use-case>.handler.ts`, the read port `application/ports/<use-case>-reader.port.ts` (an abstract class), its in-memory adapter, fake, spec, registration on the query bus. With `--search` (needs `--permission`): a kernel `PageRequest` in the query, the item, the sort and `Page<Item>` in the result file, a handler that asks `Access.scope` and hands the scope to the read port, an in-memory reader paging by offset or cursor |
627
627
  | `port` | `<context> <Name>` | `application/ports/<name>.port.ts`, one abstract class, and its fake |
628
628
  | `route` | `<context> <UseCaseName> --method <GET\|POST\|PUT\|PATCH\|DELETE> --path <p> [--command\|--query] [--group <Name>] [--mapper] [--serializer] [--cache public\|private\|no-store]` | under `"stack.routes": "controllers"`: a controller class in `presentation/http/<resource>/<use-case>/` (the resource is the first segment of the path), depending on `CommandBus` or `QueryBus`, behind the route group of its resource, written with it when it is new (`<resource>.routes.ts`: prefix, tag, `Authenticated`); a public use case stands in no group and says `guards: [Public]`; with class-validator one class per file (`<use-case>.params.ts`, `.body.ts`, `.answer.ts`, `.accepted.ts`, `.line.ts`); `--mapper` and `--serializer` add a request mapper and a serializer the controller is given; a spec; no registration in a declared project, a controller built by hand in `<context>.routes.ts` (the module file with hand wiring) in an explicit one. Under `"functions"`: a `defineRoute` function, its spec, its registration in `<context>.routes.ts`, and `<use-case>-<role>.dto.ts` classes |
629
629
  | `controller` | the same arguments as `route` | the controller class, whatever `stack.routes` says: for a project of function routes that writes its next route as a class. `--cache` writes its cache policy: `private` (a `GET` of a caller, `max-age=0`, `must-revalidate`, strong `ETag`), `public` (a `GET` of a public use case, `max-age` 1m, `s-maxage` 5m, tagged with the resources of its path), `no-store`; refused on a write, and `public` behind a route group |
630
- | `file-upload` | `<context> <UseCaseName> --path <p> (--permission <aggregate>.<action> \| --public) [--method POST\|PUT] [--group <Name>]` | an upload: a controller that declares the file it receives (its size and media types in the contract, checked as it streams), the command that carries it as a `FileUpload`, staged by the command bus before the transaction, the handler that records it and promotes it with the commit, and their specs. Refused without `stack.storage` or without an HTTP stack, with the `init --force --storage local` to run |
630
+ | `file-upload` | `<context> <UseCaseName> --path <p> (--permission <aggregate>.<action> [--grant <role>] \| --public) [--method POST\|PUT] [--group <Name>]` | an upload: a controller that declares the file it receives (its size and media types in the contract, checked as it streams), the command that carries it as a `FileUpload`, staged by the command bus before the transaction, the handler that records it and promotes it with the commit, and their specs. Refused without `stack.storage` or without an HTTP stack, with the `init --force --storage local` to run |
631
631
  | `route-group` (`group`) | `<context> <Name> [--prefix <path>] [--group <ParentName>] [--public \| --role <role>]` | `presentation/http/<name>.routes.ts`: an empty class carrying `@RouteGroup`, behind `Authenticated` unless `--public` or `--role` says otherwise (`HasRole(Role.Admin)`, the role read from the vocabulary of the platform, `<platformDir>/auth/role.ts`, which gets it when it does not hold it); with `--group` it refines that group and inherits from it |
632
632
  | `guard` | `<context> <Name>` | `presentation/http/guards/<name>.guard.ts`: a declared guard class to fill, and its spec |
633
633
  | `representation` | `<context> <UseCase> <xml\|csv\|media/type>[,...]` | adds `produces` to the `@Controller` of the use case, and `consumes: ['application/xml']` to one that receives a body when XML is asked; says when CSV needs a page or a streamed list, and when `stack.representations` is not `negotiated` |
@@ -713,7 +713,9 @@ Next, in this order: the language of the context first, then the business decisi
713
713
  - **Deny by default.** `command` and `query` are refused without `--permission` or `--public`. A new
714
714
  permission joins `<context>.permissions.ts`; its words are checked against the glossary like any
715
715
  other name. With `--authz rebac` the requirement names the context as its resource, a starting
716
- point to replace by the element the right bears on.
716
+ point to replace by the element the right bears on. With `--authz rbac`, `--grant <role>` gives
717
+ the permission to the role in `platform/auth/roles.ts` (the role joins `role.ts` when it is
718
+ new); without it, a `next` step says the grant is left to do (`authz/granted`).
717
719
  - `route` hands `actorOf(context.principal)` to a protected use case and sets `security` (the scheme
718
720
  of `--authn`, or `false` for a public one). `integration-handler` carries `systemActor('<context>.<name>')`
719
721
  for the command it builds; behind a broker it listens on the subscriber of its context
@@ -1234,6 +1236,7 @@ const due = handler.isDueNow(new Reminder(new Date('2026-03-01T09:00:00Z'))); //
1234
1236
  | `config/valid` | unknown upstream, classification, relationship, rule id, `guard` mode or `importExtension`; a context missing on disk or in the config; a `commit` limit that is not a positive integer |
1235
1237
  | `config/suppression-needs-reason` | a suppression without a rule id or a reason (kept as an alias next to `governance/recorded-deviation`, which judges the reason) |
1236
1238
  | `authz/declared` | in a module file, `builder.command(X)` or `builder.query(X)` without `.requires(` or `.public(` in its chain, unless the message class carries `@Requires` or `@Public` of `@ddd-ts-kit/kernel/declarations`; with manual or nest wiring, a command or query class absent from every `requires(X, ...)` and `publicUseCase(X)` of the module file and of `application/authorization/`; a `defineRoute` without `security` (the route type refuses it already, and an empty list too: this is the text-level net for a definition built loosely); in the declared style, the exported class of a `*.command.ts` or `*.query.ts` file carrying neither `@Requires` nor `@Public` |
1239
+ | `authz/granted` | with `stack.authz` `rbac`, a permission of a context's `definePermissions` that neither `platform/auth/roles.ts` nor `platform/auth/signed-in-grants.ts` grants by name (by the entry of its set, its id or `<context>:*`); the super-admin `*` does not count (a warning) |
1237
1240
  | `authz/in-application` | `presentation/`: a test on roles, `isAdmin`, the import of an authorizer or of `Access`; `infrastructure/`: `authorize(` or `check(` on an authorizer or access, `ForbiddenError`; `domain/`: any import of `@ddd-ts-kit/auth`, of the actor types of the kernel (`Actor`, `ActorContext`, `Session`, `ExecutionContext`, the authorized messages), a read of `.roles` or `.permissions` on an actor. The request glue of `@ddd-ts-kit/auth` (`actorOf`, `sessionOf`, `resolveSession`, `SessionAuthenticator`) is free in `presentation/`. `presentation/` and `infrastructure/`: the import of `Requires`, `Public` or `Policy` from `@ddd-ts-kit/kernel/declarations`, or of the ports `Access` and `PolicyAccess` from `@ddd-ts-kit/auth`; they are free in `application/` |
1238
1241
  | `authz/actor-explicit` | in `domain/` and `application/`: `ActorContext`, `ExecutionScope` (as a type or as a value: the class is the token of a dependency list), `AsyncLocalStorageExecutionScope`, `ScopedActorContext`, `AsyncLocalStorage`; `.current()` or `.require()` on an actor context or on something named `scope`, `scopes` or `...executionScope`; an import of `stampCreation`, `stampUpdate` or `tenantScopeOf` |
1239
1242
  | `authz/fields-by-schema` | under `application/queries/`: `roles.includes(`, `.some(`, `.every(`, `.find(`, `.indexOf(`, a comparison with a `role`, `isAdmin` |
@@ -0,0 +1,8 @@
1
+ import type { Scan } from '../scan/scan.js';
2
+ import type { PermissionSet } from './permission-sets.js';
3
+ /**
4
+ * Whether code grants a permission by name: by the entry of its set, `billingPermissions['invoice.issue']`;
5
+ * by its id, `'billing:invoice.issue'`; or by the wildcard of its context, `'billing:*'`. A comment grants nothing.
6
+ */
7
+ export declare function isGranted({ code, strings }: Scan, { set, context }: Omit<PermissionSet, 'keys'>, key: string): boolean;
8
+ //# sourceMappingURL=is-granted.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-granted.d.ts","sourceRoot":"","sources":["../../../src/check/authz/is-granted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,SAAS,CACvB,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EACvB,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,EAC7C,GAAG,EAAE,MAAM,GACV,OAAO,CAST"}
@@ -0,0 +1,11 @@
1
+ import { escapeRegExp } from '../text/escape-reg-exp.js';
2
+ /**
3
+ * Whether code grants a permission by name: by the entry of its set, `billingPermissions['invoice.issue']`;
4
+ * by its id, `'billing:invoice.issue'`; or by the wildcard of its context, `'billing:*'`. A comment grants nothing.
5
+ */
6
+ export function isGranted({ code, strings }, { set, context }, key) {
7
+ const ids = new Set([`${context}:${key}`, `${context}:*`]);
8
+ const entries = [...code.matchAll(new RegExp(`(?<![\\w$.])${escapeRegExp(set)}\\s*\\[\\s*`, 'g'))];
9
+ return (entries.some((entry) => strings.some(({ start, value }) => start === entry.index + entry[0].length && value === key)) || strings.some(({ value }) => ids.has(value)));
10
+ }
11
+ //# sourceMappingURL=is-granted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-granted.js","sourceRoot":"","sources":["../../../src/check/authz/is-granted.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD;;;GAGG;AACH,MAAM,UAAU,SAAS,CACvB,EAAE,IAAI,EAAE,OAAO,EAAQ,EACvB,EAAE,GAAG,EAAE,OAAO,EAA+B,EAC7C,GAAW;IAEX,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,IAAI,GAAG,EAAE,EAAE,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,eAAe,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAEnG,OAAO,CACL,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACrB,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,KAAK,GAAG,CAAC,CAC7F,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CACjD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { SourceFile } from '../model/source-file.js';
2
+ import type { StringRecord } from '../scan/string-record.js';
3
+ /** `export const billingPermissions = definePermissions('billing', { 'invoice.issue': .. })`, as the checker reads it. */
4
+ export interface PermissionSet {
5
+ /** The name code reads the set by: `billingPermissions`. */
6
+ readonly set: string;
7
+ readonly context: string;
8
+ /** The key of each permission, where it is written. */
9
+ readonly keys: readonly StringRecord[];
10
+ }
11
+ /** The permission sets a file declares, each with the keys of its first level. */
12
+ export declare function permissionSets(file: SourceFile): PermissionSet[];
13
+ //# sourceMappingURL=permission-sets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-sets.d.ts","sourceRoot":"","sources":["../../../src/check/authz/permission-sets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAM7D,0HAA0H;AAC1H,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;CACxC;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,aAAa,EAAE,CAqBhE"}
@@ -0,0 +1,19 @@
1
+ import { depthAt } from '../text/depth-at.js';
2
+ import { matchingBracket } from '../text/matching-bracket.js';
3
+ const PERMISSION_SET = /export\s+const\s+([a-z][\w$]*)\s*=\s*definePermissions\(\s*/g;
4
+ /** The permission sets a file declares, each with the keys of its first level. */
5
+ export function permissionSets(file) {
6
+ const { code, strings } = file.scan;
7
+ return [...code.matchAll(PERMISSION_SET)].flatMap((found) => {
8
+ const at = found.index + found[0].length;
9
+ const context = strings.find(({ start }) => start === at)?.value;
10
+ const open = code.indexOf('{', at);
11
+ if (context === undefined || open === -1) {
12
+ return [];
13
+ }
14
+ const close = matchingBracket(code, open);
15
+ const keys = strings.filter(({ start, end }) => start > open && end < close && /^\s*:/.test(code.slice(end)) && depthAt(code, open, start) === 1);
16
+ return [{ set: found[1] ?? '', context, keys }];
17
+ });
18
+ }
19
+ //# sourceMappingURL=permission-sets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-sets.js","sourceRoot":"","sources":["../../../src/check/authz/permission-sets.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,cAAc,GAAG,8DAA8D,CAAC;AAWtF,kFAAkF;AAClF,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;IAEpC,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1D,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAEnC,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;YACzC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CACzB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CACjB,KAAK,GAAG,IAAI,IAAI,GAAG,GAAG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CACnG,CAAC;QAEF,OAAO,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"architecture-rules.d.ts","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAoF7C,gHAAgH;AAChH,eAAO,MAAM,kBAAkB,EAAE,SAAS,IAAI,EAmF7C,CAAC"}
1
+ {"version":3,"file":"architecture-rules.d.ts","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAqF7C,gHAAgH;AAChH,eAAO,MAAM,kBAAkB,EAAE,SAAS,IAAI,EAoF7C,CAAC"}
@@ -2,6 +2,7 @@ import { aspectsOutsideIn } from '../rules/aspects-outside-in.js';
2
2
  import { authzActorExplicit } from '../rules/authz-actor-explicit.js';
3
3
  import { authzFieldsBySchema } from '../rules/authz-fields-by-schema.js';
4
4
  import { authzDeclared } from '../rules/authz-declared.js';
5
+ import { authzGranted } from '../rules/authz-granted.js';
5
6
  import { authzInApplication } from '../rules/authz-in-application.js';
6
7
  import { authzPolicyAsked } from '../rules/authz-policy-asked.js';
7
8
  import { cleanBlankLines } from '../rules/clean-blank-lines.js';
@@ -138,6 +139,7 @@ export const ARCHITECTURE_RULES = [
138
139
  authzActorExplicit,
139
140
  authzFieldsBySchema,
140
141
  authzPolicyAsked,
142
+ authzGranted,
141
143
  aspectsOutsideIn,
142
144
  tracingPlatformOnly,
143
145
  tenancyScopedStatement,
@@ -1 +1 @@
1
- {"version":3,"file":"architecture-rules.js","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"architecture-rules.js","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"default-severities.d.ts","sourceRoot":"","sources":["../../../src/check/catalogue/default-severities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,0GAA0G;AAC1G,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAQjE,CAAC"}
1
+ {"version":3,"file":"default-severities.d.ts","sourceRoot":"","sources":["../../../src/check/catalogue/default-severities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,0GAA0G;AAC1G,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CASjE,CAAC"}
@@ -1,5 +1,6 @@
1
1
  /** Rules that advise instead of blocking unless the config says otherwise (ARCHITECTURE.md section 3). */
2
2
  export const DEFAULT_SEVERITIES = {
3
+ 'authz/granted': 'warn',
3
4
  'test/no-mocks': 'warn',
4
5
  'test/builder-required': 'warn',
5
6
  'clean/function-size': 'warn',
@@ -1 +1 @@
1
- {"version":3,"file":"default-severities.js","sourceRoot":"","sources":["../../../src/check/catalogue/default-severities.ts"],"names":[],"mappings":"AAEA,0GAA0G;AAC1G,MAAM,CAAC,MAAM,kBAAkB,GAAuC;IACpE,eAAe,EAAE,MAAM;IACvB,uBAAuB,EAAE,MAAM;IAC/B,qBAAqB,EAAE,MAAM;IAC7B,wBAAwB,EAAE,MAAM;IAChC,wBAAwB,EAAE,MAAM;IAChC,sCAAsC,EAAE,MAAM;IAC9C,gCAAgC,EAAE,MAAM;CACzC,CAAC"}
1
+ {"version":3,"file":"default-severities.js","sourceRoot":"","sources":["../../../src/check/catalogue/default-severities.ts"],"names":[],"mappings":"AAEA,0GAA0G;AAC1G,MAAM,CAAC,MAAM,kBAAkB,GAAuC;IACpE,eAAe,EAAE,MAAM;IACvB,eAAe,EAAE,MAAM;IACvB,uBAAuB,EAAE,MAAM;IAC/B,qBAAqB,EAAE,MAAM;IAC7B,wBAAwB,EAAE,MAAM;IAChC,wBAAwB,EAAE,MAAM;IAChC,sCAAsC,EAAE,MAAM;IAC9C,gCAAgC,EAAE,MAAM;CACzC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"authz-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqExD,CAAC"}
1
+ {"version":3,"file":"authz-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoFxD,CAAC"}
@@ -27,6 +27,21 @@ await this.access.authorize(command.actor, billingPermissions['invoice.void'], i
27
27
  // application/authorization/only-issuer-voids.policy.ts
28
28
  @Policy(billingPermissions['invoice.void'], { name: 'billing.only-issuer-voids' })
29
29
  export class OnlyIssuerVoidsPolicy {}`,
30
+ },
31
+ 'authz/granted': {
32
+ why: "In a project whose rights are roles (stack.authz rbac), a permission does two things: a use case requires it, and a role holds it. The generator declares the first; the grant lives in the roles of the platform. The super-admin holds the wildcard `*`, so a permission no role names is reachable by administrators only, the checks stay green and the people the use case was written for are refused at run time. It fails closed, which is safe, but silently. Judged: every key of every `definePermissions` set of a context is named in `<platformDir>/auth/roles.ts` or in what every signed-in person holds (`signed-in-grants.ts`, which a context preset writes), by the entry of its set (`billingPermissions['invoice.issue']`), by its id (`'billing:invoice.issue'`) or by the wildcard of its context (`'billing:*'`); the bare `*` does not count, and a grant to `Role.System` does. A permission meant for administrators only is granted to `Role.Admin` by name, so that the intent is read in review. Silent when the rights are attributes, relationships or an authorizer of the project, and when the platform has no roles file. A warning: it fails closed.",
33
+ bad: `// contexts/billing/application/authorization/billing.permissions.ts
34
+ export const billingPermissions = definePermissions('billing', {
35
+ 'invoice.void': { description: 'Void invoice' },
36
+ });
37
+ // platform/auth/roles.ts
38
+ export const roles = { [Role.Admin]: ['*'] };`,
39
+ good: `// platform/auth/roles.ts
40
+ export const roles = {
41
+ [Role.Admin]: ['*'],
42
+ [Role.Accountant]: [billingPermissions['invoice.void']],
43
+ };
44
+ // or, when generating the use case: --permission invoice.void --grant accountant`,
30
45
  },
31
46
  'authz/policy-asked': {
32
47
  why: 'The bus checks the permission of a use case before its handler runs, with the identifier of the element at most: it cannot read the element. A policy is the part of the right that needs the element (only the issuer, not after closing), and it is evaluated only when the handler asks Access once the element is loaded. A handler that forgets to ask leaves the policy declared, tested and never applied, and nothing at run time says so. Judged: for every permission refined by a policy (@Policy or definePolicy in application/authorization/), the handlers in the folder of each command or query that requires it (@Requires, .requires(...) or requires(X, ...)) call authorize, decide or decideOn and name that permission in their code. The TODO(domain) the generator leaves in such a handler, naming the permission, is accepted: `ddd-ts-kit todo` lists it, and until it is done the authorization module refuses the result of the handler at run time (PolicyNotAskedError).',
@@ -1 +1 @@
1
- {"version":3,"file":"authz-docs.js","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsC;IAC3D,gBAAgB,EAAE;QAChB,GAAG,EAAE,mvBAAmvB;QACxvB,GAAG,EAAE;;;mEAG0D;QAC/D,IAAI,EAAE;;;;;mEAKyD;KAChE;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,q0BAAq0B;QAC10B,GAAG,EAAE;;;;;4DAKmD;QACxD,IAAI,EAAE;;;;;;sCAM4B;KACnC;IACD,oBAAoB,EAAE;QACpB,GAAG,EAAE,08BAA08B;QAC/8B,GAAG,EAAE;;;;;gCAKuB;QAC5B,IAAI,EAAE;;;gCAGsB;KAC7B;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,ykBAAykB;QAC9kB,GAAG,EAAE;;;;qDAI4C;QACjD,IAAI,EAAE;;;;;2GAKiG;KACxG;IACD,wBAAwB,EAAE;QACxB,GAAG,EAAE,i1BAAi1B;QACt1B,GAAG,EAAE;;+FAEsF;QAC3F,IAAI,EAAE;;;;;IAKN;KACD;CACF,CAAC"}
1
+ {"version":3,"file":"authz-docs.js","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsC;IAC3D,gBAAgB,EAAE;QAChB,GAAG,EAAE,mvBAAmvB;QACxvB,GAAG,EAAE;;;mEAG0D;QAC/D,IAAI,EAAE;;;;;mEAKyD;KAChE;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,q0BAAq0B;QAC10B,GAAG,EAAE;;;;;4DAKmD;QACxD,IAAI,EAAE;;;;;;sCAM4B;KACnC;IACD,eAAe,EAAE;QACf,GAAG,EAAE,4nCAA4nC;QACjoC,GAAG,EAAE;;;;;8CAKqC;QAC1C,IAAI,EAAE;;;;;kFAKwE;KAC/E;IACD,oBAAoB,EAAE;QACpB,GAAG,EAAE,08BAA08B;QAC/8B,GAAG,EAAE;;;;;gCAKuB;QAC5B,IAAI,EAAE;;;gCAGsB;KAC7B;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,ykBAAykB;QAC9kB,GAAG,EAAE;;;;qDAI4C;QACjD,IAAI,EAAE;;;;;2GAKiG;KACxG;IACD,wBAAwB,EAAE;QACxB,GAAG,EAAE,i1BAAi1B;QACt1B,GAAG,EAAE;;+FAEsF;QAC3F,IAAI,EAAE;;;;;IAKN;KACD;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Fixture } from './fixture.js';
2
+ export declare const AUTHZ_GRANTED_FIXTURES: readonly Fixture[];
3
+ //# sourceMappingURL=authz-granted-fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authz-granted-fixtures.d.ts","sourceRoot":"","sources":["../../../src/check/fixtures/authz-granted-fixtures.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AA+B5C,eAAO,MAAM,sBAAsB,EAAE,SAAS,OAAO,EAuDpD,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { CONFIG_FILE } from '../../config/index.js';
2
+ import { config } from './config.js';
3
+ import { PATHS } from './paths.js';
4
+ import { project } from './project.js';
5
+ import { source } from './source.js';
6
+ const { BILLING } = PATHS;
7
+ const PERMISSIONS = `${BILLING}/application/authorization/billing.permissions.ts`;
8
+ const ROLES = 'src/platform/auth/roles.ts';
9
+ const ROLE = 'src/platform/auth/role.ts';
10
+ const SIGNED_IN = 'src/platform/auth/signed-in-grants.ts';
11
+ const DECLARED = source("import { definePermissions } from '@ddd-ts-kit/auth';", '', "export const billingPermissions = definePermissions('billing', {", " 'invoice.issue': { description: 'Issue invoice' },", '});');
12
+ const ROLE_VOCABULARY = source('export const Role = {', " Admin: 'admin',", " Accountant: 'accountant',", '} as const;', '', 'export type Role = (typeof Role)[keyof typeof Role];');
13
+ const rule = 'authz/granted';
14
+ export const AUTHZ_GRANTED_FIXTURES = [
15
+ {
16
+ ruleId: rule,
17
+ name: 'a permission granted to a role by the entry of its set',
18
+ expect: 'pass',
19
+ files: granting("[Role.Accountant]: [billingPermissions['invoice.issue']],"),
20
+ },
21
+ {
22
+ ruleId: rule,
23
+ name: 'a permission granted through the wildcard of its context',
24
+ expect: 'pass',
25
+ files: granting("[Role.Accountant]: ['billing:*'],"),
26
+ },
27
+ {
28
+ ruleId: rule,
29
+ name: 'a permission granted by its id',
30
+ expect: 'pass',
31
+ files: granting("[Role.Accountant]: ['billing:invoice.issue'],"),
32
+ },
33
+ {
34
+ ruleId: rule,
35
+ name: 'a permission every signed-in person holds through the wildcard of its context',
36
+ expect: 'pass',
37
+ files: {
38
+ ...granting(),
39
+ [SIGNED_IN]: source('export const signedInGrants: readonly string[] = [', ' // ddd-ts-kit:signed-in-grants', " 'billing:*',", ' // /ddd-ts-kit:signed-in-grants', '];'),
40
+ },
41
+ },
42
+ {
43
+ ruleId: rule,
44
+ name: 'a permission no role names, in a project whose rights are attributes',
45
+ expect: 'pass',
46
+ files: {
47
+ ...granting(),
48
+ [CONFIG_FILE]: config({ stack: { authz: 'abac' } }),
49
+ },
50
+ },
51
+ {
52
+ ruleId: rule,
53
+ name: 'a permission only the super-admin wildcard reaches',
54
+ expect: { file: PERMISSIONS },
55
+ files: granting(),
56
+ },
57
+ {
58
+ ruleId: rule,
59
+ name: 'a permission granted in a comment only',
60
+ expect: { file: PERMISSIONS },
61
+ files: granting("// [Role.Accountant]: [billingPermissions['invoice.issue']],"),
62
+ },
63
+ ];
64
+ function granting(...grants) {
65
+ return project({ [PERMISSIONS]: DECLARED, [ROLE]: ROLE_VOCABULARY, [ROLES]: roles(...grants) });
66
+ }
67
+ /** A roles file of the platform whose grants are the lines given, after the super-admin. */
68
+ function roles(...grants) {
69
+ return source("import type { Grant } from '@ddd-ts-kit/auth';", "import { billingPermissions } from '@/contexts/billing/application/authorization/billing.permissions.js';", "import { Role } from '@/platform/auth/role.js';", '', 'export const roles: Readonly<Record<string, readonly Grant[]>> = {', " [Role.Admin]: ['*'],", ...grants.map((grant) => ` ${grant}`), '};', '', 'export const issuing = billingPermissions;');
70
+ }
71
+ //# sourceMappingURL=authz-granted-fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authz-granted-fixtures.js","sourceRoot":"","sources":["../../../src/check/fixtures/authz-granted-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;AAC1B,MAAM,WAAW,GAAG,GAAG,OAAO,mDAAmD,CAAC;AAClF,MAAM,KAAK,GAAG,4BAA4B,CAAC;AAC3C,MAAM,IAAI,GAAG,2BAA2B,CAAC;AACzC,MAAM,SAAS,GAAG,uCAAuC,CAAC;AAE1D,MAAM,QAAQ,GAAG,MAAM,CACrB,uDAAuD,EACvD,EAAE,EACF,kEAAkE,EAClE,sDAAsD,EACtD,KAAK,CACN,CAAC;AAEF,MAAM,eAAe,GAAG,MAAM,CAC5B,uBAAuB,EACvB,mBAAmB,EACnB,6BAA6B,EAC7B,aAAa,EACb,EAAE,EACF,sDAAsD,CACvD,CAAC;AAEF,MAAM,IAAI,GAAG,eAAe,CAAC;AAE7B,MAAM,CAAC,MAAM,sBAAsB,GAAuB;IACxD;QACE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,wDAAwD;QAC9D,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,QAAQ,CAAC,2DAA2D,CAAC;KAC7E;IACD;QACE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,0DAA0D;QAChE,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,QAAQ,CAAC,mCAAmC,CAAC;KACrD;IACD;QACE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,gCAAgC;QACtC,MAAM,EAAE,MAAM;QACd,KAAK,EAAE,QAAQ,CAAC,+CAA+C,CAAC;KACjE;IACD;QACE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,+EAA+E;QACrF,MAAM,EAAE,MAAM;QACd,KAAK,EAAE;YACL,GAAG,QAAQ,EAAE;YACb,CAAC,SAAS,CAAC,EAAE,MAAM,CACjB,oDAAoD,EACpD,kCAAkC,EAClC,gBAAgB,EAChB,mCAAmC,EACnC,IAAI,CACL;SACF;KACF;IACD;QACE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,sEAAsE;QAC5E,MAAM,EAAE,MAAM;QACd,KAAK,EAAE;YACL,GAAG,QAAQ,EAAE;YACb,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;SACpD;KACF;IACD;QACE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,oDAAoD;QAC1D,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;QAC7B,KAAK,EAAE,QAAQ,EAAE;KAClB;IACD;QACE,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,wCAAwC;QAC9C,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;QAC7B,KAAK,EAAE,QAAQ,CAAC,8DAA8D,CAAC;KAChF;CACF,CAAC;AAEF,SAAS,QAAQ,CAAC,GAAG,MAAyB;IAC5C,OAAO,OAAO,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;AAClG,CAAC;AAED,4FAA4F;AAC5F,SAAS,KAAK,CAAC,GAAG,MAAyB;IACzC,OAAO,MAAM,CACX,gDAAgD,EAChD,2GAA2G,EAC3G,iDAAiD,EACjD,EAAE,EACF,oEAAoE,EACpE,wBAAwB,EACxB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,EACtC,IAAI,EACJ,EAAE,EACF,4CAA4C,CAC7C,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../src/check/fixtures/fixtures.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,OAAO,EA0CtC,CAAC"}
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../src/check/fixtures/fixtures.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,SAAS,OAAO,EA2CtC,CAAC"}
@@ -2,6 +2,7 @@ import { ALIAS_DECLARED_FIXTURES } from './alias-declared-fixtures.js';
2
2
  import { BUSINESS_NAME_FIXTURES } from './business-name-fixtures.js';
3
3
  import { AUTHZ_DECLARED_FIXTURES } from './authz-declared-fixtures.js';
4
4
  import { AUTHZ_FIXTURES } from './authz-fixtures.js';
5
+ import { AUTHZ_GRANTED_FIXTURES } from './authz-granted-fixtures.js';
5
6
  import { AUTHZ_POLICY_FIXTURES } from './authz-policy-fixtures.js';
6
7
  import { CLEAN_FIXTURES } from './clean-fixtures.js';
7
8
  import { COMPOSITION_FIXTURES } from './composition-fixtures.js';
@@ -49,6 +50,7 @@ export const FIXTURES = [
49
50
  ...AUTHZ_DECLARED_FIXTURES,
50
51
  ...AUTHZ_FIXTURES,
51
52
  ...AUTHZ_POLICY_FIXTURES,
53
+ ...AUTHZ_GRANTED_FIXTURES,
52
54
  ...CLEAN_FIXTURES,
53
55
  ...COMPOSITION_FIXTURES,
54
56
  ...CONFIG_FIXTURES,
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../../src/check/fixtures/fixtures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../../src/check/fixtures/fixtures.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vocabulary-fixtures.d.ts","sourceRoot":"","sources":["../../../src/check/fixtures/vocabulary-fixtures.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAyC5C,eAAO,MAAM,mBAAmB,EAAE,SAAS,OAAO,EAwFjD,CAAC"}
1
+ {"version":3,"file":"vocabulary-fixtures.d.ts","sourceRoot":"","sources":["../../../src/check/fixtures/vocabulary-fixtures.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAyC5C,eAAO,MAAM,mBAAmB,EAAE,SAAS,OAAO,EA4FjD,CAAC"}
@@ -87,6 +87,8 @@ export const VOCABULARY_FIXTURES = [
87
87
  ruleId: rule,
88
88
  name: 'a role of the platform written in a file of the platform',
89
89
  expect: { file: GRANTS },
90
+ // This roles file grants nothing by name: the permission of billing is reached by no role.
91
+ also: ['authz/granted'],
90
92
  files: named({ [GRANTS]: raw('ISSUER', 'admin') }),
91
93
  },
92
94
  {
@@ -111,6 +113,8 @@ export const VOCABULARY_FIXTURES = [
111
113
  ruleId: rule,
112
114
  name: 'a value of a vocabulary of the shared kernel, in the platform',
113
115
  expect: { file: GRANTS },
116
+ // This roles file grants nothing by name: the permission of billing is reached by no role.
117
+ also: ['authz/granted'],
114
118
  files: named({ [GRANTS]: raw('PRICED_IN', 'EUR') }),
115
119
  },
116
120
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"vocabulary-fixtures.js","sourceRoot":"","sources":["../../../src/check/fixtures/vocabulary-fixtures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vocabulary-fixtures.js","sourceRoot":"","sources":["../../../src/check/fixtures/vocabulary-fixtures.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"declared-vocabularies.d.ts","sourceRoot":"","sources":["../../../src/check/language/declared-vocabularies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQzD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAU/F"}
1
+ {"version":3,"file":"declared-vocabularies.d.ts","sourceRoot":"","sources":["../../../src/check/language/declared-vocabularies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOzD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAU/F"}
@@ -1,10 +1,9 @@
1
- import { BRACKETS } from '../text/brackets.js';
1
+ import { permissionSets } from '../authz/permission-sets.js';
2
2
  import { matchingBracket } from '../text/matching-bracket.js';
3
3
  const AS_CONST = /export\s+const\s+([A-Z][\w$]*)\s*=\s*\{/g;
4
4
  const CONST_ASSERTION = /^\s*as\s+const\b/;
5
5
  const ENTRY = /^\s*(?:([A-Za-z_$][\w$]*)|#(\d+)#)\s*:\s*#(\d+)#\s*$/;
6
6
  const IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
7
- const PERMISSION_SET = /export\s+const\s+([a-z][\w$]*)\s*=\s*definePermissions\(\s*/g;
8
7
  /**
9
8
  * The closed vocabularies the project declares, by value: every object `as const` of string
10
9
  * values next to the union type of the same name (`export type AppointmentStatus = (typeof
@@ -69,31 +68,12 @@ function hasUnionType(text, name) {
69
68
  return new RegExp(`export\\s+type\\s+${name}\\s*=\\s*\\(\\s*typeof\\s+${name}\\s*\\)\\s*\\[\\s*keyof\\s+typeof\\s+${name}\\s*\\]`).test(text);
70
69
  }
71
70
  function permissionValues(file) {
72
- const { code, strings } = file.scan;
73
- return [...code.matchAll(PERMISSION_SET)].flatMap((found) => {
74
- const at = found.index + found[0].length;
75
- const context = strings.find(({ start }) => start === at)?.value;
76
- const open = code.indexOf('{', at);
77
- const close = matchingBracket(code, open);
78
- const keys = strings.filter(({ start, end }) => start > open && end < close && /^\s*:/.test(code.slice(end)) && depthAt(code, open, start) === 1);
79
- return context === undefined || open === -1
80
- ? []
81
- : keys.map(({ value: key }) => ({
82
- value: `${context}:${key}`,
83
- written: `${found[1] ?? ''}['${key}'].id`,
84
- vocabulary: found[1] ?? '',
85
- file: file.path,
86
- readBy: 'everywhere',
87
- }));
88
- });
89
- }
90
- /** How many brackets are open at an offset, counted from the one at `from`. */
91
- function depthAt(code, from, offset) {
92
- let depth = 0;
93
- for (let i = from; i < offset; i += 1) {
94
- const char = code.charAt(i);
95
- depth += BRACKETS.openers.includes(char) ? 1 : BRACKETS.closers.includes(char) ? -1 : 0;
96
- }
97
- return depth;
71
+ return permissionSets(file).flatMap(({ set, context, keys }) => keys.map(({ value: key }) => ({
72
+ value: `${context}:${key}`,
73
+ written: `${set}['${key}'].id`,
74
+ vocabulary: set,
75
+ file: file.path,
76
+ readBy: 'everywhere',
77
+ })));
98
78
  }
99
79
  //# sourceMappingURL=declared-vocabularies.js.map