@habeetat/cli 0.1.0-dev.20260708084836.99a488d → 0.1.0-dev.20260710132343.dec67be

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/bin.js CHANGED
@@ -13183,11 +13183,11 @@ SET name = EXCLUDED.name, indicator = EXCLUDED.indicator, access_token_ttl = EXC
13183
13183
 
13184
13184
  -- Scope for API Resource
13185
13185
  INSERT INTO scopes (tenant_id, id, resource_id, name, description)
13186
- VALUES ('default', 'nhp-backend-scope', 'nhp-backend-resource', 'nhp:all', 'Full access to NHP backend API')
13186
+ VALUES ('default', 'nhp-backend-scope', 'nhp-backend-resource', 'nhp:api', 'Full access to NHP backend API')
13187
13187
  ON CONFLICT (id) DO UPDATE
13188
13188
  SET resource_id = EXCLUDED.resource_id, name = EXCLUDED.name, description = EXCLUDED.description;
13189
13189
 
13190
- -- Default platform user role: grants the API scope (nhp:all) to EVERY user and is a Logto
13190
+ -- Default platform user role: grants the API scope (nhp:api) to EVERY user and is a Logto
13191
13191
  -- default role (is_default), so self-registered users are auto-assigned it on sign-up. Without
13192
13192
  -- this a new user has no scope on the API resource \u2192 their token is opaque \u2192 they can't call
13193
13193
  -- /auth/me or create their first org (org-onboarding self-registration would be locked out).
@@ -13933,6 +13933,32 @@ async function restartCommand(service) {
13933
13933
  }
13934
13934
  }
13935
13935
 
13936
+ // src/commands/reconcile-iam.ts
13937
+ async function reconcileIamCommand(options = {}) {
13938
+ const projectDir = getProjectDir();
13939
+ const spinner = ora("Reconciling IAM baseline (nhp:api scope + roles + user backfill)...").start();
13940
+ try {
13941
+ const args = [
13942
+ "compose",
13943
+ "-f",
13944
+ COMPOSE_FILE,
13945
+ "exec",
13946
+ "-T",
13947
+ "backend",
13948
+ "node",
13949
+ "dist/scripts/reconcile-iam.js"
13950
+ ];
13951
+ if (options.dropLegacy) args.push("--drop-legacy");
13952
+ const { stdout } = await execa("docker", args, { cwd: projectDir, stdio: "pipe" });
13953
+ spinner.succeed("IAM baseline reconciled");
13954
+ const line = stdout.trim();
13955
+ if (line) logger.info(line.split("\n").pop() ?? line);
13956
+ } catch (err) {
13957
+ spinner.fail("IAM baseline reconcile failed");
13958
+ throw err;
13959
+ }
13960
+ }
13961
+
13936
13962
  // src/commands/update.ts
13937
13963
  async function composePull(opts) {
13938
13964
  const cmd = opts.service ? `docker compose -f ${COMPOSE_FILE} pull ${opts.service}` : `docker compose -f ${COMPOSE_FILE} pull`;
@@ -13967,6 +13993,13 @@ async function updateCommand(service) {
13967
13993
  logger.error(String(err));
13968
13994
  process.exit(1);
13969
13995
  }
13996
+ try {
13997
+ await reconcileIamCommand();
13998
+ } catch (err) {
13999
+ logger.warn(
14000
+ `IAM baseline reconcile skipped/failed: ${String(err)}. Run 'habeetat reconcile-iam' manually.`
14001
+ );
14002
+ }
13970
14003
  console.log("");
13971
14004
  logger.info("Update complete. Run `habeetat status` to verify all services are healthy.");
13972
14005
  }
@@ -14377,6 +14410,9 @@ program2.command("doctor").description("Diagnose common issues").action(doctorCo
14377
14410
  program2.command("destroy").description("Destroy the platform \u2014 remove all containers and volumes").option("-f, --force", "Skip confirmation prompt").action((options) => {
14378
14411
  return destroyCommand(options);
14379
14412
  });
14413
+ program2.command("reconcile-iam").description("Reconcile the IAM baseline (nhp:api scope + roles + backfill users)").option("--drop-legacy", "Stop granting the legacy nhp:all alias (post-migration cleanup)").action((options) => {
14414
+ return reconcileIamCommand(options);
14415
+ });
14380
14416
  program2.command("init").description("Initialize platform (seed Logto apps, create admin user, setup database)").action(() => {
14381
14417
  return initPlatform(getProjectDir());
14382
14418
  });