|
|
@@ -1,9 +1,38 @@
|
|
|
import crypto from "crypto";
|
|
|
import axios from "axios";
|
|
|
+import dotenv from 'dotenv';
|
|
|
|
|
|
-const API_BASE_URL = 'https://dev.api.ppai.win/api/p/gate';
|
|
|
-const APP_ID = 'ppai.partner.taoge';
|
|
|
-const APP_KEY = '7F9AE8D6D2B9D39B7D76AA1EC06A5534';
|
|
|
+import path from "path";
|
|
|
+import { fileURLToPath } from "url";
|
|
|
+
|
|
|
+import { getData } from "../libs/cache.js";
|
|
|
+import Logs from "../libs/logs.js";
|
|
|
+
|
|
|
+dotenv.config();
|
|
|
+
|
|
|
+const __filename = fileURLToPath(import.meta.url);
|
|
|
+const __dirname = path.dirname(__filename);
|
|
|
+
|
|
|
+const PARTNER_DATA_FILE = path.join(__dirname, '../data/partner.json');
|
|
|
+
|
|
|
+/**
|
|
|
+ * Partner API environment variables
|
|
|
+ */
|
|
|
+const PARTNER_API_BASE = 'https://dev.api.ppai.win/api/p/gate';
|
|
|
+const { PARTNER_APP_ID, PARTNER_APP_KEY } = process.env;
|
|
|
+
|
|
|
+const PARTNER_DATA = {};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 加载本地数据
|
|
|
+ */
|
|
|
+const loadLocalData = async () => {
|
|
|
+ const data = await getData(PARTNER_DATA_FILE);
|
|
|
+ Object.assign(PARTNER_DATA, data);
|
|
|
+}
|
|
|
+loadLocalData().catch(error => {
|
|
|
+ Logs.out('not load partner data', error.message);
|
|
|
+});
|
|
|
|
|
|
/**
|
|
|
* 生成SHA256
|
|
|
@@ -34,18 +63,26 @@ const getTimestamp = () => {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 请求数据接口
|
|
|
+ * 时间窗口校验
|
|
|
+ */
|
|
|
+const isTimestampValid = (timestamp, window=300) => {
|
|
|
+ const now = getTimestamp();
|
|
|
+ return Math.abs(now - timestamp) <= window;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 请求Partner数据接口
|
|
|
*/
|
|
|
export const requestData = async (action, data) => {
|
|
|
const timestamp = getTimestamp();
|
|
|
const nonce = generateNonce();
|
|
|
- const sign = generateSignature(APP_KEY, action, timestamp, nonce);
|
|
|
- const appid = APP_ID;
|
|
|
+ const sign = generateSignature(PARTNER_APP_KEY, action, timestamp, nonce);
|
|
|
+ const appid = PARTNER_APP_ID;
|
|
|
const requestData = { action, appid, nonce, sign, timestamp };
|
|
|
if (Object.keys(data).length > 0) {
|
|
|
requestData.params = data;
|
|
|
}
|
|
|
- return axios.post(API_BASE_URL, requestData).then(res => res.data);
|
|
|
+ return axios.post(PARTNER_API_BASE, requestData).then(res => res.data);
|
|
|
}
|
|
|
|
|
|
export const updateSolutions = async (solutions) => {
|
|
|
@@ -55,4 +92,23 @@ export const updateSolutions = async (solutions) => {
|
|
|
return requestData('opps.soccer', solutions);
|
|
|
}
|
|
|
|
|
|
-export default { updateSolutions };
|
|
|
+/**
|
|
|
+ * 接收Partner数据
|
|
|
+ */
|
|
|
+export const receivePartnerData = async (data) => {
|
|
|
+ const { action, appid, nonce, sign, timestamp, params } = data;
|
|
|
+ if (!isTimestampValid(timestamp)) {
|
|
|
+ return Promise.reject(new Error('timestamp invalid'));
|
|
|
+ }
|
|
|
+ const partnerData = PARTNER_DATA[appid];
|
|
|
+ if (!partnerData) {
|
|
|
+ return Promise.reject(new Error('appid invalid'));
|
|
|
+ }
|
|
|
+ const newSign = generateSignature(partnerData.appkey, action, timestamp, nonce);
|
|
|
+ if (newSign !== sign) {
|
|
|
+ return Promise.reject(new Error('sign invalid'));
|
|
|
+ }
|
|
|
+ return Promise.resolve({ action, params });
|
|
|
+}
|
|
|
+
|
|
|
+export default { updateSolutions, receivePartnerData };
|