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
14 changes: 13 additions & 1 deletion kernel/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
// Only three values are app-specific across the whole kernel: the id the
// release manifest is signed with, the display name that appears in window
// titles and save dialogs, and where updates are fetched from. Everything
// else in the kernel is genuinely app-agnostic.
// else in the kernel is genuinely app-agnostic. Two OPTIONAL values exist for
// a fork that runs its own release channel and relay: the signing public key
// and the default sync host. Absent, the platform defaults apply unchanged.
//
// Deliberately NOT a general "kernel init" — modules that need no config
// (anim, charts) take none, so there is no import-order trap and no false
Expand All @@ -24,6 +26,16 @@ export interface AppConfig {
appName: string
/** Release manifest URL. Dev override: localStorage 'bento-update-url'. */
manifestUrl: string
/** Release-signing PUBLIC key (P-256 JWK) that manifests and pack indexes
* are verified against. Optional: absent, the kernel uses the platform key
* embedded in update.ts. A fork that publishes its own signed channel sets
* this so its shipped files never accept a manifest signed by another key
* (appId already refuses another app; this refuses another PUBLISHER). */
publicKeyJwk?: { kty: 'EC'; crv: 'P-256'; x: string; y: string }
/** Default relay host for collaboration (wss://…). Optional: absent, the
* kernel uses DEFAULT_SYNC_HOST in sync/online.ts. The localStorage
* 'bento-sync-url' dev override wins over both. */
syncHost?: string
}

let config: AppConfig | null = null
Expand Down
11 changes: 8 additions & 3 deletions kernel/src/sync/online.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { offlineEnabled } from '../update.ts'
// Every request in the app goes through the one chokepoint (kernel/src/net.ts)
// so the offline switch cannot be forgotten — see GHSA-5c3x-xqp6-g94r.
import { netWebSocket } from '../net.ts'
import { appConfig } from '../app.ts'

/** the app's store, structurally — see session.ts HostStore */
type Store = HostStore
Expand Down Expand Up @@ -144,12 +145,16 @@ export async function mintCollab(): Promise<CollabCreds> {
}
}

/** dev override for the relay host (e.g. ws://localhost:8787) */
/** The relay host: the localStorage dev override (e.g. ws://localhost:8787),
* else the host the app configured (a fork running its own relay), else the
* platform default. Rigs that never call configureApp() get the default. */
export function syncHost(): string {
let configured: string | undefined
try { configured = appConfig().syncHost } catch { /* not configured: platform default */ }
try {
return lsGet('bento-sync-url') || DEFAULT_SYNC_HOST
return lsGet('bento-sync-url') || configured || DEFAULT_SYNC_HOST
} catch {
return DEFAULT_SYNC_HOST
return configured || DEFAULT_SYNC_HOST
}
}

Expand Down
4 changes: 3 additions & 1 deletion kernel/src/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ export async function verifySigned(raw: string, what = 'signed file'): Promise<u
throw new Error(`the ${what} is malformed`)

const key = await crypto.subtle.importKey(
'jwk', PUBLIC_KEY_JWK as JsonWebKey,
// A fork with its own release channel supplies its key via configureApp();
// the platform key below is the default so upstream builds are unchanged.
'jwk', (appConfig().publicKeyJwk ?? PUBLIC_KEY_JWK) as JsonWebKey,
{ name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify'],
)
const ok = await crypto.subtle.verify(
Expand Down
Loading