mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 02:11:28 +00:00
fix: restrict local runtime readiness probes
This commit is contained in:
committed by
Tam Nhu Tran
parent
62a4d44b58
commit
9a7b26eab7
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { requireLocalAccessWhenAuthDisabled } from '../middleware/auth-middleware';
|
||||
import { isReservedName, RESERVED_PROFILE_NAMES } from '../../config/reserved-names';
|
||||
import {
|
||||
createApiProfile,
|
||||
@@ -30,6 +31,9 @@ import { isAnthropicDirectProfile, updateSettingsFile, parseTarget } from './rou
|
||||
|
||||
const router = Router();
|
||||
|
||||
const LOCAL_RUNTIME_READINESS_LOCAL_ACCESS_ERROR =
|
||||
'Local runtime readiness requires localhost access when dashboard auth is disabled.';
|
||||
|
||||
function isDenylistError(message: string | undefined): boolean {
|
||||
return typeof message === 'string' && message.toLowerCase().includes('denylist');
|
||||
}
|
||||
@@ -87,7 +91,11 @@ router.get('/cliproxy-bridge/providers', (_req: Request, res: Response): void =>
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/local-runtime-readiness', async (_req: Request, res: Response): Promise<void> => {
|
||||
router.get('/local-runtime-readiness', async (req: Request, res: Response): Promise<void> => {
|
||||
if (!requireLocalAccessWhenAuthDisabled(req, res, LOCAL_RUNTIME_READINESS_LOCAL_ACCESS_ERROR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
res.json({ runtimes: await getLocalRuntimeReadiness() });
|
||||
} catch (error) {
|
||||
|
||||
@@ -6,11 +6,20 @@ import profileRoutes from '../../../src/web-server/routes/profile-routes';
|
||||
describe('profile-routes local runtime readiness', () => {
|
||||
let server: Server;
|
||||
let baseUrl = '';
|
||||
let forcedRemoteAddress = '127.0.0.1';
|
||||
let originalDashboardAuthEnabled: string | undefined;
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
beforeAll(async () => {
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use((req, _res, next) => {
|
||||
Object.defineProperty(req.socket, 'remoteAddress', {
|
||||
value: forcedRemoteAddress,
|
||||
configurable: true,
|
||||
});
|
||||
next();
|
||||
});
|
||||
app.use('/api/profiles', profileRoutes);
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
@@ -36,6 +45,10 @@ describe('profile-routes local runtime readiness', () => {
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
originalDashboardAuthEnabled = process.env.CCS_DASHBOARD_AUTH_ENABLED;
|
||||
process.env.CCS_DASHBOARD_AUTH_ENABLED = 'false';
|
||||
forcedRemoteAddress = '127.0.0.1';
|
||||
|
||||
globalThis.fetch = (async (input: RequestInfo | URL) => {
|
||||
const url = String(input);
|
||||
|
||||
@@ -73,6 +86,12 @@ describe('profile-routes local runtime readiness', () => {
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.fetch = originalFetch;
|
||||
|
||||
if (originalDashboardAuthEnabled !== undefined) {
|
||||
process.env.CCS_DASHBOARD_AUTH_ENABLED = originalDashboardAuthEnabled;
|
||||
} else {
|
||||
delete process.env.CCS_DASHBOARD_AUTH_ENABLED;
|
||||
}
|
||||
});
|
||||
|
||||
it('reports local runtimes as ready when their endpoints respond with models', async () => {
|
||||
@@ -103,6 +122,30 @@ describe('profile-routes local runtime readiness', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('blocks remote readiness probes when dashboard auth is disabled', async () => {
|
||||
let probeCount = 0;
|
||||
forcedRemoteAddress = '10.10.0.24';
|
||||
globalThis.fetch = (async (input: RequestInfo | URL) => {
|
||||
const url = String(input);
|
||||
if (url.startsWith(baseUrl)) {
|
||||
return originalFetch(input);
|
||||
}
|
||||
probeCount += 1;
|
||||
return new Response(JSON.stringify({ models: [{ name: 'gemma4:e4b' }] }), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}) as typeof fetch;
|
||||
|
||||
const response = await fetch(`${baseUrl}/api/profiles/local-runtime-readiness`);
|
||||
|
||||
expect(response.status).toBe(403);
|
||||
expect(await response.json()).toEqual({
|
||||
error: 'Local runtime readiness requires localhost access when dashboard auth is disabled.',
|
||||
});
|
||||
expect(probeCount).toBe(0);
|
||||
});
|
||||
|
||||
it('reports setup guidance when local endpoints are unavailable', async () => {
|
||||
globalThis.fetch = (async (input: RequestInfo | URL) => {
|
||||
const url = String(input);
|
||||
|
||||
Reference in New Issue
Block a user