No description
  • TypeScript 52.8%
  • JavaScript 32.3%
  • CSS 8.9%
  • SCSS 2.6%
  • HTML 1.9%
  • Other 1.5%
Find a file
Rudi van Hierden 292cfb5491
fix: tighten authorization on user, project config and admin API writes (#1889)
* fix(api): scope user updates and auth server identity writes per project

- User.canUpdate/canDelete only act across projects for superusers or the person themselves
- Only send email/password to the auth server when the caller may update every record of that identity
- Run identity data through authorizeData before syncing; drop twoFactor fields from the user PUT
- Require the same check for two-factor reset
- Check all linked users before anonymize-all writes anything
- Only honour admin/editor role on create when the caller holds that role
- Do not demote a user when a requested role is not allowed

* fix(api): restrict project auth config to superusers

- Non-superusers may only change the auth provider settings used by the admin UI
- Hide client secrets in project config from non-superusers

* fix(api): keep records and their relations within the project

- authorizeData drops projectId/resourceId changes on update
- Only attach own-project (or global) tags and own-project statuses when creating a resource

* fix: resolve notification recipients from widget config

- Submission admin confirmation and comment confirmation recipients come from the widget config instead of the request body
- Comments and document-map widgets send their widgetId

* fix(auth): scope admin API to the authenticated client

- Non-admin clients may only set roles for, read and update their own client
- Unique and access codes are scoped to the authenticated client
- Listing clients requires the admin client
- Never return password hash, hashed phone number or 2FA token from the admin API

* fix(api): write identity fields with the admin client and reject partial updates

- Email/password changes without rights on the whole identity return 403 instead of being half applied
- Email, password and 2FA reset are sent with the admin client credentials; profile and role with the project client
- Password follows the email rule (editor or owner)
- Linked record sync errors are logged again instead of returning 500
- Comment confirmations are not sent to the resource owner when a configured address cannot be resolved

* fix(auth): restrict identity writes, user delete and client creation in admin API

- Non-admin clients may not change email, password or 2FA of, or delete, users with roles on other clients
- Creating a client requires the admin client
- Roles for other clients return 403 instead of being ignored
- Strip resetPasswordToken from admin API user output
- Unknown access code returns 404

* fix(api): only use the admin client for identity writes by superusers

Non-superusers write email, password and 2FA through the project client, so the auth server can still reject identities with roles on other clients that the api does not know about.

* fix(api): treat name and phone number as identity fields and write them first

- Name and phone number follow the email/password rules for users in multiple projects
- The person themselves also writes identity fields with the admin client
- Identity fields are written before the profile, so a refusal saves nothing
- A 403 from the auth server is returned as 403 instead of 500

* fix(api): compare auth provider when matching a user to their identity

Identifiers are only unique per auth provider. Owner checks in User.canUpdate, authorizeData and the user routes (which may use the admin client) now also compare the provider.

* fix(auth): treat name and phone numbers as identity fields

Non-admin clients may not change name, phoneNumber or hashedPhoneNumber (the SMS login key) of users with roles on other clients.
2026-10-07 16:32:01 +02:00
.github fix(security): pin GitHub Actions to SHAs, close template XSS boundaries 2026-07-15 12:11:46 +02:00
.husky chore: add Husky pre-commit hook, lint-staged, and CI formatting check 2026-02-12 19:52:28 +01:00
apps fix: tighten authorization on user, project config and admin API writes (#1889) 2026-10-07 16:32:01 +02:00
charts/openstad-headless Release/v2.8 (#1884) 2026-10-07 08:48:22 +02:00
cypress Release/v2.8 (#1884) 2026-10-07 08:48:22 +02:00
doc docs: add plugin system technical documentation (#1777) 2026-10-07 09:14:46 +02:00
img add publiccode.yml 2024-04-11 15:59:21 +02:00
operations Merge pull request #1238 from openstad/main 2025-12-11 15:22:25 +01:00
otel-collector fix(charts,docker): harden container security contexts 2026-07-15 11:36:39 +02:00
packages fix: tighten authorization on user, project config and admin API writes (#1889) 2026-10-07 16:32:01 +02:00
scripts add new envvar to docs and init-scripts 2026-06-17 16:09:05 +02:00
vendor fix: update knox dependency 2025-11-12 15:38:37 +01:00
.dockerignore Release/v2.8 (#1884) 2026-10-07 08:48:22 +02:00
.env.example add new envvar to docs and init-scripts 2026-06-17 16:09:05 +02:00
.git-blame-ignore-revs chore: add .git-blame-ignore-revs for Prettier commit 2026-02-12 19:51:08 +01:00
.gitignore Merge remote-tracking branch 'origin/feature/lightbox' into release/v2.6 2026-06-02 15:59:38 +02:00
.npmrc fix(docker): run dependency install scripts under npm 12 2026-07-09 16:40:52 +02:00
.prettierignore Release/v2.8 (#1884) 2026-10-07 08:48:22 +02:00
.prettierrc style: format entire codebase with Prettier 2026-02-12 19:50:53 +01:00
.testing.env fix: correct DB_HOST, DB_PASSWORD and DB_BASE_NAME in e2e test env 2026-04-01 17:19:42 +02:00
CALENDAR.md style: format entire codebase with Prettier 2026-02-12 19:50:53 +01:00
CHANGELOG.md style: format entire codebase with Prettier 2026-02-12 19:50:53 +01:00
CONTRIBUTING-PILOT-2026.md Change contributing docs for branch naming and pr title 2026-07-09 14:22:37 +02:00
CONTRIBUTING.md style: format entire codebase with Prettier 2026-02-12 19:50:53 +01:00
cypress.config.ts fix: migrate Cypress.env() to Cypress.expose() for Cypress 15 2026-04-02 09:08:53 +02:00
docker-compose.e2e.init.yml add new envvar to docs and init-scripts 2026-04-21 14:12:47 +02:00
docker-compose.e2e.yml add new envvar to docs and init-scripts 2026-04-21 14:12:47 +02:00
docker-compose.release.yml fix: restore multi-stage build with or without packages 2024-01-09 16:07:59 +01:00
docker-compose.yml Release/v2.8 (#1884) 2026-10-07 08:48:22 +02:00
Dockerfile Release/v2.8 (#1884) 2026-10-07 08:48:22 +02:00
GOVERNANCE.md style: format entire codebase with Prettier 2026-02-12 19:50:53 +01:00
LICENSE.md Update LICENSE.md 2025-09-01 13:52:57 +02:00
package-lock.json fix(deps): resolve npm audit and Dependabot vulnerabilities (#1888) 2026-10-07 13:33:11 +02:00
package.json fix(deps): resolve npm audit and Dependabot vulnerabilities (#1888) 2026-10-07 13:33:11 +02:00
publiccode.yml style: format entire codebase with Prettier 2026-02-12 19:50:53 +01:00
README.md chore: add Husky pre-commit hook, lint-staged, and CI formatting check 2026-02-12 19:52:28 +01:00
vitest.config.ts style: format entire codebase with Prettier 2026-02-12 19:50:53 +01:00
vitest.setup.ts fix(enquete): defer Form render for draft 2026-01-27 10:47:18 +01:00

OpenStad

This is the monorepo for the OpenStad headless project. To read more about OpenStad visit the website.

Docs

Currently the following elements have been documented:

All

Development

Code formatting

This project uses Prettier for code formatting. A pre-commit hook automatically formats staged files on commit.

Setup after cloning:

npm install

This sets up the Git hooks via Husky's prepare script.

Manual formatting:

npm run format          # format all files
npm run format:check    # check without modifying (used in CI)

API