jsir 2.4.6 → 2.4.9
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/cmd/oaa.js +7 -4
- package/deps/room.js +21 -12
- package/deps/server.js +26 -14
- package/deps/util.js +23 -3
- package/package.json +1 -1
package/cmd/oaa.js
CHANGED
|
@@ -674,6 +674,9 @@ async function joinServer(uniqueName) {
|
|
|
674
674
|
let pair = parseUniqueName(uniqueName)
|
|
675
675
|
for (let key of Object.keys(exportLib)) {
|
|
676
676
|
let val = exportLib[key];
|
|
677
|
+
Server.setRoute('get', `/${pair[0]}/${trimJsirFileName(pair[1])}/${key}`,async (req, res) => {
|
|
678
|
+
res.result = await val(...req);
|
|
679
|
+
})
|
|
677
680
|
Server.setRoute('post', `/${pair[0]}/${trimJsirFileName(pair[1])}/${key}`,async (req, res) => {
|
|
678
681
|
res.result = await val(...req);
|
|
679
682
|
})
|
|
@@ -1031,7 +1034,6 @@ async function showRooms() {
|
|
|
1031
1034
|
let room = setting.rooms[i]
|
|
1032
1035
|
let isLocal = setting.selfRoom.selfNode === room.selfNode;
|
|
1033
1036
|
results.push({
|
|
1034
|
-
mid: i,
|
|
1035
1037
|
name: (isLocal ? "*" : " ") + room.name,
|
|
1036
1038
|
node: room.selfNode,
|
|
1037
1039
|
active: room.active,
|
|
@@ -1040,17 +1042,18 @@ async function showRooms() {
|
|
|
1040
1042
|
let jsir = room.jsirs[key]
|
|
1041
1043
|
let pidStr = (process.pid === jsir.pid ? "*" : " ") + jsir.pid;
|
|
1042
1044
|
results.push({
|
|
1043
|
-
mid: i,
|
|
1044
1045
|
name: (isLocal ? "*" : " ") + room.name,
|
|
1045
1046
|
node: room.selfNode,
|
|
1046
1047
|
active: room.active,
|
|
1047
1048
|
pid: jsir.newError ? errorStr(pidStr):pidStr,
|
|
1049
|
+
up: jsir.upTime || '',
|
|
1050
|
+
version: jsir.version || '',
|
|
1048
1051
|
space: jsir.space,
|
|
1049
1052
|
running: jsir.active,
|
|
1050
1053
|
port: jsir.port,
|
|
1051
1054
|
back: jsir.back,
|
|
1052
1055
|
busy: jsir.busy,
|
|
1053
|
-
tips: Object.keys(jsir.tips).map(i => i + ': ' + jsir.tips[i]).join('\n'),
|
|
1056
|
+
tips: Object.keys(jsir.tips).map(i => infoStr(i) + ': ' + jsir.tips[i]).join('\n'),
|
|
1054
1057
|
services: Object.keys(jsir.services || []).map(msgStr).join('\n')
|
|
1055
1058
|
});
|
|
1056
1059
|
}
|
|
@@ -1484,7 +1487,7 @@ const keywordDef = {
|
|
|
1484
1487
|
suffix = 'error'
|
|
1485
1488
|
}
|
|
1486
1489
|
if (type.indexOf("t") !== -1) {
|
|
1487
|
-
cmdStr = '
|
|
1490
|
+
cmdStr = 'tail -n 50 -f'
|
|
1488
1491
|
}
|
|
1489
1492
|
path = path + '.' + suffix;
|
|
1490
1493
|
if (!fs.existsSync(path)) {
|
package/deps/room.js
CHANGED
|
@@ -2,7 +2,7 @@ const os = require('os');
|
|
|
2
2
|
const {fileJson, fileLock, vl, createConsole, getKeyTips, getValTips,
|
|
3
3
|
getRoomsDir, e, regEach, isRunningInBackground,
|
|
4
4
|
batchAsync, debugStr, trim, getOr, errorTag, warnStr, getConfig, getConfigDir,
|
|
5
|
-
fileExist
|
|
5
|
+
fileExist, formatUptime
|
|
6
6
|
} = require('./util');
|
|
7
7
|
const {setRoute, createSign} = require('../deps/server')
|
|
8
8
|
const roomDataFile = "jsirRoom.json"
|
|
@@ -17,6 +17,7 @@ const http = require('http');
|
|
|
17
17
|
const tailscalePath = os.platform() === 'darwin' ?
|
|
18
18
|
'/Applications/Tailscale.app/Contents/MacOS/Tailscale':'tailscale';
|
|
19
19
|
const configMain = getConfig("configMain");
|
|
20
|
+
const packageJson = require("../package.json");
|
|
20
21
|
|
|
21
22
|
function debug(...args) {
|
|
22
23
|
if (global.$DEBUG) {
|
|
@@ -117,19 +118,26 @@ function getSelfIP(nodes) {
|
|
|
117
118
|
|
|
118
119
|
async function getTailscaleNodes() {
|
|
119
120
|
let resp = await e(`${tailscalePath} status`);
|
|
120
|
-
let nodes =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
let nodes = {}
|
|
122
|
+
for (let line of resp.split("\n").map(trim)) {
|
|
123
|
+
if (line.indexOf('offline') !== -1) {
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
let ss = line.split(/\s+/);
|
|
127
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(ss[0])) {
|
|
128
|
+
nodes[ss[0]] = ss[1]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return nodes;
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
async function updateRoomInfo() {
|
|
128
|
-
let
|
|
135
|
+
let nodeMap = await getTailscaleNodes();
|
|
136
|
+
let nodes = Object.keys(nodeMap)
|
|
129
137
|
let ip = getSelfIP(nodes)
|
|
130
138
|
await fileJson(roomDataFile, async room => {
|
|
131
139
|
// 设置roomName
|
|
132
|
-
let name = os.hostname();
|
|
140
|
+
let name = nodeMap[ip] || os.hostname();
|
|
133
141
|
if (!vl(room.name) || room.name !== name) {
|
|
134
142
|
room.name = name;
|
|
135
143
|
debug("set roomName", name)
|
|
@@ -315,7 +323,7 @@ async function cleanRoom(room) {
|
|
|
315
323
|
for (let pid of Object.keys(room.jsirs || {})) {
|
|
316
324
|
let jsir = room.jsirs[pid]
|
|
317
325
|
let active = Date.now() - (jsir.lastUpdateTime || 0) <= setting.roomHeartbeatExpire;
|
|
318
|
-
if (!active && isPidAlive(pid)) {
|
|
326
|
+
if (jsir.back && !active && isPidAlive(pid)) {
|
|
319
327
|
try {
|
|
320
328
|
debug(`kill inactive jsir ${pid}`)
|
|
321
329
|
process.kill(parseInt(pid), 'SIGKILL'); // 强制终止进程
|
|
@@ -371,7 +379,9 @@ async function initRoomJsir(room) {
|
|
|
371
379
|
lastUpdateTime: Date.now(),
|
|
372
380
|
port: setting.server ? setting.server.address().port:null,
|
|
373
381
|
services: services,
|
|
374
|
-
newError: global.$newError
|
|
382
|
+
newError: global.$newError,
|
|
383
|
+
version: packageJson.version,
|
|
384
|
+
upTime: formatUptime()
|
|
375
385
|
}
|
|
376
386
|
}
|
|
377
387
|
|
|
@@ -523,6 +533,5 @@ module.exports = {
|
|
|
523
533
|
offRoom,
|
|
524
534
|
syncSetting,
|
|
525
535
|
reqNode,
|
|
526
|
-
reqFn
|
|
527
|
-
localConfigs
|
|
536
|
+
reqFn
|
|
528
537
|
}
|
package/deps/server.js
CHANGED
|
@@ -7,6 +7,7 @@ const preferredPort = setting.defaultPort;
|
|
|
7
7
|
// 路由存储
|
|
8
8
|
const routes = setting.routes;
|
|
9
9
|
let invokeStart = false;
|
|
10
|
+
const apiReg = /[^a-zA-Z]api[^a-zA-Z]|[^a-zA-Z]api$/i;
|
|
10
11
|
|
|
11
12
|
function debug(...args) {
|
|
12
13
|
if (global.$DEBUG) {
|
|
@@ -36,7 +37,15 @@ function createSign() {
|
|
|
36
37
|
async function createServer(port) {
|
|
37
38
|
const server = http.createServer(async (req, res) => {
|
|
38
39
|
const method = req.method.toLowerCase();
|
|
39
|
-
const
|
|
40
|
+
const originUrl = decodeURI(req.url);
|
|
41
|
+
|
|
42
|
+
let url = originUrl;
|
|
43
|
+
let params = '[]'
|
|
44
|
+
let sepIndex = originUrl.indexOf("?");
|
|
45
|
+
if (sepIndex !== -1) {
|
|
46
|
+
url = originUrl.substring(0, sepIndex).trim()
|
|
47
|
+
params = JSON.stringify([...new URLSearchParams(originUrl.substring(sepIndex).trim()).values()]);
|
|
48
|
+
}
|
|
40
49
|
|
|
41
50
|
// 获取客户端的 IP 地址
|
|
42
51
|
const clientIp = req.socket.remoteAddress || req.connection.remoteAddress;
|
|
@@ -45,22 +54,25 @@ async function createServer(port) {
|
|
|
45
54
|
debug(`Received ${routeKey} from ${clientIp}`);
|
|
46
55
|
|
|
47
56
|
if (routes[routeKey]) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
57
|
+
if (!apiReg.test(routeKey)) {
|
|
58
|
+
// 如果不是api接口,则校验签名
|
|
59
|
+
// 取header里的sign字段
|
|
60
|
+
const sign = req.headers['sign'];
|
|
61
|
+
if (sign) {
|
|
62
|
+
const decodedTime = verifySign(sign);
|
|
63
|
+
const currentTime = Date.now();
|
|
53
64
|
|
|
54
|
-
|
|
65
|
+
if (decodedTime === null || Math.abs(currentTime - decodedTime) > setting.serverSignExpire) {
|
|
66
|
+
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
67
|
+
res.end('Forbidden: Invalid Sign');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
// 如果没有sign字段,返回403
|
|
55
72
|
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
56
|
-
res.end('Forbidden:
|
|
73
|
+
res.end('Forbidden: Missing Sign');
|
|
57
74
|
return;
|
|
58
75
|
}
|
|
59
|
-
} else {
|
|
60
|
-
// 如果没有sign字段,返回403
|
|
61
|
-
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
62
|
-
res.end('Forbidden: Missing Sign');
|
|
63
|
-
return;
|
|
64
76
|
}
|
|
65
77
|
// 如果签名通过,继续处理请求
|
|
66
78
|
try {
|
|
@@ -77,7 +89,7 @@ async function createServer(port) {
|
|
|
77
89
|
resolve()
|
|
78
90
|
})
|
|
79
91
|
})
|
|
80
|
-
await routes[routeKey](body, res);
|
|
92
|
+
await routes[routeKey](body || params, res);
|
|
81
93
|
} catch (e) {
|
|
82
94
|
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
83
95
|
res.end(String(isError(e) ? e.message:e));
|
package/deps/util.js
CHANGED
|
@@ -2048,7 +2048,7 @@ function getValTips() {
|
|
|
2048
2048
|
}
|
|
2049
2049
|
return item;
|
|
2050
2050
|
}).join("|");
|
|
2051
|
-
items.push(val)
|
|
2051
|
+
items.push(val || trim(key))
|
|
2052
2052
|
}
|
|
2053
2053
|
return items
|
|
2054
2054
|
}
|
|
@@ -2078,7 +2078,7 @@ function interceptStdStreams() {
|
|
|
2078
2078
|
if(setting.enterOutputs) {
|
|
2079
2079
|
setting.enterOutputs.push(chunk.toString());
|
|
2080
2080
|
} else if (isRunningInBackground()) {
|
|
2081
|
-
console.$log(process.pid, "
|
|
2081
|
+
console.$log(process.pid, "stdout", "\n" + chunk.toString().trimEnd());
|
|
2082
2082
|
} else {
|
|
2083
2083
|
originalStdoutWrite(chunk, ...args); // 保留原始行为
|
|
2084
2084
|
}
|
|
@@ -2089,14 +2089,34 @@ function interceptStdStreams() {
|
|
|
2089
2089
|
if(setting.enterOutputs) {
|
|
2090
2090
|
setting.enterOutputs.push(chunk.toString());
|
|
2091
2091
|
} else if (isRunningInBackground()) {
|
|
2092
|
-
console.$error(process.pid, errorStr("
|
|
2092
|
+
console.$error(process.pid, errorStr("stderr"), "\n" + chunk.toString().trimEnd());
|
|
2093
2093
|
} else {
|
|
2094
2094
|
originalStderrWrite(chunk, ...args); // 保留原始行为
|
|
2095
2095
|
}
|
|
2096
2096
|
};
|
|
2097
2097
|
}
|
|
2098
2098
|
|
|
2099
|
+
function formatUptime() {
|
|
2100
|
+
const uptimeSeconds = process.uptime();
|
|
2101
|
+
|
|
2102
|
+
const days = Math.floor(uptimeSeconds / (3600 * 24)); // 计算天数
|
|
2103
|
+
const hours = Math.floor((uptimeSeconds % (3600 * 24)) / 3600); // 计算小时
|
|
2104
|
+
const minutes = Math.floor((uptimeSeconds % 3600) / 60); // 计算分钟
|
|
2105
|
+
const seconds = Math.floor(uptimeSeconds % 60); // 计算秒数
|
|
2106
|
+
|
|
2107
|
+
if (days > 0) {
|
|
2108
|
+
return `${days}d${hours}h`;
|
|
2109
|
+
} else if (hours > 0) {
|
|
2110
|
+
return `${hours}h${minutes}m`;
|
|
2111
|
+
} else if (minutes > 0) {
|
|
2112
|
+
return `${minutes}m${seconds}s`;
|
|
2113
|
+
} else {
|
|
2114
|
+
return `${seconds}s`;
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2099
2118
|
module.exports = {
|
|
2119
|
+
formatUptime,
|
|
2100
2120
|
wrapperJsirText,
|
|
2101
2121
|
run,
|
|
2102
2122
|
reget,
|