ctxindex 0.1.1 → 0.1.2
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/ctxindex.mjs +105 -35
- package/package.json +1 -1
package/dist/ctxindex.mjs
CHANGED
|
@@ -39006,6 +39006,40 @@ async function launchOAuthBrowser(url2) {
|
|
|
39006
39006
|
if (await processHandle.exited !== 0)
|
|
39007
39007
|
throw new Error("browser launcher failed");
|
|
39008
39008
|
}
|
|
39009
|
+
function callbackResult(value, redirectUri, state) {
|
|
39010
|
+
const pasted = value.trim();
|
|
39011
|
+
if (pasted.length === 0 || pasted.length > 16384)
|
|
39012
|
+
throw new CtxindexAuthError("missing_code", "OAuth authorization failed: missing_code");
|
|
39013
|
+
if (!/^https?:\/\//i.test(pasted)) {
|
|
39014
|
+
if (/\s/.test(pasted))
|
|
39015
|
+
throw new CtxindexAuthError("missing_code", "OAuth authorization failed: missing_code");
|
|
39016
|
+
return pasted;
|
|
39017
|
+
}
|
|
39018
|
+
let callback;
|
|
39019
|
+
try {
|
|
39020
|
+
callback = new URL(pasted);
|
|
39021
|
+
} catch {
|
|
39022
|
+
throw new CtxindexAuthError("oauth_failed", "OAuth authorization failed: invalid_callback");
|
|
39023
|
+
}
|
|
39024
|
+
const expected = new URL(redirectUri);
|
|
39025
|
+
if (callback.origin !== expected.origin || callback.pathname !== callbackPath || callback.username !== "" || callback.password !== "" || callback.hash !== "")
|
|
39026
|
+
throw new CtxindexAuthError("oauth_failed", "OAuth authorization failed: invalid_callback");
|
|
39027
|
+
if (callback.searchParams.getAll("state").length !== 1 || callback.searchParams.get("state") !== state)
|
|
39028
|
+
throw new CtxindexAuthError("state_mismatch", "OAuth authorization failed: state_mismatch");
|
|
39029
|
+
const providerError = callback.searchParams.get("error");
|
|
39030
|
+
if (providerError === "access_denied")
|
|
39031
|
+
throw new CtxindexAuthError("authorization_denied", "OAuth authorization failed: authorization_denied");
|
|
39032
|
+
if (providerError) {
|
|
39033
|
+
const safeError = /^[A-Za-z0-9._-]{1,64}$/.test(providerError) ? providerError : "unknown_error";
|
|
39034
|
+
const providerCode = callback.searchParams.get("error_description")?.match(/\b[A-Z]{2,12}\d{3,10}\b/)?.[0];
|
|
39035
|
+
const diagnostic = providerCode ? `${safeError} (${providerCode})` : safeError;
|
|
39036
|
+
throw new CtxindexAuthError("oauth_failed", `OAuth authorization failed: ${diagnostic}`);
|
|
39037
|
+
}
|
|
39038
|
+
const codes = callback.searchParams.getAll("code");
|
|
39039
|
+
if (codes.length !== 1 || !codes[0])
|
|
39040
|
+
throw new CtxindexAuthError("missing_code", "OAuth authorization failed: missing_code");
|
|
39041
|
+
return codes[0];
|
|
39042
|
+
}
|
|
39009
39043
|
async function openOAuthLoopback(input) {
|
|
39010
39044
|
const state = randomToken();
|
|
39011
39045
|
const codeVerifier = randomToken();
|
|
@@ -39025,17 +39059,20 @@ async function openOAuthLoopback(input) {
|
|
|
39025
39059
|
const authorizationUrl = authorization.toString();
|
|
39026
39060
|
let timer;
|
|
39027
39061
|
let settled = false;
|
|
39062
|
+
const manualInput = new AbortController;
|
|
39063
|
+
let finishCallback = () => {};
|
|
39028
39064
|
const callback = new Promise((resolve, reject) => {
|
|
39029
|
-
|
|
39065
|
+
finishCallback = (error51, code) => {
|
|
39030
39066
|
if (settled)
|
|
39031
39067
|
return;
|
|
39032
39068
|
settled = true;
|
|
39069
|
+
manualInput.abort();
|
|
39033
39070
|
if (error51)
|
|
39034
39071
|
reject(error51);
|
|
39035
39072
|
else
|
|
39036
39073
|
resolve(code ?? "");
|
|
39037
39074
|
};
|
|
39038
|
-
timer = setTimeout(() =>
|
|
39075
|
+
timer = setTimeout(() => finishCallback(new CtxindexAuthError("loopback_timeout", "OAuth authorization failed: loopback_timeout (callback timed out)")), input.timeoutMs ?? defaultTimeoutMs);
|
|
39039
39076
|
server.on("request", (request, response) => {
|
|
39040
39077
|
const url2 = new URL(request.url ?? "/", redirectUri);
|
|
39041
39078
|
if (url2.pathname !== callbackPath) {
|
|
@@ -39043,38 +39080,16 @@ async function openOAuthLoopback(input) {
|
|
|
39043
39080
|
response.end("not found");
|
|
39044
39081
|
return;
|
|
39045
39082
|
}
|
|
39046
|
-
|
|
39047
|
-
|
|
39048
|
-
response.
|
|
39049
|
-
|
|
39050
|
-
|
|
39051
|
-
}
|
|
39052
|
-
const providerError = url2.searchParams.get("error");
|
|
39053
|
-
if (providerError === "access_denied") {
|
|
39054
|
-
response.writeHead(400, { "content-type": "text/plain" });
|
|
39055
|
-
response.end("authorization denied");
|
|
39056
|
-
finish(new CtxindexAuthError("authorization_denied", "OAuth authorization failed: authorization_denied"));
|
|
39057
|
-
return;
|
|
39058
|
-
}
|
|
39059
|
-
if (providerError) {
|
|
39060
|
-
const safeError = /^[A-Za-z0-9._-]{1,64}$/.test(providerError) ? providerError : "unknown_error";
|
|
39061
|
-
const providerCode = url2.searchParams.get("error_description")?.match(/\b[A-Z]{2,12}\d{3,10}\b/)?.[0];
|
|
39062
|
-
const diagnostic = providerCode ? `${safeError} (${providerCode})` : safeError;
|
|
39083
|
+
try {
|
|
39084
|
+
const code = callbackResult(url2.toString(), redirectUri, state);
|
|
39085
|
+
response.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
39086
|
+
response.end("<!doctype html><title>ctxindex authorization complete</title><p>You can close this window.</p>");
|
|
39087
|
+
finishCallback(null, code);
|
|
39088
|
+
} catch (error51) {
|
|
39063
39089
|
response.writeHead(400, { "content-type": "text/plain" });
|
|
39064
|
-
response.end(
|
|
39065
|
-
|
|
39066
|
-
return;
|
|
39090
|
+
response.end("authorization failed");
|
|
39091
|
+
finishCallback(error51 instanceof CtxindexAuthError ? error51 : new CtxindexAuthError("oauth_failed", "OAuth authorization failed: invalid_callback"));
|
|
39067
39092
|
}
|
|
39068
|
-
const code = url2.searchParams.get("code");
|
|
39069
|
-
if (!code) {
|
|
39070
|
-
response.writeHead(400, { "content-type": "text/plain" });
|
|
39071
|
-
response.end("missing code");
|
|
39072
|
-
finish(new CtxindexAuthError("missing_code", "OAuth authorization failed: missing_code"));
|
|
39073
|
-
return;
|
|
39074
|
-
}
|
|
39075
|
-
response.writeHead(200, { "content-type": "text/html; charset=utf-8" });
|
|
39076
|
-
response.end("<!doctype html><title>ctxindex authorization complete</title><p>You can close this window.</p>");
|
|
39077
|
-
finish(null, code);
|
|
39078
39093
|
});
|
|
39079
39094
|
});
|
|
39080
39095
|
try {
|
|
@@ -39087,6 +39102,24 @@ async function openOAuthLoopback(input) {
|
|
|
39087
39102
|
input.emitAuthorizationUrl?.(authorizationUrl);
|
|
39088
39103
|
}
|
|
39089
39104
|
}
|
|
39105
|
+
if (input.readAuthorizationResponse) {
|
|
39106
|
+
input.readAuthorizationResponse({
|
|
39107
|
+
authorizationUrl,
|
|
39108
|
+
redirectUri,
|
|
39109
|
+
signal: manualInput.signal
|
|
39110
|
+
}).then((value) => {
|
|
39111
|
+
if (value === undefined || settled)
|
|
39112
|
+
return;
|
|
39113
|
+
try {
|
|
39114
|
+
finishCallback(null, callbackResult(value, redirectUri, state));
|
|
39115
|
+
} catch (error51) {
|
|
39116
|
+
finishCallback(error51 instanceof CtxindexAuthError ? error51 : new CtxindexAuthError("oauth_failed", "OAuth authorization failed: invalid_callback"));
|
|
39117
|
+
}
|
|
39118
|
+
}).catch((error51) => {
|
|
39119
|
+
if (!manualInput.signal.aborted)
|
|
39120
|
+
finishCallback(error51 instanceof CtxindexAuthError ? error51 : new CtxindexAuthError("oauth_failed", "OAuth authorization failed: manual_input"));
|
|
39121
|
+
});
|
|
39122
|
+
}
|
|
39090
39123
|
const code = await callback;
|
|
39091
39124
|
return { code, codeVerifier, redirectUri, authorizationUrl };
|
|
39092
39125
|
} finally {
|
|
@@ -39374,7 +39407,8 @@ async function authorizeProvider(input, deps) {
|
|
|
39374
39407
|
...Number.isFinite(timeoutSeconds) && timeoutSeconds >= 0 ? { timeoutMs: timeoutSeconds * 1000 } : {},
|
|
39375
39408
|
noBrowser: readEnvironment("CTXINDEX_NO_BROWSER") === "1",
|
|
39376
39409
|
...deps.launchBrowser ? { launchBrowser: deps.launchBrowser } : {},
|
|
39377
|
-
...deps.emitAuthorizationUrl ? { emitAuthorizationUrl: deps.emitAuthorizationUrl } : {}
|
|
39410
|
+
...deps.emitAuthorizationUrl ? { emitAuthorizationUrl: deps.emitAuthorizationUrl } : {},
|
|
39411
|
+
...deps.readAuthorizationResponse ? { readAuthorizationResponse: deps.readAuthorizationResponse } : {}
|
|
39378
39412
|
});
|
|
39379
39413
|
token = await postOAuthToken({
|
|
39380
39414
|
provider,
|
|
@@ -80861,6 +80895,41 @@ async function runWithExit(handler4) {
|
|
|
80861
80895
|
}
|
|
80862
80896
|
}
|
|
80863
80897
|
|
|
80898
|
+
// src/account/read-hidden-oauth-response.ts
|
|
80899
|
+
import { createInterface } from "readline";
|
|
80900
|
+
var prompt = "Paste the redirect URL or authorization code here: ";
|
|
80901
|
+
function readHiddenOAuthResponse(input) {
|
|
80902
|
+
const stdin = process.stdin;
|
|
80903
|
+
const stdout = process.stdout;
|
|
80904
|
+
return new Promise((resolve9) => {
|
|
80905
|
+
let finished = false;
|
|
80906
|
+
const wasRaw = stdin.isRaw;
|
|
80907
|
+
const interactive = stdin.isTTY && typeof stdin.setRawMode === "function";
|
|
80908
|
+
const lines = createInterface({ input: stdin, terminal: false });
|
|
80909
|
+
const finish = (value2) => {
|
|
80910
|
+
if (finished)
|
|
80911
|
+
return;
|
|
80912
|
+
finished = true;
|
|
80913
|
+
input.signal.removeEventListener("abort", onAbort);
|
|
80914
|
+
lines.close();
|
|
80915
|
+
if (interactive)
|
|
80916
|
+
stdin.setRawMode(Boolean(wasRaw));
|
|
80917
|
+
stdout.write(`
|
|
80918
|
+
`);
|
|
80919
|
+
resolve9(value2);
|
|
80920
|
+
};
|
|
80921
|
+
const onAbort = () => finish();
|
|
80922
|
+
input.signal.addEventListener("abort", onAbort, { once: true });
|
|
80923
|
+
if (input.signal.aborted)
|
|
80924
|
+
return finish();
|
|
80925
|
+
stdout.write(prompt);
|
|
80926
|
+
if (interactive)
|
|
80927
|
+
stdin.setRawMode(true);
|
|
80928
|
+
lines.once("line", (line) => finish(line));
|
|
80929
|
+
lines.once("close", () => finish());
|
|
80930
|
+
});
|
|
80931
|
+
}
|
|
80932
|
+
|
|
80864
80933
|
// src/account/handle-account-command.ts
|
|
80865
80934
|
var accountCommandRuntime = {
|
|
80866
80935
|
assertInitialized,
|
|
@@ -80946,7 +81015,8 @@ async function handleAccountCommand(parsed, runtime = accountCommandRuntime) {
|
|
|
80946
81015
|
}
|
|
80947
81016
|
return app;
|
|
80948
81017
|
},
|
|
80949
|
-
emitAuthorizationUrl: (url2) => console.log(`Open this URL: ${url2}`)
|
|
81018
|
+
emitAuthorizationUrl: (url2) => console.log(`Open this URL: ${url2}`),
|
|
81019
|
+
readAuthorizationResponse: readHiddenOAuthResponse
|
|
80950
81020
|
});
|
|
80951
81021
|
console.log(formatAccountAdded(result));
|
|
80952
81022
|
}
|
|
@@ -85459,7 +85529,7 @@ var daemonCommand = defineCtxCommand({
|
|
|
85459
85529
|
|
|
85460
85530
|
// src/main.ts
|
|
85461
85531
|
var LOG_LEVELS = ["trace", "debug", "info", "warn", "error", "fatal"];
|
|
85462
|
-
var cliVersion = "0.1.
|
|
85532
|
+
var cliVersion = "0.1.2";
|
|
85463
85533
|
function captureProcessExit() {
|
|
85464
85534
|
const originalExit = process.exit;
|
|
85465
85535
|
process.exit = (code) => {
|