fix(config): harden remote and identity validation

This commit is contained in:
2026-09-05 01:36:10 +08:00
parent d1ad63983b
commit 73cdf7d95c
7 changed files with 89 additions and 23 deletions
@@ -21,16 +21,21 @@ function validateIdentity(identity: Partial<ChannelIdentity>): ChannelIdentity {
throw new Error(`Invalid identity: missing ${missing.join(', ')}`);
}
for (const key of ['agentid', 'channelid', 'marketid'] as const) {
if (typeof identity[key] !== 'string' && typeof identity[key] !== 'number') {
const value = identity[key];
if (typeof value !== 'string' && typeof value !== 'number') {
throw new Error(`Invalid identity: ${key} type`);
}
if (typeof value === 'number' && !Number.isFinite(value)) {
throw new Error(`Invalid identity: ${key} must be finite`);
}
}
if (typeof identity.gameid !== 'string') {
throw new Error('Invalid identity: gameid type');
}
if (typeof identity.version !== 'number' || !Number.isFinite(identity.version)) {
if (typeof identity.version !== 'number') {
throw new Error('Invalid identity: version type');
}
if (!Number.isFinite(identity.version)) throw new Error('Invalid identity: version must be finite');
return identity as ChannelIdentity;
}
@@ -1,5 +1,5 @@
import type { ConfigFetcher } from './remote-config.ts';
import { ConfigParseError } from './remote-config.ts';
import { ConfigFetchError, ConfigParseError } from './remote-config.ts';
type FetchImplementation = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
@@ -10,6 +10,9 @@ export class HttpConfigFetcher implements ConfigFetcher {
async fetch(gameserver: string, cacheBust: () => string = () => String(Date.now())): Promise<unknown> {
const url = `${gameserver}?${cacheBust()}`;
const response = await this.fetchImpl(url, { method: 'POST', body: '' });
if (response.status !== 200) {
throw new ConfigFetchError(`远程配置 HTTP 状态错误: status ${response.status}, url: ${url}`);
}
const text = await response.text();
try {
return JSON.parse(text) as unknown;
@@ -15,7 +15,12 @@ export class ConfigFetchError extends Error {}
export class ConfigParseError extends Error {}
function normalizeWebSocketUrl(value: string): string {
return value.startsWith('ws://') || value.startsWith('wss://') ? value : `ws://${value}`;
if (value.startsWith('ws://') || value.startsWith('wss://')) return value;
const scheme = /^([A-Za-z][A-Za-z0-9+.-]*):\/\//.exec(value);
if (scheme) {
throw new ConfigParseError(`远程配置 data.urlserver 不支持 scheme: ${scheme[1]}`);
}
return `ws://${value}`;
}
/**