lockin-mcp 1.0.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 +349 -0
- package/assets/icon-256.png +0 -0
- package/assets/icon-32.png +0 -0
- package/assets/icon.svg +4 -0
- package/dist/blocker.d.ts +23 -0
- package/dist/blocker.d.ts.map +1 -0
- package/dist/blocker.js +184 -0
- package/dist/blocker.js.map +1 -0
- package/dist/brand.d.ts +12 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +12 -0
- package/dist/brand.js.map +1 -0
- package/dist/hosts-manager.d.ts +14 -0
- package/dist/hosts-manager.d.ts.map +1 -0
- package/dist/hosts-manager.js +233 -0
- package/dist/hosts-manager.js.map +1 -0
- package/dist/hosts-manager.test.d.ts +2 -0
- package/dist/hosts-manager.test.d.ts.map +1 -0
- package/dist/hosts-manager.test.js +19 -0
- package/dist/hosts-manager.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +296 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +3 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +15 -0
- package/dist/install.js.map +1 -0
- package/dist/installer/agent-instructions.d.ts +25 -0
- package/dist/installer/agent-instructions.d.ts.map +1 -0
- package/dist/installer/agent-instructions.js +36 -0
- package/dist/installer/agent-instructions.js.map +1 -0
- package/dist/installer/agents.d.ts +9 -0
- package/dist/installer/agents.d.ts.map +1 -0
- package/dist/installer/agents.js +223 -0
- package/dist/installer/agents.js.map +1 -0
- package/dist/installer/background-service.d.ts +11 -0
- package/dist/installer/background-service.d.ts.map +1 -0
- package/dist/installer/background-service.js +47 -0
- package/dist/installer/background-service.js.map +1 -0
- package/dist/installer/clipboard.d.ts +2 -0
- package/dist/installer/clipboard.d.ts.map +1 -0
- package/dist/installer/clipboard.js +28 -0
- package/dist/installer/clipboard.js.map +1 -0
- package/dist/installer/daemon-linux.d.ts +10 -0
- package/dist/installer/daemon-linux.d.ts.map +1 -0
- package/dist/installer/daemon-linux.js +66 -0
- package/dist/installer/daemon-linux.js.map +1 -0
- package/dist/installer/daemon-windows.d.ts +10 -0
- package/dist/installer/daemon-windows.d.ts.map +1 -0
- package/dist/installer/daemon-windows.js +88 -0
- package/dist/installer/daemon-windows.js.map +1 -0
- package/dist/installer/daemon.d.ts +10 -0
- package/dist/installer/daemon.d.ts.map +1 -0
- package/dist/installer/daemon.js +96 -0
- package/dist/installer/daemon.js.map +1 -0
- package/dist/installer/hosts-sudo.d.ts +6 -0
- package/dist/installer/hosts-sudo.d.ts.map +1 -0
- package/dist/installer/hosts-sudo.js +111 -0
- package/dist/installer/hosts-sudo.js.map +1 -0
- package/dist/installer/legacy-tunnels.d.ts +2 -0
- package/dist/installer/legacy-tunnels.d.ts.map +1 -0
- package/dist/installer/legacy-tunnels.js +27 -0
- package/dist/installer/legacy-tunnels.js.map +1 -0
- package/dist/installer/license.d.ts +9 -0
- package/dist/installer/license.d.ts.map +1 -0
- package/dist/installer/license.js +193 -0
- package/dist/installer/license.js.map +1 -0
- package/dist/installer/mcp-cleanup.d.ts +3 -0
- package/dist/installer/mcp-cleanup.d.ts.map +1 -0
- package/dist/installer/mcp-cleanup.js +28 -0
- package/dist/installer/mcp-cleanup.js.map +1 -0
- package/dist/installer/platform.d.ts +7 -0
- package/dist/installer/platform.d.ts.map +1 -0
- package/dist/installer/platform.js +76 -0
- package/dist/installer/platform.js.map +1 -0
- package/dist/installer/poke-daemon.d.ts +14 -0
- package/dist/installer/poke-daemon.d.ts.map +1 -0
- package/dist/installer/poke-daemon.js +161 -0
- package/dist/installer/poke-daemon.js.map +1 -0
- package/dist/installer/poke.d.ts +43 -0
- package/dist/installer/poke.d.ts.map +1 -0
- package/dist/installer/poke.js +154 -0
- package/dist/installer/poke.js.map +1 -0
- package/dist/installer/port.d.ts +6 -0
- package/dist/installer/port.d.ts.map +1 -0
- package/dist/installer/port.js +76 -0
- package/dist/installer/port.js.map +1 -0
- package/dist/installer/presets.d.ts +5 -0
- package/dist/installer/presets.d.ts.map +1 -0
- package/dist/installer/presets.js +22 -0
- package/dist/installer/presets.js.map +1 -0
- package/dist/installer/prompts.d.ts +8 -0
- package/dist/installer/prompts.d.ts.map +1 -0
- package/dist/installer/prompts.js +128 -0
- package/dist/installer/prompts.js.map +1 -0
- package/dist/installer/relay-credentials.d.ts +26 -0
- package/dist/installer/relay-credentials.d.ts.map +1 -0
- package/dist/installer/relay-credentials.js +75 -0
- package/dist/installer/relay-credentials.js.map +1 -0
- package/dist/installer/relay-provision.d.ts +26 -0
- package/dist/installer/relay-provision.d.ts.map +1 -0
- package/dist/installer/relay-provision.js +57 -0
- package/dist/installer/relay-provision.js.map +1 -0
- package/dist/installer/run.d.ts +2 -0
- package/dist/installer/run.d.ts.map +1 -0
- package/dist/installer/run.js +365 -0
- package/dist/installer/run.js.map +1 -0
- package/dist/installer/tty.d.ts +7 -0
- package/dist/installer/tty.d.ts.map +1 -0
- package/dist/installer/tty.js +37 -0
- package/dist/installer/tty.js.map +1 -0
- package/dist/installer/tui.d.ts +14 -0
- package/dist/installer/tui.d.ts.map +1 -0
- package/dist/installer/tui.js +150 -0
- package/dist/installer/tui.js.map +1 -0
- package/dist/installer/tunnel-daemon.d.ts +13 -0
- package/dist/installer/tunnel-daemon.d.ts.map +1 -0
- package/dist/installer/tunnel-daemon.js +129 -0
- package/dist/installer/tunnel-daemon.js.map +1 -0
- package/dist/installer/tunnel-provision.d.ts +14 -0
- package/dist/installer/tunnel-provision.d.ts.map +1 -0
- package/dist/installer/tunnel-provision.js +31 -0
- package/dist/installer/tunnel-provision.js.map +1 -0
- package/dist/installer/tunnel.d.ts +12 -0
- package/dist/installer/tunnel.d.ts.map +1 -0
- package/dist/installer/tunnel.js +91 -0
- package/dist/installer/tunnel.js.map +1 -0
- package/dist/installer/types.d.ts +59 -0
- package/dist/installer/types.d.ts.map +1 -0
- package/dist/installer/types.js +2 -0
- package/dist/installer/types.js.map +1 -0
- package/dist/license-check.d.ts +12 -0
- package/dist/license-check.d.ts.map +1 -0
- package/dist/license-check.js +59 -0
- package/dist/license-check.js.map +1 -0
- package/dist/license-guard.d.ts +14 -0
- package/dist/license-guard.d.ts.map +1 -0
- package/dist/license-guard.js +56 -0
- package/dist/license-guard.js.map +1 -0
- package/dist/license-guard.test.d.ts +2 -0
- package/dist/license-guard.test.d.ts.map +1 -0
- package/dist/license-guard.test.js +34 -0
- package/dist/license-guard.test.js.map +1 -0
- package/dist/relay-client.d.ts +32 -0
- package/dist/relay-client.d.ts.map +1 -0
- package/dist/relay-client.js +249 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay-types.d.ts +30 -0
- package/dist/relay-types.d.ts.map +1 -0
- package/dist/relay-types.js +2 -0
- package/dist/relay-types.js.map +1 -0
- package/dist/relay-urls.d.ts +22 -0
- package/dist/relay-urls.d.ts.map +1 -0
- package/dist/relay-urls.js +57 -0
- package/dist/relay-urls.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +164 -0
- package/dist/server.js.map +1 -0
- package/dist/state.d.ts +12 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +91 -0
- package/dist/state.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +41 -0
- package/dist/types.js.map +1 -0
- package/dist/types.test.d.ts +2 -0
- package/dist/types.test.d.ts.map +1 -0
- package/dist/types.test.js +13 -0
- package/dist/types.test.js.map +1 -0
- package/install.ps1 +41 -0
- package/install.sh +39 -0
- package/package.json +64 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { access, mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { getInstallDir } from "./platform.js";
|
|
7
|
+
import { resolveCloudflared, cloudflaredQuickTunnelArgs } from "./tunnel.js";
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const LAUNCH_LABEL = "com.lockin.cloudflared";
|
|
10
|
+
function escapeXml(value) {
|
|
11
|
+
return value
|
|
12
|
+
.replace(/&/g, "&")
|
|
13
|
+
.replace(/</g, "<")
|
|
14
|
+
.replace(/>/g, ">")
|
|
15
|
+
.replace(/"/g, """);
|
|
16
|
+
}
|
|
17
|
+
export async function installCloudflaredLaunchAgent(params) {
|
|
18
|
+
const installDir = getInstallDir();
|
|
19
|
+
await mkdir(installDir, { recursive: true });
|
|
20
|
+
const tokenPath = join(installDir, "tunnel-token");
|
|
21
|
+
await writeFile(tokenPath, `${params.tunnelToken}\n`, { mode: 0o600 });
|
|
22
|
+
const cloudflaredBinary = await resolveCloudflared(params.platform, params.autoInstallTunnel);
|
|
23
|
+
const stdoutLog = join(installDir, "cloudflared.stdout.log");
|
|
24
|
+
const stderrLog = join(installDir, "cloudflared.stderr.log");
|
|
25
|
+
const plistPath = join(homedir(), "Library", "LaunchAgents", `${LAUNCH_LABEL}.plist`);
|
|
26
|
+
await mkdir(dirname(plistPath), { recursive: true });
|
|
27
|
+
const home = homedir();
|
|
28
|
+
const pathEnv = "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:" +
|
|
29
|
+
`${home}/.local/bin`;
|
|
30
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
31
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
32
|
+
<plist version="1.0">
|
|
33
|
+
<dict>
|
|
34
|
+
<key>Label</key>
|
|
35
|
+
<string>${LAUNCH_LABEL}</string>
|
|
36
|
+
<key>ProgramArguments</key>
|
|
37
|
+
<array>
|
|
38
|
+
<string>${escapeXml(cloudflaredBinary)}</string>
|
|
39
|
+
<string>tunnel</string>
|
|
40
|
+
<string>run</string>
|
|
41
|
+
<string>--token</string>
|
|
42
|
+
<string>${escapeXml(params.tunnelToken)}</string>
|
|
43
|
+
</array>
|
|
44
|
+
<key>EnvironmentVariables</key>
|
|
45
|
+
<dict>
|
|
46
|
+
<key>HOME</key>
|
|
47
|
+
<string>${escapeXml(home)}</string>
|
|
48
|
+
<key>PATH</key>
|
|
49
|
+
<string>${escapeXml(pathEnv)}</string>
|
|
50
|
+
</dict>
|
|
51
|
+
<key>RunAtLoad</key>
|
|
52
|
+
<true/>
|
|
53
|
+
<key>KeepAlive</key>
|
|
54
|
+
<true/>
|
|
55
|
+
<key>ThrottleInterval</key>
|
|
56
|
+
<integer>30</integer>
|
|
57
|
+
<key>StandardOutPath</key>
|
|
58
|
+
<string>${escapeXml(stdoutLog)}</string>
|
|
59
|
+
<key>StandardErrorPath</key>
|
|
60
|
+
<string>${escapeXml(stderrLog)}</string>
|
|
61
|
+
</dict>
|
|
62
|
+
</plist>
|
|
63
|
+
`;
|
|
64
|
+
await writeFile(plistPath, plist, { mode: 0o644 });
|
|
65
|
+
const guiDomain = `gui/${process.getuid?.() ?? process.env.UID ?? "501"}`;
|
|
66
|
+
await execFileAsync("launchctl", ["bootout", guiDomain, plistPath]).catch(() => undefined);
|
|
67
|
+
await execFileAsync("launchctl", ["bootstrap", guiDomain, plistPath]);
|
|
68
|
+
return plistPath;
|
|
69
|
+
}
|
|
70
|
+
export async function installQuickTunnelLaunchAgent(params) {
|
|
71
|
+
const installDir = getInstallDir();
|
|
72
|
+
await mkdir(installDir, { recursive: true });
|
|
73
|
+
const cloudflaredBinary = await resolveCloudflared(params.platform, params.autoInstallTunnel);
|
|
74
|
+
const stdoutLog = join(installDir, "cloudflared.stdout.log");
|
|
75
|
+
const stderrLog = join(installDir, "cloudflared.stderr.log");
|
|
76
|
+
const plistPath = join(homedir(), "Library", "LaunchAgents", `${LAUNCH_LABEL}.plist`);
|
|
77
|
+
await mkdir(dirname(plistPath), { recursive: true });
|
|
78
|
+
const home = homedir();
|
|
79
|
+
const pathEnv = "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:" +
|
|
80
|
+
`${home}/.local/bin`;
|
|
81
|
+
const tunnelArgs = cloudflaredQuickTunnelArgs(params.port);
|
|
82
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
83
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
84
|
+
<plist version="1.0">
|
|
85
|
+
<dict>
|
|
86
|
+
<key>Label</key>
|
|
87
|
+
<string>${LAUNCH_LABEL}</string>
|
|
88
|
+
<key>ProgramArguments</key>
|
|
89
|
+
<array>
|
|
90
|
+
<string>${escapeXml(cloudflaredBinary)}</string>
|
|
91
|
+
${tunnelArgs.map((arg) => `<string>${escapeXml(arg)}</string>`).join("\n ")}
|
|
92
|
+
</array>
|
|
93
|
+
<key>EnvironmentVariables</key>
|
|
94
|
+
<dict>
|
|
95
|
+
<key>HOME</key>
|
|
96
|
+
<string>${escapeXml(home)}</string>
|
|
97
|
+
<key>PATH</key>
|
|
98
|
+
<string>${escapeXml(pathEnv)}</string>
|
|
99
|
+
</dict>
|
|
100
|
+
<key>RunAtLoad</key>
|
|
101
|
+
<true/>
|
|
102
|
+
<key>KeepAlive</key>
|
|
103
|
+
<true/>
|
|
104
|
+
<key>ThrottleInterval</key>
|
|
105
|
+
<integer>30</integer>
|
|
106
|
+
<key>StandardOutPath</key>
|
|
107
|
+
<string>${escapeXml(stdoutLog)}</string>
|
|
108
|
+
<key>StandardErrorPath</key>
|
|
109
|
+
<string>${escapeXml(stderrLog)}</string>
|
|
110
|
+
</dict>
|
|
111
|
+
</plist>
|
|
112
|
+
`;
|
|
113
|
+
await writeFile(plistPath, plist, { mode: 0o644 });
|
|
114
|
+
const guiDomain = `gui/${process.getuid?.() ?? process.env.UID ?? "501"}`;
|
|
115
|
+
await execFileAsync("launchctl", ["bootout", guiDomain, plistPath]).catch(() => undefined);
|
|
116
|
+
await execFileAsync("launchctl", ["bootstrap", guiDomain, plistPath]);
|
|
117
|
+
return plistPath;
|
|
118
|
+
}
|
|
119
|
+
export async function isCloudflaredLaunchAgentInstalled() {
|
|
120
|
+
const plistPath = join(homedir(), "Library", "LaunchAgents", `${LAUNCH_LABEL}.plist`);
|
|
121
|
+
try {
|
|
122
|
+
await access(plistPath);
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=tunnel-daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-daemon.js","sourceRoot":"","sources":["../../src/installer/tunnel-daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface PermanentTunnelResult {
|
|
2
|
+
hostname: string;
|
|
3
|
+
tunnelToken: string;
|
|
4
|
+
sseUrl: string;
|
|
5
|
+
mcpUrl: string;
|
|
6
|
+
subdomain: string;
|
|
7
|
+
manualDnsCname?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function provisionPermanentTunnel(params: {
|
|
10
|
+
licenseToken: string;
|
|
11
|
+
port: number;
|
|
12
|
+
}): Promise<PermanentTunnelResult>;
|
|
13
|
+
export declare function isPermanentTunnelMode(): boolean;
|
|
14
|
+
//# sourceMappingURL=tunnel-provision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-provision.d.ts","sourceRoot":"","sources":["../../src/installer/tunnel-provision.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA8BjC;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const LICENSE_API_URL = process.env.MDB_LICENSE_API_URL ??
|
|
2
|
+
"http://localhost:3001/api/v1";
|
|
3
|
+
export async function provisionPermanentTunnel(params) {
|
|
4
|
+
const response = await fetch(`${LICENSE_API_URL}/tunnel/provision`, {
|
|
5
|
+
method: "POST",
|
|
6
|
+
headers: {
|
|
7
|
+
"Content-Type": "application/json",
|
|
8
|
+
Authorization: `Bearer ${params.licenseToken}`,
|
|
9
|
+
},
|
|
10
|
+
body: JSON.stringify({ port: params.port }),
|
|
11
|
+
});
|
|
12
|
+
const body = (await response.json());
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
throw new Error(body.error ?? `Tunnel provision failed (${response.status})`);
|
|
15
|
+
}
|
|
16
|
+
if (!body.hostname || !body.tunnelToken) {
|
|
17
|
+
throw new Error("Tunnel provision returned incomplete data");
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
hostname: body.hostname,
|
|
21
|
+
tunnelToken: body.tunnelToken,
|
|
22
|
+
sseUrl: body.sseUrl,
|
|
23
|
+
mcpUrl: body.mcpUrl,
|
|
24
|
+
subdomain: body.subdomain,
|
|
25
|
+
manualDnsCname: body.manualDnsCname,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function isPermanentTunnelMode() {
|
|
29
|
+
return process.env.MDB_TUNNEL_MODE === "permanent";
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=tunnel-provision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-provision.js","sourceRoot":"","sources":["../../src/installer/tunnel-provision.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GACnB,OAAO,CAAC,GAAG,CAAC,mBAAmB;IAC/B,8BAA8B,CAAC;AAWjC,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAG9C;IACC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,eAAe,mBAAmB,EAAE;QAClE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,MAAM,CAAC,YAAY,EAAE;SAC/C;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;KAC5C,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,4BAA4B,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,cAAc,EAAE,IAAI,CAAC,cAAc;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,WAAW,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function waitForHttp(url: string, attempts?: number, delayMs?: number): Promise<void>;
|
|
2
|
+
export declare function verifyPublicTunnel(params: {
|
|
3
|
+
publicBaseUrl: string;
|
|
4
|
+
authToken?: string;
|
|
5
|
+
attempts?: number;
|
|
6
|
+
delayMs?: number;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
healthOk: boolean;
|
|
9
|
+
mcpOk: boolean;
|
|
10
|
+
detail: string;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=tunnel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/installer/tunnel.ts"],"names":[],"mappings":"AAIA,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,SAAK,EACb,OAAO,SAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA6EjE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
function sleep(ms) {
|
|
2
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3
|
+
}
|
|
4
|
+
export async function waitForHttp(url, attempts = 30, delayMs = 500) {
|
|
5
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
6
|
+
try {
|
|
7
|
+
const response = await fetch(url);
|
|
8
|
+
if (response.ok) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// retry
|
|
14
|
+
}
|
|
15
|
+
await sleep(delayMs);
|
|
16
|
+
}
|
|
17
|
+
throw new Error(`Service did not become ready at ${url}`);
|
|
18
|
+
}
|
|
19
|
+
export async function verifyPublicTunnel(params) {
|
|
20
|
+
const base = params.publicBaseUrl.replace(/\/$/, "");
|
|
21
|
+
const headers = params.authToken
|
|
22
|
+
? { Authorization: `Bearer ${params.authToken}` }
|
|
23
|
+
: {};
|
|
24
|
+
const attempts = params.attempts ?? 12;
|
|
25
|
+
const delayMs = params.delayMs ?? 2000;
|
|
26
|
+
let healthOk = false;
|
|
27
|
+
let mcpOk = false;
|
|
28
|
+
let detail = "";
|
|
29
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
30
|
+
healthOk = false;
|
|
31
|
+
mcpOk = false;
|
|
32
|
+
detail = "";
|
|
33
|
+
try {
|
|
34
|
+
const health = await fetch(`${base}/health`, {
|
|
35
|
+
signal: AbortSignal.timeout(10_000),
|
|
36
|
+
});
|
|
37
|
+
const healthBody = (await health.json());
|
|
38
|
+
if (healthBody.error === "Device offline") {
|
|
39
|
+
healthOk = false;
|
|
40
|
+
detail =
|
|
41
|
+
"Relay is up but your Mac is not connected. Keep the installer running until this step passes.";
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
healthOk = health.ok && healthBody.service === "lockin-mcp";
|
|
45
|
+
if (!health.ok) {
|
|
46
|
+
detail = `GET /health returned ${health.status}`;
|
|
47
|
+
}
|
|
48
|
+
else if (!healthOk) {
|
|
49
|
+
detail =
|
|
50
|
+
`GET /health did not reach LockIn MCP (got ${JSON.stringify(healthBody)}).`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
detail =
|
|
56
|
+
error instanceof Error ? error.message : "Could not reach /health through relay";
|
|
57
|
+
}
|
|
58
|
+
if (healthOk) {
|
|
59
|
+
try {
|
|
60
|
+
const mcp = await fetch(`${base}/mcp`, {
|
|
61
|
+
method: "GET",
|
|
62
|
+
headers,
|
|
63
|
+
signal: AbortSignal.timeout(10_000),
|
|
64
|
+
});
|
|
65
|
+
mcpOk = mcp.ok || mcp.status === 405 || mcp.status === 406;
|
|
66
|
+
if (!mcpOk) {
|
|
67
|
+
const body = (await mcp.text()).slice(0, 180);
|
|
68
|
+
detail = `GET /mcp returned ${mcp.status}: ${body}`;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
detail = "Relay verified (/health and /mcp reachable)";
|
|
72
|
+
}
|
|
73
|
+
await mcp.body?.cancel().catch(() => undefined);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
detail =
|
|
77
|
+
error instanceof Error
|
|
78
|
+
? error.message
|
|
79
|
+
: "Could not reach /mcp through relay";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (healthOk && mcpOk) {
|
|
83
|
+
return { healthOk, mcpOk, detail };
|
|
84
|
+
}
|
|
85
|
+
if (attempt < attempts - 1) {
|
|
86
|
+
await sleep(delayMs);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { healthOk, mcpOk, detail };
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../src/installer/tunnel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type PlatformId = "darwin" | "linux" | "win32" | "unsupported";
|
|
2
|
+
export type LicenseTier = "free" | "pro";
|
|
3
|
+
export interface PlatformInfo {
|
|
4
|
+
id: PlatformId;
|
|
5
|
+
name: string;
|
|
6
|
+
isHostsSupported: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface LicenseInfo {
|
|
9
|
+
tier: LicenseTier;
|
|
10
|
+
method: "license_key" | "browser" | "cached";
|
|
11
|
+
token?: string;
|
|
12
|
+
email?: string;
|
|
13
|
+
expiresAt?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface SitePreset {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
domain: string;
|
|
19
|
+
defaultSelected: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface InstallerOptions {
|
|
22
|
+
nonInteractive: boolean;
|
|
23
|
+
licenseKey?: string;
|
|
24
|
+
useBrowserLogin: boolean;
|
|
25
|
+
port: number;
|
|
26
|
+
selectedPresetIds: string[];
|
|
27
|
+
customDomains: string[];
|
|
28
|
+
skipBlock: boolean;
|
|
29
|
+
skipTunnel: boolean;
|
|
30
|
+
skipPoke: boolean;
|
|
31
|
+
pokeRecipe: boolean;
|
|
32
|
+
mcpAuthToken?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface InstallerResult {
|
|
35
|
+
platform: PlatformInfo;
|
|
36
|
+
license: LicenseInfo;
|
|
37
|
+
blockedDomains: string[];
|
|
38
|
+
localMcpUrl: string;
|
|
39
|
+
relayMcpUrl?: string;
|
|
40
|
+
mcpAuthToken?: string;
|
|
41
|
+
pokeIntegrationUrl?: string;
|
|
42
|
+
pokeRecipeUrl?: string;
|
|
43
|
+
setupManifestPath: string;
|
|
44
|
+
}
|
|
45
|
+
export interface SetupManifest {
|
|
46
|
+
version: string;
|
|
47
|
+
installedAt: string;
|
|
48
|
+
platform: string;
|
|
49
|
+
licenseTier: LicenseTier;
|
|
50
|
+
blockedDomains: string[];
|
|
51
|
+
localMcpUrl: string;
|
|
52
|
+
publicMcpUrl?: string;
|
|
53
|
+
mcpAuthToken?: string;
|
|
54
|
+
pokeIntegrationUrl?: string;
|
|
55
|
+
pokeRecipeUrl?: string;
|
|
56
|
+
relayDeviceId?: string;
|
|
57
|
+
relayUrl?: string;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/installer/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,UAAU,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/installer/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LicenseInfo, LicenseTier } from "./installer/types.js";
|
|
2
|
+
export interface LicenseStatusResult {
|
|
3
|
+
valid: boolean;
|
|
4
|
+
tier: LicenseTier;
|
|
5
|
+
email?: string;
|
|
6
|
+
expiresAt?: number;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function verifyTokenWithBackend(token: string): Promise<LicenseStatusResult>;
|
|
10
|
+
export declare function verifyLicenseInfo(license: LicenseInfo): Promise<LicenseStatusResult>;
|
|
11
|
+
export declare function startLicenseVerificationWatcher(getToken: () => string | undefined, onInvalid: (result: LicenseStatusResult) => void): () => void;
|
|
12
|
+
//# sourceMappingURL=license-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-check.d.ts","sourceRoot":"","sources":["../src/license-check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMrE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,CAAC,CAyC9B;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,mBAAmB,CAAC,CAM9B;AAID,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,MAAM,GAAG,SAAS,EAClC,SAAS,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,GAC/C,MAAM,IAAI,CAeZ"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const LICENSE_API_URL = process.env.MDB_LICENSE_API_URL ??
|
|
2
|
+
"http://localhost:3001/api/v1";
|
|
3
|
+
export async function verifyTokenWithBackend(token) {
|
|
4
|
+
try {
|
|
5
|
+
const response = await fetch(`${LICENSE_API_URL}/license/status`, {
|
|
6
|
+
method: "POST",
|
|
7
|
+
headers: {
|
|
8
|
+
"Content-Type": "application/json",
|
|
9
|
+
Authorization: `Bearer ${token}`,
|
|
10
|
+
},
|
|
11
|
+
body: JSON.stringify({ token }),
|
|
12
|
+
});
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
const data = (await response.json());
|
|
15
|
+
return {
|
|
16
|
+
valid: false,
|
|
17
|
+
tier: data.tier ?? "free",
|
|
18
|
+
error: data.error ?? `Verification failed (${response.status})`,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const data = (await response.json());
|
|
22
|
+
return {
|
|
23
|
+
valid: data.valid,
|
|
24
|
+
tier: data.tier ?? "free",
|
|
25
|
+
email: data.email,
|
|
26
|
+
expiresAt: data.expires_at,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
const message = error instanceof Error ? error.message : "Network error";
|
|
31
|
+
return {
|
|
32
|
+
valid: false,
|
|
33
|
+
tier: "free",
|
|
34
|
+
error: message,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function verifyLicenseInfo(license) {
|
|
39
|
+
if (license.tier !== "pro" || !license.token) {
|
|
40
|
+
return { valid: license.tier === "pro", tier: license.tier };
|
|
41
|
+
}
|
|
42
|
+
return verifyTokenWithBackend(license.token);
|
|
43
|
+
}
|
|
44
|
+
const VERIFY_INTERVAL_MS = 60 * 60 * 1000;
|
|
45
|
+
export function startLicenseVerificationWatcher(getToken, onInvalid) {
|
|
46
|
+
const interval = setInterval(() => {
|
|
47
|
+
const token = getToken();
|
|
48
|
+
if (!token) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
void verifyTokenWithBackend(token).then((result) => {
|
|
52
|
+
if (!result.valid) {
|
|
53
|
+
onInvalid(result);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}, VERIFY_INTERVAL_MS);
|
|
57
|
+
return () => clearInterval(interval);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=license-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-check.js","sourceRoot":"","sources":["../src/license-check.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GACnB,OAAO,CAAC,GAAG,CAAC,mBAAmB;IAC/B,8BAA8B,CAAC;AAUjC,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,eAAe,iBAAiB,EAAE;YAChE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;SAChC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2C,CAAC;YAC/E,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,MAAM;gBACzB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,wBAAwB,QAAQ,CAAC,MAAM,GAAG;aAChE,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAKlC,CAAC;QAEF,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,MAAM;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,UAAU;SAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,OAAO;SACf,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAoB;IAEpB,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC7C,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;IAC/D,CAAC;IAED,OAAO,sBAAsB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C,MAAM,UAAU,+BAA+B,CAC7C,QAAkC,EAClC,SAAgD;IAEhD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;QAChC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QAED,KAAK,sBAAsB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACjD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAClB,SAAS,CAAC,MAAM,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAEvB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type LicenseStatusResult } from "./license-check.js";
|
|
2
|
+
export interface LicenseGuardOptions {
|
|
3
|
+
/** When true, destructive tools are allowed without a license (dev only). */
|
|
4
|
+
skipCheck?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function getPurchaseUrl(): string;
|
|
7
|
+
export declare function licenseRequiredMessage(): string;
|
|
8
|
+
export declare function isProLicenseActive(options?: LicenseGuardOptions): Promise<boolean>;
|
|
9
|
+
export declare function invalidateLicenseCache(): void;
|
|
10
|
+
export declare function requireProLicense(options?: LicenseGuardOptions): Promise<void>;
|
|
11
|
+
export declare function getLicenseStatus(): Promise<LicenseStatusResult & {
|
|
12
|
+
purchaseUrl: string;
|
|
13
|
+
}>;
|
|
14
|
+
//# sourceMappingURL=license-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-guard.d.ts","sourceRoot":"","sources":["../src/license-guard.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAMD,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAG7C;AAED,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAa/F"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { APP_DOMAIN } from "./brand.js";
|
|
2
|
+
import { loadCachedLicense } from "./installer/license.js";
|
|
3
|
+
import { verifyLicenseInfo, } from "./license-check.js";
|
|
4
|
+
let cachedProValid = null;
|
|
5
|
+
let cachedProCheckedAt = 0;
|
|
6
|
+
const CACHE_TTL_MS = 60_000;
|
|
7
|
+
export function getPurchaseUrl() {
|
|
8
|
+
const appUrl = process.env.MDB_APP_URL ?? process.env.NEXT_PUBLIC_APP_URL ?? `https://${APP_DOMAIN}`;
|
|
9
|
+
return `${appUrl.replace(/\/$/, "")}/signup?redirect=checkout`;
|
|
10
|
+
}
|
|
11
|
+
export function licenseRequiredMessage() {
|
|
12
|
+
return `Pro license required. Purchase at ${getPurchaseUrl()}`;
|
|
13
|
+
}
|
|
14
|
+
export async function isProLicenseActive(options = {}) {
|
|
15
|
+
if (options.skipCheck || process.env.MDB_SKIP_LICENSE_CHECK === "1") {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
if (cachedProValid !== null && now - cachedProCheckedAt < CACHE_TTL_MS) {
|
|
20
|
+
return cachedProValid;
|
|
21
|
+
}
|
|
22
|
+
const license = await loadCachedLicense();
|
|
23
|
+
if (!license || license.tier !== "pro") {
|
|
24
|
+
cachedProValid = false;
|
|
25
|
+
cachedProCheckedAt = now;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const status = await verifyLicenseInfo(license);
|
|
29
|
+
cachedProValid = status.valid && status.tier === "pro";
|
|
30
|
+
cachedProCheckedAt = now;
|
|
31
|
+
return cachedProValid;
|
|
32
|
+
}
|
|
33
|
+
export function invalidateLicenseCache() {
|
|
34
|
+
cachedProValid = null;
|
|
35
|
+
cachedProCheckedAt = 0;
|
|
36
|
+
}
|
|
37
|
+
export async function requireProLicense(options = {}) {
|
|
38
|
+
const active = await isProLicenseActive(options);
|
|
39
|
+
if (!active) {
|
|
40
|
+
throw new Error(licenseRequiredMessage());
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export async function getLicenseStatus() {
|
|
44
|
+
const license = await loadCachedLicense();
|
|
45
|
+
if (!license) {
|
|
46
|
+
return {
|
|
47
|
+
valid: false,
|
|
48
|
+
tier: "free",
|
|
49
|
+
error: "No license found",
|
|
50
|
+
purchaseUrl: getPurchaseUrl(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const status = await verifyLicenseInfo(license);
|
|
54
|
+
return { ...status, purchaseUrl: getPurchaseUrl() };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=license-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-guard.js","sourceRoot":"","sources":["../src/license-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EACL,iBAAiB,GAElB,MAAM,oBAAoB,CAAC;AAO5B,IAAI,cAAc,GAAmB,IAAI,CAAC;AAC1C,IAAI,kBAAkB,GAAG,CAAC,CAAC;AAC3B,MAAM,YAAY,GAAG,MAAM,CAAC;AAE5B,MAAM,UAAU,cAAc;IAC5B,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,WAAW,UAAU,EAAE,CAAC;IACxF,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,2BAA2B,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,qCAAqC,cAAc,EAAE,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAA+B,EAAE;IAEjC,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,GAAG,EAAE,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,cAAc,KAAK,IAAI,IAAI,GAAG,GAAG,kBAAkB,GAAG,YAAY,EAAE,CAAC;QACvE,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC1C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACvC,cAAc,GAAG,KAAK,CAAC;QACvB,kBAAkB,GAAG,GAAG,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;IACvD,kBAAkB,GAAG,GAAG,CAAC;IACzB,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,cAAc,GAAG,IAAI,CAAC;IACtB,kBAAkB,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAA+B,EAAE;IAEjC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,cAAc,EAAE;SAC9B,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-guard.test.d.ts","sourceRoot":"","sources":["../src/license-guard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
2
|
+
vi.mock("./installer/license.js", () => ({
|
|
3
|
+
loadCachedLicense: vi.fn(),
|
|
4
|
+
}));
|
|
5
|
+
vi.mock("./license-check.js", () => ({
|
|
6
|
+
verifyLicenseInfo: vi.fn(),
|
|
7
|
+
}));
|
|
8
|
+
import { loadCachedLicense } from "./installer/license.js";
|
|
9
|
+
import { verifyLicenseInfo } from "./license-check.js";
|
|
10
|
+
import { isProLicenseActive, invalidateLicenseCache } from "./license-guard.js";
|
|
11
|
+
describe("license-guard", () => {
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
invalidateLicenseCache();
|
|
14
|
+
vi.mocked(loadCachedLicense).mockReset();
|
|
15
|
+
vi.mocked(verifyLicenseInfo).mockReset();
|
|
16
|
+
});
|
|
17
|
+
it("returns false without cached license", async () => {
|
|
18
|
+
vi.mocked(loadCachedLicense).mockResolvedValue(null);
|
|
19
|
+
await expect(isProLicenseActive()).resolves.toBe(false);
|
|
20
|
+
});
|
|
21
|
+
it("returns true for valid pro license", async () => {
|
|
22
|
+
vi.mocked(loadCachedLicense).mockResolvedValue({
|
|
23
|
+
tier: "pro",
|
|
24
|
+
method: "browser",
|
|
25
|
+
token: "token",
|
|
26
|
+
});
|
|
27
|
+
vi.mocked(verifyLicenseInfo).mockResolvedValue({
|
|
28
|
+
valid: true,
|
|
29
|
+
tier: "pro",
|
|
30
|
+
});
|
|
31
|
+
await expect(isProLicenseActive()).resolves.toBe(true);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=license-guard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-guard.test.js","sourceRoot":"","sources":["../src/license-guard.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE;CAC3B,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;IACnC,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE;CAC3B,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEhF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,UAAU,CAAC,GAAG,EAAE;QACd,sBAAsB,EAAE,CAAC;QACzB,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,SAAS,EAAE,CAAC;QACzC,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,SAAS,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,iBAAiB,CAAC;YAC7C,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,SAAS;YACjB,KAAK,EAAE,OAAO;SACf,CAAC,CAAC;QACH,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,iBAAiB,CAAC;YAC7C,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface RelayClientConfig {
|
|
2
|
+
relayUrl: string;
|
|
3
|
+
deviceId: string;
|
|
4
|
+
deviceToken: string;
|
|
5
|
+
localPort: number;
|
|
6
|
+
onLog?: (message: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare class RelayClient {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private ws;
|
|
11
|
+
private reconnectDelayMs;
|
|
12
|
+
private readonly maxReconnectDelayMs;
|
|
13
|
+
private stopped;
|
|
14
|
+
private heartbeatTimer;
|
|
15
|
+
constructor(config: RelayClientConfig);
|
|
16
|
+
start(): void;
|
|
17
|
+
stop(): void;
|
|
18
|
+
private log;
|
|
19
|
+
private connectUrl;
|
|
20
|
+
private connect;
|
|
21
|
+
private scheduleReconnect;
|
|
22
|
+
private startHeartbeat;
|
|
23
|
+
private stopHeartbeat;
|
|
24
|
+
private send;
|
|
25
|
+
private handleMessage;
|
|
26
|
+
private localOrigin;
|
|
27
|
+
private handleHttpBridge;
|
|
28
|
+
private handleSseBridge;
|
|
29
|
+
}
|
|
30
|
+
export declare function loadRelayConfigFromEnv(): RelayClientConfig | null;
|
|
31
|
+
export declare function startRelayClientFromEnv(onLog?: (message: string) => void): RelayClient | null;
|
|
32
|
+
//# sourceMappingURL=relay-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-client.d.ts","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAGD,qBAAa,WAAW;IAOV,OAAO,CAAC,QAAQ,CAAC,MAAM;IANnC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAA+C;gBAExC,MAAM,EAAE,iBAAiB;IAEtD,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI;IAUZ,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,UAAU;YASJ,OAAO;IAwCrB,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,IAAI;YAME,aAAa;IAkB3B,OAAO,CAAC,WAAW;YAIL,gBAAgB;YAgEhB,eAAe;CAqD9B;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,GAAG,IAAI,CAqBjE;AAED,wBAAgB,uBAAuB,CACrC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAChC,WAAW,GAAG,IAAI,CASpB"}
|