chapa-cli 0.2.1 → 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 +67 -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}`;
@@ -330,16 +361,42 @@ async function login(serverUrl) {
330
361
  console.log("Tip: If your default browser has your work (EMU) account,");
331
362
  console.log(" use a different browser or an incognito/private window.\n");
332
363
  console.log("Waiting for approval...");
364
+ let serverErrorLogged = false;
333
365
  for (let i = 0; i < MAX_POLL_ATTEMPTS; i++) {
334
366
  await sleep(POLL_INTERVAL_MS);
367
+ if (i > 0 && i % 5 === 0) {
368
+ process.stdout.write(".");
369
+ }
335
370
  let data = null;
336
371
  try {
337
372
  const res = await fetch(
338
373
  `${baseUrl}/api/cli/auth/poll?session=${sessionId}`
339
374
  );
340
- if (!res.ok) continue;
375
+ if (!res.ok) {
376
+ if (verbose) {
377
+ console.error(`[poll ${i + 1}] HTTP ${res.status}`);
378
+ } else if (!serverErrorLogged) {
379
+ console.error(`
380
+ Server returned ${res.status}. Retrying...`);
381
+ serverErrorLogged = true;
382
+ }
383
+ continue;
384
+ }
341
385
  data = await res.json();
342
- } 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
+ }
343
400
  continue;
344
401
  }
345
402
  if (data?.status === "approved" && data.token && data.handle) {
@@ -351,19 +408,22 @@ async function login(serverUrl) {
351
408
  console.log(`
352
409
  Logged in as ${data.handle}!`);
353
410
  console.log("Credentials saved to ~/.chapa/credentials.json");
411
+ restoreTls(insecure, originalTlsSetting);
354
412
  return;
355
413
  }
356
414
  if (data?.status === "expired") {
415
+ restoreTls(insecure, originalTlsSetting);
357
416
  console.error("\nSession expired. Please try again.");
358
417
  process.exit(1);
359
418
  }
360
419
  }
420
+ restoreTls(insecure, originalTlsSetting);
361
421
  console.error("\nTimed out waiting for approval. Please try again.");
362
422
  process.exit(1);
363
423
  }
364
424
 
365
425
  // src/index.ts
366
- var VERSION = true ? "0.2.1" : "0.0.0-dev";
426
+ var VERSION = true ? "0.2.4" : "0.0.0-dev";
367
427
  var HELP_TEXT = `chapa-cli v${VERSION}
368
428
 
369
429
  Merge GitHub EMU (Enterprise Managed User) contributions into your Chapa badge.
@@ -379,6 +439,8 @@ Options:
379
439
  --handle <handle> Override personal handle (auto-detected from login)
380
440
  --token <token> Override auth token (auto-detected from login)
381
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)
382
444
  --version, -v Show version number
383
445
  --help, -h Show this help message
384
446
  `;
@@ -393,7 +455,7 @@ async function main() {
393
455
  process.exit(0);
394
456
  }
395
457
  if (args.command === "login") {
396
- await login(args.server);
458
+ await login(args.server, { verbose: args.verbose, insecure: args.insecure });
397
459
  return;
398
460
  }
399
461
  if (args.command === "logout") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chapa-cli",
3
- "version": "0.2.1",
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": {