@lasso-ai/cli 1.4.0 → 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.
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export declare const TLS_KEY_FILE: string;
|
|
2
2
|
export declare const TLS_CERT_FILE: string;
|
|
3
|
-
export declare function ensureHostCertificate(): {
|
|
3
|
+
export declare function ensureHostCertificate(onProgress?: (message: string) => void): Promise<{
|
|
4
4
|
ok: boolean;
|
|
5
5
|
trusted: boolean;
|
|
6
6
|
error?: string;
|
|
7
|
-
}
|
|
7
|
+
}>;
|
|
8
8
|
export declare function hostCertificateStatus(): {
|
|
9
9
|
present: boolean;
|
|
10
10
|
certificate: string;
|
|
11
11
|
key: string;
|
|
12
|
+
trusted: boolean;
|
|
12
13
|
};
|
|
@@ -10,27 +10,238 @@ 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");
|
|
16
18
|
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
|
-
function
|
|
20
|
-
|
|
21
|
-
if (hasCertificate())
|
|
22
|
-
return { ok: true, trusted: false };
|
|
21
|
+
function isMkcertInstalled() {
|
|
22
|
+
// Check system PATH first
|
|
23
23
|
try {
|
|
24
|
-
(0, node_child_process_1.execFileSync)("mkcert", ["-
|
|
25
|
-
|
|
26
|
-
node_fs_1.default.chmodSync(exports.TLS_KEY_FILE, 0o600);
|
|
27
|
-
return { ok: true, trusted: true };
|
|
24
|
+
(0, node_child_process_1.execFileSync)("mkcert", ["-version"], { stdio: "ignore" });
|
|
25
|
+
return true;
|
|
28
26
|
}
|
|
29
27
|
catch {
|
|
30
|
-
//
|
|
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 { }
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
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
|
+
}
|
|
83
|
+
return new Promise((resolve) => {
|
|
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}` });
|
|
93
|
+
}
|
|
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 };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
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 };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
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) {
|
|
175
|
+
(0, node_child_process_1.execFileSync)("mkcert", ["-install"], { stdio: "ignore" });
|
|
176
|
+
console.log("[Lasso] ✓ mkcert installed and CA configured");
|
|
177
|
+
return { ok: true };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
console.log("[Lasso] Package manager not available, trying direct download...");
|
|
182
|
+
}
|
|
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" };
|
|
31
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
|
+
}
|
|
211
|
+
}
|
|
212
|
+
async function ensureHostCertificate(onProgress) {
|
|
213
|
+
node_fs_1.default.mkdirSync(paths_1.HOST_DIR, { recursive: true, mode: 0o700 });
|
|
214
|
+
if (hasCertificate()) {
|
|
215
|
+
const certStatus = hostCertificateStatus();
|
|
216
|
+
return { ok: true, trusted: certStatus.trusted };
|
|
217
|
+
}
|
|
218
|
+
onProgress?.("Generating SSL certificate...");
|
|
219
|
+
// Try mkcert first - it creates system-trusted certificates
|
|
220
|
+
if (!isMkcertInstalled()) {
|
|
221
|
+
onProgress?.("mkcert not found, installing...");
|
|
222
|
+
const installResult = await installMkcert();
|
|
223
|
+
if (!installResult.ok) {
|
|
224
|
+
console.warn(`[Lasso] ${installResult.error}`);
|
|
225
|
+
console.warn("[Lasso] Falling back to OpenSSL (certificate will show as not secure)");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (isMkcertInstalled()) {
|
|
229
|
+
try {
|
|
230
|
+
onProgress?.("Creating trusted certificate with mkcert...");
|
|
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" });
|
|
233
|
+
node_fs_1.default.chmodSync(exports.TLS_KEY_FILE, 0o600);
|
|
234
|
+
onProgress?.("✓ SSL certificate ready (trusted)");
|
|
235
|
+
return { ok: true, trusted: true };
|
|
236
|
+
}
|
|
237
|
+
catch (mkcertError) {
|
|
238
|
+
console.warn("[Lasso] mkcert failed, falling back to OpenSSL");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Fallback to OpenSSL - creates self-signed certificate (not trusted by browsers)
|
|
32
242
|
const configFile = node_path_1.default.join(node_os_1.default.tmpdir(), `lasso-host-${process.pid}.cnf`);
|
|
33
243
|
try {
|
|
244
|
+
onProgress?.("Creating self-signed certificate with OpenSSL...");
|
|
34
245
|
node_fs_1.default.writeFileSync(configFile, [
|
|
35
246
|
"[req]", "distinguished_name = req_distinguished_name", "x509_extensions = v3_req", "prompt = no",
|
|
36
247
|
"[req_distinguished_name]", "CN = *.lasso", "[v3_req]",
|
|
@@ -38,6 +249,7 @@ function ensureHostCertificate() {
|
|
|
38
249
|
].join("\n"), { mode: 0o600 });
|
|
39
250
|
(0, node_child_process_1.execFileSync)("openssl", ["req", "-x509", "-nodes", "-newkey", "rsa:2048", "-keyout", exports.TLS_KEY_FILE, "-out", exports.TLS_CERT_FILE, "-days", "825", "-config", configFile], { stdio: "ignore" });
|
|
40
251
|
node_fs_1.default.chmodSync(exports.TLS_KEY_FILE, 0o600);
|
|
252
|
+
onProgress?.("✓ SSL certificate ready (self-signed)");
|
|
41
253
|
return { ok: true, trusted: false };
|
|
42
254
|
}
|
|
43
255
|
catch (error) {
|
|
@@ -48,5 +260,17 @@ function ensureHostCertificate() {
|
|
|
48
260
|
}
|
|
49
261
|
}
|
|
50
262
|
function hostCertificateStatus() {
|
|
51
|
-
|
|
263
|
+
// Check if certificate was created by mkcert (trusted) or OpenSSL (self-signed)
|
|
264
|
+
let trusted = false;
|
|
265
|
+
if (hasCertificate()) {
|
|
266
|
+
try {
|
|
267
|
+
const certContent = node_fs_1.default.readFileSync(exports.TLS_CERT_FILE, "utf8");
|
|
268
|
+
// mkcert certificates include "mkcert" in the issuer
|
|
269
|
+
trusted = certContent.includes("mkcert");
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
// If we can't read the cert, assume not trusted
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return { present: hasCertificate(), certificate: exports.TLS_CERT_FILE, key: exports.TLS_KEY_FILE, trusted };
|
|
52
276
|
}
|
package/dist/cli/host/daemon.js
CHANGED
|
@@ -60,10 +60,10 @@ class LassoHost {
|
|
|
60
60
|
proxies = new Map();
|
|
61
61
|
constructor(opts) {
|
|
62
62
|
this.opts = opts;
|
|
63
|
-
this.server = node_http_1.default.createServer((req, res) => this.handleRequest(req, res));
|
|
64
|
-
this.server.on("upgrade", (req, socket, head) => this.handleUpgrade(req, socket, head));
|
|
65
|
-
this.secureServer = node_https_1.default.createServer({}, (req, res) => this.handleRequest(req, res));
|
|
66
|
-
this.secureServer.on("upgrade", (req, socket, head) => this.handleUpgrade(req, socket, head));
|
|
63
|
+
this.server = node_http_1.default.createServer((req, res) => this.handleRequest(req, res, false));
|
|
64
|
+
this.server.on("upgrade", (req, socket, head) => this.handleUpgrade(req, socket, head, false));
|
|
65
|
+
this.secureServer = node_https_1.default.createServer({}, (req, res) => this.handleRequest(req, res, true));
|
|
66
|
+
this.secureServer.on("upgrade", (req, socket, head) => this.handleUpgrade(req, socket, head, true));
|
|
67
67
|
this.resolver = (0, dns_1.createDomainResolver)();
|
|
68
68
|
this.registry = (0, registry_1.loadRegistry)();
|
|
69
69
|
for (const domain of Object.keys(this.registry))
|
|
@@ -246,6 +246,7 @@ class LassoHost {
|
|
|
246
246
|
];
|
|
247
247
|
}
|
|
248
248
|
health(res) {
|
|
249
|
+
const certStatus = (0, certificates_1.hostCertificateStatus)();
|
|
249
250
|
writeJson(res, 200, {
|
|
250
251
|
ok: true,
|
|
251
252
|
service: exports.SERVICE_NAME,
|
|
@@ -256,14 +257,15 @@ class LassoHost {
|
|
|
256
257
|
dnsPort: this.dnsHandle?.port ?? null,
|
|
257
258
|
proxyPort: this.opts.proxyPort,
|
|
258
259
|
httpsPort: this.opts.httpsPort,
|
|
259
|
-
https:
|
|
260
|
+
https: certStatus.present,
|
|
261
|
+
trusted: certStatus.trusted,
|
|
260
262
|
running: this.running.size,
|
|
261
263
|
registered: Object.keys(this.registry).length,
|
|
262
264
|
projects: this.projectList(),
|
|
263
265
|
});
|
|
264
266
|
}
|
|
265
267
|
// ---- request handling --------------------------------------------
|
|
266
|
-
handleRequest(req, res) {
|
|
268
|
+
handleRequest(req, res, isSecure = false) {
|
|
267
269
|
const url = req.url || "/";
|
|
268
270
|
const route = this.routes().find((r) => r.route === `${req.method} ${url}`);
|
|
269
271
|
if (route) {
|
|
@@ -283,6 +285,13 @@ class LassoHost {
|
|
|
283
285
|
writeJson(res, 404, { ok: false, error: "Lasso Host only proxies *.lasso domains.", host: req.headers.host });
|
|
284
286
|
return;
|
|
285
287
|
}
|
|
288
|
+
// Redirect HTTP to HTTPS for .lasso domains
|
|
289
|
+
if (!isSecure) {
|
|
290
|
+
const httpsUrl = `https://${hostname}${url}`;
|
|
291
|
+
res.writeHead(301, { Location: httpsUrl });
|
|
292
|
+
res.end();
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
286
295
|
void this.proxyToProject(hostname, req, res);
|
|
287
296
|
}
|
|
288
297
|
async proxyToProject(hostname, req, res) {
|
|
@@ -309,13 +318,20 @@ class LassoHost {
|
|
|
309
318
|
res.destroy();
|
|
310
319
|
});
|
|
311
320
|
}
|
|
312
|
-
handleUpgrade(req, socket, head) {
|
|
321
|
+
handleUpgrade(req, socket, head, isSecure) {
|
|
313
322
|
const hostname = (0, paths_1.domainOf)(req.headers.host || "");
|
|
314
323
|
if (!(0, paths_1.isLassoDomain)(hostname)) {
|
|
315
324
|
socket.write("HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n");
|
|
316
325
|
socket.destroy();
|
|
317
326
|
return;
|
|
318
327
|
}
|
|
328
|
+
// Redirect HTTP WebSocket upgrades to HTTPS
|
|
329
|
+
if (!isSecure) {
|
|
330
|
+
const wsUrl = `wss://${hostname}${req.url}`;
|
|
331
|
+
socket.write(`HTTP/1.1 301 Moved Permanently\r\nLocation: ${wsUrl}\r\nConnection: close\r\n\r\n`);
|
|
332
|
+
socket.destroy();
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
319
335
|
void (async () => {
|
|
320
336
|
let runtime;
|
|
321
337
|
try {
|
|
@@ -345,7 +361,7 @@ class LassoHost {
|
|
|
345
361
|
this.dnsHandle = null;
|
|
346
362
|
this.log(`dns server failed to start on ${this.opts.dnsPort}: ${line(error)}`);
|
|
347
363
|
}
|
|
348
|
-
const certificate = (0, certificates_1.ensureHostCertificate)();
|
|
364
|
+
const certificate = await (0, certificates_1.ensureHostCertificate)((message) => this.log(message));
|
|
349
365
|
if (!certificate.ok)
|
|
350
366
|
this.log(`https certificate unavailable: ${certificate.error}`);
|
|
351
367
|
else {
|
package/dist/cli/index.js
CHANGED
|
@@ -147,7 +147,7 @@ const daemon = program.command("daemon [action]")
|
|
|
147
147
|
console.log(chalk_1.default.bold("Lasso Host"));
|
|
148
148
|
console.log(chalk_1.default.dim(` Status: ${report.running ? chalk_1.default.green("running") + (report.pid ? ` (pid ${report.pid})` : "") : chalk_1.default.red("not running")}`));
|
|
149
149
|
console.log(chalk_1.default.dim(` Proxy port: ${(0, paths_1.hostProxyPort)(env)}`));
|
|
150
|
-
console.log(chalk_1.default.dim(` HTTPS port: ${(0, paths_1.hostHttpsPort)(env)}${report.health?.https ? chalk_1.default.green(" (
|
|
150
|
+
console.log(chalk_1.default.dim(` HTTPS port: ${(0, paths_1.hostHttpsPort)(env)}${report.health?.https ? (report.health.trusted ? chalk_1.default.green(" (trusted)") : chalk_1.default.yellow(" (self-signed)")) : chalk_1.default.yellow(" (certificate unavailable)")}`));
|
|
151
151
|
console.log(chalk_1.default.dim(` DNS port: ${(0, paths_1.hostDnsPort)(env)}`));
|
|
152
152
|
console.log(chalk_1.default.dim(` Domain resolution: ${report.resolver.installed ? chalk_1.default.green("configured") : chalk_1.default.yellow("not configured")} — ${report.resolver.detail}`));
|
|
153
153
|
console.log(chalk_1.default.dim(` Automatic startup: ${report.autoStart ? chalk_1.default.green("enabled (LaunchAgent)") : chalk_1.default.yellow("disabled")}`));
|
package/package.json
CHANGED