Skip to content

Commit

Permalink
feat: register with password when email and sms both disable
Browse files Browse the repository at this point in the history
  • Loading branch information
AprilNEA committed Dec 9, 2023
1 parent b971d53 commit 25309e8
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 76 deletions.
22 changes: 22 additions & 0 deletions packages/backend/src/common/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,26 @@ export class ConfigService {
fs.writeFileSync(this.configFilePath, jsonData, 'utf8');
this.loadConfig();
}

checkEmailEnable() {
return (
this.get('email') &&
this.get('email').use &&
this.get('email').use !== 'disable'
);
}

checkSMSEnable() {
return (
this.get('sms') &&
this.get('sms').use &&
this.get('sms').use !== 'disable'
);
}

checkNotifierEnable(all = false) {
return all
? this.checkEmailEnable() && this.checkSMSEnable()
: this.checkEmailEnable() || this.checkSMSEnable();
}
}
4 changes: 4 additions & 0 deletions packages/backend/src/common/exceptions/biz.exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,15 @@ export const ErrorCode = Object.freeze<
});

export class BizException extends HttpException {
code: ErrorCodeEnum;

constructor(code: ErrorCodeEnum) {
const [message, chMessage, statusCode] = ErrorCode[code];
super(
HttpException.createBody({ success: false, code, message, chMessage }),
statusCode,
);

this.code = code;
}
}
35 changes: 28 additions & 7 deletions packages/backend/src/modules/auth/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Body, Controller, Get, Post, Put, Query } from '@nestjs/common';
import { Role } from '@prisma/client';

import { ConfigService } from '@/common/config';
import { BizException } from '@/common/exceptions/biz.exception';
import { Payload, Public } from '@/common/guards/auth.guard';
import { ZodValidationPipe } from '@/common/pipes/zod';
import { WechatService } from '@/modules/auth/wechat.service';

import { AuthDTO } from 'shared';
import { AuthDTO, ErrorCodeEnum } from 'shared';

import { AuthService } from './auth.service';

Expand All @@ -14,6 +16,7 @@ export class AuthController {
constructor(
private readonly authService: AuthService,
private wechatService: WechatService,
private configService: ConfigService,
) {}

@Public()
Expand All @@ -28,17 +31,35 @@ export class AuthController {
};
}

/* 方法一:密码登录 */
/* 方法一:密码登录
* WARN: 当邮箱和短信通知均为开启时,用户可直接通过该接口注册
* WARN: When both email and SMS notification are enabled,
* users can register directly through this interface.
*/
@Public()
@Post('password')
async password(
@Body(new ZodValidationPipe(AuthDTO.PasswordLoginSchema))
body: AuthDTO.PasswordLoginDto,
) {
return {
success: true,
...(await this.authService.loginPassword(body)),
};
try {
return {
success: true,
...(await this.authService.loginPassword(body)),
};
} catch (e) {
if (
e instanceof BizException &&
e.code === ErrorCodeEnum.UserNotExist &&
this.configService.checkNotifierEnable(false) === false // It won't hold as long as one is enabled
) {
return {
success: true,
...(await this.authService.registerPassword(body)),
};
}
throw e;
}
}

/* 方法二:验证码登录/注册 */
Expand All @@ -61,7 +82,7 @@ export class AuthController {
) {
return {
success: true,
...(await this.authService.WithValidateCode(data.identity, data.code)),
...(await this.authService.withValidateCode(data.identity, data.code)),
};
}

Expand Down
44 changes: 0 additions & 44 deletions packages/backend/src/modules/auth/auth.dto.ts

This file was deleted.

64 changes: 41 additions & 23 deletions packages/backend/src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,38 @@ export class AuthService {
}
}

async #register({
identity,
password,
}: {
identity: string;
password?: string;
}) {
const { email, phone } = getPhoneOrEmail(identity);

const existUser = await this.prisma.client.user.findMany({
where: {
OR: [{ email }, { phone }],
},
});

let user;
if (existUser.length != 1) {
// 注册用户
user = await this.prisma.client.user.create({
data: {
email: email,
phone: phone,
role: Role.User,
password: password ? hashSync(password, SALT_ROUNDS) : undefined,
},
});
} else {
user = existUser[0];
}
return this.#signWithCheck(user);
}

/* 添加验证码 */
async newValidateCode(identity: string) {
const { email, phone } = getPhoneOrEmail(identity);
Expand Down Expand Up @@ -127,32 +159,18 @@ export class AuthService {
}
}

/* Only used when email and sms service both disabled */
registerPassword(data: ByPassword) {
return this.#register(data);
}

/* 通过验证码登录/注册 */
async WithValidateCode(identity: string, code: string) {
async withValidateCode(identity: string, code: string) {
const { email, phone } = getPhoneOrEmail(identity);

await this.#verifyCode(identity, code);

const existUser = await this.prisma.client.user.findMany({
where: {
OR: [{ email }, { phone }],
},
});

let user;
if (existUser.length != 1) {
// 注册用户
user = await this.prisma.client.user.create({
data: {
email: email,
phone: phone,
role: Role.User,
},
});
} else {
user = existUser[0];
}
return this.#signWithCheck(user);
return this.#register({ identity });
}

/* 通过密码登录 */
Expand All @@ -165,11 +183,11 @@ export class AuthService {
},
});
if (user.length != 1) {
throw Error('User does not exist');
throw new BizException(ErrorCodeEnum.UserNotExist);
}
const isPasswordCorrect = await compare(password, user[0].password);
if (!isPasswordCorrect) {
throw Error('Password is incorrect');
throw new BizException(ErrorCodeEnum.PasswordError);
}
return this.#signWithCheck(user[0]);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/shared/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface ConfigType {
keys: string;
};
sms: {
use?: 'aliyun' | 'tencent' | 'uni';
use?: 'disable' | 'aliyun' | 'tencent' | 'uni';
uni?: {
signature: string;
templateId: string;
Expand All @@ -40,7 +40,7 @@ export interface ConfigType {
};
};
email: {
use?: 'smtp' | 'resend' | 'mailgun' | 'elastic';
use?: 'disable' | 'smtp' | 'resend' | 'mailgun' | 'elastic';
domain: string;
sender?: string;
smtp: {};
Expand Down

0 comments on commit 25309e8

Please sign in to comment.