@hcmai/cli 0.3.2 → 0.3.3
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/index.js +133 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2034,6 +2034,11 @@ async function readStdin() {
|
|
|
2034
2034
|
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
2035
2035
|
return Buffer.concat(chunks).toString("utf-8").trim();
|
|
2036
2036
|
}
|
|
2037
|
+
async function readSecretFromStdin() {
|
|
2038
|
+
const chunks = [];
|
|
2039
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
2040
|
+
return Buffer.concat(chunks).toString("utf-8").replace(/\r?\n$/, "");
|
|
2041
|
+
}
|
|
2037
2042
|
async function promptConfirm(question) {
|
|
2038
2043
|
const ans = await promptText(question);
|
|
2039
2044
|
return /^y(es)?$/i.test(ans.trim());
|
|
@@ -2281,9 +2286,9 @@ async function loginCommand(args) {
|
|
|
2281
2286
|
} catch (e) {
|
|
2282
2287
|
const err = e;
|
|
2283
2288
|
if (err.isAxiosError) {
|
|
2284
|
-
const { fromAxiosError:
|
|
2289
|
+
const { fromAxiosError: fromAxiosError18 } = await import("@hcmai/sdk");
|
|
2285
2290
|
exitWithError(
|
|
2286
|
-
|
|
2291
|
+
fromAxiosError18(
|
|
2287
2292
|
e,
|
|
2288
2293
|
envName
|
|
2289
2294
|
)
|
|
@@ -7581,7 +7586,8 @@ var GUARDED_EXECUTOR_REASON_CODES = /* @__PURE__ */ new Set([
|
|
|
7581
7586
|
"record-create",
|
|
7582
7587
|
"record-update",
|
|
7583
7588
|
"cache-mutation",
|
|
7584
|
-
"setting-write"
|
|
7589
|
+
"setting-write",
|
|
7590
|
+
"credential-reset"
|
|
7585
7591
|
]);
|
|
7586
7592
|
function assessDeliveryCommand(inputArgv) {
|
|
7587
7593
|
const argv = inputArgv[0] === "--" ? inputArgv.slice(1) : [...inputArgv];
|
|
@@ -7590,7 +7596,9 @@ function assessDeliveryCommand(inputArgv) {
|
|
|
7590
7596
|
const subcommand = argv[1] && !argv[1].startsWith("-") ? argv[1] : void 0;
|
|
7591
7597
|
const envAlias = flagValue(argv, "--env");
|
|
7592
7598
|
const identityAlias = flagValue(argv, "--as");
|
|
7593
|
-
const sensitiveFlags = [
|
|
7599
|
+
const sensitiveFlags = [
|
|
7600
|
+
...new Set([...PAYLOAD_FLAGS, ...CREDENTIAL_FLAGS].filter((flag) => hasFlag(argv, flag)))
|
|
7601
|
+
];
|
|
7594
7602
|
const target = summarizeTarget(argv);
|
|
7595
7603
|
let classification = classify(argv);
|
|
7596
7604
|
const invalidPayload = payloadError(argv);
|
|
@@ -7644,6 +7652,19 @@ function classify(argv) {
|
|
|
7644
7652
|
if (argv.some((arg) => APPROVAL_BYPASS_FLAGS.has(flagName(arg)))) {
|
|
7645
7653
|
return forbidden("approval-bypass", "\u547D\u4EE4\u5305\u542B\u8DF3\u8FC7\u786E\u8BA4\u7684\u65D7\u6807\uFF0C\u987E\u95EE\u4EA4\u4ED8\u9762\u4E0D\u6267\u884C\u3002");
|
|
7646
7654
|
}
|
|
7655
|
+
if (name === "user" && subcommand === "reset-password") {
|
|
7656
|
+
const nonStdinCredential = argv.some((arg) => {
|
|
7657
|
+
const flag = flagName(arg);
|
|
7658
|
+
return CREDENTIAL_FLAGS.has(flag) && flag !== "--password-stdin";
|
|
7659
|
+
});
|
|
7660
|
+
if (nonStdinCredential || !argv.includes("--password-stdin")) {
|
|
7661
|
+
return forbidden(
|
|
7662
|
+
"credential-governance",
|
|
7663
|
+
"\u7528\u6237\u5BC6\u7801\u91CD\u7F6E\u53EA\u80FD\u901A\u8FC7 --password-stdin \u8FDB\u5165\u53D7\u63A7\u51ED\u636E\u6D41\u7A0B\u3002"
|
|
7664
|
+
);
|
|
7665
|
+
}
|
|
7666
|
+
return guarded("credential-write", "credential-reset");
|
|
7667
|
+
}
|
|
7647
7668
|
if (argv.some((arg) => CREDENTIAL_FLAGS.has(flagName(arg)))) {
|
|
7648
7669
|
return forbidden("credential-governance", "\u547D\u4EE4\u643A\u5E26\u8EAB\u4EFD\u51ED\u636E\u53C2\u6570\uFF0C\u5FC5\u987B\u8F6C\u4EA4\u8EAB\u4EFD\u6CBB\u7406\u6D41\u7A0B\u3002");
|
|
7649
7670
|
}
|
|
@@ -7765,7 +7786,14 @@ function summarizeTarget(argv) {
|
|
|
7765
7786
|
if (settingKeys.length > 0) target.settingKeys = settingKeys;
|
|
7766
7787
|
}
|
|
7767
7788
|
const id = flagValue(argv, "--id");
|
|
7768
|
-
if (
|
|
7789
|
+
if (name === "user" && subcommand === "reset-password") {
|
|
7790
|
+
if (id) target.userIdSha256 = sha2565(id);
|
|
7791
|
+
const username = flagValue(argv, "--username");
|
|
7792
|
+
if (username) target.usernameSha256 = sha2565(username);
|
|
7793
|
+
target.forceChangeOnNextLogin = !hasFlag(argv, "--no-force-change");
|
|
7794
|
+
} else if (id) {
|
|
7795
|
+
target.recordIdSha256 = sha2565(id);
|
|
7796
|
+
}
|
|
7769
7797
|
for (const flag of PAYLOAD_FLAGS) {
|
|
7770
7798
|
const raw = flagValue(argv, flag);
|
|
7771
7799
|
if (!raw) continue;
|
|
@@ -8116,6 +8144,32 @@ function assertGuardedAssessment(assessment, argv) {
|
|
|
8116
8144
|
validateSupportedCommandShape(assessment.reasonCode, argv);
|
|
8117
8145
|
}
|
|
8118
8146
|
function validateSupportedCommandShape(reasonCode, argv) {
|
|
8147
|
+
if (reasonCode === "credential-reset") {
|
|
8148
|
+
if (argv[0] !== "user" || argv[1] !== "reset-password") {
|
|
8149
|
+
throw invalid4("credential-reset \u53EA\u652F\u6301 user reset-password");
|
|
8150
|
+
}
|
|
8151
|
+
const userId = optionalFlagValue(argv, "--id");
|
|
8152
|
+
const username = optionalFlagValue(argv, "--username");
|
|
8153
|
+
if (Boolean(userId) === Boolean(username)) {
|
|
8154
|
+
throw invalid4("user reset-password \u5FC5\u987B\u4E14\u53EA\u80FD\u5305\u542B --id \u6216 --username");
|
|
8155
|
+
}
|
|
8156
|
+
if (!argv.includes("--password-stdin")) {
|
|
8157
|
+
throw invalid4("user reset-password \u5FC5\u987B\u5305\u542B\u72EC\u7ACB\u7684 --password-stdin");
|
|
8158
|
+
}
|
|
8159
|
+
if (argv.some(
|
|
8160
|
+
(value) => [
|
|
8161
|
+
"--password",
|
|
8162
|
+
"--new-password",
|
|
8163
|
+
"--client-secret",
|
|
8164
|
+
"--pat",
|
|
8165
|
+
"--new-password-stdin",
|
|
8166
|
+
"--pat-stdin"
|
|
8167
|
+
].includes(value.split("=", 1)[0] ?? "")
|
|
8168
|
+
) || argv.some((value) => value.startsWith("--password-stdin="))) {
|
|
8169
|
+
throw invalid4("user reset-password \u4E0D\u5141\u8BB8\u5728 argv \u4E2D\u643A\u5E26\u660E\u6587\u51ED\u636E");
|
|
8170
|
+
}
|
|
8171
|
+
return;
|
|
8172
|
+
}
|
|
8119
8173
|
if (reasonCode === "record-create") {
|
|
8120
8174
|
requireFlagValue(argv, "--data", "create \u5FC5\u987B\u5305\u542B --data <JSON>");
|
|
8121
8175
|
return;
|
|
@@ -8140,6 +8194,19 @@ function validateSupportedCommandShape(reasonCode, argv) {
|
|
|
8140
8194
|
}
|
|
8141
8195
|
}
|
|
8142
8196
|
}
|
|
8197
|
+
function optionalFlagValue(argv, flag) {
|
|
8198
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
8199
|
+
const value = argv[index];
|
|
8200
|
+
if (value === flag) {
|
|
8201
|
+
const next = argv[index + 1];
|
|
8202
|
+
return next && !next.startsWith("-") ? next : void 0;
|
|
8203
|
+
}
|
|
8204
|
+
if (value?.startsWith(`${flag}=`) && value.length > flag.length + 1) {
|
|
8205
|
+
return value.slice(flag.length + 1);
|
|
8206
|
+
}
|
|
8207
|
+
}
|
|
8208
|
+
return void 0;
|
|
8209
|
+
}
|
|
8143
8210
|
function requireFlagValue(argv, flag, message) {
|
|
8144
8211
|
for (let index = 0; index < argv.length; index += 1) {
|
|
8145
8212
|
const value = argv[index];
|
|
@@ -8318,6 +8385,65 @@ function invalid4(message, cause) {
|
|
|
8318
8385
|
return new CliError20({ code: CliErrorCode19.INVALID_ARGUMENT, message, cause });
|
|
8319
8386
|
}
|
|
8320
8387
|
|
|
8388
|
+
// src/commands/user.ts
|
|
8389
|
+
init_auth_guard();
|
|
8390
|
+
init_exit();
|
|
8391
|
+
import {
|
|
8392
|
+
HcmClient as HcmClient17,
|
|
8393
|
+
adminResetPassword,
|
|
8394
|
+
formatObject as formatObject19,
|
|
8395
|
+
fromAxiosError as fromAxiosError17,
|
|
8396
|
+
CliError as CliError21,
|
|
8397
|
+
CliErrorCode as CliErrorCode20
|
|
8398
|
+
} from "@hcmai/sdk";
|
|
8399
|
+
function buildAdminResetPasswordRequest(args, password) {
|
|
8400
|
+
const hasId = Boolean(args.id);
|
|
8401
|
+
const hasUsername = Boolean(args.username);
|
|
8402
|
+
if (hasId === hasUsername) {
|
|
8403
|
+
throw new CliError21({
|
|
8404
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8405
|
+
message: "--id <uuid> \u4E0E --username <user> \u5FC5\u987B\u4E14\u53EA\u80FD\u63D0\u4F9B\u4E00\u4E2A"
|
|
8406
|
+
});
|
|
8407
|
+
}
|
|
8408
|
+
if (!password) {
|
|
8409
|
+
throw new CliError21({
|
|
8410
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8411
|
+
message: "\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A"
|
|
8412
|
+
});
|
|
8413
|
+
}
|
|
8414
|
+
return {
|
|
8415
|
+
...args.id ? { userId: args.id } : {},
|
|
8416
|
+
...args.username ? { username: args.username } : {},
|
|
8417
|
+
newPassword: password,
|
|
8418
|
+
confirmPassword: password,
|
|
8419
|
+
forceChangeOnNextLogin: args.forceChange !== false
|
|
8420
|
+
};
|
|
8421
|
+
}
|
|
8422
|
+
async function userResetPasswordCommand(args) {
|
|
8423
|
+
try {
|
|
8424
|
+
const password = args.passwordStdin ? await readSecretFromStdin() : await promptPasswordTwice();
|
|
8425
|
+
const request = buildAdminResetPasswordRequest(args, password);
|
|
8426
|
+
const client3 = HcmClient17.fromAuthContext(await getActiveAuthContextFromCli(args));
|
|
8427
|
+
const result2 = await adminResetPassword(client3.raw(), request);
|
|
8428
|
+
process.stdout.write(formatObject19(result2, { format: args.output ?? "json" }) + "\n");
|
|
8429
|
+
} catch (cause) {
|
|
8430
|
+
const err = cause;
|
|
8431
|
+
if (err?.isAxiosError) exitWithError(fromAxiosError17(err, args.env));
|
|
8432
|
+
exitWithError(cause);
|
|
8433
|
+
}
|
|
8434
|
+
}
|
|
8435
|
+
async function promptPasswordTwice() {
|
|
8436
|
+
const password = await promptSecret("\u65B0\u5BC6\u7801: ");
|
|
8437
|
+
const confirmation = await promptSecret("\u518D\u6B21\u8F93\u5165\u65B0\u5BC6\u7801: ");
|
|
8438
|
+
if (password !== confirmation) {
|
|
8439
|
+
throw new CliError21({
|
|
8440
|
+
code: CliErrorCode20.INVALID_ARGUMENT,
|
|
8441
|
+
message: "\u4E24\u6B21\u8F93\u5165\u7684\u65B0\u5BC6\u7801\u4E0D\u4E00\u81F4"
|
|
8442
|
+
});
|
|
8443
|
+
}
|
|
8444
|
+
return password;
|
|
8445
|
+
}
|
|
8446
|
+
|
|
8321
8447
|
// src/startup.ts
|
|
8322
8448
|
function needsLegacyProfileMigration(argv) {
|
|
8323
8449
|
const args = argv.slice(2);
|
|
@@ -8355,6 +8481,8 @@ var identity = program.command("identity").description("\u7BA1\u7406 HCM \u8EAB\
|
|
|
8355
8481
|
identity.command("list").description("\u5217\u51FA identity\uFF08\u9ED8\u8BA4\u5217\u5F53\u524D env\uFF0C--env all \u5217\u5168\u90E8\uFF09").option("--env <name>", '\u8FC7\u6EE4 env\uFF1B\u4F20 "all" \u5217\u5168\u90E8', void 0).action((opts) => identityList(opts));
|
|
8356
8482
|
identity.command("use <name>").description("\u628A identity \u8BBE\u4E3A\u5176 env \u7684 default identity").action((name) => identityUse(name));
|
|
8357
8483
|
identity.command("remove <name>").description("\u5220\u9664 identity\uFF08\u6E05 token + \u82E5\u662F env default \u5219\u6E05\u7A7A\uFF09").action((name) => identityRemove(name));
|
|
8484
|
+
var user = program.command("user").description("\u7BA1\u7406\u79DF\u6237\u7528\u6237\u7684\u4E13\u7528\u51ED\u636E\u6D41\u7A0B");
|
|
8485
|
+
user.command("reset-password").description("\u7531 admin.system \u5B89\u5168\u91CD\u7F6E\u7528\u6237\u5BC6\u7801\uFF0C\u5E76\u4F7F\u65E2\u6709\u4F1A\u8BDD\u5931\u6548").option("--id <uuid>", "\u76EE\u6807\u7528\u6237 ID\uFF08\u4E0E --username \u4E8C\u9009\u4E00\uFF09").option("--username <user>", "\u76EE\u6807\u7528\u6237\u540D\uFF08\u4E0E --id \u4E8C\u9009\u4E00\uFF09").option("--password-stdin", "\u4ECE\u6807\u51C6\u8F93\u5165\u8BFB\u53D6\u65B0\u5BC6\u7801\uFF08Agent/\u53D7\u63A7\u4EA4\u4ED8\u5FC5\u987B\u4F7F\u7528\uFF09").option("--no-force-change", "\u4E0B\u6B21\u767B\u5F55\u4E0D\u5F3A\u5236\u6539\u5BC6\uFF08\u4EC5\u9650\u5DF2\u6279\u51C6\u7684\u9694\u79BB\u6D4B\u8BD5\u73AF\u5883\uFF09").option("--env <name>", "\u4E34\u65F6\u5207\u73AF\u5883\uFF08\u8986\u76D6 activeEnv\uFF0C\u672C\u6B21\u547D\u4EE4\uFF09").option("--as <identity>", "\u4E34\u65F6\u6362\u8EAB\u4EFD\uFF08\u5FC5\u987B\u5177\u5907 admin.system\uFF09").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").action((opts) => userResetPasswordCommand(opts));
|
|
8358
8486
|
var delivery = program.command("delivery").description("\u987E\u95EE\u4EA4\u4ED8\u547D\u4EE4\u7684\u98CE\u9669\u8BC4\u4F30\u4E0E\u4E00\u6B21\u6027\u53D7\u63A7\u6267\u884C\u5408\u540C");
|
|
8359
8487
|
delivery.command("assess").description("\u7EAF\u672C\u5730\u8BC4\u4F30\u4E00\u6B21 HCM CLI argv\uFF1B\u7528 -- \u5206\u9694\u88AB\u8BC4\u4F30\u547D\u4EE4").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u88AB\u8BC4\u4F30\u7684 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570\uFF0C\u4E0D\u5305\u542B hcm \u672C\u8EAB").action((command, opts) => deliveryAssessCommand(command, opts));
|
|
8360
8488
|
delivery.command("prepare").description("\u628A\u53D7\u652F\u6301\u7684 R2 argv \u4E0E\u9501\u3001\u8FD0\u884C\u65F6\u548C\u53D8\u66F4/\u56DE\u6EDA\u8BF4\u660E\u7ED1\u5B9A\u4E3A\u77ED\u65F6\u6267\u884C\u8BA1\u5212").requiredOption("--change-ref <file>", "\u9879\u76EE work/ \u6216 decisions/ \u4E0B\u7684\u53D8\u66F4\u8BF4\u660E").requiredOption("--rollback-ref <file>", "\u9879\u76EE work/ \u6216 decisions/ \u4E0B\u7684\u56DE\u6EDA\u8BF4\u660E").requiredOption("--evidence-dir <dir>", "\u9879\u76EE evidence/ \u4E0B\u7684\u6536\u636E\u76EE\u5F55").option("--project <dir>", "HCM \u987E\u95EE\u9879\u76EE\u6839\u76EE\u5F55", ".").option("--ttl-seconds <n>", "\u6709\u6548\u671F\u79D2\u6570\uFF0860-3600\uFF09", "900").option("--output <fmt>", "\u8F93\u51FA\u683C\u5F0F\uFF1Atable | json | yaml", "json").allowUnknownOption(true).argument("<command...>", "\u88AB\u7ED1\u5B9A\u7684 R2 HCM \u5B50\u547D\u4EE4\u4E0E\u53C2\u6570\uFF0C\u4E0D\u5305\u542B hcm \u672C\u8EAB").action((command, opts) => deliveryPrepareCommand(command, opts));
|