Skip to content

Commit

Permalink
Merge pull request #491 from andrechristikan/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
andrechristikan authored Nov 7, 2023
2 parents 2aa8258 + d5279f2 commit 153ab39
Show file tree
Hide file tree
Showing 15 changed files with 376 additions and 280 deletions.
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ AWS_S3_BUCKET=
AWS_SES_CREDENTIAL_KEY=
AWS_SES_CREDENTIAL_SECRET=
AWS_SES_REGION=ap-southeast-3
AWS_SES_FROM_EMAIL=


SSO_GOOGLE_CLIENT_ID=
Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@
"@nestjs/throttler": "^5.0.1",
"@ntegral/nestjs-sentry": "^4.0.0",
"@sentry/node": "^7.77.0",
"@types/response-time": "^2.3.7",
"@types/response-time": "^2.3.8",
"axios": "^1.6.0",
"bcryptjs": "^2.4.3",
"case": "^1.6.3",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"crypto-js": "^4.2.0",
"google-auth-library": "^9.2.0",
"helmet": "^7.0.0",
"helmet": "^7.1.0",
"joi": "^17.11.0",
"moment": "^2.29.4",
"mongoose": "^8.0.0",
Expand All @@ -100,24 +100,24 @@
"@nestjs/cli": "^10.2.1",
"@nestjs/schematics": "^10.0.3",
"@nestjs/testing": "^10.2.8",
"@types/bcryptjs": "^2.4.5",
"@types/bytes": "^3.1.3",
"@types/cors": "^2.8.15",
"@types/bcryptjs": "^2.4.6",
"@types/bytes": "^3.1.4",
"@types/cors": "^2.8.16",
"@types/cron": "^2.0.1",
"@types/crypto-js": "^4.1.3",
"@types/express": "^4.17.20",
"@types/crypto-js": "^4.2.1",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.7",
"@types/lodash": "^4.14.200",
"@types/ms": "^0.7.33",
"@types/multer": "^1.4.9",
"@types/ms": "^0.7.34",
"@types/multer": "^1.4.10",
"@types/node": "^20.8.10",
"@types/passport-jwt": "^3.0.12",
"@types/passport-jwt": "^3.0.13",
"@types/supertest": "^2.0.15",
"@types/ua-parser-js": "^0.7.38",
"@types/uuid": "^9.0.6",
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"cspell": "^7.3.8",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
"cspell": "^8.0.0",
"eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.29.0",
Expand Down
6 changes: 3 additions & 3 deletions src/common/aws/dtos/aws.ses.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ export class AwsSESSendDto<T> {
templateData?: T;

@ApiProperty({
required: false,
required: true,
})
@IsEmail()
@IsString()
@IsOptional()
sender?: string;
@IsNotEmpty()
sender: string;

@ApiProperty({
required: false,
Expand Down
13 changes: 4 additions & 9 deletions src/common/aws/services/aws.ses.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { IAwsSESService } from 'src/common/aws/interfaces/aws.ses-service.interf
@Injectable()
export class AwsSESService implements IAwsSESService {
private readonly sesClient: SESClient;
private readonly fromEmail: string;

constructor(private readonly configService: ConfigService) {
this.sesClient = new SESClient({
Expand All @@ -50,8 +49,6 @@ export class AwsSESService implements IAwsSESService {
},
region: this.configService.get<string>('aws.ses.region'),
});

this.fromEmail = this.configService.get<string>('aws.ses.fromEmail');
}

async listTemplates(
Expand Down Expand Up @@ -186,7 +183,6 @@ export class AwsSESService implements IAwsSESService {
templateName,
templateData,
}: AwsSESSendDto<T>): Promise<SendTemplatedEmailCommandOutput> {
const sdr = sender ?? this.fromEmail;
const command: SendTemplatedEmailCommand =
new SendTemplatedEmailCommand({
Template: templateName,
Expand All @@ -195,9 +191,9 @@ export class AwsSESService implements IAwsSESService {
BccAddresses: bcc ?? [],
CcAddresses: cc ?? [],
},
Source: sdr,
Source: sender,
TemplateData: JSON.stringify(templateData ?? ''),
ReplyToAddresses: [replyTo ?? sdr],
ReplyToAddresses: [replyTo ?? sender],
});

try {
Expand All @@ -221,7 +217,6 @@ export class AwsSESService implements IAwsSESService {
cc,
templateName,
}: AwsSESSendBulkDto): Promise<SendBulkTemplatedEmailCommandOutput> {
const sdr = sender ?? this.fromEmail;
const command: SendBulkTemplatedEmailCommand =
new SendBulkTemplatedEmailCommand({
Template: templateName,
Expand All @@ -235,8 +230,8 @@ export class AwsSESService implements IAwsSESService {
e.templateData ?? ''
),
})),
Source: sdr,
ReplyToAddresses: [replyTo ?? sdr],
Source: sender,
ReplyToAddresses: [replyTo ?? sender],
});

try {
Expand Down
1 change: 0 additions & 1 deletion src/common/common.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ import { PolicyModule } from 'src/common/policy/policy.module';
.allow(null, '')
.optional(),
AWS_SES_REGION: Joi.string().allow(null, '').optional(),
AWS_SES_FROM_EMAIL: Joi.string().allow(null, '').optional(),

SSO_GOOGLE_CLIENT_ID: Joi.string().allow(null, '').optional(),
SSO_GOOGLE_CLIENT_SECRET: Joi.string()
Expand Down
1 change: 0 additions & 1 deletion src/configs/aws.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export default registerAs(
secret: process.env.AWS_SES_CREDENTIAL_SECRET,
},
region: process.env.AWS_SES_REGION,
fromEmail: process.env.AWS_SES_FROM_EMAIL,
},
})
);
10 changes: 10 additions & 0 deletions src/configs/email.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { registerAs } from '@nestjs/config';

