Files
coder/site/permissions.json
T
Kyle Carberry 47846c0ee4 fix(site): inject permissions and organizations metadata to eliminate loading spinners (#22741)
## Problem

Two network requests were blocking the initial page render with
fullscreen `<Loader fullscreen />` spinners:

1. **`POST /api/v2/authcheck`** (permissions) — blocked in `RequireAuth`
via `AuthProvider.isLoading`
2. **`GET /api/v2/organizations`** — blocked in `DashboardProvider`

All other bootstrap queries (`user`, `entitlements`, `appearance`,
`experiments`, `build-info`, `regions`) already used server-side
metadata injection via `index.html` meta tags and resolved instantly.
These two did not.

## Solution

Follow the existing `cachedQuery` + `<meta>` tag pattern to inject both
datasets server-side:

### Server-side (`site/site.go`)
- Add `Permissions` and `Organizations` fields to `htmlState`
- Fetch organizations via `GetOrganizationsByUserID` in parallel with
existing queries
- Evaluate all `permissionChecks` using the RBAC authorizer directly
- Inject results as HTML-escaped JSON into `<meta>` tags

### Frontend
- Register `permissions` and `organizations` in `useEmbeddedMetadata`
- Update `checkAuthorization()` to accept optional metadata and use
`disabledRefetchOptions` when available
- Update `organizations()` to accept optional metadata and use
`cachedQuery` when available
- Wire metadata through `AuthProvider` and `DashboardProvider`

### Note
The Go `permissionChecks` map in `site/site.go` mirrors
`site/src/modules/permissions/index.ts` and must be kept in sync.
2026-03-09 16:12:04 +00:00

123 lines
3.0 KiB
JSON

{
"viewAllUsers": {
"object": { "resource_type": "user" },
"action": "read"
},
"updateUsers": {
"object": { "resource_type": "user" },
"action": "update"
},
"createUser": {
"object": { "resource_type": "user" },
"action": "create"
},
"createTemplates": {
"object": { "resource_type": "template", "any_org": true },
"action": "create"
},
"updateTemplates": {
"object": { "resource_type": "template" },
"action": "update"
},
"deleteTemplates": {
"object": { "resource_type": "template" },
"action": "delete"
},
"viewDeploymentConfig": {
"object": { "resource_type": "deployment_config" },
"action": "read"
},
"editDeploymentConfig": {
"object": { "resource_type": "deployment_config" },
"action": "update"
},
"viewDeploymentStats": {
"object": { "resource_type": "deployment_stats" },
"action": "read"
},
"readWorkspaceProxies": {
"object": { "resource_type": "workspace_proxy" },
"action": "read"
},
"editWorkspaceProxies": {
"object": { "resource_type": "workspace_proxy" },
"action": "create"
},
"createOrganization": {
"object": { "resource_type": "organization" },
"action": "create"
},
"viewAnyGroup": {
"object": { "resource_type": "group" },
"action": "read"
},
"createGroup": {
"object": { "resource_type": "group" },
"action": "create"
},
"viewAllLicenses": {
"object": { "resource_type": "license" },
"action": "read"
},
"viewNotificationTemplate": {
"object": { "resource_type": "notification_template" },
"action": "read"
},
"viewOrganizationIDPSyncSettings": {
"object": { "resource_type": "idpsync_settings" },
"action": "read"
},
"viewAnyMembers": {
"object": { "resource_type": "organization_member", "any_org": true },
"action": "read"
},
"editAnyGroups": {
"object": { "resource_type": "group", "any_org": true },
"action": "update"
},
"assignAnyRoles": {
"object": { "resource_type": "assign_org_role", "any_org": true },
"action": "assign"
},
"viewAnyIdpSyncSettings": {
"object": { "resource_type": "idpsync_settings", "any_org": true },
"action": "read"
},
"editAnySettings": {
"object": { "resource_type": "organization", "any_org": true },
"action": "update"
},
"viewAnyAuditLog": {
"object": { "resource_type": "audit_log", "any_org": true },
"action": "read"
},
"viewAnyConnectionLog": {
"object": { "resource_type": "connection_log", "any_org": true },
"action": "read"
},
"viewDebugInfo": {
"object": { "resource_type": "debug_info" },
"action": "read"
},
"viewAnyAIBridgeInterception": {
"object": { "resource_type": "aibridge_interception", "any_org": true },
"action": "read"
},
"createOAuth2App": {
"object": { "resource_type": "oauth2_app" },
"action": "create"
},
"editOAuth2App": {
"object": { "resource_type": "oauth2_app" },
"action": "update"
},
"deleteOAuth2App": {
"object": { "resource_type": "oauth2_app" },
"action": "delete"
},
"viewOAuth2AppSecrets": {
"object": { "resource_type": "oauth2_app_secret" },
"action": "read"
}
}