Feature: E-Mail verify #8
|
@ -0,0 +1,33 @@
|
|||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
OneToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { UserCredentials } from './user-credentials.entity';
|
||||
|
||||
@Entity()
|
||||
export class EmailVerification {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
public id: string;
|
||||
|
||||
@Column()
|
||||
public token: string;
|
||||
|
||||
@Column()
|
||||
public expiresAt: Date;
|
||||
|
||||
@OneToOne(() => UserCredentials)
|
||||
@JoinColumn({ name: 'userCredentialsId' })
|
||||
public user: UserCredentials;
|
||||
|
||||
@CreateDateColumn()
|
||||
public createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
public updatedAt: Date;
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
export * from './user-credentials.entity';
|
||||
export * from './user-data.entity';
|
||||
export * from './email-verification.entity';
|
||||
|
|
|
@ -5,6 +5,7 @@ import { UserCredentials } from 'src/entities';
|
|||
|
||||
import { SendgridModule } from '../sendgrid-module/sendgrid.module';
|
||||
import { UserModule } from '../user-module/user.module';
|
||||
import { VerifyModule } from '../verify-module/verify.module';
|
||||
|
||||
import { AuthController } from './controller/auth.controller';
|
||||
import { UserCredentialsRepository } from './repositories/user-credentials.repository';
|
||||
|
@ -17,6 +18,7 @@ import { AccessTokenStrategy, RefreshTokenStrategy } from './strategies';
|
|||
imports: [
|
||||
UserModule,
|
||||
SendgridModule,
|
||||
VerifyModule,
|
||||
JwtModule.register({}),
|
||||
TypeOrmModule.forFeature([UserCredentials]),
|
||||
],
|
||||
|
|
|
@ -31,12 +31,15 @@ export class AuthService {
|
|||
|
||||
await this.userDataRepository.createInitialUserData(user);
|
||||
|
||||
// TODO Send email confirmation
|
||||
// await this.passwordConfirmationMailService.sendPasswordConfirmationMail(
|
||||
// user.email
|
||||
// );
|
||||
const token =
|
||||
await this.emailVerificationService.generateEmailVerificationToken(
|
||||
user.id
|
||||
);
|
||||
|
||||
// await this.emailVerificationService.generateEmailVerificationToken(user.id);
|
||||
await this.passwordConfirmationMailService.sendPasswordConfirmationMail(
|
||||
user.email,
|
||||
token
|
||||
);
|
||||
|
||||
return this.generateAndPersistTokens(user.id, user.email);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ConfigService } from '@nestjs/config';
|
||||
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
|
||||
import { UserCredentials, UserData } from 'src/entities';
|
||||
import { EmailVerification, UserCredentials, UserData } from 'src/entities';
|
||||
|
||||
export const databaseConfigFactory = (
|
||||
configService: ConfigService
|
||||
|
@ -13,5 +13,5 @@ export const databaseConfigFactory = (
|
|||
database: configService.get('DB_NAME'),
|
||||
synchronize: true,
|
||||
logging: true,
|
||||
entities: [UserCredentials, UserData],
|
||||
entities: [UserCredentials, UserData, EmailVerification],
|
||||
});
|
||||
|
|
|
@ -16,18 +16,23 @@ export class PasswordConfirmationMailService extends BaseMailService {
|
|||
super(sendGridApiKey);
|
||||
}
|
||||
|
||||
public async sendPasswordConfirmationMail(to: string): Promise<void> {
|
||||
public async sendPasswordConfirmationMail(
|
||||
to: string,
|
||||
token: string
|
||||
): Promise<void> {
|
||||
const templateId: string = this.templateConfigService.getTemplateId(
|
||||
this.PASSWORD_CONFIRMATION_EMAIL
|
||||
);
|
||||
|
||||
const encodedToken = encodeURIComponent(token);
|
||||
|
||||
const mailoptions: SendGridMailApi.MailDataRequired = {
|
||||
to,
|
||||
from: { email: 'info@igor-propisnov.com', name: 'Ticket App' },
|
||||
templateId: templateId,
|
||||
dynamicTemplateData: {
|
||||
name: 'Mara',
|
||||
buttonUrl: 'https://igor-propisnov.com',
|
||||
buttonUrl: `http://localhost:4200/?token=${encodedToken}`,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { EmailVerification } from 'src/entities';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
@Injectable()
|
||||
export class EmailVerifyRepository {
|
||||
public constructor(
|
||||
@InjectRepository(EmailVerification)
|
||||
private readonly repository: Repository<EmailVerification>
|
||||
) {}
|
||||
|
||||
public async createEmailVerification(
|
||||
token: string,
|
||||
expiresAt: Date,
|
||||
userId: string
|
||||
): Promise<void> {
|
||||
await this.repository.save({
|
||||
token,
|
||||
expiresAt,
|
||||
user: { id: userId },
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './email-verify.repository';
|
|
@ -0,0 +1,27 @@
|
|||
import { randomBytes } from 'crypto';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { EmailVerifyRepository } from '../repositories';
|
||||
|
||||
@Injectable()
|
||||
export class EmailVerificationService {
|
||||
public constructor(
|
||||
private readonly emailVerifyRepository: EmailVerifyRepository
|
||||
) {}
|
||||
|
||||
public async generateEmailVerificationToken(userId: string): Promise<string> {
|
||||
const token = randomBytes(32).toString('hex');
|
||||
|
||||
// TODO Check users local time zone and set expiration time accordingly
|
||||
const expiration = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
||||
|
||||
this.emailVerifyRepository.createEmailVerification(
|
||||
token,
|
||||
expiration,
|
||||
userId
|
||||
);
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { EmailVerification } from 'src/entities';
|
||||
|
||||
import { EmailVerifyRepository } from './repositories';
|
||||
import { EmailVerificationService } from './services/email-verification.service';
|
||||
|
||||
@Module({
|
||||
imports: [ConfigModule, TypeOrmModule.forFeature([EmailVerification])],
|
||||
providers: [EmailVerifyRepository, EmailVerificationService],
|
||||
controllers: [],
|
||||
exports: [EmailVerificationService],
|
||||
})
|
||||
export class VerifyModule {}
|
Loading…
Reference in New Issue