fix(coding): remediate ML-07 plugin authority

This commit is contained in:
2026-08-27 20:40:58 +08:00
parent 9407c67df2
commit cf13aa7eba
29 changed files with 1008 additions and 214 deletions

View File

@@ -1,5 +1,5 @@
import { WORKS_SQUARE_CONFIG } from '../api/works-config';
import { proxyAwareFetch } from '../utils/proxy-fetch';
import { proxyAwareFetch, runWithDeadline } from '../utils/proxy-fetch';
const MAX_CATALOG_BYTES = 1_310_720;
const MAX_CATALOG_VERSION = 64;
@@ -7,6 +7,7 @@ const MAX_PLUGIN_ID = 48;
const MAX_CAPABILITY_ID = 64;
const MAX_OPERATION_ID = 64;
const MAX_NOTICE = 160;
const DEFAULT_POLICY_REQUEST_TIMEOUT_MS = 10_000;
const PLUGIN_ID_PATTERN = /^[a-z][a-z0-9.-]{0,47}$/u;
const CAPABILITY_ID_PATTERN = /^[a-z][a-z0-9.-]{0,63}$/u;
const OPERATION_ID_PATTERN = /^[a-z][a-z0-9._-]{0,63}$/u;
@@ -86,6 +87,7 @@ export interface PluginPolicyClientOptions {
fetchImpl?: FetchImplementation;
apiBaseUrl?: string;
now?: () => number;
requestTimeoutMs?: number;
}
export class PluginPolicyCatalogError extends Error {
@@ -384,6 +386,7 @@ export class PluginPolicyClient {
private readonly fetchImpl: FetchImplementation;
private readonly apiBaseUrl: string;
private readonly now: () => number;
private readonly requestTimeoutMs: number;
private state: PluginPolicyClientState = {
status: 'unavailable',
catalog: null,
@@ -396,6 +399,7 @@ export class PluginPolicyClient {
this.fetchImpl = options.fetchImpl ?? proxyAwareFetch;
this.apiBaseUrl = (options.apiBaseUrl ?? WORKS_SQUARE_CONFIG.apiBaseUrl).replace(/\/+$/u, '');
this.now = options.now ?? (() => Date.now());
this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_POLICY_REQUEST_TIMEOUT_MS;
}
getState(): PluginPolicyClientState {
@@ -442,24 +446,26 @@ export class PluginPolicyClient {
}
private async fetchCatalog(): Promise<PluginCatalog> {
let response: Response;
try {
response = await this.fetchImpl(
`${this.apiBaseUrl}/api/plugins/v1/catalog`,
{
method: 'GET',
headers: { Accept: 'application/json' },
redirect: 'manual',
},
);
return await runWithDeadline(async (signal) => {
const response = await this.fetchImpl(
`${this.apiBaseUrl}/api/plugins/v1/catalog`,
{
method: 'GET',
headers: { Accept: 'application/json' },
redirect: 'manual',
signal,
},
);
if (!response.ok) {
await response.body?.cancel().catch(() => undefined);
throw new PluginPolicyCatalogError('catalog request failed');
}
return await readCatalog(response);
}, this.requestTimeoutMs);
} catch {
throw new PluginPolicyCatalogError('catalog request failed');
}
if (!response.ok) {
await response.body?.cancel().catch(() => undefined);
throw new PluginPolicyCatalogError('catalog request failed');
}
return await readCatalog(response);
}
}