314 lines
8.4 KiB
JavaScript
314 lines
8.4 KiB
JavaScript
|
// 填入你的配置,或者通过环境变量传入
|
|||
|
const QYWX_KEY =
|
|||
|
process.env.QYWX_KEY && process.env.QYWX_KEY.length > 0
|
|||
|
? process.env.QYWX_KEY
|
|||
|
: '';
|
|||
|
// 尽量不用@all,除非只有你一个人
|
|||
|
const QYWX_AM =
|
|||
|
process.env.QYWX_AM && process.env.QYWX_AM.length > 0
|
|||
|
? process.env.QYWX_AM
|
|||
|
: '';
|
|||
|
const express = require('express');
|
|||
|
const got = require('got');
|
|||
|
const path = require('path');
|
|||
|
const bodyParser = require('body-parser');
|
|||
|
const app = express();
|
|||
|
app.use(bodyParser.json({ limit: '50mb' }));
|
|||
|
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
|
|||
|
const crypto = require('crypto');
|
|||
|
const md5 = function (str) {
|
|||
|
const encode = crypto.createHash('md5');
|
|||
|
return encode.update(str).digest('hex');
|
|||
|
};
|
|||
|
/**
|
|||
|
* 发送消息推送
|
|||
|
*
|
|||
|
* @param {*} msg
|
|||
|
*/
|
|||
|
async function sendMsg(updateMsg, cookie, userMsg) {
|
|||
|
// 企业微信群机器人
|
|||
|
if (QYWX_KEY) {
|
|||
|
try {
|
|||
|
await got.post(
|
|||
|
`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${QYWX_KEY}`,
|
|||
|
{
|
|||
|
responseType: 'json',
|
|||
|
json: {
|
|||
|
msgtype: 'text',
|
|||
|
text: {
|
|||
|
content: `====获取到cookie====\n${updateMsg}\n用户备注:${userMsg}\n${cookie}`,
|
|||
|
},
|
|||
|
},
|
|||
|
}
|
|||
|
);
|
|||
|
} catch (err) {
|
|||
|
console.log({
|
|||
|
msg: '企业微信群机器人消息发送失败',
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
if (QYWX_AM) {
|
|||
|
try {
|
|||
|
const [corpid, corpsecret, userId, agentid] = QYWX_AM.split(',');
|
|||
|
const getToken = await got.post({
|
|||
|
url: `https://qyapi.weixin.qq.com/cgi-bin/gettoken`,
|
|||
|
json: {
|
|||
|
corpid,
|
|||
|
corpsecret,
|
|||
|
},
|
|||
|
headers: {
|
|||
|
'Content-Type': 'application/json',
|
|||
|
},
|
|||
|
timeout: 10000,
|
|||
|
});
|
|||
|
const accessToken = JSON.parse(getToken.body).access_token;
|
|||
|
const res = await got.post({
|
|||
|
url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${accessToken}`,
|
|||
|
json: {
|
|||
|
touser: userId,
|
|||
|
agentid,
|
|||
|
safe: '0',
|
|||
|
msgtype: 'text',
|
|||
|
text: {
|
|||
|
content: `====获取到cookie====\n${updateMsg}\n用户备注:${userMsg}\n${cookie}`,
|
|||
|
},
|
|||
|
},
|
|||
|
headers: {
|
|||
|
'Content-Type': 'application/json',
|
|||
|
},
|
|||
|
timeout: 10000,
|
|||
|
});
|
|||
|
} catch (err) {
|
|||
|
console.log({
|
|||
|
msg: '企业微信应用消息发送失败',
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 对ck进行处 的流程
|
|||
|
*
|
|||
|
* @param {*} cookie
|
|||
|
* @return {*}
|
|||
|
*/
|
|||
|
async function cookieFlow(cookie, userMsg) {
|
|||
|
try {
|
|||
|
await sendMsg(updateMsg, cookie, userMsg);
|
|||
|
return msg;
|
|||
|
} catch (err) {
|
|||
|
return '';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
async function sendSms(phone) {
|
|||
|
let appid = 959;
|
|||
|
let version = '1.0.0';
|
|||
|
let countryCode = 86;
|
|||
|
let timestamp = new Date().getTime();
|
|||
|
let subCmd = 1;
|
|||
|
let gsalt = 'sb2cwlYyaCSN1KUv5RHG3tmqxfEb8NKN';
|
|||
|
let gsign = md5('' + appid + version + timestamp + '36' + subCmd + gsalt);
|
|||
|
let res = await got.post('https://qapplogin.m.jd.com/cgi-bin/qapp/quick', {
|
|||
|
method: 'post',
|
|||
|
headers: {
|
|||
|
'user-agent':
|
|||
|
'Mozilla/5.0 (Linux; Android 10; V1838T Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.87 Mobile Safari/537.36 hap/1.9/vivo com.vivo.hybrid/1.9.6.302 com.jd.crplandroidhap/1.0.3 ({packageName:com.vivo.hybrid,type:deeplink,extra:{}})',
|
|||
|
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
|||
|
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
|||
|
'accept-encoding': '',
|
|||
|
cookie: '',
|
|||
|
},
|
|||
|
body:
|
|||
|
'client_ver=' +
|
|||
|
version +
|
|||
|
'&gsign=' +
|
|||
|
gsign +
|
|||
|
'&appid=' +
|
|||
|
appid +
|
|||
|
'&return_page=https%3A%2F%2Fcrpl.jd.com%2Fn%2Fmine%3FpartnerId%3DWBTF0KYY%26ADTAG%3Dkyy_mrqd%26token%3D&cmd=36&sdk_ver=1.0.0&sub_cmd=' +
|
|||
|
subCmd +
|
|||
|
'&qversion=' +
|
|||
|
version +
|
|||
|
'&ts=' +
|
|||
|
timestamp,
|
|||
|
dataType: 'json',
|
|||
|
});
|
|||
|
let data = JSON.parse(res.body).data;
|
|||
|
subCmd = 2;
|
|||
|
timestamp = new Date().getTime();
|
|||
|
gsalt = data.gsalt;
|
|||
|
gsign = md5('' + appid + version + timestamp + '36' + subCmd + gsalt);
|
|||
|
let sign = md5(
|
|||
|
'' +
|
|||
|
appid +
|
|||
|
version +
|
|||
|
countryCode +
|
|||
|
phone +
|
|||
|
'4dtyyzKF3w6o54fJZnmeW3bVHl0$PbXj'
|
|||
|
);
|
|||
|
let ck =
|
|||
|
'guid=' +
|
|||
|
data.guid +
|
|||
|
';lsid=' +
|
|||
|
data.lsid +
|
|||
|
';gsalt=' +
|
|||
|
data.gsalt +
|
|||
|
';rsa_modulus=' +
|
|||
|
data.rsa_modulus +
|
|||
|
';';
|
|||
|
res = await got.post('https://qapplogin.m.jd.com/cgi-bin/qapp/quick', {
|
|||
|
method: 'post',
|
|||
|
headers: {
|
|||
|
'user-agent':
|
|||
|
'Mozilla/5.0 (Linux; Android 10; V1838T Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.87 Mobile Safari/537.36 hap/1.9/vivo com.vivo.hybrid/1.9.6.302 com.jd.crplandroidhap/1.0.3 ({packageName:com.vivo.hybrid,type:deeplink,extra:{}})',
|
|||
|
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
|||
|
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
|||
|
'accept-encoding': '',
|
|||
|
cookie: ck,
|
|||
|
},
|
|||
|
body:
|
|||
|
'country_code=' +
|
|||
|
countryCode +
|
|||
|
'&client_ver=' +
|
|||
|
version +
|
|||
|
'&gsign=' +
|
|||
|
gsign +
|
|||
|
'&appid=' +
|
|||
|
appid +
|
|||
|
'&mobile=' +
|
|||
|
phone +
|
|||
|
'&sign=' +
|
|||
|
sign +
|
|||
|
'&cmd=36&sub_cmd=' +
|
|||
|
subCmd +
|
|||
|
'&qversion=' +
|
|||
|
version +
|
|||
|
'&ts=' +
|
|||
|
timestamp,
|
|||
|
dataType: 'json',
|
|||
|
});
|
|||
|
data = JSON.parse(res.body).data;
|
|||
|
|
|||
|
if (data.err_code > 0) {
|
|||
|
return { ok: false, msg: '发送验证码失败:' + data.err_msg };
|
|||
|
} else {
|
|||
|
return { ok: true, msg: 'success', data: { ck: ck, gsalt: gsalt } };
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
async function checkCode(phone, code, gsalt, ck) {
|
|||
|
let appid = 959;
|
|||
|
let version = '1.0.0';
|
|||
|
let countryCode = 86;
|
|||
|
let timestamp = new Date().getTime();
|
|||
|
let subCmd = 3;
|
|||
|
let gsign = md5('' + appid + version + timestamp + '36' + subCmd + gsalt);
|
|||
|
let body =
|
|||
|
'country_code=' +
|
|||
|
countryCode +
|
|||
|
'&client_ver=' +
|
|||
|
version +
|
|||
|
'&gsign=' +
|
|||
|
gsign +
|
|||
|
'&smscode=' +
|
|||
|
code +
|
|||
|
'&appid=' +
|
|||
|
appid +
|
|||
|
'&mobile=' +
|
|||
|
phone +
|
|||
|
'&cmd=36&sub_cmd=' +
|
|||
|
subCmd +
|
|||
|
'&qversion=' +
|
|||
|
version +
|
|||
|
'&ts=' +
|
|||
|
timestamp;
|
|||
|
res = await got.post('https://qapplogin.m.jd.com/cgi-bin/qapp/quick', {
|
|||
|
method: 'post',
|
|||
|
headers: {
|
|||
|
'user-agent':
|
|||
|
'Mozilla/5.0 (Linux; Android 10; V1838T Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.87 Mobile Safari/537.36 hap/1.9/vivo com.vivo.hybrid/1.9.6.302 com.jd.crplandroidhap/1.0.3 ({packageName:com.vivo.hybrid,type:deeplink,extra:{}})',
|
|||
|
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
|||
|
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
|||
|
'accept-encoding': '',
|
|||
|
cookie: ck,
|
|||
|
},
|
|||
|
body: body,
|
|||
|
dataType: 'json',
|
|||
|
});
|
|||
|
let data = JSON.parse(res.body);
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* API 发验证码
|
|||
|
*/
|
|||
|
app.get('/sendSms', async function (request, response) {
|
|||
|
try {
|
|||
|
const phone = request.query.phone;
|
|||
|
if (!new RegExp('\\d{11}').test(phone)) {
|
|||
|
response.send({ ok: false, msg: '手机号格式错误' });
|
|||
|
return;
|
|||
|
}
|
|||
|
console.log(phone);
|
|||
|
const data = await sendSms(phone);
|
|||
|
response.send(data);
|
|||
|
} catch (err) {
|
|||
|
console.log(err);
|
|||
|
response.send({ ok: false, msg: '错误' });
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
app.post('/checkCode', async function (request, response) {
|
|||
|
try {
|
|||
|
const phone = request.query.phone;
|
|||
|
if (!new RegExp('\\d{11}').test(phone)) {
|
|||
|
response.send({ ok: false, msg: '手机号格式错误' });
|
|||
|
return;
|
|||
|
}
|
|||
|
const code = request.query.code;
|
|||
|
if (!new RegExp('\\d{6}').test(code)) {
|
|||
|
response.send({ ok: false, msg: '验证码格式错误' });
|
|||
|
return;
|
|||
|
}
|
|||
|
const { gsalt, ck } = request.body;
|
|||
|
console.log(phone, code);
|
|||
|
const data = await checkCode(phone, code, gsalt, ck);
|
|||
|
if (data.err_code > 0) {
|
|||
|
response.send({ ok: false, msg: '登录失败:' + r.err_msg });
|
|||
|
} else {
|
|||
|
const cookie =
|
|||
|
'pt_key=' +
|
|||
|
data.data.pt_key +
|
|||
|
';pt_pin=' +
|
|||
|
encodeURIComponent(data.data.pt_pin) +
|
|||
|
';';
|
|||
|
await cookieFlow(cookie, '短信登录');
|
|||
|
response.send({
|
|||
|
ok: true,
|
|||
|
msg: '获取ck成功',
|
|||
|
data: {
|
|||
|
ck: cookie,
|
|||
|
},
|
|||
|
});
|
|||
|
}
|
|||
|
} catch (err) {
|
|||
|
console.log(err);
|
|||
|
response.send({ ok: false, msg: '错误' });
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
const sleep = (ms) => {
|
|||
|
return new Promise((resolve) => {
|
|||
|
setTimeout(resolve, ms);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
app.use(express.static(path.join(__dirname, 'public')));
|
|||
|
|
|||
|
|
|||
|
const PORT = 6789;
|
|||
|
app.listen(PORT, () => {
|
|||
|
console.log(`应用正在监听 ${PORT} 端口!`);
|
|||
|
});
|