test: harden business boundary conditions
This commit is contained in:
@@ -205,13 +205,21 @@ export class IntegrationConfigService {
|
||||
|
||||
/** 调钉钉新版接口拿 access_token */
|
||||
private async fetchDingTalkToken(appKey: string, appSecret: string): Promise<string | null> {
|
||||
const res = await fetch('https://api.dingtalk.com/v1.0/oauth2/accessToken', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ appKey, appSecret }),
|
||||
});
|
||||
const body = (await res.json()) as { accessToken?: string; expireIn?: number };
|
||||
return body.accessToken || null;
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 10_000);
|
||||
try {
|
||||
const res = await fetch('https://api.dingtalk.com/v1.0/oauth2/accessToken', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ appKey, appSecret }),
|
||||
signal: controller.signal,
|
||||
});
|
||||
if (!res.ok) return null;
|
||||
const body = (await res.json()) as { accessToken?: string; expireIn?: number };
|
||||
return body.accessToken || null;
|
||||
} finally {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/** 解析并脱敏:删掉 appSecret 后返回 config 对象 */
|
||||
@@ -219,9 +227,10 @@ export class IntegrationConfigService {
|
||||
if (!content) return {};
|
||||
try {
|
||||
const parsed = JSON.parse(content);
|
||||
const cfg = parsed.config || parsed;
|
||||
if (cfg.appSecret) delete cfg.appSecret;
|
||||
return cfg;
|
||||
const source = parsed.config || parsed;
|
||||
if (!source || typeof source !== 'object' || Array.isArray(source)) return {};
|
||||
const { appSecret: _appSecret, ...masked } = source as Record<string, unknown>;
|
||||
return masked;
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user