officialAccountAccess.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. const db = require('../../plugin/DataBase/db')
  2. const AccessControl = require('../AccessControl')
  3. const { BaseStdResponse } = require('../../BaseStdResponse')
  4. function isMissing(value) {
  5. return value === '' || value === null || value === undefined
  6. }
  7. function errorResponse(base, msg) {
  8. return { ...base, msg }
  9. }
  10. async function queryAccount(studentNum) {
  11. const rows = await db.query(
  12. `SELECT uid, token, school_id, student_num, userAgent, state, create_user
  13. FROM lepao_account
  14. WHERE student_num = ?`,
  15. [studentNum]
  16. )
  17. return rows?.[0] || null
  18. }
  19. function validateRunnableAccount(account) {
  20. if (!account) {
  21. return errorResponse(BaseStdResponse.ERR, '未找到该乐跑账号')
  22. }
  23. if (account.state !== 1) {
  24. return errorResponse(BaseStdResponse.ERR, '仅状态为正常的账号可查看官方记录')
  25. }
  26. if (!account.uid || !account.token || !account.school_id) {
  27. return errorResponse(BaseStdResponse.ERR, '乐跑账号登录信息不完整,请使用登录器更新账号')
  28. }
  29. return null
  30. }
  31. async function loadUserOfficialAccount(uuid, studentNum) {
  32. const account = await queryAccount(studentNum)
  33. if (!account || account.create_user !== uuid) {
  34. return {
  35. error: errorResponse(BaseStdResponse.ERR, '未找到该乐跑账号或无权限操作')
  36. }
  37. }
  38. const invalid = validateRunnableAccount(account)
  39. if (invalid) return { error: invalid }
  40. return { account }
  41. }
  42. async function loadAdminOfficialAccount(uuid, studentNum) {
  43. const permission = await AccessControl.getPermission(uuid)
  44. if (!permission.includes('admin') && !permission.includes('service') && !permission.includes('server')) {
  45. return {
  46. error: BaseStdResponse.PERMISSION_DENIED
  47. }
  48. }
  49. const account = await queryAccount(studentNum)
  50. const invalid = validateRunnableAccount(account)
  51. if (invalid) return { error: invalid }
  52. return { account }
  53. }
  54. function isLoginExpiredError(error) {
  55. const msg = error?.message || ''
  56. return (
  57. error?.code === 'LEPAO_LOGIN_EXPIRED' ||
  58. String(msg).includes('重新登录') ||
  59. String(msg).includes('登录已过期') ||
  60. String(msg).includes('登录失效')
  61. )
  62. }
  63. async function markAccountLoginExpired(studentNum, logger) {
  64. if (!studentNum) return
  65. try {
  66. await db.query('UPDATE lepao_account SET state = 0, update_time = ? WHERE student_num = ?', [
  67. Date.now(),
  68. studentNum
  69. ])
  70. logger?.warn?.(`${studentNum} 官方乐跑登录已失效,账号状态已更新为未登录`)
  71. } catch (updateError) {
  72. logger?.error?.(`更新乐跑账号登录状态失败 ${studentNum}: ${updateError.stack || updateError}`)
  73. }
  74. }
  75. async function mapOfficialError(error, studentNum, logger) {
  76. if (isLoginExpiredError(error)) {
  77. await markAccountLoginExpired(studentNum, logger)
  78. return errorResponse(BaseStdResponse.ERR, '乐跑登录已过期,请使用登录器更新账号')
  79. }
  80. const msg = error?.message || '获取官方乐跑记录失败'
  81. return errorResponse(BaseStdResponse.ERR, msg)
  82. }
  83. module.exports = {
  84. isMissing,
  85. loadUserOfficialAccount,
  86. loadAdminOfficialAccount,
  87. isLoginExpiredError,
  88. markAccountLoginExpired,
  89. mapOfficialError
  90. }