UNPKG

cea-check-in

Version:

check in plugin for cea

193 lines (192 loc) 6.33 kB
import crypto from "crypto"; import { CampusphereEndpoint } from "cea-core"; import { handleCookie, log, sstore } from "cea-core"; import fetch from "node-fetch"; import * as uuid from "uuid"; import { LogInfoKeys } from "./types.js"; const _CheckIn = class { constructor(user) { const school = sstore.get("schools")[user.school]; this.school = school; this.user = user; this.headers = { "user-agent": "Mozilla/5.0 (Linux; Android 10; GM1910 Build/QKQ1.190716.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36 cpdaily/8.2.13 wisedu/8.2.13", "content-type": "application/json" }; } async signInfo() { var _a; const { user, school } = this; const storeCookiePath = `cookie.${user.alias}`; const cookie = sstore.get(storeCookiePath); const campusCookieIdx = new URL(school.campusphere).host; if (!cookie) { return; } this.headers.cookie = cookie[campusCookieIdx]; const res = await fetch(`${school.campusphere}${CampusphereEndpoint.getStuSignInfosInOneDay}`, { method: "POST", headers: this.headers, body: JSON.stringify({}) }); if ((_a = res.headers.get("content-type")) == null ? void 0 : _a.includes("json")) { const signQ = await res.json(); const isValidCookie = signQ.message === "SUCCESS"; if (isValidCookie) { return signQ.datas; } } } async signWithForm(curTask) { const { school, headers, user } = this; const { signInstanceWid, signWid } = curTask; let res = await fetch(`${school.campusphere}${CampusphereEndpoint.detailSignInstance}`, { headers, method: "POST", body: JSON.stringify({ signInstanceWid, signWid }) }); const signDetails = (await res.json()).datas; let { extraField, longitude, latitude, signPlaceSelected, isNeedExtra, signedStuInfo } = signDetails; let position; const placeList = signPlaceSelected[0]; const isSignAtHome = !Boolean(school.defaultAddr); [longitude, latitude, position] = isSignAtHome ? this.user.addr : [placeList.longitude, placeList.latitude, school.defaultAddr]; const extraFieldItems = _CheckIn.fillExtra(extraField); const formBody = { longitude: _CheckIn.fixedFloatRight(longitude), latitude: _CheckIn.fixedFloatRight(latitude), isMalposition: isSignAtHome ? 1 : 0, abnormalReason: "", signPhotoUrl: "", isNeedExtra, position, uaIsCpadaily: true, signInstanceWid, extraFieldItems }; const bodyString = _CheckIn.formBodyEncrypt(formBody); const signHashBody = { appVersion: _CheckIn.VERSION.app, bodyString, deviceId: uuid.v1(), lat: formBody.latitude, lon: formBody.longitude, model: "Cock", systemName: "android", systemVersion: "11", userId: this.user.username }; const signExtensionBody = { ...signHashBody, bodyString: void 0 }; const signHash = crypto.createHash("md5").update(`${new URLSearchParams(signHashBody).toString()}&${_CheckIn.FORMBODY_ENCRYPT.key}`).digest("hex"); const postBody = { sign: signHash, version: _CheckIn.VERSION.version, calVersion: _CheckIn.VERSION.calVersion, ...signHashBody }; headers["Cpdaily-Extension"] = _CheckIn.extensionEncrypt(signExtensionBody); res = await fetch(`${school.campusphere}${CampusphereEndpoint.submitSign}`, { headers, method: "POST", body: JSON.stringify(postBody) }); const result = await res.json(); const logInfo = { [LogInfoKeys.result]: result.message, [LogInfoKeys.addr]: formBody.position }; if (process.env.GITHUB_ACTION) { delete logInfo[LogInfoKeys.addr]; } return logInfo; } static fixedFloatRight(floatStr) { return parseFloat(floatStr.replace(/(\d+\.\d{5})(\d{1})(.*)/, (s, p, p2) => `${p}${p2 == 0 ? 1 : p2}`)); } static fillExtra(extraField) { return extraField.map((e) => { let chosenWid; const normal = e.extraFieldItems.filter((i) => { if (i.isAbnormal === false) chosenWid = i.wid; return !i.isAbnormal; })[0]; return { extraFieldItemWid: chosenWid, extraFieldItemValue: normal.content }; }); } static extensionEncrypt(body) { const { algo, key, iv } = _CheckIn.EXTENSION_ENCRYPT; const cipher = crypto.createCipheriv(algo, key, iv); let encrypted = cipher.update(JSON.stringify(body), "utf8", "base64"); encrypted += cipher.final("base64"); return encrypted; } static formBodyEncrypt(body) { const { algo, key, iv } = _CheckIn.FORMBODY_ENCRYPT; const cipher = crypto.createCipheriv(algo, key, iv); let encrypted = cipher.update(JSON.stringify(body), "utf8", "base64"); encrypted += cipher.final("base64"); return encrypted; } }; export let CheckIn = _CheckIn; CheckIn.VERSION = { app: "9.0.12", version: "first_v2", calVersion: "firstv" }; CheckIn.EXTENSION_ENCRYPT = { key: "b3L26XNL", iv: Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]), algo: "des-cbc" }; CheckIn.FORMBODY_ENCRYPT = { key: "ytUQ7l2ZZu8mLvJZ", iv: Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7]), algo: "aes-128-cbc" }; export async function checkIn() { await handleCookie(); const users = sstore.get("users"); if (users == null ? void 0 : users.length) { const logs = await signIn(users); if (logs) { console.table(logs); } } } async function signIn(users) { const logs = {}; await Promise.all(users.map(async (i) => { const instance = new CheckIn(i); const curTask = await instance.signInfo(); if (curTask) { const needCheckInTasks = curTask.unSignedTasks.concat(curTask.leaveTasks); if (needCheckInTasks.length) { const result = await instance.signWithForm(needCheckInTasks[0]); logs[i.alias] = result; } else { logs[i.alias] = { [LogInfoKeys.result]: `\u5DF2\u5B8C\u6210\uFF1A${curTask.signedTasks[0].taskName}` }; } } })); log.notify(`\u7B7E\u5230\u7ED3\u679C => ${JSON.stringify(logs, null, " ")}`); return Object.keys(logs).length ? logs : null; } //# sourceMappingURL=index.js.map