Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions apps/desktop/src/main/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { describe, expect, it } from 'vitest'
import {
addressSpaceOverrideForOrigin,
canonicalOrigin,
createConfigStore,
DEFAULT_ORIGIN,
Expand Down Expand Up @@ -42,6 +43,17 @@ describe('partitionForOrigin', () => {
})
})

describe('addressSpaceOverrideForOrigin', () => {
it('marks only self-hosted deployment hosts as public', () => {
expect(addressSpaceOverrideForOrigin('https://sim.internal.example')).toBe(
'sim.internal.example=public'
)
expect(addressSpaceOverrideForOrigin('https://192.168.50.173')).toBe('192.168.50.173=public')
expect(addressSpaceOverrideForOrigin('https://www.sim.ai')).toBeNull()
expect(addressSpaceOverrideForOrigin('http://localhost:3000')).toBeNull()
})
})

describe('canonicalOrigin', () => {
it('keeps a rewritten install on its existing cookie partition', () => {
// The whole point of rewriting rather than leaving the apex in place: the
Expand Down
18 changes: 18 additions & 0 deletions apps/desktop/src/main/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,24 @@ export function isSimCloudOrigin(origin: string): boolean {
}
}

/**
* Chromium's Local Network Access checks reject a top-level navigation when a
* self-hosted deployment name resolves to RFC1918 space, before Electron can
* show a permission prompt or the request reaches the server. The configured
* Sim origin is an explicit trust decision and already owns the shell's preload
* bridge, so classify only that hostname as public instead of disabling the
* process-wide checks that protect arbitrary browser tabs.
*/
export function addressSpaceOverrideForOrigin(origin: string): string | null {
try {
const host = new URL(origin).hostname.toLowerCase()
if (isLoopbackHostname(host) || isSimCloudOrigin(origin)) return null
return `${host}=public`
} catch {
return null
}
}

/**
* Maps a server origin to its cookie/storage partition. Each origin gets an
* isolated persistent partition so sessions never leak across instances.
Expand Down
5 changes: 5 additions & 0 deletions apps/desktop/src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { NativeComputerUseClient } from '@/main/computer-use/native-client'
import { ComputerUseService } from '@/main/computer-use/service'
import {
APP_NAME_FOR_CHANNEL,
addressSpaceOverrideForOrigin,
channelForOrigin,
createConfigStore,
DEFAULT_ORIGIN,
Expand Down Expand Up @@ -156,6 +157,10 @@ function main(): void {
logger.error('Could not repair desktop settings for account-data recovery')
}
}
const addressSpaceOverride = addressSpaceOverrideForOrigin(config.getOrigin())
if (addressSpaceOverride) {
app.commandLine.appendSwitch('ip-address-space-overrides', addressSpaceOverride)
}
const accountDataAvailable = () =>
config.isPersistenceAvailable() && !isAccountDataTeardownRequired()
const events = createEventLog(join(userDataPath, 'logs'))
Expand Down