feat: initial public release
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env node
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { mkdirSync, openSync, closeSync, writeFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
|
||||
const host = process.argv[2];
|
||||
const remotePath = process.argv[3] ?? "/home/pi/.config/ding-approval-tui/config.yaml";
|
||||
const destination = resolve(process.env.DINGTALK_CREDENTIALS_FILE ?? ".secrets/dingtalk.json");
|
||||
|
||||
if (!host || host.startsWith("-") || !/^[a-zA-Z0-9_.@:-]+$/.test(host)) {
|
||||
throw new Error("用法:npm run import:dingcli -- 用户@主机 [远程配置路径]");
|
||||
}
|
||||
if (!remotePath.startsWith("/") || /[\r\n\0]/.test(remotePath)) {
|
||||
throw new Error("远程配置路径必须是绝对路径");
|
||||
}
|
||||
|
||||
const yaml = execFileSync("ssh", ["-o", "BatchMode=yes", host, "cat", remotePath], {
|
||||
encoding: "utf8",
|
||||
stdio: ["ignore", "pipe", "inherit"],
|
||||
maxBuffer: 1024 * 1024,
|
||||
});
|
||||
|
||||
const appKey = yamlValue(yaml, "app_key");
|
||||
const appSecret = yamlValue(yaml, "app_secret");
|
||||
if (!appKey || !appSecret) throw new Error("远端 dingCLI 配置缺少 app_key 或 app_secret");
|
||||
|
||||
mkdirSync(dirname(destination), { recursive: true, mode: 0o700 });
|
||||
const fd = openSync(destination, "wx", 0o600);
|
||||
try {
|
||||
writeFileSync(fd, `${JSON.stringify({ clientId: appKey, clientSecret: appSecret }, null, 2)}\n`);
|
||||
} finally {
|
||||
closeSync(fd);
|
||||
}
|
||||
console.error(`钉钉凭证已安全导入 ${destination}(未复制其他配置)`);
|
||||
|
||||
function yamlValue(source, key) {
|
||||
const match = source.match(new RegExp(`^\\s*${key}:\\s*(.+?)\\s*$`, "m"));
|
||||
if (!match) return undefined;
|
||||
const value = match[1].trim();
|
||||
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
||||
return value.slice(1, -1);
|
||||
}
|
||||
return value.replace(/\s+#.*$/, "").trim();
|
||||
}
|
||||
Reference in New Issue
Block a user