mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
chore(cloud): dev-only probe of the org the Orca Cloud token claims (GH-LIST-MISSING diagnostics)
Dev builds only: globalThis.__orcaCloudTokenClaims() in the main process returns { org, orgRole,
sub } from the current sandbox token's payload, never the token. Packaged builds install nothing.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import { installDevTokenClaimsProbe, tokenOrgClaims } from './dev-token-claims-probe'
|
||||
|
||||
const encode = (value: unknown): string => Buffer.from(JSON.stringify(value)).toString('base64url')
|
||||
const jwt = (claims: unknown): string => `${encode({ alg: 'ES256' })}.${encode(claims)}.sig`
|
||||
|
||||
describe('dev token claims probe (GH-LIST-MISSING)', () => {
|
||||
afterEach(() => {
|
||||
Reflect.deleteProperty(globalThis, '__orcaCloudTokenClaims')
|
||||
})
|
||||
|
||||
it('reads only org, role and user from the payload', () => {
|
||||
expect(tokenOrgClaims(jwt({ sub: 'u1', org: 'o1', org_role: 'owner', exp: 1 }))).toEqual({
|
||||
org: 'o1',
|
||||
orgRole: 'owner',
|
||||
sub: 'u1'
|
||||
})
|
||||
expect(tokenOrgClaims(jwt({ sub: 'u1' }))).toEqual({ org: null, orgRole: null, sub: 'u1' })
|
||||
expect(tokenOrgClaims('not-a-token')).toEqual({ org: null, orgRole: null, sub: null })
|
||||
})
|
||||
|
||||
it('exists only in dev builds, and never hands back the token', async () => {
|
||||
expect(installDevTokenClaimsProbe(async () => jwt({ sub: 'u1', org: 'o1' }), true)).toBeNull()
|
||||
expect('__orcaCloudTokenClaims' in globalThis).toBe(false)
|
||||
const probe = installDevTokenClaimsProbe(async () => jwt({ sub: 'u1', org: 'o1' }), false)
|
||||
expect('__orcaCloudTokenClaims' in globalThis).toBe(true)
|
||||
const answer = await probe?.()
|
||||
expect(answer).toEqual({ org: 'o1', orgRole: null, sub: 'u1' })
|
||||
expect(JSON.stringify(answer)).not.toContain('sig')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
// GH-LIST-MISSING diagnostics, dev builds only: which org the Orca Cloud token in use claims, next
|
||||
// to the team the app shows. A token minted for another team (or none) explains an empty GitHub
|
||||
// list after an owner → member → owner switch. Never the token itself, and never in packaged builds.
|
||||
|
||||
type ClaimsProbe = () => Promise<{ org: string | null; orgRole: string | null; sub: string | null }>
|
||||
|
||||
/** Reads the claims of a JWT's payload without verifying it; nothing else of the token leaves. */
|
||||
export function tokenOrgClaims(token: string): Awaited<ReturnType<ClaimsProbe>> {
|
||||
const payload = token.split('.')[1]
|
||||
let claims: Record<string, unknown> = {}
|
||||
try {
|
||||
const parsed: unknown = JSON.parse(Buffer.from(payload ?? '', 'base64url').toString('utf8'))
|
||||
if (parsed && typeof parsed === 'object') {
|
||||
claims = { ...parsed }
|
||||
}
|
||||
} catch {
|
||||
// Not a JWT: report nothing rather than guess.
|
||||
}
|
||||
const text = (value: unknown): string | null => (typeof value === 'string' ? value : null)
|
||||
return { org: text(claims.org), orgRole: text(claims.org_role), sub: text(claims.sub) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Dev builds: `globalThis.__orcaCloudTokenClaims()` in the main process (the harness's inspector)
|
||||
* answers the org, role and user the current sandbox token claims.
|
||||
*/
|
||||
export function installDevTokenClaimsProbe(
|
||||
getAccessToken: () => Promise<string>,
|
||||
packaged: boolean
|
||||
): ClaimsProbe | null {
|
||||
if (packaged) {
|
||||
return null
|
||||
}
|
||||
const probe: ClaimsProbe = async () => tokenOrgClaims(await getAccessToken())
|
||||
Object.assign(globalThis, { __orcaCloudTokenClaims: probe })
|
||||
return probe
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { installDevTokenClaimsProbe } from './dev-token-claims-probe'
|
||||
import { cloudDevSigningAllowed, withCloudBuildDefaults } from '../cloud-build-defaults'
|
||||
import {
|
||||
findCloudRuntimeBySandboxId,
|
||||
@@ -132,6 +133,7 @@ export function installHostedSandbox(
|
||||
// A cloud list refresh or a not-found status read asks for the prune now (LC-2).
|
||||
setCloudGonePruneRunner(() => accountBackfill.run({ force: true }))
|
||||
installLocalCommands(userDataPath)
|
||||
installDevTokenClaimsProbe(() => config.getAccessToken(), app.isPackaged)
|
||||
const mcpSync = installCloudMcpSync(userDataPath, {
|
||||
baseUrl: config.controlPlaneUrl,
|
||||
getAccessToken: config.getAccessToken
|
||||
|
||||
Reference in New Issue
Block a user