@lanonasis/cli 3.6.3 → 3.6.5
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/commands/api-keys.d.ts +1 -2
- package/dist/commands/api-keys.js +78 -73
- package/dist/commands/auth.js +167 -160
- package/dist/commands/completion.js +39 -31
- package/dist/commands/config.js +201 -162
- package/dist/commands/enhanced-memory.js +17 -11
- package/dist/commands/guide.js +88 -79
- package/dist/commands/init.js +20 -14
- package/dist/commands/mcp.js +173 -142
- package/dist/commands/memory.js +83 -77
- package/dist/commands/organization.js +21 -15
- package/dist/commands/topics.js +58 -52
- package/dist/core/achievements.js +26 -19
- package/dist/core/architecture.js +59 -42
- package/dist/core/dashboard.js +81 -71
- package/dist/core/error-handler.js +39 -30
- package/dist/core/power-mode.js +53 -46
- package/dist/core/progress.js +44 -35
- package/dist/core/welcome.js +64 -56
- package/dist/enhanced-cli.js +58 -49
- package/dist/index-simple.js +112 -74
- package/dist/index.js +68 -63
- package/dist/mcp/access-control.js +17 -13
- package/dist/mcp/client/enhanced-client.js +23 -16
- package/dist/mcp/enhanced-server.js +14 -10
- package/dist/mcp/logger.js +6 -2
- package/dist/mcp/memory-state.js +17 -13
- package/dist/mcp/schemas/tool-schemas.d.ts +28 -28
- package/dist/mcp/schemas/tool-schemas.js +126 -122
- package/dist/mcp/server/lanonasis-server.js +51 -44
- package/dist/mcp/transports/transport-manager.js +25 -18
- package/dist/mcp/vector-store.js +10 -6
- package/dist/mcp-server.js +21 -17
- package/dist/utils/api.js +30 -21
- package/dist/utils/config.js +61 -15
- package/dist/utils/formatting.js +14 -6
- package/dist/utils/mcp-client.js +132 -77
- package/package.json +17 -92
- package/dist/completions/bash-completion.sh +0 -88
- package/dist/completions/fish-completion.fish +0 -132
- package/dist/completions/zsh-completion.zsh +0 -196
package/dist/commands/auth.js
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.diagnoseCommand = diagnoseCommand;
|
|
7
|
+
exports.loginCommand = loginCommand;
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
|
+
const ora_1 = __importDefault(require("ora"));
|
|
11
|
+
const open_1 = __importDefault(require("open"));
|
|
12
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
13
|
+
const http_1 = __importDefault(require("http"));
|
|
14
|
+
const url_1 = __importDefault(require("url"));
|
|
15
|
+
const api_js_1 = require("../utils/api.js");
|
|
16
|
+
const config_js_1 = require("../utils/config.js");
|
|
10
17
|
// Color scheme
|
|
11
18
|
const colors = {
|
|
12
|
-
primary:
|
|
13
|
-
success:
|
|
14
|
-
warning:
|
|
15
|
-
error:
|
|
16
|
-
info:
|
|
17
|
-
accent:
|
|
18
|
-
muted:
|
|
19
|
-
highlight:
|
|
19
|
+
primary: chalk_1.default.blue.bold,
|
|
20
|
+
success: chalk_1.default.green,
|
|
21
|
+
warning: chalk_1.default.yellow,
|
|
22
|
+
error: chalk_1.default.red,
|
|
23
|
+
info: chalk_1.default.cyan,
|
|
24
|
+
accent: chalk_1.default.magenta,
|
|
25
|
+
muted: chalk_1.default.gray,
|
|
26
|
+
highlight: chalk_1.default.white.bold
|
|
20
27
|
};
|
|
21
28
|
// Helper function to handle authentication delays
|
|
22
29
|
async function handleAuthDelay(config) {
|
|
@@ -25,15 +32,15 @@ async function handleAuthDelay(config) {
|
|
|
25
32
|
const failureCount = config.getFailureCount();
|
|
26
33
|
const lastFailure = config.getLastAuthFailure();
|
|
27
34
|
console.log();
|
|
28
|
-
console.log(
|
|
35
|
+
console.log(chalk_1.default.yellow(`⚠️ Multiple authentication failures detected (${failureCount} attempts)`));
|
|
29
36
|
if (lastFailure) {
|
|
30
37
|
const lastFailureDate = new Date(lastFailure);
|
|
31
|
-
console.log(
|
|
38
|
+
console.log(chalk_1.default.gray(`Last failure: ${lastFailureDate.toLocaleString()}`));
|
|
32
39
|
}
|
|
33
|
-
console.log(
|
|
34
|
-
console.log(
|
|
40
|
+
console.log(chalk_1.default.yellow(`Waiting ${Math.round(delayMs / 1000)} seconds before retry...`));
|
|
41
|
+
console.log(chalk_1.default.gray('This delay helps prevent account lockouts and reduces server load.'));
|
|
35
42
|
// Show countdown
|
|
36
|
-
const spinner =
|
|
43
|
+
const spinner = (0, ora_1.default)(`Waiting ${Math.round(delayMs / 1000)} seconds...`).start();
|
|
37
44
|
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
38
45
|
spinner.succeed('Ready to retry authentication');
|
|
39
46
|
console.log();
|
|
@@ -47,70 +54,70 @@ async function handleAuthenticationFailure(error, config, authMethod = 'jwt') {
|
|
|
47
54
|
// Determine error type and provide specific guidance
|
|
48
55
|
const errorType = categorizeAuthError(error);
|
|
49
56
|
console.log();
|
|
50
|
-
console.log(
|
|
57
|
+
console.log(chalk_1.default.red('✖ Authentication failed'));
|
|
51
58
|
switch (errorType) {
|
|
52
59
|
case 'invalid_credentials':
|
|
53
|
-
console.log(
|
|
60
|
+
console.log(chalk_1.default.red('Invalid credentials provided'));
|
|
54
61
|
if (authMethod === 'vendor_key') {
|
|
55
|
-
console.log(
|
|
56
|
-
console.log(
|
|
57
|
-
console.log(
|
|
62
|
+
console.log(chalk_1.default.gray('• Verify the vendor key matches the value shown in your dashboard'));
|
|
63
|
+
console.log(chalk_1.default.gray('• Confirm the key is active and has not been revoked'));
|
|
64
|
+
console.log(chalk_1.default.gray('• Ensure you copied the entire key without extra spaces'));
|
|
58
65
|
}
|
|
59
66
|
else {
|
|
60
|
-
console.log(
|
|
61
|
-
console.log(
|
|
62
|
-
console.log(
|
|
67
|
+
console.log(chalk_1.default.gray('• Double-check your email and password'));
|
|
68
|
+
console.log(chalk_1.default.gray('• Passwords are case-sensitive'));
|
|
69
|
+
console.log(chalk_1.default.gray('• Consider resetting your password if needed'));
|
|
63
70
|
}
|
|
64
71
|
break;
|
|
65
72
|
case 'network_error':
|
|
66
|
-
console.log(
|
|
67
|
-
console.log(
|
|
68
|
-
console.log(
|
|
69
|
-
console.log(
|
|
73
|
+
console.log(chalk_1.default.red('Network connection failed'));
|
|
74
|
+
console.log(chalk_1.default.gray('• Check your internet connection'));
|
|
75
|
+
console.log(chalk_1.default.gray('• Verify you can access https://auth.lanonasis.com'));
|
|
76
|
+
console.log(chalk_1.default.gray('• Try again in a few moments'));
|
|
70
77
|
if (failureCount >= 2) {
|
|
71
|
-
console.log(
|
|
78
|
+
console.log(chalk_1.default.gray('• Consider using a different network if issues persist'));
|
|
72
79
|
}
|
|
73
80
|
break;
|
|
74
81
|
case 'server_error':
|
|
75
|
-
console.log(
|
|
76
|
-
console.log(
|
|
77
|
-
console.log(
|
|
78
|
-
console.log(
|
|
82
|
+
console.log(chalk_1.default.red('Server temporarily unavailable'));
|
|
83
|
+
console.log(chalk_1.default.gray('• The authentication service may be experiencing issues'));
|
|
84
|
+
console.log(chalk_1.default.gray('• Please try again in a few minutes'));
|
|
85
|
+
console.log(chalk_1.default.gray('• Check https://status.lanonasis.com for service status'));
|
|
79
86
|
break;
|
|
80
87
|
case 'rate_limited':
|
|
81
|
-
console.log(
|
|
82
|
-
console.log(
|
|
83
|
-
console.log(
|
|
84
|
-
console.log(
|
|
88
|
+
console.log(chalk_1.default.red('Too many authentication attempts'));
|
|
89
|
+
console.log(chalk_1.default.gray('• Please wait before trying again'));
|
|
90
|
+
console.log(chalk_1.default.gray('• Rate limiting helps protect your account'));
|
|
91
|
+
console.log(chalk_1.default.gray('• Consider using a vendor key for automated access'));
|
|
85
92
|
break;
|
|
86
93
|
case 'expired_token':
|
|
87
|
-
console.log(
|
|
88
|
-
console.log(
|
|
89
|
-
console.log(
|
|
94
|
+
console.log(chalk_1.default.red('Authentication token has expired'));
|
|
95
|
+
console.log(chalk_1.default.gray('• Please log in again to refresh your session'));
|
|
96
|
+
console.log(chalk_1.default.gray('• Consider using a vendor key for longer-term access'));
|
|
90
97
|
await config.clearInvalidCredentials();
|
|
91
98
|
break;
|
|
92
99
|
default:
|
|
93
|
-
console.log(
|
|
94
|
-
console.log(
|
|
95
|
-
console.log(
|
|
100
|
+
console.log(chalk_1.default.red(`Unexpected error: ${error.message || 'Unknown error'}`));
|
|
101
|
+
console.log(chalk_1.default.gray('• Please try again'));
|
|
102
|
+
console.log(chalk_1.default.gray('• If the problem persists, contact support'));
|
|
96
103
|
}
|
|
97
104
|
// Progressive guidance for repeated failures
|
|
98
105
|
if (failureCount >= 3) {
|
|
99
106
|
console.log();
|
|
100
|
-
console.log(
|
|
107
|
+
console.log(chalk_1.default.yellow('💡 Multiple failures detected. Recovery options:'));
|
|
101
108
|
if (authMethod === 'vendor_key') {
|
|
102
|
-
console.log(
|
|
103
|
-
console.log(
|
|
104
|
-
console.log(
|
|
109
|
+
console.log(chalk_1.default.cyan('• Generate a new vendor key from your dashboard'));
|
|
110
|
+
console.log(chalk_1.default.cyan('• Try: lanonasis auth logout && lanonasis auth login'));
|
|
111
|
+
console.log(chalk_1.default.cyan('• Switch to browser login: lanonasis auth login (choose Browser Login)'));
|
|
105
112
|
}
|
|
106
113
|
else {
|
|
107
|
-
console.log(
|
|
108
|
-
console.log(
|
|
109
|
-
console.log(
|
|
114
|
+
console.log(chalk_1.default.cyan('• Reset your password if you\'re unsure'));
|
|
115
|
+
console.log(chalk_1.default.cyan('• Try vendor key authentication instead'));
|
|
116
|
+
console.log(chalk_1.default.cyan('• Clear stored config: lanonasis auth logout'));
|
|
110
117
|
}
|
|
111
118
|
if (failureCount >= 5) {
|
|
112
|
-
console.log(
|
|
113
|
-
console.log(
|
|
119
|
+
console.log(chalk_1.default.yellow('• Consider contacting support if issues persist'));
|
|
120
|
+
console.log(chalk_1.default.gray('• Include error details and your email address'));
|
|
114
121
|
}
|
|
115
122
|
}
|
|
116
123
|
}
|
|
@@ -174,9 +181,9 @@ function categorizeAuthError(error) {
|
|
|
174
181
|
*/
|
|
175
182
|
function generatePKCE() {
|
|
176
183
|
// Generate random verifier (43-128 chars, base64url)
|
|
177
|
-
const verifier =
|
|
184
|
+
const verifier = crypto_1.default.randomBytes(32).toString('base64url');
|
|
178
185
|
// Generate challenge: base64url(sha256(verifier))
|
|
179
|
-
const challenge =
|
|
186
|
+
const challenge = crypto_1.default
|
|
180
187
|
.createHash('sha256')
|
|
181
188
|
.update(verifier)
|
|
182
189
|
.digest('base64url');
|
|
@@ -187,8 +194,8 @@ function generatePKCE() {
|
|
|
187
194
|
*/
|
|
188
195
|
function createCallbackServer(port = 8888) {
|
|
189
196
|
return new Promise((resolve, reject) => {
|
|
190
|
-
const server =
|
|
191
|
-
const parsedUrl =
|
|
197
|
+
const server = http_1.default.createServer((req, res) => {
|
|
198
|
+
const parsedUrl = url_1.default.parse(req.url, true);
|
|
192
199
|
if (parsedUrl.pathname === '/callback') {
|
|
193
200
|
const { code, state, error, error_description } = parsedUrl.query;
|
|
194
201
|
// Send response to browser
|
|
@@ -230,7 +237,7 @@ function createCallbackServer(port = 8888) {
|
|
|
230
237
|
}
|
|
231
238
|
});
|
|
232
239
|
server.listen(port, () => {
|
|
233
|
-
console.log(
|
|
240
|
+
console.log(chalk_1.default.gray(` Local callback server listening on port ${port}`));
|
|
234
241
|
});
|
|
235
242
|
// Timeout after 5 minutes
|
|
236
243
|
setTimeout(() => {
|
|
@@ -244,7 +251,7 @@ function createCallbackServer(port = 8888) {
|
|
|
244
251
|
*/
|
|
245
252
|
async function exchangeCodeForTokens(code, verifier, authBase) {
|
|
246
253
|
const tokenEndpoint = `${authBase}/oauth/token`;
|
|
247
|
-
const response = await apiClient.post(tokenEndpoint, {
|
|
254
|
+
const response = await api_js_1.apiClient.post(tokenEndpoint, {
|
|
248
255
|
grant_type: 'authorization_code',
|
|
249
256
|
code,
|
|
250
257
|
code_verifier: verifier,
|
|
@@ -263,7 +270,7 @@ async function refreshOAuth2Token(config) {
|
|
|
263
270
|
}
|
|
264
271
|
try {
|
|
265
272
|
const authBase = config.getDiscoveredApiUrl();
|
|
266
|
-
const response = await apiClient.post(`${authBase}/oauth/token`, {
|
|
273
|
+
const response = await api_js_1.apiClient.post(`${authBase}/oauth/token`, {
|
|
267
274
|
grant_type: 'refresh_token',
|
|
268
275
|
refresh_token: refreshToken,
|
|
269
276
|
client_id: 'lanonasis-cli'
|
|
@@ -276,14 +283,14 @@ async function refreshOAuth2Token(config) {
|
|
|
276
283
|
return true;
|
|
277
284
|
}
|
|
278
285
|
catch (error) {
|
|
279
|
-
console.error(
|
|
286
|
+
console.error(chalk_1.default.yellow('⚠️ Token refresh failed, please re-authenticate'));
|
|
280
287
|
return false;
|
|
281
288
|
}
|
|
282
289
|
}
|
|
283
|
-
|
|
284
|
-
const config = new CLIConfig();
|
|
290
|
+
async function diagnoseCommand() {
|
|
291
|
+
const config = new config_js_1.CLIConfig();
|
|
285
292
|
await config.init();
|
|
286
|
-
console.log(
|
|
293
|
+
console.log(chalk_1.default.blue.bold('🔍 Authentication Diagnostic'));
|
|
287
294
|
console.log(colors.info('━'.repeat(50)));
|
|
288
295
|
console.log();
|
|
289
296
|
const diagnostics = {
|
|
@@ -299,146 +306,146 @@ export async function diagnoseCommand() {
|
|
|
299
306
|
deviceId: null
|
|
300
307
|
};
|
|
301
308
|
// Step 1: Check if config exists
|
|
302
|
-
console.log(
|
|
309
|
+
console.log(chalk_1.default.cyan('1. Configuration File'));
|
|
303
310
|
try {
|
|
304
311
|
const configExists = await config.exists();
|
|
305
312
|
diagnostics.configExists = configExists;
|
|
306
313
|
if (configExists) {
|
|
307
|
-
console.log(
|
|
314
|
+
console.log(chalk_1.default.green(' ✓ Config file exists at'), config.getConfigPath());
|
|
308
315
|
}
|
|
309
316
|
else {
|
|
310
|
-
console.log(
|
|
311
|
-
console.log(
|
|
317
|
+
console.log(chalk_1.default.red(' ✖ Config file not found at'), config.getConfigPath());
|
|
318
|
+
console.log(chalk_1.default.gray(' → Run: lanonasis auth login'));
|
|
312
319
|
}
|
|
313
320
|
}
|
|
314
321
|
catch (error) {
|
|
315
|
-
console.log(
|
|
322
|
+
console.log(chalk_1.default.red(' ✖ Error checking config:'), error instanceof Error ? error.message : 'Unknown error');
|
|
316
323
|
}
|
|
317
324
|
// Step 2: Check stored credentials
|
|
318
|
-
console.log(
|
|
325
|
+
console.log(chalk_1.default.cyan('\n2. Stored Credentials'));
|
|
319
326
|
const token = config.getToken();
|
|
320
327
|
const vendorKey = config.getVendorKey();
|
|
321
328
|
const authMethod = config.get('authMethod');
|
|
322
329
|
if (vendorKey) {
|
|
323
330
|
diagnostics.hasCredentials = true;
|
|
324
331
|
diagnostics.credentialType = 'vendor_key';
|
|
325
|
-
console.log(
|
|
332
|
+
console.log(chalk_1.default.green(' ✓ Vendor key found'));
|
|
326
333
|
// Validate vendor key presence
|
|
327
334
|
const formatValidation = config.validateVendorKeyFormat(vendorKey);
|
|
328
335
|
if (formatValidation !== true) {
|
|
329
|
-
console.log(
|
|
336
|
+
console.log(chalk_1.default.red(` ✖ Vendor key issue: ${formatValidation}`));
|
|
330
337
|
}
|
|
331
338
|
}
|
|
332
339
|
else if (token) {
|
|
333
340
|
diagnostics.hasCredentials = true;
|
|
334
341
|
diagnostics.credentialType = authMethod === 'oauth' ? 'oauth' : 'jwt';
|
|
335
|
-
console.log(
|
|
342
|
+
console.log(chalk_1.default.green(` ✓ ${diagnostics.credentialType.toUpperCase()} token found`));
|
|
336
343
|
// Check token expiry
|
|
337
344
|
try {
|
|
338
345
|
const isAuth = await config.isAuthenticated();
|
|
339
346
|
if (!isAuth) {
|
|
340
347
|
diagnostics.tokenExpired = true;
|
|
341
|
-
console.log(
|
|
348
|
+
console.log(chalk_1.default.red(' ✖ Token is expired'));
|
|
342
349
|
}
|
|
343
350
|
else {
|
|
344
|
-
console.log(
|
|
351
|
+
console.log(chalk_1.default.green(' ✓ Token is not expired'));
|
|
345
352
|
}
|
|
346
353
|
}
|
|
347
354
|
catch (error) {
|
|
348
|
-
console.log(
|
|
355
|
+
console.log(chalk_1.default.yellow(' ⚠ Could not validate token expiry'));
|
|
349
356
|
if (process.env.CLI_VERBOSE === 'true' && error instanceof Error) {
|
|
350
|
-
console.log(
|
|
357
|
+
console.log(chalk_1.default.gray(` ${error.message}`));
|
|
351
358
|
}
|
|
352
359
|
}
|
|
353
360
|
}
|
|
354
361
|
else {
|
|
355
|
-
console.log(
|
|
356
|
-
console.log(
|
|
362
|
+
console.log(chalk_1.default.red(' ✖ No credentials found'));
|
|
363
|
+
console.log(chalk_1.default.gray(' → Run: lanonasis auth login'));
|
|
357
364
|
}
|
|
358
365
|
// Step 3: Check authentication failures
|
|
359
|
-
console.log(
|
|
366
|
+
console.log(chalk_1.default.cyan('\n3. Authentication History'));
|
|
360
367
|
diagnostics.authFailures = config.getFailureCount();
|
|
361
368
|
diagnostics.lastFailure = config.getLastAuthFailure() ?? null;
|
|
362
369
|
if (diagnostics.authFailures === 0) {
|
|
363
|
-
console.log(
|
|
370
|
+
console.log(chalk_1.default.green(' ✓ No recent authentication failures'));
|
|
364
371
|
}
|
|
365
372
|
else {
|
|
366
|
-
console.log(
|
|
373
|
+
console.log(chalk_1.default.yellow(` ⚠ ${diagnostics.authFailures} recent authentication failures`));
|
|
367
374
|
if (diagnostics.lastFailure) {
|
|
368
375
|
const lastFailureDate = new Date(diagnostics.lastFailure);
|
|
369
|
-
console.log(
|
|
376
|
+
console.log(chalk_1.default.gray(` Last failure: ${lastFailureDate.toLocaleString()}`));
|
|
370
377
|
}
|
|
371
378
|
if (config.shouldDelayAuth()) {
|
|
372
379
|
const delayMs = config.getAuthDelayMs();
|
|
373
|
-
console.log(
|
|
380
|
+
console.log(chalk_1.default.yellow(` ⚠ Authentication delay active: ${Math.round(delayMs / 1000)}s`));
|
|
374
381
|
}
|
|
375
382
|
}
|
|
376
383
|
// Step 4: Test credential validation against server
|
|
377
|
-
console.log(
|
|
384
|
+
console.log(chalk_1.default.cyan('\n4. Server Validation'));
|
|
378
385
|
if (diagnostics.hasCredentials) {
|
|
379
|
-
const spinner =
|
|
386
|
+
const spinner = (0, ora_1.default)('Testing credentials against server...').start();
|
|
380
387
|
try {
|
|
381
388
|
const isValid = await config.validateStoredCredentials();
|
|
382
389
|
diagnostics.credentialsValid = isValid;
|
|
383
390
|
if (isValid) {
|
|
384
391
|
spinner.succeed('Credentials are valid');
|
|
385
|
-
console.log(
|
|
392
|
+
console.log(chalk_1.default.green(' ✓ Server authentication successful'));
|
|
386
393
|
}
|
|
387
394
|
else {
|
|
388
395
|
spinner.fail('Credentials are invalid');
|
|
389
|
-
console.log(
|
|
390
|
-
console.log(
|
|
396
|
+
console.log(chalk_1.default.red(' ✖ Server rejected credentials'));
|
|
397
|
+
console.log(chalk_1.default.gray(' → Try: lanonasis auth login'));
|
|
391
398
|
}
|
|
392
399
|
}
|
|
393
400
|
catch (error) {
|
|
394
401
|
spinner.fail('Server validation failed');
|
|
395
|
-
console.log(
|
|
396
|
-
console.log(
|
|
402
|
+
console.log(chalk_1.default.red(' ✖ Could not validate with server:'));
|
|
403
|
+
console.log(chalk_1.default.gray(` ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
397
404
|
}
|
|
398
405
|
}
|
|
399
406
|
else {
|
|
400
|
-
console.log(
|
|
407
|
+
console.log(chalk_1.default.gray(' - Skipped (no credentials to validate)'));
|
|
401
408
|
}
|
|
402
409
|
// Step 5: Test endpoint connectivity
|
|
403
|
-
console.log(
|
|
404
|
-
const spinner2 =
|
|
410
|
+
console.log(chalk_1.default.cyan('\n5. Endpoint Connectivity'));
|
|
411
|
+
const spinner2 = (0, ora_1.default)('Testing authentication endpoints...').start();
|
|
405
412
|
try {
|
|
406
413
|
await config.discoverServices();
|
|
407
414
|
diagnostics.serviceDiscovery = true;
|
|
408
415
|
const services = config.get('discoveredServices');
|
|
409
416
|
if (services) {
|
|
410
417
|
spinner2.succeed('Authentication endpoints reachable');
|
|
411
|
-
console.log(
|
|
412
|
-
console.log(
|
|
418
|
+
console.log(chalk_1.default.green(' ✓ Service discovery successful'));
|
|
419
|
+
console.log(chalk_1.default.gray(` Auth endpoint: ${services.auth_base}`));
|
|
413
420
|
diagnostics.endpointsReachable = true;
|
|
414
421
|
}
|
|
415
422
|
else {
|
|
416
423
|
spinner2.warn('Using fallback endpoints');
|
|
417
|
-
console.log(
|
|
424
|
+
console.log(chalk_1.default.yellow(' ⚠ Service discovery failed, using fallbacks'));
|
|
418
425
|
diagnostics.endpointsReachable = true; // Fallbacks still work
|
|
419
426
|
}
|
|
420
427
|
}
|
|
421
428
|
catch (error) {
|
|
422
429
|
spinner2.fail('Endpoint connectivity failed');
|
|
423
|
-
console.log(
|
|
424
|
-
console.log(
|
|
425
|
-
console.log(
|
|
430
|
+
console.log(chalk_1.default.red(' ✖ Cannot reach authentication endpoints'));
|
|
431
|
+
console.log(chalk_1.default.gray(` ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
432
|
+
console.log(chalk_1.default.gray(' → Check internet connection'));
|
|
426
433
|
}
|
|
427
434
|
// Step 6: Device identification
|
|
428
|
-
console.log(
|
|
435
|
+
console.log(chalk_1.default.cyan('\n6. Device Information'));
|
|
429
436
|
try {
|
|
430
437
|
const deviceId = await config.getDeviceId();
|
|
431
438
|
diagnostics.deviceId = deviceId;
|
|
432
|
-
console.log(
|
|
439
|
+
console.log(chalk_1.default.green(' ✓ Device ID:'), chalk_1.default.gray(deviceId));
|
|
433
440
|
}
|
|
434
441
|
catch (error) {
|
|
435
|
-
console.log(
|
|
442
|
+
console.log(chalk_1.default.yellow(' ⚠ Could not get device ID'));
|
|
436
443
|
if (process.env.CLI_VERBOSE === 'true' && error instanceof Error) {
|
|
437
|
-
console.log(
|
|
444
|
+
console.log(chalk_1.default.gray(` ${error.message}`));
|
|
438
445
|
}
|
|
439
446
|
}
|
|
440
447
|
// Summary and recommendations
|
|
441
|
-
console.log(
|
|
448
|
+
console.log(chalk_1.default.blue.bold('\n📋 Diagnostic Summary'));
|
|
442
449
|
console.log(colors.info('━'.repeat(50)));
|
|
443
450
|
const issues = [];
|
|
444
451
|
const recommendations = [];
|
|
@@ -467,32 +474,32 @@ export async function diagnoseCommand() {
|
|
|
467
474
|
recommendations.push('Check internet connection and firewall settings');
|
|
468
475
|
}
|
|
469
476
|
if (issues.length === 0) {
|
|
470
|
-
console.log(
|
|
471
|
-
console.log(
|
|
477
|
+
console.log(chalk_1.default.green('✅ All authentication checks passed!'));
|
|
478
|
+
console.log(chalk_1.default.cyan(' Your authentication is working correctly.'));
|
|
472
479
|
}
|
|
473
480
|
else {
|
|
474
|
-
console.log(
|
|
481
|
+
console.log(chalk_1.default.red(`❌ Found ${issues.length} issue(s):`));
|
|
475
482
|
issues.forEach(issue => {
|
|
476
|
-
console.log(
|
|
483
|
+
console.log(chalk_1.default.red(` • ${issue}`));
|
|
477
484
|
});
|
|
478
|
-
console.log(
|
|
485
|
+
console.log(chalk_1.default.yellow('\n💡 Recommended actions:'));
|
|
479
486
|
recommendations.forEach(rec => {
|
|
480
|
-
console.log(
|
|
487
|
+
console.log(chalk_1.default.cyan(` • ${rec}`));
|
|
481
488
|
});
|
|
482
489
|
}
|
|
483
490
|
// Additional troubleshooting info
|
|
484
491
|
if (diagnostics.authFailures > 0 || !diagnostics.credentialsValid) {
|
|
485
|
-
console.log(
|
|
486
|
-
console.log(
|
|
487
|
-
console.log(
|
|
488
|
-
console.log(
|
|
489
|
-
console.log(
|
|
492
|
+
console.log(chalk_1.default.gray('\n🔧 Additional troubleshooting:'));
|
|
493
|
+
console.log(chalk_1.default.gray(' • Verify the vendor key matches the value shown in your dashboard'));
|
|
494
|
+
console.log(chalk_1.default.gray(' • Check if your key is active in the dashboard'));
|
|
495
|
+
console.log(chalk_1.default.gray(' • Try browser authentication: lanonasis auth login (choose Browser Login)'));
|
|
496
|
+
console.log(chalk_1.default.gray(' • Contact support if issues persist'));
|
|
490
497
|
}
|
|
491
498
|
}
|
|
492
|
-
|
|
493
|
-
const config = new CLIConfig();
|
|
499
|
+
async function loginCommand(options) {
|
|
500
|
+
const config = new config_js_1.CLIConfig();
|
|
494
501
|
await config.init();
|
|
495
|
-
console.log(
|
|
502
|
+
console.log(chalk_1.default.blue.bold('🔐 Onasis-Core Golden Contract Authentication'));
|
|
496
503
|
console.log(colors.info('━'.repeat(50)));
|
|
497
504
|
console.log();
|
|
498
505
|
// Debug: Check options
|
|
@@ -514,7 +521,7 @@ export async function loginCommand(options) {
|
|
|
514
521
|
return;
|
|
515
522
|
}
|
|
516
523
|
// Show authentication options
|
|
517
|
-
const authChoice = await
|
|
524
|
+
const authChoice = await inquirer_1.default.prompt([
|
|
518
525
|
{
|
|
519
526
|
type: 'list',
|
|
520
527
|
name: 'method',
|
|
@@ -550,14 +557,14 @@ export async function loginCommand(options) {
|
|
|
550
557
|
async function handleVendorKeyAuth(vendorKey, config) {
|
|
551
558
|
// Check for authentication delay before attempting
|
|
552
559
|
await handleAuthDelay(config);
|
|
553
|
-
const spinner =
|
|
560
|
+
const spinner = (0, ora_1.default)('Validating vendor key...').start();
|
|
554
561
|
try {
|
|
555
562
|
await config.setVendorKey(vendorKey);
|
|
556
563
|
// Test the vendor key with a health check
|
|
557
|
-
await apiClient.get('/health');
|
|
564
|
+
await api_js_1.apiClient.get('/health');
|
|
558
565
|
spinner.succeed('Vendor key authentication successful');
|
|
559
566
|
console.log();
|
|
560
|
-
console.log(
|
|
567
|
+
console.log(chalk_1.default.green('✓ Authenticated with vendor key'));
|
|
561
568
|
console.log(colors.info('Ready to use Onasis-Core services'));
|
|
562
569
|
}
|
|
563
570
|
catch (error) {
|
|
@@ -569,16 +576,16 @@ async function handleVendorKeyAuth(vendorKey, config) {
|
|
|
569
576
|
}
|
|
570
577
|
async function handleVendorKeyFlow(config) {
|
|
571
578
|
console.log();
|
|
572
|
-
console.log(
|
|
573
|
-
console.log(
|
|
579
|
+
console.log(chalk_1.default.yellow('🔑 Vendor Key Authentication'));
|
|
580
|
+
console.log(chalk_1.default.gray('Vendor keys provide secure API access for automation and integrations.'));
|
|
574
581
|
console.log();
|
|
575
582
|
// Enhanced guidance for obtaining vendor keys
|
|
576
|
-
console.log(
|
|
577
|
-
console.log(
|
|
578
|
-
console.log(
|
|
579
|
-
console.log(
|
|
583
|
+
console.log(chalk_1.default.cyan('📋 How to get your vendor key:'));
|
|
584
|
+
console.log(chalk_1.default.gray('1. Visit your Lanonasis dashboard at https://dashboard.lanonasis.com'));
|
|
585
|
+
console.log(chalk_1.default.gray('2. Navigate to Settings → API Keys'));
|
|
586
|
+
console.log(chalk_1.default.gray('3. Click "Generate New Key" and copy the full key value'));
|
|
580
587
|
console.log();
|
|
581
|
-
const { vendorKey } = await
|
|
588
|
+
const { vendorKey } = await inquirer_1.default.prompt([
|
|
582
589
|
{
|
|
583
590
|
type: 'password',
|
|
584
591
|
name: 'vendorKey',
|
|
@@ -593,10 +600,10 @@ async function handleVendorKeyFlow(config) {
|
|
|
593
600
|
}
|
|
594
601
|
async function handleOAuthFlow(config) {
|
|
595
602
|
console.log();
|
|
596
|
-
console.log(
|
|
597
|
-
console.log(
|
|
603
|
+
console.log(chalk_1.default.yellow('🌐 Browser-Based OAuth2 Authentication'));
|
|
604
|
+
console.log(chalk_1.default.gray('Secure authentication using OAuth2 with PKCE'));
|
|
598
605
|
console.log();
|
|
599
|
-
const { openBrowser } = await
|
|
606
|
+
const { openBrowser } = await inquirer_1.default.prompt([
|
|
600
607
|
{
|
|
601
608
|
type: 'confirm',
|
|
602
609
|
name: 'openBrowser',
|
|
@@ -605,17 +612,17 @@ async function handleOAuthFlow(config) {
|
|
|
605
612
|
}
|
|
606
613
|
]);
|
|
607
614
|
if (!openBrowser) {
|
|
608
|
-
console.log(
|
|
615
|
+
console.log(chalk_1.default.yellow('⚠️ Authentication cancelled'));
|
|
609
616
|
return;
|
|
610
617
|
}
|
|
611
618
|
try {
|
|
612
619
|
// Generate PKCE challenge
|
|
613
620
|
const pkce = generatePKCE();
|
|
614
|
-
console.log(
|
|
621
|
+
console.log(chalk_1.default.gray(' ✓ Generated PKCE challenge'));
|
|
615
622
|
// Start local callback server
|
|
616
623
|
const callbackPort = 8888;
|
|
617
624
|
const callbackPromise = createCallbackServer(callbackPort);
|
|
618
|
-
console.log(
|
|
625
|
+
console.log(chalk_1.default.gray(` ✓ Started local callback server on port ${callbackPort}`));
|
|
619
626
|
// Build OAuth2 authorization URL
|
|
620
627
|
const authBase = config.getDiscoveredApiUrl();
|
|
621
628
|
const authUrl = new URL(`${authBase}/oauth/authorize`);
|
|
@@ -625,15 +632,15 @@ async function handleOAuthFlow(config) {
|
|
|
625
632
|
authUrl.searchParams.set('scope', 'read write offline_access');
|
|
626
633
|
authUrl.searchParams.set('code_challenge', pkce.challenge);
|
|
627
634
|
authUrl.searchParams.set('code_challenge_method', 'S256');
|
|
628
|
-
authUrl.searchParams.set('state',
|
|
635
|
+
authUrl.searchParams.set('state', crypto_1.default.randomBytes(16).toString('hex'));
|
|
629
636
|
console.log();
|
|
630
637
|
console.log(colors.info('Opening browser for authentication...'));
|
|
631
|
-
await
|
|
638
|
+
await (0, open_1.default)(authUrl.toString());
|
|
632
639
|
console.log(colors.info('Waiting for authentication in browser...'));
|
|
633
640
|
console.log(colors.muted(`If browser doesn't open, visit: ${authUrl.toString()}`));
|
|
634
641
|
console.log();
|
|
635
642
|
// Wait for callback
|
|
636
|
-
const spinner =
|
|
643
|
+
const spinner = (0, ora_1.default)('Waiting for authorization...').start();
|
|
637
644
|
const { code } = await callbackPromise;
|
|
638
645
|
spinner.succeed('Authorization code received');
|
|
639
646
|
// Exchange code for tokens
|
|
@@ -647,27 +654,27 @@ async function handleOAuthFlow(config) {
|
|
|
647
654
|
await config.set('token_expires_at', Date.now() + (tokens.expires_in * 1000));
|
|
648
655
|
await config.set('authMethod', 'oauth2');
|
|
649
656
|
console.log();
|
|
650
|
-
console.log(
|
|
657
|
+
console.log(chalk_1.default.green('✓ OAuth2 authentication successful'));
|
|
651
658
|
console.log(colors.info('You can now use Lanonasis services'));
|
|
652
659
|
process.exit(0);
|
|
653
660
|
}
|
|
654
661
|
catch (error) {
|
|
655
|
-
console.error(
|
|
662
|
+
console.error(chalk_1.default.red('✖ OAuth2 authentication failed'));
|
|
656
663
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
657
|
-
console.error(
|
|
664
|
+
console.error(chalk_1.default.gray(` ${errorMessage}`));
|
|
658
665
|
process.exit(1);
|
|
659
666
|
}
|
|
660
667
|
}
|
|
661
668
|
async function handleCredentialsFlow(options, config) {
|
|
662
669
|
console.log();
|
|
663
|
-
console.log(
|
|
670
|
+
console.log(chalk_1.default.yellow('⚙️ Username/Password Authentication'));
|
|
664
671
|
console.log();
|
|
665
672
|
// Check for authentication delay before attempting
|
|
666
673
|
await handleAuthDelay(config);
|
|
667
674
|
let { email, password } = options;
|
|
668
675
|
// Get credentials if not provided
|
|
669
676
|
if (!email || !password) {
|
|
670
|
-
const answers = await
|
|
677
|
+
const answers = await inquirer_1.default.prompt([
|
|
671
678
|
{
|
|
672
679
|
type: 'input',
|
|
673
680
|
name: 'email',
|
|
@@ -689,14 +696,14 @@ async function handleCredentialsFlow(options, config) {
|
|
|
689
696
|
email = answers.email;
|
|
690
697
|
password = answers.password;
|
|
691
698
|
}
|
|
692
|
-
const spinner =
|
|
699
|
+
const spinner = (0, ora_1.default)('Authenticating...').start();
|
|
693
700
|
try {
|
|
694
|
-
const response = await apiClient.login(email, password);
|
|
701
|
+
const response = await api_js_1.apiClient.login(email, password);
|
|
695
702
|
// Store token and user info
|
|
696
703
|
await config.setToken(response.token);
|
|
697
704
|
spinner.succeed('Login successful');
|
|
698
705
|
console.log();
|
|
699
|
-
console.log(
|
|
706
|
+
console.log(chalk_1.default.green('✓ Authenticated successfully'));
|
|
700
707
|
console.log(`Welcome, ${response.user.email}!`);
|
|
701
708
|
if (response.user.organization_id) {
|
|
702
709
|
console.log(`Organization: ${response.user.organization_id}`);
|
|
@@ -711,7 +718,7 @@ async function handleCredentialsFlow(options, config) {
|
|
|
711
718
|
const errorResponse = error && typeof error === 'object' && 'response' in error ? error.response : null;
|
|
712
719
|
if (errorResponse && typeof errorResponse === 'object' && 'status' in errorResponse && errorResponse.status === 401) {
|
|
713
720
|
console.log();
|
|
714
|
-
const answer = await
|
|
721
|
+
const answer = await inquirer_1.default.prompt([
|
|
715
722
|
{
|
|
716
723
|
type: 'confirm',
|
|
717
724
|
name: 'register',
|
|
@@ -729,9 +736,9 @@ async function handleCredentialsFlow(options, config) {
|
|
|
729
736
|
}
|
|
730
737
|
async function registerFlow(defaultEmail) {
|
|
731
738
|
console.log();
|
|
732
|
-
console.log(
|
|
739
|
+
console.log(chalk_1.default.blue.bold('📝 Create New Account'));
|
|
733
740
|
console.log();
|
|
734
|
-
const answers = await
|
|
741
|
+
const answers = await inquirer_1.default.prompt([
|
|
735
742
|
{
|
|
736
743
|
type: 'input',
|
|
737
744
|
name: 'email',
|
|
@@ -765,14 +772,14 @@ async function registerFlow(defaultEmail) {
|
|
|
765
772
|
default: ''
|
|
766
773
|
}
|
|
767
774
|
]);
|
|
768
|
-
const spinner =
|
|
775
|
+
const spinner = (0, ora_1.default)('Creating account...').start();
|
|
769
776
|
try {
|
|
770
|
-
const response = await apiClient.register(answers.email, answers.password, answers.organizationName || undefined);
|
|
771
|
-
const config = new CLIConfig();
|
|
777
|
+
const response = await api_js_1.apiClient.register(answers.email, answers.password, answers.organizationName || undefined);
|
|
778
|
+
const config = new config_js_1.CLIConfig();
|
|
772
779
|
await config.setToken(response.token);
|
|
773
780
|
spinner.succeed('Account created successfully');
|
|
774
781
|
console.log();
|
|
775
|
-
console.log(
|
|
782
|
+
console.log(chalk_1.default.green('✓ Account created and authenticated'));
|
|
776
783
|
console.log(`Welcome to MaaS, ${response.user.email}!`);
|
|
777
784
|
if (answers.organizationName) {
|
|
778
785
|
console.log(`Organization: ${answers.organizationName}`);
|
|
@@ -782,7 +789,7 @@ async function registerFlow(defaultEmail) {
|
|
|
782
789
|
catch (error) {
|
|
783
790
|
spinner.fail('Registration failed');
|
|
784
791
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
785
|
-
console.error(
|
|
792
|
+
console.error(chalk_1.default.red('✖ Registration failed:'), errorMessage);
|
|
786
793
|
process.exit(1);
|
|
787
794
|
}
|
|
788
795
|
}
|