MCPcopy Create free account
hub / github.com/TraderAlice/OpenAlice / start

Method start

src/webui/plugin.ts:94–340  ·  view source on GitHub ↗
(ctx: EngineContext)

Source from the content-addressed store, hash-verified

92 ) {}
93
94 async start(ctx: EngineContext) {
95 // ==================== Auth bootstrap ====================
96 // Generate the admin token on first run; subsequent boots no-op.
97 // We do this BEFORE any route mounts so the public-mode safety
98 // check below has a meaningful auth-file state to read.
99 const { bootstrapToken, getTokenInfo } = await import('@/services/auth/index.js')
100 await bootstrapToken({
101 onFirstGeneration: (token) => {
102 console.log('')
103 console.log('═══════════════════════════════════════════════════════════════')
104 console.log(' First-run admin token (save this — won\'t be shown again):')
105 console.log('')
106 console.log(` ${token}`)
107 console.log('')
108 console.log(' To rotate: delete data/config/auth.json and restart.')
109 console.log('═══════════════════════════════════════════════════════════════')
110 console.log('')
111 },
112 })
113
114 // ==================== Public-mode safety net ====================
115 // Refuse to start if Alice is bound to a non-localhost interface
116 // without an admin token configured. Prevents the "I set
117 // OPENALICE_BIND_HOST=0.0.0.0 for testing and forgot auth" footgun.
118 const bindHost = (process.env['OPENALICE_BIND_HOST'] ?? '127.0.0.1').trim()
119 const bindIsPublic = bindHost !== '127.0.0.1' && bindHost !== '::1' && bindHost !== 'localhost'
120 if (bindIsPublic) {
121 const tokenInfo = await getTokenInfo()
122 if (!tokenInfo.exists && process.env['OPENALICE_DISABLE_AUTH'] !== '1') {
123 throw new Error(
124 `Refusing to start: OPENALICE_BIND_HOST="${bindHost}" exposes Alice ` +
125 `to non-localhost callers, but no admin token has been provisioned. ` +
126 `Start once with OPENALICE_BIND_HOST=127.0.0.1 to generate the token, ` +
127 `then re-set the bind. Set OPENALICE_DISABLE_AUTH=1 only when you ` +
128 `understand the implication (no protection at the Alice boundary).`
129 )
130 }
131 }
132
133 // Load sub-channel definitions
134 const subChannels = await readWebSubchannels()
135
136 // Initialize sessions for the default channel and all sub-channels
137 const sessions = new Map<string, SessionStore>()
138
139 const defaultSession = new SessionStore('web/default')
140 await defaultSession.restore()
141 sessions.set('default', defaultSession)
142
143 for (const ch of subChannels) {
144 const session = new SessionStore(`web/${ch.id}`)
145 await session.restore()
146 sessions.set(ch.id, session)
147 }
148
149 // Initialize SSE map for known channels (entries are created lazily too)
150 this.sseByChannel.set('default', new Map())
151 for (const ch of subChannels) {

Callers

nothing calls this directly

Calls 15

restoreMethod · 0.95
bootstrapTokenFunction · 0.85
getTokenInfoFunction · 0.85
readWebSubchannelsFunction · 0.85
mountLocalToolGatewayFunction · 0.85
createAuthRoutesFunction · 0.85
createAuthMiddlewareFunction · 0.85
createChannelsRoutesFunction · 0.85
createMediaRoutesFunction · 0.85
createConfigRoutesFunction · 0.85
createMarketDataRoutesFunction · 0.85
createEventsRoutesFunction · 0.85

Tested by

no test coverage detected