Feature: Added Send Grid Intrgration #7
|
@ -31,6 +31,7 @@
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"@nestjs/swagger": "^7.3.1",
|
"@nestjs/swagger": "^7.3.1",
|
||||||
"@nestjs/typeorm": "^10.0.2",
|
"@nestjs/typeorm": "^10.0.2",
|
||||||
|
"@sendgrid/mail": "^8.1.3",
|
||||||
"argon2": "^0.40.1",
|
"argon2": "^0.40.1",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,7 @@ import { SecurityHeadersMiddleware } from './middleware/security-middleware/secu
|
||||||
import { AuthModule } from './modules/auth-module/auth.module';
|
import { AuthModule } from './modules/auth-module/auth.module';
|
||||||
import { AccessTokenGuard } from './modules/auth-module/common/guards';
|
import { AccessTokenGuard } from './modules/auth-module/common/guards';
|
||||||
import { DatabaseModule } from './modules/database-module/database.module';
|
import { DatabaseModule } from './modules/database-module/database.module';
|
||||||
|
import { SendgridModule } from './modules/sendgrid-module/sendgrid.module';
|
||||||
import { UserModule } from './modules/user-module/user.module';
|
import { UserModule } from './modules/user-module/user.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
@ -20,6 +21,7 @@ import { UserModule } from './modules/user-module/user.module';
|
||||||
DatabaseModule,
|
DatabaseModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
|
SendgridModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService, { provide: 'APP_GUARD', useClass: AccessTokenGuard }],
|
providers: [AppService, { provide: 'APP_GUARD', useClass: AccessTokenGuard }],
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { JwtModule } from '@nestjs/jwt';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { UserCredentials } from 'src/entities';
|
import { UserCredentials } from 'src/entities';
|
||||||
|
|
||||||
|
import { SendgridModule } from '../sendgrid-module/sendgrid.module';
|
||||||
import { UserModule } from '../user-module/user.module';
|
import { UserModule } from '../user-module/user.module';
|
||||||
|
|
||||||
import { AuthController } from './controller/auth.controller';
|
import { AuthController } from './controller/auth.controller';
|
||||||
|
@ -15,6 +16,7 @@ import { AccessTokenStrategy, RefreshTokenStrategy } from './strategies';
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
UserModule,
|
UserModule,
|
||||||
|
SendgridModule,
|
||||||
JwtModule.register({}),
|
JwtModule.register({}),
|
||||||
TypeOrmModule.forFeature([UserCredentials]),
|
TypeOrmModule.forFeature([UserCredentials]),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ForbiddenException, Injectable } from '@nestjs/common';
|
import { ForbiddenException, Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { PasswordConfirmationMailService } from '../../sendgrid-module/services/password-confirmation.mail.service';
|
||||||
import { UserDataRepository } from '../../user-module/repositories/user-data.repository';
|
import { UserDataRepository } from '../../user-module/repositories/user-data.repository';
|
||||||
import { TokensDto, UserCredentialsDto } from '../models/dto';
|
import { TokensDto, UserCredentialsDto } from '../models/dto';
|
||||||
import { UserCredentialsRepository } from '../repositories/user-credentials.repository';
|
import { UserCredentialsRepository } from '../repositories/user-credentials.repository';
|
||||||
|
@ -13,7 +14,8 @@ export class AuthService {
|
||||||
private readonly userCredentialsRepository: UserCredentialsRepository,
|
private readonly userCredentialsRepository: UserCredentialsRepository,
|
||||||
private readonly userDataRepository: UserDataRepository,
|
private readonly userDataRepository: UserDataRepository,
|
||||||
private readonly tokenManagementService: TokenManagementService,
|
private readonly tokenManagementService: TokenManagementService,
|
||||||
private readonly encryptionService: EncryptionService
|
private readonly encryptionService: EncryptionService,
|
||||||
|
private readonly passwordConfirmationMailService: PasswordConfirmationMailService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async signup(userCredentials: UserCredentialsDto): Promise<TokensDto> {
|
public async signup(userCredentials: UserCredentialsDto): Promise<TokensDto> {
|
||||||
|
@ -27,6 +29,11 @@ export class AuthService {
|
||||||
|
|
||||||
await this.userDataRepository.createInitialUserData(user);
|
await this.userDataRepository.createInitialUserData(user);
|
||||||
|
|
||||||
|
// TODO Send email confirmation
|
||||||
|
// await this.passwordConfirmationMailService.sendPasswordConfirmationMail(
|
||||||
|
// user.email
|
||||||
|
// );
|
||||||
|
|
||||||
return this.generateAndPersistTokens(user.id, user.email);
|
return this.generateAndPersistTokens(user.id, user.email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
|
import { PasswordConfirmationMailService } from './services/password-confirmation.mail.service';
|
||||||
|
import { TemplateConfigService } from './services/template-config.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: 'SEND_GRID_API_KEY',
|
||||||
|
useFactory: (configService: ConfigService): string =>
|
||||||
|
configService.get<string>('SEND_GRID_API_KEY'),
|
||||||
|
inject: [ConfigService],
|
||||||
|
},
|
||||||
|
PasswordConfirmationMailService,
|
||||||
|
TemplateConfigService,
|
||||||
|
],
|
||||||
|
controllers: [],
|
||||||
|
exports: [PasswordConfirmationMailService],
|
||||||
|
})
|
||||||
|
export class SendgridModule {}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import * as SendGridMailApi from '@sendgrid/mail';
|
||||||
|
|
||||||
|
// API: https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send#request-body
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export abstract class BaseMailService {
|
||||||
|
public constructor(
|
||||||
|
@Inject('SEND_GRID_API_KEY') protected readonly sendGridApiKey: string
|
||||||
|
) {
|
||||||
|
SendGridMailApi.setApiKey(this.sendGridApiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async sendMail(
|
||||||
|
mailOptions: SendGridMailApi.MailDataRequired
|
||||||
|
): Promise<[SendGridMailApi.ClientResponse, object]> {
|
||||||
|
return SendGridMailApi.send(mailOptions);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
import * as SendGridMailApi from '@sendgrid/mail';
|
||||||
|
|
||||||
|
import { BaseMailService } from './base.mail.service';
|
||||||
|
import { TemplateConfigService } from './template-config.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PasswordConfirmationMailService extends BaseMailService {
|
||||||
|
private readonly PASSWORD_CONFIRMATION_EMAIL: string =
|
||||||
|
'PASSWORD_CONFIRMATION_EMAIL';
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
@Inject('SEND_GRID_API_KEY') protected readonly sendGridApiKey: string,
|
||||||
|
private readonly templateConfigService: TemplateConfigService
|
||||||
|
) {
|
||||||
|
super(sendGridApiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async sendPasswordConfirmationMail(to: string): Promise<void> {
|
||||||
|
const templateId: string = this.templateConfigService.getTemplateId(
|
||||||
|
this.PASSWORD_CONFIRMATION_EMAIL
|
||||||
|
);
|
||||||
|
|
||||||
|
const mailoptions: SendGridMailApi.MailDataRequired = {
|
||||||
|
to,
|
||||||
|
from: { email: 'info@igor-propisnov.com', name: 'Ticket App' },
|
||||||
|
templateId: templateId,
|
||||||
|
dynamicTemplateData: {
|
||||||
|
name: 'Mara',
|
||||||
|
buttonUrl: 'https://igor-propisnov.com',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.sendMail(mailoptions);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TemplateConfigService {
|
||||||
|
public constructor(private configService: ConfigService) {}
|
||||||
|
|
||||||
|
public getTemplateId(key: string): string {
|
||||||
|
return this.configService.get<string>(`SENDGRID_TEMPLATE_${key}`);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue