From bc0df064457ead64223a4d4f3570f2cd56b92d96 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Fri, 26 Jun 2026 09:20:57 +0000 Subject: [PATCH] =?UTF-8?q?fix(TLS=20=E9=A9=97=E8=AD=89):=20=E5=A5=97?= =?UTF-8?q?=E7=94=A8=E5=85=A8=E5=9F=9F=E6=86=91=E8=AD=89=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/config.js | 12 ++++++++---- app/git.js | 8 +++++++- app/gitea.js | 5 ++--- app/preflight.js | 4 ++-- app/usage.js | 2 ++ 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/app/config.js b/app/config.js index 3f205d1..c92f2b1 100644 --- a/app/config.js +++ b/app/config.js @@ -1,5 +1,7 @@ import https from 'https'; +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + export const GITEA_TOKEN = process.env.GITEA_TOKEN || ''; export const GITEA_COMMENT_TOKEN = process.env.GITEA_COMMENT_TOKEN || ''; export const GITEA_SERVER_URL = process.env.GITEA_SERVER_URL || 'https://gitea.com'; @@ -14,18 +16,20 @@ export const EXCLUSIONS_PATH = '.gitea/ai-review/exclusions.json'; /** * 建立一個停用 TLS 憑證驗證(`rejectUnauthorized: false`)的 HTTPS Agent, - * 供連接使用自簽或無效憑證的 OpenCode 服務時使用。 + * 供連接使用自簽或無效憑證的內部服務時使用。 * * @remarks 首次呼叫時建立,之後快取為模組層級單例(singleton)重複使用, * 避免每次都新建 Agent 與連線池、浪費 TCP 三次握手。 * 停用憑證驗證有中間人攻擊風險,僅限受信任的內部環境使用。 * @returns {import('https').Agent} 已關閉憑證驗證的 HTTPS Agent 單例。 */ -let _openCodeHttpsAgent = null; -export function getOpenCodeHttpsAgent() { - return (_openCodeHttpsAgent ??= new https.Agent({ rejectUnauthorized: false })); +let _insecureHttpsAgent = null; +export function getInsecureHttpsAgent() { + return (_insecureHttpsAgent ??= new https.Agent({ rejectUnauthorized: false })); } +export const getOpenCodeHttpsAgent = getInsecureHttpsAgent; + /** * 依環境變數解析並回傳 LLM 提供者設定。 * diff --git a/app/git.js b/app/git.js index 8fc9423..ea8146e 100644 --- a/app/git.js +++ b/app/git.js @@ -61,7 +61,13 @@ function makeRunner(spawn) { function withAskpass(workspace, fn, token = GITEA_TOKEN) { const askpassScript = path.join(workspace, '.git-askpass.sh'); fs.writeFileSync(askpassScript, '#!/bin/sh\necho "$GIT_TOKEN"\n', { mode: 0o700 }); - const credEnv = { ...process.env, GIT_ASKPASS: askpassScript, GIT_USERNAME: 'x-token', GIT_TOKEN: token }; + const credEnv = { + ...process.env, + GIT_ASKPASS: askpassScript, + GIT_SSL_NO_VERIFY: 'true', + GIT_USERNAME: 'x-token', + GIT_TOKEN: token, + }; const cleanup = () => { try { fs.unlinkSync(askpassScript); } catch {} }; let result; try { diff --git a/app/gitea.js b/app/gitea.js index ccd6b49..3f06b0a 100644 --- a/app/gitea.js +++ b/app/gitea.js @@ -1,9 +1,8 @@ import axios from 'axios'; -import https from 'https'; -import { GITEA_TOKEN, GITEA_COMMENT_TOKEN, GITEA_SERVER_URL, GITEA_REPOSITORY, PR_NUMBER, PR_HEAD_SHA, PR_HEAD_BRANCH } from './config.js'; +import { GITEA_TOKEN, GITEA_COMMENT_TOKEN, GITEA_SERVER_URL, GITEA_REPOSITORY, PR_NUMBER, PR_HEAD_SHA, PR_HEAD_BRANCH, getInsecureHttpsAgent } from './config.js'; import { line, warn } from './log.js'; -const httpsAgent = new https.Agent({ rejectUnauthorized: false }); +const httpsAgent = getInsecureHttpsAgent(); /** * 產生呼叫 Gitea API 所需的 HTTP headers(含 Gitea token 授權與 JSON content-type)。 * 授權格式為 Gitea 專用的 `token `,並非 OAuth Bearer。 diff --git a/app/preflight.js b/app/preflight.js index 3f94fb6..90b8814 100644 --- a/app/preflight.js +++ b/app/preflight.js @@ -1,18 +1,18 @@ import axios from 'axios'; -import https from 'https'; import { GITEA_TOKEN, GITEA_COMMENT_TOKEN, GITEA_SERVER_URL, GITEA_REPOSITORY, PR_NUMBER, + getInsecureHttpsAgent, getOpenCodeHttpsAgent, getLLMConfig, } from './config.js'; import { verifyRemoteAccess } from './git.js'; import { step, line, ok, error, result } from './log.js'; -const httpsAgent = new https.Agent({ rejectUnauthorized: false }); +const httpsAgent = getInsecureHttpsAgent(); /** * 組出 Gitea REST API v1 的完整網址。 * diff --git a/app/usage.js b/app/usage.js index 9376b56..97eb2df 100644 --- a/app/usage.js +++ b/app/usage.js @@ -1,4 +1,5 @@ import axios from 'axios'; +import { getInsecureHttpsAgent } from './config.js'; import { warn } from './log.js'; /** 本次執行的 token 累計(跨所有 LLM 呼叫)。 */ @@ -176,6 +177,7 @@ async function fetchOpenRouterQuota({ apiKey, baseURL }, get) { const resp = await get(`${stripSlash(baseURL)}/auth/key`, { headers: { Authorization: `Bearer ${apiKey}` }, timeout: 30000, + httpsAgent: getInsecureHttpsAgent(), }); const d = resp.data?.data || {}; const used = num(d.usage);