All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- 新增 ENERGY_ACCESS_ROLES 与 canAccessEnergy(roles) 守卫(全量权限角色亦可访问) - 后端 /api/energy/* 加模块级守卫:无角色返回 403 - 前端 App.tsx 按角色动态注入 EnergyModule,无权限时主导航不显示 - dev mock 用户(前端 + 后端)追加 BI-LEADER-ENERGY 便于本地调试 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import type { Context, Next } from 'hono';
|
|
import jwt from 'jsonwebtoken';
|
|
import type { JwtPayload, AuthUser } from './types.js';
|
|
|
|
const JWT_SECRET = process.env.JWT_SECRET || 'ln-bi-default-secret';
|
|
|
|
// 临时:跳过所有认证(保留完整逻辑便于快速恢复)
|
|
const BYPASS_AUTH = false;
|
|
|
|
export async function authMiddleware(c: Context, next: Next) {
|
|
const path = c.req.path;
|
|
|
|
if (BYPASS_AUTH) {
|
|
return next();
|
|
}
|
|
|
|
// 本地开发免登录开关:.env 里设 DEV_BYPASS_AUTH=1 启用
|
|
if (process.env.DEV_BYPASS_AUTH === '1') {
|
|
const devUser: AuthUser = {
|
|
userId: 'dev-local',
|
|
userName: '本地开发',
|
|
loginName: 'dev-local',
|
|
depCode: '',
|
|
depName: '',
|
|
permissionLevel: 'full',
|
|
roles: ['所有权限', 'BI-SCHEDULE-OPT', 'BI-ADMIN-FEEDBACK', 'BI-LEADER-ENERGY'],
|
|
};
|
|
c.set('user', devUser);
|
|
return next();
|
|
}
|
|
|
|
// 跳过不需要认证的路径
|
|
if (path === '/api/health' || path.startsWith('/api/auth/')) {
|
|
return next();
|
|
}
|
|
|
|
const authHeader = c.req.header('Authorization');
|
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
return c.json({ error: 'Unauthorized' }, 401);
|
|
}
|
|
|
|
const token = authHeader.slice(7);
|
|
|
|
try {
|
|
const payload = jwt.verify(token, JWT_SECRET) as JwtPayload;
|
|
const user: AuthUser = {
|
|
userId: payload.userId,
|
|
userName: payload.userName,
|
|
loginName: payload.loginName,
|
|
depCode: payload.depCode,
|
|
depName: payload.depName,
|
|
permissionLevel: payload.permissionLevel,
|
|
roles: payload.roles ?? [],
|
|
};
|
|
c.set('user', user);
|
|
return next();
|
|
} catch {
|
|
return c.json({ error: 'Invalid or expired token' }, 401);
|
|
}
|
|
}
|