@indigoai-us/hq-cli 5.53.0 → 5.53.1
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/CHANGELOG.md +12 -0
- package/dist/commands/members.js +11 -2
- package/package.json +1 -1
- package/src/commands/members.test.ts +16 -1
- package/src/commands/members.ts +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.53.1]
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **`hq members promote` now clarifies admin access.** Promoting someone to
|
|
10
|
+
`owner` or `admin` prints that they automatically have full read and write
|
|
11
|
+
access to all of the company's context — there is no separate context grant to
|
|
12
|
+
give them (owners/admins resolve to full access via the server-side role
|
|
13
|
+
bypass) — and that what they actually see synced locally is governed by their
|
|
14
|
+
sync mode (`hq sync mode`), not by access. Member/guest promotions are
|
|
15
|
+
unchanged.
|
|
16
|
+
|
|
5
17
|
## [5.53.0]
|
|
6
18
|
|
|
7
19
|
### Added
|
package/dist/commands/members.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c844265d-9140-55ac-8fc7-c0b2a049a0af")}catch(e){}}();
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { ensureCognitoToken } from "../utils/cognito-session.js";
|
|
5
5
|
import { vaultApiFetch, getCompanyUid } from "../utils/vault-api.js";
|
|
@@ -316,6 +316,15 @@ export function registerMembersCommand(program) {
|
|
|
316
316
|
const membershipKey = resolveRevokeTargetToMembershipKey(target, companyUid);
|
|
317
317
|
await changeMemberRole(token, companyUid, membershipKey, role);
|
|
318
318
|
console.log(chalk.green(`Updated role for '${target}' to ${role}`));
|
|
319
|
+
if (role === "owner" || role === "admin") {
|
|
320
|
+
// Clarify the common confusion: owners/admins already get full
|
|
321
|
+
// access to ALL company context automatically via the role bypass
|
|
322
|
+
// (hq-pro resolveEffectivePermission) — there is no separate context
|
|
323
|
+
// grant to give them. What they SEE locally is governed by their sync
|
|
324
|
+
// mode, not by access.
|
|
325
|
+
console.log(chalk.dim(`${role === "owner" ? "Owners" : "Admins"} automatically have full read and write access to all of this company's context — no separate context grant is needed.\n` +
|
|
326
|
+
`What they actually see synced to their machine is governed by their sync mode (\`hq sync mode\`), not by access.`));
|
|
327
|
+
}
|
|
319
328
|
}
|
|
320
329
|
catch (err) {
|
|
321
330
|
if (err instanceof InviteHttpError) {
|
|
@@ -555,4 +564,4 @@ export function registerMembersCommand(program) {
|
|
|
555
564
|
});
|
|
556
565
|
}
|
|
557
566
|
//# sourceMappingURL=members.js.map
|
|
558
|
-
//# debugId=
|
|
567
|
+
//# debugId=c844265d-9140-55ac-8fc7-c0b2a049a0af
|
package/package.json
CHANGED
|
@@ -1051,11 +1051,21 @@ describe("registerMembersCommand promote", () => {
|
|
|
1051
1051
|
expect(logSpy).toHaveBeenCalledWith(
|
|
1052
1052
|
expect.stringContaining("Updated role for 'alice@example.com' to admin"),
|
|
1053
1053
|
);
|
|
1054
|
+
// Clarifies that admins already have full context access automatically
|
|
1055
|
+
// (no separate grant) and that sync mode governs local visibility.
|
|
1056
|
+
expect(logSpy).toHaveBeenCalledWith(
|
|
1057
|
+
expect.stringContaining(
|
|
1058
|
+
"Admins automatically have full read and write access",
|
|
1059
|
+
),
|
|
1060
|
+
);
|
|
1061
|
+
expect(logSpy).toHaveBeenCalledWith(
|
|
1062
|
+
expect.stringContaining("governed by their sync mode"),
|
|
1063
|
+
);
|
|
1054
1064
|
});
|
|
1055
1065
|
|
|
1056
1066
|
it("forwards a personUid target and the guest role (beyond set-role's admin|member cap)", async () => {
|
|
1057
1067
|
fetchSpy.mockResolvedValueOnce(jsonResponse(200, {}));
|
|
1058
|
-
vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
1068
|
+
const logSpy = vi.spyOn(console, "log").mockImplementation(() => undefined);
|
|
1059
1069
|
|
|
1060
1070
|
await buildMembersProgram().parseAsync(
|
|
1061
1071
|
["members", "--company", "acme", "promote", "prs_bob", "guest"],
|
|
@@ -1070,6 +1080,11 @@ describe("registerMembersCommand promote", () => {
|
|
|
1070
1080
|
membershipKey: "prs_bob#cmp_acme",
|
|
1071
1081
|
newRole: "guest",
|
|
1072
1082
|
});
|
|
1083
|
+
// The full-access clarification applies ONLY to the role-bypass roles
|
|
1084
|
+
// (owner/admin) — a guest/member promotion must not claim full access.
|
|
1085
|
+
expect(logSpy).not.toHaveBeenCalledWith(
|
|
1086
|
+
expect.stringContaining("full read and write access"),
|
|
1087
|
+
);
|
|
1073
1088
|
});
|
|
1074
1089
|
|
|
1075
1090
|
it("rejects an invalid role at the CLI and exits non-zero without a network call", async () => {
|
package/src/commands/members.ts
CHANGED
|
@@ -575,6 +575,19 @@ export function registerMembersCommand(program: Command): void {
|
|
|
575
575
|
console.log(
|
|
576
576
|
chalk.green(`Updated role for '${target}' to ${role}`),
|
|
577
577
|
);
|
|
578
|
+
if (role === "owner" || role === "admin") {
|
|
579
|
+
// Clarify the common confusion: owners/admins already get full
|
|
580
|
+
// access to ALL company context automatically via the role bypass
|
|
581
|
+
// (hq-pro resolveEffectivePermission) — there is no separate context
|
|
582
|
+
// grant to give them. What they SEE locally is governed by their sync
|
|
583
|
+
// mode, not by access.
|
|
584
|
+
console.log(
|
|
585
|
+
chalk.dim(
|
|
586
|
+
`${role === "owner" ? "Owners" : "Admins"} automatically have full read and write access to all of this company's context — no separate context grant is needed.\n` +
|
|
587
|
+
`What they actually see synced to their machine is governed by their sync mode (\`hq sync mode\`), not by access.`,
|
|
588
|
+
),
|
|
589
|
+
);
|
|
590
|
+
}
|
|
578
591
|
} catch (err) {
|
|
579
592
|
if (err instanceof InviteHttpError) {
|
|
580
593
|
console.error(chalk.red(err.message));
|