Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { EventEmitterModule } from '@nestjs/event-emitter';
import { MongooseModule } from '@nestjs/mongoose/dist/mongoose.module';
import { redisClusterInsStore, redisInsStore } from 'cache-manager-redis-yet';

import * as config from 'src/constants';

import { AppController } from './app.controller';
import { AuthModule } from './auth';
import { CaptchaModule } from './captcha';
Expand All @@ -13,9 +15,8 @@ import { EmailModule } from './email';
import { GroupModule } from './group';
import { HelloController } from './hello.controller';
import { IndustryModule } from './industry';
import { config as mongo } from './mongo';
import { NamespaceModule } from './namespace';
import { config as redis, RedisModule } from './redis';
import { RedisModule } from './redis';
import { RegionModule } from './region';
import { RoleModule } from './role';
import { SessionModule } from './session';
Expand All @@ -26,9 +27,9 @@ import { UserModule } from './user';
@Module({
imports: [
RedisModule,
MongooseModule.forRoot(mongo.url),
MongooseModule.forRoot(config.mongo.url),
BullModule.forRoot({
redis: redis.url,
redis: config.redis.url,
}),
CacheModule.registerAsync({
isGlobal: true,
Expand Down
13 changes: 7 additions & 6 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';

import { JwtPayload } from 'src/auth';
import { CaptchaService } from 'src/captcha';
import { ErrorCodes } from 'src/constants';
import * as config from 'src/constants';
import { addShortTimeSpan } from 'src/lib/lang/time';
import { CreateSessionDto, ErrorCodes as SessionErrorCodes, SessionService } from 'src/session';
import { CreateSessionDto, SessionService } from 'src/session';
import { ThirdPartySource } from 'src/third-party';
import { User, UserDocument, ErrorCodes as UserErrorCodes, UserService } from 'src/user';
import { User, UserDocument, UserService } from 'src/user';

import { AuthService } from './auth.service';
import { ErrorCodes } from './constants';
import { GithubDto } from './dto/github.dto';
import { LoginByEmailDto, LoginByPhoneDto, LoginDto, LogoutDto } from './dto/login.dto';
import { RefreshTokenDto } from './dto/refresh-token.dto';
Expand Down Expand Up @@ -343,7 +344,7 @@ export class AuthController {
const user = await this.userService.get(dto.uid);
if (!user) {
throw new NotFoundException({
code: UserErrorCodes.USER_NOT_FOUND,
code: config.ErrorCodes.USER_NOT_FOUND,
message: `user ${dto.uid} not found.`,
});
}
Expand Down Expand Up @@ -381,14 +382,14 @@ export class AuthController {
let session = await this.sessionService.findByRefreshToken(dto.refreshToken);
if (!session) {
throw new UnauthorizedException({
code: SessionErrorCodes.SESSION_NOT_FOUND,
code: config.ErrorCodes.SESSION_NOT_FOUND,
message: `session with refresh token ${dto.refreshToken} not found.`,
});
}

if (session.refreshTokenExpireAt.getTime() < Date.now()) {
throw new UnauthorizedException({
code: SessionErrorCodes.SESSION_EXPIRED,
code: config.ErrorCodes.SESSION_EXPIRED,
message: 'Session has been expired.',
});
}
Expand Down
6 changes: 3 additions & 3 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';

import { CaptchaModule } from 'src/captcha';
import * as config from 'src/constants';
import { EmailModule } from 'src/email';
import { GroupModule } from 'src/group';
import { NamespaceModule } from 'src/namespace';
Expand All @@ -15,16 +16,15 @@ import { UserModule } from 'src/user';

import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { jwtSecretKey } from './config';

@Module({
imports: [
JwtModule.register({
global: true,
secretOrPrivateKey: jwtSecretKey ?? fs.readFileSync('ssl/private.key', 'utf-8'),
secretOrPrivateKey: config.auth.jwtSecretKey ?? fs.readFileSync('ssl/private.key', 'utf-8'),
signOptions: {
allowInsecureKeySizes: true,
algorithm: jwtSecretKey ? 'HS256' : 'RS256',
algorithm: config.auth.jwtSecretKey ? 'HS256' : 'RS256',
},
}),
UserModule,
Expand Down
15 changes: 7 additions & 8 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { Inject, Injectable } from '@nestjs/common';
import { RedisClientType } from 'redis';

import { createThirdPartyDto } from 'src/third-party/dto/create-third-party.dto';
import { ThirdPartyDoc, ThirdPartySource } from 'src/third-party/entities/third-party.entity';
import { ThirdPartyService } from 'src/third-party/third-party.service';

import * as config from './config';
import * as config from 'src/constants';
import {
GithubAccessTokenUrl,
GithubClientId,
GithubClientSecret,
GithubUserUrl,
} from './constants';
} from 'src/constants';
import { createThirdPartyDto } from 'src/third-party/dto/create-third-party.dto';
import { ThirdPartyDoc, ThirdPartySource } from 'src/third-party/entities/third-party.entity';
import { ThirdPartyService } from 'src/third-party/third-party.service';

@Injectable()
export class AuthService {
Expand All @@ -24,7 +23,7 @@ export class AuthService {
const lock = await this.redisClient.hGetAll(`loginLock:${login}`);
if (!lock || !lock.attempts) return false;

return Number(lock.attempts) >= config.maxLoginAttempts;
return Number(lock.attempts) >= config.auth.maxLoginAttempts;
}

async lock(login: string): Promise<void> {
Expand All @@ -38,7 +37,7 @@ export class AuthService {
});

// 设置过期时间为登录锁定时长(秒)
await this.redisClient.expire(lockKey, config.loginLockInS);
await this.redisClient.expire(lockKey, config.auth.loginLockInS);
}

async getGithubAccessToken(code: string): Promise<string> {
Expand Down
7 changes: 0 additions & 7 deletions src/auth/config.ts

This file was deleted.

12 changes: 0 additions & 12 deletions src/auth/constants.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './auth.module';
export * from './entities/jwt.entity';
export * from './entities/session-with-token.entity';
export * from './constants';
3 changes: 2 additions & 1 deletion src/captcha/captcha.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import {
} from '@nestjs/swagger';
import { Response } from 'express';

import { ErrorCodes } from 'src/constants';

import { CaptchaService } from './captcha.service';
import { ErrorCodes } from './constants';
import { CreateCaptchaDto } from './dto/create-captcha.dto';
import { ListCaptchasQuery } from './dto/list-captchas.dto';
import { UpdateCaptchaDto } from './dto/update-captcha.dto';
Expand Down
6 changes: 3 additions & 3 deletions src/captcha/captcha.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import dayjs from 'dayjs';
import { DeleteResult } from 'mongodb';
import { Model } from 'mongoose';

import * as config from 'src/constants';
import { buildMongooseQuery } from 'src/mongo';

import * as config from './config';
import { CreateCaptchaDto } from './dto/create-captcha.dto';
import { getCaptchaByKeyDto } from './dto/get-captcha.dto';
import { ListCaptchasQuery } from './dto/list-captchas.dto';
Expand All @@ -20,7 +20,7 @@ export class CaptchaService {

create(createDto: CreateCaptchaDto) {
if (!createDto.code) {
createDto.code = this.generateCaptcha(config.codeLength);
createDto.code = this.generateCaptcha(config.captcha.codeLength);
}
const createdCaptcha = new this.captchaModel(createDto);
return createdCaptcha.save();
Expand Down Expand Up @@ -64,7 +64,7 @@ export class CaptchaService {
{ key },
{
...upsertDto,
expireAt: dayjs().add(config.expiresInS, 'second').toDate(),
expireAt: dayjs().add(config.captcha.expiresInS, 'second').toDate(),
},
{ upsert: true, new: true }
)
Expand Down
6 changes: 0 additions & 6 deletions src/captcha/config.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/captcha/constants.ts

This file was deleted.

5 changes: 2 additions & 3 deletions src/captcha/entities/captcha.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import { IntersectionType } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsDate, IsNotEmpty, IsString } from 'class-validator';

import * as config from 'src/constants';
import { SortFields } from 'src/lib/sort';
import { helper, MongoEntity } from 'src/mongo';

import * as config from '../config';

@Schema()
@SortFields(['expireAt'])
export class CaptchaDoc {
Expand All @@ -25,7 +24,7 @@ export class CaptchaDoc {
@IsNotEmpty()
@Type(() => Date)
@IsDate()
@Prop({ default: () => Date.now() + config.expiresInS * 1000, expires: '7d' })
@Prop({ default: () => Date.now() + config.captcha.expiresInS * 1000, expires: '7d' })
expireAt: Date;

/**
Expand Down
2 changes: 0 additions & 2 deletions src/captcha/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ export * from './captcha.controller';
export * from './captcha.service';
export * from './dto/create-captcha.dto';
export * from './entities/captcha.entity';
export * from './constants';
export * as config from './config';
5 changes: 0 additions & 5 deletions src/common/constants.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/common/exception-factory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BadRequestException } from '@nestjs/common';
import { ValidationError } from 'class-validator';

import { ErrorCodes } from './constants';
import { ErrorCodes } from 'src/constants';

export type ValidationErrorDetail = {
message: string;
Expand Down
6 changes: 0 additions & 6 deletions src/config.ts

This file was deleted.

61 changes: 61 additions & 0 deletions src/constants/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { toInteger, trimStart } from 'lodash';

import { EmailTransporter } from 'src/lib/email';
import { toBoolean } from 'src/lib/lang/boolean';

import { loadEnv } from '../lib/utils/env';

export const port = loadEnv('PORT');
export const prefix = trimStart(loadEnv('PREFIX') || '', '/');

export const auth = {
maxLoginAttempts: toInteger(loadEnv('MAX_LOGIN_ATTEMPTS')), // 过期时间
loginLockInS: toInteger(loadEnv('LOGIN_LOCK_IN_S')), // 验证码长度
jwtSecretKey: loadEnv('JWT_SECRET_KEY'), // jwt secret key
};

export const captcha = {
expiresInS: toInteger(loadEnv('CAPTCHA_EXPIRES_IN_S')), // 过期时间
codeLength: toInteger(loadEnv('CAPTCHA_CODE_LENGTH')), // 验证码长度
};

export const email = {
transporter: loadEnv('EMAIL_TRANSPORTER') as EmailTransporter,
nodemailer: {
pool: true,
host: loadEnv('NODEMAILER_HOST'),
port: Number(loadEnv('NODEMAILER_PORT')),
secure: toBoolean(loadEnv('NODEMAILER_SECURE')),
tls: {
rejectUnauthorized: false,
},
auth: {
user: loadEnv('NODEMAILER_AUTH_USER'),
pass: loadEnv('NODEMAILER_AUTH_PASS'),
},
},
postmark: {
serverToken: loadEnv('POSTMARK_API_TOKEN'),
},
};

export const mongo = {
url: loadEnv('MONGO_URL'),
};

export const redis = {
url: loadEnv('REDIS_URL'),
};

export const sms = {
aliyun: {
keyId: loadEnv('ALIYUN_SMS_KEY_ID'),
keySecret: loadEnv('ALIYUN_SMS_KEY_SECRET'),
},
};

export const user = {
identityVerify: {
appCode: 'appCode',
},
};
32 changes: 32 additions & 0 deletions src/constants/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export const ErrorCodes = {
AUTH_FAILED: 'AUTH_FAILED',
USER_ALREADY_EXISTS: 'USER_ALREADY_EXISTS',
CAPTCHA_INVALID: 'CAPTCHA_INVALID',
TOO_MANY_LOGIN_ATTEMPTS: 'TOO_MANY_LOGIN_ATTEMPTS',
USER_NOT_FOUND: 'USER_NOT_FOUND',
CAPTCHA_NOT_FOUND: 'CAPTCHA_NOT_FOUND',
CASTERROR: 'CASTERROR',
DUPLICATE: 'DUPLICATE',
VALIDATE_FAILED: 'VALIDATION_FAILED',
EMAIL_SEND_FAILED: 'EMAIL_SEND_FAILED',
EMAIL_RECORD_NOT_FOUND: 'EMAIL_RECORD_NOT_FOUND',
GROUP_ALREADY_EXISTS: 'GROUP_ALREADY_EXISTS',
GROUP_NOT_FOUND: 'GROUP_NOT_FOUND',
NAMESPACE_ALREADY_EXISTS: 'NAMESPACE_ALREADY_EXISTS',
NAMESPACE_NOT_FOUND: 'NAMESPACE_NOT_FOUND',
EMPLOYEE_ID_ALREADY_EXISTS: 'EMPLOYEE_ID_ALREADY_EXISTS',
EMAIL_ALREADY_EXISTS: 'EMAIL_ALREADY_EXISTS',
PHONE_ALREADY_EXISTS: 'PHONE_ALREADY_EXISTS',
WRONG_OLD_PASSWORD: 'WRONG_OLD_PASSWORD',
ROLE_ALREADY_EXISTS: 'ROLE_ALREADY_EXISTS',
ROLE_NOT_FOUND: 'ROLE_NOT_FOUND',
SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',
SESSION_EXPIRED: 'SESSION_EXPIRED',
SMS_SEND_FAILED: 'SMS_SEND_FAILED',
SMS_RECORD_NOT_FOUND: 'SMS_RECORD_NOT_FOUND',
};

export const GithubAccessTokenUrl = 'https://github.com/login/oauth/access_token';
export const GithubClientId = 'Iv23lizBaVPIiABBCHaz';
export const GithubClientSecret = '041f46399c1396ec27d16851c1aa2aa479a3f5a5';
export const GithubUserUrl = 'https://api.github.com/user';
2 changes: 2 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './constants';
export * from './config';
23 changes: 0 additions & 23 deletions src/email/config.ts

This file was deleted.

4 changes: 0 additions & 4 deletions src/email/constants.ts

This file was deleted.

Loading
Loading