fix(config): harden remote and identity validation
This commit is contained in:
@@ -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}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user