locadot 1.4.0 → 1.5.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 +49 -5
- package/dist/certs.js +4 -3
- package/dist/constants/index.js +26 -0
- package/dist/constants/template.js +67 -0
- package/dist/core.js +5 -5
- package/dist/index.js +93 -52
- package/dist/lib/cloudflared.js +98 -0
- package/dist/lib/commands.js +55 -12
- package/dist/lib/http.js +64 -0
- package/dist/lib/locadot-file.js +50 -66
- package/dist/proxy.js +139 -0
- package/dist/server.js +90 -93
- package/dist/utils/certs.js +43 -0
- package/dist/utils/file.js +182 -0
- package/dist/utils/logger.js +16 -0
- package/package.json +9 -9
package/dist/lib/locadot-file.js
CHANGED
|
@@ -3,110 +3,92 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
const file_1 = __importDefault(require("../utils/file"));
|
|
7
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
9
|
class locadotFile {
|
|
10
10
|
static async createLockFile(processId) {
|
|
11
|
-
|
|
11
|
+
await file_1.default.writeFileSync("LOCK_FILE", processId);
|
|
12
12
|
}
|
|
13
13
|
static async getProcessId() {
|
|
14
14
|
try {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return pid.toString();
|
|
18
|
-
}
|
|
15
|
+
const lockFile = await file_1.default.readFileSync("LOCK_FILE");
|
|
16
|
+
return parseInt(lockFile).toString();
|
|
19
17
|
}
|
|
20
18
|
catch (err) {
|
|
19
|
+
await file_1.default.removeFileSync("LOCK_FILE");
|
|
21
20
|
return;
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
static async deleteLockFile() {
|
|
25
|
-
|
|
24
|
+
await file_1.default.removeFileSync("LOCK_FILE");
|
|
26
25
|
}
|
|
27
26
|
static async getRegistry() {
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(await file_1.default.readFileSync("REGISTRY_FILE"));
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
logger_1.default.error(error);
|
|
32
|
+
return {};
|
|
30
33
|
}
|
|
31
|
-
return JSON.parse(fs_1.default.readFileSync(constants_1.locadotPath.REGISTRY_FILE, "utf-8"));
|
|
32
34
|
}
|
|
33
35
|
static async addRegistry(domain, port) {
|
|
34
36
|
const registry = await locadotFile.getRegistry();
|
|
35
37
|
registry[domain] = port;
|
|
36
|
-
|
|
38
|
+
file_1.default.writeFileSync("REGISTRY_FILE", JSON.stringify(registry));
|
|
37
39
|
}
|
|
38
40
|
static async removeAllRegistry() {
|
|
39
|
-
|
|
41
|
+
file_1.default.writeFileSync("REGISTRY_FILE", "{}");
|
|
40
42
|
}
|
|
41
43
|
static async updateRegistry(domain, port) {
|
|
42
44
|
const registry = await locadotFile.getRegistry();
|
|
43
45
|
registry[domain] = port;
|
|
44
|
-
|
|
46
|
+
file_1.default.writeFileSync("REGISTRY_FILE", JSON.stringify(registry));
|
|
45
47
|
}
|
|
46
48
|
static async deleteRegistry(domain) {
|
|
47
49
|
const registry = await locadotFile.getRegistry();
|
|
48
50
|
delete registry[domain];
|
|
49
|
-
|
|
51
|
+
file_1.default.writeFileSync("REGISTRY_FILE", JSON.stringify(registry));
|
|
50
52
|
}
|
|
51
53
|
static async watchRegistry(callBackOnChange) {
|
|
52
|
-
return
|
|
53
|
-
if (eventType === "change") {
|
|
54
|
-
this.updateLogs("🔄 Updated domain mappings.");
|
|
55
|
-
callBackOnChange && callBackOnChange();
|
|
56
|
-
}
|
|
57
|
-
});
|
|
54
|
+
return file_1.default.watchFileWithInit("REGISTRY_FILE", () => callBackOnChange?.());
|
|
58
55
|
}
|
|
59
56
|
static async getLogs() {
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
try {
|
|
58
|
+
return await file_1.default.readFileSync("LOGS");
|
|
62
59
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const logs = (await locadotFile.getLogs()).logs || [];
|
|
67
|
-
if (!Array.isArray(logs)) {
|
|
68
|
-
fs_1.default.writeFileSync(constants_1.locadotPath.LOGS, "{}");
|
|
60
|
+
catch (error) {
|
|
61
|
+
file_1.default.removeFileSync("LOGS");
|
|
62
|
+
return "";
|
|
69
63
|
}
|
|
70
|
-
logs.push({
|
|
71
|
-
message,
|
|
72
|
-
timestamp: Date.now(),
|
|
73
|
-
status: status,
|
|
74
|
-
description,
|
|
75
|
-
});
|
|
76
|
-
fs_1.default.writeFileSync(constants_1.locadotPath.LOGS, JSON.stringify({ logs: logs }));
|
|
77
64
|
}
|
|
78
65
|
static async clearLogs() {
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
static async printLogs(log) {
|
|
82
|
-
console[log.status || "log"](`${(0, date_fns_1.format)(log.timestamp, "yyyy-MM-dd HH:mm:ss")}: ${log.message} ${log.description ? "==> " : ""}${log.description ? log.description : ""}\n`);
|
|
66
|
+
file_1.default.writeFileSync("LOGS", "");
|
|
83
67
|
}
|
|
84
68
|
static async watchLogs() {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
catch (error) { }
|
|
101
|
-
});
|
|
69
|
+
file_1.default.tailFile("LOGS");
|
|
70
|
+
}
|
|
71
|
+
static getStartProxyFile() {
|
|
72
|
+
if (process.env.NODE_ENV === "production") {
|
|
73
|
+
const filePath = path_1.default.join(process.cwd(), "core.js");
|
|
74
|
+
return {
|
|
75
|
+
command: "node",
|
|
76
|
+
path: [filePath],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const filePath = path_1.default.join(process.cwd(), "dist", "core.js");
|
|
80
|
+
return {
|
|
81
|
+
command: "node",
|
|
82
|
+
path: [filePath],
|
|
83
|
+
};
|
|
102
84
|
}
|
|
103
85
|
static async destroy(watcher) {
|
|
104
86
|
try {
|
|
105
87
|
const pid = await locadotFile.getProcessId();
|
|
106
|
-
locadotFile.deleteLockFile();
|
|
107
|
-
locadotFile.removeAllRegistry();
|
|
108
|
-
locadotFile.clearLogs();
|
|
109
|
-
watcher?.close();
|
|
88
|
+
await locadotFile.deleteLockFile();
|
|
89
|
+
await locadotFile.removeAllRegistry();
|
|
90
|
+
await locadotFile.clearLogs();
|
|
91
|
+
await watcher?.close();
|
|
110
92
|
if (pid) {
|
|
111
93
|
process.kill(parseInt(pid));
|
|
112
94
|
}
|
|
@@ -116,14 +98,16 @@ class locadotFile {
|
|
|
116
98
|
static async softDestroy(watcher) {
|
|
117
99
|
try {
|
|
118
100
|
const pid = await locadotFile.getProcessId();
|
|
119
|
-
locadotFile.deleteLockFile();
|
|
120
|
-
locadotFile.clearLogs();
|
|
121
|
-
watcher?.close();
|
|
101
|
+
await locadotFile.deleteLockFile();
|
|
102
|
+
await locadotFile.clearLogs();
|
|
103
|
+
await watcher?.close();
|
|
122
104
|
if (pid) {
|
|
123
105
|
process.kill(parseInt(pid));
|
|
124
106
|
}
|
|
125
107
|
}
|
|
126
|
-
catch (error) {
|
|
108
|
+
catch (error) {
|
|
109
|
+
logger_1.default.error(error);
|
|
110
|
+
}
|
|
127
111
|
}
|
|
128
112
|
}
|
|
129
113
|
exports.default = locadotFile;
|
package/dist/proxy.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const http_proxy_1 = __importDefault(require("http-proxy"));
|
|
7
|
+
const certs_1 = require("./utils/certs");
|
|
8
|
+
const https_1 = __importDefault(require("https"));
|
|
9
|
+
const http_1 = __importDefault(require("http"));
|
|
10
|
+
const locadot_file_1 = __importDefault(require("./lib/locadot-file"));
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const file_1 = __importDefault(require("./utils/file"));
|
|
13
|
+
const logger_1 = __importDefault(require("./utils/logger"));
|
|
14
|
+
const http_2 = __importDefault(require("./lib/http"));
|
|
15
|
+
class ProxyHandler {
|
|
16
|
+
async startCentralProxy() {
|
|
17
|
+
try {
|
|
18
|
+
let domainMap = await locadot_file_1.default.getRegistry();
|
|
19
|
+
const proxy = http_proxy_1.default.createProxyServer({});
|
|
20
|
+
const defaultCert = await (0, certs_1.createSSL)("localhost");
|
|
21
|
+
const watcher = await locadot_file_1.default.watchRegistry(async () => {
|
|
22
|
+
logger_1.default.info("🔄 Updated domain mapping");
|
|
23
|
+
domainMap = await locadot_file_1.default.getRegistry();
|
|
24
|
+
});
|
|
25
|
+
process.on("SIGINT", async (err) => {
|
|
26
|
+
logger_1.default.error("🛑 Proxy stopped. Proxy soft destroyed as process SIGINT", err);
|
|
27
|
+
await locadot_file_1.default.softDestroy(watcher);
|
|
28
|
+
});
|
|
29
|
+
process.on("SIGTERM", async (err) => {
|
|
30
|
+
logger_1.default.error("🛑 Proxy stopped. Proxy soft destroyed as process SIGTERM", err);
|
|
31
|
+
await locadot_file_1.default.softDestroy(watcher);
|
|
32
|
+
});
|
|
33
|
+
process.on("exit", (code, signal) => {
|
|
34
|
+
logger_1.default.error(`Process exited with error ${code} and signal ${signal}`);
|
|
35
|
+
locadot_file_1.default.softDestroy(watcher);
|
|
36
|
+
});
|
|
37
|
+
const httpsServer = https_1.default.createServer(defaultCert, (req, res) => {
|
|
38
|
+
http_2.default.requestHandler(req, res, proxy, domainMap);
|
|
39
|
+
});
|
|
40
|
+
const httpServer = http_1.default.createServer((req, res) => {
|
|
41
|
+
http_2.default.requestHandler(req, res, proxy, domainMap);
|
|
42
|
+
});
|
|
43
|
+
httpsServer.listen(443, () => {
|
|
44
|
+
logger_1.default.info("🛜 HTTPS proxy running on port 443");
|
|
45
|
+
});
|
|
46
|
+
httpsServer.on("upgrade", (req, res, head) => {
|
|
47
|
+
http_2.default.requestUpgrade(req, res, head, proxy, domainMap);
|
|
48
|
+
});
|
|
49
|
+
httpServer.listen(80, () => {
|
|
50
|
+
logger_1.default.info("🛜 HTTP proxy running on port 80");
|
|
51
|
+
});
|
|
52
|
+
httpServer.on("upgrade", (req, socket, head) => {
|
|
53
|
+
http_2.default.requestUpgrade(req, socket, head, proxy, domainMap);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
logger_1.default.error("Failed to start central proxy", error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
static async isProxyRunning() {
|
|
61
|
+
try {
|
|
62
|
+
const pid = Number(await locadot_file_1.default.getProcessId());
|
|
63
|
+
if (!pid || isNaN(pid)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
process.kill(pid, 0);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async startProxy() {
|
|
74
|
+
try {
|
|
75
|
+
if (await ProxyHandler.isProxyRunning()) {
|
|
76
|
+
logger_1.default.error("Proxy is already running");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const command = locadot_file_1.default.getStartProxyFile();
|
|
80
|
+
const proxyProcess = (0, child_process_1.spawn)(command.command, command.path, {
|
|
81
|
+
detached: true,
|
|
82
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
83
|
+
});
|
|
84
|
+
const logStream = file_1.default.writeFileStream("LOGS", true);
|
|
85
|
+
proxyProcess.stderr.pipe(logStream);
|
|
86
|
+
proxyProcess.on("error", (err) => {
|
|
87
|
+
console.error("Failed to start child process:", err);
|
|
88
|
+
});
|
|
89
|
+
if (!proxyProcess.pid) {
|
|
90
|
+
logger_1.default.error("❌ Central proxy failed to start");
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
locadot_file_1.default.createLockFile(proxyProcess.pid?.toString());
|
|
95
|
+
}
|
|
96
|
+
proxyProcess.unref();
|
|
97
|
+
logger_1.default.info("🚀 Central proxy started in background.");
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
logger_1.default.error("Failed to start central proxy", error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async addProxy(domain, port) {
|
|
104
|
+
if (!(await ProxyHandler.isProxyRunning())) {
|
|
105
|
+
await this.startProxy();
|
|
106
|
+
}
|
|
107
|
+
let registry = await locadot_file_1.default.getRegistry();
|
|
108
|
+
if (registry[domain]) {
|
|
109
|
+
console.error(`❌ ${domain} already mapped to port ${registry[domain]} use update instead.`);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
await locadot_file_1.default.addRegistry(domain, port);
|
|
113
|
+
logger_1.default.info(`✅ ${domain} => http://localhost:${port}`);
|
|
114
|
+
}
|
|
115
|
+
async removeProxy(domain) {
|
|
116
|
+
if (!(await ProxyHandler.isProxyRunning())) {
|
|
117
|
+
await this.startProxy();
|
|
118
|
+
}
|
|
119
|
+
await locadot_file_1.default.deleteRegistry(domain);
|
|
120
|
+
}
|
|
121
|
+
async updateProxy(domain, port) {
|
|
122
|
+
if (!(await ProxyHandler.isProxyRunning())) {
|
|
123
|
+
await this.startProxy();
|
|
124
|
+
}
|
|
125
|
+
await locadot_file_1.default.updateRegistry(domain, port);
|
|
126
|
+
}
|
|
127
|
+
async stopProxy() {
|
|
128
|
+
await locadot_file_1.default.softDestroy();
|
|
129
|
+
}
|
|
130
|
+
async killProxy() {
|
|
131
|
+
await locadot_file_1.default.destroy();
|
|
132
|
+
}
|
|
133
|
+
async restartProxy() {
|
|
134
|
+
await locadot_file_1.default.softDestroy();
|
|
135
|
+
await this.startProxy();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const locadotProxy = new ProxyHandler();
|
|
139
|
+
exports.default = locadotProxy;
|
package/dist/server.js
CHANGED
|
@@ -8,121 +8,118 @@ const certs_1 = require("./certs");
|
|
|
8
8
|
const https_1 = __importDefault(require("https"));
|
|
9
9
|
const http_1 = __importDefault(require("http"));
|
|
10
10
|
const fs_1 = __importDefault(require("fs"));
|
|
11
|
-
const utils_1 = require("./utils");
|
|
12
|
-
const constants_1 = require("./utils/constants");
|
|
13
11
|
const locadot_file_1 = __importDefault(require("./lib/locadot-file"));
|
|
14
12
|
const child_process_1 = require("child_process");
|
|
15
|
-
const
|
|
13
|
+
const file_1 = __importDefault(require("./utils/file"));
|
|
14
|
+
const logger_1 = __importDefault(require("./utils/logger"));
|
|
15
|
+
const constants_1 = __importDefault(require("./constants"));
|
|
16
|
+
const http_2 = __importDefault(require("./lib/http"));
|
|
16
17
|
class ProxyHandler {
|
|
17
18
|
async startCentralProxy() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
locadot_file_1.default.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
process.on("SIGINT", async () => {
|
|
26
|
-
locadot_file_1.default.updateLogs("🛑 Proxy stopped.", "error", "Proxy soft destroyed as process SIGINT");
|
|
27
|
-
await locadot_file_1.default.softDestroy(watcher);
|
|
28
|
-
});
|
|
29
|
-
process.on("SIGTERM", async () => {
|
|
30
|
-
locadot_file_1.default.updateLogs("🛑 Proxy stopped.", "error", "Proxy soft destroyed as process SIGTERM");
|
|
31
|
-
await locadot_file_1.default.softDestroy(watcher);
|
|
32
|
-
});
|
|
33
|
-
const requestHandler = (req, res) => {
|
|
34
|
-
const host = req.headers.host?.split(":")[0];
|
|
35
|
-
const targetPort = domainMap[host];
|
|
36
|
-
if (!targetPort) {
|
|
37
|
-
res.writeHead(502, { "Content-Type": "text/html" });
|
|
38
|
-
res.end((0, utils_1.proxyNotFound)(host));
|
|
39
|
-
}
|
|
40
|
-
proxy.web(req, res, {
|
|
41
|
-
target: `http://localhost:${targetPort}`,
|
|
42
|
-
changeOrigin: true,
|
|
43
|
-
}, (err) => {
|
|
44
|
-
locadot_file_1.default.updateLogs(host || "", "warn", `${err.name}=> ${err.message}`);
|
|
45
|
-
res.writeHead(502);
|
|
46
|
-
res.end("Connection failed. Host not found.");
|
|
19
|
+
try {
|
|
20
|
+
let domainMap = await locadot_file_1.default.getRegistry();
|
|
21
|
+
const proxy = http_proxy_1.default.createProxyServer({});
|
|
22
|
+
const defaultCert = await (0, certs_1.createSSL)("localhost");
|
|
23
|
+
const watcher = await locadot_file_1.default.watchRegistry(async () => {
|
|
24
|
+
logger_1.default.info("🔄 Updated domain mapping");
|
|
25
|
+
domainMap = await locadot_file_1.default.getRegistry();
|
|
47
26
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
headers: {
|
|
66
|
-
host: `localhost:${targetPort}`,
|
|
67
|
-
},
|
|
68
|
-
}, (err) => {
|
|
69
|
-
locadot_file_1.default.updateLogs(host || "", "warn", `WebSocket Error: ${err.name}=> ${err.message}`);
|
|
70
|
-
socket.end();
|
|
27
|
+
process.on("SIGINT", async (err) => {
|
|
28
|
+
logger_1.default.error("🛑 Proxy stopped. Proxy soft destroyed as process SIGINT", err);
|
|
29
|
+
await locadot_file_1.default.softDestroy(watcher);
|
|
30
|
+
});
|
|
31
|
+
process.on("SIGTERM", async (err) => {
|
|
32
|
+
logger_1.default.error("🛑 Proxy stopped. Proxy soft destroyed as process SIGTERM", err);
|
|
33
|
+
await locadot_file_1.default.softDestroy(watcher);
|
|
34
|
+
});
|
|
35
|
+
process.on("exit", (code, signal) => {
|
|
36
|
+
logger_1.default.error(`Process exited with error ${code} and signal ${signal}`);
|
|
37
|
+
locadot_file_1.default.softDestroy(watcher);
|
|
38
|
+
});
|
|
39
|
+
const httpsServer = https_1.default.createServer(defaultCert, (req, res) => {
|
|
40
|
+
http_2.default.requestHandler(req, res, proxy, domainMap);
|
|
41
|
+
});
|
|
42
|
+
const httpServer = http_1.default.createServer((req, res) => {
|
|
43
|
+
http_2.default.requestHandler(req, res, proxy, domainMap);
|
|
71
44
|
});
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
45
|
+
httpsServer.listen(443, () => {
|
|
46
|
+
logger_1.default.info("🛜 HTTPS proxy running on port 443");
|
|
47
|
+
});
|
|
48
|
+
httpsServer.on("upgrade", (req, res, head) => {
|
|
49
|
+
http_2.default.requestUpgrade(req, res, head, proxy, domainMap);
|
|
50
|
+
});
|
|
51
|
+
httpServer.listen(80, () => {
|
|
52
|
+
logger_1.default.info("🛜 HTTP proxy running on port 80");
|
|
53
|
+
});
|
|
54
|
+
httpServer.on("upgrade", (req, socket, head) => {
|
|
55
|
+
http_2.default.requestUpgrade(req, socket, head, proxy, domainMap);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
logger_1.default.error("Failed to start central proxy", error);
|
|
60
|
+
}
|
|
83
61
|
}
|
|
84
|
-
async
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
62
|
+
static async isProxyRunning() {
|
|
63
|
+
try {
|
|
64
|
+
const pid = Number(await locadot_file_1.default.getProcessId());
|
|
65
|
+
if (!pid || isNaN(pid)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
process.kill(pid, 0);
|
|
69
|
+
return true;
|
|
88
70
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
71
|
+
catch (error) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async startProxy() {
|
|
76
|
+
try {
|
|
77
|
+
if (await ProxyHandler.isProxyRunning()) {
|
|
78
|
+
logger_1.default.error("Proxy is already running");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const command = locadot_file_1.default.getStartProxyFile();
|
|
82
|
+
const proxyProcess = (0, child_process_1.spawn)(command.command, command.path, {
|
|
83
|
+
detached: true,
|
|
84
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
85
|
+
});
|
|
86
|
+
const logStream = file_1.default.writeFileStream("LOGS", true);
|
|
87
|
+
proxyProcess.stderr.pipe(logStream);
|
|
88
|
+
proxyProcess.on("error", (err) => {
|
|
89
|
+
console.error("Failed to start child process:", err);
|
|
90
|
+
});
|
|
91
|
+
if (!proxyProcess.pid) {
|
|
92
|
+
logger_1.default.error("❌ Central proxy failed to start");
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
locadot_file_1.default.createLockFile(proxyProcess.pid?.toString());
|
|
97
|
+
}
|
|
98
|
+
proxyProcess.unref();
|
|
99
|
+
logger_1.default.info("🚀 Central proxy started in background.");
|
|
101
100
|
}
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
catch (error) {
|
|
102
|
+
logger_1.default.error("Failed to start central proxy", error);
|
|
104
103
|
}
|
|
105
|
-
proxyProcess.unref();
|
|
106
|
-
console.log("🚀 Central proxy started in background.");
|
|
107
104
|
}
|
|
108
105
|
async registerDomain(domain, port) {
|
|
109
|
-
if (!(await
|
|
106
|
+
if (!(await ProxyHandler.isProxyRunning())) {
|
|
110
107
|
await this.startProxy();
|
|
111
108
|
}
|
|
112
109
|
let registry = await locadot_file_1.default.getRegistry();
|
|
113
|
-
if (!fs_1.default.existsSync(constants_1.
|
|
114
|
-
fs_1.default.writeFileSync(constants_1.
|
|
110
|
+
if (!fs_1.default.existsSync(constants_1.default.paths.REGISTRY_FILE)) {
|
|
111
|
+
fs_1.default.writeFileSync(constants_1.default.paths.REGISTRY_FILE, "{}");
|
|
115
112
|
}
|
|
116
|
-
if (fs_1.default.existsSync(constants_1.
|
|
117
|
-
registry = JSON.parse(fs_1.default.readFileSync(constants_1.
|
|
113
|
+
if (fs_1.default.existsSync(constants_1.default.paths.REGISTRY_FILE)) {
|
|
114
|
+
registry = JSON.parse(fs_1.default.readFileSync(constants_1.default.paths.REGISTRY_FILE, "utf-8"));
|
|
118
115
|
}
|
|
119
116
|
if (registry[domain]) {
|
|
120
117
|
console.error(`❌ ${domain} already mapped to port ${registry[domain]}`);
|
|
121
118
|
process.exit(1);
|
|
122
119
|
}
|
|
123
120
|
registry[domain] = port;
|
|
124
|
-
fs_1.default.writeFileSync(constants_1.
|
|
125
|
-
|
|
121
|
+
fs_1.default.writeFileSync(constants_1.default.paths.REGISTRY_FILE, JSON.stringify(registry, null, 2));
|
|
122
|
+
logger_1.default.info(`✅ ${domain} => http://localhost:${port}`);
|
|
126
123
|
}
|
|
127
124
|
async stopProxy() {
|
|
128
125
|
await locadot_file_1.default.softDestroy();
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createSSL = createSSL;
|
|
7
|
+
const appdata_path_1 = __importDefault(require("appdata-path"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const CERT_PATH = (0, appdata_path_1.default)("locadot");
|
|
11
|
+
const mkcert_1 = require("mkcert");
|
|
12
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
13
|
+
async function createSSL(domain) {
|
|
14
|
+
logger_1.default.info(`🔐 Preparing SSL cert for ${domain}`);
|
|
15
|
+
const KEY_FILE = path_1.default.join(CERT_PATH, domain + ".key");
|
|
16
|
+
const CERT_FILE = path_1.default.join(CERT_PATH, domain + ".pem");
|
|
17
|
+
if (fs_1.default.existsSync(KEY_FILE) && fs_1.default.existsSync(CERT_FILE)) {
|
|
18
|
+
logger_1.default.info(`🔄 Using existing certificate for ${domain}`);
|
|
19
|
+
const key = fs_1.default.readFileSync(KEY_FILE, "utf-8");
|
|
20
|
+
const cert = fs_1.default.readFileSync(CERT_FILE, "utf-8");
|
|
21
|
+
return { key, cert };
|
|
22
|
+
}
|
|
23
|
+
// Otherwise, generate a new one
|
|
24
|
+
logger_1.default.info(`🔐 Generating SSL cert for ${domain}`);
|
|
25
|
+
const ca = await (0, mkcert_1.createCA)({
|
|
26
|
+
organization: "Locadot",
|
|
27
|
+
countryCode: "IN",
|
|
28
|
+
state: "DevState",
|
|
29
|
+
locality: "DevTown",
|
|
30
|
+
validity: 365,
|
|
31
|
+
});
|
|
32
|
+
const cert = await (0, mkcert_1.createCert)({
|
|
33
|
+
domains: [domain],
|
|
34
|
+
ca: ca,
|
|
35
|
+
validity: 365,
|
|
36
|
+
organization: "Locadot",
|
|
37
|
+
});
|
|
38
|
+
if (!fs_1.default.existsSync(CERT_PATH))
|
|
39
|
+
fs_1.default.mkdirSync(CERT_PATH, { recursive: true });
|
|
40
|
+
fs_1.default.writeFileSync(KEY_FILE, cert.key);
|
|
41
|
+
fs_1.default.writeFileSync(CERT_FILE, cert.cert);
|
|
42
|
+
return { key: cert.key, cert: cert.cert };
|
|
43
|
+
}
|