Files
js_tool_clone/panel/server.js
2021-08-09 12:12:42 -04:00

1045 lines
32 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author: Jerrykuku https://github.com/jerrykuku
* @Date: 2021-1-8
* @Version: v0.0.2
* @thanks: FanchangWang https://github.com/FanchangWang
*/
var express = require('express');
var session = require('express-session');
var compression = require('compression');
var bodyParser = require('body-parser');
var got = require('got');
var path = require('path');
var fs = require('fs');
var { execSync, exec } = require('child_process');
const crypto = require('crypto');
const { createProxyMiddleware } = require('http-proxy-middleware');
var rootPath = path.resolve(__dirname, '..');
// cookie.sh 文件所在目录
var ckFile = path.join(rootPath, 'config/cookie.sh');
// config.sh 文件所在目录
var confFile = path.join(rootPath, 'config/config.sh');
// config.sh.sample 文件所在目录
var sampleFile = path.join(rootPath, 'sample/config.sh.sample');
// crontab.list 文件所在目录
var crontabFile = path.join(rootPath, 'config/crontab.list');
// config.sh 文件备份目录
var confBakDir = path.join(rootPath, 'config/bak/');
// auth.json 文件目录
var authConfigFile = path.join(rootPath, 'config/auth.json');
// 限制文件
var autoConfigFile = path.join(rootPath, '.AutoConfig/config.sh');
// Share Code 文件目录
var shareCodeDir = path.join(rootPath, 'log/jd_get_share_code/');
// diy.sh 文件目录
var diyFile = path.join(rootPath, 'config/diy.sh');
// 日志目录
var logPath = path.join(rootPath, 'log/');
// 脚本目录
var ScriptsPath = path.join(rootPath, 'scripts/');
var authError = "错误的用户名密码,请重试";
var loginFaild = "请先登录!";
var configString = "config usrconfig sample crontab shareCode diy";
var s_token, cookies, guid, lsid, lstoken, okl_token, token, userCookie = "";
var ErrorTimes = 0;
function praseSetCookies(response) {
s_token = response.body.s_token
guid = response.headers['set-cookie'][0]
guid = guid.substring(guid.indexOf("=") + 1, guid.indexOf(";"))
lsid = response.headers['set-cookie'][2]
lsid = lsid.substring(lsid.indexOf("=") + 1, lsid.indexOf(";"))
lstoken = response.headers['set-cookie'][3]
lstoken = lstoken.substring(lstoken.indexOf("=") + 1, lstoken.indexOf(";"))
cookies = "guid=" + guid + "; lang=chs; lsid=" + lsid + "; lstoken=" + lstoken + "; "
}
function getCookie(response) {
var TrackerID = response.headers['set-cookie'][0]
TrackerID = TrackerID.substring(TrackerID.indexOf("=") + 1, TrackerID.indexOf(";"))
var pt_key = response.headers['set-cookie'][1]
pt_key = pt_key.substring(pt_key.indexOf("=") + 1, pt_key.indexOf(";"))
var pt_pin = response.headers['set-cookie'][2]
pt_pin = pt_pin.substring(pt_pin.indexOf("=") + 1, pt_pin.indexOf(";"))
var pt_token = response.headers['set-cookie'][3]
pt_token = pt_token.substring(pt_token.indexOf("=") + 1, pt_token.indexOf(";"))
var pwdt_id = response.headers['set-cookie'][4]
pwdt_id = pwdt_id.substring(pwdt_id.indexOf("=") + 1, pwdt_id.indexOf(";"))
var s_key = response.headers['set-cookie'][5]
s_key = s_key.substring(s_key.indexOf("=") + 1, s_key.indexOf(";"))
var s_pin = response.headers['set-cookie'][6]
s_pin = s_pin.substring(s_pin.indexOf("=") + 1, s_pin.indexOf(";"))
cookies = "TrackerID=" + TrackerID + "; pt_key=" + pt_key + "; pt_pin=" + pt_pin + "; pt_token=" + pt_token + "; pwdt_id=" + pwdt_id + "; s_key=" + s_key + "; s_pin=" + s_pin + "; wq_skey="
var userCookie = "pt_key=" + pt_key + ";pt_pin=" + pt_pin + ";";
return userCookie;
}
async function step1() {
try {
s_token, cookies, guid, lsid, lstoken, okl_token, token = ""
let timeStamp = (new Date()).getTime()
let url = 'https://plogin.m.jd.com/cgi-bin/mm/new_login_entrance?lang=chs&appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' + timeStamp + '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport'
const response = await got(url, {
responseType: 'json',
headers: {
'Connection': 'Keep-Alive',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-cn',
'Referer': 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=' + timeStamp + '&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 SP-engine/2.14.0 main%2F1.0 baiduboxapp/11.18.0.16 (Baidu; P2 13.3.1) NABar/0.0',
'Host': 'plogin.m.jd.com'
}
});
praseSetCookies(response)
} catch (error) {
cookies = "";
console.log(error.response.body);
}
};
async function step2() {
try {
if (cookies == "") {
return 0
}
let timeStamp = (new Date()).getTime()
let url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthreflogurl?s_token=' + s_token + '&v=' + timeStamp + '&remember=true'
const response = await got.post(url, {
responseType: 'json',
json: {
'lang': 'chs',
'appid': 300,
'source': 'wq_passport',
'returnurl': 'https://wqlogin2.jd.com/passport/LoginRedirect?state=' + timeStamp + '&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action'
},
headers: {
'Connection': 'Keep-Alive',
'Content-Type': 'application/x-www-form-urlencoded; Charset=UTF-8',
'Accept': 'application/json, text/plain, */*',
'Cookie': cookies,
'Referer': 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=' + timeStamp + '&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 SP-engine/2.14.0 main%2F1.0 baiduboxapp/11.18.0.16 (Baidu; P2 13.3.1) NABar/0.0',
'Host': 'plogin.m.jd.com',
}
});
token = response.body.token
okl_token = response.headers['set-cookie'][0]
okl_token = okl_token.substring(okl_token.indexOf("=") + 1, okl_token.indexOf(";"))
var qrUrl = 'https://plogin.m.jd.com/cgi-bin/m/tmauth?appid=300&client_type=m&token=' + token;
return qrUrl;
} catch (error) {
console.log(error.response.body);
return 0
}
}
var i = 0;
async function checkLogin() {
try {
if (cookies == "") {
return 0
}
let timeStamp = (new Date()).getTime()
let url = 'https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=' + token + '&ou_state=0&okl_token=' + okl_token;
const response = await got.post(url, {
responseType: 'json',
form: {
lang: 'chs',
appid: 300,
source: 'wq_passport',
returnurl: 'https://wqlogin2.jd.com/passport/LoginRedirect?state=' + timeStamp + '&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action'
},
headers: {
'Referer': 'https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=' + timeStamp + '&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
'Cookie': cookies,
'Connection': 'Keep-Alive',
'Content-Type': 'application/x-www-form-urlencoded; Charset=UTF-8',
'Accept': 'application/json, text/plain, */*',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 SP-engine/2.14.0 main%2F1.0 baiduboxapp/11.18.0.16 (Baidu; P2 13.3.1) NABar/0.0',
}
});
return response;
} catch (error) {
console.log(error.response.body);
let res = {}
res.body = { check_ip: 0, errcode: 222, message: '出错' }
res.headers = {}
return res;
}
}
function TotalBean() {
return new Promise(async resolve => {
const options = {
url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion",
headers: {
Host: "me-api.jd.com",
Accept: "*/*",
Connection: "keep-alive",
Cookie: cookies,
'User-Agent': 'jdapp;iPhone;10.0.2;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1',
"Accept-Language": "zh-cn",
"Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&",
"Accept-Encoding": "gzip, deflate, br"
}
}
$.get(options, (err, resp, data) => {
try {
if (err) {
$.logErr(err)
} else {
if (data) {
data = JSON.parse(data);
if (data['retcode'] === "1001") {
$.isLogin = false; //cookie过期
return;
}
if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) {
$.nickName = data.data.userInfo.baseInfo.nickname;
}
} else {
$.log('京东服务器返回空数据');
}
}
} catch (e) {
$.logErr(e)
} finally {
resolve();
}
})
})
}
function AutoAddCK(cookie, msg) {
const content = getFileContentByName(ckFile);
const lines = content.split('\n');
const pt_pin = cookie.match(/pt_pin=.+?;/)[0];
let updateFlag = false;
let lastIndex = 0;
let maxCookieCount = 0;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.startsWith('Cookie')) {
maxCookieCount = line.split('=')[0].split('Cookie')[1];
lastIndex = i;
if (
line.match(/pt_pin=.+?;/) &&
line.match(/pt_pin=.+?;/)[0] == pt_pin
) {
const head = line.split('=')[0];
const newLine = [head, '=', '"', cookie, '"', ' #', msg].join('');
lines[i] = newLine;
updateFlag = true;
}
}
}
if (!updateFlag) {
const newLine = [
'Cookie',
Number(maxCookieCount) + 1,
'=',
'"',
cookie,
'"',
' #',
msg,
].join('');
lines.splice(lastIndex + 1, 0, newLine);
}
saveNewConf('cookie.sh', lines.join('\n'));
}
/**
* hash方法
*
* @param {String} e.g.: 'md5', 'sha1'
* @param {String|Buffer} s
* @param {String} [format] 'hex''base64'. default is 'hex'.
* @return {String} 编码值
* @private
*/
const hash = (method, s, format) => {
var sum = crypto.createHash(method);
var isBuffer = Buffer.isBuffer(s);
if (!isBuffer && typeof s === 'object') {
s = JSON.stringify(sortObject(s));
}
sum.update(s, isBuffer ? 'binary' : 'utf8');
return sum.digest(format || 'hex');
};
/**
- md5 编码
- 3. @param {String|Buffer} s
- @param {String} [format] 'hex''base64'. default is 'hex'.
- @return {String} md5 hash string
- @public
*/
const md5 = (s, format) => {
return hash('md5', s, format);
};
function CountUser() {
const content = getFileContentByName(ckFile);
const lines = content.split('\n');
let maxCookieCount = 0;
let UserCount;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.startsWith('Cookie')) {
maxCookieCount = line.split('=')[0].split('Cookie')[1];
UserCount = Number(maxCookieCount);
}
}
return UserCount;
}
/**
* @getClientIP
* @desc 获取用户 ip 地址
* @param {Object} req - 请求
*/
function getClientIP(req) {
return req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
};
/**
* 检查 config.sh 以及 config.sh.sample 文件是否存在
*/
function checkConfigFile() {
if (!fs.existsSync(ckFile)) {
console.error('脚本启动失败cookie.sh 文件不存在!');
process.exit(1);
}
if (!fs.existsSync(sampleFile)) {
console.error('脚本启动失败config.sh.sample 文件不存在!');
process.exit(1);
}
if (!fs.existsSync(autoConfigFile)) {
console.error('脚本启动失败此面板只适用于JSTOOL');
process.exit(1);
}
}
/**
* 检查 config/bak/ 备份目录是否存在,不存在则创建
*/
function mkdirConfigBakDir() {
if (!fs.existsSync(confBakDir)) {
fs.mkdirSync(confBakDir);
}
}
/**
* 备份 config.sh 文件
*/
function bakConfFile(file) {
mkdirConfigBakDir();
let date = new Date();
let bakConfFile = confBakDir + file + '_' + date.getFullYear() + '-' + date.getMonth() + '-' + date.getDay() + '-' + date.getHours() + '-' + date.getMinutes() + '-' + date.getMilliseconds();
let oldConfContent = "";
switch (file) {
case "cookie.sh":
oldConfContent = getFileContentByName(ckFile);
fs.writeFileSync(bakConfFile, oldConfContent);
break;
case "config.sh":
oldConfContent = getFileContentByName(confFile);
fs.writeFileSync(bakConfFile, oldConfContent);
break;
case "crontab.list":
oldConfContent = getFileContentByName(crontabFile);
fs.writeFileSync(bakConfFile, oldConfContent);
break;
case "diy.sh":
oldConfContent = getFileContentByName(diyFile);
fs.writeFileSync(bakConfFile, oldConfContent);
break;
default:
break;
}
}
/**
* 将 post 提交内容写入 config.sh 文件(同时备份旧的 config.sh 文件到 bak 目录)
* @param content
*/
function saveNewConf(file, content) {
bakConfFile(file);
switch (file) {
case "cookie.sh":
fs.writeFileSync(ckFile, content);
break;
case "config.sh":
fs.writeFileSync(confFile, content);
break;
case "crontab.list":
fs.writeFileSync(crontabFile, content);
execSync('crontab ' + crontabFile);
break;
case "diy.sh":
fs.writeFileSync(diyFile, content);
break;
default:
break;
}
}
/**
* 获取文件内容
* @param fileName 文件路径
* @returns {string}
*/
function getFileContentByName(fileName) {
if (fs.existsSync(fileName)) {
return fs.readFileSync(fileName, 'utf8');
}
return '';
}
/**
* 获取目录中最后修改的文件的路径
* @param dir 目录路径
* @returns {string} 最新文件路径
*/
function getLastModifyFilePath(dir) {
var filePath = '';
if (fs.existsSync(dir)) {
var lastmtime = 0;
var arr = fs.readdirSync(dir);
arr.forEach(function (item) {
var fullpath = path.join(dir, item);
var stats = fs.statSync(fullpath);
if (stats.isFile()) {
if (stats.mtimeMs >= lastmtime) {
filePath = fullpath;
}
}
});
}
return filePath;
}
var app = express();
// gzip压缩
app.use(compression({ level: 6, filter: shouldCompress }));
function shouldCompress(req, res) {
if (req.headers['x-no-compression']) {
// don't compress responses with this request header
return false;
}
// fallback to standard filter function
return compression.filter(req, res);
}
app.use(session({
secret: 'secret',
name: `connect.${Math.random()}`,
resave: true,
saveUninitialized: true
}));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
/**
* 首页
*/
app.get('/', function (request, response) {
let OldIPContent = getFileContentByName(logPath + 'panel.txt');
let date = new Date();
let bakConfFile = '时间为:' + date.getFullYear() + '-' + date.getMonth() + '-' + date.getDay() + '-' + date.getHours() + '-' + date.getMinutes() + '-' + date.getMilliseconds();
OldIPContent = OldIPContent + '\n' + '访问您【首页】的IP为' + getClientIP(request) + bakConfFile + '\n';
fs.writeFileSync(logPath + 'panel.txt', OldIPContent);
if (request.session.loggedin) {
response.redirect('./usrconfig');
} else {
response.sendFile(path.join(__dirname + '/public/index1.html'));
}
});
/**
* 登录页面
*/
app.get('/login', function (request, response) {
if (request.session.loggedin) {
response.redirect('./usrconfig');
} else {
response.sendFile(path.join(__dirname + '/public/login.html'));
}
});
/**
* 用户名密码
*/
app.get('/changepwd', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/pwd.html'));
} else {
response.redirect('/login');
}
});
/**
* terminal
*/
app.get('/terminal', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/terminal.html'));
} else {
response.redirect('/');
}
});
/**
* 获取二维码链接
*/
app.get('/qrcode', function (request, response) {
(async () => {
try {
await step1();
const qrurl = await step2();
if (qrurl != 0) {
response.send({ err: 0, qrcode: qrurl });
} else {
response.send({ err: 1, msg: "错误" });
}
} catch (err) {
response.send({ err: 1, msg: err });
}
})();
})
/**
* 发送用户数
*/
app.get('/GetUserCount', function (request, response) {
let SendNum = '当前有' + CountUser() + '名用户';
response.send({ err: 0, msg: SendNum });
})
/**
* 获取返回的cookie信息
*/
app.get('/cookie', function (request, response) {
if (request.session.loggedin && cookies != "") {
(async () => {
try {
const cookie = await checkLogin();
if (cookie.body.errcode == 0) {
let ucookie = getCookie(cookie);
response.send({ err: 0, cookie: ucookie });
} else {
response.send({ err: cookie.body.errcode, msg: cookie.body.message });
}
} catch (err) {
response.send({ err: 1, msg: err });
}
})();
} else {
response.send({ err: 1, msg: loginFaild });
}
})
/**
* 获取返回的cookie信息
*/
app.post('/cookie', function (request, response) {
(async () => {
try {
const cookie = await checkLogin();
if (cookie.body.errcode == 0) {
let ucookie = getCookie(cookie);
let adddata = ucookie;
AutoAddCK(adddata, request.body.msg);
response.send({ err: 0, cookie: ucookie });
} else {
response.send({ err: cookie.body.errcode, msg: cookie.body.message });
}
} catch (err) {
response.send({ err: 1, msg: err });
}
})();
})
/**
* 获取各种配置文件api
*/
app.get('/api/config/:key', function (request, response) {
if (request.session.loggedin) {
if (configString.indexOf(request.params.key) > -1) {
switch (request.params.key) {
case 'config':
content = getFileContentByName(confFile);
break;
case 'usrconfig':
content = getFileContentByName(ckFile);
break;
case 'sample':
content = getFileContentByName(sampleFile);
break;
case 'crontab':
content = getFileContentByName(crontabFile);
break;
case 'shareCode':
let shareCodeFile = getLastModifyFilePath(shareCodeDir);
content = getFileContentByName(shareCodeFile);
break;
case 'diy':
content = getFileContentByName(diyFile);
break;
default:
break;
}
response.setHeader("Content-Type", "text/plain");
response.send(content);
} else {
response.send("no config");
}
} else {
response.send(loginFaild);
}
})
/**
* 首页
*/
app.get('/home', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/home.html'));
} else {
response.redirect('/login');
}
});
/**
* 配置页面
*/
app.get('/usrconfig', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/usrconfig.html'));
} else {
response.redirect('/login');
}
});
/**
* 对比 配置页面
*/
app.get('/diff', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/diff.html'));
} else {
response.redirect('/login');
}
});
/**
* Share Code 页面
*/
app.get('/shareCode', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/shareCode.html'));
} else {
response.redirect('/login');
}
});
/**
* crontab 配置页面
*/
app.get('/crontab', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/crontab.html'));
} else {
response.redirect('/login');
}
});
/**
* 自定义脚本 页面
*/
app.get('/diy', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/diy.html'));
} else {
response.redirect('/login');
}
});
/**
* 手动执行脚本 页面
*/
app.get('/run', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/run.html'));
} else {
response.redirect('/login');
}
});
app.post('/runCmd', function (request, response) {
if (request.session.loggedin) {
const cmd = `cd ${rootPath};` + request.body.cmd;
const delay = request.body.delay || 0;
// console.log('before exec');
// exec maxBuffer 20MB
exec(cmd, { maxBuffer: 1024 * 1024 * 20 }, (error, stdout, stderr) => {
// console.log(error, stdout, stderr);
// 根据传入延时返回数据,有时太快会出问题
setTimeout(() => {
if (error) {
console.error(`执行的错误: ${error}`);
response.send({ err: 1, msg: stdout ? `${stdout}${error}` : `${error}` });
return;
}
if (stdout) {
// console.log(`stdout: ${stdout}`)
response.send({ err: 0, msg: `${stdout}` });
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
response.send({ err: 1, msg: `${stderr}` });
return;
}
response.send({ err: 0, msg: '执行结束,无结果返回。' });
}, delay);
});
} else {
response.redirect('/login');
}
});
/**
* 使用jsName获取最新的日志
*/
app.get('/runLog/:jsName', function (request, response) {
if (request.session.loggedin) {
const jsName = request.params.jsName;
let shareCodeFile = getLastModifyFilePath(path.join(rootPath, `log/${jsName}/`));
if (jsName === 'rm_log') {
shareCodeFile = path.join(rootPath, `log/${jsName}.log`)
}
if (shareCodeFile) {
const content = getFileContentByName(shareCodeFile);
response.setHeader("Content-Type", "text/plain");
response.send(content);
} else {
response.send("no logs");
}
} else {
response.send(loginFaild);
}
})
/**
* login
*/
app.post('/login', function (request, response) {
let username = md5(request.body.username);
let password = md5(request.body.password);
let OldIPContent = getFileContentByName(logPath + 'panel.txt');
let UserTicket;
if (ErrorTimes > 30) {
response.send({ err: 1, msg: "面板检测到有暴力破解的行为,已关闭登入系统" });
}
fs.readFile(authConfigFile, 'utf8', function (err, data) {
if (err) console.log(err);
var con = JSON.parse(data);
if (con.entry !== '1') {
let AuthData = {
UserTicket: md5(con.user) + md5(con.password),
entry: '1'
}
UserTicket = md5(con.user) + md5(con.password);
fs.writeFileSync(authConfigFile, JSON.stringify(AuthData));
}
if (username && password) {
let GetTicket = username + password;
if (GetTicket == con.UserTicket) {
ErrorTimes = 0;
request.session.loggedin = true;
request.session.UserTicket = GetTicket;
response.send({ err: 0 });
}
else if (GetTicket == UserTicket) {
ErrorTimes = 0;
request.session.loggedin = true;
request.session.UserTicket = GetTicket;
response.send({ err: 0 });
}
else {
response.send({ err: 1, msg: authError });
//setTimeout(function() { callback(null); }, 8000);
ErrorTimes = ErrorTimes + 1;
let date = new Date();
let bakConfFile = '时间为:' + date.getFullYear() + '-' + date.getMonth() + '-' + date.getDay() + '-' + date.getHours() + '-' + date.getMinutes() + '-' + date.getMilliseconds();
OldIPContent = OldIPContent + '\n' + '【输入密码错误】访问IP为' + getClientIP(request) + bakConfFile + '\n';
if (ErrorTimes > 29) {
OldIPContent = OldIPContent + '面板检测到有暴力破解的行为,已关闭登入系统' + '\n';
}
fs.writeFileSync(logPath + 'panel.txt', OldIPContent);
}
} else {
response.send({ err: 1, msg: "请输入用户名密码!" });
}
});
});
/**
* change pwd
*/
app.post('/changepass', function (request, response) {
if (request.session.loggedin) {
let username = request.body.username;
let password = request.body.password;
let config = {
user: username,
password: password
}
if (username && password) {
fs.writeFile(authConfigFile, JSON.stringify(config), function (err) {
if (err) {
response.send({ err: 1, msg: "写入错误请重试!" });
} else {
response.send({ err: 0, msg: "更新成功!" });
}
});
} else {
response.send({ err: 1, msg: "请输入用户名密码!" });
}
} else {
response.send(loginFaild);
}
});
/**
* change pwd
*/
app.get('/logout', function (request, response) {
request.session.destroy()
response.redirect('/login');
});
/**
* save config
*/
app.post('/api/save', function (request, response) {
if (request.session.loggedin) {
let postContent = request.body.content;
let postfile = request.body.name;
saveNewConf(postfile, postContent);
response.send({ err: 0, title: "保存成功! ", msg: "将自动刷新页面查看修改后的 " + postfile + " 文件" });
} else {
response.send({ err: 1, title: "保存失败! ", msg: loginFaild });
}
});
/**
* 日志查询 页面
*/
app.get('/log', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/tasklog.html'));
} else {
response.redirect('/login');
}
});
/**
* 日志列表
*/
app.get('/api/logs', function (request, response) {
if (request.session.loggedin) {
var fileList = fs.readdirSync(logPath, 'utf-8');
var dirs = [];
var rootFiles = [];
for (var i = 0; i < fileList.length; i++) {
var stat = fs.lstatSync(logPath + fileList[i]);
// 是目录,需要继续
if (stat.isDirectory()) {
var fileListTmp = fs.readdirSync(logPath + '/' + fileList[i], 'utf-8');
fileListTmp.reverse();
var dirMap = {
dirName: fileList[i],
files: fileListTmp
}
dirs.push(dirMap);
} else {
rootFiles.push(fileList[i]);
}
}
dirs.push({
dirName: '@',
files: rootFiles
});
var result = { dirs };
response.send(result);
} else {
response.redirect('/login');
}
});
/**
* 日志文件
*/
app.get('/api/logs/:dir/:file', function (request, response) {
if (request.session.loggedin) {
let filePath;
if (request.params.dir === '@') {
filePath = logPath + request.params.file;
} else {
filePath = logPath + request.params.dir + '/' + request.params.file;
}
var content = getFileContentByName(filePath);
response.setHeader("Content-Type", "text/plain");
response.send(content);
} else {
response.redirect('/login');
}
});
/**
* 查看脚本 页面
*/
app.get('/viewScripts', function (request, response) {
if (request.session.loggedin) {
response.sendFile(path.join(__dirname + '/public/viewScripts.html'));
} else {
response.redirect('/login');
}
});
/**
* 脚本列表
*/
app.get('/api/scripts', function (request, response) {
if (request.session.loggedin) {
var fileList = fs.readdirSync(ScriptsPath, 'utf-8');
var dirs = [];
var rootFiles = [];
var excludeRegExp = /(git)|(node_modules)|(icon)/;
for (var i = 0; i < fileList.length; i++) {
var stat = fs.lstatSync(ScriptsPath + fileList[i]);
// 是目录,需要继续
if (stat.isDirectory()) {
var fileListTmp = fs.readdirSync(ScriptsPath + '/' + fileList[i], 'utf-8');
fileListTmp.reverse();
if (excludeRegExp.test(fileList[i])) {
continue;
}
var dirMap = {
dirName: fileList[i],
files: fileListTmp
}
dirs.push(dirMap);
} else {
if (excludeRegExp.test(fileList[i])) {
continue;
}
rootFiles.push(fileList[i]);
}
}
dirs.push({
dirName: '@',
files: rootFiles
});
var result = { dirs };
response.send(result);
} else {
response.redirect('/login');
}
});
/**
* 脚本文件
*/
app.get('/api/scripts/:dir/:file', function (request, response) {
if (request.session.loggedin) {
let filePath;
if (request.params.dir === '@') {
filePath = ScriptsPath + request.params.file;
} else {
filePath = ScriptsPath + request.params.dir + '/' + request.params.file;
}
var content = getFileContentByName(filePath);
response.setHeader("Content-Type", "text/plain");
response.send(content);
} else {
response.redirect('/login');
}
});
checkConfigFile();
// ttyd proxy
app.use('/RandomShellEntry', createProxyMiddleware({
target: 'http://localhost:9999',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/RandomShellEntry': '/',
},
}));
app.listen(5678, () => {
console.log('应用正在监听 5678 端口!');
});