| 1 | import * as Schema from "effect/Schema"; |
| 2 | import { GitPreparePullRequestThreadInput } from "./git.ts"; |
| 3 | import { |
| 4 | AuthOrchestrationOperateScope, |
| 5 | AuthTerminalOperateScope, |
| 6 | AuthFilesystemReadScope, |
| 7 | AuthOrchestrationReadScope, |
| 8 | AuthSettingsWriteScope, |
| 9 | AuthSourceControlWriteScope, |
| 10 | type AuthEnvironmentScope, |
| 11 | } from "./auth.ts"; |
| 12 | import { ORCHESTRATION_V2_WS_METHODS } from "./orchestrationV2.ts"; |
| 13 | import { WS_METHODS } from "./rpc.ts"; |
| 14 | |
| 15 | /** Incremental client enforcement; the server still authorizes every request. */ |
| 16 | export const CLIENT_GUARDED_RPC_SCOPES = { |
| 17 | [WS_METHODS.uiSettingsPatch]: AuthSettingsWriteScope, |
| 18 | [WS_METHODS.devServerStatus]: AuthFilesystemReadScope, |
| 19 | [WS_METHODS.devServerStart]: AuthTerminalOperateScope, |
| 20 | [WS_METHODS.managedWorkspacesCreate]: AuthOrchestrationOperateScope, |
| 21 | [WS_METHODS.managedWorkspacesArchiveCompleted]: AuthOrchestrationOperateScope, |
| 22 | [WS_METHODS.serverRunStorageCleanup]: AuthSettingsWriteScope, |
| 23 | // Endpoint checks exist to configure exports, so they need the same grant as saving them. |
| 24 | [WS_METHODS.serverCheckOtlpEndpoint]: AuthSettingsWriteScope, |
| 25 | [WS_METHODS.pullRequestsRunAction]: AuthSourceControlWriteScope, |
| 26 | [WS_METHODS.mergebotOpenPullRequest]: AuthSourceControlWriteScope, |
| 27 | [WS_METHODS.mergebotSetAutoMerge]: AuthSourceControlWriteScope, |
| 28 | [WS_METHODS.mergebotUpdatePullRequest]: AuthSourceControlWriteScope, |
| 29 | [WS_METHODS.mergebotDeployProduction]: AuthSourceControlWriteScope, |
| 30 | [WS_METHODS.jjDescribe]: AuthSourceControlWriteScope, |
| 31 | [WS_METHODS.jjSquash]: AuthSourceControlWriteScope, |
| 32 | [WS_METHODS.jjPush]: AuthSourceControlWriteScope, |
| 33 | [WS_METHODS.pullRequestsUpdate]: AuthSourceControlWriteScope, |
| 34 | [WS_METHODS.pullRequestsComment]: AuthSourceControlWriteScope, |
| 35 | [WS_METHODS.pullRequestsUpdateComment]: AuthSourceControlWriteScope, |
| 36 | [WS_METHODS.pullRequestsSubmitReview]: AuthSourceControlWriteScope, |
| 37 | [WS_METHODS.pullRequestsReplyToThread]: AuthSourceControlWriteScope, |
| 38 | [WS_METHODS.pullRequestsSetThreadResolution]: AuthSourceControlWriteScope, |
| 39 | [WS_METHODS.pullRequestsSetReaction]: AuthSourceControlWriteScope, |
| 40 | [WS_METHODS.pullRequestsSetFilesViewed]: AuthSourceControlWriteScope, |
| 41 | [WS_METHODS.pullRequestsRequestReviewers]: AuthSourceControlWriteScope, |
| 42 | [WS_METHODS.pullRequestsSetLabels]: AuthSourceControlWriteScope, |
| 43 | // Writing a guide runs a model on this environment's providers, which reading one does not. |
| 44 | [WS_METHODS.pullRequestsGenerateReviewGuide]: AuthOrchestrationOperateScope, |
| 45 | [WS_METHODS.sourceControlCloneRepository]: AuthSourceControlWriteScope, |
| 46 | [WS_METHODS.sourceControlPublishRepository]: AuthSourceControlWriteScope, |
| 47 | [WS_METHODS.projectCloneStart]: AuthSourceControlWriteScope, |
| 48 | [WS_METHODS.projectCloneCancel]: AuthSourceControlWriteScope, |
| 49 | [WS_METHODS.projectCloneRetry]: AuthSourceControlWriteScope, |
| 50 | [WS_METHODS.vcsPull]: AuthSourceControlWriteScope, |
| 51 | [WS_METHODS.gitRunStackedAction]: AuthSourceControlWriteScope, |
| 52 | [WS_METHODS.gitPreparePullRequestThread]: AuthSourceControlWriteScope, |
| 53 | [WS_METHODS.vcsCreateWorktree]: AuthSourceControlWriteScope, |
| 54 | [WS_METHODS.vcsRemoveWorktree]: AuthSourceControlWriteScope, |
| 55 | [WS_METHODS.vcsCreateRef]: AuthSourceControlWriteScope, |
| 56 | [WS_METHODS.vcsSwitchRef]: AuthSourceControlWriteScope, |
| 57 | [WS_METHODS.vcsInit]: AuthSourceControlWriteScope, |
| 58 | |
| 59 | [WS_METHODS.scheduledTasksUpsert]: AuthOrchestrationOperateScope, |
| 60 | [WS_METHODS.scheduledTasksSetEnabled]: AuthOrchestrationOperateScope, |
| 61 | [WS_METHODS.scheduledTasksDelete]: AuthOrchestrationOperateScope, |
| 62 | [WS_METHODS.scheduledTasksRunNow]: AuthOrchestrationOperateScope, |
| 63 | [WS_METHODS.scheduledTasksRotateWebhookToken]: AuthOrchestrationOperateScope, |
| 64 | [ORCHESTRATION_V2_WS_METHODS.stopWorkflow]: AuthOrchestrationOperateScope, |
| 65 | } as const; |
| 66 | export type ClientGuardedRpcTag = keyof typeof CLIENT_GUARDED_RPC_SCOPES; |
| 67 | |
| 68 | const decodePrepareThread = Schema.decodeUnknownSync(GitPreparePullRequestThreadInput); |
| 69 | |
| 70 | export function clientRpcRequiredScopes( |
| 71 | method: string, |
| 72 | input: unknown, |
| 73 | ): readonly AuthEnvironmentScope[] { |
| 74 | if (method === WS_METHODS.devServerStatus) |
| 75 | return [AuthFilesystemReadScope, AuthOrchestrationReadScope]; |
| 76 | if (method === WS_METHODS.gitPreparePullRequestThread && input !== undefined) { |
| 77 | const payload = decodePrepareThread(input); |
| 78 | if (payload.mode === "worktree" && payload.threadId !== undefined) |
| 79 | return [AuthSourceControlWriteScope, AuthOrchestrationOperateScope]; |
| 80 | } |
| 81 | return Object.hasOwn(CLIENT_GUARDED_RPC_SCOPES, method) |
| 82 | ? [CLIENT_GUARDED_RPC_SCOPES[method as ClientGuardedRpcTag]] |
| 83 | : []; |
| 84 | } |