Files
3dp-manager/server/src/auth/auth.controller.ts
T

105 lines
2.9 KiB
TypeScript

import {
Controller,
Post,
Body,
HttpException,
HttpStatus,
Res,
Logger,
Req,
} from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
import { AuthService } from './auth.service';
import { Public } from './public.decorator';
import type { Request, Response } from 'express';
import { ConfigService } from '@nestjs/config';
interface LoginDto {
login: string;
password: string;
}
@Controller('auth')
export class AuthController {
private readonly logger = new Logger(AuthController.name);
constructor(
private authService: AuthService,
private configService: ConfigService,
) {}
@Public()
@Throttle({
default: { limit: 5, ttl: 60000 },
})
@Post('login')
async login(
@Body() req: LoginDto,
@Res({ passthrough: true }) res: Response,
) {
this.logger.debug(`Login request received for user: ${req.login}`);
const user = await this.authService.validateUser(req.login, req.password);
if (!user) {
this.logger.warn(`Login failed for user: ${req.login}`);
throw new HttpException(
'Неверный логин или пароль',
HttpStatus.UNAUTHORIZED,
);
}
const { access_token } = this.authService.login(user as { login: string });
// Устанавливаем httpOnly cookie
const isProduction =
this.configService.get<string>('NODE_ENV') === 'production';
this.logger.debug(
`Login succeeded for user: ${req.login}. Setting auth cookie (secure=${isProduction}, sameSite=lax, maxAgeMs=86400000)`,
);
res.cookie('access_token', access_token, {
httpOnly: true,
secure: isProduction, // HTTPS только в production
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000, // 24 часа
path: '/',
});
this.logger.debug(`Login response prepared for user: ${req.login}`);
return { access_token };
}
@Public()
@Post('logout')
logout(@Req() req: Request, @Res({ passthrough: true }) res: Response) {
const hadCookie = Boolean(
(req.cookies as Record<string, unknown> | undefined)?.access_token,
);
this.logger.debug(`Logout request received. Cookie present: ${hadCookie}`);
// Очищаем httpOnly cookie
const isProduction =
this.configService.get<string>('NODE_ENV') === 'production';
res.clearCookie('access_token', {
httpOnly: true,
secure: isProduction,
sameSite: 'lax',
path: '/',
});
this.logger.debug(
`Auth cookie cleared (secure=${isProduction}, sameSite=lax, path=/)`,
);
return { success: true };
}
@Post('change-password')
async changePassword(@Body('password') password: string) {
await this.authService.changePassword(password);
return { success: true };
}
@Post('update-profile')
async updateProfile(@Body() body: { login: string; password?: string }) {
await this.authService.updateAdminProfile(body.login, body.password);
return { success: true };
}
}