chapa-cli 0.2.2 → 0.2.4

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.
Files changed (2) hide show
  1. package/dist/index.js +56 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -16,6 +16,8 @@ function parseArgs(argv) {
16
16
  "emu-token": { type: "string" },
17
17
  token: { type: "string" },
18
18
  server: { type: "string", default: DEFAULT_SERVER },
19
+ verbose: { type: "boolean", default: false },
20
+ insecure: { type: "boolean", default: false },
19
21
  version: { type: "boolean", short: "v", default: false },
20
22
  help: { type: "boolean", short: "h", default: false }
21
23
  },
@@ -28,6 +30,8 @@ function parseArgs(argv) {
28
30
  emuToken: values["emu-token"],
29
31
  token: values.token,
30
32
  server: values.server ?? DEFAULT_SERVER,
33
+ verbose: values.verbose ?? false,
34
+ insecure: values.insecure ?? false,
31
35
  version: values.version ?? false,
32
36
  help: values.help ?? false
33
37
  };
@@ -319,7 +323,34 @@ var MAX_POLL_ATTEMPTS = 150;
319
323
  function sleep(ms) {
320
324
  return new Promise((resolve) => setTimeout(resolve, ms));
321
325
  }
322
- async function login(serverUrl) {
326
+ function restoreTls(insecure, original) {
327
+ if (!insecure) return;
328
+ if (original === void 0) {
329
+ delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
330
+ } else {
331
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = original;
332
+ }
333
+ }
334
+ var TLS_ERROR_PATTERNS = [
335
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
336
+ "CERT_HAS_EXPIRED",
337
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
338
+ "SELF_SIGNED_CERT_IN_CHAIN",
339
+ "ERR_TLS_CERT_ALTNAME_INVALID",
340
+ "CERTIFICATE_VERIFY_FAILED",
341
+ "SSL"
342
+ ];
343
+ function isTlsError(message) {
344
+ return TLS_ERROR_PATTERNS.some((p) => message.includes(p));
345
+ }
346
+ async function login(serverUrl, opts = {}) {
347
+ const { verbose = false, insecure = false } = opts;
348
+ const originalTlsSetting = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
349
+ if (insecure) {
350
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
351
+ console.warn("\n\u26A0 TLS certificate verification disabled (--insecure).");
352
+ console.warn(" Use only on corporate networks with TLS interception.\n");
353
+ }
323
354
  const baseUrl = serverUrl.replace(/\/+$/, "");
324
355
  const sessionId = randomUUID();
325
356
  const authorizeUrl = `${baseUrl}/cli/authorize?session=${sessionId}`;
@@ -342,7 +373,9 @@ async function login(serverUrl) {
342
373
  `${baseUrl}/api/cli/auth/poll?session=${sessionId}`
343
374
  );
344
375
  if (!res.ok) {
345
- if (!serverErrorLogged) {
376
+ if (verbose) {
377
+ console.error(`[poll ${i + 1}] HTTP ${res.status}`);
378
+ } else if (!serverErrorLogged) {
346
379
  console.error(`
347
380
  Server returned ${res.status}. Retrying...`);
348
381
  serverErrorLogged = true;
@@ -350,7 +383,20 @@ Server returned ${res.status}. Retrying...`);
350
383
  continue;
351
384
  }
352
385
  data = await res.json();
353
- } catch {
386
+ if (verbose) {
387
+ console.error(`[poll ${i + 1}] ${data?.status ?? "no status"}`);
388
+ }
389
+ } catch (err) {
390
+ const errMsg = err.message;
391
+ if (verbose) {
392
+ console.error(`[poll ${i + 1}] network error: ${errMsg}`);
393
+ }
394
+ if (!insecure && isTlsError(errMsg)) {
395
+ console.error(`
396
+ TLS certificate error: ${errMsg}`);
397
+ console.error("This looks like a corporate network with TLS interception.");
398
+ console.error(" try: chapa login --insecure\n");
399
+ }
354
400
  continue;
355
401
  }
356
402
  if (data?.status === "approved" && data.token && data.handle) {
@@ -362,19 +408,22 @@ Server returned ${res.status}. Retrying...`);
362
408
  console.log(`
363
409
  Logged in as ${data.handle}!`);
364
410
  console.log("Credentials saved to ~/.chapa/credentials.json");
411
+ restoreTls(insecure, originalTlsSetting);
365
412
  return;
366
413
  }
367
414
  if (data?.status === "expired") {
415
+ restoreTls(insecure, originalTlsSetting);
368
416
  console.error("\nSession expired. Please try again.");
369
417
  process.exit(1);
370
418
  }
371
419
  }
420
+ restoreTls(insecure, originalTlsSetting);
372
421
  console.error("\nTimed out waiting for approval. Please try again.");
373
422
  process.exit(1);
374
423
  }
375
424
 
376
425
  // src/index.ts
377
- var VERSION = true ? "0.2.2" : "0.0.0-dev";
426
+ var VERSION = true ? "0.2.4" : "0.0.0-dev";
378
427
  var HELP_TEXT = `chapa-cli v${VERSION}
379
428
 
380
429
  Merge GitHub EMU (Enterprise Managed User) contributions into your Chapa badge.
@@ -390,6 +439,8 @@ Options:
390
439
  --handle <handle> Override personal handle (auto-detected from login)
391
440
  --token <token> Override auth token (auto-detected from login)
392
441
  --server <url> Chapa server URL (default: https://chapa.thecreativetoken.com)
442
+ --verbose Show detailed polling logs during login
443
+ --insecure Skip TLS certificate verification (corporate networks)
393
444
  --version, -v Show version number
394
445
  --help, -h Show this help message
395
446
  `;
@@ -404,7 +455,7 @@ async function main() {
404
455
  process.exit(0);
405
456
  }
406
457
  if (args.command === "login") {
407
- await login(args.server);
458
+ await login(args.server, { verbose: args.verbose, insecure: args.insecure });
408
459
  return;
409
460
  }
410
461
  if (args.command === "logout") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chapa-cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Merge GitHub EMU contributions into your Chapa developer impact badge",
5
5
  "type": "module",
6
6
  "bin": {