128 lines
4.2 KiB
TypeScript
128 lines
4.2 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Get,
|
|
Inject,
|
|
Param,
|
|
Post,
|
|
Request,
|
|
UnauthorizedException,
|
|
UseGuards,
|
|
} from '@nestjs/common';
|
|
import { Throttle } from '@nestjs/throttler';
|
|
import {
|
|
ApiTags,
|
|
ApiOperation,
|
|
ApiBody,
|
|
ApiParam,
|
|
ApiResponse,
|
|
ApiExtraModels,
|
|
getSchemaPath,
|
|
} from '@nestjs/swagger';
|
|
import { PublicRoute } from './guards/jwt.guard';
|
|
import { AuthenticationApplication } from './AuthApplication.sevice';
|
|
import { AuthSignupDto } from './dtos/AuthSignup.dto';
|
|
import { AuthSigninDto } from './dtos/AuthSignin.dto';
|
|
import { AuthSignupVerifyDto } from './dtos/AuthSignupVerify.dto';
|
|
import { AuthSendResetPasswordDto } from './dtos/AuthSendResetPassword.dto';
|
|
import { AuthResetPasswordDto } from './dtos/AuthResetPassword.dto';
|
|
import { AuthSigninResponseDto } from './dtos/AuthSigninResponse.dto';
|
|
import { AuthMetaResponseDto } from './dtos/AuthMetaResponse.dto';
|
|
import { LocalAuthGuard } from './guards/Local.guard';
|
|
import { AuthSigninService } from './commands/AuthSignin.service';
|
|
import { TenantModel } from '../System/models/TenantModel';
|
|
import { SystemUser } from '../System/models/SystemUser';
|
|
|
|
@Controller('/auth')
|
|
@ApiTags('Auth')
|
|
@ApiExtraModels(AuthSigninResponseDto, AuthMetaResponseDto)
|
|
@PublicRoute()
|
|
@Throttle({ auth: {} })
|
|
export class AuthController {
|
|
constructor(
|
|
private readonly authApp: AuthenticationApplication,
|
|
private readonly authSignin: AuthSigninService,
|
|
|
|
@Inject(TenantModel.name)
|
|
private readonly tenantModel: typeof TenantModel,
|
|
) { }
|
|
|
|
@Post('/signin')
|
|
@UseGuards(LocalAuthGuard)
|
|
@ApiOperation({ summary: 'Sign in a user' })
|
|
@ApiBody({ type: AuthSigninDto })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: 'Sign-in successful. Returns access token and tenant/organization IDs.',
|
|
schema: { $ref: getSchemaPath(AuthSigninResponseDto) },
|
|
})
|
|
async signin(
|
|
@Request() req: Request & { user: SystemUser },
|
|
@Body() signinDto: AuthSigninDto,
|
|
): Promise<AuthSigninResponseDto> {
|
|
const { user } = req;
|
|
const tenant = await this.tenantModel.query().findById(user.tenantId);
|
|
|
|
if (tenant.isInactive) {
|
|
throw new UnauthorizedException({
|
|
message: 'Organization is inactive. Please contact the administrator.',
|
|
errors: [{ type: 'ORGANIZATION.INACTIVE' }],
|
|
});
|
|
}
|
|
|
|
return {
|
|
accessToken: this.authSignin.signToken(user),
|
|
organizationId: tenant.organizationId,
|
|
tenantId: tenant.id,
|
|
userId: user.id,
|
|
};
|
|
}
|
|
|
|
@Post('/signup')
|
|
@ApiOperation({ summary: 'Sign up a new user' })
|
|
@ApiBody({ type: AuthSignupDto })
|
|
@ApiResponse({ status: 201, description: 'Sign-up initiated. Check email for confirmation.' })
|
|
signup(@Request() req: Request, @Body() signupDto: AuthSignupDto) {
|
|
return this.authApp.signUp(signupDto);
|
|
}
|
|
|
|
@Post('/signup/verify')
|
|
@ApiOperation({ summary: 'Confirm user signup' })
|
|
@ApiBody({ type: AuthSignupVerifyDto })
|
|
@ApiResponse({ status: 200, description: 'Signup confirmed successfully.' })
|
|
signupConfirm(@Body() body: AuthSignupVerifyDto) {
|
|
return this.authApp.signUpConfirm(body.email, body.token);
|
|
}
|
|
|
|
@Post('/send_reset_password')
|
|
@ApiOperation({ summary: 'Send reset password email' })
|
|
@ApiBody({ type: AuthSendResetPasswordDto })
|
|
@ApiResponse({ status: 200, description: 'Reset password email sent if the account exists.' })
|
|
sendResetPassword(@Body() body: AuthSendResetPasswordDto) {
|
|
return this.authApp.sendResetPassword(body.email);
|
|
}
|
|
|
|
@Post('/reset_password/:token')
|
|
@ApiOperation({ summary: 'Reset password using token' })
|
|
@ApiParam({ name: 'token', description: 'Reset password token from email link' })
|
|
@ApiBody({ type: AuthResetPasswordDto })
|
|
@ApiResponse({ status: 200, description: 'Password reset successfully.' })
|
|
resetPassword(
|
|
@Param('token') token: string,
|
|
@Body() body: AuthResetPasswordDto,
|
|
) {
|
|
return this.authApp.resetPassword(token, body.password);
|
|
}
|
|
|
|
@Get('/meta')
|
|
@ApiOperation({ summary: 'Get auth metadata (e.g. signup disabled)' })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: 'Auth metadata for the login/signup page.',
|
|
schema: { $ref: getSchemaPath(AuthMetaResponseDto) },
|
|
})
|
|
meta(): Promise<AuthMetaResponseDto> {
|
|
return this.authApp.getAuthMeta();
|
|
}
|
|
}
|