Files
ts-scripts/single-scripts/kpxcenv.ts

128 lines
3.6 KiB
TypeScript
Executable File

#!/usr/bin/env runts -- --allow-env --allow-run --allow-import
// Reference:
// - https://github.com/nwwdles/kpxcpc
// - https://stackoverflow.com/questions/62142699/how-do-i-run-an-arbitrary-shell-command-from-deno
// - https://docs.deno.com/api/deno/~/Deno.CommandOptions
// - https://github.com/aliyun/aliyun-cli
import {
compareVersion,
isEnvOn,
log,
} from "https://global.hatter.ink/script/get/@1/deno-commons-mod.ts";
const args = Deno.args;
if (args.length == 0) {
console.log(
`kpxcenv.js - KeepassXC environment tool (currently only support Alibaba Cloud)
kpxcenv.js aliyunak://ak-name
Environments:
KPXC_SHELL - Shell, default bash
KPXC_REGION - Region, default cn-hangzhou, effects env: ALIBABA_CLOUD_REGION_ID
KPXC_DEBUG - Debug, default false
`,
);
Deno.exit(0);
}
const KEEPASSXC_PROXY_COMMAND = "kpxcpc";
const isDebug = isEnvOn("KPXC_DEBUG");
const xdrRuntimeDir = Deno.env.get("XDG_RUNTIME_DIR");
if (xdrRuntimeDir == null) {
const tmpdir = Deno.env.get("TMPDIR");
if (tmpdir == null) {
log.error("Environment XDG_RUNTIME_DIR is not set.");
Deno.exit(1);
}
if (isDebug) {
log.debug("Set env XDG_RUNTIME_DIR=" + tmpdir);
}
Deno.env.set("XDG_RUNTIME_DIR", tmpdir);
}
const shellCommand = Deno.env.get("KPXC_SHELL") || "bash";
const region = Deno.env.get("KPXC_REGION") || "cn-hangzhou";
if (compareVersion(Deno.version.deno, "1.18.0") < 0) {
log.error("Require deno version >= 1.18.0 .");
Deno.exit(1);
}
async function commandExists(cmd: string): Promise<boolean> {
const whichCmd = new Deno.Command("which", {
args: [cmd],
});
const {
code: whichCmdCode,
stdout: _whichCmdStdout,
stderr: _whichCmdStderr,
} = await whichCmd.output();
return whichCmdCode === 0;
}
if (!await commandExists(KEEPASSXC_PROXY_COMMAND)) {
log.error(
"Command kpxcpc is not installed, please install from: https://github.com/nwwdles/kpxcpc",
);
Deno.exit(1);
}
const akName = args[0];
const kpxcpcCmd = new Deno.Command(KEEPASSXC_PROXY_COMMAND, {
args: ["--json", akName],
});
const {
code: kpxcpcCmdCode,
stdout: kpxcpcCmdStdout,
stderr: kpxcpcCmdStderr,
} = await kpxcpcCmd.output();
if (kpxcpcCmdCode != 0) {
console.error(new TextDecoder().decode(kpxcpcCmdStderr));
console.log(new TextDecoder().decode(kpxcpcCmdStdout));
Deno.exit(kpxcpcCmdCode);
}
const kpxcpcCmdStdoutString = new TextDecoder().decode(kpxcpcCmdStdout);
const kpxcpcCmdJsonObjects = JSON.parse(kpxcpcCmdStdoutString);
if (kpxcpcCmdJsonObjects.length == 0) {
log.error(
"Should not happen, since KeepassXC return JSON array is empty.",
);
Deno.exit(1);
}
if (kpxcpcCmdJsonObjects.length > 1) {
log.warn(
"Get more than one vaule from KeepassXC, default use the first.",
);
}
const kpxcpcCmdJsonObject = kpxcpcCmdJsonObjects[0];
const accessKeyName = kpxcpcCmdJsonObject.name;
const accessKeyId = kpxcpcCmdJsonObject.login;
const accessKeySecret = kpxcpcCmdJsonObject.password;
if (isDebug) {
log.debug("Found object: ", kpxcpcCmdJsonObject);
}
const command = new Deno.Command(shellCommand, {
args: [],
env: {
"PS1": accessKeyName + " (" + akName + ")" + "> ", // FIXME support fish
"ALIBABA_CLOUD_REGION_ID": region,
"ALIBABA_CLOUD_ACCESS_KEY_ID": accessKeyId,
"ALIBABA_CLOUD_ACCESS_KEY_SECRET": accessKeySecret,
},
stdin: "inherit",
stdout: "inherit",
});
const _child = command.spawn();
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20250621T102747+08:00.MEYCIQCI2ic4Mi6kZVAAgBBS
// 9VT9PCrf2QShr3maSyfwe6jk7QIhAPNpRqEmEH2H7AGp499xHDxtXLqgy6eCK/2p8hf7Coaj