fix: harden tenant auth and quality gates
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/common';
|
||||
import { ForbiddenException, Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { AuthSessionRecord, SessionPortal, SessionService } from './session.service';
|
||||
|
||||
@@ -8,6 +8,7 @@ export type SessionRequest = {
|
||||
url?: string;
|
||||
sessionUserId?: string;
|
||||
sessionToken?: string;
|
||||
sessionTenantId?: string;
|
||||
authSession?: AuthSessionRecord;
|
||||
};
|
||||
|
||||
@@ -38,7 +39,7 @@ export class SessionValidationMiddleware implements NestMiddleware {
|
||||
|
||||
const user = await this.prisma.user.findUnique({
|
||||
where: { id: result.record.userId },
|
||||
select: { id: true, status: true, deletedAt: true, sessionVersion: true },
|
||||
select: { id: true, tenantId: true, status: true, deletedAt: true, sessionVersion: true },
|
||||
});
|
||||
if (!user || user.status !== 'active' || user.deletedAt || user.sessionVersion !== result.record.sessionVersion) {
|
||||
await this.sessions.remove(token);
|
||||
@@ -51,6 +52,25 @@ export class SessionValidationMiddleware implements NestMiddleware {
|
||||
request.sessionUserId = user.id;
|
||||
request.sessionToken = token;
|
||||
request.authSession = result.record;
|
||||
if (portal === 'client') {
|
||||
if (!user.tenantId) {
|
||||
throw new ForbiddenException({ code: 'CLIENT_TENANT_REQUIRED', message: '当前客户端账号未关联企业' });
|
||||
}
|
||||
const suppliedTenantId = request.header('x-tenant-id')?.trim();
|
||||
if (suppliedTenantId && suppliedTenantId !== user.tenantId) {
|
||||
await this.prisma.operationLog.create({
|
||||
data: {
|
||||
tenantId: user.tenantId,
|
||||
userId: user.id,
|
||||
action: 'security.client_tenant_mismatch',
|
||||
resource: 'auth_session',
|
||||
detail: { suppliedTenantId },
|
||||
},
|
||||
});
|
||||
throw new ForbiddenException({ code: 'CLIENT_TENANT_MISMATCH', message: '请求企业与登录企业不一致' });
|
||||
}
|
||||
request.sessionTenantId = user.tenantId;
|
||||
}
|
||||
const isSessionRecoveryRoute = /\/auth\/(?:session(?:\/unlock)?|logout)(?:\?|$)/.test(path);
|
||||
if (result.status === 'locked' && !isSessionRecoveryRoute) {
|
||||
if (result.newlyLocked) {
|
||||
|
||||
Reference in New Issue
Block a user