fix(cli): disable web self update execution

This commit is contained in:
digua authored and digua committed 2026-05-26 23:19:47 +08:00
1 parent 5a524b8abf
commit c736fdc93b
5 files changed
+26 -49

No files matched your search

-17
View File
@@ -1,17 +0,0 @@
import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import { createServer } from './server'
import { setAuthToken } from './auth'
describe('CLI HTTP auth hook', () => {
it('requires bearer token for the CLI self-update endpoint under /_web', async () => {
setAuthToken('clb_test_token')
const app = createServer()
app.post('/_web/system/update', async () => ({ success: true }))
const response = await app.inject({ method: 'POST', url: '/_web/system/update' })
await app.close()
assert.equal(response.statusCode, 401)
})
})
-5
View File
@@ -10,7 +10,6 @@ import { unauthorized, errorResponse } from './errors'
let cachedToken: string | null = null
let webModeEnabled = false
const protectedWebPaths = new Set(['/_web/system/update'])
/**
* 设置 auth hook 使用的 token(由 server 启动时注入)
@@ -37,10 +36,6 @@ function safeTokenCompare(a: string, b: string): boolean {
export async function authHook(request: FastifyRequest, reply: FastifyReply): Promise<void> {
if (!cachedToken) return
if (protectedWebPaths.has(request.url.split('?')[0])) {
return requireBearerToken(request, reply)
}
// /_web/ internal API: no auth required (same-origin Web UI only)
if (request.url.startsWith('/_web/')) return
-17
View File
@@ -19,7 +19,6 @@
import * as os from 'os'
import * as path from 'path'
import { execFile } from 'child_process'
import type { FastifyInstance } from 'fastify'
import type { PathProvider } from '@openchatlab/core'
import type { DatabaseManager } from '@openchatlab/node-runtime'
@@ -119,20 +118,4 @@ export function registerWebRoutes(
}
}
})
server.post('/_web/system/update', async () => {
const packageName = 'chatlab-cli'
try {
await new Promise<void>((resolve, reject) => {
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'
execFile(npmCmd, ['install', '-g', `${packageName}@latest`], { timeout: 120_000 }, (err, _stdout, stderr) => {
if (err) return reject(new Error(stderr || err.message))
resolve()
})
})
return { success: true }
} catch (err) {
return { success: false, error: err instanceof Error ? err.message : String(err) }
}
})
}
+23
View File
@@ -0,0 +1,23 @@
import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import { WebPlatformAdapter } from './web'
describe('WebPlatformAdapter', () => {
it('does not bootstrap self-update auth from public web config', async () => {
const originalFetch = globalThis.fetch
const requestedUrls: string[] = []
globalThis.fetch = ((input: RequestInfo | URL) => {
requestedUrls.push(String(input))
return Promise.resolve(new Response('{}'))
}) as typeof fetch
try {
const result = await new WebPlatformAdapter().performUpdate()
assert.equal(result.success, false)
assert.equal(requestedUrls.length, 0)
} finally {
globalThis.fetch = originalFetch
}
})
})
+3 -10
View File
@@ -73,16 +73,9 @@ export class WebPlatformAdapter implements PlatformAdapter {
}
async performUpdate(): Promise<PerformUpdateResult> {
try {
const configResp = await fetch('/_web/automation/config')
const config = (await configResp.json()) as { token?: string }
const headers: Record<string, string> = {}
if (config.token) headers.Authorization = `Bearer ${config.token}`
const resp = await fetch('/_web/system/update', { method: 'POST', headers })
return await resp.json()
} catch (err) {
return { success: false, error: err instanceof Error ? err.message : String(err) }
return {
success: false,
error: 'Web update is unavailable. Run npm install -g chatlab-cli@latest in your terminal.',
}
}