115 lines
2.4 KiB
TypeScript
115 lines
2.4 KiB
TypeScript
import {
|
|
Controller,
|
|
Post,
|
|
Body,
|
|
UnauthorizedException,
|
|
HttpCode,
|
|
HttpStatus,
|
|
Req,
|
|
} from '@nestjs/common';
|
|
import { IsEmail, IsString, MinLength, IsOptional } from 'class-validator';
|
|
import { AuthService } from './auth.service';
|
|
import { TenantId } from '../tenant/tenant.decorator';
|
|
|
|
class LoginDto {
|
|
@IsEmail()
|
|
email: string;
|
|
|
|
@IsString()
|
|
@MinLength(6)
|
|
password: string;
|
|
}
|
|
|
|
class RegisterDto {
|
|
@IsEmail()
|
|
email: string;
|
|
|
|
@IsString()
|
|
@MinLength(6)
|
|
password: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
firstName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
lastName?: string;
|
|
}
|
|
|
|
@Controller('auth')
|
|
export class AuthController {
|
|
constructor(private authService: AuthService) {}
|
|
|
|
private isCentralSubdomain(subdomain: string): boolean {
|
|
const centralSubdomains = (process.env.CENTRAL_SUBDOMAINS || 'central,admin').split(',');
|
|
return centralSubdomains.includes(subdomain);
|
|
}
|
|
|
|
@HttpCode(HttpStatus.OK)
|
|
@Post('login')
|
|
async login(
|
|
@TenantId() tenantId: string,
|
|
@Body() loginDto: LoginDto,
|
|
@Req() req: any,
|
|
) {
|
|
const subdomain = req.raw?.subdomain;
|
|
|
|
|
|
// If it's a central subdomain, tenantId is not required
|
|
if (!subdomain || !this.isCentralSubdomain(subdomain)) {
|
|
if (!tenantId) {
|
|
throw new UnauthorizedException('Tenant ID is required');
|
|
}
|
|
}
|
|
|
|
const user = await this.authService.validateUser(
|
|
tenantId,
|
|
loginDto.email,
|
|
loginDto.password,
|
|
subdomain,
|
|
);
|
|
|
|
if (!user) {
|
|
throw new UnauthorizedException('Invalid credentials');
|
|
}
|
|
|
|
return this.authService.login(user);
|
|
}
|
|
|
|
@Post('register')
|
|
async register(
|
|
@TenantId() tenantId: string,
|
|
@Body() registerDto: RegisterDto,
|
|
@Req() req: any,
|
|
) {
|
|
const subdomain = req.raw?.subdomain;
|
|
|
|
// If it's a central subdomain, tenantId is not required
|
|
if (!subdomain || !this.isCentralSubdomain(subdomain)) {
|
|
if (!tenantId) {
|
|
throw new UnauthorizedException('Tenant ID is required');
|
|
}
|
|
}
|
|
|
|
const user = await this.authService.register(
|
|
tenantId,
|
|
registerDto.email,
|
|
registerDto.password,
|
|
registerDto.firstName,
|
|
registerDto.lastName,
|
|
subdomain,
|
|
);
|
|
|
|
return user;
|
|
}
|
|
|
|
@HttpCode(HttpStatus.OK)
|
|
@Post('logout')
|
|
async logout() {
|
|
// For stateless JWT, logout is handled on client-side
|
|
// This endpoint exists for consistency and potential future enhancements
|
|
return { message: 'Logged out successfully' };
|
|
}
|
|
}
|