修复 openapi 鉴权提示

This commit is contained in:
whyour 2026-06-26 15:31:25 +08:00
parent 3044f63f03
commit 5fbff0e1c8
2 changed files with 28 additions and 18 deletions

View File

@ -12,6 +12,7 @@ import { IKeyvStore, shareStore } from '../shared/store';
import { isValidToken } from '../shared/auth'; import { isValidToken } from '../shared/auth';
import path from 'path'; import path from 'path';
import { t } from '../shared/i18n'; import { t } from '../shared/i18n';
import { AppScope } from '../data/open';
export default ({ app }: { app: Application }) => { export default ({ app }: { app: Application }) => {
// Security: Enable strict routing to prevent case-insensitive path bypass // Security: Enable strict routing to prevent case-insensitive path bypass
@ -87,17 +88,26 @@ export default ({ app }: { app: Application }) => {
const currentToken = doc.tokens.find((x) => x.value === headerToken); const currentToken = doc.tokens.find((x) => x.value === headerToken);
const keyMatch = pathLower.match(/\/open\/([a-z]+)\/*/); const keyMatch = pathLower.match(/\/open\/([a-z]+)\/*/);
const key = keyMatch && keyMatch[1]; const key = keyMatch && keyMatch[1];
if (
doc.scopes.includes(key as any) && if (!doc.scopes.includes(key as AppScope)) {
currentToken && const err = new UnauthorizedError('credentials_bad_scheme', {
currentToken.expiration >= Math.round(Date.now() / 1000) message: t('暂无权限'),
) { });
return next(err);
}
if (!currentToken || currentToken.expiration < Math.round(Date.now() / 1000)) {
const err = new UnauthorizedError('invalid_token', {
message: t('Token 已失效'),
});
return next(err);
}
return next(); return next();
} }
} }
}
const originPath = `${req.baseUrl}${req.path === '/' ? '' : req.path}`; const originPath = `${req.baseUrl}${pathLower === '/' ? '' : pathLower}`;
if ( if (
!headerToken && !headerToken &&
originPath && originPath &&
@ -113,8 +123,8 @@ export default ({ app }: { app: Application }) => {
const errorCode = headerToken ? 'invalid_token' : 'credentials_required'; const errorCode = headerToken ? 'invalid_token' : 'credentials_required';
const errorMessage = headerToken const errorMessage = headerToken
? 'jwt malformed' ? t('Token 已失效')
: 'No authorization token was found'; : t('请先登录');
const err = new UnauthorizedError(errorCode, { message: errorMessage }); const err = new UnauthorizedError(errorCode, { message: errorMessage });
next(err); next(err);
}); });
@ -127,7 +137,7 @@ export default ({ app }: { app: Application }) => {
'/api/user/notification/init', '/api/user/notification/init',
'/open/user/init', '/open/user/init',
'/open/user/notification/init', '/open/user/notification/init',
].includes(req.path) ].includes(pathLower)
) { ) {
return next(); return next();
} }

View File

@ -82,7 +82,7 @@ const messages: Record<string, Record<string, string>> = {
'Url 或者 Body 中必须包含 $title': 'Url or Body must contain $title', 'Url 或者 Body 中必须包含 $title': 'Url or Body must contain $title',
'绝对路径必须在日志目录内或使用 /dev/null': '绝对路径必须在日志目录内或使用 /dev/null':
'Absolute path must be within log directory or use /dev/null', 'Absolute path must be within log directory or use /dev/null',
'请先登录!': 'Please login first!', '请先登录': 'Please login first',
'运行中...': 'Running...', '运行中...': 'Running...',
'日志不存在...': 'Log does not exist...', '日志不存在...': 'Log does not exist...',
'未分类': 'Uncategorized', '未分类': 'Uncategorized',