Release Notes — WUIC Framework v1.7.22
Date: 6 October 2026 Previous published version: 1.7.21 (4 October 2026) Backend: .NET 10 + IIS / Linux nginx Frontend: Angular 21
This release aligns scaffolding across the four databases and completes the second part of the security review of OData, API tokens and reports. In short:
- scaffolding produces the same metadata on SQL Server, MySQL, PostgreSQL and Oracle: foreign keys as lookups, uniform types and default values;
- OData checks denied columns on the parsed query, limits
$topand$expand, and puts$batchbehind authentication; - API tokens are bound to the session's company, are revoked automatically on password change and user deletion, and can be restricted by role;
- the report of a denied route is refused on every database, not only on SQL Server;
- wrong column types in the MySQL, PostgreSQL and Oracle tutorial metadata are fixed at startup.
Metadata changes are applied automatically at startup. The end-to-end tests for OData, API tokens, reports, scaffolding, secure uploads, many-to-many and pivot passed on SQL Server, MySQL, PostgreSQL and Oracle, on clean installs on both Windows (IIS) and Linux, and on Oracle both version 21 and 23.
🗄️ Uniform scaffolding across databases
- Foreign keys as lookups. On Oracle and PostgreSQL, database foreign keys become
lookupByIDcolumns pointing to the route of the referenced table, as on SQL Server and MySQL already. - Aligned types. The same column scaffolded on different DBMSs produces the same metadata type; where types do not match exactly the closest one is used (for example Oracle
NUMBER(p,s)as decimal,NUMBER(p,0)as integer). - Oracle booleans. A
NUMBER(1)column becomes boolean only with a CHECK constraint on 0/1 (alsoIN ('0','1')orBETWEEN 0 AND 1) or when it is NOT NULL with a default of 0 or 1. A code column with default 1 stays numeric. - Default values. Oracle and PostgreSQL defaults reach the metadata without casts or quotes; columns defaulting to the server time (
SYSDATE,now(),CURRENT_TIMESTAMP) are read-only and hidden in the form. datetimeoffset. SQL Serverdatetimeoffsetcolumns stay editable and saving keeps the offset. On existing installations the same rule applies when the foreign key fix (fixFKeys) is run again.- Tutorial metadata. On MySQL, PostgreSQL and Oracle a startup migration fixes tutorial columns with a wrong type (for example
LatestRecordedPopulationdeclared as text instead of number, boolean flags declared as integers). It only touches columns holding the original wrong value: a type chosen by hand is not changed.
🔗 OData
- Denied columns. The check reads the already parsed query (
$filter,$orderby,$select,$expand,any/alllambdas): spaces around the slash, parentheses and aliases no longer get around the restriction. A path that returns to the starting type through another entity is checked as well. - Responses. Denied columns are removed from the response instead of coming back with an empty value, also after a
PATCH. Credential columns never leave the server, superadmin included. - Limits.
odataMaxTop(default 1000) andodataMaxExpandDepth(default 2): beyond them, response 400. - Writes.
POSTandPATCHrequire a JSON body, otherwise 415. A denied column sent empty or with its default value no longer rejects the whole write. DELETE. The delete permission and the visible rows are checked before answering 404, so the existence of a hidden row cannot be inferred from the response.$batch. The outer request goes through the same credential check as the single calls: without credentials it answers 401.- Browser login. The
Basiccredentials challenge stays for Power BI and Excel, but is no longer sent to the application's calls: when the session expires the app goes back to the login page instead of opening the browser's native dialog. - Oracle and spatial columns. The generated SQL is compatible with Oracle 19 (before, some
$expandqueries failed on Oracle 21 and earlier); spatial columns (geometry,SDO_GEOMETRY, …) stay out of the OData model on every database.
🔐 API tokens
- Session company. A token is bound to the user and to the company of the session that created it; listing, counting and revoking apply to that pair.
- Automatic revocation. Password reset and change, deletion and soft deletion of the user revoke their tokens. A soft-deleted user receives 401.
- Roles.
apiTokenAllowedRoleslists the roles that can create and use tokens,apiTokenWriteRolesthose that can write. They also apply to tokens already created. - "Revoke all my tokens". New button in the "API tokens" dialog.
- Failed attempts. The lockout after too many attempts only counts rejected tokens: a valid token from the same address always goes through.
🛡️ Security
Best-effort hardening: SQL join fragments sent by the client require a superadmin, like where fragments; the pivot of a non-admin user starts from their visible rows (restriction, default filter, soft deletion) and no longer receives the query text; the report of a denied route answers 403 on MySQL, PostgreSQL and Oracle too; protected upload areas apply to every company in multi-company mode; with custom authentication the cookie is renewed on every request; trusted proxies can be configured with forwardedHeadersKnownProxies and forwardedHeadersKnownNetworks.
🐛 Notable bug fixes
- Many-to-many filter on Oracle and PostgreSQL. A grid filter on a many-to-many column answered with an error on Oracle and did not filter on PostgreSQL; it now returns the rows associated with the chosen values, as on SQL Server and MySQL.
- Pivot on PostgreSQL and Oracle. Some pivot options reached the query generator in the wrong order.
- Routes with different casing on Oracle and PostgreSQL. After the cache was cleared, a route whose casing differed from the registered name was no longer found.
- OData on
/odatabehind nginx. The service document without a trailing slash answered with a redirect instead of the authentication response. - Swagger in templates. Controllers of generated projects show the XML comment descriptions in Swagger.
📦 Updated packages
| Package | From | To |
|---|---|---|
WuicCore |
1.7.21 | 1.7.22 |
Wuic.Webcore |
1.7.21 | 1.7.22 |
WuicOData |
1.7.21 | 1.7.22 |
RuntimeEfCore |
1.7.21 | 1.7.22 |
Wuic.MySqlProvider |
1.7.21 | 1.7.22 |
Wuic.PostgresProvider |
1.7.21 | 1.7.22 |
Wuic.OracleProvider |
1.7.21 | 1.7.22 |
wuic-framework-lib (npm) |
1.7.21 | 1.7.22 |
🔧 Recommended operational updates when upgrading
- OData clients with large pages: a
$topabove 1000 now answers 400. RaiseodataMaxTopif a client reads larger pages. - OData clients that write: send
Content-Type: application/jsononPOSTandPATCH, otherwise the response is 415. - Reports: on MySQL, PostgreSQL and Oracle a report whose data source matches no route answers 403. Check that existing reports open and, if needed, rename the data source after the route.
- API tokens in multi-company mode: a token of a user whose row has a company different from the token's is rejected. Check multi-company installations where user rows have an
id_aziendadifferent from the tenant's company. - Behind a load balancer: set
forwardedHeadersKnownProxies(orforwardedHeadersKnownNetworks) to the proxy addresses, so attempt limits count per client and not per proxy. - Token roles: to restrict who can create tokens or write through OData, set
apiTokenAllowedRolesandapiTokenWriteRolesfrom the AppSettings editor.