fix(設定與 release 取得): 補 GITEA_REPOSITORY 格式驗證並讓 JSON 解析錯誤帶回傳內容
This commit is contained in:
+37
-3
@@ -42,7 +42,19 @@ function normalizeBetaFlag(value) {
|
||||
return value === 'true';
|
||||
}
|
||||
|
||||
// 驗證字串為合法的 http/https URL,否則拋出錯誤(避免指向非預期協定或格式錯誤的位址)
|
||||
/**
|
||||
* 驗證字串為合法的 http/https URL,否則拋出錯誤(避免指向非預期協定或格式錯誤的位址)。
|
||||
*
|
||||
* 先以 `new URL(value)` 解析,無法解析時視為格式錯誤;解析成功後再檢查協定,
|
||||
* 僅允許 `http:` 與 `https:`,其餘協定(如 ftp)一律拒絕。
|
||||
*
|
||||
* @param {string} name - 設定項名稱,用於組出錯誤訊息(例如 `GITEA_SERVER_URL`)。
|
||||
* @param {string} value - 待驗證的 URL 字串。
|
||||
* @returns {void} 驗證通過時不回傳值;不通過時改以拋出例外表示。
|
||||
* @throws {Error} 當 value 無法解析為合法 URL 時拋出 `${name} 格式錯誤,必須為合法的 URL`。
|
||||
* @throws {Error} 當 value 協定非 http/https 時拋出 `${name} 必須使用 http 或 https 協定`。
|
||||
* @remarks 由 loadConfig 於驗證 GITEA_SERVER_URL 時呼叫,確保後續組出的 release API URL 指向合法位址。
|
||||
*/
|
||||
function assertHttpUrl(name, value) {
|
||||
let parsed;
|
||||
try {
|
||||
@@ -55,20 +67,42 @@ function assertHttpUrl(name, value) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 驗證字串為合法的 `owner/repo` 形式,否則拋出錯誤。
|
||||
*
|
||||
* 此值會直接拼接於 release API URL(`.../repos/{repository}/releases`),故須限制為單一斜線
|
||||
* 分隔的合法 repo 字元,並排除含 `..` 等可能造成路徑穿越或非預期端點存取的輸入。
|
||||
*
|
||||
* @param {string} name - 設定項名稱,用於組出錯誤訊息(例如 `GITEA_REPOSITORY`)。
|
||||
* @param {string} value - 待驗證的 `owner/repo` 字串。
|
||||
* @returns {void} 驗證通過時不回傳值;不通過時改以拋出例外表示。
|
||||
* @throws {Error} 當 value 非 `owner/repo` 形式、含非法字元或含 `..` 路徑穿越片段時拋出。
|
||||
* @remarks 由 loadConfig 於驗證 GITEA_REPOSITORY 時呼叫;允許 repo 名稱含 `.`(如 `org/my.repo`),
|
||||
* 但拒絕任何 `..` 片段與多餘斜線,避免拼接出非預期的 API 路徑。
|
||||
*/
|
||||
function assertRepository(name, value) {
|
||||
if (!/^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/.test(value) || value.includes('..')) {
|
||||
throw new Error(`${name} 格式錯誤,必須為 owner/repo 形式`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 從環境變數載入並驗證執行所需的設定。
|
||||
*
|
||||
* GITEA_SERVER_URL 與 GITEA_REPOSITORY 為必填,未設定時會拋出錯誤;GITEA_SERVER_URL
|
||||
* 另需為合法的 http/https URL;GITEA_TOKEN 為非必填,未設定時為 null;IS_BETA 會被正規化為布林值。
|
||||
* 另需為合法的 http/https URL;GITEA_REPOSITORY 另需為合法的 `owner/repo` 形式(排除路徑穿越);
|
||||
* GITEA_TOKEN 為非必填,未設定時為 null;IS_BETA 會被正規化為布林值。
|
||||
*
|
||||
* @param {Object} [env=process.env] - 環境變數來源物件,預設為 process.env。
|
||||
* @returns {{ serverUrl: string, repository: string, token: (string|null), isBeta: boolean }} 已驗證的設定物件。
|
||||
* @throws {Error} 當 GITEA_SERVER_URL 或 GITEA_REPOSITORY 未設定,或 GITEA_SERVER_URL 非合法 http/https URL 時拋出。
|
||||
* @throws {Error} 當 GITEA_SERVER_URL 或 GITEA_REPOSITORY 未設定、GITEA_SERVER_URL 非合法 http/https URL,
|
||||
* 或 GITEA_REPOSITORY 非合法 owner/repo 形式時拋出。
|
||||
*/
|
||||
function loadConfig(env = process.env) {
|
||||
const serverUrl = requireEnv('GITEA_SERVER_URL', env.GITEA_SERVER_URL);
|
||||
assertHttpUrl('GITEA_SERVER_URL', serverUrl);
|
||||
const repository = requireEnv('GITEA_REPOSITORY', env.GITEA_REPOSITORY);
|
||||
assertRepository('GITEA_REPOSITORY', repository);
|
||||
const token = isUnset(env.GITEA_TOKEN) ? null : env.GITEA_TOKEN;
|
||||
const isBeta = normalizeBetaFlag(env.IS_BETA);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user