/**
* Token 驗證 Middleware
* 從 Authorization header 提取 Token,查詢 FX-CRM 驗證用戶身份
*/
import type { Request, Response, NextFunction } from 'express'
import type { UserIdentity } from '@mcp-internal/shared'
import { ErrorCode } from '@mcp-internal/shared'
import { validateFsuid } from '../services/fxcrm/personnel.js'
/** 擴展 Express Request 型別 */
declare global {
namespace Express {
interface Request {
user?: UserIdentity
}
}
}
/**
* Token 驗證 Middleware
*/
export async function tokenAuth(
req: Request,
res: Response,
next: NextFunction
): Promise<void> {
const authHeader = req.headers.authorization
// 檢查 Authorization header
if (!authHeader) {
res.status(401).json({
success: false,
error: {
code: ErrorCode.UNAUTHORIZED,
message: '缺少 Authorization header',
},
})
return
}
// 解析 Bearer token
const match = authHeader.match(/^Bearer\s+(.+)$/i)
if (!match) {
res.status(401).json({
success: false,
error: {
code: ErrorCode.INVALID_TOKEN,
message: 'Authorization header 格式不正確,應為 Bearer <token>',
},
})
return
}
const token = match[1]
// 驗證 FSUID
const user = await validateFsuid(token)
if (!user) {
res.status(401).json({
success: false,
error: {
code: ErrorCode.INVALID_TOKEN,
message: 'FSUID 無效或用戶不存在',
},
})
return
}
// 將用戶資訊附加到 request
req.user = user
next()
}
/**
* 可選的 Token 驗證 Middleware(允許未認證請求)
*/
export async function optionalTokenAuth(
req: Request,
_res: Response,
next: NextFunction
): Promise<void> {
const authHeader = req.headers.authorization
if (authHeader) {
const match = authHeader.match(/^Bearer\s+(.+)$/i)
if (match) {
const user = await validateFsuid(match[1])
if (user) {
req.user = user
}
}
}
next()
}