rechrome 1.9.1 → 1.10.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/package.json +1 -1
- package/rech.js +29 -11
- package/rech.ts +29 -11
package/package.json
CHANGED
package/rech.js
CHANGED
|
@@ -11,8 +11,8 @@ export const DEFAULT_PORT = 13775;
|
|
|
11
11
|
export const RECH_DIR = join(import.meta.dir, ".rech");
|
|
12
12
|
export const LOG_DIR = join(RECH_DIR, "logs");
|
|
13
13
|
|
|
14
|
-
const RECH_HOME_DIR = join(process.env.HOME!, ".
|
|
15
|
-
const TOKENS_FILE = join(RECH_HOME_DIR, "
|
|
14
|
+
const RECH_HOME_DIR = join(process.env.HOME!, ".rechrome");
|
|
15
|
+
const TOKENS_FILE = join(RECH_HOME_DIR, "profiles.json");
|
|
16
16
|
|
|
17
17
|
type TokenEntry = { extensionId: string; token: string; profileDir: string; userDataDir?: string };
|
|
18
18
|
|
|
@@ -362,7 +362,7 @@ async function callServe(
|
|
|
362
362
|
process.exit(1);
|
|
363
363
|
});
|
|
364
364
|
if (res.status === 401) {
|
|
365
|
-
console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected -> playwright[unknown]`);
|
|
365
|
+
console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected (used: ${key.slice(0, 6)}...) -> playwright[unknown]`);
|
|
366
366
|
process.exit(1);
|
|
367
367
|
}
|
|
368
368
|
return res.json();
|
|
@@ -549,13 +549,18 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
549
549
|
const { host, port, protocol } = parseUrl(url);
|
|
550
550
|
|
|
551
551
|
const { key: serveKey } = parseUrl(url);
|
|
552
|
-
|
|
552
|
+
// First check if server is up at all (unauthenticated root), then verify our key matches
|
|
553
|
+
const anonPing = await fetch(`${protocol}://${host}:${port}/`, { signal: AbortSignal.timeout(2000) }).catch(() => null);
|
|
554
|
+
const authPing = anonPing ? await fetch(`${protocol}://${host}:${port}/ping`, {
|
|
553
555
|
headers: { Authorization: `Bearer ${serveKey}` },
|
|
554
556
|
signal: AbortSignal.timeout(2000),
|
|
555
|
-
}).catch(() => null);
|
|
556
|
-
if (authPing?.ok) {
|
|
557
|
+
}).catch(() => null) : null;
|
|
558
|
+
if (anonPing && authPing?.ok) {
|
|
557
559
|
console.log(` Already running at ${protocol}://${host}:${port} — skipping reinstall`);
|
|
558
560
|
await runOxmgr(["service", "install"]);
|
|
561
|
+
} else if (anonPing && !authPing?.ok) {
|
|
562
|
+
console.log(` Server running but key mismatch — reinstalling with new key`);
|
|
563
|
+
await daemonInstall(url);
|
|
559
564
|
} else {
|
|
560
565
|
await daemonInstall(url);
|
|
561
566
|
console.log(` Registered daemon: ${OXMGR_PROCESS_NAME}`);
|
|
@@ -603,7 +608,7 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
603
608
|
return available[idx];
|
|
604
609
|
}
|
|
605
610
|
|
|
606
|
-
async function getExtAndToken(profileDir: string, profileDisplay: string): Promise<{ extId: string; token: string } | null> {
|
|
611
|
+
async function getExtAndToken(profileDir: string, profileDisplay: string, profileKey: string): Promise<{ extId: string; token: string } | null> {
|
|
607
612
|
// Extension check
|
|
608
613
|
let extId: string | undefined;
|
|
609
614
|
while (true) {
|
|
@@ -620,6 +625,19 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
620
625
|
}
|
|
621
626
|
console.log(` Extension found: ${extId}`);
|
|
622
627
|
|
|
628
|
+
// Check for existing token in registry
|
|
629
|
+
const registry = await readTokenRegistry();
|
|
630
|
+
const existing = registry[profileKey];
|
|
631
|
+
if (existing && existing.extensionId === extId && existing.token) {
|
|
632
|
+
console.log(` Existing token found: ${existing.token.slice(0, 6)}…`);
|
|
633
|
+
if (!isTTY) console.log(` [agent] Provide y to keep existing token, n to refresh on next stdin line`);
|
|
634
|
+
const keep = (await ask(" Keep existing token? [Y/n]: ")).trim().toLowerCase();
|
|
635
|
+
if (keep !== "n") {
|
|
636
|
+
console.log(" Keeping existing token");
|
|
637
|
+
return { extId, token: existing.token };
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
623
641
|
// Token
|
|
624
642
|
const statusUrl = `chrome-extension://${extId}/status.html`;
|
|
625
643
|
console.log(`\n Get auth token from the extension:`);
|
|
@@ -653,10 +671,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
653
671
|
|
|
654
672
|
// [3+4/4] Extension + token for primary profile
|
|
655
673
|
console.log("\n[3/4] Checking extension...");
|
|
656
|
-
const
|
|
674
|
+
const profileEmail = profileInfoSel.user_name || profileDir;
|
|
675
|
+
const primary = await getExtAndToken(profileDir, profileDisplay, profileEmail);
|
|
657
676
|
if (!primary) { rl?.close(); process.exit(1); }
|
|
658
677
|
const { extId, token } = primary;
|
|
659
|
-
const profileEmail = profileInfoSel.user_name || profileDir;
|
|
660
678
|
|
|
661
679
|
// Build RECHROME_URL and show it before asking where to save
|
|
662
680
|
const rechUrl = new URL(url);
|
|
@@ -703,10 +721,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
703
721
|
if (!extra) { console.log(" Skipped."); continue; }
|
|
704
722
|
const [extraDir, extraInfo] = extra;
|
|
705
723
|
const extraDisplay = extraInfo.user_name || extraInfo.name || extraDir;
|
|
724
|
+
const extraEmail = extraInfo.user_name || extraDir;
|
|
706
725
|
console.log(`\n Setting up: ${extraDisplay}`);
|
|
707
|
-
const result = await getExtAndToken(extraDir, extraDisplay);
|
|
726
|
+
const result = await getExtAndToken(extraDir, extraDisplay, extraEmail);
|
|
708
727
|
if (!result) { console.log(" Skipped."); continue; }
|
|
709
|
-
const extraEmail = extraInfo.user_name || extraDir;
|
|
710
728
|
await saveTokenEntry(extraEmail, { extensionId: result.extId, token: result.token, profileDir: extraDir, userDataDir: userDataDir ?? undefined });
|
|
711
729
|
configured.add(extraDir);
|
|
712
730
|
console.log(` Saved token for ${extraDisplay}`);
|
package/rech.ts
CHANGED
|
@@ -11,8 +11,8 @@ export const DEFAULT_PORT = 13775;
|
|
|
11
11
|
export const RECH_DIR = join(import.meta.dir, ".rech");
|
|
12
12
|
export const LOG_DIR = join(RECH_DIR, "logs");
|
|
13
13
|
|
|
14
|
-
const RECH_HOME_DIR = join(process.env.HOME!, ".
|
|
15
|
-
const TOKENS_FILE = join(RECH_HOME_DIR, "
|
|
14
|
+
const RECH_HOME_DIR = join(process.env.HOME!, ".rechrome");
|
|
15
|
+
const TOKENS_FILE = join(RECH_HOME_DIR, "profiles.json");
|
|
16
16
|
|
|
17
17
|
type TokenEntry = { extensionId: string; token: string; profileDir: string; userDataDir?: string };
|
|
18
18
|
|
|
@@ -362,7 +362,7 @@ async function callServe(
|
|
|
362
362
|
process.exit(1);
|
|
363
363
|
});
|
|
364
364
|
if (res.status === 401) {
|
|
365
|
-
console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected -> playwright[unknown]`);
|
|
365
|
+
console.error(`[rech] rech-client -> rech-server[ok]\n -x: token rejected (used: ${key.slice(0, 6)}...) -> playwright[unknown]`);
|
|
366
366
|
process.exit(1);
|
|
367
367
|
}
|
|
368
368
|
return res.json();
|
|
@@ -549,13 +549,18 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
549
549
|
const { host, port, protocol } = parseUrl(url);
|
|
550
550
|
|
|
551
551
|
const { key: serveKey } = parseUrl(url);
|
|
552
|
-
|
|
552
|
+
// First check if server is up at all (unauthenticated root), then verify our key matches
|
|
553
|
+
const anonPing = await fetch(`${protocol}://${host}:${port}/`, { signal: AbortSignal.timeout(2000) }).catch(() => null);
|
|
554
|
+
const authPing = anonPing ? await fetch(`${protocol}://${host}:${port}/ping`, {
|
|
553
555
|
headers: { Authorization: `Bearer ${serveKey}` },
|
|
554
556
|
signal: AbortSignal.timeout(2000),
|
|
555
|
-
}).catch(() => null);
|
|
556
|
-
if (authPing?.ok) {
|
|
557
|
+
}).catch(() => null) : null;
|
|
558
|
+
if (anonPing && authPing?.ok) {
|
|
557
559
|
console.log(` Already running at ${protocol}://${host}:${port} — skipping reinstall`);
|
|
558
560
|
await runOxmgr(["service", "install"]);
|
|
561
|
+
} else if (anonPing && !authPing?.ok) {
|
|
562
|
+
console.log(` Server running but key mismatch — reinstalling with new key`);
|
|
563
|
+
await daemonInstall(url);
|
|
559
564
|
} else {
|
|
560
565
|
await daemonInstall(url);
|
|
561
566
|
console.log(` Registered daemon: ${OXMGR_PROCESS_NAME}`);
|
|
@@ -603,7 +608,7 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
603
608
|
return available[idx];
|
|
604
609
|
}
|
|
605
610
|
|
|
606
|
-
async function getExtAndToken(profileDir: string, profileDisplay: string): Promise<{ extId: string; token: string } | null> {
|
|
611
|
+
async function getExtAndToken(profileDir: string, profileDisplay: string, profileKey: string): Promise<{ extId: string; token: string } | null> {
|
|
607
612
|
// Extension check
|
|
608
613
|
let extId: string | undefined;
|
|
609
614
|
while (true) {
|
|
@@ -620,6 +625,19 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
620
625
|
}
|
|
621
626
|
console.log(` Extension found: ${extId}`);
|
|
622
627
|
|
|
628
|
+
// Check for existing token in registry
|
|
629
|
+
const registry = await readTokenRegistry();
|
|
630
|
+
const existing = registry[profileKey];
|
|
631
|
+
if (existing && existing.extensionId === extId && existing.token) {
|
|
632
|
+
console.log(` Existing token found: ${existing.token.slice(0, 6)}…`);
|
|
633
|
+
if (!isTTY) console.log(` [agent] Provide y to keep existing token, n to refresh on next stdin line`);
|
|
634
|
+
const keep = (await ask(" Keep existing token? [Y/n]: ")).trim().toLowerCase();
|
|
635
|
+
if (keep !== "n") {
|
|
636
|
+
console.log(" Keeping existing token");
|
|
637
|
+
return { extId, token: existing.token };
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
623
641
|
// Token
|
|
624
642
|
const statusUrl = `chrome-extension://${extId}/status.html`;
|
|
625
643
|
console.log(`\n Get auth token from the extension:`);
|
|
@@ -653,10 +671,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
653
671
|
|
|
654
672
|
// [3+4/4] Extension + token for primary profile
|
|
655
673
|
console.log("\n[3/4] Checking extension...");
|
|
656
|
-
const
|
|
674
|
+
const profileEmail = profileInfoSel.user_name || profileDir;
|
|
675
|
+
const primary = await getExtAndToken(profileDir, profileDisplay, profileEmail);
|
|
657
676
|
if (!primary) { rl?.close(); process.exit(1); }
|
|
658
677
|
const { extId, token } = primary;
|
|
659
|
-
const profileEmail = profileInfoSel.user_name || profileDir;
|
|
660
678
|
|
|
661
679
|
// Build RECHROME_URL and show it before asking where to save
|
|
662
680
|
const rechUrl = new URL(url);
|
|
@@ -703,10 +721,10 @@ async function setup(opts: { profile?: string } = {}): Promise<void> {
|
|
|
703
721
|
if (!extra) { console.log(" Skipped."); continue; }
|
|
704
722
|
const [extraDir, extraInfo] = extra;
|
|
705
723
|
const extraDisplay = extraInfo.user_name || extraInfo.name || extraDir;
|
|
724
|
+
const extraEmail = extraInfo.user_name || extraDir;
|
|
706
725
|
console.log(`\n Setting up: ${extraDisplay}`);
|
|
707
|
-
const result = await getExtAndToken(extraDir, extraDisplay);
|
|
726
|
+
const result = await getExtAndToken(extraDir, extraDisplay, extraEmail);
|
|
708
727
|
if (!result) { console.log(" Skipped."); continue; }
|
|
709
|
-
const extraEmail = extraInfo.user_name || extraDir;
|
|
710
728
|
await saveTokenEntry(extraEmail, { extensionId: result.extId, token: result.token, profileDir: extraDir, userDataDir: userDataDir ?? undefined });
|
|
711
729
|
configured.add(extraDir);
|
|
712
730
|
console.log(` Saved token for ${extraDisplay}`);
|