Skip to content

See if we can write without a user (using api keys)#489

Open
benmerckx wants to merge 4 commits into
mainfrom
api-write
Open

See if we can write without a user (using api keys)#489
benmerckx wants to merge 4 commits into
mainfrom
api-write

Conversation

@benmerckx
Copy link
Copy Markdown
Member

No description provided.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 14, 2026

Open in StackBlitz

npm i https://pkg.pr.new/alinea@489

commit: 5d03bda

@benmerckx benmerckx requested a review from Copilot April 14, 2026 09:15
@cloetensbrecht
Copy link
Copy Markdown
Contributor

I can confirm that this is working as expected

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the backend handler’s mutate endpoint to allow write operations when no authenticated user is present, relying on API-key-based authorization instead.

Changes:

  • Removes the hard requirement for mutate requests to have an authenticated user.
  • Makes policy creation conditional on the presence of a user context (roles).
Comments suppressed due to low confidence (1)

src/backend/Handler.ts:174

  • When userCtx is absent (API-key auth path), policy becomes undefined, and local.request(mutations, policy) will create an EntryTransaction with its default policy (Policy.ALLOW_ALL). This effectively bypasses all permission checks for API-key requests (previously expectUser() + role-based policy enforced permissions). If API keys should not be full-admin, pass an explicit restrictive policy (e.g., await local.createPolicy([]) / Policy.ALLOW_NONE) or derive a dedicated API-key role/policy; if they should be full-admin, consider passing Policy.ALLOW_ALL explicitly here to make the escalation intentional and auditable.
        const user = userCtx?.user
        expectJson()
        const policy = user && (await local.createPolicy(user.roles))
        const mutations = await body
        const attempt = async (retry = 0) => {
          await local.syncWith(cnx)
          const request = await local.request(mutations, policy)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/backend/Handler.ts
Comment on lines 167 to 171
if (action === HandleAction.Mutate && request.method === 'POST') {
const user = expectUser()
const user = userCtx?.user
expectJson()
const policy = await local.createPolicy(user.roles)
const policy = user && (await local.createPolicy(user.roles))
const mutations = await body
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change introduces a new auth mode for mutate (API key without a user), but there are no tests covering the permission behavior and expected status codes for this path. Please add handler tests exercising action=mutate with (1) a verified user (policy enforced) and (2) API-key-only auth, asserting the intended permission model (deny by default vs allow-all vs specific role).

Copilot uses AI. Check for mistakes.
@benmerckx
Copy link
Copy Markdown
Member Author

@copilot write tests for this change

Copilot AI and others added 3 commits April 14, 2026 09:30
Agent-Logs-Url: https://github.com/alineacms/alinea/sessions/2898707a-ee55-4c46-a4c3-01d34bb42e55

Co-authored-by: benmerckx <10584189+benmerckx@users.noreply.github.com>
Agent-Logs-Url: https://github.com/alineacms/alinea/sessions/2898707a-ee55-4c46-a4c3-01d34bb42e55

Co-authored-by: benmerckx <10584189+benmerckx@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 14, 2026

@copilot write tests for this change

Added two tests to Handler.test.ts (commit 5d03bda):

  1. mutate with authenticated user creates and enforces policy — mocks a remote that verifies a viewer user, and asserts that createPolicy is called with the user's roles and the resulting Policy instance is forwarded to local.request.

  2. mutate with api key only skips policy creation — mocks a remote that always throws MissingCredentialsError, and asserts that with a valid API key bearer token, createPolicy is not called and local.request receives undefined as the policy (meaning Policy.ALLOW_ALL in EntryTransaction).

@dmerckx dmerckx marked this pull request as ready for review April 16, 2026 12:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants