- JWT 加 super 标志,sub 保持超管真实 userId,tenantCode 随切换 - isSuper 解析/checkUserActive/PermissionsGuard 支持跨租户超管 - POST /auth/switch-tenant Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
76 lines
2.5 KiB
TypeScript
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);
|
|
}
|
|
}
|