@agentdocumentformat/cli 0.7.7 → 0.8.0
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/README.md +1 -1
- package/dist/adf.mjs +59 -8
- package/dist/chunks/{APEv2Parser-2CNNHMXV.mjs → APEv2Parser-WIXRJLHB.mjs} +2 -2
- package/dist/chunks/{AiffParser-7BR4RL6G.mjs → AiffParser-ZC4QFOVJ.mjs} +5 -5
- package/dist/chunks/{App-5KXVPMBV.mjs → App-A5GUFCFJ.mjs} +279 -291
- package/dist/chunks/{DsdiffParser-CMD4AX7A.mjs → DsdiffParser-UAPAJHFX.mjs} +5 -5
- package/dist/chunks/{DsfParser-UOGZDS2M.mjs → DsfParser-NNYZK2QX.mjs} +6 -6
- package/dist/chunks/{FlacParser-HB3T3CD4.mjs → FlacParser-MW2W4LO3.mjs} +6 -6
- package/dist/chunks/{MP4Parser-66HBRUSX.mjs → MP4Parser-Z57SYOOQ.mjs} +4 -4
- package/dist/chunks/{MpegParser-YW6LIUEW.mjs → MpegParser-XIIPAZVM.mjs} +7 -7
- package/dist/chunks/{MusepackParser-PAUSXP7D.mjs → MusepackParser-QWNDEYHJ.mjs} +6 -6
- package/dist/chunks/{OggParser-NUBV3GWC.mjs → OggParser-WRX53F77.mjs} +9 -9
- package/dist/chunks/{WavPackParser-WQAGT7TC.mjs → WavPackParser-MJ7WCSJ5.mjs} +2 -2
- package/dist/chunks/{WaveParser-EWLQVDX4.mjs → WaveParser-RAVLHZ5S.mjs} +7 -7
- package/dist/chunks/{adf-schema-US4NFHMR.mjs → adf-schema-YJSGLMA4.mjs} +2 -2
- package/dist/chunks/auth-manager-AJ32FZWS.mjs +19 -0
- package/dist/chunks/auth-manager-C5OBEQK2.mjs +18 -0
- package/dist/chunks/auth-manager-TBNKCJ45.mjs +17 -0
- package/dist/chunks/{chatgpt-subscription-E4MXTIAT.mjs → chatgpt-subscription-MMGNW5KJ.mjs} +5 -2
- package/dist/chunks/chunk-3UGZFWIF.mjs +26 -0
- package/dist/chunks/{chunk-5PO5PKRV.mjs → chunk-4OGZFUKA.mjs} +126 -67
- package/dist/chunks/{chunk-VN7UH7I5.mjs → chunk-6XQZGYMK.mjs} +246 -67
- package/dist/chunks/{chunk-XNPZBLYL.mjs → chunk-75DC5EWN.mjs} +13 -2
- package/dist/chunks/chunk-AZYOXXVL.mjs +865 -0
- package/dist/chunks/{chunk-6VQEXLE2.mjs → chunk-BHY7QDCM.mjs} +41 -3
- package/dist/chunks/chunk-C2S64Y6F.mjs +203 -0
- package/dist/chunks/chunk-C4GA5SI4.mjs +12799 -0
- package/dist/chunks/chunk-DDTTSKGG.mjs +2443 -0
- package/dist/chunks/{chunk-VAUOM3IN.mjs → chunk-DLWCKKIO.mjs} +1 -1
- package/dist/chunks/{chunk-HPVFJYXR.mjs → chunk-ESP3VNMX.mjs} +1 -1
- package/dist/chunks/{chunk-QPLEAE6V.mjs → chunk-G6NBFYG5.mjs} +152 -824
- package/dist/chunks/{chunk-KXEF4F4E.mjs → chunk-GAZO6UMI.mjs} +1 -1
- package/dist/chunks/{chunk-XYTWGHFS.mjs → chunk-H3XLRWVE.mjs} +1 -1
- package/dist/chunks/{chunk-7T2YMTWL.mjs → chunk-H4C65MTP.mjs} +4 -4
- package/dist/chunks/chunk-HBOFZRUS.mjs +738 -0
- package/dist/chunks/chunk-JVPZIMXW.mjs +976 -0
- package/dist/chunks/{chunk-XYV3VCIX.mjs → chunk-JZFONJSL.mjs} +79 -20
- package/dist/chunks/chunk-KDDVQKCG.mjs +65 -0
- package/dist/chunks/chunk-KRPKWOMB.mjs +290 -0
- package/dist/chunks/{chunk-4N4ASPH6.mjs → chunk-LCMANRYY.mjs} +4 -254
- package/dist/chunks/{chunk-TPRZQ7Z4.mjs → chunk-LGL6ML37.mjs} +4 -4
- package/dist/chunks/chunk-LKFHERRV.mjs +145 -0
- package/dist/chunks/chunk-LTX74NU6.mjs +29 -0
- package/dist/chunks/chunk-M2F7C2UJ.mjs +425 -0
- package/dist/chunks/{chunk-62NE4LG4.mjs → chunk-MQAMI5BF.mjs} +5 -5
- package/dist/chunks/chunk-MZRXFWPQ.mjs +278 -0
- package/dist/chunks/{chunk-PRMGZZM5.mjs → chunk-NZLEPJ5M.mjs} +2 -0
- package/dist/chunks/{chunk-CD3ATSXE.mjs → chunk-NZO5O4VN.mjs} +1 -1
- package/dist/chunks/{chunk-I3UYSITV.mjs → chunk-O7XKQ6CH.mjs} +1 -1
- package/dist/chunks/chunk-P3RG5LQA.mjs +244 -0
- package/dist/chunks/chunk-PAK5JCO2.mjs +48 -0
- package/dist/chunks/chunk-PC63YFB7.mjs +34 -0
- package/dist/chunks/{daemon-control-HKFVSQTQ.mjs → chunk-PRPTKMQW.mjs} +67 -26
- package/dist/chunks/{chunk-LFMB4PAA.mjs → chunk-TKXIH27X.mjs} +974 -113
- package/dist/chunks/{chunk-5W7KES6P.mjs → chunk-UZPDETEU.mjs} +1 -1
- package/dist/chunks/chunk-V2T6NZX2.mjs +517 -0
- package/dist/chunks/chunk-V3MM6PCH.mjs +366 -0
- package/dist/chunks/chunk-WJGPNHGX.mjs +67 -0
- package/dist/chunks/chunk-WVTPPOKK.mjs +290 -0
- package/dist/chunks/{chunk-J74STFKE.mjs → chunk-WX6QCUWI.mjs} +272 -51
- package/dist/chunks/{chunk-Y5ZLKFLE.mjs → chunk-XNNJQCZP.mjs} +196 -165
- package/dist/chunks/{chunk-HDBPBORT.mjs → chunk-XT2BJUFC.mjs} +15 -6
- package/dist/chunks/chunk-YRMKSHW3.mjs +9076 -0
- package/dist/chunks/{chunk-BNXUAOO4.mjs → chunk-ZGXUOAWZ.mjs} +3186 -959
- package/dist/chunks/chunk-ZPB3HYM7.mjs +45 -0
- package/dist/chunks/claude-subscription-33BMZB6I.mjs +29 -0
- package/dist/chunks/{cli-AFHQ2XTN.mjs → cli-I47IFDHJ.mjs} +797 -56
- package/dist/chunks/{commands-XNJMCD5L.mjs → commands-E4EQUHE5.mjs} +5 -2
- package/dist/chunks/{daemon-CHZHTLGR.mjs → daemon-FQ5BV3AP.mjs} +84550 -70518
- package/dist/chunks/daemon-control-L3CLG63P.mjs +59 -0
- package/dist/chunks/{daemon-token-WRSULP7G.mjs → daemon-token-L5QKTHU5.mjs} +3 -1
- package/dist/chunks/{discord-DSP4HUWI.mjs → discord-IR62565M.mjs} +3 -52
- package/dist/chunks/{email-BRG7KUO2.mjs → email-KHHTJBDW.mjs} +4 -2
- package/dist/chunks/{environment-NX277MQG.mjs → environment-R47X44GM.mjs} +1 -1
- package/dist/chunks/{grok-subscription-4PYX7TBF.mjs → grok-subscription-E74FS5EG.mjs} +5 -2
- package/dist/chunks/{lib-N7FCZWKH.mjs → lib-L27L5PXM.mjs} +22 -22
- package/dist/chunks/{open-VAU7PXT6.mjs → open-TLGS2Z3Q.mjs} +4 -4
- package/dist/chunks/{parser-JVY2PWSM.mjs → parser-7GARNT5L.mjs} +1 -1
- package/dist/chunks/{pipeline-executor-U6IMCCP3.mjs → pipeline-executor-FD4FBWQA.mjs} +8 -5
- package/dist/chunks/prompt-RRHZX4YT.mjs +13 -0
- package/dist/chunks/remote-access-cli-XXAPQWH6.mjs +268 -0
- package/dist/chunks/remote-hello-UFWUBDQI.mjs +37 -0
- package/dist/chunks/sdk-5FD2ZP7N.mjs +28422 -0
- package/dist/chunks/{slack-OCNNF4DX.mjs → slack-IYC5RAB5.mjs} +3 -4
- package/dist/chunks/{store-HUVDJPYN.mjs → store-ZRN2WCFB.mjs} +6 -3
- package/dist/chunks/tailscale-WLJATFMB.mjs +25 -0
- package/dist/chunks/{theme-SFE3JMA2.mjs → theme-HLBDTF6F.mjs} +1 -1
- package/dist/chunks/{themes-YLXLOIJF.mjs → themes-BQ72P446.mjs} +2 -2
- package/dist/chunks/{token-6G3HCMNX.mjs → token-6D22WECM.mjs} +20 -16
- package/dist/chunks/{token-util-UXYSDQIW.mjs → token-util-YF3ZWBZ4.mjs} +1 -2
- package/dist/chunks/{tui-4ZWZKD4C.mjs → tui-SPSPDADM.mjs} +17 -14
- package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
- package/dist/chunks/{whatsapp-AVKT3CTJ.mjs → whatsapp-YJFFVN4Q.mjs} +8 -8
- package/package.json +1 -1
- package/dist/chunks/chunk-GKKCMXIZ.mjs +0 -94
- package/dist/chunks/chunk-IHDDCZBS.mjs +0 -112
- package/dist/chunks/chunk-KWFOS5WC.mjs +0 -41
- package/dist/chunks/chunk-UEZR2CNS.mjs +0 -65
- package/dist/chunks/chunk-VMHTYDH4.mjs +0 -172
- package/dist/chunks/chunk-ZROSGV65.mjs +0 -3112
- package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
- package/dist/chunks/{telegram-YI2OHNTD.mjs → telegram-JYY2VDTI.mjs} +4 -4
|
@@ -17,19 +17,23 @@ __export(auth_flow_exports, {
|
|
|
17
17
|
AUTH_POLL_INTERVAL_MS: () => AUTH_POLL_INTERVAL_MS,
|
|
18
18
|
AUTH_PROVIDERS: () => AUTH_PROVIDERS,
|
|
19
19
|
AUTH_PROVIDER_LABELS: () => AUTH_PROVIDER_LABELS,
|
|
20
|
+
CLAUDE_AUTH_TIMEOUT_MS: () => CLAUDE_AUTH_TIMEOUT_MS,
|
|
20
21
|
RELAY_CALLBACK_TIMEOUT_MS: () => RELAY_CALLBACK_TIMEOUT_MS,
|
|
21
22
|
browserLaunchCommand: () => browserLaunchCommand,
|
|
22
23
|
daemonIsLocal: () => daemonIsLocal,
|
|
23
24
|
loginChatGpt: () => loginChatGpt,
|
|
25
|
+
loginClaude: () => loginClaude,
|
|
24
26
|
loginGrok: () => loginGrok,
|
|
25
27
|
normalizeAuthProvider: () => normalizeAuthProvider,
|
|
26
28
|
openBrowser: () => openBrowser,
|
|
29
|
+
submitClaudeCode: () => submitClaudeCode,
|
|
27
30
|
waitForAuth: () => waitForAuth
|
|
28
31
|
});
|
|
29
32
|
import { spawn as nodeSpawn } from "child_process";
|
|
30
|
-
var AUTH_PROVIDERS = ["chatgpt", "grok"], AUTH_PROVIDER_LABELS = {
|
|
33
|
+
var AUTH_PROVIDERS = ["chatgpt", "grok", "claude"], AUTH_PROVIDER_LABELS = {
|
|
31
34
|
chatgpt: "ChatGPT",
|
|
32
|
-
grok: "Grok"
|
|
35
|
+
grok: "Grok",
|
|
36
|
+
claude: "Claude"
|
|
33
37
|
}, RELAY_CALLBACK_TIMEOUT_MS = 300 * 1e3, AUTH_POLL_INTERVAL_MS = 2e3, LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
34
38
|
function normalizeAuthProvider(value) {
|
|
35
39
|
switch (value?.toLowerCase()) {
|
|
@@ -40,6 +44,9 @@ function normalizeAuthProvider(value) {
|
|
|
40
44
|
case "grok":
|
|
41
45
|
case "xai":
|
|
42
46
|
return "grok";
|
|
47
|
+
case "claude":
|
|
48
|
+
case "claude-code":
|
|
49
|
+
return "claude";
|
|
43
50
|
default:
|
|
44
51
|
return null;
|
|
45
52
|
}
|
|
@@ -63,7 +70,7 @@ function openBrowser(url, deps = {}) {
|
|
|
63
70
|
} catch {
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
|
-
var CANCELLED = { ok: !1, error: "Sign-in cancelled", cancelled: !0 };
|
|
73
|
+
var CLAUDE_AUTH_TIMEOUT_MS = 660 * 1e3, CANCELLED = { ok: !1, error: "Sign-in cancelled", cancelled: !0 };
|
|
67
74
|
function isRecord(value) {
|
|
68
75
|
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
69
76
|
}
|
|
@@ -107,6 +114,35 @@ async function loginGrok(deps, opts) {
|
|
|
107
114
|
let userCode = typeof data.userCode == "string" ? data.userCode : "", verificationUri = typeof data.verificationUriComplete == "string" && data.verificationUriComplete ? data.verificationUriComplete : typeof data.verificationUri == "string" ? data.verificationUri : "", expiresInSec = typeof data.expiresIn == "number" && data.expiresIn > 0 ? data.expiresIn : 900;
|
|
108
115
|
return opts.onStart({ userCode, verificationUri, expiresInSec, raw: data }), deps.signal?.aborted ? CANCELLED : (verificationUri && (deps.openBrowser ?? openBrowser)(verificationUri), waitForAuth(deps, "grok", expiresInSec * 1e3));
|
|
109
116
|
}
|
|
117
|
+
async function loginClaude(deps, opts) {
|
|
118
|
+
let before = await deps.request("GET", "/auth/claude/status");
|
|
119
|
+
if (isRecord(before) && before.installed === !1) {
|
|
120
|
+
let installUrl = typeof before.installUrl == "string" ? before.installUrl : "";
|
|
121
|
+
return { ok: !1, error: `Claude Code is not installed on the daemon host.${installUrl ? ` Install it from ${installUrl}, then sign in again.` : ""}`, notInstalled: !0, installUrl };
|
|
122
|
+
}
|
|
123
|
+
let data = await deps.request("POST", "/auth/claude/start"), url = isRecord(data) && typeof data.url == "string" ? data.url : "";
|
|
124
|
+
if (opts.onStart({ url, raw: data }), opts.wait === !1 && !deps.signal?.aborted) return { ok: !1, error: "Sign-in started; not waiting for it", detached: !0 };
|
|
125
|
+
let outcome = deps.signal?.aborted ? CANCELLED : await waitForClaude(deps);
|
|
126
|
+
return !outcome.ok && (outcome.cancelled || outcome.timedOut) && await deps.request("POST", "/auth/claude/cancel").catch(() => {
|
|
127
|
+
}), outcome;
|
|
128
|
+
}
|
|
129
|
+
async function submitClaudeCode(deps, code) {
|
|
130
|
+
await deps.request("POST", "/auth/claude/code", { code: code.trim() });
|
|
131
|
+
}
|
|
132
|
+
async function waitForClaude(deps) {
|
|
133
|
+
let sleep = deps.sleep ?? ((ms) => abortableSleep(ms, deps.signal)), deadline = Date.now() + CLAUDE_AUTH_TIMEOUT_MS;
|
|
134
|
+
for (; Date.now() < deadline; ) {
|
|
135
|
+
if (await sleep(AUTH_POLL_INTERVAL_MS), deps.signal?.aborted) return CANCELLED;
|
|
136
|
+
let status = await deps.request("GET", "/auth/claude/status");
|
|
137
|
+
if (deps.signal?.aborted) return CANCELLED;
|
|
138
|
+
if (isRecord(status) && status.flowPending !== !0) {
|
|
139
|
+
if (typeof status.flowError == "string" && status.flowError) return { ok: !1, error: status.flowError };
|
|
140
|
+
if (status.authenticated === !0) return { ok: !0, email: typeof status.email == "string" ? status.email : void 0, raw: status };
|
|
141
|
+
if (status.installed === !1) return { ok: !1, error: "Claude Code is not installed on the daemon host." };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return { ok: !1, error: "Timed out waiting for Claude sign-in", timedOut: !0 };
|
|
145
|
+
}
|
|
110
146
|
async function waitForAuth(deps, provider, timeoutMs) {
|
|
111
147
|
let sleep = deps.sleep ?? ((ms) => abortableSleep(ms, deps.signal)), deadline = Date.now() + timeoutMs;
|
|
112
148
|
for (; Date.now() < deadline; ) {
|
|
@@ -140,5 +176,7 @@ export {
|
|
|
140
176
|
openBrowser,
|
|
141
177
|
loginChatGpt,
|
|
142
178
|
loginGrok,
|
|
179
|
+
loginClaude,
|
|
180
|
+
submitClaudeCode,
|
|
143
181
|
auth_flow_exports
|
|
144
182
|
};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { createRequire as __adfCreateRequire } from 'node:module';
|
|
2
|
+
import { fileURLToPath as __adfFileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname as __adfDirname } from 'node:path';
|
|
4
|
+
const require = __adfCreateRequire(import.meta.url);
|
|
5
|
+
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = __adfDirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
getUserDataPath
|
|
9
|
+
} from "./chunk-PAK5JCO2.mjs";
|
|
10
|
+
import {
|
|
11
|
+
protectSecretFile
|
|
12
|
+
} from "./chunk-LTX74NU6.mjs";
|
|
13
|
+
import {
|
|
14
|
+
__require
|
|
15
|
+
} from "./chunk-M2RX3S2T.mjs";
|
|
16
|
+
|
|
17
|
+
// src/main/providers/subscription-token-store.ts
|
|
18
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync } from "fs";
|
|
19
|
+
import { join as join2 } from "path";
|
|
20
|
+
|
|
21
|
+
// src/main/utils/credential-cipher.ts
|
|
22
|
+
import { randomBytes, createCipheriv, createDecipheriv } from "crypto";
|
|
23
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
24
|
+
import { join } from "path";
|
|
25
|
+
var AES_GCM_PREFIX = "aesgcm:", SAFE_STORAGE_PREFIX = "safe:", KEY_FILE_NAME = "credential.key", KEY_BYTES = 32, IV_BYTES = 12, TAG_BYTES = 16, cachedKey = null, cachedKeyPath = null;
|
|
26
|
+
function getSafeStorage() {
|
|
27
|
+
try {
|
|
28
|
+
return __require("electron").safeStorage ?? null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function credentialKeyPath() {
|
|
34
|
+
let dir = getUserDataPath();
|
|
35
|
+
return existsSync(dir) || mkdirSync(dir, { recursive: !0 }), join(dir, KEY_FILE_NAME);
|
|
36
|
+
}
|
|
37
|
+
function readKeyFile(path) {
|
|
38
|
+
try {
|
|
39
|
+
let key = Buffer.from(readFileSync(path, "utf-8").trim(), "base64");
|
|
40
|
+
return key.length === KEY_BYTES ? key : null;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function getCredentialKey() {
|
|
46
|
+
let path = credentialKeyPath();
|
|
47
|
+
if (cachedKey && cachedKeyPath === path) return cachedKey;
|
|
48
|
+
let key = existsSync(path) ? readKeyFile(path) : null;
|
|
49
|
+
if (key && protectSecretFile(path), !key && existsSync(path) && console.warn(`[Credentials] Key file at ${path} is unreadable \u2014 regenerating. Stored credentials will need re-authentication.`), !key) {
|
|
50
|
+
let generated = randomBytes(KEY_BYTES);
|
|
51
|
+
try {
|
|
52
|
+
writeFileSync(path, generated.toString("base64"), { mode: 384, flag: "wx" }), protectSecretFile(path), key = generated;
|
|
53
|
+
} catch (err) {
|
|
54
|
+
if (err.code === "EEXIST")
|
|
55
|
+
key = readKeyFile(path), key || (writeFileSync(path, generated.toString("base64"), { mode: 384 }), protectSecretFile(path), key = generated);
|
|
56
|
+
else
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return cachedKey = key, cachedKeyPath = path, key;
|
|
61
|
+
}
|
|
62
|
+
function encryptCredential(value) {
|
|
63
|
+
let iv = randomBytes(IV_BYTES), cipher = createCipheriv("aes-256-gcm", getCredentialKey(), iv), ciphertext = Buffer.concat([cipher.update(value, "utf-8"), cipher.final()]), tag = cipher.getAuthTag();
|
|
64
|
+
return `${AES_GCM_PREFIX}${iv.toString("base64")}.${tag.toString("base64")}.${ciphertext.toString("base64")}`;
|
|
65
|
+
}
|
|
66
|
+
function decryptAesGcm(raw, logPrefix) {
|
|
67
|
+
let parts = raw.slice(AES_GCM_PREFIX.length).split(".");
|
|
68
|
+
if (parts.length !== 3)
|
|
69
|
+
return console.warn(`${logPrefix} Malformed encrypted credential payload`), null;
|
|
70
|
+
try {
|
|
71
|
+
let iv = Buffer.from(parts[0], "base64"), tag = Buffer.from(parts[1], "base64");
|
|
72
|
+
if (iv.length !== IV_BYTES || tag.length !== TAG_BYTES)
|
|
73
|
+
return console.warn(`${logPrefix} Malformed encrypted credential payload`), null;
|
|
74
|
+
let decipher = createDecipheriv("aes-256-gcm", getCredentialKey(), iv);
|
|
75
|
+
return decipher.setAuthTag(tag), Buffer.concat([
|
|
76
|
+
decipher.update(Buffer.from(parts[2], "base64")),
|
|
77
|
+
decipher.final()
|
|
78
|
+
]).toString("utf-8");
|
|
79
|
+
} catch {
|
|
80
|
+
return console.warn(`${logPrefix} Could not decrypt credential \u2014 the key file may have been regenerated. Sign in again.`), null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function decryptCredential(raw, logPrefix = "[Credentials]") {
|
|
84
|
+
if (raw.startsWith(AES_GCM_PREFIX))
|
|
85
|
+
return decryptAesGcm(raw, logPrefix);
|
|
86
|
+
if (raw.startsWith(SAFE_STORAGE_PREFIX)) {
|
|
87
|
+
let safeStorage = getSafeStorage();
|
|
88
|
+
if (!safeStorage?.isEncryptionAvailable())
|
|
89
|
+
return console.warn(`${logPrefix} Credential is safeStorage-encrypted and this process has no Electron keychain access. Start ADF Studio once to migrate it, or sign in here.`), null;
|
|
90
|
+
try {
|
|
91
|
+
return safeStorage.decryptString(Buffer.from(raw.slice(SAFE_STORAGE_PREFIX.length), "base64"));
|
|
92
|
+
} catch (err) {
|
|
93
|
+
return console.warn(`${logPrefix} Failed to decrypt safeStorage credential:`, err), null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return raw;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/main/providers/subscription-token-store.ts
|
|
100
|
+
var STUDIO_FILE = "auth.json", DAEMON_FILE = "auth.daemon.json", REPLACED_FILE_PATTERN = /^auth\.replaced(\.[\w-]+)?\.json$/;
|
|
101
|
+
function getSafeStorage2() {
|
|
102
|
+
try {
|
|
103
|
+
return __require("electron").safeStorage ?? null;
|
|
104
|
+
} catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function isElectronSurface() {
|
|
109
|
+
return getSafeStorage2() !== null;
|
|
110
|
+
}
|
|
111
|
+
function createSubscriptionTokenStore(dirName) {
|
|
112
|
+
let logTag = `[${dirName} Auth]`;
|
|
113
|
+
function getDir() {
|
|
114
|
+
let dir = join2(getUserDataPath(), dirName);
|
|
115
|
+
return existsSync2(dir) || mkdirSync2(dir, { recursive: !0 }), dir;
|
|
116
|
+
}
|
|
117
|
+
function getStorePath() {
|
|
118
|
+
return join2(getDir(), isElectronSurface() ? STUDIO_FILE : DAEMON_FILE);
|
|
119
|
+
}
|
|
120
|
+
function encryptValue(value) {
|
|
121
|
+
let safeStorage = getSafeStorage2();
|
|
122
|
+
if (safeStorage?.isEncryptionAvailable()) {
|
|
123
|
+
let encrypted = safeStorage.encryptString(value);
|
|
124
|
+
return SAFE_STORAGE_PREFIX + encrypted.toString("base64");
|
|
125
|
+
}
|
|
126
|
+
return safeStorage && console.warn(`${logTag} safeStorage unavailable \u2014 falling back to key-file encryption`), encryptCredential(value);
|
|
127
|
+
}
|
|
128
|
+
function decryptValue(raw) {
|
|
129
|
+
return decryptCredential(raw, logTag);
|
|
130
|
+
}
|
|
131
|
+
function adoptLegacyFile(ownPath) {
|
|
132
|
+
let legacyPath = join2(getDir(), STUDIO_FILE);
|
|
133
|
+
if (existsSync2(legacyPath))
|
|
134
|
+
try {
|
|
135
|
+
let raw = readFileSync2(legacyPath, "utf-8");
|
|
136
|
+
if (raw.startsWith(SAFE_STORAGE_PREFIX)) {
|
|
137
|
+
console.warn(
|
|
138
|
+
`${logTag} ${STUDIO_FILE} is encrypted by ADF Studio and cannot be used here \u2014 log in from this surface to create its own session`
|
|
139
|
+
);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
writeFileSync2(ownPath, raw, { mode: 384 }), console.log(`${logTag} Adopted legacy shared token file into ${DAEMON_FILE}`);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
console.warn(`${logTag} Failed to adopt legacy token file:`, err);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function readTokens() {
|
|
148
|
+
let path = getStorePath();
|
|
149
|
+
if (!existsSync2(path) && !isElectronSurface() && adoptLegacyFile(path), !existsSync2(path)) return null;
|
|
150
|
+
try {
|
|
151
|
+
let raw = readFileSync2(path, "utf-8"), decrypted = decryptValue(raw);
|
|
152
|
+
return decrypted ? JSON.parse(decrypted) : null;
|
|
153
|
+
} catch (err) {
|
|
154
|
+
return console.warn(`${logTag} Failed to read tokens:`, err), null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function writeTokens(tokens) {
|
|
158
|
+
let path = getStorePath(), value = encryptValue(JSON.stringify(tokens));
|
|
159
|
+
if (!value.startsWith(SAFE_STORAGE_PREFIX) && existsSync2(path)) {
|
|
160
|
+
let existing = null;
|
|
161
|
+
try {
|
|
162
|
+
existing = readFileSync2(path, "utf-8");
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
if (existing?.startsWith(SAFE_STORAGE_PREFIX))
|
|
166
|
+
throw new Error(
|
|
167
|
+
`${logTag} refusing to overwrite a keychain-encrypted session with weaker key-file encryption. Log out (clearing the stored session) and log in again from this surface.`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
writeFileSync2(path, value, { mode: 384 });
|
|
171
|
+
}
|
|
172
|
+
function clearTokens() {
|
|
173
|
+
let path = getStorePath();
|
|
174
|
+
if (existsSync2(path))
|
|
175
|
+
try {
|
|
176
|
+
unlinkSync(path);
|
|
177
|
+
} catch {
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function signedIn(accountId) {
|
|
181
|
+
if (!accountId) return;
|
|
182
|
+
let names;
|
|
183
|
+
try {
|
|
184
|
+
names = readdirSync(getDir()).filter((name) => REPLACED_FILE_PATTERN.test(name));
|
|
185
|
+
} catch (err) {
|
|
186
|
+
console.warn(`${logTag} Could not list the sessions set aside after the sign-in:`, err instanceof Error ? err.message : err);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
for (let name of names)
|
|
190
|
+
try {
|
|
191
|
+
let path = join2(getDir(), name);
|
|
192
|
+
if (JSON.parse(decryptValue(readFileSync2(path, "utf-8")) ?? "null")?.account_id !== accountId) continue;
|
|
193
|
+
unlinkSync(path), console.log(`${logTag} Deleted ${name}: ${accountId} signed in again, so the session set aside for it is no longer needed`);
|
|
194
|
+
} catch (err) {
|
|
195
|
+
console.warn(`${logTag} Could not check ${name} after the sign-in:`, err instanceof Error ? err.message : err);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return { readTokens, writeTokens, clearTokens, signedIn };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export {
|
|
202
|
+
createSubscriptionTokenStore
|
|
203
|
+
};
|