{"record":{"id":"8e0adbee8127d49c","repo":"yikart/AiToEarn","slug":"2-8e0adb","errorCode":null,"errorMessage":"需要管理员权限2","messagePattern":"需要管理员权限2","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"project/aitoearn-electron/server/src/auth/manager.guard.ts","lineNumber":62,"sourceCode":"\n    const request = context.switchToHttp().getRequest();\n    const token = this.extractTokenFromHeader(request);\n    if (!token) {\n      throw new UnauthorizedException('token不存在,需要管理员权限');\n    }\n\n    try {\n      const payload = await this.jwtService.verifyAsync(token, {\n        secret: process.env.AUTH_SECRET,\n      });\n\n      if (!payload.isManager) {\n        throw new UnauthorizedException('需要管理员权限1');\n      }\n\n      request['user'] = payload;\n    } catch {\n      throw new UnauthorizedException('需要管理员权限2');\n    }\n    return true;\n  }\n\n  private extractTokenFromHeader(request: Request): string | undefined {\n    const [type, token] = request.headers.authorization?.split(' ') ?? [];\n    return type === 'Bearer' ? token : undefined;\n  }\n}\n","sourceCodeStart":44,"sourceCodeEnd":72,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/server/src/auth/manager.guard.ts#L44-L72","documentation":"The catch-all of ManagerGuard.canActivate: any failure during jwtService.verifyAsync (expired token, bad signature, malformed token) is swallowed and rethrown as UnauthorizedException '需要管理员权限2'. This masks the underlying JWT error, so any invalid manager token produces this message — including the inner '需要管理员权限1' being caught and replaced.","triggerScenarios":"verifyAsync throws — expired JWT, wrong AUTH_SECRET, malformed token, or the inner UnauthorizedException from the isManager check being caught by this catch block.","commonSituations":"Expired manager session; secret mismatch after deploy; debugging confusion because the '权限1' message never surfaces and always becomes '权限2'.","solutions":["Re-login as manager to get a fresh valid token.","Refactor the catch to rethrow the inner UnauthorizedException instead of masking it.","Log the original error in the catch block to see whether it was expiry, signature, or the isManager check.","Confirm AUTH_SECRET env var is set and identical on all instances."],"exampleFix":"// before\n} catch {\n  throw new UnauthorizedException('需要管理员权限2');\n}\n// after\n} catch (e) {\n  if (e instanceof UnauthorizedException) throw e;\n  throw new UnauthorizedException('需要管理员权限2');\n}","handlingStrategy":"try-catch","validationCode":"function tokenLooksValid(token) {\n  const t = token.replace(/^Bearer\\s+/, '');\n  if (t.split('.').length !== 3) return false;\n  const payload = JSON.parse(atob(t.split('.')[1]));\n  return payload.exp * 1000 > Date.now() && payload.isManager === true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await adminApi.call(managerToken);\n} catch (e) {\n  if (e?.response?.status === 401 && e.message.includes('需要管理员权限2')) {\n    await reloginAsManager(); // verify 失败：过期/签名错误/格式错误，重新登录\n  } else throw e;\n}","preventionTips":["Since the guard masks the real cause ('权限2'), check token exp and signature client-side before calling.","Keep AUTH_SECRET stable across deploys or support dual-secret grace verification.","Re-login when any admin 401 occurs — retrying the same token will fail identically.","Report/fix the guard to rethrow inner UnauthorizedException so '权限1' is distinguishable."],"tags":["jwt","auth","guard","swallowed-error","http-401"],"backgroundTag":"jwt-verification-failed","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}