feat: add email/phone change notifications
This commit is contained in:
parent
7e9e47f755
commit
a4b9f46afd
@ -19,4 +19,13 @@ export class MailService {
|
|||||||
html
|
html
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async sendEmailChange(email: string, code: string) {
|
||||||
|
const html = this.templateService.render('email-change', { code })
|
||||||
|
await this.transporter.sendMail({
|
||||||
|
to: email,
|
||||||
|
subject: 'Подтверждение смены почты',
|
||||||
|
html
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/infra/mail/templates/email-change.hbs
Normal file
14
src/infra/mail/templates/email-change.hbs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>Подтверждение смены почты</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Подтверждение смены почты</h1>
|
||||||
|
<p>Ваш код подтверждения для смены почты: {{code}}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1,6 +1,10 @@
|
|||||||
import { Controller } from '@nestjs/common'
|
import { Controller, Logger } from '@nestjs/common'
|
||||||
import { Ctx, EventPattern, Payload, RmqContext } from '@nestjs/microservices'
|
import { Ctx, EventPattern, Payload, RmqContext } from '@nestjs/microservices'
|
||||||
import type { OtpRequestedEvent } from '@teacinema/contracts'
|
import type {
|
||||||
|
EmailChangedEvent,
|
||||||
|
OtpRequestedEvent,
|
||||||
|
PhoneChangedEvent
|
||||||
|
} from '@teacinema/contracts'
|
||||||
|
|
||||||
import { RmqService } from '../../infra/rmq/rmq.service'
|
import { RmqService } from '../../infra/rmq/rmq.service'
|
||||||
|
|
||||||
@ -8,6 +12,8 @@ import { NotificationsService } from './notifications.service'
|
|||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class NotificationsController {
|
export class NotificationsController {
|
||||||
|
private readonly logger = new Logger(NotificationsController.name)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly notificationsService: NotificationsService,
|
private readonly notificationsService: NotificationsService,
|
||||||
private readonly rmqService: RmqService
|
private readonly rmqService: RmqService
|
||||||
@ -22,7 +28,35 @@ export class NotificationsController {
|
|||||||
await this.notificationsService.sendOtp(data)
|
await this.notificationsService.sendOtp(data)
|
||||||
this.rmqService.ack(ctx)
|
this.rmqService.ack(ctx)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('OTP processing error', e.message ?? e)
|
this.logger.error(`OTP processing error ${e.message ?? e}}`)
|
||||||
|
this.rmqService.nack(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventPattern('account.phone.changed')
|
||||||
|
public async phoneChangedRequested(
|
||||||
|
@Payload() data: PhoneChangedEvent,
|
||||||
|
@Ctx() ctx: RmqContext
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
await this.notificationsService.phoneChanged(data)
|
||||||
|
this.rmqService.ack(ctx)
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(`Phone changing processing error ${e.message ?? e}}`)
|
||||||
|
this.rmqService.nack(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventPattern('account.email.changed')
|
||||||
|
public async emaileChangedRequested(
|
||||||
|
@Payload() data: EmailChangedEvent,
|
||||||
|
@Ctx() ctx: RmqContext
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
await this.notificationsService.emailChanged(data)
|
||||||
|
this.rmqService.ack(ctx)
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(`Email changing processing error ${e.message ?? e}}`)
|
||||||
this.rmqService.nack(ctx)
|
this.rmqService.nack(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,51 @@
|
|||||||
import { Injectable } from '@nestjs/common'
|
import { Injectable, Logger } from '@nestjs/common'
|
||||||
import { OtpRequestedEvent } from '@teacinema/contracts'
|
import {
|
||||||
|
EmailChangedEvent,
|
||||||
|
OtpRequestedEvent,
|
||||||
|
PhoneChangedEvent
|
||||||
|
} from '@teacinema/contracts'
|
||||||
|
|
||||||
import { MailService } from '../../infra/mail/mail.service'
|
import { MailService } from '../../infra/mail/mail.service'
|
||||||
|
import { SmsService } from '../../infra/sms/sms.service'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NotificationsService {
|
export class NotificationsService {
|
||||||
constructor(private readonly mailService: MailService) {}
|
private readonly logger = new Logger(NotificationsService.name)
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private readonly mailService: MailService,
|
||||||
|
private readonly smsService: SmsService
|
||||||
|
) {}
|
||||||
|
|
||||||
public async sendOtp(data: OtpRequestedEvent) {
|
public async sendOtp(data: OtpRequestedEvent) {
|
||||||
const { identifier, type, code } = data
|
const { identifier, type, code } = data
|
||||||
|
|
||||||
if (type === 'email') {
|
this.logger.log(`Send OTP to ${identifier} via ${type}`)
|
||||||
console.log('SEND EMAIL', data)
|
|
||||||
await this.mailService.sendOtp(identifier, code)
|
switch (type) {
|
||||||
} else {
|
case 'email':
|
||||||
console.log('SMS')
|
await this.mailService.sendOtp(identifier, code)
|
||||||
|
break
|
||||||
|
case 'phone':
|
||||||
|
await this.smsService.sendOtp(identifier, code)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
this.logger.error(`Unknown notification type: ${type}`)
|
||||||
|
throw new Error(`Unknown type: ${type}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async phoneChanged(data: PhoneChangedEvent) {
|
||||||
|
const { phone, code } = data
|
||||||
|
|
||||||
|
this.logger.log(`Change phone to ${phone} via phone`)
|
||||||
|
return await this.smsService.sendPhoneChanged(phone, code)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async emailChanged(data: EmailChangedEvent) {
|
||||||
|
const { email, code } = data
|
||||||
|
|
||||||
|
this.logger.log(`Change email to ${email} via email`)
|
||||||
|
return await this.mailService.sendEmailChange(email, code)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user