bf22373315
see [discord discussion](https://discord.com/channels/1130383047699738754/1486299347091198054/1486299351520383116) ## Summary When an OAuth application token carries both `applicationId` and `userId`/`userWorkspaceId`, the auth context now uses the **user's role** for permissions instead of the application's `defaultRoleId`. This fixes the case where external clients authenticating via OAuth (e.g. a client's external AI chat) were getting the app's permissions instead of the authenticated user's. ### What changed - **`jwt.auth.strategy.ts`** (`validateApplicationToken`): when an application token includes user info, also resolve `workspaceMemberId` and `workspaceMember` from the workspace cache (same pattern as `validateAccessToken`) - **`workspace-auth-context.middleware.ts`** (`buildAuthContext`): when both `application` and `user` (with `workspaceMemberId`/`workspaceMember`) are present on the request, build a `UserWorkspaceAuthContext` instead of `ApplicationWorkspaceAuthContext`. Falls back to application context if workspace member cannot be resolved. ### Places impacted by this change (no code changes, behavior changes) These places check `isApplicationAuthContext` or resolve roles from auth context. Since hybrid tokens (OAuth with user) now produce a `UserWorkspaceAuthContext`, they naturally flow into the `isUserAuthContext` branches: | File | Impact | |------|--------| | `permissions.service.ts` — `resolveRolePermissionConfigFromAuthContext` | OAuth+user now uses user's role via `isUserAuthContext` branch instead of `application.defaultRoleId` | | `common-api-context-builder.service.ts` — `getObjectsPermissions` | Same — OAuth+user falls into `isUserAuthContext` branch | | `common-base-query-runner.service.ts` — `getRoleIdOrThrow` | Same — OAuth+user falls into `isUserAuthContext` branch | | `actor-from-auth-context.service.ts` — `buildActorMetadata` | Records created via OAuth+user will show the **user's name** as actor instead of the application's name | | `message-find-one.post-query.hook.ts` | OAuth+user now passes the `isUserAuthContext` check (previously would fail unless it was the Twenty standard application) | | `front-component.resolver.ts` | Front component tokens include `userId` — they will now correctly use the user's role, fixing a pre-existing permission escalation where a user could access data through a front component's app role that exceeded their own | | `logic-function-executor.service.ts` | **Not impacted** — only generates tokens with `applicationId` (no `userId`) |