chapa-cli 0.2.2 → 0.2.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/index.js +75 -5
- 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,52 @@ var MAX_POLL_ATTEMPTS = 150;
|
|
|
319
323
|
function sleep(ms) {
|
|
320
324
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
321
325
|
}
|
|
322
|
-
|
|
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
|
+
function getRootErrorMessage(err) {
|
|
347
|
+
let current = err;
|
|
348
|
+
let message = "";
|
|
349
|
+
while (current instanceof Error) {
|
|
350
|
+
message = current.message;
|
|
351
|
+
current = current.cause;
|
|
352
|
+
}
|
|
353
|
+
return message;
|
|
354
|
+
}
|
|
355
|
+
function getFullErrorChain(err) {
|
|
356
|
+
const messages = [];
|
|
357
|
+
let current = err;
|
|
358
|
+
while (current instanceof Error) {
|
|
359
|
+
messages.push(current.message);
|
|
360
|
+
current = current.cause;
|
|
361
|
+
}
|
|
362
|
+
return messages.join(" | ");
|
|
363
|
+
}
|
|
364
|
+
async function login(serverUrl, opts = {}) {
|
|
365
|
+
const { verbose = false, insecure = false } = opts;
|
|
366
|
+
const originalTlsSetting = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
|
|
367
|
+
if (insecure) {
|
|
368
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
369
|
+
console.warn("\n\u26A0 TLS certificate verification disabled (--insecure).");
|
|
370
|
+
console.warn(" Use only on corporate networks with TLS interception.\n");
|
|
371
|
+
}
|
|
323
372
|
const baseUrl = serverUrl.replace(/\/+$/, "");
|
|
324
373
|
const sessionId = randomUUID();
|
|
325
374
|
const authorizeUrl = `${baseUrl}/cli/authorize?session=${sessionId}`;
|
|
@@ -342,7 +391,9 @@ async function login(serverUrl) {
|
|
|
342
391
|
`${baseUrl}/api/cli/auth/poll?session=${sessionId}`
|
|
343
392
|
);
|
|
344
393
|
if (!res.ok) {
|
|
345
|
-
if (
|
|
394
|
+
if (verbose) {
|
|
395
|
+
console.error(`[poll ${i + 1}] HTTP ${res.status}`);
|
|
396
|
+
} else if (!serverErrorLogged) {
|
|
346
397
|
console.error(`
|
|
347
398
|
Server returned ${res.status}. Retrying...`);
|
|
348
399
|
serverErrorLogged = true;
|
|
@@ -350,7 +401,21 @@ Server returned ${res.status}. Retrying...`);
|
|
|
350
401
|
continue;
|
|
351
402
|
}
|
|
352
403
|
data = await res.json();
|
|
353
|
-
|
|
404
|
+
if (verbose) {
|
|
405
|
+
console.error(`[poll ${i + 1}] ${data?.status ?? "no status"}`);
|
|
406
|
+
}
|
|
407
|
+
} catch (err) {
|
|
408
|
+
const rootMsg = getRootErrorMessage(err);
|
|
409
|
+
const fullChain = getFullErrorChain(err);
|
|
410
|
+
if (verbose) {
|
|
411
|
+
console.error(`[poll ${i + 1}] network error: ${rootMsg}`);
|
|
412
|
+
}
|
|
413
|
+
if (!insecure && isTlsError(fullChain)) {
|
|
414
|
+
console.error(`
|
|
415
|
+
TLS certificate error: ${rootMsg}`);
|
|
416
|
+
console.error("This looks like a corporate network with TLS interception.");
|
|
417
|
+
console.error(" try: chapa login --insecure\n");
|
|
418
|
+
}
|
|
354
419
|
continue;
|
|
355
420
|
}
|
|
356
421
|
if (data?.status === "approved" && data.token && data.handle) {
|
|
@@ -362,19 +427,22 @@ Server returned ${res.status}. Retrying...`);
|
|
|
362
427
|
console.log(`
|
|
363
428
|
Logged in as ${data.handle}!`);
|
|
364
429
|
console.log("Credentials saved to ~/.chapa/credentials.json");
|
|
430
|
+
restoreTls(insecure, originalTlsSetting);
|
|
365
431
|
return;
|
|
366
432
|
}
|
|
367
433
|
if (data?.status === "expired") {
|
|
434
|
+
restoreTls(insecure, originalTlsSetting);
|
|
368
435
|
console.error("\nSession expired. Please try again.");
|
|
369
436
|
process.exit(1);
|
|
370
437
|
}
|
|
371
438
|
}
|
|
439
|
+
restoreTls(insecure, originalTlsSetting);
|
|
372
440
|
console.error("\nTimed out waiting for approval. Please try again.");
|
|
373
441
|
process.exit(1);
|
|
374
442
|
}
|
|
375
443
|
|
|
376
444
|
// src/index.ts
|
|
377
|
-
var VERSION = true ? "0.2.
|
|
445
|
+
var VERSION = true ? "0.2.5" : "0.0.0-dev";
|
|
378
446
|
var HELP_TEXT = `chapa-cli v${VERSION}
|
|
379
447
|
|
|
380
448
|
Merge GitHub EMU (Enterprise Managed User) contributions into your Chapa badge.
|
|
@@ -390,6 +458,8 @@ Options:
|
|
|
390
458
|
--handle <handle> Override personal handle (auto-detected from login)
|
|
391
459
|
--token <token> Override auth token (auto-detected from login)
|
|
392
460
|
--server <url> Chapa server URL (default: https://chapa.thecreativetoken.com)
|
|
461
|
+
--verbose Show detailed polling logs during login
|
|
462
|
+
--insecure Skip TLS certificate verification (corporate networks)
|
|
393
463
|
--version, -v Show version number
|
|
394
464
|
--help, -h Show this help message
|
|
395
465
|
`;
|
|
@@ -404,7 +474,7 @@ async function main() {
|
|
|
404
474
|
process.exit(0);
|
|
405
475
|
}
|
|
406
476
|
if (args.command === "login") {
|
|
407
|
-
await login(args.server);
|
|
477
|
+
await login(args.server, { verbose: args.verbose, insecure: args.insecure });
|
|
408
478
|
return;
|
|
409
479
|
}
|
|
410
480
|
if (args.command === "logout") {
|