lint
This commit is contained in:
@@ -30,10 +30,12 @@ import { ThrottlerModule } from '@nestjs/throttler';
|
|||||||
}),
|
}),
|
||||||
PassportModule.register({ defaultStrategy: 'jwt' }),
|
PassportModule.register({ defaultStrategy: 'jwt' }),
|
||||||
ThrottlerModule.forRoot({
|
ThrottlerModule.forRoot({
|
||||||
throttlers: [{
|
throttlers: [
|
||||||
|
{
|
||||||
limit: 1000,
|
limit: 1000,
|
||||||
ttl: 60000, // 1 minute
|
ttl: 60000, // 1 minute
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
UserModule,
|
UserModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { JwtStrategy } from './strategies/jwt.strategy';
|
|||||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||||
import { VerificationModule } from 'src/verification/verification.module';
|
import { VerificationModule } from 'src/verification/verification.module';
|
||||||
import { OptionalAuthGuard } from './strategies/OptionalAuthGuard';
|
import { OptionalAuthGuard } from './strategies/OptionalAuthGuard';
|
||||||
import { NotificationModule } from 'src/notification/notification.module';
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common';
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
Injectable,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||||
@@ -37,7 +41,7 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
sessionId
|
sessionId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {
|
|||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
Get,
|
Get,
|
||||||
Ip,
|
|
||||||
Param,
|
Param,
|
||||||
ParseUUIDPipe,
|
ParseUUIDPipe,
|
||||||
Post,
|
Post,
|
||||||
|
|||||||
@@ -1,30 +1,34 @@
|
|||||||
import { BadRequestException, CanActivate, ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common';
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
CanActivate,
|
||||||
|
ExecutionContext,
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { Reflector } from '@nestjs/core';
|
import { Reflector } from '@nestjs/core';
|
||||||
import { Role } from 'src/auth/role.enum';
|
import { Role } from 'src/auth/role.enum';
|
||||||
import { User } from 'src/user/entities/user.entity';
|
import { User } from 'src/user/entities/user.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RolesGuard implements CanActivate {
|
export class RolesGuard implements CanActivate {
|
||||||
constructor(
|
constructor(private reflector: Reflector) {}
|
||||||
private reflector: Reflector,
|
|
||||||
) { }
|
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
const requiredRoles = this.reflector.getAllAndOverride<Role[] | undefined>('roles', [
|
const requiredRoles = this.reflector.getAllAndOverride<Role[] | undefined>(
|
||||||
context.getHandler(),
|
'roles',
|
||||||
context.getClass(),
|
[context.getHandler(), context.getClass()],
|
||||||
]);
|
);
|
||||||
|
|
||||||
if (!requiredRoles) return true;
|
if (!requiredRoles) return true;
|
||||||
|
|
||||||
const request = context.switchToHttp().getRequest();
|
const request = context.switchToHttp().getRequest();
|
||||||
const user = request.user as (User | void);
|
const user = request.user as User | void;
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
throw new BadRequestException('服务器内部错误');
|
throw new BadRequestException('服务器内部错误');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!requiredRoles.some(role => user.roles.includes(role))) {
|
if (!requiredRoles.some((role) => user.roles.includes(role))) {
|
||||||
throw new ForbiddenException('权限不足');
|
throw new ForbiddenException('权限不足');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import Dm20151123, * as $Dm20151123 from '@alicloud/dm20151123';
|
import Dm20151123, * as $Dm20151123 from '@alicloud/dm20151123';
|
||||||
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
|
import * as $OpenApi from '@alicloud/openapi-client';
|
||||||
import Client, * as $dm from "@alicloud/dm20151123";
|
// import Client, * as $dm from '@alicloud/dm20151123';
|
||||||
import Util, * as $Util from '@alicloud/tea-util';
|
import * as $Util from '@alicloud/tea-util';
|
||||||
import Credential, { Config } from '@alicloud/credentials';
|
import Credential, { Config } from '@alicloud/credentials';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NotificationService {
|
export class NotificationService {
|
||||||
|
|
||||||
private dm: Dm20151123;
|
private dm: Dm20151123;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -23,7 +22,7 @@ export class NotificationService {
|
|||||||
this.dm = new Dm20151123(config);
|
this.dm = new Dm20151123(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMailHtmlBody(option: { type: 'login-verify', code: string }) {
|
private getMailHtmlBody(option: { type: 'login-verify'; code: string }) {
|
||||||
if (option.type === 'login-verify') {
|
if (option.type === 'login-verify') {
|
||||||
return `<!DOCTYPE html>
|
return `<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@@ -76,25 +75,31 @@ export class NotificationService {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>`
|
</html>`;
|
||||||
} else {
|
} else {
|
||||||
throw new Error('未配置的模版');
|
throw new Error('未配置的模版');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendMail(option: {
|
||||||
async sendMail(option: { type: 'login-verify', targetMail: string, code: string; }) {
|
type: 'login-verify';
|
||||||
|
targetMail: string;
|
||||||
|
code: string;
|
||||||
|
}) {
|
||||||
const runtime = new $Util.RuntimeOptions({});
|
const runtime = new $Util.RuntimeOptions({});
|
||||||
|
|
||||||
const singleSendMailRequest = new $Dm20151123.SingleSendMailRequest({
|
const singleSendMailRequest = new $Dm20151123.SingleSendMailRequest({
|
||||||
accountName: "security@tonesc.cn",
|
accountName: 'security@tonesc.cn',
|
||||||
addressType: 1,
|
addressType: 1,
|
||||||
replyToAddress: false,
|
replyToAddress: false,
|
||||||
toAddress: `${option.targetMail}`,
|
toAddress: `${option.targetMail}`,
|
||||||
subject: "【特恩的日志】登陆验证码",
|
subject: '【特恩的日志】登陆验证码',
|
||||||
htmlBody: this.getMailHtmlBody({ type: 'login-verify', code: option.code }),
|
htmlBody: this.getMailHtmlBody({
|
||||||
textBody: "",
|
type: 'login-verify',
|
||||||
})
|
code: option.code,
|
||||||
|
}),
|
||||||
|
textBody: '',
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.dm.singleSendMailWithOptions(singleSendMailRequest, runtime);
|
await this.dm.singleSendMailWithOptions(singleSendMailRequest, runtime);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export class UserService {
|
|||||||
return this.userRepository.findOne({
|
return this.userRepository.findOne({
|
||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import { BadRequestException, Body, Controller, Post, UseGuards } from '@nestjs/common';
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Post,
|
||||||
|
UseGuards,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { SendVerificationCodeDto } from './dto/send-verification-code.dto';
|
import { SendVerificationCodeDto } from './dto/send-verification-code.dto';
|
||||||
import { VerificationService } from './verification.service';
|
import { VerificationService } from './verification.service';
|
||||||
import { Throttle, ThrottlerGuard } from '@nestjs/throttler';
|
import { Throttle, ThrottlerGuard } from '@nestjs/throttler';
|
||||||
|
|||||||
@@ -51,10 +51,12 @@ export class VerificationService {
|
|||||||
this.saveCode(key, code);
|
this.saveCode(key, code);
|
||||||
this.logger.log(`Email[${email}] code: ${code}`);
|
this.logger.log(`Email[${email}] code: ${code}`);
|
||||||
// 发送验证码
|
// 发送验证码
|
||||||
await this.notificationService.sendMail({ type: 'login-verify', targetMail: email, code, }).catch(() => {
|
await this.notificationService
|
||||||
|
.sendMail({ type: 'login-verify', targetMail: email, code })
|
||||||
|
.catch(() => {
|
||||||
this.clearCode(key);
|
this.clearCode(key);
|
||||||
throw new BadRequestException('发送失败,请稍后再试');
|
throw new BadRequestException('发送失败,请稍后再试');
|
||||||
})
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default function Page() {
|
|||||||
refreshSTSToken: async () => {
|
refreshSTSToken: async () => {
|
||||||
await storeMeta.refresh();
|
await storeMeta.refresh();
|
||||||
if (!storeMeta.stsTokenData) throw new Error();
|
if (!storeMeta.stsTokenData) throw new Error();
|
||||||
const { AccessKeyId, AccessKeySecret, SecurityToken } = data;
|
const { AccessKeyId, AccessKeySecret, SecurityToken } = storeMeta.stsTokenData;
|
||||||
return {
|
return {
|
||||||
accessKeyId: AccessKeyId,
|
accessKeyId: AccessKeyId,
|
||||||
accessKeySecret: AccessKeySecret,
|
accessKeySecret: AccessKeySecret,
|
||||||
@@ -65,6 +65,7 @@ export default function Page() {
|
|||||||
ossStore.setStore(store);
|
ossStore.setStore(store);
|
||||||
ossStore.setWorkDir(`tone-page/${data.userId}`)
|
ossStore.setWorkDir(`tone-page/${data.userId}`)
|
||||||
ossStore.loadObjectList();
|
ossStore.loadObjectList();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- storeMeta引用会导致无限循环,依赖stsTokenData即可
|
||||||
}, [storeMeta.stsTokenData]);
|
}, [storeMeta.stsTokenData]);
|
||||||
|
|
||||||
const handleRefreshFileList = async () => ossStore.loadObjectList().catch(e => toast.error(e.message));
|
const handleRefreshFileList = async () => ossStore.loadObjectList().catch(e => toast.error(e.message));
|
||||||
|
|||||||
Reference in New Issue
Block a user