mirror of
https://github.com/n08i40k/schedule-parser-next.git
synced 2025-12-06 09:47:46 +03:00
1.4.0
Энд-поинт schedule/get-group-names теперь не требует авторизации (для формы регистрации). Энд-поинт schedule/get-group теперь не требует указания группы. Она берётся из данных пользователя. Энд-поинт auth/sign-in теперь может возвращать группу пользователя начиная с версии 1.
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "schedule-parser-next",
|
||||
"version": "1.3.5",
|
||||
"version": "1.4.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "schedule-parser-next",
|
||||
"version": "1.3.5",
|
||||
"version": "1.4.0",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@nestjs/cache-manager": "^2.2.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "schedule-parser-next",
|
||||
"version": "1.3.5",
|
||||
"version": "1.4.0",
|
||||
"description": "",
|
||||
"author": "N08I40K",
|
||||
"private": true,
|
||||
|
||||
@@ -2,3 +2,4 @@ import { Reflector } from "@nestjs/core";
|
||||
import { UserRoleDto } from "../dto/user.dto";
|
||||
|
||||
export const AuthRoles = Reflector.createDecorator<UserRoleDto[]>();
|
||||
export const AuthUnauthorized = Reflector.createDecorator<true>();
|
||||
|
||||
@@ -26,10 +26,13 @@ import {
|
||||
ChangePasswordReqDto,
|
||||
UpdateTokenReqDto,
|
||||
UpdateTokenResDto,
|
||||
SignInResDtoV0,
|
||||
SignInResDtoV1,
|
||||
} from "../dto/auth.dto";
|
||||
import { ResultDto } from "../utility/validation/class-validator.interceptor";
|
||||
import { ScheduleService } from "../schedule/schedule.service";
|
||||
import { UserToken } from "./auth.decorator";
|
||||
import { ResponseVersion } from "../version/response-version.decorator";
|
||||
|
||||
@Controller("api/v1/auth")
|
||||
export class AuthController {
|
||||
@@ -39,21 +42,30 @@ export class AuthController {
|
||||
) {}
|
||||
|
||||
@ApiExtraModels(SignInReqDto)
|
||||
@ApiExtraModels(SignInResDto)
|
||||
@ApiExtraModels(SignInResDtoV0)
|
||||
@ApiExtraModels(SignInResDtoV1)
|
||||
@ApiOperation({ summary: "Авторизация по логину и паролю", tags: ["auth"] })
|
||||
@ApiBody({ schema: refs(SignInReqDto)[0] })
|
||||
@ApiOkResponse({
|
||||
description: "Авторизация прошла успешно",
|
||||
schema: refs(SignInResDto)[0],
|
||||
schema: refs(SignInResDtoV0)[0],
|
||||
})
|
||||
@ApiOkResponse({
|
||||
description: "Авторизация прошла успешно",
|
||||
schema: refs(SignInResDtoV1)[0],
|
||||
})
|
||||
@ApiUnauthorizedResponse({
|
||||
description: "Некорректное имя пользователя или пароль",
|
||||
})
|
||||
@ResultDto(SignInResDto)
|
||||
@ResultDto([SignInResDtoV0, SignInResDtoV1])
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post("sign-in")
|
||||
signIn(@Body() signInDto: SignInReqDto) {
|
||||
return this.authService.signIn(signInDto);
|
||||
async signIn(
|
||||
@Body() signInDto: SignInReqDto,
|
||||
@ResponseVersion() responseVersion: number,
|
||||
): Promise<SignInResDtoV1 | SignInResDtoV0> {
|
||||
const data = await this.authService.signIn(signInDto);
|
||||
return SignInResDto.stripVersion(data, responseVersion);
|
||||
}
|
||||
|
||||
@ApiExtraModels(SignUpReqDto)
|
||||
|
||||
@@ -9,7 +9,7 @@ import { JwtService } from "@nestjs/jwt";
|
||||
import { Request } from "express";
|
||||
import { UsersService } from "../users/users.service";
|
||||
import { Reflector } from "@nestjs/core";
|
||||
import { AuthRoles } from "../auth-role/auth-role.decorator";
|
||||
import { AuthRoles, AuthUnauthorized } from "../auth-role/auth-role.decorator";
|
||||
import { isJWT } from "class-validator";
|
||||
|
||||
@Injectable()
|
||||
@@ -30,6 +30,9 @@ export class AuthGuard implements CanActivate {
|
||||
}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
if (this.reflector.get(AuthUnauthorized, context.getHandler()))
|
||||
return true;
|
||||
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const token = AuthGuard.extractTokenFromRequest(request);
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ export class AuthService {
|
||||
data: { accessToken: accessToken },
|
||||
});
|
||||
|
||||
return { id: user.id, accessToken: accessToken };
|
||||
return { id: user.id, accessToken: accessToken, group: user.group };
|
||||
}
|
||||
|
||||
async updateToken(
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
PickType,
|
||||
} from "@nestjs/swagger";
|
||||
import { UserDto } from "./user.dto";
|
||||
import { IsString } from "class-validator";
|
||||
import { Expose } from "class-transformer";
|
||||
import { IsJWT, IsMongoId, IsString } from "class-validator";
|
||||
import { Expose, instanceToPlain, plainToClass } from "class-transformer";
|
||||
|
||||
// SignIn
|
||||
export class SignInReqDto extends PickType(UserDto, ["username"]) {
|
||||
@@ -18,7 +18,50 @@ export class SignInReqDto extends PickType(UserDto, ["username"]) {
|
||||
password: string;
|
||||
}
|
||||
|
||||
export class SignInResDto extends PickType(UserDto, ["id", "accessToken"]) {}
|
||||
export class SignInResDtoV0 {
|
||||
@ApiProperty({
|
||||
example: "66e1b7e255c5d5f1268cce90",
|
||||
description: "Идентификатор (ObjectId)",
|
||||
})
|
||||
@IsMongoId()
|
||||
@Expose()
|
||||
id: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
description: "Последний токен доступа",
|
||||
})
|
||||
@IsJWT()
|
||||
@Expose()
|
||||
accessToken: string;
|
||||
}
|
||||
|
||||
export class SignInResDtoV1 extends SignInResDtoV0 {
|
||||
@ApiProperty({
|
||||
example: "ИС-214/23",
|
||||
description: "Группа",
|
||||
})
|
||||
@IsString()
|
||||
@Expose()
|
||||
group: string;
|
||||
}
|
||||
|
||||
export class SignInResDto extends SignInResDtoV1 {
|
||||
public static stripVersion(
|
||||
instance: SignInResDto,
|
||||
version: number,
|
||||
): SignInResDtoV0 | SignInResDtoV1 {
|
||||
switch (version) {
|
||||
default:
|
||||
return instance;
|
||||
case 0: {
|
||||
return plainToClass(SignInResDtoV0, instanceToPlain(instance), {
|
||||
excludeExtraneousValues: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SignUp
|
||||
export class SignUpReqDto extends IntersectionType(
|
||||
@@ -27,7 +70,10 @@ export class SignUpReqDto extends IntersectionType(
|
||||
PartialType(PickType(UserDto, ["version"])),
|
||||
) {}
|
||||
|
||||
export class SignUpResDto extends SignInResDto {}
|
||||
export class SignUpResDto extends PickType(SignInResDto, [
|
||||
"id",
|
||||
"accessToken",
|
||||
]) {}
|
||||
|
||||
// Update token
|
||||
export class UpdateTokenReqDto extends PickType(UserDto, ["accessToken"]) {}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
IsString,
|
||||
ValidateNested,
|
||||
} from "class-validator";
|
||||
import { ApiProperty, OmitType, PickType } from "@nestjs/swagger";
|
||||
import { ApiProperty, OmitType, PartialType, PickType } from "@nestjs/swagger";
|
||||
import {
|
||||
Expose,
|
||||
instanceToPlain,
|
||||
@@ -296,7 +296,9 @@ export class ScheduleDto {
|
||||
lastChangedDays: Array<Array<number>>;
|
||||
}
|
||||
|
||||
export class GroupScheduleRequestDto extends PickType(GroupDto, ["name"]) {}
|
||||
export class GroupScheduleReqDto extends PartialType(
|
||||
PickType(GroupDto, ["name"]),
|
||||
) {}
|
||||
|
||||
export class ScheduleGroupsDto {
|
||||
@ApiProperty({
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
CacheStatusV0Dto,
|
||||
CacheStatusV1Dto,
|
||||
GroupScheduleDto,
|
||||
GroupScheduleRequestDto,
|
||||
GroupScheduleReqDto,
|
||||
ScheduleDto,
|
||||
ScheduleGroupsDto,
|
||||
SiteMainPageDto,
|
||||
@@ -28,7 +28,11 @@ import {
|
||||
ApiOperation,
|
||||
refs,
|
||||
} from "@nestjs/swagger";
|
||||
import { ClientVersion } from "../version/client-version.decorator";
|
||||
import { ResponseVersion } from "../version/response-version.decorator";
|
||||
import { AuthRoles, AuthUnauthorized } from "../auth-role/auth-role.decorator";
|
||||
import { UserDto, UserRoleDto } from "../dto/user.dto";
|
||||
import { UserToken } from "../auth/auth.decorator";
|
||||
import { UserFromTokenPipe } from "../auth/auth.pipe";
|
||||
|
||||
@Controller("api/v1/schedule")
|
||||
@UseGuards(AuthGuard)
|
||||
@@ -36,12 +40,16 @@ export class ScheduleController {
|
||||
constructor(private readonly scheduleService: ScheduleService) {}
|
||||
|
||||
@ApiExtraModels(ScheduleDto)
|
||||
@ApiOperation({ summary: "Получение расписания", tags: ["schedule"] })
|
||||
@ApiOperation({
|
||||
summary: "Получение расписания",
|
||||
tags: ["schedule", "admin"],
|
||||
})
|
||||
@ApiOkResponse({
|
||||
description: "Расписание получено успешно",
|
||||
schema: refs(ScheduleDto)[0],
|
||||
})
|
||||
@ResultDto(ScheduleDto)
|
||||
@AuthRoles([UserRoleDto.ADMIN])
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Get("get")
|
||||
async getSchedule(): Promise<ScheduleDto> {
|
||||
@@ -62,9 +70,10 @@ export class ScheduleController {
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Post("get-group")
|
||||
async getGroupSchedule(
|
||||
@Body() groupDto: GroupScheduleRequestDto,
|
||||
@Body() groupDto: GroupScheduleReqDto,
|
||||
@UserToken(UserFromTokenPipe) user: UserDto,
|
||||
): Promise<GroupScheduleDto> {
|
||||
return await this.scheduleService.getGroup(groupDto.name);
|
||||
return await this.scheduleService.getGroup(groupDto.name ?? user.group);
|
||||
}
|
||||
|
||||
@ApiExtraModels(ScheduleGroupsDto)
|
||||
@@ -78,6 +87,7 @@ export class ScheduleController {
|
||||
})
|
||||
@ApiNotFoundResponse({ description: "Требуемая группа не найдена" })
|
||||
@ResultDto(ScheduleGroupsDto)
|
||||
@AuthUnauthorized()
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Get("get-group-names")
|
||||
async getGroupNames(): Promise<ScheduleGroupsDto> {
|
||||
@@ -107,7 +117,7 @@ export class ScheduleController {
|
||||
@Post("update-site-main-page")
|
||||
async updateSiteMainPage(
|
||||
@Body() siteMainPageDto: SiteMainPageDto,
|
||||
@ClientVersion() version: number,
|
||||
@ResponseVersion() version: number,
|
||||
): Promise<CacheStatusV0Dto> {
|
||||
return CacheStatusDto.stripVersion(
|
||||
await this.scheduleService.updateSiteMainPage(siteMainPageDto),
|
||||
@@ -133,7 +143,7 @@ export class ScheduleController {
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Get("cache-status")
|
||||
getCacheStatus(
|
||||
@ClientVersion() version: number,
|
||||
@ResponseVersion() version: number,
|
||||
): CacheStatusV0Dto | CacheStatusV1Dto {
|
||||
return CacheStatusDto.stripVersion(
|
||||
this.scheduleService.getCacheStatus(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createParamDecorator, ExecutionContext } from "@nestjs/common";
|
||||
|
||||
export const ClientVersion = createParamDecorator(
|
||||
export const ResponseVersion = createParamDecorator(
|
||||
(_, context: ExecutionContext) => {
|
||||
const sourceVersion: string | null = context.switchToHttp().getRequest()
|
||||
.headers.version;
|
||||
Reference in New Issue
Block a user