Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
feat: add confirmation mail register
Browse files Browse the repository at this point in the history
  • Loading branch information
ludovicGendre committed Jan 21, 2022
1 parent 02c7a4e commit 296a50b
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ SALT="EAsCKIFVCV5CcfJc7M24Zgegy0j9zEuu"
EMAIL_SERVICE="gmail"
EMAIL_USER="[email protected]"
EMAIL_PASSWORD="Secret00"
JWT_VERIFICATION_TOKEN_SECRET="7AnEd5epXmdaJfUrokkQ"
JWT_VERIFICATION_TOKEN_EXPIRATION_TIME=21600
EMAIL_CONFIRMATION_URL="https://localhost:3000/confirm-email"
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ model User {
email String @unique
sex Int @default(0)
latitude Float?
isEmailConfirmed Boolean @default(false)
longitude Float?
avatarId String? @db.Uuid
cityId String @db.Uuid
Expand Down
14 changes: 11 additions & 3 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';

import { AccountDto, CreateUserDto, AuthTokenDto } from '../dtos';
import { AccountDto, CreateUserDto, AuthTokenDto, UserDto } from '../dtos';

import { AuthService } from './auth.service';
import { UserService } from '../user/user.service';
import { EmailConfirmationService } from 'src/email/confirmation/emailConfirmation.service';

@Controller('/auth')
export class AuthController {
public constructor(
private readonly authService: AuthService,
private readonly citizenService: UserService,
private readonly emailConfirmationService: EmailConfirmationService,
) {}

@Post('/register')
Expand All @@ -18,10 +20,16 @@ export class AuthController {
//FIXME
@Body() body: CreateUserDto & { password: string },
@Body('password') password: string,
): Promise<void> {
): Promise<AccountDto> {
delete body.password;
const { id } = await this.citizenService.create(body);
await this.authService.register(body.username, password, id);
const account = await this.authService.register(
body.username,
password,
id,
);
await this.emailConfirmationService.sendVerificationLink(body.email);
return account;
}

@Post('/login')
Expand Down
11 changes: 10 additions & 1 deletion src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { JwtStrategy } from './jwt-strategy';
import { AuthService } from './auth.service';
import { PrismaService } from 'src/prisma.service';
import { UserService } from 'src/user/user.service';
import { EmailConfirmationService } from 'src/email/confirmation/emailConfirmation.service';
import EmailService from 'src/email/email.service';

@Module({
imports: [
Expand All @@ -18,7 +20,14 @@ import { UserService } from 'src/user/user.service';
}),
}),
],
providers: [AuthService, JwtStrategy, PrismaService, UserService],
providers: [
AuthService,
JwtStrategy,
PrismaService,
UserService,
EmailConfirmationService,
EmailService,
],
controllers: [AuthController],
})
export class AuthModule {}
6 changes: 4 additions & 2 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { AuthTokenDto } from '../dtos';
import { pbkdf2Sync } from 'crypto';
import { ConfigService } from 'config/config.service';
import { PrismaService } from '../prisma.service';
import { Account } from '@prisma/client';

@Injectable()
export class AuthService {
Expand All @@ -17,11 +18,12 @@ export class AuthService {
username: string,
password: string,
id: string,
): Promise<void> {
): Promise<Account> {
const hashedPassword = this.hashPassword(password);

const account = { username, password: hashedPassword };
await this.prisma.account.create({ data: account });
const result = await this.prisma.account.create({ data: account });
return result;
}

public async login(
Expand Down
5 changes: 5 additions & 0 deletions src/dtos/users/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
IsBoolean,
IsEmail,
IsISO8601,
IsNotEmpty,
Expand Down Expand Up @@ -71,6 +72,10 @@ export class UserDto extends CreateUserDto {
@ApiProperty({ type: () => FileDto })
public avatar?: RelationInput<FileDto>;

@ApiProperty()
@IsBoolean()
public isEmailConfirmed!: boolean;

@ApiProperty()
@IsNotEmpty()
@IsUUID(4)
Expand Down
33 changes: 33 additions & 0 deletions src/email/confirmation/emailConfirmation.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import EmailService from '../email.service';

interface VerificationTokenPayload {
email: string;
}

@Injectable()
export class EmailConfirmationService {
constructor(
private readonly jwtService: JwtService,
private readonly emailService: EmailService,
) {}

public sendVerificationLink(email: string) {
const payload: VerificationTokenPayload = { email };
const token = this.jwtService.sign(payload, {
secret: process.env.JWT_VERIFICATION_TOKEN_SECRET,
expiresIn: `${process.env.JWT_VERIFICATION_TOKEN_EXPIRATION_TIME}s`,
});

const url = `${process.env.EMAIL_CONFIRMATION_URL}?token=${token}`;

const text = `Welcome to the application. To confirm the email address, click here: ${url}`;

return this.emailService.sendMail({
to: email,
subject: 'Email confirmation',
text,
});
}
}
3 changes: 2 additions & 1 deletion src/email/email.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Module } from '@nestjs/common';
import EmailService from './email.service';
import EmailSchedulingController from './emailSchedule.controller';
import EmailSchedulingService from './emailSchedule.service';
import { PrismaService } from '../prisma.service';

@Module({
controllers: [EmailSchedulingController],
providers: [EmailService, EmailSchedulingService],
providers: [EmailService, EmailSchedulingService, PrismaService],
exports: [EmailService],
})
export class EmailModule {}

0 comments on commit 296a50b

Please sign in to comment.