| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- /**
- * WebVPN 会话 Cookie:调用 ic-ctbu-backend-py /webvpnlogin,并可 Redis 缓存。
- */
- const axios = require('axios')
- const config = require('../../config.json')
- const db = require('../../plugin/DataBase/db')
- const Redis = require('../../plugin/DataBase/Redis')
- const CACHE_PREFIX = 'webvpn_cookie:'
- const CACHE_TTL_SEC = 25 * 60
- function webvpnLoginBaseUrl() {
- const u = config.webvpnLoginBaseUrl || config.url3
- return (u && String(u).replace(/\/$/, '')) || ''
- }
- function isProbablyVpnLoginHtml(body) {
- if (typeof body !== 'string') return false
- return (
- body.includes('lyuapServer') ||
- body.includes('ivpn') ||
- body.includes('统一认证') ||
- body.includes('rump_frontend/login')
- )
- }
- async function fetchWebVpnCookieFromPy(username, password) {
- const base = webvpnLoginBaseUrl()
- if (!base) {
- throw new Error('未配置 webvpnLoginBaseUrl')
- }
- const url = `${base}/webvpnlogin`
- const res = await axios.post(
- url,
- { username, password },
- { timeout: 120000, proxy: false, validateStatus: () => true }
- )
- const data = res.data
- if (!data || data.code !== 0 || !data.webvpn_cookie) {
- throw new Error(data?.msg || 'WebVPN 登录失败')
- }
- return String(data.webvpn_cookie)
- }
- async function getJwPasswordForUser(uuid, jwUsername) {
- const rows = await db.query(
- 'SELECT password FROM jw_account WHERE create_user = ? AND username = ? AND state IN (0, 1)',
- [uuid, jwUsername]
- )
- if (!rows || rows.length !== 1 || !rows[0].password) {
- throw new Error('未绑定教务账号或账号不可用,请先绑定教务账号')
- }
- return rows[0].password
- }
- /**
- * @param {string} createUserUuid
- * @param {string} jwUsername 教务登录名
- * @param {{ skipCache?: boolean }} [opts]
- */
- async function getWebVpnCookieHeader(createUserUuid, jwUsername, opts = {}) {
- const skipCache = opts.skipCache === true
- const key = `${CACHE_PREFIX}${createUserUuid}:${jwUsername}`
- if (!skipCache) {
- const cached = await Redis.get(key)
- if (cached) return cached
- }
- const pwd = await getJwPasswordForUser(createUserUuid, jwUsername)
- const cookie = await fetchWebVpnCookieFromPy(jwUsername, pwd)
- await Redis.set(key, cookie, { EX: CACHE_TTL_SEC })
- return cookie
- }
- async function invalidateWebVpnCookie(createUserUuid, jwUsername) {
- const key = `${CACHE_PREFIX}${createUserUuid}:${jwUsername}`
- await Redis.del(key)
- }
- module.exports = {
- webvpnLoginBaseUrl,
- isProbablyVpnLoginHtml,
- fetchWebVpnCookieFromPy,
- getWebVpnCookieHeader,
- invalidateWebVpnCookie,
- CACHE_TTL_SEC
- }
|