@appxdigital/appx-core 0.1.121 → 0.1.122
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.
- package/CHANGELOG.md +8 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,12 @@ This project follows the `MAJOR.MINOR.PATCH` scheme in `package.json`.
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
+
## [0.1.122] — 2026-07-21
|
|
18
|
+
|
|
19
|
+
**No migration necessary.**
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
17
23
|
## [0.1.121] — 2026-07-14
|
|
18
24
|
|
|
19
25
|
Hardening release: request validation, boot configuration, generated-CRUD DTOs, and data-access create enforcement.
|
|
@@ -38,8 +44,7 @@ Hardening release: request validation, boot configuration, generated-CRUD DTOs,
|
|
|
38
44
|
- `src/generated/dto/<model>/<action>-<model>.generated.dto.ts` — base class, **always overwritten**, under the gitignored `src/generated/`. Never hand-edit.
|
|
39
45
|
- `src/modules/<model>/dto/<action>-<model>.dto.ts` — a hand-owned subclass, generated **once**, for custom validation. The controller imports this.
|
|
40
46
|
- **`/// @NoWrite` field annotation** — excludes a field from the generated create/update DTOs (all roles). Fields annotated `/// @Role(none)` are also treated as non-writable.
|
|
41
|
-
- **Create-permission enforcement in the data-access proxy.** `create` / `createMany` validate that the incoming data satisfies the permission's `conditions` before insert (own
|
|
42
|
-
- **`restrictedFields` on `create`** in `CoreController` (previously only `update`, which also read the wrong permission key so it never applied under `updateMany`).
|
|
47
|
+
- **Create-permission enforcement in the data-access proxy.** `create` / `createMany` validate that the incoming data satisfies the permission's `conditions` before insert (the model's **own scalar fields** — relationship authorization is handled by the `connect` action; see Migration), and default-deny when the model/role has no `create` permission. A development-only warning fires when a created row would not satisfy the model's `find` conditions.
|
|
43
48
|
|
|
44
49
|
### Writable-field policy (generated DTOs)
|
|
45
50
|
|
|
@@ -112,7 +117,7 @@ async create(@Body() data: Create<Model>Dto) { return super.create(data as any);
|
|
|
112
117
|
@Put(':id') @Permission('updateMany')
|
|
113
118
|
async update(@Param('id') id: string, @Body() data: Update<Model>Dto) { return super.update(id, data as any); }
|
|
114
119
|
```
|
|
115
|
-
(Or delete an un-customized controller and re-run `appx generate` for the new template.) Add custom validation in the hand-owned `dto/*.dto.ts` subclasses — never in the `.generated.dto.ts` base. Lock sensitive columns with `/// @NoWrite` (
|
|
120
|
+
(Or delete an un-customized controller and re-run `appx generate` for the new template.) Add custom validation in the hand-owned `dto/*.dto.ts` subclasses — never in the `.generated.dto.ts` base. Lock sensitive columns with `/// @NoWrite` / `/// @Role(none)` (all roles), then regenerate. To drop a field from one endpoint's DTO, extend `OmitType(<Model>GeneratedDto, ['field'] as const)`. Full details in [`docs/dtos.md`](../docs/dtos.md).
|
|
116
121
|
|
|
117
122
|
> **Nested relation writes are now an explicit, permission-gated allowlist — this is a behaviour restriction; a migrating agent MUST flag it to the developer.** Generated **create** DTOs accept only two nested operators, each authorized by ABAC: **`create`** (checked against the related model's `create` rule) and **`connect`** (checked against the related model's new dedicated **`connect`** permission — a `connect` rule is required; no rule ⇒ refused). Every other operator (`set`, `disconnect`, `update`, `upsert`, `delete`, …) is rejected (`400`). Nested writes are available on **`create` only** — `update` resolves to `updateMany`, whose payload is scalar-only. **Keep `forbidNonWhitelisted: true` on (fail loud); never `whitelist`-strip on writes.**
|
|
118
123
|
>
|
|
@@ -147,4 +152,3 @@ prefix. The auth building blocks (`AuthController`, `AuthService`, `RegisterDto`
|
|
|
147
152
|
**5. Create-permission enforcement (behaviour change — review before upgrading).**
|
|
148
153
|
- Ensure every model/role that legitimately creates records has an explicit `create` permission (or `'ALL'`). Without one, create now returns `403` (previously unchecked). Internal framework flows (registration, sessions, tokens) are unaffected.
|
|
149
154
|
- If you supplied arbitrary values for a field a `create` condition constrains (e.g. an owner id), those requests now return `403` unless the value matches — use `setUserIdField` to have the framework set it.
|
|
150
|
-
- **`restrictedFields` under `updateMany` now applies** (it was a no-op before). Fields listed there are stripped on `PUT`. Remove any field that should remain writable.
|
package/package.json
CHANGED