ec-nest/src/auth/auth.controller.ts
liuyun 6618137da5 feat(auth): 平台超管租户切换(super 标志 + switch-tenant)
- JWT 加 super 标志,sub 保持超管真实 userId,tenantCode 随切换
- isSuper 解析/checkUserActive/PermissionsGuard 支持跨租户超管
- POST /auth/switch-tenant

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-12 00:00:38 +08:00

76 lines
2.5 KiB
TypeScript

import { Body, Controller, Get, Patch, Post, Req, UnauthorizedException } from '@nestjs/common';
import type { Request } from 'express';
import { AuthService } from './auth.service.js';
import { ChangePasswordDto, LoginDto, RefreshDto, RegisterDto, SwitchTenantDto } from './dto.js';
import { Public } from './decorators.js';
import { getRequestContext } from '../common/context/request-context.js';
@Controller('auth')
export class AuthController {
constructor(private readonly auth: AuthService) {}
@Public()
@Post('login')
login(@Body() dto: LoginDto, @Req() req: Request) {
return this.auth.login(dto, req.ip, req.headers['user-agent']);
}
@Public()
@Post('register')
register(@Body() dto: RegisterDto) {
return this.auth.register(dto);
}
@Public()
@Post('refresh')
refresh(@Body() dto: RefreshDto) {
return this.auth.refresh(dto);
}
@Public()
@Post('logout')
logout(@Body() dto: RefreshDto, @Req() req: Request) {
return this.auth.logout(dto, req.ip, req.headers['user-agent']);
}
/** 当前用户菜单树(仅需登录,无需额外权限)。 */
@Get('menus')
menus() {
const ctx = getRequestContext();
if (!ctx) throw new UnauthorizedException('未登录');
return this.auth.getMenus(ctx.tenantCode, ctx.userId, ctx.super);
}
/** 当前用户权限码(含超管标志),供前端按钮/路由级权限控制(仅需登录)。 */
@Get('permissions')
permissions() {
const ctx = getRequestContext();
if (!ctx) throw new UnauthorizedException('未登录');
return this.auth.getPermissionSet(ctx.tenantCode, ctx.userId, ctx.super);
}
/** 平台超管切换租户(仅需登录;内部校验调用者为平台超管)。 */
@Post('switch-tenant')
switchTenant(@Body() dto: SwitchTenantDto, @Req() req: Request) {
const ctx = getRequestContext();
if (!ctx) throw new UnauthorizedException('未登录');
return this.auth.switchTenant(ctx.userId, dto, req.ip, req.headers['user-agent']);
}
/** 当前租户品牌(仅需登录)。 */
@Get('brand')
brand() {
const ctx = getRequestContext();
if (!ctx) throw new UnauthorizedException('未登录');
return this.auth.getBrand(ctx.tenantCode);
}
/** 修改本人密码(仅需登录)。 */
@Patch('me/password')
changePassword(@Body() dto: ChangePasswordDto) {
const ctx = getRequestContext();
if (!ctx) throw new UnauthorizedException('未登录');
return this.auth.changePassword(ctx.tenantCode, ctx.userId, dto);
}
}