Commit b149c3a1 by 宋毅

增加路由

parent 027370fa
......@@ -58,6 +58,10 @@ module.exports = {
"/api/tm/status/notify",
"/api/tm/tmcase/nbtzreceiveAssistTmData",
"/api/tm/tmcase/nbtzreceiveEditAssistTmData"
],
apiAliSendKeyPathList: [
"/api/opreceive/pushAliInfo/tmNote",
"/api/opreceive/pushAliInfo/icNote",
]
},
AREACOMM: {
......
......@@ -6,700 +6,724 @@ const utilsFeishuSve = system.getObject("service.utilsSve.utilsFeishuSve");
const signSve = system.getObject("service.common.signSve");
const xml2js = require('xml2js');
const jwt = require('jsonwebtoken');
const { PDICT } = require("../../config/businessConfig");
const {PDICT} = require("../../config/businessConfig");
const settings = require("../../config/settings");
module.exports = function (app) {
//-----------------------新的模式---------web---------开始
//-----------------------新的模式---------web---------开始
app.use('/tlpay/aliPayNotify', async function (req, res) {//钉钉接入的搁浅
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.opH5AliDingPayBackNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录阿里钉钉支付回调处理结果",
op: "center-channel/tlpay/aliPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "阿里钉钉支付回调处理异常",
op: "center-channel/tlpay/aliPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
app.use('/tlpay/notify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.receiveCallBackNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录回调处理结果:,method=" + req.body.trxcode,
op: "center-channel/tlpay/notify",
content: "回调参数:" + JSON.stringify(req.body) + "回调结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录回调处理结果异常:,method=" + req.body.trxcode,
op: "center-channel/tlpay/notify",
content: "回调参数:" + JSON.stringify(req.body) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
app.use('/tlpay/opBackNotify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.opBackNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "回调处理订单结果:,method=" + req.body.trxcode,
op: "center-channel/tlpay/opBackNotify",
content: "回调参数:" + JSON.stringify(req.body) + "回调处理订单结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
res.end(JSON.stringify(result));
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录回调处理结果异常:,method=" + req.body.trxcode,
op: "center-channel/tlpay/opBackNotify",
content: "回调参数:" + JSON.stringify(req.body) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
//----------------------飞书小程序---------------------------------------------开始
app.use('/tlpay/aliPayNotify', async function (req, res) {//钉钉接入的搁浅
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.opH5AliDingPayBackNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录阿里钉钉支付回调处理结果",
op: "center-channel/tlpay/aliPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "阿里钉钉支付回调处理异常",
op: "center-channel/tlpay/aliPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
app.use('/tlpay/notify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.receiveCallBackNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录回调处理结果:,method=" + req.body.trxcode,
op: "center-channel/tlpay/notify",
content: "回调参数:" + JSON.stringify(req.body) + "回调结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录回调处理结果异常:,method=" + req.body.trxcode,
op: "center-channel/tlpay/notify",
content: "回调参数:" + JSON.stringify(req.body) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
app.use('/tlpay/opBackNotify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.opBackNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "回调处理订单结果:,method=" + req.body.trxcode,
op: "center-channel/tlpay/opBackNotify",
content: "回调参数:" + JSON.stringify(req.body) + "回调处理订单结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
res.end(JSON.stringify(result));
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录回调处理结果异常:,method=" + req.body.trxcode,
op: "center-channel/tlpay/opBackNotify",
content: "回调参数:" + JSON.stringify(req.body) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
//----------------------飞书小程序---------------------------------------------开始
//飞书通知
app.use('/feishu/notify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsFeishuSve.notify(req.body);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果,method=notify",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(req.body) + "回调结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
var returnObj = JSON.stringify(result);
return res.end(returnObj);
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果异常:,method=notify",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(req.body) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
app.use('/feishu/login', async function (req, res) {
try {
var result = system.getResult(null, "login fail");
// console.log(req,"/feishu/login++++++++++++++++++++++++++++++++++++++");
var client_ip = system.get_client_ip(req);
var pobj = req.query;
var token = pobj.state || "";
if (!token) {
result.msg = "req headers token can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
var cacheManager = system.getObject("db.common.cacheManager");
var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
if (result.status != 0) {
res.end(JSON.stringify(result));
return;
}
pobj.appInfo = result.data;
result = await utilsFeishuSve.checkAndLogin(req, pobj);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果,method=login",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(pobj) + "回调结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
var returnObj = JSON.stringify(result);
return res.end(returnObj);
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果异常:,method=login",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(req.query) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
//----------------------飞书小程序---------------------------------------------结束
//飞书通知
app.use('/feishu/notify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsFeishuSve.notify(req.body);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果,method=notify",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(req.body) + "回调结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
var returnObj = JSON.stringify(result);
return res.end(returnObj);
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果异常:,method=notify",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(req.body) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
app.use('/feishu/login', async function (req, res) {
try {
var result = system.getResult(null, "login fail");
// console.log(req,"/feishu/login++++++++++++++++++++++++++++++++++++++");
var client_ip = system.get_client_ip(req);
var pobj = req.query;
var token = pobj.state || "";
if (!token) {
result.msg = "req headers token can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
var cacheManager = system.getObject("db.common.cacheManager");
var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
if (result.status != 0) {
res.end(JSON.stringify(result));
return;
}
pobj.appInfo = result.data;
result = await utilsFeishuSve.checkAndLogin(req, pobj);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果,method=login",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(pobj) + "回调结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
var returnObj = JSON.stringify(result);
return res.end(returnObj);
} catch (error) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "飞书小程序记录回调处理结果异常:,method=login",
op: "app/config/routes/api.js/feishu/notify",
content: "回调参数:" + JSON.stringify(req.query) + "error:" + error.stack,
clientIp: client_ip || ""
});
}
});
//----------------------飞书小程序---------------------------------------------结束
// app-ali支付回调通知
app.use('/orderNotify/aliPayNotify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.aliPayNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录支付宝回调处理结果 api层",
op: "center-channel/orderNotify/aliPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
} catch (e) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "支付宝回调处理异常 api层",
op: "center-channel/orderNotify/aliPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + e.stack,
clientIp: client_ip || ""
});
}
});
// app-wx支付回调
app.use('/orderNotify/wxPayNotify', async function (req, res) {
try {
var body = "";
// app-ali支付回调通知
app.use('/orderNotify/aliPayNotify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.aliPayNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录支付宝回调处理结果 api层",
op: "center-channel/orderNotify/aliPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
} catch (e) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "支付宝回调处理异常 api层",
op: "center-channel/orderNotify/aliPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + e.stack,
clientIp: client_ip || ""
});
}
});
// app-wx支付回调
app.use('/orderNotify/wxPayNotify', async function (req, res) {
try {
var body = "";
req.on('data', function (data) {
body += data;
});
req.on('end', async function () {
xml2js.parseString(body, { trim: true, explicitArray: false, explicitRoot: false }, async function (err, json) {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.wxPayNotify(json);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录微信支付回调处理结果",
op: "center-channel/orderNotify/wxPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
})
req.on('data', function (data) {
body += data;
});
req.on('end', async function () {
xml2js.parseString(body, {
trim: true,
explicitArray: false,
explicitRoot: false
}, async function (err, json) {
var client_ip = system.get_client_ip(req);
var result = await utilsOrderSve.wxPayNotify(json);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "记录微信支付回调处理结果",
op: "center-channel/orderNotify/wxPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
if (result.status != 0) {
return res.end("FAIL");
}
return res.end("success");
})
})
} catch (e) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "微信回调处理异常",
op: "center-channel/orderNotify/wxPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + e.stack,
clientIp: client_ip || ""
});
}
});
})
} catch (e) {
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "微信回调处理异常",
op: "center-channel/orderNotify/wxPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + e.stack,
clientIp: client_ip || ""
});
}
});
app.use('/orderNotify/channelPayNotify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
let result = {};
result = await utilsOrderSve.channelPayNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "渠道支付订单通知 api层",
op: "center-channel/orderNotify/channelPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
var returnObj = JSON.stringify(result);
return res.end(returnObj);
} catch (e) {
var client_ip = system.get_client_ip(req);
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "渠道订单支付通知处理异常",
op: "center-channel/orderNotify/channelPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + e.stack,
clientIp: client_ip || ""
});
}
});
app.use('/orderNotify/channelPayNotify', async function (req, res) {
try {
var client_ip = system.get_client_ip(req);
let result = {};
result = await utilsOrderSve.channelPayNotify(req.body, client_ip);
logCtl.info({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "渠道支付订单通知 api层",
op: "center-channel/orderNotify/channelPayNotify",
content: "支付回调处理结果:" + JSON.stringify(result),
clientIp: client_ip || ""
});
var returnObj = JSON.stringify(result);
return res.end(returnObj);
} catch (e) {
var client_ip = system.get_client_ip(req);
logCtl.error({
optitle: (new Date()).Format("yyyy-MM-dd hh:mm:ss") + "渠道订单支付通知处理异常",
op: "center-channel/orderNotify/channelPayNotify",
content: "回调参数:req=" + JSON.stringify(req) + "error:" + e.stack,
clientIp: client_ip || ""
});
}
});
app.all("/web/*", async function (req, res, next) {
const self = this;
var result = system.getResult(null, "req method must is post");
if (req.method != "POST") {
res.end(JSON.stringify(result));
return;
}
if (!req.body.actionType) {
result.msg = "actionType can not be empty";
res.end(JSON.stringify(result));
return;
}
// 2020 0812 lin 只去掉了check,因为要记录智能诊断的返回值,其他接口暂时未去掉
if (["getAppTokenByHosts", "getAppTokenByAppKey", "test", "getIndustries", "getSecondIndustries", "getQualificationByIndustry", "counselling", "queryTradeProduceList"].indexOf(req.body.actionType) >= 0) {
req.body.actionBody.appHosts = req.host;
next();
return;
}
if (req.body.actionType == "receiveCallBackNotify") {
req.body.actionBody.app_hosts = req.host;
next();
return;
}
var token = req.headers["token"] || "";
if (!token) {
result.msg = "req headers token can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
//校验jwt产生的token
const tokenSecret = settings.env == "localhost" || settings.env == "dev" ? PDICT.token_secret_dev : PDICT.token_secret_prod;
let token_secret_str = null;
jwt.verify(token, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(-88, "Failed to authenticate token,error:" + err));
} else {
token_secret_str = decoded.token_secret;
}
});
let decryptResult = await utilsAuthSve.decryptInfo(token_secret_str);
if (decryptResult.status != 0) {
return res.send(system.getResultFail(-88, "Failed to authenticate token,fail:" + decryptResult.msg));
}
let tmpAppInfo = JSON.parse(decryptResult.data);
req.body.appInfo = tmpAppInfo;
req.body.actionProcess = tmpAppInfo.app_code;
app.all("/web/*", async function (req, res, next) {
const self = this;
var result = system.getResult(null, "req method must is post");
if (req.method != "POST") {
res.end(JSON.stringify(result));
return;
}
if (!req.body.actionType) {
result.msg = "actionType can not be empty";
res.end(JSON.stringify(result));
return;
}
// 2020 0812 lin 只去掉了check,因为要记录智能诊断的返回值,其他接口暂时未去掉
if (["getAppTokenByHosts", "getAppTokenByAppKey", "test", "getIndustries", "getSecondIndustries", "getQualificationByIndustry", "counselling", "queryTradeProduceList"].indexOf(req.body.actionType) >= 0) {
req.body.actionBody.appHosts = req.host;
next();
return;
}
if (req.body.actionType == "receiveCallBackNotify") {
req.body.actionBody.app_hosts = req.host;
next();
return;
}
var token = req.headers["token"] || "";
if (!token) {
result.msg = "req headers token can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
//校验jwt产生的token
const tokenSecret = settings.env == "localhost" || settings.env == "dev" ? PDICT.token_secret_dev : PDICT.token_secret_prod;
let token_secret_str = null;
jwt.verify(token, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(-88, "Failed to authenticate token,error:" + err));
} else {
token_secret_str = decoded.token_secret;
}
});
let decryptResult = await utilsAuthSve.decryptInfo(token_secret_str);
if (decryptResult.status != 0) {
return res.send(system.getResultFail(-88, "Failed to authenticate token,fail:" + decryptResult.msg));
}
let tmpAppInfo = JSON.parse(decryptResult.data);
req.body.appInfo = tmpAppInfo;
req.body.actionProcess = tmpAppInfo.app_code;
//去除缓存,改用jwt模式
// var cacheManager = system.getObject("db.common.cacheManager");
// var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
// if (result.status != 0) {
// res.end(JSON.stringify(result));
// return;
// }
// req.body.appInfo = result.data;
// req.body.actionProcess = result.data.app_code;
if (PDICT.webMustUserpinList.indexOf(req.body.actionType) >= 0) {
var userpin = req.headers["userpin"] || "";
if (!userpin) {
result.status = system.noLogin;
result.msg = "req headers userpin can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
let userpin_secret_str = null;
jwt.verify(userpin, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,error:" + err));
} else {
userpin_secret_str = decoded.userpin_secret;
}
});
let userDecryptResult = await utilsAuthSve.decryptInfo(userpin_secret_str);
if (userDecryptResult.status != 0) {
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,fail:" + userDecryptResult.msg));
}
let tmpUserInfo = JSON.parse(userDecryptResult.data);
req.body.userInfo = tmpUserInfo;
if (req.body.actionType === "getLoginInfo") {
result = system.getResultSuccess(tmpUserInfo);
res.end(JSON.stringify(result));
return;
}
// var params = {
// "appInfo": req.body.appInfo,
// "actionType": "getLoginInfo",
// "actionBody": {
// "userpin": userpin
// }
// }
// result = await utilsAuthSve.getLoginInfo(params, params.actionBody);
// if (result.status != 0) {
// result.status = system.noLogin;
// result.msg = "user login is invalidation";
// res.end(JSON.stringify(result));
// return;
// }
// req.body.userInfo = result.data;
//去除缓存,改用jwt模式
// var cacheManager = system.getObject("db.common.cacheManager");
// var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
// if (result.status != 0) {
// res.end(JSON.stringify(result));
// return;
// }
// req.body.appInfo = result.data;
// req.body.actionProcess = result.data.app_code;
if (PDICT.webMustUserpinList.indexOf(req.body.actionType) >= 0) {
var userpin = req.headers["userpin"] || "";
if (!userpin) {
result.status = system.noLogin;
result.msg = "req headers userpin can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
let userpin_secret_str = null;
jwt.verify(userpin, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,error:" + err));
} else {
userpin_secret_str = decoded.userpin_secret;
}
});
let userDecryptResult = await utilsAuthSve.decryptInfo(userpin_secret_str);
if (userDecryptResult.status != 0) {
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,fail:" + userDecryptResult.msg));
}
let tmpUserInfo = JSON.parse(userDecryptResult.data);
req.body.userInfo = tmpUserInfo;
if (req.body.actionType === "getLoginInfo") {
result = system.getResultSuccess(tmpUserInfo);
res.end(JSON.stringify(result));
return;
}
// var params = {
// "appInfo": req.body.appInfo,
// "actionType": "getLoginInfo",
// "actionBody": {
// "userpin": userpin
// }
// }
// result = await utilsAuthSve.getLoginInfo(params, params.actionBody);
// if (result.status != 0) {
// result.status = system.noLogin;
// result.msg = "user login is invalidation";
// res.end(JSON.stringify(result));
// return;
// }
// req.body.userInfo = result.data;
}//需要用户登录
next();
});
}//需要用户登录
next();
});
app.get('/web/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
app.get('/web/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
req.clientIp = tClientIp; req
req.uagent = req.headers["user-agent"];
req.classname = classPath;
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
req.clientIp = tClientIp;
req
req.uagent = req.headers["user-agent"];
req.classname = classPath;
var params = [];
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
app.post('/web/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
var params = [];
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
var params = [];
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
app.post('/web/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
var params = [];
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
req.clientIp = tClientIp;
req.uagent = req.headers["user-agent"];
req.classname = classPath;
req.clientIp = tClientIp;
req.uagent = req.headers["user-agent"];
req.classname = classPath;
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//-----------------------新的模式---------web---------结束
//-----------------------新的模式---------web---------结束
//-----------------------新的模式---------api---------开始
//-----------------------新的模式---------api---------开始
//百度手动获取签名sign方法
// app.post("/baidu/creatSign", async function (req, res, next) {
// if (!req.body.key) {
// res.end({ code: -200, message: "缺少加签秘钥key参数" });
// return;
// }
// if (!req.body.obj) {
// res.end({ code: -200, message: "缺少obj参数" });
// return;
// }
// let obj = req.body.obj;
// let key = req.body.key;
// let result = await signSve.createSign(obj, key);
// res.end(JSON.stringify(result));
// return;
// });
//百度手动获取签名sign方法
// app.post("/baidu/creatSign", async function (req, res, next) {
// if (!req.body.key) {
// res.end({ code: -200, message: "缺少加签秘钥key参数" });
// return;
// }
// if (!req.body.obj) {
// res.end({ code: -200, message: "缺少obj参数" });
// return;
// }
// let obj = req.body.obj;
// let key = req.body.key;
// let result = await signSve.createSign(obj, key);
// res.end(JSON.stringify(result));
// return;
// });
app.all("/api/*", async function (req, res, next) {
var result = system.getResult(null, "req method must is post");
if (req.method != "POST") {
res.end(JSON.stringify(result));
return;
}
if (PDICT.apiSecretPathList.indexOf(req.originalUrl) >= 0) {
//TODO:验证数据签名
var appkey = req.headers["appkey"] || "";
if (!appkey) {
result.msg = "req headers appkey can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
var sign = req.headers["sign"] || "";
if (!sign) {
result.msg = "req headers sign can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
//1.通过appkey 获取appInfo
var appRes = await signSve.getAppInfoByAppKey(appkey);
if (!appRes || appRes.status != 0) {
result.msg = "获取应用信息失败";
result.data = null;
res.end(JSON.stringify(result));
return;
}
var appInfo = appRes.data;
//2.通过appsecret 验签
req.body.sign = sign;
var signParams = req.body;
var verifyRes = await signSve.verifySign(req.body, appInfo.uapp_secret);
if (verifyRes && verifyRes.status == 0) {
req.body.appInfo = appInfo;
req.appInfo = appInfo;
req.actionProcess = appInfo.app_code;
next();
return;
} else {
res.end(JSON.stringify(verifyRes));
return;
}
app.all("/api/*", async function (req, res, next) {
var result = system.getResult(null, "req method must is post");
if (req.method != "POST") {
res.end(JSON.stringify(result));
return;
}
if (PDICT.apiAliSendKeyPathList.indexOf(req.originalUrl) >= 0) {
//验证数据key
var appkey = req.headers["appkey"] || "";
if (!appkey) {
result.msg = "req headers appkey can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
if (appkey != "201912031344") {
result.msg = "req appkey verify error";
result.data = null;
res.end(JSON.stringify(result));
return;
}
next();
return;
}
if (PDICT.apiSecretPathList.indexOf(req.originalUrl) >= 0) {
//验证数据签名
var appkey = req.headers["appkey"] || "";
if (!appkey) {
result.msg = "req headers appkey can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
var sign = req.headers["sign"] || "";
if (!sign) {
result.msg = "req headers sign can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
//1.通过appkey 获取appInfo
var appRes = await signSve.getAppInfoByAppKey(appkey);
if (!appRes || appRes.status != 0) {
result.msg = "获取应用信息失败";
result.data = null;
res.end(JSON.stringify(result));
return;
}
var appInfo = appRes.data;
//2.通过appsecret 验签
req.body.sign = sign;
var signParams = req.body;
var verifyRes = await signSve.verifySign(req.body, appInfo.uapp_secret);
if (verifyRes && verifyRes.status == 0) {
req.body.appInfo = appInfo;
req.appInfo = appInfo;
req.actionProcess = appInfo.app_code;
next();
return;
} else {
res.end(JSON.stringify(verifyRes));
return;
}
}
if (["getAppTokenByHosts", "getAppTokenByAppKey", "getTmNclFilterSearch", "feedback", "accountingInfo", "booksInfo"].indexOf(req.body.actionType) >= 0) {
req.body.actionBody.appHosts = req.host;
next();
return;
}
if (req.path.indexOf("/taskapi/") >= 0) {
next();
return;
}
if (!req.body.actionType) {
result.msg = "actionType can not be empty";
res.end(JSON.stringify(result));
return;
}
var token = req.headers["token"] || "";
if (!token) {
result.msg = "req headers token can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
//校验jwt产生的token
const tokenSecret = settings.env == "localhost" || settings.env == "dev" ? PDICT.token_secret_dev : PDICT.token_secret_prod;
let token_secret_str = null;
jwt.verify(token, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(-88, "Failed to authenticate token,error:" + err));
} else {
token_secret_str = decoded.token_secret;
}
});
let decryptResult = await utilsAuthSve.decryptInfo(token_secret_str);
if (decryptResult.status != 0) {
return res.send(system.getResultFail(-88, "Failed to authenticate token,fail:" + decryptResult.msg));
}
let tmpAppInfo = JSON.parse(decryptResult.data);
req.body.appInfo = tmpAppInfo;
req.body.actionProcess = tmpAppInfo.app_code;
// var cacheManager = system.getObject("db.common.cacheManager");
// var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
// if (result.status != 0) {
// res.end(JSON.stringify(result));
// return;
// }
// req.body.appInfo = result.data;
// req.body.actionProcess = result.data.app_code;
if (PDICT.apiMustUserpinList.indexOf(req.body.actionType) >= 0) {
var userpin = req.headers["userpin"] || "";
if (!userpin) {
result.status = system.noLogin;
result.msg = "req headers userpin can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
// var params = {
// "appInfo": req.body.appInfo,
// "actionType": "getLoginInfo",
// "actionBody": {
// "userpin": userpin
// }
// }
// result = await utilsAuthSve.getLoginInfo(params, params.actionBody);
// if (result.status != 0) {
// result.status = system.noLogin;
// result.msg = "user login is invalidation";
// res.end(JSON.stringify(result));
// return;
// }
let userpin_secret_str = null;
jwt.verify(userpin, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,error:" + err));
} else {
userpin_secret_str = decoded.userpin_secret;
}
});
let userDecryptResult = await utilsAuthSve.decryptInfo(userpin_secret_str);
if (userDecryptResult.status != 0) {
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,fail:" + userDecryptResult.msg));
}
let tmpUserInfo = JSON.parse(userDecryptResult.data);
req.body.userInfo = tmpUserInfo;
if (req.body.actionType === "getLoginInfo") {
result = system.getResultSuccess(tmpUserInfo);
res.end(JSON.stringify(result));
return;
}
}//需要用户登录
next();
});
}
if (["getAppTokenByHosts", "getAppTokenByAppKey", "getTmNclFilterSearch", "feedback", "accountingInfo", "booksInfo"].indexOf(req.body.actionType) >= 0) {
req.body.actionBody.appHosts = req.host;
next();
return;
}
if (req.path.indexOf("/taskapi/") >= 0) {
next();
return;
}
if (!req.body.actionType) {
result.msg = "actionType can not be empty";
res.end(JSON.stringify(result));
return;
}
var token = req.headers["token"] || "";
if (!token) {
result.msg = "req headers token can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
//校验jwt产生的token
const tokenSecret = settings.env == "localhost" || settings.env == "dev" ? PDICT.token_secret_dev : PDICT.token_secret_prod;
let token_secret_str = null;
jwt.verify(token, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(-88, "Failed to authenticate token,error:" + err));
} else {
token_secret_str = decoded.token_secret;
}
});
let decryptResult = await utilsAuthSve.decryptInfo(token_secret_str);
if (decryptResult.status != 0) {
return res.send(system.getResultFail(-88, "Failed to authenticate token,fail:" + decryptResult.msg));
}
let tmpAppInfo = JSON.parse(decryptResult.data);
req.body.appInfo = tmpAppInfo;
req.body.actionProcess = tmpAppInfo.app_code;
// var cacheManager = system.getObject("db.common.cacheManager");
// var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
// if (result.status != 0) {
// res.end(JSON.stringify(result));
// return;
// }
// req.body.appInfo = result.data;
// req.body.actionProcess = result.data.app_code;
if (PDICT.apiMustUserpinList.indexOf(req.body.actionType) >= 0) {
var userpin = req.headers["userpin"] || "";
if (!userpin) {
result.status = system.noLogin;
result.msg = "req headers userpin can not be empty";
result.data = null;
res.end(JSON.stringify(result));
return;
}
// var params = {
// "appInfo": req.body.appInfo,
// "actionType": "getLoginInfo",
// "actionBody": {
// "userpin": userpin
// }
// }
// result = await utilsAuthSve.getLoginInfo(params, params.actionBody);
// if (result.status != 0) {
// result.status = system.noLogin;
// result.msg = "user login is invalidation";
// res.end(JSON.stringify(result));
// return;
// }
let userpin_secret_str = null;
jwt.verify(userpin, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,error:" + err));
} else {
userpin_secret_str = decoded.userpin_secret;
}
});
let userDecryptResult = await utilsAuthSve.decryptInfo(userpin_secret_str);
if (userDecryptResult.status != 0) {
return res.send(system.getResultFail(system.noLogin, "Failed to authenticate userpin,fail:" + userDecryptResult.msg));
}
let tmpUserInfo = JSON.parse(userDecryptResult.data);
req.body.userInfo = tmpUserInfo;
if (req.body.actionType === "getLoginInfo") {
result = system.getResultSuccess(tmpUserInfo);
res.end(JSON.stringify(result));
return;
}
}//需要用户登录
next();
});
app.get('/api/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
app.get('/api/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
req.clientIp = tClientIp; req
req.uagent = req.headers["user-agent"];
req.classname = classPath;
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
req.clientIp = tClientIp;
req
req.uagent = req.headers["user-agent"];
req.classname = classPath;
var params = [];
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
app.post('/api/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
var params = [];
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
var params = [];
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
app.post('/api/:gname/:qname/:method', function (req, res) {
var classPath = req.params["qname"];
var methodName = req.params["method"];
var gname = req.params["gname"];
var params = [];
classPath = gname + "." + classPath;
var tClientIp = system.get_client_ip(req);
req.clientIp = tClientIp;
req.uagent = req.headers["user-agent"];
req.classname = classPath;
req.clientIp = tClientIp;
req.uagent = req.headers["user-agent"];
req.classname = classPath;
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
params.push(gname);
params.push(methodName);
params.push(req.body);
params.push(req.query);
params.push(req);
var p = null;
var invokeObj = system.getObject("api." + classPath);
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//-----------------------新的模式---------api---------结束
//-----------------------新的模式---------ICP---------开始
app.all("/icp/*", async function (req, res, next) {
var result = system.getResult(null, "req method must is post");
if (req.method != "POST") {
res.end(JSON.stringify(result));
return;
}
// var token = req.headers["token"] || "";
// if (!token) {
// var resfail = {
// "success": false,
// "errorMsg": "req headers token can not be empty",
// "errorCode": "ok"
// };
// res.end(JSON.stringify(resfail));
// return;
// }
// var cacheManager = system.getObject("db.common.cacheManager");
// var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
// if (result.status != 0) {
// var resfail = {
// "success": false,
// "errorMsg": result.msg || "token error",
// "errorCode": "ok"
// };
// res.end(JSON.stringify(resfail));
// // res.end(JSON.stringify(result));
// return;
// }
// req.appInfo = result.data;
// req.body.appInfo = result.data;
// req.actionProcess = result.data.app_code;
var token = req.headers["token"] || "";
if (!token) {
var resfail = {
"success": false,
"errorMsg": "req headers token can not be empty",
"errorCode": "ok"
};
res.end(JSON.stringify(resfail));
return;
}
//校验jwt产生的token
const tokenSecret = settings.env == "localhost" || settings.env == "dev" ? PDICT.token_secret_dev : PDICT.token_secret_prod;
let token_secret_str = null;
jwt.verify(token, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(-88, "Failed to authenticate token,error:" + err));
} else {
token_secret_str = decoded.token_secret;
}
});
let decryptResult = await utilsAuthSve.decryptInfo(token_secret_str);
if (decryptResult.status != 0) {
return res.send(system.getResultFail(-88, "Failed to authenticate token,fail:" + decryptResult.msg));
}
let tmpAppInfo = JSON.parse(decryptResult.data);
req.body.appInfo = tmpAppInfo;
req.appInfo = tmpAppInfo;
req.actionProcess = tmpAppInfo.app_code;
next();
});
//icp需求推送
app.post('/icp/consultation/submit', function (req, res) {
var p = null;
var params = ["icpnotify", "icpSubmitNeed", req.body, req.query, req];
// gname, methodname, pobj, query, req
var invokeObj = system.getObject("api.action.icpnotify");
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//⽤户反馈需求通知服务商
app.post('/icp/feedback/submit', function (req, res) {
var p = null;
req.body.action_type = "icpFeedbackSubmit";
var params = ["icpnotify", "icpFeedbackSubmit", req.body, req.query, req];
// gname, methodname, pobj, query, req
var invokeObj = system.getObject("api.action.icpnotify");
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//推送订单信息
app.post('/icp/order/notify', function (req, res) {
var p = null;
req.body.action_type = "icpNotify";
var params = ["icpnotify", "icpNotify", req.body, req.query, req];
// gname, methodname, pobj, query, req
var invokeObj = system.getObject("api.action.icpnotify");
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//-----------------------新的模式---------ICP---------结束
//-----------------------新的模式---------api---------结束
//-----------------------新的模式---------ICP---------开始
app.all("/icp/*", async function (req, res, next) {
var result = system.getResult(null, "req method must is post");
if (req.method != "POST") {
res.end(JSON.stringify(result));
return;
}
// var token = req.headers["token"] || "";
// if (!token) {
// var resfail = {
// "success": false,
// "errorMsg": "req headers token can not be empty",
// "errorCode": "ok"
// };
// res.end(JSON.stringify(resfail));
// return;
// }
// var cacheManager = system.getObject("db.common.cacheManager");
// var result = await cacheManager["AppTokenByHostsCache"].getCache(token, system.exTime);
// if (result.status != 0) {
// var resfail = {
// "success": false,
// "errorMsg": result.msg || "token error",
// "errorCode": "ok"
// };
// res.end(JSON.stringify(resfail));
// // res.end(JSON.stringify(result));
// return;
// }
// req.appInfo = result.data;
// req.body.appInfo = result.data;
// req.actionProcess = result.data.app_code;
var token = req.headers["token"] || "";
if (!token) {
var resfail = {
"success": false,
"errorMsg": "req headers token can not be empty",
"errorCode": "ok"
};
res.end(JSON.stringify(resfail));
return;
}
//校验jwt产生的token
const tokenSecret = settings.env == "localhost" || settings.env == "dev" ? PDICT.token_secret_dev : PDICT.token_secret_prod;
let token_secret_str = null;
jwt.verify(token, tokenSecret, function (err, decoded) { // decoded:指的是token解码后用户信息
if (err) { //如果token过期则会执行err的代码块
return res.send(system.getResultFail(-88, "Failed to authenticate token,error:" + err));
} else {
token_secret_str = decoded.token_secret;
}
});
let decryptResult = await utilsAuthSve.decryptInfo(token_secret_str);
if (decryptResult.status != 0) {
return res.send(system.getResultFail(-88, "Failed to authenticate token,fail:" + decryptResult.msg));
}
let tmpAppInfo = JSON.parse(decryptResult.data);
req.body.appInfo = tmpAppInfo;
req.appInfo = tmpAppInfo;
req.actionProcess = tmpAppInfo.app_code;
next();
});
//icp需求推送
app.post('/icp/consultation/submit', function (req, res) {
var p = null;
var params = ["icpnotify", "icpSubmitNeed", req.body, req.query, req];
// gname, methodname, pobj, query, req
var invokeObj = system.getObject("api.action.icpnotify");
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//⽤户反馈需求通知服务商
app.post('/icp/feedback/submit', function (req, res) {
var p = null;
req.body.action_type = "icpFeedbackSubmit";
var params = ["icpnotify", "icpFeedbackSubmit", req.body, req.query, req];
// gname, methodname, pobj, query, req
var invokeObj = system.getObject("api.action.icpnotify");
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//推送订单信息
app.post('/icp/order/notify', function (req, res) {
var p = null;
req.body.action_type = "icpNotify";
var params = ["icpnotify", "icpNotify", req.body, req.query, req];
// gname, methodname, pobj, query, req
var invokeObj = system.getObject("api.action.icpnotify");
if (invokeObj["doexecMethod"]) {
p = invokeObj["doexecMethod"].apply(invokeObj, params);
}
p.then(r => {
res.end(JSON.stringify(r));
});
});
//-----------------------新的模式---------ICP---------结束
};
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment