fix(resources): probe passwordless instances

This commit is contained in:
chick
2026-07-19 00:51:55 +08:00
parent 23f18963ef
commit 4e7bdea230
2 changed files with 32 additions and 3 deletions
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { parseSim, parseStats } from './instance-resource-service.js'; import { InstanceResourceService, parseSim, parseStats } from './instance-resource-service.js';
const response = (body: unknown) => ({ const response = (body: unknown) => ({
status: 200, status: 200,
@@ -41,6 +41,31 @@ describe('instance resource allowlist parsing', () => {
).toEqual({ phoneNumbers: ['+86 138-0000-0000'] }); ).toEqual({ phoneNumbers: ['+86 138-0000-0000'] });
}); });
it('probes passwordless instances without manufacturing a cookie', async () => {
const requests: Array<{ headers: Readonly<Record<string, string>> }> = [];
const service = new InstanceResourceService({
instances: { get: async () => ({ origin: 'http://192.168.3.55:3000' }) } as never,
sessions: { sessionFor: () => undefined } as never,
request: async (request) => {
requests.push(request);
return response(
request.url.endsWith('/api/stats')
? { data: { cpu_load: { load_percent: 12 }, memory: { used_percent: 34 } } }
: { data: { phone_numbers: ['13800000000'] } },
);
},
});
await expect(service.get('device-1')).resolves.toEqual({
cpuPercent: 12,
memoryPercent: 34,
phoneNumbers: ['13800000000'],
});
expect(requests.map((request) => request.headers)).toEqual([
{ accept: 'application/json' },
{ accept: 'application/json' },
]);
});
it('fails closed for malformed and oversized payloads', () => { it('fails closed for malformed and oversized payloads', () => {
expect(parseStats({ status: 200, headers: {}, body: '{' })).toEqual({}); expect(parseStats({ status: 200, headers: {}, body: '{' })).toEqual({});
expect(parseSim({ status: 200, headers: {}, body: 'x'.repeat(40_000) })).toEqual({}); expect(parseSim({ status: 200, headers: {}, body: 'x'.repeat(40_000) })).toEqual({});
@@ -77,12 +77,16 @@ export class InstanceResourceService {
this.options.instances.get(instanceId), this.options.instances.get(instanceId),
Promise.resolve(this.options.sessions.sessionFor(instanceId)), Promise.resolve(this.options.sessions.sessionFor(instanceId)),
]); ]);
if (!instance || !session || session.origin !== instance.origin) return {}; if (!instance) return {};
if (session && session.origin !== instance.origin) return {};
const get = (path: '/api/stats' | '/api/sim') => const get = (path: '/api/stats' | '/api/sim') =>
this.options.request({ this.options.request({
url: `${instance.origin}${path}`, url: `${instance.origin}${path}`,
method: 'GET', method: 'GET',
headers: { cookie: session.cookie, accept: 'application/json' }, headers: {
accept: 'application/json',
...(session ? { cookie: session.cookie } : {}),
},
}); });
const [stats, sim] = await Promise.allSettled([get('/api/stats'), get('/api/sim')]); const [stats, sim] = await Promise.allSettled([get('/api/stats'), get('/api/sim')]);
return { return {