diff --git a/src/minecraft/minecraft.service.ts b/src/minecraft/minecraft.service.ts index a953d6f..9b10711 100644 --- a/src/minecraft/minecraft.service.ts +++ b/src/minecraft/minecraft.service.ts @@ -215,25 +215,6 @@ export class MinecraftService { }; } - - async changeValid(session: Session, state: boolean) { - /* switch displaying nick in search */ - - const minecraft = await this.prisma.minecraft.findFirst({ where: { userId: session.user.id } }); - - if (!minecraft) return { - statusCode: 404, - message: 'Minecraft account not connected', - message_ru: 'Аккаунт Minecraft не привязан' - }; - - const result = await this.prisma.minecraft.update({ - where: { id: minecraft.id }, - data: { valid: state } - }) - return { statusCode: 200, new_data: result.valid }; - } - async getByCode(code: string): Promise<{ nickname: string, UUID: string } | null> { const response = await axios.get(`https://mc-oauth.andcool.ru/code/${code}`, { validateStatus: () => true }); if (response.status !== 200) return null; diff --git a/src/root/root.module.ts b/src/root/root.module.ts index 740caa4..098290a 100644 --- a/src/root/root.module.ts +++ b/src/root/root.module.ts @@ -20,7 +20,8 @@ import { CacheModule } from '@nestjs/cache-manager'; ConfigModule.forRoot(); @Module({ - providers: [{ provide: APP_GUARD, useClass: ThrottlerGuard }, + providers: [ + { provide: APP_GUARD, useClass: ThrottlerGuard }, UserService, PrismaService, BandageService, diff --git a/src/user/dto/queries.dto.ts b/src/user/dto/queries.dto.ts index caafef4..eaac853 100644 --- a/src/user/dto/queries.dto.ts +++ b/src/user/dto/queries.dto.ts @@ -2,12 +2,6 @@ import { Type } from 'class-transformer'; import { IsNotEmpty, IsNumber, IsOptional, Max, Min } from 'class-validator'; import { IsBooleanStr } from 'src/common/types.decorator'; -export class StateQueryDTO { - @IsBooleanStr() - @IsNotEmpty() - state?: string; -} - export class SetQueryDTO { @IsBooleanStr() @IsNotEmpty() @@ -29,12 +23,3 @@ export class PageTakeQueryDTO { page?: number; } - -export class ThemeQueryDTO { - @IsNumber() - @Type(() => Number) - @IsNotEmpty() - @Min(0) - @Max(2) - theme?: number; -} diff --git a/src/user/dto/updateUser.dto.ts b/src/user/dto/updateUser.dto.ts index 9b107ac..a72dd13 100644 --- a/src/user/dto/updateUser.dto.ts +++ b/src/user/dto/updateUser.dto.ts @@ -1,7 +1,27 @@ -import { IsBoolean, IsOptional } from 'class-validator'; +import { IsBoolean, IsNumber, IsOptional, Max, Min } from 'class-validator'; export class UpdateUsersDto { @IsOptional() @IsBoolean() banned?: boolean; +} + +export class UpdateSelfUserDto { + @IsNumber() + @IsOptional() + @Min(0) + @Max(2) + theme?: number; + + @IsBoolean() + @IsOptional() + skin_autoload?: boolean + + @IsBoolean() + @IsOptional() + nick_search?: boolean + + @IsBoolean() + @IsOptional() + public?: boolean } \ No newline at end of file diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts index fa821c9..c9af61c 100644 --- a/src/user/user.controller.ts +++ b/src/user/user.controller.ts @@ -12,7 +12,8 @@ import { UseGuards, ValidationPipe, UsePipes, - StreamableFile + StreamableFile, + Patch } from '@nestjs/common'; import type { Response } from 'express' import { AuthGuard } from 'src/guards/auth.guard'; @@ -24,9 +25,9 @@ import { RolesGuard } from 'src/guards/roles.guard'; import { AuthEnum, RolesEnum } from 'src/interfaces/types'; import { Auth } from 'src/decorators/auth.decorator'; import { Roles } from 'src/decorators/access.decorator'; -import { UpdateUsersDto } from './dto/updateUser.dto'; +import { UpdateSelfUserDto, UpdateUsersDto } from './dto/updateUser.dto'; import { RequestSession } from 'src/common/bandage_response'; -import { PageTakeQueryDTO, StateQueryDTO, ThemeQueryDTO } from './dto/queries.dto'; +import { PageTakeQueryDTO } from './dto/queries.dto'; @Controller() @UseGuards(AuthGuard, RolesGuard) @@ -98,51 +99,6 @@ export class UserController { res.send(data); } - @Put("/user/me/theme") - @Auth(AuthEnum.Strict) - @UsePipes(new ValidationPipe({ whitelist: true, transform: true })) - async profile_theme( - @Req() request: RequestSession, - @Res() res: Response, - @Body() body: ThemeQueryDTO - ): Promise { - /* update profile theme */ - - await this.userService.setProfileTheme(request.session, body.theme as number); - res.status(200).send({ - statusCode: 200, - new_theme: body.theme - }) - } - - @Put("/user/me/connections/minecraft/valid") - @Auth(AuthEnum.Strict) - @UsePipes(new ValidationPipe({ whitelist: true, transform: true })) - async set_valid( - @Req() request: RequestSession, - @Res() res: Response, - @Query() query: StateQueryDTO - ): Promise { - /* set displaying nickname in search */ - - const data = await this.minecraftService.changeValid(request.session, query.state === 'true'); - res.status(data.statusCode).send(data); - } - - @Put("/user/me/connections/minecraft/autoload") - @Auth(AuthEnum.Strict) - @UsePipes(new ValidationPipe({ whitelist: true, transform: true })) - async set_autoload( - @Req() request: RequestSession, - @Res() res: Response, - @Query() query: StateQueryDTO - ): Promise { - /* set skin autoload in editor */ - - const data = await this.userService.changeAutoload(request.session, query.state === 'true'); - res.status(data.statusCode).send(data); - } - @Post("/user/me/connections/minecraft/connect/:code") @Auth(AuthEnum.Strict) async connectMinecraft( @@ -243,20 +199,6 @@ export class UserController { res.status(data.statusCode).send(data); } - @Put("/user/me/settings/public") - @Auth(AuthEnum.Strict) - @UsePipes(new ValidationPipe({ whitelist: true, transform: true })) - async set_public( - @Req() request: RequestSession, - @Res() res: Response, - @Query() query: StateQueryDTO - ): Promise { - /* set skin autoload in editor */ - - const data = await this.userService.setPublic(request.session, query.state === 'true'); - res.status(data.statusCode).send(data); - } - @Get('/users') @Auth(AuthEnum.Strict) @Roles([RolesEnum.UpdateUsers]) @@ -268,7 +210,11 @@ export class UserController { @Auth(AuthEnum.Strict) @Roles([RolesEnum.UpdateUsers]) @UsePipes(new ValidationPipe({ whitelist: true, transform: true })) - async update_user(@Param('username') username: string, @Res() res: Response, @Body() body: UpdateUsersDto) { + async update_user( + @Param('username') username: string, + @Res() res: Response, + @Body() body: UpdateUsersDto + ) { const data = await this.userService.updateUser(username, body); res.status(data.statusCode).send(data); } @@ -293,4 +239,18 @@ export class UserController { res.setHeader('Content-Type', 'image/png'); return new StreamableFile(Buffer.from(cache, "base64")); } + + @Patch('/user/me') + @Auth(AuthEnum.Strict) + @UsePipes(new ValidationPipe({ whitelist: true, transform: true })) + async update_me( + @Req() request: RequestSession, + @Res() res: Response, + @Body() body: UpdateSelfUserDto + ) { + /* Update self data */ + + const data = await this.userService.updateSelfUser(request.session, body); + res.status(data.statusCode).send(data); + } } \ No newline at end of file diff --git a/src/user/user.service.ts b/src/user/user.service.ts index 28e89c5..24e2f72 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -2,10 +2,11 @@ import { Inject, Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import axios from 'axios'; import { hasAccess, Session } from 'src/auth/auth.service'; -import { UpdateUsersDto } from './dto/updateUser.dto'; +import { UpdateSelfUserDto, UpdateUsersDto } from './dto/updateUser.dto'; import { generateResponse } from 'src/common/bandage_response'; import { RolesEnum } from 'src/interfaces/types'; import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager'; +import { days } from '@nestjs/throttler'; const discord_url = process.env.DISCORD_URL + "/api/v10"; @@ -347,31 +348,6 @@ export class UserService { } } - async setProfileTheme(session: Session, theme: number) { - await this.prisma.userSettings.update({ where: { userId: session.user.id }, data: { profile_theme: theme } }); - } - - async changeAutoload(session: Session, state: boolean) { - /* switch skin autoload in editor */ - - const result = await this.prisma.userSettings.update({ - where: { userId: session.user.id }, data: { autoload: state } - }) - return { - statusCode: 200, - new_data: result.autoload - }; - } - - async setPublic(session: Session, state: boolean) { - /* change profile visibility */ - - const result = await this.prisma.userSettings.update({ - where: { userId: session.user.id }, data: { public_profile: state } - }) - return { statusCode: 200, new_data: result.public_profile }; - } - async getUsers() { const users = await this.prisma.user.findMany({ include: { UserSettings: true, AccessRoles: true } }); @@ -407,5 +383,45 @@ export class UserService { message_ru: 'Обновлён' } } + + async updateSelfUser(session: Session, body: UpdateSelfUserDto) { + /* Update self data */ + /* TODO: Nickname changing */ + + if ( + body.theme !== undefined || + body.skin_autoload !== undefined || + body.public !== undefined + ) { + await this.prisma.userSettings.update({ + where: { userId: session.user.id }, + data: { + profile_theme: body.theme, + autoload: body.skin_autoload, + public_profile: body.public + } + }); + } + + if (body.nick_search !== undefined) { + if (!session.user.profile) { + return { + statusCode: 400, + message: 'Minecraft profile didn\'t connected', + message_ru: 'К вашему профилю не подключена учетная запись Minecraft' + } + } + await this.prisma.minecraft.update({ + where: { id: session.user.profile.id }, + data: { valid: body.nick_search } + }); + } + + return { + statusCode: 200, + message: 'Patched', + message_ru: 'Обновлен' + } + } }