feat: init email service

This commit is contained in:
Innei
2021-09-03 17:33:17 +08:00
parent 4fcb0dfb5d
commit df9f54494c
5 changed files with 108 additions and 30 deletions

View File

@@ -1,9 +1,11 @@
import { Global, Module } from '@nestjs/common'
import { UserModule } from '../user/user.module'
import { ConfigsService } from './configs.service'
@Global()
@Module({
providers: [ConfigsService],
imports: [UserModule],
exports: [ConfigsService],
})
export class ConfigsModule {}

View File

@@ -1,37 +1,63 @@
import { Injectable, UnprocessableEntityException } from '@nestjs/common'
import { Injectable, Logger } from '@nestjs/common'
import { ReturnModelType } from '@typegoose/typegoose'
import { InjectModel } from 'nestjs-typegoose'
import { UserModel } from '../user/user.model'
import { UserService } from '../user/user.service'
import { BackupOptions, MailOptionsDto, SEODto, UrlDto } from './configs.dto'
import { IConfig } from './configs.interface'
import { OptionModel } from './configs.model'
const defaultConfig = {
seo: {
title: 'mx-space',
description: 'Hello World~',
},
url: {
wsUrl: 'http://localhost:8080', //todo
adminUrl: 'http://localhost:9528',
serverUrl: 'http://localhost:2333',
webUrl: 'http://localhost:2323',
},
mailOptions: {} as MailOptionsDto,
commentOptions: { antiSpam: false },
backupOptions: { enable: false } as BackupOptions,
baiduSearchOptions: { enable: false },
}
@Injectable()
export class ConfigsService {
private config: IConfig = {
seo: {
title: 'mx-space',
description: 'Hello World~',
},
url: {
wsUrl: 'http://localhost:8080', //todo
adminUrl: 'http://localhost:9528',
serverUrl: 'http://localhost:2333',
webUrl: 'http://localhost:2323',
},
mailOptions: {} as MailOptionsDto,
commentOptions: { antiSpam: false },
backupOptions: { enable: false } as BackupOptions,
baiduSearchOptions: { enable: false },
}
private config: IConfig = defaultConfig
private logger: Logger
constructor(
@InjectModel(OptionModel)
private readonly optionModel: ReturnModelType<typeof OptionModel>,
@InjectModel(UserModel)
private readonly userModel: ReturnModelType<typeof UserModel>,
private readonly userService: UserService,
) {
this.configInit()
this.logger = new Logger(ConfigsService.name)
}
private configInitd = false
public waitForConfigReady() {
return new Promise<IConfig>(async (r, j) => {
const maxCount = 5
let curCount = 0
const check = () => {
if (curCount >= maxCount) {
j('检查数据库连接')
timer = clearTimeout(timer)
}
if (this.configInitd) {
r({ ...this.config })
timer = clearTimeout(timer)
} else {
check()
}
curCount += 1
}
let timer: any = setTimeout(() => {
check()
}, 1000)
})
}
protected async configInit() {
@@ -41,6 +67,8 @@ export class ConfigsService {
const value = field.value
this.config[name] = value
})
this.configInitd = true
this.logger.log('Config 已经加载完毕!')
}
public get seo() {
@@ -79,11 +107,7 @@ export class ConfigsService {
return this.config[key]
}
public async getMaster() {
const master = await this.userModel.findOne()
if (!master) {
throw new UnprocessableEntityException('未初始化')
}
return master
get getMaster() {
return this.userService.getMaster
}
}

View File

@@ -56,9 +56,14 @@ export class UserService {
return !!(await this.userModel.countDocuments())
}
getMaster() {
return this.userModel.findOne().lean()
public async getMaster() {
const master = await this.userModel.findOne().lean()
if (!master) {
throw new BadRequestException('我还没有主人')
}
return master
}
async createMaster(
model: Pick<UserModel, 'username' | 'name' | 'password'> &
Partial<Pick<UserModel, 'introduce' | 'avatar' | 'url'>>,

View File

@@ -0,0 +1,46 @@
import { Injectable, Logger } from '@nestjs/common'
import { createTransport } from 'nodemailer'
import { ConfigsService } from '~/modules/configs/configs.service'
@Injectable()
export class EmailService {
private instance: ReturnType<typeof createTransport>
private logger: Logger
constructor(private readonly configsService: ConfigsService) {
this.init()
this.logger = new Logger(EmailService.name)
}
init() {
this.getConfigFromConfigService().then((config) => {
this.instance = createTransport({
...config,
secure: true,
tls: {
rejectUnauthorized: false,
},
})
this.logger.log('送信服务已经加载完毕!')
})
}
private getConfigFromConfigService() {
return new Promise<{
host: string
port: number
auth: { user: string; pass: string }
}>((r) => {
this.configsService.waitForConfigReady().then(({ mailOptions }) => {
const { options, user, pass } = mailOptions
r({
host: options.host,
port: +options.port || 465,
auth: { user, pass },
} as const)
})
})
}
get checkIsReady() {
return !!this.instance
}
}

View File

@@ -1,4 +1,5 @@
import { Module } from '@nestjs/common'
import { EmailService } from './helper.email.service'
@Module({ imports: [] })
@Module({ imports: [], providers: [EmailService] })
export class HelperModule {}