vigthoria-cli 1.13.23 → 1.13.24

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.
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import readline from 'readline';
3
3
  import { Config } from '../utils/config.js';
4
4
  import { clearGatewayPreflightCache } from '../utils/cli-state.js';
5
- import { AuthSessionService } from '../utils/auth-session.js';
5
+ import { AuthSessionService, validateTokenStructure } from '../utils/auth-session.js';
6
6
  import { assertTrustedEndpoint, guardedFetch } from '../utils/network-policy.js';
7
7
  import { CliCommandError, commandFailure } from '../utils/command-contract.js';
8
8
  const DEFAULT_API_URL = 'https://coder.vigthoria.io';
@@ -228,13 +228,17 @@ export async function login(email, password) {
228
228
  }
229
229
  const authBases = getAuthBaseCandidates(getApiUrl());
230
230
  const endpointVariants = [
231
- { path: '/auth/login', body: { email: resolvedEmail, password: resolvedPassword } },
232
- { path: '/api/auth/login', body: { email: resolvedEmail, password: resolvedPassword } },
233
- { path: '/api/login-json', body: { identifier: resolvedEmail, password: resolvedPassword } },
231
+ // `/api/login` is the public Coder credential exchange. Older routes are
232
+ // compatibility fallbacks and may only be tried when a route is absent;
233
+ // retrying a decisive auth response consumes rate-limit budget and can
234
+ // turn an authorization or server-contract failure into a false
235
+ // "invalid password" report.
234
236
  { path: '/api/login', body: { email: resolvedEmail, password: resolvedPassword } },
237
+ { path: '/api/login-json', body: { identifier: resolvedEmail, password: resolvedPassword } },
238
+ { path: '/api/auth/login', body: { email: resolvedEmail, password: resolvedPassword } },
239
+ { path: '/auth/login', body: { email: resolvedEmail, password: resolvedPassword } },
235
240
  ];
236
241
  const attempted = [];
237
- const failures = [];
238
242
  for (const base of authBases) {
239
243
  for (const variant of endpointVariants) {
240
244
  const endpoint = `${trimTrailingSlash(base)}${variant.path}`;
@@ -246,19 +250,32 @@ export async function login(email, password) {
246
250
  });
247
251
  const token = extractAuthToken(result);
248
252
  if (!token) {
249
- failures.push(`${endpoint} -> success without token`);
250
- continue;
253
+ throw new CliCommandError('The Vigthoria login service accepted the request but did not issue an access token.', {
254
+ code: 'LOGIN_TOKEN_MISSING', category: 'authentication', status: 502,
255
+ });
251
256
  }
252
257
  const normalizedBase = trimTrailingSlash(base);
253
- const v3ServiceKey = await fetchV3ServiceKey(normalizedBase, token);
258
+ try {
259
+ validateTokenStructure(token, normalizedBase);
260
+ }
261
+ catch (error) {
262
+ throw new CliCommandError(`The Vigthoria login service issued a token that the CLI cannot safely accept: ${humanMessage(error)}`, {
263
+ code: 'LOGIN_TOKEN_INVALID', category: 'authentication', status: 502, cause: error,
264
+ });
265
+ }
254
266
  const identity = extractAuthUser(result, resolvedEmail);
255
267
  const refreshToken = result.tokens?.refresh_token || undefined;
256
268
  await new AuthSessionService(new Config()).validateAndPersistToken(token, {
257
269
  apiUrl: normalizedBase,
258
270
  refreshToken,
259
271
  identity: { userId: identity?.id, email: identity?.email },
260
- v3ServiceKey: v3ServiceKey || null,
272
+ v3ServiceKey: null,
261
273
  });
274
+ // Only present the newly issued token to secondary authenticated
275
+ // endpoints after its structure and Coder acceptance are proven.
276
+ const v3ServiceKey = await fetchV3ServiceKey(normalizedBase, token);
277
+ if (v3ServiceKey)
278
+ new Config().setAuth({ token, v3ServiceKey });
262
279
  const config = {
263
280
  apiUrl: normalizedBase,
264
281
  token,
@@ -270,15 +287,41 @@ export async function login(email, password) {
270
287
  return config;
271
288
  }
272
289
  catch (error) {
290
+ if (error instanceof CliCommandError)
291
+ throw error;
273
292
  if (error instanceof HttpError && error.code === 'SUBSCRIPTION_REQUIRED') {
274
293
  throw error;
275
294
  }
276
- const message = humanMessage(error);
277
- failures.push(`${endpoint} -> ${message}`);
295
+ if (error instanceof HttpError && (error.status === 404 || error.status === 405)) {
296
+ continue;
297
+ }
298
+ if (error instanceof HttpError && error.status === 401) {
299
+ throw new CliCommandError('Invalid email or password. Please check your credentials and try again.', {
300
+ code: error.code || 'LOGIN_FAILED', category: 'authentication', status: error.status, cause: error,
301
+ });
302
+ }
303
+ if (error instanceof HttpError && error.status === 403) {
304
+ throw new CliCommandError(humanMessage(error), {
305
+ code: error.code || 'LOGIN_FORBIDDEN', category: 'authorization', status: error.status, cause: error,
306
+ });
307
+ }
308
+ if (error instanceof HttpError && error.status === 429) {
309
+ throw new CliCommandError('Too many login attempts. Wait for the authentication rate limit to reset, then try once.', {
310
+ code: 'LOGIN_RATE_LIMITED', category: 'authentication', status: error.status, cause: error,
311
+ });
312
+ }
313
+ if (error instanceof HttpError && error.status >= 500) {
314
+ throw new CliCommandError(`Vigthoria authentication is temporarily unavailable: ${humanMessage(error)}`, {
315
+ code: error.code || 'LOGIN_SERVICE_UNAVAILABLE', category: 'network', status: error.status, cause: error,
316
+ });
317
+ }
318
+ throw error;
278
319
  }
279
320
  }
280
321
  }
281
- throw new Error('Invalid email or password. Please check your credentials and try again.');
322
+ throw new CliCommandError(`No supported login route is available on the configured Vigthoria endpoint. Tried ${attempted.join(', ')}.`, {
323
+ code: 'LOGIN_ROUTE_UNAVAILABLE', category: 'configuration', status: 404,
324
+ });
282
325
  }
283
326
  catch (error) {
284
327
  const message = humanMessage(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vigthoria-cli",
3
- "version": "1.13.23",
3
+ "version": "1.13.24",
4
4
  "description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",