Commit Graph
567 Commits
Author SHA1 Message Date
Hein aec87a81e7 fix(bun): ignore scanonly columns in ExcludeColumn
Tests / Integration Tests (push) Skipped
Tests / Unit Tests (push) Successful in 1m37s
Tests / Race Detector (push) Successful in 3m52s
Build , Vet Test, and Lint / Build (push) Successful in 1m33s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 2m16s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 2m19s
Build , Vet Test, and Lint / Lint Code (push) Successful in 2m19s
Bun's ExcludeColumn errors with "can't find column" for scanonly fields
because they are not in the table's writable fields. Filter the exclude
list to writable bun fields so models with scanonly buffers can insert
and update again. Add tests for the adapter and reflection.
v1.3.3
2026-10-05 14:10:52 +02:00
warkanum 9235292586 fix(crud): skip generated and read-only columns on insert and update
Tests / Integration Tests (push) Skipped
Build , Vet Test, and Lint / Build (push) Successful in 1m34s
Tests / Unit Tests (push) Successful in 1m42s
Build , Vet Test, and Lint / Lint Code (push) Successful in 2m11s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 2m25s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 2m28s
Tests / Race Detector (push) Successful in 4m6s
Read-merge-update wrote every model column back, so GENERATED ALWAYS
columns failed with SQLSTATE 428C9. Add a bun 'generated' tag option,
reflection.NonWritableColumns/RemoveNonWritableColumns, and apply them
in resolvespec, restheadspec, websocketspec, mqttspec, resolvemcp and
the nested CUD processor. Add ExcludeColumn to InsertQuery/UpdateQuery
for model-based writes.
v1.3.2
2026-10-02 22:43:45 +02:00
warkanum 23f10387c5 ci(release): fix rust toolchain setup and dart publish validation warnings
Tests / Integration Tests (push) Skipped
Build , Vet Test, and Lint / Build (push) Successful in 3m15s
Tests / Unit Tests (push) Successful in 3m26s
Build , Vet Test, and Lint / Lint Code (push) Successful in 4m45s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 4m55s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 4m55s
Tests / Race Detector (push) Successful in 7m6s
2026-10-01 21:20:04 +02:00
warkanum 0d3ad9e4fd ci(tests): disable integration tests job and install psql client v1.3.1 2026-10-01 21:16:34 +02:00
warkanum f5d232d971 ci: move workflows to Gitea and add client release workflow
Tests / Integration Tests (push) Failing after 1m39s
Build , Vet Test, and Lint / Build (push) Successful in 2m3s
Tests / Unit Tests (push) Successful in 2m8s
Build , Vet Test, and Lint / Lint Code (push) Successful in 2m51s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 2m57s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 2m59s
Tests / Race Detector (push) Successful in 5m9s
Move .github/workflows to .gitea/workflows with Gitea-compatible action
versions, fix make_tag outputs/major bump, and add release_clients.yml to
build and publish all clients to the Gitea package registries. Rename the Go
client module to git.warky.dev/wdevs and add LICENSE/CHANGELOG for Dart.
2026-10-01 21:11:41 +02:00
Hein a4702161fb docs(readme): add breaking changes section for 2026-09-30 to 2026-10-01 v1.3.0 v1.2.12 2026-10-01 15:17:37 +02:00
Hein 640faeeeaf feat(security): full OAuth 2.1 / OpenID Connect server and OIDC relying-party client
Authorization server: consent and scopes, OIDC (nonce, auth_time, acr, sid,
at_hash, signed userinfo, RP-initiated and back-channel logout), managed
refresh tokens with rotation and reuse detection, RFC 9068 JWT access tokens,
DPoP, PAR, device grant, token exchange, private_key_jwt, RFC 7591/7592
registration, RFC 9207 iss, signing keyring with rotation.

State is DB-backed through a new lookup.OAuthGrantStore (procedure and direct
backends, four dialect DDLs, conformance cases).

Client side: WithOIDC discovery, PKCE, nonce, id_token validation, OAuth2LogoutURL.

PeekRefresh now returns already rotated tokens so RotateRefresh can detect reuse.

