fix(desktop): keep primary remote gateway extra headers on REST calls
createPrimaryRemoteConnection() rebuilt the primary remote descriptor field by field and left out `headers`, so every REST call routed through fetchJsonForBackend() (Settings profiles/config, session history) reached the gateway without the configured extra headers while chat, the Test button and the readiness probe -- which read the exact-URL WebSocket header store or the resolved route directly -- kept working. Behind an access proxy (e.g. a service-token gate) those REST calls came back as a 302 to the login page. Carry `headers` through the descriptor like every other rebuild site (buildRemoteConnection, the registry pool path and both ensureRegistryBackend reuse branches already spread it), and pin it with an invariant test on the existing primary-descriptor seam. Fixes #112072 Co-authored-by: plluviera <plluviera@users.noreply.github.com> Co-authored-by: KoNit-K <124019182+KoNit-K@users.noreply.github.com>
This commit is contained in:
@@ -50,6 +50,30 @@ test('primary remote descriptor preserves a resolved registry connection id', ()
|
||||
assert.equal(connection.isFullscreen, false)
|
||||
})
|
||||
|
||||
test('primary remote descriptor preserves the gateway extra headers for REST calls', () => {
|
||||
// Chat and the Test button carry the headers via the exact-URL WS store, but
|
||||
// fetchJsonForBackend reads descriptor.headers — dropping them here made every
|
||||
// Settings/session-history call hit an access proxy unauthenticated (#112072).
|
||||
const headers = { 'CF-Access-Client-Id': 'client-id', 'CF-Access-Client-Secret': 'client-secret' }
|
||||
|
||||
const connection = createPrimaryRemoteConnection(
|
||||
{
|
||||
authMode: 'token',
|
||||
baseUrl: 'https://gateway.example.com',
|
||||
connectionId: 'gateway',
|
||||
headers,
|
||||
remoteKind: 'url',
|
||||
source: 'settings',
|
||||
token: 'secret',
|
||||
wsUrl: 'wss://gateway.example.com/api/ws?token=secret'
|
||||
},
|
||||
[],
|
||||
{}
|
||||
)
|
||||
|
||||
assert.deepEqual(connection.headers, headers)
|
||||
})
|
||||
|
||||
test('primary remote descriptor preserves the effective SSH dialing identity', () => {
|
||||
const ssh = {
|
||||
effectiveConfigFingerprint: 'effective-config',
|
||||
|
||||
@@ -19,6 +19,7 @@ interface ResolvedPrimaryRemote {
|
||||
authMode?: 'oauth' | 'token'
|
||||
baseUrl: string
|
||||
connectionId?: string
|
||||
headers?: Record<string, string>
|
||||
remoteHermesVersion?: string
|
||||
remoteHost?: string
|
||||
remoteKind?: 'cloud' | 'ssh' | 'url'
|
||||
@@ -56,6 +57,9 @@ export function createPrimaryRemoteConnection<State extends object>(
|
||||
remoteHermesVersion: remote.remoteHermesVersion,
|
||||
...(remote.connectionId ? { connectionId: remote.connectionId } : {}),
|
||||
...(remote.ssh ? { ssh: remote.ssh } : {}),
|
||||
// fetchJsonForBackend reads descriptor.headers for every REST call; the
|
||||
// WebSocket header store is keyed by exact URL and cannot stand in for it.
|
||||
headers: remote.headers,
|
||||
token: remote.token,
|
||||
wsUrl: remote.wsUrl,
|
||||
logs,
|
||||
|
||||
Reference in New Issue
Block a user