Skip to content

Conversation

@thehabes
Copy link
Member

@thehabes thehabes commented Jan 7, 2026

Closes #440
Unblocks #437 (express-oauth2-jwt-bearer package update)
Currently ignores #442

Summary

This PR adds permission checks to project read endpoints and standardizes authentication error handling.

Note that the express-oauth2-jwt-bearer library behavior changed with the last update. Previously if the Authorization header was omitted from a request the library returned a 401. Now it is returning a 400 in this scenario. This is temporary as the library developers are currently working on reverting the behavior so that it returns a 401 again.

The following test files were updated to expect 400 as a temporary workaround:

  • tests/smoke.test.js
  • auth/tests/auth_unit_test.js
  • classes/User/tests/unit.test.js
  • userProfile/tests/end_to_end_unit.test.js

When the library is patched, these tests should be reverted to expect 401.

If an Authorization header with a token is provided and that token is no good that still returns a 401.

Changes

  1. Added permission checks to previously unprotected authenticated endpoints:

    • GET /project/:id - now checks READ permission
    • GET /project/:id/manifest - now checks UPDATE permission (export)
    • GET /project/:id/deploymentStatus - now checks READ permission
  2. Added missing authentication check to POST /project/import endpoint:

    • Previously accessed user.agent without verifying user exists after auth middleware
    • Now properly returns 401 if user is not authenticated
  3. Standardized 401 error message across all protected endpoints:

    "Not authenticated. Please provide a valid, unexpired Bearer token"
    
  4. Updated tests to expect 400 for missing Authorization header (this is the express-oauth2-jwt-bearer library behavior, not a body validation error)

Key Files Modified

File Changes
project/projectReadRouter.js Added checkUserAccess permission checks to all 3 GET endpoints
project/projectCreateRouter.js Added missing user authentication check to /import endpoint
project/projectCopyRouter.js Added permission checks, standardized 401 message
project/memberRouter.js Standardized 401 messages
project/customRolesRouter.js Standardized 401 messages
project/projectToolsRouter.js Added permission checks, standardized 401 message
userProfile/privateProfile.js Standardized 401 messages
line/index.js Added permission checks, standardized 401 message
layer/index.js Added permission checks, standardized 401 message
page/index.js Added permission checks, standardized 401 message
Test files Updated to expect 400 for missing auth header

Bearer Token Authentication Audit

How Authentication Errors Work

Scenario Status Message
No Authorization header 400 express-oauth2-jwt-bearer returns Bad Request
Invalid/expired Bearer token 401 "Not authenticated. Please provide a valid, unexpired Bearer token"
Valid token, insufficient permissions 403 Context-specific permission message

Public Endpoints (No Bearer Token Required)

Method Endpoint
GET /
GET /api
GET /user/:id
GET /project/:projectId/layer/:layerId
GET /project/:projectId/page/:pageId
GET /project/:projectId/page/:pageId/resolved
GET /project/:projectId/page/:pageId/line/:lineId
GET /:projectId/collaborator/:collaboratorId/decline
GET /:projectId/collaborator/:collaboratorId/agent/:agentId

Protected Endpoints

