@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 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: fromAxiosError17 } = await import("@hcmai/sdk");
2289
+ const { fromAxiosError: fromAxiosError18 } = await import("@hcmai/sdk");
2285
2290
  exitWithError(
2286
- fromAxiosError17(
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 = [...new Set(PAYLOAD_FLAGS.filter((flag) => hasFlag(argv, flag)))];
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 (id) target.recordIdSha256 = sha2565(id);
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));