import { Body, Controller, Get, Post, Query, Render, Req, Res, UnauthorizedException, } from '@nestjs/common'; import { Throttle } from '@nestjs/throttler'; import { Request, Response } from 'express'; import { ConfigurationService } from 'src/modules/config/config.service'; import { UserService } from 'src/modules/objects/user/user.service'; import { FormUtilityService } from 'src/modules/utility/services/form-utility.service'; import { RegisterDto } from './register.interfaces'; @Controller('/register') export class RegisterController { constructor( private readonly userService: UserService, private readonly formUtil: FormUtilityService, private readonly config: ConfigurationService, ) {} @Get() @Render('register') public registerView(@Req() req: Request): Record { return this.formUtil.populateTemplate(req, { registrationAuthorized: this.config.get('app.registrations'), }); } @Post() @Throttle(3, 10) public async registerRequest( @Req() req: Request, @Res() res: Response, @Body() body: RegisterDto, @Query('redirectTo') redirectTo?: string, ) { const { username, display_name, email, password, password_repeat } = this.formUtil.trimmed(body, ['username', 'display_name', 'email']); if (!this.config.get('app.registrations')) { throw new UnauthorizedException( 'Registrations are disabled by administrator.', ); } try { if ( !username || !display_name || !email || !password || !password_repeat ) { throw new Error('Please fill out all of the fields!'); } if (!username || !username.match(this.formUtil.usernameRegex)) { throw new Error( 'Username must be alphanumeric and between 3 to 26 characters long (_, - and . are also allowed)', ); } if (display_name.length < 3 || display_name.length > 32) { throw new Error( 'Display name must be between 3 and 32 characters long.', ); } // https://stackoverflow.com/a/21456918 if (!password.match(this.formUtil.passwordRegex)) { throw new Error( 'Password must be at least 8 characters long, contain a capital and lowercase letter and a number', ); } if (!email.match(this.formUtil.emailRegex)) { throw new Error('Invalid email address!'); } if (password !== password_repeat) { throw new Error('The passwords do not match!'); } await this.userService.userRegistration(body, redirectTo); req.flash('message', { error: false, text: `An activation email has been sent to ${email}!`, }); res.redirect('/login' + (redirectTo ? '?redirectTo=' + redirectTo : '')); } catch (e: any) { req.flash('message', { error: true, text: e.message }); req.flash('form', { ...body, password_repeat: undefined }); res.redirect(req.originalUrl); } } }