feat: add rmq publishing
This commit is contained in:
parent
0d184020d9
commit
5d3e468bf6
@ -35,6 +35,8 @@
|
|||||||
"@teacinema/common": "^1.0.0",
|
"@teacinema/common": "^1.0.0",
|
||||||
"@teacinema/contracts": "^1.0.0",
|
"@teacinema/contracts": "^1.0.0",
|
||||||
"@teacinema/passport": "^1.0.0",
|
"@teacinema/passport": "^1.0.0",
|
||||||
|
"amqp-connection-manager": "^5.0.0",
|
||||||
|
"amqplib": "^0.10.9",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.3",
|
"class-validator": "^0.14.3",
|
||||||
"dotenv-expand": "^12.0.3",
|
"dotenv-expand": "^12.0.3",
|
||||||
|
|||||||
@ -6,8 +6,10 @@ import {
|
|||||||
grpcEnv,
|
grpcEnv,
|
||||||
passportEnv,
|
passportEnv,
|
||||||
redisEnv,
|
redisEnv,
|
||||||
|
rmqEnv,
|
||||||
telegramEnv
|
telegramEnv
|
||||||
} from './config'
|
} from './config'
|
||||||
|
import { MessagingModule } from './infra/messaging/messaging.module'
|
||||||
import { PrismaModule } from './infra/prisma/prisma.module'
|
import { PrismaModule } from './infra/prisma/prisma.module'
|
||||||
import { RedisModule } from './infra/redis/redis.module'
|
import { RedisModule } from './infra/redis/redis.module'
|
||||||
import { AccountModule } from './modules/account/account.module'
|
import { AccountModule } from './modules/account/account.module'
|
||||||
@ -20,7 +22,7 @@ import { TokenModule } from './modules/token/token.module'
|
|||||||
imports: [
|
imports: [
|
||||||
ConfigModule.forRoot({
|
ConfigModule.forRoot({
|
||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
load: [dabataseEnv, grpcEnv, redisEnv, passportEnv, telegramEnv]
|
load: [dabataseEnv, grpcEnv, redisEnv, passportEnv, telegramEnv, rmqEnv]
|
||||||
}),
|
}),
|
||||||
PrismaModule,
|
PrismaModule,
|
||||||
RedisModule,
|
RedisModule,
|
||||||
@ -28,7 +30,8 @@ import { TokenModule } from './modules/token/token.module'
|
|||||||
OtpModule,
|
OtpModule,
|
||||||
AccountModule,
|
AccountModule,
|
||||||
TelegramModule,
|
TelegramModule,
|
||||||
TokenModule
|
TokenModule,
|
||||||
|
MessagingModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|||||||
1
src/config/env/index.ts
vendored
1
src/config/env/index.ts
vendored
@ -3,3 +3,4 @@ export * from './database.env'
|
|||||||
export * from './redis.env'
|
export * from './redis.env'
|
||||||
export * from './passport.env'
|
export * from './passport.env'
|
||||||
export * from './telegram.env'
|
export * from './telegram.env'
|
||||||
|
export * from './rmq.env'
|
||||||
|
|||||||
14
src/config/env/rmq.env.ts
vendored
Normal file
14
src/config/env/rmq.env.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { registerAs } from '@nestjs/config'
|
||||||
|
|
||||||
|
import { RmqValidator } from '@/config/validators'
|
||||||
|
import { validateEnv } from '@/shared/utils'
|
||||||
|
|
||||||
|
import { RmqConfig } from '../interfaces/rmq.interface'
|
||||||
|
|
||||||
|
export const rmqEnv = registerAs<RmqConfig>('rmq', () => {
|
||||||
|
validateEnv(process.env, RmqValidator)
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: process.env.RMQ_URL
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -2,6 +2,7 @@ import { DatabaseConfig } from './database.interface'
|
|||||||
import { GrpcConfig } from './grpc.interface'
|
import { GrpcConfig } from './grpc.interface'
|
||||||
import { PassportConfig } from './passport.interface'
|
import { PassportConfig } from './passport.interface'
|
||||||
import { RedisConfig } from './redis.interface'
|
import { RedisConfig } from './redis.interface'
|
||||||
|
import { RmqConfig } from './rmq.interface'
|
||||||
import { TelegramConfig } from './telegram.interface'
|
import { TelegramConfig } from './telegram.interface'
|
||||||
|
|
||||||
export interface AllConfigs {
|
export interface AllConfigs {
|
||||||
@ -10,4 +11,5 @@ export interface AllConfigs {
|
|||||||
redis: RedisConfig
|
redis: RedisConfig
|
||||||
passport: PassportConfig
|
passport: PassportConfig
|
||||||
telegram: TelegramConfig
|
telegram: TelegramConfig
|
||||||
|
rmq: RmqConfig
|
||||||
}
|
}
|
||||||
|
|||||||
3
src/config/interfaces/rmq.interface.ts
Normal file
3
src/config/interfaces/rmq.interface.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface RmqConfig {
|
||||||
|
url: string
|
||||||
|
}
|
||||||
@ -3,3 +3,4 @@ export * from './database.validator'
|
|||||||
export * from './redis.validator'
|
export * from './redis.validator'
|
||||||
export * from './passport.validator'
|
export * from './passport.validator'
|
||||||
export * from './telegram.validator'
|
export * from './telegram.validator'
|
||||||
|
export * from './rmq.validator'
|
||||||
|
|||||||
6
src/config/validators/rmq.validator.ts
Normal file
6
src/config/validators/rmq.validator.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { IsString } from 'class-validator'
|
||||||
|
|
||||||
|
export class RmqValidator {
|
||||||
|
@IsString()
|
||||||
|
public RMQ_URL: string
|
||||||
|
}
|
||||||
32
src/infra/messaging/messaging.module.ts
Normal file
32
src/infra/messaging/messaging.module.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { Global, Module } from '@nestjs/common'
|
||||||
|
import { ConfigService } from '@nestjs/config'
|
||||||
|
import { ClientsModule, Transport } from '@nestjs/microservices'
|
||||||
|
|
||||||
|
import { AllConfigs } from '@/config'
|
||||||
|
|
||||||
|
import { MessagingService } from './messaging.service'
|
||||||
|
|
||||||
|
@Global()
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
ClientsModule.registerAsync([
|
||||||
|
{
|
||||||
|
name: 'NOTIFICATION_CLIENT',
|
||||||
|
useFactory: (configService: ConfigService<AllConfigs>) => ({
|
||||||
|
transport: Transport.RMQ,
|
||||||
|
options: {
|
||||||
|
urls: [configService.get<string>('rmq.url', { infer: true })],
|
||||||
|
queue: 'notifications_queue',
|
||||||
|
queueOptions: {
|
||||||
|
durable: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
inject: [ConfigService]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
],
|
||||||
|
providers: [MessagingService],
|
||||||
|
exports: [MessagingService]
|
||||||
|
})
|
||||||
|
export class MessagingModule {}
|
||||||
14
src/infra/messaging/messaging.service.ts
Normal file
14
src/infra/messaging/messaging.service.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Inject, Injectable } from '@nestjs/common'
|
||||||
|
import { ClientProxy } from '@nestjs/microservices'
|
||||||
|
import { OtpRequestedEvent } from '@teacinema/contracts'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class MessagingService {
|
||||||
|
constructor(
|
||||||
|
@Inject('NOTIFICATION_CLIENT') private readonly client: ClientProxy
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public otpRequested(data: OtpRequestedEvent) {
|
||||||
|
return this.client.emit('auth.otp.requested', data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ import {
|
|||||||
VerifyOtpResponse
|
VerifyOtpResponse
|
||||||
} from '@teacinema/contracts/gen/auth'
|
} from '@teacinema/contracts/gen/auth'
|
||||||
|
|
||||||
|
import { MessagingService } from '@/infra/messaging/messaging.service'
|
||||||
import { OtpService } from '@/modules/otp/otp.service'
|
import { OtpService } from '@/modules/otp/otp.service'
|
||||||
import { UserRepository } from '@/shared/utils/repositories'
|
import { UserRepository } from '@/shared/utils/repositories'
|
||||||
|
|
||||||
@ -21,7 +22,8 @@ export class AuthService {
|
|||||||
public constructor(
|
public constructor(
|
||||||
private readonly userRepository: UserRepository,
|
private readonly userRepository: UserRepository,
|
||||||
private readonly otpService: OtpService,
|
private readonly otpService: OtpService,
|
||||||
private readonly tokenService: TokenService
|
private readonly tokenService: TokenService,
|
||||||
|
private readonly messagingService: MessagingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public async sendOtp(data: SendOtpRequest): Promise<SendOtpResponse> {
|
public async sendOtp(data: SendOtpRequest): Promise<SendOtpResponse> {
|
||||||
@ -44,11 +46,15 @@ export class AuthService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = await this.otpService.send(
|
const { code } = await this.otpService.send(
|
||||||
identifier,
|
identifier,
|
||||||
type as 'email' | 'phone'
|
type as 'email' | 'phone'
|
||||||
)
|
)
|
||||||
console.debug('CODE', code)
|
this.messagingService.otpRequested({
|
||||||
|
code: code.toString(),
|
||||||
|
identifier,
|
||||||
|
type: type as 'email' | 'phone'
|
||||||
|
})
|
||||||
|
|
||||||
return { ok: true }
|
return { ok: true }
|
||||||
}
|
}
|
||||||
|
|||||||
49
yarn.lock
49
yarn.lock
@ -1383,9 +1383,9 @@
|
|||||||
integrity sha512-q3DURJbSk3k8MNWFIYaSM4LEcBgPbWa+HJmBz/nzYT4kuYitJVSXxpZ97kr0Ea+81AZwAU3JhQKlkK0SBWUi0A==
|
integrity sha512-q3DURJbSk3k8MNWFIYaSM4LEcBgPbWa+HJmBz/nzYT4kuYitJVSXxpZ97kr0Ea+81AZwAU3JhQKlkK0SBWUi0A==
|
||||||
|
|
||||||
"@teacinema/contracts@^1.0.0":
|
"@teacinema/contracts@^1.0.0":
|
||||||
version "1.0.9"
|
version "1.1.0"
|
||||||
resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.9/contracts-1.0.9.tgz#14b136d0c08552147b0de637a7af6d340d538527"
|
resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.1.0/contracts-1.1.0.tgz#0d2f03f283dc9ee048eeb770152127f2037b7133"
|
||||||
integrity sha512-9BwWvXaDKgRcef6+1ep9vUDWBdOndqheeTX5mXK5OOvLXbLOlzYoqAUoT0ZwaRwOCD+Je/LDrqcdti6eoss71Q==
|
integrity sha512-x90R4R96AgrUDzOjUT7ePtc7phG3Gx61sI8/CZ1hETF3Ok/TWTHblxX/CIZVcOormBrxEh1FfU39P8/nfno91g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@nestjs/microservices" "^11.1.12"
|
"@nestjs/microservices" "^11.1.12"
|
||||||
protoc "33.4.0"
|
protoc "33.4.0"
|
||||||
@ -2087,6 +2087,21 @@ ajv@^6.12.4, ajv@^6.12.5:
|
|||||||
json-schema-traverse "^0.4.1"
|
json-schema-traverse "^0.4.1"
|
||||||
uri-js "^4.2.2"
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
|
amqp-connection-manager@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/amqp-connection-manager/-/amqp-connection-manager-5.0.0.tgz#3bf72f76e1e041768080227fffab1f9baea70baa"
|
||||||
|
integrity sha512-88yQzqa5RSBgnLl504XjvCQJ7d+osskdwvg35Lwm1LRbfLjNU9p7SQUMSP82BB7mseiq9tIUPJ3HE3eXQbpjEw==
|
||||||
|
dependencies:
|
||||||
|
promise-breaker "^6.0.0"
|
||||||
|
|
||||||
|
amqplib@^0.10.9:
|
||||||
|
version "0.10.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/amqplib/-/amqplib-0.10.9.tgz#5b744c21d624f9307d0399e4d339b7354675831c"
|
||||||
|
integrity sha512-jwSftI4QjS3mizvnSnOrPGYiUnm1vI2OP1iXeOUz5pb74Ua0nbf6nPyyTzuiCLEE3fMpaJORXh2K/TQ08H5xGA==
|
||||||
|
dependencies:
|
||||||
|
buffer-more-ints "~1.0.0"
|
||||||
|
url-parse "~1.5.10"
|
||||||
|
|
||||||
ansi-colors@4.1.3:
|
ansi-colors@4.1.3:
|
||||||
version "4.1.3"
|
version "4.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
|
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
|
||||||
@ -2332,6 +2347,11 @@ buffer-from@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||||
|
|
||||||
|
buffer-more-ints@~1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz#ef4f8e2dddbad429ed3828a9c55d44f05c611422"
|
||||||
|
integrity sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==
|
||||||
|
|
||||||
buffer@^5.5.0:
|
buffer@^5.5.0:
|
||||||
version "5.7.1"
|
version "5.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
|
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
|
||||||
@ -4897,6 +4917,11 @@ prisma@^7.3.0:
|
|||||||
mysql2 "3.15.3"
|
mysql2 "3.15.3"
|
||||||
postgres "3.4.7"
|
postgres "3.4.7"
|
||||||
|
|
||||||
|
promise-breaker@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/promise-breaker/-/promise-breaker-6.0.0.tgz#107d2b70f161236abdb4ac5a736c7eb8df489d0f"
|
||||||
|
integrity sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==
|
||||||
|
|
||||||
proper-lockfile@4.1.2:
|
proper-lockfile@4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f"
|
resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f"
|
||||||
@ -4959,6 +4984,11 @@ qs@^6.14.0, qs@^6.14.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
side-channel "^1.1.0"
|
side-channel "^1.1.0"
|
||||||
|
|
||||||
|
querystringify@^2.1.1:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||||
|
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
|
||||||
|
|
||||||
randombytes@^2.1.0:
|
randombytes@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||||
@ -5045,6 +5075,11 @@ require-from-string@^2.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||||
|
|
||||||
|
requires-port@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||||
|
integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
|
||||||
|
|
||||||
resolve-cwd@^3.0.0:
|
resolve-cwd@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
|
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
|
||||||
@ -5773,6 +5808,14 @@ uri-js@^4.2.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.0"
|
punycode "^2.1.0"
|
||||||
|
|
||||||
|
url-parse@~1.5.10:
|
||||||
|
version "1.5.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
|
||||||
|
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
|
||||||
|
dependencies:
|
||||||
|
querystringify "^2.1.1"
|
||||||
|
requires-port "^1.0.0"
|
||||||
|
|
||||||
util-deprecate@^1.0.1:
|
util-deprecate@^1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user