@zivis/cli 0.1.0-alpha.6 → 0.1.0-alpha.8
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.
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import * as readline from "node:readline/promises";
|
|
2
|
-
import { login, getStorageName, saveSessionEntry
|
|
3
|
-
import { getValidAccessToken } from "@zivis/mcp/auth/token-refresh";
|
|
2
|
+
import { login, getStorageName, saveSessionEntry } from "@zivis/mcp/auth";
|
|
4
3
|
import { DEFAULT_CONFIG } from "@zivis/mcp/types";
|
|
5
4
|
import { fetchUserOrgs, extractEmail } from "../../internal/orgs.js";
|
|
6
5
|
import { ensureProjectBinding } from "../../internal/project-binding.js";
|
|
7
|
-
|
|
8
|
-
function parseReceivedOrgId(msg) {
|
|
9
|
-
const m = msg.match(/received (org_\w+)/);
|
|
10
|
-
return m ? m[1] : null;
|
|
11
|
-
}
|
|
6
|
+
import { decodeJwtPayload } from "@zivis/mcp/auth/jwt";
|
|
12
7
|
async function prompt(question) {
|
|
13
8
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
14
9
|
try {
|
|
@@ -21,116 +16,114 @@ async function prompt(question) {
|
|
|
21
16
|
export async function initCommand(opts) {
|
|
22
17
|
const config = DEFAULT_CONFIG;
|
|
23
18
|
const session = opts.session || "default";
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const stored = await loadTokens(session);
|
|
29
|
-
const email = extractEmail(stored?.id_token);
|
|
30
|
-
console.log(`Using existing session (${email}).`);
|
|
31
|
-
console.log(`To force re-login first: zivis auth logout && zivis auth init\n`);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
console.log("Step 1/2: Authenticate (browser will open)...");
|
|
35
|
-
try {
|
|
36
|
-
const tokens = await login(config, session, undefined, { skipConfirm: true });
|
|
37
|
-
bootstrapToken = tokens.access_token;
|
|
38
|
-
const email = extractEmail(tokens.id_token);
|
|
39
|
-
console.log(`✓ Authenticated as ${email}`);
|
|
40
|
-
}
|
|
41
|
-
catch (err) {
|
|
42
|
-
console.error("Login failed:", err instanceof Error ? err.message : err);
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// Fetch the user's orgs
|
|
47
|
-
let orgs;
|
|
19
|
+
// Step 1: Open browser — no org pre-selection. User picks the org in their browser.
|
|
20
|
+
console.log("Opening browser for authentication...");
|
|
21
|
+
console.log("Log into the org you want to bind this project to.\n");
|
|
22
|
+
let tokens;
|
|
48
23
|
try {
|
|
49
|
-
|
|
24
|
+
tokens = await login(config, session, undefined, { skipConfirm: true });
|
|
50
25
|
}
|
|
51
26
|
catch (err) {
|
|
52
|
-
console.error("
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
if (orgs.length === 0) {
|
|
56
|
-
console.error("No organizations found for this account. Contact support.");
|
|
27
|
+
console.error("Login failed:", err instanceof Error ? err.message : err);
|
|
57
28
|
process.exit(1);
|
|
58
29
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
30
|
+
const email = extractEmail(tokens.id_token);
|
|
31
|
+
const storageName = getStorageName();
|
|
32
|
+
await saveSessionEntry(session, email);
|
|
33
|
+
console.log(`\n✓ Authenticated as ${email}`);
|
|
34
|
+
console.log(`✓ Credentials stored in ${storageName}`);
|
|
35
|
+
// Step 2: Determine which org the JWT is scoped to
|
|
36
|
+
const claims = decodeJwtPayload(tokens.access_token);
|
|
37
|
+
const jwtOrgId = claims?.org_id;
|
|
38
|
+
if (jwtOrgId) {
|
|
39
|
+
// JWT already has an org — look up the name and write the binding
|
|
40
|
+
let orgName;
|
|
41
|
+
try {
|
|
42
|
+
const orgs = await fetchUserOrgs(config, tokens.access_token);
|
|
43
|
+
orgName = orgs.find((o) => o.workosOrgId === jwtOrgId)?.name;
|
|
68
44
|
}
|
|
69
|
-
|
|
45
|
+
catch {
|
|
46
|
+
// non-fatal — binding still works with just the org ID
|
|
47
|
+
}
|
|
48
|
+
const orgLabel = orgName ? `${orgName}` : jwtOrgId;
|
|
49
|
+
console.log(`✓ JWT scoped to org: ${orgLabel}`);
|
|
50
|
+
await ensureProjectBinding({
|
|
51
|
+
config,
|
|
52
|
+
session,
|
|
53
|
+
accessToken: tokens.access_token,
|
|
54
|
+
organizationId: jwtOrgId,
|
|
55
|
+
cwd: process.cwd(),
|
|
56
|
+
autoBind: true,
|
|
57
|
+
skipBind: false,
|
|
58
|
+
});
|
|
70
59
|
}
|
|
71
60
|
else {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
console.
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
// Attempt org-scoped login, with graceful handling for browser-session mismatches
|
|
79
|
-
let scopedTokens;
|
|
80
|
-
let finalOrgId = selectedOrg.workosOrgId;
|
|
81
|
-
let finalOrgName = selectedOrg.name;
|
|
82
|
-
for (let attempt = 0; attempt < 2; attempt++) {
|
|
83
|
-
console.log(`\nStep ${orgs.length > 1 ? "2/2" : "1/1"}: Logging in to ${finalOrgName} (browser will open)...`);
|
|
61
|
+
// No org in JWT — user is authenticated but not scoped to an org yet.
|
|
62
|
+
// Fetch orgs and let them pick, then do a scoped login.
|
|
63
|
+
console.log("\nYour account isn't scoped to a specific org yet.");
|
|
64
|
+
console.log("Fetching your organizations...\n");
|
|
65
|
+
let orgs;
|
|
84
66
|
try {
|
|
85
|
-
|
|
86
|
-
orgName: finalOrgName,
|
|
87
|
-
skipConfirm: true,
|
|
88
|
-
});
|
|
89
|
-
break; // success
|
|
67
|
+
orgs = await fetchUserOrgs(config, tokens.access_token);
|
|
90
68
|
}
|
|
91
69
|
catch (err) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
70
|
+
console.error("Failed to fetch organizations:", err instanceof Error ? err.message : err);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
if (orgs.length === 0) {
|
|
74
|
+
console.error("No organizations found. Contact support.");
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
if (orgs.length === 1) {
|
|
78
|
+
console.log(`One org found: ${orgs[0].name}. Re-authenticating scoped to that org...`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.log("Your organizations:");
|
|
82
|
+
orgs.forEach((org, i) => console.log(` ${i + 1}. ${org.name}`));
|
|
83
|
+
const answer = await prompt(`\nSelect org to bind this project to [1-${orgs.length}]: `);
|
|
84
|
+
const idx = parseInt(answer, 10) - 1;
|
|
85
|
+
if (isNaN(idx) || idx < 0 || idx >= orgs.length) {
|
|
86
|
+
console.error("Invalid selection.");
|
|
96
87
|
process.exit(1);
|
|
97
88
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
console.error(`\n⚠ Browser authenticated to "${receivedName}" instead of "${finalOrgName}".`);
|
|
102
|
-
console.error(` This happens when your browser's active session is for a different org.\n`);
|
|
103
|
-
if (attempt >= 1) {
|
|
104
|
-
console.error("Still mismatched after retry. Run `zivis auth init` again after switching orgs in your browser.");
|
|
89
|
+
const selected = orgs[idx];
|
|
90
|
+
if (!selected.workosOrgId) {
|
|
91
|
+
console.error(`Org "${selected.name}" has no WorkOS org ID.`);
|
|
105
92
|
process.exit(1);
|
|
106
93
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
94
|
+
console.log(`\nRe-opening browser scoped to ${selected.name}...`);
|
|
95
|
+
console.log("(Tip: if your browser logs into the wrong org, use option 2 to get a URL for a private/incognito window)\n");
|
|
96
|
+
try {
|
|
97
|
+
const scopedTokens = await login(config, session, selected.workosOrgId, {
|
|
98
|
+
orgName: selected.name,
|
|
99
|
+
skipConfirm: true,
|
|
100
|
+
});
|
|
101
|
+
await saveSessionEntry(session, email);
|
|
102
|
+
await ensureProjectBinding({
|
|
103
|
+
config,
|
|
104
|
+
session,
|
|
105
|
+
accessToken: scopedTokens.access_token,
|
|
106
|
+
organizationId: selected.workosOrgId,
|
|
107
|
+
cwd: process.cwd(),
|
|
108
|
+
autoBind: true,
|
|
109
|
+
skipBind: false,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
114
|
+
const m = msg.match(/received (org_\w+)/);
|
|
115
|
+
if (m) {
|
|
116
|
+
console.error(`\n⚠ Browser authenticated to a different org than selected.`);
|
|
117
|
+
console.error(` Your browser has an active session for a different org.\n`);
|
|
118
|
+
console.error(` To fix: run \`zivis auth init\` again and paste the URL into a private/incognito window.`);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
console.error("Login failed:", msg);
|
|
122
|
+
}
|
|
123
|
+
process.exit(1);
|
|
111
124
|
}
|
|
112
|
-
// Retry scoped to what the browser actually has
|
|
113
|
-
finalOrgId = receivedOrgId;
|
|
114
|
-
finalOrgName = receivedName;
|
|
115
125
|
}
|
|
116
126
|
}
|
|
117
|
-
if (!scopedTokens) {
|
|
118
|
-
process.exit(1);
|
|
119
|
-
}
|
|
120
|
-
const email = extractEmail(scopedTokens.id_token);
|
|
121
|
-
const storageName = getStorageName();
|
|
122
|
-
await saveSessionEntry(session, email);
|
|
123
|
-
console.log(`\n✓ Logged in as ${email} → ${finalOrgName}`);
|
|
124
|
-
console.log(`✓ Credentials stored in ${storageName}`);
|
|
125
|
-
await ensureProjectBinding({
|
|
126
|
-
config,
|
|
127
|
-
session,
|
|
128
|
-
accessToken: scopedTokens.access_token,
|
|
129
|
-
organizationId: finalOrgId,
|
|
130
|
-
cwd: process.cwd(),
|
|
131
|
-
autoBind: true,
|
|
132
|
-
skipBind: false,
|
|
133
|
-
});
|
|
134
127
|
process.exit(0);
|
|
135
128
|
}
|
|
136
129
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/auth/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/auth/init.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zivis/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.8",
|
|
4
4
|
"description": "ZIVIS CLI — threat modeling, scans, and MCP server for IDE integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"ignore": "^7.0.5",
|
|
24
24
|
"open": "^10.1.0",
|
|
25
25
|
"web-tree-sitter": "^0.26.8",
|
|
26
|
-
"@zivis/mcp": "0.1.0-alpha.
|
|
26
|
+
"@zivis/mcp": "0.1.0-alpha.3"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^22.0.0",
|