@ayurak/aribot-cli 1.0.10 → 1.0.12

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/cli.js CHANGED
@@ -37,7 +37,7 @@ const program = new commander_1.Command();
37
37
  program
38
38
  .name('aribot')
39
39
  .description('Aribot - Economic, Regulatory & Security APIs for Modern Applications')
40
- .version('1.0.10');
40
+ .version('1.0.12');
41
41
  // Helper to get auth headers
42
42
  function getHeaders() {
43
43
  const apiKey = config.get('apiKey');
@@ -80,17 +80,84 @@ async function resolveDiagramId(shortId) {
80
80
  program
81
81
  .command('login')
82
82
  .description('Authenticate with your Aribot API key')
83
- .action(async () => {
84
- const { apiKey } = await inquirer_1.default.prompt([{
85
- type: 'password',
86
- name: 'apiKey',
87
- message: 'Enter your Aribot API key:',
88
- mask: '*'
89
- }]);
90
- const spinner = (0, ora_1.default)('Exchanging API key for token...').start();
83
+ .option('-k, --key <key>', 'API key (alternative to interactive prompt)')
84
+ .option('--open-portal', 'Open developer portal to create API key')
85
+ .action(async (options) => {
86
+ // Welcome banner
87
+ console.log();
88
+ console.log(chalk_1.default.cyan('='.repeat(50)));
89
+ console.log(chalk_1.default.cyan.bold(' ARIBOT CLI - Secure Authentication'));
90
+ console.log(chalk_1.default.cyan('='.repeat(50)));
91
+ console.log();
92
+ // Check existing auth
93
+ const existingKey = config.get('apiKey');
94
+ if (existingKey) {
95
+ console.log(chalk_1.default.yellow('You are already logged in.'));
96
+ const email = config.get('userEmail');
97
+ const company = config.get('company');
98
+ if (email) {
99
+ console.log(` ${chalk_1.default.dim('Email:')} ${email}`);
100
+ console.log(` ${chalk_1.default.dim('Company:')} ${company || 'N/A'}`);
101
+ }
102
+ console.log();
103
+ const { reauth } = await inquirer_1.default.prompt([{
104
+ type: 'confirm',
105
+ name: 'reauth',
106
+ message: 'Would you like to re-authenticate with a different key?',
107
+ default: false
108
+ }]);
109
+ if (!reauth)
110
+ return;
111
+ }
112
+ // Open developer portal if requested
113
+ if (options.openPortal) {
114
+ const open = (await import('open')).default;
115
+ const portalUrl = 'https://portal.aribot.ayurak.com/developer';
116
+ console.log(chalk_1.default.cyan('Opening developer portal...'));
117
+ console.log(chalk_1.default.dim(portalUrl));
118
+ await open(portalUrl);
119
+ console.log();
120
+ console.log(chalk_1.default.dim('After creating your API key, run:'));
121
+ console.log(' ' + chalk_1.default.green('aribot login'));
122
+ return;
123
+ }
124
+ // Show instructions
125
+ console.log(chalk_1.default.bold('To authenticate, you need an API key.'));
126
+ console.log();
127
+ console.log(chalk_1.default.dim('Get your API key from the developer portal:'));
128
+ console.log(' ' + chalk_1.default.cyan('https://portal.aribot.ayurak.com/developer'));
129
+ console.log();
130
+ console.log(chalk_1.default.dim('Or run: ' + chalk_1.default.green('aribot login --open-portal') + ' to open it'));
131
+ console.log();
132
+ // Get API key
133
+ let apiKey = options.key;
134
+ if (!apiKey) {
135
+ console.log(chalk_1.default.bold('Enter your API key below'));
136
+ console.log(chalk_1.default.dim('(input is hidden for security)'));
137
+ const response = await inquirer_1.default.prompt([{
138
+ type: 'password',
139
+ name: 'apiKey',
140
+ message: 'API Key:',
141
+ mask: '*'
142
+ }]);
143
+ apiKey = response.apiKey;
144
+ }
145
+ else {
146
+ console.log(chalk_1.default.dim('Using provided API key...'));
147
+ }
148
+ // Validate format
149
+ apiKey = apiKey.trim();
150
+ if (apiKey.length < 20) {
151
+ console.log();
152
+ console.log(chalk_1.default.red('Invalid API key format'));
153
+ console.log(chalk_1.default.dim('API keys should be at least 20 characters long.'));
154
+ console.log(chalk_1.default.dim('Get a valid key from: https://portal.aribot.ayurak.com/developer'));
155
+ return;
156
+ }
157
+ console.log();
158
+ const spinner = (0, ora_1.default)('Validating API key...').start();
91
159
  try {
92
160
  const fetch = (await import('node-fetch')).default;
93
- // Exchange API key for JWT token
94
161
  const response = await fetch(`${API_BASE}/v1/developer/token/`, {
95
162
  method: 'POST',
96
163
  headers: { 'Content-Type': 'application/json' },
@@ -98,22 +165,62 @@ program
98
165
  });
99
166
  if (response.ok) {
100
167
  const data = await response.json();
168
+ spinner.text = 'Storing credentials securely...';
101
169
  config.set('accessToken', data.access);
102
170
  config.set('refreshToken', data.refresh);
103
171
  config.set('apiKey', apiKey);
104
172
  config.set('userEmail', data.user?.email);
105
173
  config.set('company', data.user?.company);
106
- spinner.succeed(chalk_1.default.green('Authenticated successfully!'));
107
- console.log(chalk_1.default.dim(`Logged in as ${data.user?.email}`));
174
+ spinner.succeed(chalk_1.default.green('Authentication successful!'));
175
+ console.log();
176
+ console.log(chalk_1.default.bold('Account Details:'));
177
+ console.log(` ${chalk_1.default.cyan('Email:')} ${data.user?.email || 'N/A'}`);
178
+ console.log(` ${chalk_1.default.cyan('Company:')} ${data.user?.company || 'N/A'}`);
179
+ console.log(` ${chalk_1.default.cyan('Plan:')} ${data.plan || 'Standard'}`);
180
+ console.log();
181
+ console.log(chalk_1.default.bold('Security:'));
182
+ console.log(' ' + chalk_1.default.green('API key stored in secure config'));
183
+ console.log(' ' + chalk_1.default.dim('Your key is encrypted and safe.'));
184
+ console.log();
185
+ console.log(chalk_1.default.bold('Next steps:'));
186
+ console.log(' ' + chalk_1.default.cyan('aribot diagrams') + ' - List your diagrams');
187
+ console.log(' ' + chalk_1.default.cyan('aribot analyze <file>') + ' - Analyze a new diagram');
188
+ console.log(' ' + chalk_1.default.cyan('aribot status') + ' - Check API status');
189
+ console.log(' ' + chalk_1.default.cyan('aribot --help') + ' - See all commands');
108
190
  }
109
191
  else {
110
- const error = await response.json();
111
- spinner.fail(chalk_1.default.red(error.message || 'Invalid API key'));
192
+ spinner.fail(chalk_1.default.red('Authentication failed'));
193
+ console.log();
194
+ try {
195
+ const error = await response.json();
196
+ console.log(chalk_1.default.red(error.message || error.detail || 'Invalid API key'));
197
+ }
198
+ catch {
199
+ if (response.status === 401) {
200
+ console.log(chalk_1.default.red('Invalid API key. Please check and try again.'));
201
+ }
202
+ else if (response.status === 403) {
203
+ console.log(chalk_1.default.red('API key is disabled or expired.'));
204
+ }
205
+ else {
206
+ console.log(chalk_1.default.red(`Authentication failed (HTTP ${response.status})`));
207
+ }
208
+ }
209
+ console.log();
210
+ console.log(chalk_1.default.dim('Need a new API key? Visit:'));
211
+ console.log(' ' + chalk_1.default.cyan('https://portal.aribot.ayurak.com/developer'));
112
212
  }
113
213
  }
114
214
  catch (error) {
115
215
  spinner.fail(chalk_1.default.red('Authentication failed'));
116
- console.error(error);
216
+ console.log();
217
+ if (error.code === 'ETIMEDOUT' || error.code === 'ECONNREFUSED') {
218
+ console.log(chalk_1.default.red('Could not connect to Aribot servers.'));
219
+ console.log(chalk_1.default.dim('Please check your internet connection.'));
220
+ }
221
+ else {
222
+ console.error(error.message || error);
223
+ }
117
224
  }
118
225
  });
119
226
  // Logout command
package/dist/sdk.js CHANGED
@@ -69,7 +69,7 @@ exports.runComplianceCheck = runComplianceCheck;
69
69
  const fs = __importStar(require("fs"));
70
70
  const path = __importStar(require("path"));
71
71
  const crypto = __importStar(require("crypto"));
72
- const VERSION = '1.0.6';
72
+ const VERSION = '1.0.12';
73
73
  const DEFAULT_BASE_URL = 'https://api.aribot.ayurak.com/aribot-api';
74
74
  // =============================================================================
75
75
  // ERRORS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ayurak/aribot-cli",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Aribot - Economic, Regulatory & Security APIs for Modern Applications. Advanced multi-framework threat modeling (STRIDE, PASTA, NIST, Aristiun), 100+ compliance standards, Cloud Security, FinOps, and Red Team automation.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -73,6 +73,7 @@
73
73
  "form-data": "^4.0.0",
74
74
  "inquirer": "^9.2.0",
75
75
  "node-fetch": "^3.3.0",
76
+ "open": "^11.0.0",
76
77
  "ora": "^8.0.0"
77
78
  },
78
79
  "devDependencies": {
package/src/cli.ts CHANGED
@@ -36,7 +36,7 @@ const program = new Command();
36
36
  program
37
37
  .name('aribot')
38
38
  .description('Aribot - Economic, Regulatory & Security APIs for Modern Applications')
39
- .version('1.0.10');
39
+ .version('1.0.12');
40
40
 
41
41
  // Helper to get auth headers
42
42
  function getHeaders(): Record<string, string> {
@@ -88,19 +88,89 @@ async function resolveDiagramId(shortId: string): Promise<string> {
88
88
  program
89
89
  .command('login')
90
90
  .description('Authenticate with your Aribot API key')
91
- .action(async () => {
92
- const { apiKey } = await inquirer.prompt([{
93
- type: 'password',
94
- name: 'apiKey',
95
- message: 'Enter your Aribot API key:',
96
- mask: '*'
97
- }]);
91
+ .option('-k, --key <key>', 'API key (alternative to interactive prompt)')
92
+ .option('--open-portal', 'Open developer portal to create API key')
93
+ .action(async (options) => {
94
+ // Welcome banner
95
+ console.log();
96
+ console.log(chalk.cyan('='.repeat(50)));
97
+ console.log(chalk.cyan.bold(' ARIBOT CLI - Secure Authentication'));
98
+ console.log(chalk.cyan('='.repeat(50)));
99
+ console.log();
100
+
101
+ // Check existing auth
102
+ const existingKey = config.get('apiKey') as string;
103
+ if (existingKey) {
104
+ console.log(chalk.yellow('You are already logged in.'));
105
+ const email = config.get('userEmail') as string;
106
+ const company = config.get('company') as string;
107
+ if (email) {
108
+ console.log(` ${chalk.dim('Email:')} ${email}`);
109
+ console.log(` ${chalk.dim('Company:')} ${company || 'N/A'}`);
110
+ }
111
+ console.log();
112
+ const { reauth } = await inquirer.prompt([{
113
+ type: 'confirm',
114
+ name: 'reauth',
115
+ message: 'Would you like to re-authenticate with a different key?',
116
+ default: false
117
+ }]);
118
+ if (!reauth) return;
119
+ }
98
120
 
99
- const spinner = ora('Exchanging API key for token...').start();
121
+ // Open developer portal if requested
122
+ if (options.openPortal) {
123
+ const open = (await import('open')).default;
124
+ const portalUrl = 'https://portal.aribot.ayurak.com/developer';
125
+ console.log(chalk.cyan('Opening developer portal...'));
126
+ console.log(chalk.dim(portalUrl));
127
+ await open(portalUrl);
128
+ console.log();
129
+ console.log(chalk.dim('After creating your API key, run:'));
130
+ console.log(' ' + chalk.green('aribot login'));
131
+ return;
132
+ }
133
+
134
+ // Show instructions
135
+ console.log(chalk.bold('To authenticate, you need an API key.'));
136
+ console.log();
137
+ console.log(chalk.dim('Get your API key from the developer portal:'));
138
+ console.log(' ' + chalk.cyan('https://portal.aribot.ayurak.com/developer'));
139
+ console.log();
140
+ console.log(chalk.dim('Or run: ' + chalk.green('aribot login --open-portal') + ' to open it'));
141
+ console.log();
142
+
143
+ // Get API key
144
+ let apiKey = options.key;
145
+ if (!apiKey) {
146
+ console.log(chalk.bold('Enter your API key below'));
147
+ console.log(chalk.dim('(input is hidden for security)'));
148
+ const response = await inquirer.prompt([{
149
+ type: 'password',
150
+ name: 'apiKey',
151
+ message: 'API Key:',
152
+ mask: '*'
153
+ }]);
154
+ apiKey = response.apiKey;
155
+ } else {
156
+ console.log(chalk.dim('Using provided API key...'));
157
+ }
158
+
159
+ // Validate format
160
+ apiKey = apiKey.trim();
161
+ if (apiKey.length < 20) {
162
+ console.log();
163
+ console.log(chalk.red('Invalid API key format'));
164
+ console.log(chalk.dim('API keys should be at least 20 characters long.'));
165
+ console.log(chalk.dim('Get a valid key from: https://portal.aribot.ayurak.com/developer'));
166
+ return;
167
+ }
168
+
169
+ console.log();
170
+ const spinner = ora('Validating API key...').start();
100
171
 
101
172
  try {
102
173
  const fetch = (await import('node-fetch')).default;
103
- // Exchange API key for JWT token
104
174
  const response = await fetch(`${API_BASE}/v1/developer/token/`, {
105
175
  method: 'POST',
106
176
  headers: { 'Content-Type': 'application/json' },
@@ -109,20 +179,59 @@ program
109
179
 
110
180
  if (response.ok) {
111
181
  const data = await response.json() as any;
182
+ spinner.text = 'Storing credentials securely...';
183
+
112
184
  config.set('accessToken', data.access);
113
185
  config.set('refreshToken', data.refresh);
114
186
  config.set('apiKey', apiKey);
115
187
  config.set('userEmail', data.user?.email);
116
188
  config.set('company', data.user?.company);
117
- spinner.succeed(chalk.green('Authenticated successfully!'));
118
- console.log(chalk.dim(`Logged in as ${data.user?.email}`));
189
+
190
+ spinner.succeed(chalk.green('Authentication successful!'));
191
+
192
+ console.log();
193
+ console.log(chalk.bold('Account Details:'));
194
+ console.log(` ${chalk.cyan('Email:')} ${data.user?.email || 'N/A'}`);
195
+ console.log(` ${chalk.cyan('Company:')} ${data.user?.company || 'N/A'}`);
196
+ console.log(` ${chalk.cyan('Plan:')} ${data.plan || 'Standard'}`);
197
+ console.log();
198
+ console.log(chalk.bold('Security:'));
199
+ console.log(' ' + chalk.green('API key stored in secure config'));
200
+ console.log(' ' + chalk.dim('Your key is encrypted and safe.'));
201
+ console.log();
202
+ console.log(chalk.bold('Next steps:'));
203
+ console.log(' ' + chalk.cyan('aribot diagrams') + ' - List your diagrams');
204
+ console.log(' ' + chalk.cyan('aribot analyze <file>') + ' - Analyze a new diagram');
205
+ console.log(' ' + chalk.cyan('aribot status') + ' - Check API status');
206
+ console.log(' ' + chalk.cyan('aribot --help') + ' - See all commands');
119
207
  } else {
120
- const error = await response.json() as any;
121
- spinner.fail(chalk.red(error.message || 'Invalid API key'));
208
+ spinner.fail(chalk.red('Authentication failed'));
209
+ console.log();
210
+ try {
211
+ const error = await response.json() as any;
212
+ console.log(chalk.red(error.message || error.detail || 'Invalid API key'));
213
+ } catch {
214
+ if (response.status === 401) {
215
+ console.log(chalk.red('Invalid API key. Please check and try again.'));
216
+ } else if (response.status === 403) {
217
+ console.log(chalk.red('API key is disabled or expired.'));
218
+ } else {
219
+ console.log(chalk.red(`Authentication failed (HTTP ${response.status})`));
220
+ }
221
+ }
222
+ console.log();
223
+ console.log(chalk.dim('Need a new API key? Visit:'));
224
+ console.log(' ' + chalk.cyan('https://portal.aribot.ayurak.com/developer'));
122
225
  }
123
- } catch (error) {
226
+ } catch (error: any) {
124
227
  spinner.fail(chalk.red('Authentication failed'));
125
- console.error(error);
228
+ console.log();
229
+ if (error.code === 'ETIMEDOUT' || error.code === 'ECONNREFUSED') {
230
+ console.log(chalk.red('Could not connect to Aribot servers.'));
231
+ console.log(chalk.dim('Please check your internet connection.'));
232
+ } else {
233
+ console.error(error.message || error);
234
+ }
126
235
  }
127
236
  });
128
237
 
package/src/sdk.ts CHANGED
@@ -33,7 +33,7 @@ import * as fs from 'fs';
33
33
  import * as path from 'path';
34
34
  import * as crypto from 'crypto';
35
35
 
36
- const VERSION = '1.0.6';
36
+ const VERSION = '1.0.12';
37
37
  const DEFAULT_BASE_URL = 'https://api.aribot.ayurak.com/aribot-api';
38
38
 
39
39
  // =============================================================================