backupdrill 2.2.3 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backup.js +5 -3
- package/dist/restore-engine.js +13 -3
- package/package.json +1 -1
package/dist/backup.js
CHANGED
|
@@ -17,7 +17,7 @@ import { dumpPartSizeFor } from "./part-size.js";
|
|
|
17
17
|
// 解析函数搬到了 pgbin(演练与恢复都要读 pg_restore 版本,放这里会成环);保留旧出口
|
|
18
18
|
export { parsePgDumpMajor };
|
|
19
19
|
import { dumpUrlFor, connectPg, isSupabaseHost } from "./supabase-ca.js";
|
|
20
|
-
import { libpqChildEnv, urlSslModeOf } from "./restore-engine.js";
|
|
20
|
+
import { credentialSafeDbArgs, libpqChildEnv, urlSslModeOf } from "./restore-engine.js";
|
|
21
21
|
const execFileAsync = promisify(execFile);
|
|
22
22
|
function majorOf(serverVersionNum) {
|
|
23
23
|
// server_version_num: 150004 → 15, 170002 → 17
|
|
@@ -106,7 +106,9 @@ async function dumpToS3(config, s3, key, pgDumpBin, partSize) {
|
|
|
106
106
|
});
|
|
107
107
|
const schemaArgs = config.schemas.map((s) => `--schema=${s}`);
|
|
108
108
|
// pg_dump(libpq):Supabase 主机才改写成 sslmode=verify-full + sslrootcert=<打包CA临时文件>
|
|
109
|
-
|
|
109
|
+
// 凭据不进 argv(D6):argv 对同机任何进程的 `ps` 可见。与恢复路径同一个函数——
|
|
110
|
+
// 先改写 SSL 再拆密码,密码经 PGPASSWORD 交给 libpq
|
|
111
|
+
const { url: dumpDbUrl, env: credentialEnv } = credentialSafeDbArgs(dumpUrlFor(config.databaseUrl));
|
|
110
112
|
const dump = spawn(pgDumpBin, [
|
|
111
113
|
"--format=custom",
|
|
112
114
|
"--no-owner",
|
|
@@ -118,7 +120,7 @@ async function dumpToS3(config, s3, key, pgDumpBin, partSize) {
|
|
|
118
120
|
// 环境剔除改写目标/身份的 PG* 变量:pg_dump 只认 --dbname 里的 URL(TLS 策略等保留)
|
|
119
121
|
{
|
|
120
122
|
stdio: ["ignore", "pipe", "pipe"],
|
|
121
|
-
env: libpqChildEnv(
|
|
123
|
+
env: libpqChildEnv(credentialEnv, process.env, {
|
|
122
124
|
supabaseHost: isSupabaseHost(config.databaseUrl),
|
|
123
125
|
urlSslMode: urlSslModeOf(dumpDbUrl),
|
|
124
126
|
}),
|
package/dist/restore-engine.js
CHANGED
|
@@ -395,6 +395,10 @@ export function credentialSafeDbArgs(connString) {
|
|
|
395
395
|
}
|
|
396
396
|
return { url: connString, env: {} };
|
|
397
397
|
}
|
|
398
|
+
// 兜底(入口的 assertNoHostOverride 已拒字面 #):片段留在输出里,libpq 会把 `#?host=…` 当查询参数
|
|
399
|
+
if (url.hash) {
|
|
400
|
+
throw new Error("connection string contains a literal '#' — percent-encode it as %23 (for example inside the password).");
|
|
401
|
+
}
|
|
398
402
|
let password = "";
|
|
399
403
|
if (url.password) {
|
|
400
404
|
try {
|
|
@@ -427,9 +431,9 @@ export function credentialSafeDbArgs(connString) {
|
|
|
427
431
|
if (/^password$/i.test(key)) {
|
|
428
432
|
const rawValue = eq === -1 ? "" : part.slice(eq + 1);
|
|
429
433
|
try {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
434
|
+
// 空值也要记:libpq 取最后一个(空 = 回落 .pgpass),只记非空会把前面的旧值
|
|
435
|
+
// 当成密码——?password=stale&password= 预检走 .pgpass、pg_dump 却用 stale
|
|
436
|
+
queryPasswords.push(decodeURIComponent(rawValue.replace(/\+/g, "%20")));
|
|
433
437
|
}
|
|
434
438
|
catch {
|
|
435
439
|
throw new Error("the connection string ?password= value contains malformed percent-encoding — " +
|
|
@@ -469,6 +473,12 @@ export function assertNoHostOverride(connString) {
|
|
|
469
473
|
if (containsNul(connString)) {
|
|
470
474
|
throw new Error("connection string contains a NUL byte — use a plain connection string.");
|
|
471
475
|
}
|
|
476
|
+
// 字面 # 同样在解析前拒:WHATWG URL 把 # 之后当片段,这里看到的主机干净;libpq 不认片段,
|
|
477
|
+
// 剥掉 ?password= 后剩下的 `#?host=…` 会被它读成查询参数,改写连接目标(交叉审查)。
|
|
478
|
+
// 合法的 # 只会出现在密码等值里,写成 %23 即可
|
|
479
|
+
if (connString.includes("#")) {
|
|
480
|
+
throw new Error("connection string contains a literal '#' — percent-encode it as %23 (for example inside the password).");
|
|
481
|
+
}
|
|
472
482
|
// 解析不了的连接串直接拒:曾经"放行让 pg 自己报错",但 pg 的解析器比 WHATWG URL 宽
|
|
473
483
|
// (`postgresql://user@/db?host=…` 这类串 pg 接受、这里解析失败),放行 = 身份判定为空却照样连接
|
|
474
484
|
// (交叉审查)。校验逻辑放在 try 外面——曾按文案里有没有 "override" 决定重抛,新理由一措辞不同就被吞。
|
package/package.json
CHANGED