@lasso-ai/cli 1.4.1 → 1.4.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/cli/host/certificates.js +174 -49
- package/package.json +1 -1
|
@@ -10,6 +10,8 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
10
10
|
const node_os_1 = __importDefault(require("node:os"));
|
|
11
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
12
|
const node_child_process_1 = require("node:child_process");
|
|
13
|
+
const node_https_1 = __importDefault(require("node:https"));
|
|
14
|
+
const node_http_1 = __importDefault(require("node:http"));
|
|
13
15
|
const paths_1 = require("./paths");
|
|
14
16
|
exports.TLS_KEY_FILE = node_path_1.default.join(paths_1.HOST_DIR, "host.key");
|
|
15
17
|
exports.TLS_CERT_FILE = node_path_1.default.join(paths_1.HOST_DIR, "host.crt");
|
|
@@ -17,73 +19,195 @@ function hasCertificate() {
|
|
|
17
19
|
return node_fs_1.default.existsSync(exports.TLS_KEY_FILE) && node_fs_1.default.existsSync(exports.TLS_CERT_FILE);
|
|
18
20
|
}
|
|
19
21
|
function isMkcertInstalled() {
|
|
22
|
+
// Check system PATH first
|
|
20
23
|
try {
|
|
21
24
|
(0, node_child_process_1.execFileSync)("mkcert", ["-version"], { stdio: "ignore" });
|
|
22
25
|
return true;
|
|
23
26
|
}
|
|
24
27
|
catch {
|
|
28
|
+
// Check local installation
|
|
29
|
+
try {
|
|
30
|
+
const localMkcert = node_path_1.default.join(node_os_1.default.homedir(), ".lasso", "bin", "mkcert");
|
|
31
|
+
if (node_fs_1.default.existsSync(localMkcert)) {
|
|
32
|
+
(0, node_child_process_1.execFileSync)(localMkcert, ["-version"], { stdio: "ignore" });
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch { }
|
|
25
37
|
return false;
|
|
26
38
|
}
|
|
27
39
|
}
|
|
28
|
-
|
|
40
|
+
function getMkcertPath() {
|
|
41
|
+
// Check local installation first
|
|
42
|
+
const localMkcert = node_path_1.default.join(node_os_1.default.homedir(), ".lasso", "bin", "mkcert");
|
|
43
|
+
if (node_fs_1.default.existsSync(localMkcert)) {
|
|
44
|
+
return localMkcert;
|
|
45
|
+
}
|
|
46
|
+
return "mkcert";
|
|
47
|
+
}
|
|
48
|
+
async function downloadMkcert() {
|
|
49
|
+
const platform = node_os_1.default.platform();
|
|
50
|
+
const arch = node_os_1.default.arch();
|
|
51
|
+
let downloadUrl;
|
|
52
|
+
let binaryName;
|
|
53
|
+
// Determine the correct binary for the platform
|
|
54
|
+
if (platform === "darwin") {
|
|
55
|
+
if (arch === "x64") {
|
|
56
|
+
downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-darwin-amd64";
|
|
57
|
+
binaryName = "mkcert-darwin-amd64";
|
|
58
|
+
}
|
|
59
|
+
else if (arch === "arm64") {
|
|
60
|
+
downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-darwin-arm64";
|
|
61
|
+
binaryName = "mkcert-darwin-arm64";
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return { ok: false, error: `Unsupported architecture: ${arch}` };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (platform === "linux") {
|
|
68
|
+
if (arch === "x64") {
|
|
69
|
+
downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64";
|
|
70
|
+
binaryName = "mkcert-linux-amd64";
|
|
71
|
+
}
|
|
72
|
+
else if (arch === "arm64") {
|
|
73
|
+
downloadUrl = "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-arm64";
|
|
74
|
+
binaryName = "mkcert-linux-arm64";
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return { ok: false, error: `Unsupported architecture: ${arch}` };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
return { ok: false, error: `Unsupported platform: ${platform}` };
|
|
82
|
+
}
|
|
29
83
|
return new Promise((resolve) => {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
84
|
+
const protocol = downloadUrl.startsWith("https") ? node_https_1.default : node_http_1.default;
|
|
85
|
+
const tempDir = node_os_1.default.tmpdir();
|
|
86
|
+
const tempPath = node_path_1.default.join(tempDir, binaryName);
|
|
87
|
+
console.log(`[Lasso] Downloading mkcert from ${downloadUrl}...`);
|
|
88
|
+
const file = node_fs_1.default.createWriteStream(tempPath);
|
|
89
|
+
protocol.get(downloadUrl, (response) => {
|
|
90
|
+
if (response.statusCode !== 200) {
|
|
91
|
+
node_fs_1.default.unlinkSync(tempPath);
|
|
92
|
+
return resolve({ ok: false, error: `Failed to download mkcert: ${response.statusCode}` });
|
|
39
93
|
}
|
|
40
|
-
|
|
41
|
-
|
|
94
|
+
response.pipe(file);
|
|
95
|
+
file.on("finish", () => {
|
|
96
|
+
file.close();
|
|
97
|
+
node_fs_1.default.chmodSync(tempPath, 0o755);
|
|
98
|
+
console.log(`[Lasso] ✓ mkcert downloaded to ${tempPath}`);
|
|
99
|
+
resolve({ ok: true, path: tempPath });
|
|
100
|
+
});
|
|
101
|
+
}).on("error", (error) => {
|
|
102
|
+
node_fs_1.default.unlinkSync(tempPath);
|
|
103
|
+
resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
async function installMkcert() {
|
|
108
|
+
const platform = node_os_1.default.platform();
|
|
109
|
+
// Try package manager first
|
|
110
|
+
if (platform === "darwin") {
|
|
111
|
+
try {
|
|
112
|
+
(0, node_child_process_1.execFileSync)("brew", ["--version"], { stdio: "ignore" });
|
|
113
|
+
console.log("[Lasso] Installing mkcert via Homebrew...");
|
|
114
|
+
const installResult = await new Promise((resolve) => {
|
|
115
|
+
const install = (0, node_child_process_1.spawn)("brew", ["install", "mkcert", "nss"], { stdio: "inherit" });
|
|
116
|
+
install.on("close", (code) => {
|
|
117
|
+
if (code === 0)
|
|
118
|
+
resolve({ ok: true });
|
|
119
|
+
else
|
|
120
|
+
resolve({ ok: false, error: `Homebrew install failed with code ${code}` });
|
|
121
|
+
});
|
|
122
|
+
install.on("error", (error) => {
|
|
123
|
+
resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
if (installResult.ok) {
|
|
127
|
+
(0, node_child_process_1.execFileSync)("mkcert", ["-install"], { stdio: "ignore" });
|
|
128
|
+
console.log("[Lasso] ✓ mkcert installed and CA configured");
|
|
129
|
+
return { ok: true };
|
|
42
130
|
}
|
|
43
131
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
132
|
+
catch {
|
|
133
|
+
console.log("[Lasso] Homebrew not available, trying direct download...");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (platform === "linux") {
|
|
137
|
+
try {
|
|
138
|
+
(0, node_child_process_1.execFileSync)("apt-get", ["--version"], { stdio: "ignore" });
|
|
139
|
+
console.log("[Lasso] Installing mkcert via apt-get...");
|
|
140
|
+
const installResult = await new Promise((resolve) => {
|
|
141
|
+
const install = (0, node_child_process_1.spawn)("sudo", ["apt-get", "install", "-y", "mkcert"], { stdio: "inherit" });
|
|
142
|
+
install.on("close", (code) => {
|
|
143
|
+
if (code === 0)
|
|
144
|
+
resolve({ ok: true });
|
|
145
|
+
else
|
|
146
|
+
resolve({ ok: false, error: `apt-get install failed with code ${code}` });
|
|
147
|
+
});
|
|
148
|
+
install.on("error", (error) => {
|
|
149
|
+
resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
if (installResult.ok) {
|
|
153
|
+
(0, node_child_process_1.execFileSync)("mkcert", ["-install"], { stdio: "ignore" });
|
|
154
|
+
console.log("[Lasso] ✓ mkcert installed and CA configured");
|
|
155
|
+
return { ok: true };
|
|
60
156
|
}
|
|
61
157
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
158
|
+
catch {
|
|
159
|
+
try {
|
|
160
|
+
(0, node_child_process_1.execFileSync)("dnf", ["--version"], { stdio: "ignore" });
|
|
161
|
+
console.log("[Lasso] Installing mkcert via dnf...");
|
|
162
|
+
const installResult = await new Promise((resolve) => {
|
|
163
|
+
const install = (0, node_child_process_1.spawn)("sudo", ["dnf", "install", "-y", "mkcert"], { stdio: "inherit" });
|
|
164
|
+
install.on("close", (code) => {
|
|
165
|
+
if (code === 0)
|
|
166
|
+
resolve({ ok: true });
|
|
167
|
+
else
|
|
168
|
+
resolve({ ok: false, error: `dnf install failed with code ${code}` });
|
|
169
|
+
});
|
|
170
|
+
install.on("error", (error) => {
|
|
171
|
+
resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
if (installResult.ok) {
|
|
71
175
|
(0, node_child_process_1.execFileSync)("mkcert", ["-install"], { stdio: "ignore" });
|
|
72
176
|
console.log("[Lasso] ✓ mkcert installed and CA configured");
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
resolve({ ok: false, error: error instanceof Error ? error.message : String(error) });
|
|
177
|
+
return { ok: true };
|
|
77
178
|
}
|
|
78
179
|
}
|
|
79
|
-
|
|
80
|
-
|
|
180
|
+
catch {
|
|
181
|
+
console.log("[Lasso] Package manager not available, trying direct download...");
|
|
81
182
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Fallback: Download mkcert binary directly from GitHub
|
|
186
|
+
console.log("[Lasso] Downloading mkcert binary from GitHub...");
|
|
187
|
+
const downloadResult = await downloadMkcert();
|
|
188
|
+
if (!downloadResult.ok || !downloadResult.path) {
|
|
189
|
+
return { ok: false, error: downloadResult.error || "Failed to download mkcert binary" };
|
|
190
|
+
}
|
|
191
|
+
// Copy binary to a permanent location
|
|
192
|
+
const binDir = node_path_1.default.join(node_os_1.default.homedir(), ".lasso", "bin");
|
|
193
|
+
node_fs_1.default.mkdirSync(binDir, { recursive: true, mode: 0o755 });
|
|
194
|
+
const mkcertPath = node_path_1.default.join(binDir, "mkcert");
|
|
195
|
+
node_fs_1.default.copyFileSync(downloadResult.path, mkcertPath);
|
|
196
|
+
node_fs_1.default.chmodSync(mkcertPath, 0o755);
|
|
197
|
+
// Clean up temp file
|
|
198
|
+
try {
|
|
199
|
+
node_fs_1.default.unlinkSync(downloadResult.path);
|
|
200
|
+
}
|
|
201
|
+
catch { }
|
|
202
|
+
// Install the local CA using the downloaded binary
|
|
203
|
+
try {
|
|
204
|
+
(0, node_child_process_1.execFileSync)(mkcertPath, ["-install"], { stdio: "inherit" });
|
|
205
|
+
console.log("[Lasso] ✓ mkcert installed and CA configured");
|
|
206
|
+
return { ok: true };
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
210
|
+
}
|
|
87
211
|
}
|
|
88
212
|
async function ensureHostCertificate(onProgress) {
|
|
89
213
|
node_fs_1.default.mkdirSync(paths_1.HOST_DIR, { recursive: true, mode: 0o700 });
|
|
@@ -104,7 +228,8 @@ async function ensureHostCertificate(onProgress) {
|
|
|
104
228
|
if (isMkcertInstalled()) {
|
|
105
229
|
try {
|
|
106
230
|
onProgress?.("Creating trusted certificate with mkcert...");
|
|
107
|
-
|
|
231
|
+
const mkcertPath = getMkcertPath();
|
|
232
|
+
(0, node_child_process_1.execFileSync)(mkcertPath, ["-cert-file", exports.TLS_CERT_FILE, "-key-file", exports.TLS_KEY_FILE, "localhost", "127.0.0.1", "::1", "*.lasso"], { stdio: "ignore" });
|
|
108
233
|
node_fs_1.default.chmodSync(exports.TLS_KEY_FILE, 0o600);
|
|
109
234
|
onProgress?.("✓ SSL certificate ready (trusted)");
|
|
110
235
|
return { ok: true, trusted: true };
|
package/package.json
CHANGED