export default registerAs(
'email',
(): Record<string, any> => ({
fromEmail: 'noreply@mail.com',
signUpPlainBody: 'Hi {{name}}, welcome to {{appName}}',
changePasswordPlainBody: 'Hi {{name}}, you password has changed',
})
);
2 changes: 2 additions & 0 deletions src/configs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import DocConfig from './doc.config';
import DebuggerConfig from './debugger.config';
import MessageConfig from './message.config';
import GoogleConfig from './google.config';
import EmailConfig from './email.config';

export default [
AppConfig,
Expand All @@ -24,4 +25,5 @@ export default [
DebuggerConfig,
MessageConfig,
GoogleConfig,
EmailConfig,
];
12 changes: 10 additions & 2 deletions src/migration/seeds/migration.email.seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ export class MigrationEmailSeed {
'aws.ses.credential.secret'
);
if (clientId && clientSecret) {
const check: boolean = await this.emailService.getSignUp();
if (!check) {
const checkSignUp: boolean =
await this.emailService.getSignUp();
if (!checkSignUp) {
await this.emailService.createSignUp();
}

const checkChangePassword: boolean =
await this.emailService.getChangePassword();
if (!checkChangePassword) {
await this.emailService.createChangePassword();
}
}
} catch (err: any) {
throw new Error(err.message);
Expand All @@ -42,6 +49,7 @@ export class MigrationEmailSeed {
async remove(): Promise<void> {
try {
await this.emailService.deleteSignUp();
await this.emailService.deleteChangePassword();
} catch (err: any) {
throw new Error(err.message);
}
Expand Down
1 change: 0 additions & 1 deletion src/modules/email/constants/email.constant.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/modules/email/constants/email.enum.constant.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export enum ENUM_EMAIL {
SIGN_UP = 'SIGN_UP',
CHANGE_PASSWORD = 'CHANGE_PASSWORD',
}
6 changes: 6 additions & 0 deletions src/modules/email/dtos/email.send-change-password.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { PickType } from '@nestjs/swagger';
import { EmailSendSignUpDto } from 'src/modules/email/dtos/email.send-sign-up.dto';

export class EmailSendChangePasswordDto extends PickType(EmailSendSignUpDto, [
'name',
] as const) {}
75 changes: 72 additions & 3 deletions src/modules/email/services/email.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,40 @@ import { AwsSESService } from 'src/common/aws/services/aws.ses.service';
import { ENUM_EMAIL } from 'src/modules/email/constants/email.enum.constant';
import { capital } from 'case';
import { ConfigService } from '@nestjs/config';
import { signUpPlainBody } from 'src/modules/email/constants/email.constant';
import { UserDoc } from 'src/modules/user/repository/entities/user.entity';
import { EmailSendSignUpDto } from 'src/modules/email/dtos/email.send-sign-up.dto';
import { IEmailService } from 'src/modules/email/interfaces/email.service.interface';
import { EmailSendChangePasswordDto } from 'src/modules/email/dtos/email.send-change-password.dto';

@Injectable()
export class EmailService implements IEmailService {
private readonly appName: string;
private readonly fromEmail: string;

private readonly signUpPlainBody: string;
private readonly changePasswordPlainBody: string;

constructor(
private readonly awsSESService: AwsSESService,
private readonly configService: ConfigService
) {
this.appName = this.configService.get<string>('app.name');
this.fromEmail = this.configService.get<string>('email.fromEmail');

this.signUpPlainBody = this.configService.get<string>(
'email.signUpPlainBody'
);
this.changePasswordPlainBody = this.configService.get<string>(
'email.changePasswordPlainBody'
);
}

async createSignUp(): Promise<boolean> {
try {
await this.awsSESService.createTemplate({
name: ENUM_EMAIL.SIGN_UP,
subject: `${this.appName} ${capital(ENUM_EMAIL.SIGN_UP)}`,
htmlBody: `<h1>${signUpPlainBody}</h1>`,
plainTextBody: signUpPlainBody,
plainTextBody: this.signUpPlainBody,
});

return true;
Expand Down Expand Up @@ -63,6 +74,7 @@ export class EmailService implements IEmailService {
await this.awsSESService.send<EmailSendSignUpDto>({
templateName: ENUM_EMAIL.SIGN_UP,
recipients: [user.email],
sender: this.fromEmail,
templateData: {
appName: capital(this.appName),
name: capital(`${user.firstName} ${user.lastName}`),
Expand All @@ -74,4 +86,61 @@ export class EmailService implements IEmailService {
return false;
}
}

async createChangePassword(): Promise<boolean> {
try {
await this.awsSESService.createTemplate({
name: ENUM_EMAIL.CHANGE_PASSWORD,
subject: `${this.appName} ${capital(
ENUM_EMAIL.CHANGE_PASSWORD
)}`,
plainTextBody: this.changePasswordPlainBody,
});

return true;
} catch (err: unknown) {
return false;
}
}

async getChangePassword(): Promise<boolean> {
try {
await this.awsSESService.getTemplate({
name: ENUM_EMAIL.CHANGE_PASSWORD,
});

return true;
} catch (err: unknown) {
return false;
}
}

async deleteChangePassword(): Promise<boolean> {
try {
await this.awsSESService.deleteTemplate({
name: ENUM_EMAIL.CHANGE_PASSWORD,
});

return true;
} catch (err: unknown) {
return false;
}
}

async sendChangePassword(user: UserDoc): Promise<boolean> {
try {
await this.awsSESService.send<EmailSendChangePasswordDto>({
templateName: ENUM_EMAIL.CHANGE_PASSWORD,
recipients: [user.email],
sender: this.fromEmail,
templateData: {
name: capital(`${user.firstName} ${user.lastName}`),
},
});

return true;
} catch (err: unknown) {
return false;
}
}
}
4 changes: 4 additions & 0 deletions test/aws/aws.ses.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ describe('AwsSESService', () => {
const result: SendTemplatedEmailCommandOutput = await service.send({
recipients: ['mail@mail.com'],
templateName: 'template',
sender: 'sender@mail.com',
});
expect(service['sesClient'].send).toHaveBeenCalled();
expect(result).toEqual(data);
Expand All @@ -281,6 +282,7 @@ describe('AwsSESService', () => {
const result = service.send({
recipients: ['mail@mail.com'],
templateName: 'template',
sender: 'sender@mail.com',
});

try {
Expand Down Expand Up @@ -310,6 +312,7 @@ describe('AwsSESService', () => {
},
],
templateName: 'template',
sender: 'sender@mail.com',
});
expect(service['sesClient'].send).toHaveBeenCalled();
expect(result).toEqual(data);
Expand All @@ -328,6 +331,7 @@ describe('AwsSESService', () => {
},
],
templateName: 'template',
sender: 'sender@mail.com',
});

try {
Expand Down
Loading

0 comments on commit 153ab39

Please sign in to comment.