Docs: OAUTH2_SERVER.md, oauth2_full_example.go, breaking_changes.md step 8.
2026-10-01 14:42:12 +02:00
Hein f54b707040 feat(pgsql): add WhereGroup and a podman/docker hardening test
- PgSQLSelectQuery implements common.WhereGrouper so x-custom-sql-or
  is grouped with the client's own conditions on the pgx adapter too.
- Add a container test (opt-in via RESOLVESPEC_TEST_CONTAINERS=1) that
  starts PostgreSQL with podman or docker and checks the hardening
  against a real database: parenthesis escape, pg_sleep, catalog
  subquery, stacked statements, x-custom-sql-or grouping and the
  legacy behaviour when hardening is switched off.
2026-10-01 14:41:46 +02:00
Hein ca89cb8a73 fix(common): harden CORS, sort, raw-SQL WHERE and x-custom-sql-or
Add a `hardening` config section (RESOLVESPEC_HARDENING_*) so each
fix can be switched off to restore the previous behaviour:

- cors_strict_origins: only reflect origins listed in
  cors.allowed_origins / server URLs, with credentials; `*` never
  sends credentials; fix shared-slice append of expose headers.
- sort_strict: join aliases must match `alias.identifier` (empty alias
  no longer matches everything); sort expressions reject dangerous
  functions/catalogs; cql* columns must be identifier-safe.
- sql_strict: client raw-SQL fragments must have balanced parens and
  quotes, no comments/`;`/`$$`, DML keywords, dangerous functions or
  system catalogs; a rejected fragment now fails closed ("(1=0)")
  instead of dropping the filter. Subqueries stay allowed unless
  sql_block_subqueries is set.
- x-custom-sql-or is grouped together with the client's own
  conditions (new optional WhereGrouper, implemented for bun and gorm)
  so it can no longer OR past server-side filters.
2026-10-01 13:46:01 +02:00
Hein c1153522f2 docs(resolvemcp): rewrite README for meta tools, guard and limits; update plan status 2026-10-01 13:42:14 +02:00
Hein 155e04deea chore(resolvemcp): drop unused helpers, silence rangeValCopy 2026-10-01 13:40:21 +02:00
Hein e49c3a916e feat(resolvemcp): replace per-model tools with fixed meta tools, guarded filter writes and a function registry
Tools: list_tables, describe_table, select_table, insert_into_table, update_table,
delete_from_table, list_functions, call_function. Visibility follows the model rules.
Filter-based update/delete require filters (never dropped silently), cap the matched rows
(MaxWriteRows), support dry_run, and need a single-use confirm token bound to caller, table,
filters, data and the matched rows. RegisterFunction adds Go-callback and SQL-procedure
functions run in a transaction with BeforeCall/AfterCall hooks. Per-model tools and
resources are removed.

fix(pgsql): UPDATE with SET and a multi-placeholder WHERE renumbered the WHERE parameters
wrongly ($1, $2 became $3, $2); shift them in one pass.
2026-10-01 13:40:00 +02:00
Hein 276c3814d8 feat(resolvemcp): read/write limits, preload validation, query timeout, stable client error codes
Config gains DefaultLimit/MaxLimit/MaxOffset/MaxBatch/MaxPreloadDepth/MaxWriteRows/QueryTimeout/
ConfirmTTL. Reads are capped and the total COUNT is optional. Errors reach clients as
{code,message}; everything else is logged with a reference. Panics (handler and hooks) are
recovered without returning the panic value.
2026-10-01 13:35:00 +02:00
Hein 82f901a49c fix(resolvemcp): single transaction for create/update, hook registry mutex, uniform not-found, bounded SSE host cache 2026-10-01 13:33:11 +02:00
Hein ad2f54693f feat(resolvemcp): require authentication on MCP endpoints and enforce model rules on writes
Guard() rejects unauthenticated callers (no guest/optional mode); Setup*/New* helpers take a
SecurityList and have explicit *Unauthenticated variants. Model rules now reach the security
hooks, create checks CanCreate (security.CheckModelCreateAllowed), create/update validate keys
against the model's writable columns, update sets only given keys (NULL allowed), update and
delete go through row security via a new BeforeScan hook, and the annotation tool is opt-in
(Config.EnableAnnotations) and runs BeforeHandle.
2026-10-01 13:31:13 +02:00
Hein 7662d5055c test(security): seed expired key as UTC in direct auth test
Tests / Race Detector (push) Failing after 27s
Tests / Unit Tests (push) Failing after 29s
Tests / Integration Tests (push) Failing after 30s
Build , Vet Test, and Lint / Build (push) Successful in 1m14s
Build , Vet Test, and Lint / Lint Code (push) Successful in 1m32s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 1m42s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 1m40s
2026-10-01 13:24:38 +02:00
Hein ea6a2e705f test(security): add SQL Server container conformance test; bind timestamps as UTC in direct backend 2026-10-01 13:24:26 +02:00
Hein 2516fcb13d chore(security): apply golangci-lint fixes to lookup and security packages 2026-10-01 13:21:00 +02:00
Hein c9fa8c60f2 refactor(security): move all database access into pkg/security/lookup
pkg/security no longer contains SQL. Every provider calls a store interface
from lookup, implemented by a procedure backend (Postgres stored procedures,
the default there) and a direct backend (dialect-driven SQL for postgres,
sqlite, mysql and mssql with configurable table and column names).

- add sectypes, lookup, lookup/{dialect,procedure,direct,backends,ddl,conformance}
- split totp and providers sub packages out of the core package
- replace SQLNames/TableNames/QueryMode with lookup.Config (see breaking_changes.md)
- direct backend now covers column/row security and API-key login
- move txsettings SQL to lookup.ApplyTxSettings; remove password.go
- move schema scripts under lookup/, add reference DDL per dialect
- add a shared conformance suite; run it on sqlite, and on Postgres in a
  podman/docker container (RESOLVESPEC_TEST_CONTAINERS=1)
- fix procedure schema bugs found on real Postgres: duplicate p_data
  parameter, JSON null arrays, expires_at timezone casts, passkey list
  GROUP BY, missing resolvespec_passkey_login; accept zone-less timestamps
2026-10-01 13:19:44 +02:00
Hein 60bd0a6dd3 feat(security): add plan for pkg/security lookup sub package 2026-10-01 11:29:02 +02:00
Hein 982c90bfdd feat(websocketspec): fire BeforeDisconnect/AfterDisconnect hooks on close
Hooks fire from Connection.Close() once per connection. ConnectionManager
Shutdown now closes connections outside its lock so hooks can call back
into the manager. Update the single-transaction audit plan status.
2026-10-01 10:53:21 +02:00
Hein ae2b0a4ef4 fix(security): skip row security filter for insert queries
Insert queries have no Where clause and read no existing rows, so the
fail-closed check rejected every insert when a row security template
was defined.
v1.2.11
2026-10-01 10:47:54 +02:00
Hein daeea241af fix(restheadspec): honour string URL ids on POST updates
POST with a non-numeric URL id (e.g. a string primary key) was treated as
having no id, so the body primary key was used to look up the existing row.
That broke primary key changes. Treat any non-empty, non-zero URL id as the
update target, and add an integration test through Handle for POST and PUT.
v1.2.10
2026-10-01 10:23:23 +02:00
Hein 3bd3e46409 fix(restheadspec): handle primary key changes in updates
* Allow primary key changes when specified in the request body.
* Ensure correct record fetching after primary key updates.
* Add integration tests for primary key update scenarios.
v1.2.9
2026-10-01 10:16:26 +02:00
Hein 247111c32e docs(README): update table of contents and feature descriptions 2026-10-01 09:46:17 +02:00
Hein Puth (Warkanum) ec8d4d2c77 Merge pull request #25 from bitechdev/fix/row-security-update-delete
Fix/row security update delete
v1.2.8
2026-10-01 09:40:33 +02:00
Hein a3287f3b53 fix(security): reorder import statements for consistency 2026-10-01 09:33:57 +02:00
Hein 1e4a76643d fix(security): apply row security to update and delete queries
ApplyRowSecurity only accepted common.SelectQuery, so the BeforeScan hook
failed closed on update/delete when a row-security template existed.
Type-switch on SelectQuery, UpdateQuery and DeleteQuery; other types
still return an error.
2026-10-01 09:31:56 +02:00
Hein Puth (Warkanum) a81031b83d Merge pull request #23 from bitechdev/fix/db-connection-bursts
Tests / Race Detector (push) Failing after 23s
Tests / Unit Tests (push) Failing after 25s
Tests / Integration Tests (push) Failing after 26s
Build , Vet Test, and Lint / Build (push) Successful in 1m4s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 1m34s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 1m34s
Build , Vet Test, and Lint / Lint Code (push) Failing after 1m34s
Fix/db connection bursts
v1.2.7
2026-09-30 23:53:17 +02:00
warkanum ac4cf9b4b6 Merge branch 'main' of github.com:bitechdev/ResolveSpec into fix/db-connection-bursts 2026-09-30 23:51:24 +02:00
warkanum b35399fdfa feat(security): exclude hidden/masked columns from create and update payloads 2026-09-30 23:48:09 +02:00
warkanum a65ca5f5ce fix: fire resolvespec AfterRead/AfterCreate/AfterDelete, key restheadspec total cache by record id 2026-09-30 23:40:32 +02:00
warkanum 5933637a88 docs(readme): update slogan placement in README 2026-09-30 23:35:08 +02:00
warkanum 7f84debdc5 test(tx): regression tests for per-request transactions across all specs 2026-09-30 23:19:58 +02:00
warkanum 2042205817 fix(pgsql): return subquery preload errors instead of logging and continuing 2026-09-30 23:11:30 +02:00
warkanum 6335bfe87e docs(readme): reference all pkg packages and clients 2026-09-30 23:04:56 +02:00
warkanum 129c1a043d docs(readme): document single transaction per request, OnTxBegin, test server 2026-09-30 23:03:50 +02:00
warkanum da0b1f5123 chore(testserver): host networking, ports 8123/8124, smoke read+update, dbtrace pooled=0 verified 2026-09-30 23:01:52 +02:00
warkanum ff76eb8e1f feat(security): stamp transaction-local settings on OnTxBegin in all specs 2026-09-30 22:55:26 +02:00
warkanum 3b93802a25 fix(tx): run restheadspec AfterRead in a second short transaction 2026-09-30 22:53:07 +02:00
warkanum 6b6f540ab0 feat(tx): run funcspec OnTxBegin and BeforeResponse in transactions 2026-09-30 22:50:41 +02:00
warkanum 4cbe4f597d feat(tx): run resolvemcp operations in per-operation transactions with OnTxBegin 2026-09-30 22:49:47 +02:00
warkanum ed457eb14a feat(tx): run websocketspec and mqttspec operations in per-message transactions
Reads and deletes run in one transaction; create and update write in one
and re-fetch plus After hooks in a second. OnTxBegin fires first in each.
2026-09-30 22:46:46 +02:00
warkanum 97bcb44fdc fix(clients): verify C# client, read Content-Range from content headers 2026-09-30 22:44:15 +02:00
warkanum 17bb6ea76d fix(clients): verify Dart client, case-insensitive Content-Range lookup 2026-09-30 22:42:55 +02:00
warkanum ce706bacda feat(tx): run update re-fetch and post-commit hooks in a second transaction
Re-fetch, BeforeScan and AfterUpdate/AfterCreate now run on a short
transaction that fires OnTxBegin. Existence selects inside the first
transaction use tx instead of the pool.
2026-09-30 22:42:33 +02:00
warkanum eb492d52aa feat(clients): add Go, Rust, C# and Dart clients for ResolveSpec and FunctionSpec 2026-09-30 22:40:33 +02:00
warkanum f2dbe2561c feat(hooks): add OnTxBegin and runInTx for resolvespec and restheadspec
Every transaction the handlers open now fires OnTxBegin first, with the
transaction in hookCtx.Tx, via common.RunRequestTx.
2026-09-30 22:40:06 +02:00
warkanum cd96404cdd fix(delete): run delete hooks and queries in one transaction
- resolvespec/restheadspec: single and batch delete use one transaction
- add sqlmock tests for delete transaction behaviour
- testmodels: serial integer ids; update tests accordingly
- add compose testserver, smoke script, podman-first Makefile targets
2026-09-30 22:33:25 +02:00
warkanum b2b815552f refactor: move JS and Python clients under clients/ 2026-09-30 22:31:43 +02:00