User Profile (/my/*)

Method Endpoint 400 401 403
GET /my/profile Missing header Invalid token
PUT /my/profile Missing header Invalid token
GET /my/projects Missing header Invalid token

Project Read (/project/*)

Method Endpoint 400 401 403
GET /project/:id Missing header Invalid token No READ on PROJECT
GET /project/:id/manifest Missing header Invalid token No UPDATE on PROJECT
GET /project/:id/deploymentStatus Missing header Invalid token No READ on PROJECT
PATCH /project/:projectId/label Missing header Invalid token No UPDATE on METADATA

Project Creation

Method Endpoint 400 401 403
POST /project/create Missing header Invalid token
POST /project/import Missing header Invalid token
POST /project/import-image Missing header Invalid token

Project Copy

Method Endpoint 400 401 403
POST /project/:projectId/copy Missing header Invalid token No READ on PROJECT
POST /project/:projectId/copy-without-annotations Missing header Invalid token No READ on PROJECT
POST /project/:projectId/copy-with-group Missing header Invalid token No READ on PROJECT
POST /project/:projectId/copy-with-customizations Missing header Invalid token No READ on PROJECT

Project Members

Method Endpoint 400 401 403
POST /project/:id/invite-member Missing header Invalid token No UPDATE on MEMBER
POST /project/:id/remove-member Missing header Invalid token No DELETE on MEMBER
POST /:projectId/collaborator/:id/addRoles Missing header Invalid token No UPDATE on MEMBER
PUT /:projectId/collaborator/:id/setRoles Missing header Invalid token No UPDATE on MEMBER
POST /:projectId/collaborator/:id/removeRoles Missing header Invalid token No DELETE on MEMBER
POST /:projectId/switch/owner Missing header Invalid token No ALL permissions
POST /project/:id/leave Missing header Invalid token

Project Tools

Method Endpoint 400 401 403
POST /project/:projectId/tool Missing header Invalid token No UPDATE on TOOLS
DELETE /project/:projectId/tool Missing header Invalid token No DELETE on TOOLS
PUT /project/:projectId/toggleTool Missing header Invalid token No UPDATE on TOOLS

Project Custom Roles

Method Endpoint 400 401 403
GET /project/:projectId/customRoles Missing header Invalid token No READ on GROUP
POST /project/:projectId/addCustomRoles Missing header Invalid token No CREATE on ROLE
PUT /project/:projectId/updateCustomRoles Missing header Invalid token No UPDATE on ROLE
DELETE /project/:projectId/removeCustomRoles Missing header Invalid token No DELETE on ROLE

Project Metadata

Method Endpoint 400 401 403
PUT /project/:projectId/metadata Missing header Invalid token No UPDATE on METADATA
GET /project/:id/custom Missing header Invalid token No READ on OPTIONS
POST /project/:id/custom Missing header Invalid token No UPDATE on OPTIONS
PUT /project/:id/custom Missing header Invalid token No UPDATE on OPTIONS

TPEN 2.8 Import

Method Endpoint 400 401 403
GET /project/deletecookie Missing header Invalid token
GET /project/import28/:uid Missing header Invalid token
GET /project/import28/selectedproject/:id Missing header Invalid token

Layer Routes

Method Endpoint 400 401 403
PUT /project/:projectId/layer/:layerId Missing header Invalid token No UPDATE on LAYER
POST /project/:projectId/layer/ Missing header Invalid token No CREATE on LAYER

Page Routes

Method Endpoint 400 401 403
PUT /project/:projectId/page/:pageId Missing header Invalid token No UPDATE on PAGE
POST /project/:projectId/page/:pageId/column Missing header Invalid token No UPDATE on PAGE
PUT /project/:projectId/page/:pageId/column Missing header Invalid token No UPDATE on PAGE
PATCH /project/:projectId/page/:pageId/column Missing header Invalid token No UPDATE on PAGE
DELETE /project/:projectId/page/:pageId/clear-columns Missing header Invalid token No DELETE on PAGE

Line Routes

Method Endpoint 400 401 403
POST /project/:projectId/page/:pageId/line/ Missing header Invalid token No CREATE on LINE
PUT /project/:projectId/page/:pageId/line/:lineId Missing header Invalid token No UPDATE on LINE
PATCH /.../line/:lineId/text Missing header Invalid token No UPDATE on TEXT
PATCH /.../line/:lineId/bounds Missing header Invalid token No UPDATE on SELECTOR

Feedback Routes

Method Endpoint 400 401 403
POST /beta/feedback Missing header Invalid token
POST /beta/bug Missing header Invalid token
image

@thehabes thehabes changed the title Authentication and Authorization Audit Authentication (token 400 or 401) and Authorization (user permissions) Audit Jan 7, 2026
@thehabes thehabes self-assigned this Jan 7, 2026
@thehabes thehabes linked an issue Jan 7, 2026 that may be closed by this pull request
@thehabes
Copy link
Member Author

thehabes commented Jan 8, 2026

@copilot review this pull request. Make sure to look at the pull request description to get a good understanding of what the code changes are doing.

@thehabes
Copy link
Member Author

thehabes commented Jan 8, 2026

Okay yeah I guess just do your own pull request that feels right. I guess mine is just trash.

This comment was marked as resolved.

@thehabes thehabes marked this pull request as ready for review January 8, 2026 21:00
@thehabes thehabes requested a review from Copilot January 8, 2026 21:00
Copy link
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

Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.

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.

Permission Checks in Endpoints

2 participants