diff --git a/back/volume/src/chat/chat.controller.ts b/back/volume/src/chat/chat.controller.ts index cd925a0..e13aca0 100644 --- a/back/volume/src/chat/chat.controller.ts +++ b/back/volume/src/chat/chat.controller.ts @@ -1,99 +1,97 @@ import { + BadRequestException, Body, Controller, Delete, Get, NotFoundException, Param, + ParseIntPipe, Post, -} from "@nestjs/common"; -//import { channel, Channel } from "diagnostics_channel"; -import { Channel } from './entity/channel.entity'; -import { ChannelService } from "./chat.service"; -import { CreateChannelDto } from "./dto/create-channel.dto"; -import { UsersService } from "src/users/users.service"; -import { UpdateChannelDto } from "./dto/update-channel.dto"; -import { User } from "src/users/entity/user.entity"; + UseGuards +} from '@nestjs/common' +import { AuthenticatedGuard } from 'src/auth/42-auth.guard' +import { UsersService } from 'src/users/users.service' +import { ChannelService } from './chat.service' -@Controller("chat") -export class ChatController { - private readonly channelService: ChannelService; - private readonly usersService: UsersService; +import { CreateChannelDto } from './dto/create-channel.dto' +import { UpdateChannelDto } from './dto/update-channel.dto' - @Get("channels/:id") - getChannelsForUser(@Param("id") id: number): Promise> { - return this.channelService.getChannelsForUser(id); - } +import type User from 'src/users/entity/user.entity' +import type Channel from './entity/channel.entity' +import { Profile42 } from 'src/auth/42.decorator' +import { Profile } from 'passport-42' - @Post("channels") - async createChannel(@Body() channel: CreateChannelDto) { - return await this.channelService.createChannel(channel); - } +@Controller('channels') +export class ChatController { + constructor ( + private readonly channelService: ChannelService, + private readonly usersService: UsersService + ) {} - @Delete("channels/:id") - async deleteChannel(@Param("id") id: number) { - return await this.channelService.removeChannel(id); + @Post(':id/admin') + async addAdmin (@Param('id') id: number, @Body() userId: number) { + const channel = await this.channelService.getChannel(id) + const user: User | null = await this.usersService.findUser(userId) + if (user == null) throw new NotFoundException(`User #${userId} not found`) + channel.admins.push(user) + this.channelService.update(channel) } - @Post("channels/:id/owner") - async moveOwner(@Param("id") id: number, @Body() userId: number) { - const channel = await this.channelService.getChannel(id); - const user: User | null = await this.usersService.findUser(userId); - if (user == null) throw new NotFoundException(`User #${userId} not found`); - channel.owner = user; - this.channelService.update(channel); + @Delete(':id/admin') + async removeAdmin (@Param('id') id: number, @Body() userId: number) { + const channel = await this.channelService.getChannel(id) + channel.admins = channel.admins.filter((usr: User) => { + return usr.ftId !== userId + }) + this.channelService.update(channel) } - @Post("channels/:id/admin") - async addAdmin(@Param("id") id: number, @Body() userId: number) { - const channel = await this.channelService.getChannel(id); - const user: User | null = await this.usersService.findUser(userId); - if (user == null) throw new NotFoundException(`User #${userId} not found`); - channel.admins.push(user); - this.channelService.update(channel); + @Post(':id/ban') + async addBan (@Param('id') id: number, @Body() userId: number) { + const channel = await this.channelService.getChannel(id) + const user: User | null = await this.usersService.findUser(userId) + if (user == null) throw new NotFoundException(`User #${userId} not found`) + channel.banned.push(user) + this.channelService.update(channel) } - @Delete("channels/:id/admin") - async removeAdmin(@Param("id") id: number, @Body() userId: number) { - const channel = await this.channelService.getChannel(id); - channel.admins = channel.admins.filter((a) => { - return a.ftId !== userId; - }); - this.channelService.update(channel); + @Post(':id/mute') + async addMute (@Param('id') id: number, @Body() userId: number) { + const channel = await this.channelService.getChannel(id) + const user: User | null = await this.usersService.findUser(userId) + if (user == null) throw new NotFoundException(`User #${userId} not found`) + channel.muted.push(user) + this.channelService.update(channel) } - @Post("channels/:id/ban") - async addBan(@Param("id") id: number, @Body() userId: number) { - const channel = await this.channelService.getChannel(id); - const user: User | null = await this.usersService.findUser(userId); - if (user == null) throw new NotFoundException(`User #${userId} not found`); - channel.banned.push(user); - this.channelService.update(channel); + @Delete(':id/mute') + async removeMute (@Param('id') id: number, @Body() userId: number) { + const channel = await this.channelService.getChannel(id) + channel.muted = channel.muted.filter((usr: User) => { + return usr.ftId !== userId + }) + this.channelService.update(channel) } - @Delete("channels/:id/ban") - async removeBan(@Param("id") id: number, @Body() userId: number) { - const channel = await this.channelService.getChannel(id); - channel.banned = channel.banned.filter((a) => { - return a.ftId !== userId; - }); - this.channelService.update(channel); + @Delete(':id') + @UseGuards(AuthenticatedGuard) + async deleteChannel (@Profile42() profile: Profile, @Param('id') id: number) { + if (await this.channelService.isOwner(id, +profile.id)) { + await this.channelService.removeChannel(id) + return + } + throw new BadRequestException('You are not the owner of this channel') } - @Post("channels/:id/mute") - async addMute(@Param("id") id: number, @Body() userId: number) { - const channel = await this.channelService.getChannel(id); - const user: User | null = await this.usersService.findUser(userId); - if (user == null) throw new NotFoundException(`User #${userId} not found`); - channel.mute.push(user); - this.channelService.update(channel); + @Get() + @UseGuards(AuthenticatedGuard) + async getChannelsForUser (@Profile42() profile: Profile): Promise { + return await this.channelService.getChannelsForUser(profile.id) } - @Delete("channels/:id/mute") - async removeMute(@Param("id") id: number, @Body() userId: number) { - const channel = await this.channelService.getChannel(id); - channel.mute = channel.mute.filter((a) => { - return a.ftId !== userId; - }); - this.channelService.update(channel); + + @Post() + async createChannel (@Body() channel: CreateChannelDto) { + return await this.channelService.createChannel(channel) } } diff --git a/back/volume/src/chat/chat.module.ts b/back/volume/src/chat/chat.module.ts index 4f69607..8fcaa1f 100644 --- a/back/volume/src/chat/chat.module.ts +++ b/back/volume/src/chat/chat.module.ts @@ -3,11 +3,12 @@ import { TypeOrmModule } from '@nestjs/typeorm' import { AuthModule } from 'src/auth/auth.module' import { UsersModule } from 'src/users/users.module' -//import { ChatGateway } from './chat.gateway' +// import { ChatGateway } from './chat.gateway' import { ChatController } from './chat.controller' import { ChannelService } from './chat.service' -import { Channel } from './entity/channel.entity' -import { Message } from './entity/message.entity' + +import Channel from './entity/channel.entity' +import Message from './entity/message.entity' @Module({ imports: [ @@ -17,6 +18,6 @@ import { Message } from './entity/message.entity' TypeOrmModule.forFeature([Message]) ], controllers: [ChatController], - providers: [/*ChatGateway, */ChannelService] + providers: [ChannelService] }) export class ChatModule {} diff --git a/back/volume/src/chat/chat.service.ts b/back/volume/src/chat/chat.service.ts index ab5c270..0b50500 100644 --- a/back/volume/src/chat/chat.service.ts +++ b/back/volume/src/chat/chat.service.ts @@ -1,56 +1,118 @@ -import { Injectable, NotFoundException } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Channel } from './entity/channel.entity'; -import { User } from 'src/users/entity/user.entity'; -import { Repository } from 'typeorm'; -import { CreateChannelDto } from './dto/create-channel.dto'; -import { UsersService } from 'src/users/users.service'; +import { Injectable, NotFoundException } from '@nestjs/common' +import { InjectRepository } from '@nestjs/typeorm' +import { Repository } from 'typeorm' + +import { type CreateChannelDto } from './dto/create-channel.dto' +import { UsersService } from 'src/users/users.service' + +import type User from 'src/users/entity/user.entity' +import Channel from './entity/channel.entity' +import { classToPlain, plainToClass } from 'class-transformer' @Injectable() export class ChannelService { - constructor( + constructor ( @InjectRepository(Channel) private readonly ChannelRepository: Repository, - private readonly usersService: UsersService, + private readonly usersService: UsersService ) {} - async createChannel(channel: CreateChannelDto): Promise { - const newChannel = this.ChannelRepository.create({ - name: channel.name, - password: channel.password, - }); - let user: User| null = await this.usersService.findUser(channel.owner); - if (user == null) throw new NotFoundException(`User #${channel.owner} not found`) - newChannel.owner = user; - return await this.ChannelRepository.save(newChannel); + async createChannel (channel: CreateChannelDto): Promise { + const user: User | null = await this.usersService.findUser(channel.owner) + if (user == null) { + throw new NotFoundException(`User #${channel.owner} not found`) + } + const newChannel = new Channel() + newChannel.owner = user + newChannel.users = [user] + newChannel.admins = [user] + newChannel.name = channel.name + newChannel.isPrivate = channel.isPrivate + newChannel.password = channel.password + return await this.ChannelRepository.save(newChannel) + } + + async getChannelsForUser (ftId: number): Promise { + let rooms: Channel[] = [] + rooms = [ + ...(await this.ChannelRepository.createQueryBuilder('room') + .where('room.isPrivate = false') + .getMany()) + ] + + rooms = [ + ...rooms, + ...(await this.ChannelRepository.createQueryBuilder('room') + .innerJoin('room.users', 'users') + .where('room.isPrivate = true') + .andWhere('users.ftId = :ftId', { ftId }) + .getMany()) + ] + return rooms } - async getChannelsForUser(ftId: number): Promise> { - const query = await this.ChannelRepository.createQueryBuilder('room') - .innerJoin('room.users', 'users') - .where('users.ftId = :ftId', { ftId }) - .leftJoinAndSelect('room.users', 'all_users') - .orderBy('room.id', 'DESC') // TODO: order by last message - .getRawMany(); - return query; //where userId is in User[] of channel? + async addUserToChannel (channel: Channel, user: User): Promise { + channel.owner = user + return await this.ChannelRepository.save(channel) } - async addUserToChannel(channel: Channel, user: User): Promise { - channel.owner = user; - return await this.ChannelRepository.save(channel); + async getChannel (id: number): Promise { + const channel = await this.ChannelRepository.findOneBy({ id }) + if (channel == null) { throw new NotFoundException(`Channel #${id} not found`) } + return channel } - async getChannel(id: number): Promise { - const channel = await this.ChannelRepository.findOneBy({ id }); - if (!channel) throw new NotFoundException(`Channel #${id} not found`); - return channel; + async update (channel: Channel) { + this.ChannelRepository.update(channel.id, channel) } - async update(channel: Channel) { - this.ChannelRepository.update(channel.id, channel); + async removeChannel (channelId: number) { + await this.ChannelRepository.delete(channelId) } - async removeChannel(id: number) { - await this.ChannelRepository.delete(id); + + async isOwner (id: number, userId: number): Promise { + const channel = await this.ChannelRepository.findOne({ + where: { id }, + relations: { owner: true } + }) + if (channel == null) { throw new NotFoundException(`Channel #${id} not found`) } + console.log(channel.owner.ftId, userId) + return channel.owner.ftId == userId } -} + async isAdmin (id: number, userId: number): Promise { + const channel = await this.ChannelRepository.findOne({ + where: { id }, + relations: { admins: true } + }) + if (channel == null) { throw new NotFoundException(`Channel #${id} not found`) } + return channel.admins.findIndex((user) => user.ftId == userId) != -1 + } + + async isUser (id: number, userId: number): Promise { + const channel = await this.ChannelRepository.findOne({ + where: { id }, + relations: { users: true } + }) + if (channel == null) { throw new NotFoundException(`Channel #${id} not found`) } + return channel.users.findIndex((user) => user.ftId == userId) != -1 + } + + async isBanned (id: number, userId: number): Promise { + const channel = await this.ChannelRepository.findOne({ + where: { id }, + relations: { banned: true } + }) + if (channel == null) { throw new NotFoundException(`Channel #${id} not found`) } + return channel.banned.findIndex((user) => user.ftId == userId) != -1 + } + + async isMuted (id: number, userId: number): Promise { + const channel = await this.ChannelRepository.findOne({ + where: { id }, + relations: { muted: true } + }) + if (channel == null) { throw new NotFoundException(`Channel #${id} not found`) } + return channel.muted.findIndex((user) => user.ftId == userId) != -1 + } +} diff --git a/back/volume/src/chat/dto/connection.dto.ts b/back/volume/src/chat/dto/connection.dto.ts index 7f9e2b6..c70f38c 100644 --- a/back/volume/src/chat/dto/connection.dto.ts +++ b/back/volume/src/chat/dto/connection.dto.ts @@ -1,10 +1,13 @@ -import { IsNumber } from 'class-validator'; +import { IsNumber, IsOptional, IsString } from 'class-validator' export class ConnectionDto { @IsNumber() - UserId: number; - @IsNumber() - ChannelId: number; + UserId: number + @IsNumber() - SocketId: number; + ChannelId: number + + @IsString() + @IsOptional() + pwd: string } diff --git a/back/volume/src/chat/dto/create-channel.dto.ts b/back/volume/src/chat/dto/create-channel.dto.ts index ab7d4ec..af1f03a 100644 --- a/back/volume/src/chat/dto/create-channel.dto.ts +++ b/back/volume/src/chat/dto/create-channel.dto.ts @@ -1,13 +1,28 @@ -import { IsPositive, IsAlpha, IsString, IsOptional } from 'class-validator'; +import { Transform } from 'class-transformer' +import { + IsPositive, + IsAlpha, + IsString, + IsOptional, + IsNumber, + IsBoolean +} from 'class-validator' export class CreateChannelDto { + @IsOptional() + @IsPositive() + id: number + @IsString() - @IsAlpha() - name: string; + name: string - @IsPositive() - owner: number; + @IsNumber() + owner: number @IsOptional() - password: string; + password: string + + @IsBoolean() + @Transform(({ value }) => value === 'true') + isPrivate: boolean } diff --git a/back/volume/src/chat/dto/create-message.dto.ts b/back/volume/src/chat/dto/create-message.dto.ts index 6abbfb9..56419a0 100644 --- a/back/volume/src/chat/dto/create-message.dto.ts +++ b/back/volume/src/chat/dto/create-message.dto.ts @@ -1,12 +1,12 @@ -import { IsNumber, IsString } from 'class-validator'; +import { IsNumber, IsString } from 'class-validator' export class CreateMessageDto { @IsString() - text: string; + text: string @IsNumber() - UserId: number; + UserId: number @IsNumber() - ChannelId: number; + ChannelId: number } diff --git a/back/volume/src/chat/dto/update-channel.dto.ts b/back/volume/src/chat/dto/update-channel.dto.ts index bdf4c87..c9cb3a3 100644 --- a/back/volume/src/chat/dto/update-channel.dto.ts +++ b/back/volume/src/chat/dto/update-channel.dto.ts @@ -1,20 +1,30 @@ -import { PartialType } from '@nestjs/mapped-types'; -import { CreateChannelDto } from './create-channel.dto'; -import { IsOptional, IsString } from 'class-validator'; +import { PartialType } from '@nestjs/mapped-types' +import { CreateChannelDto } from './create-channel.dto' +import { IsNumber, IsOptional, IsString } from 'class-validator' export class UpdateChannelDto extends PartialType(CreateChannelDto) { - id: number; + id: number @IsOptional() - users: [number]; + @IsNumber() + users: [number] + @IsOptional() - messages: [number]; + @IsNumber() + messages: [number] + @IsOptional() - owners: [number]; //user id + @IsNumber() + owners: [number] // user id + @IsOptional() - banned: [number]; //user id + @IsNumber() + banned: [number] // user id + @IsOptional() - muted: [number]; //user id + @IsNumber() + muted: [number] // user id + @IsString() @IsOptional() - password: string; + password: string } diff --git a/back/volume/src/chat/entity/channel.entity.ts b/back/volume/src/chat/entity/channel.entity.ts index 624473e..f2b51c9 100644 --- a/back/volume/src/chat/entity/channel.entity.ts +++ b/back/volume/src/chat/entity/channel.entity.ts @@ -2,31 +2,39 @@ import { BeforeInsert, Column, Entity, + JoinColumn, JoinTable, ManyToMany, + ManyToOne, OneToMany, + OneToOne, PrimaryGeneratedColumn } from 'typeorm' +import User from 'src/users/entity/user.entity' +import Message from './message.entity' import * as bcrypt from 'bcrypt' -import { User } from 'src/users/entity/user.entity' -import { Message } from './message.entity' - @Entity() -export class Channel { +export default class Channel { @PrimaryGeneratedColumn() id: number @Column() name: string - @ManyToMany(() => User) - @JoinTable() - owner: User + @Column({ default: false }) + isPrivate: boolean - @ManyToMany(() => User) - @JoinTable() - admins: User[] + @Column({ select: false, default: '' }) + password: string + + @BeforeInsert() + async hashPassword () { + this.password = await bcrypt.hash( + this.password, + Number(process.env.HASH_SALT) + ) + } @ManyToMany(() => User) @JoinTable() @@ -35,22 +43,19 @@ export class Channel { @OneToMany(() => Message, (message: Message) => message.channel) messages: Message[] - @OneToMany(() => User, (user: User) => user.id) // refuse connection - banned: User[] + @ManyToOne(() => User) + @JoinColumn() + owner: User - @OneToMany(() => User, (user: User) => user.id) // refuse post - mute: User[] + @ManyToMany(() => User) + @JoinTable() + admins: User[] - @Column({ select: false }) - password: string + @ManyToMany(() => User) // refuse connection + @JoinTable() + banned: User[] - @BeforeInsert() - async hashPassword () { - this.password = await bcrypt.hash( - this.password, - Number(process.env.HASH_SALT) - ) - } + @ManyToMany(() => User) // refuse post + @JoinTable() + muted: User[] } - -export default Channel diff --git a/back/volume/src/chat/entity/connection.entity.ts b/back/volume/src/chat/entity/connection.entity.ts new file mode 100644 index 0000000..fc949f9 --- /dev/null +++ b/back/volume/src/chat/entity/connection.entity.ts @@ -0,0 +1,16 @@ +import { Column, Entity, OneToOne } from 'typeorm' + +import Channel from './channel.entity' +import User from 'src/users/entity/user.entity' + +@Entity() +export class connectedUser { + @OneToOne(() => User) + user: User + + @OneToOne(() => Channel, (channel) => channel.id) + channel: Channel + + @Column() + socket: string +} diff --git a/back/volume/src/chat/entity/dm.entity.ts b/back/volume/src/chat/entity/dm.entity.ts new file mode 100644 index 0000000..d1a344c --- /dev/null +++ b/back/volume/src/chat/entity/dm.entity.ts @@ -0,0 +1,15 @@ +import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm' +import Message from './message.entity' +import type User from 'src/users/entity/user.entity' + +@Entity() +export class Channel { + @PrimaryGeneratedColumn() + id: number + + @Column() + users: User[] + + @OneToMany(() => Message, (message) => message.channel) + messages: Message[] +} diff --git a/back/volume/src/chat/entity/message.entity.ts b/back/volume/src/chat/entity/message.entity.ts index 488dacd..e44b4a3 100644 --- a/back/volume/src/chat/entity/message.entity.ts +++ b/back/volume/src/chat/entity/message.entity.ts @@ -7,28 +7,25 @@ import { ManyToOne, PrimaryGeneratedColumn } from 'typeorm' - -import { User } from 'src/users/entity/user.entity' -import { Channel } from './channel.entity' +import User from 'src/users/entity/user.entity' +import Channel from './channel.entity' @Entity() -export class Message { +export default class Message { @PrimaryGeneratedColumn() id: number @Column() text: string - @ManyToOne(() => User, (author: User) => author.messages) + @ManyToOne(() => User) @JoinColumn() author: User - @ManyToOne(() => Channel, (channel: Channel) => channel.messages) + @ManyToOne(() => Channel, (channel) => channel.messages, { cascade: true }) @JoinTable() channel: Channel @CreateDateColumn() - createdAt: Date + created_at: Date } - -export default Message diff --git a/back/volume/src/pong/pong.controller.ts b/back/volume/src/pong/pong.controller.ts new file mode 100644 index 0000000..809880d --- /dev/null +++ b/back/volume/src/pong/pong.controller.ts @@ -0,0 +1,33 @@ +import { + Controller, + Get, + Param, + ParseIntPipe, + UseGuards +} from '@nestjs/common' +import { Paginate, type Paginated, PaginateQuery } from 'nestjs-paginate' +import { AuthenticatedGuard } from 'src/auth/42-auth.guard' +import type Result from './entity/result.entity' +import { PongService } from './pong.service' + +@Controller('results') +export class PongController { + constructor (private readonly pongService: PongService) {} + + @Get('global') + @UseGuards(AuthenticatedGuard) + async getGlobalHistory ( + @Paginate() query: PaginateQuery + ): Promise> { + return await this.pongService.getHistory(query, 0) + } + + @Get(':id') + @UseGuards(AuthenticatedGuard) + async getHistoryById ( + @Param('id', ParseIntPipe) id: number, + @Paginate() query: PaginateQuery + ): Promise> { + return await this.pongService.getHistory(query, id) + } +} diff --git a/back/volume/src/pong/pong.module.ts b/back/volume/src/pong/pong.module.ts index 821acbb..df862a7 100644 --- a/back/volume/src/pong/pong.module.ts +++ b/back/volume/src/pong/pong.module.ts @@ -4,10 +4,12 @@ import Result from './entity/result.entity' import { TypeOrmModule } from '@nestjs/typeorm' import { PongService } from './pong.service' import { UsersModule } from 'src/users/users.module' +import { PongController } from './pong.controller' @Module({ imports: [forwardRef(() => UsersModule), TypeOrmModule.forFeature([Result])], providers: [PongGateway, PongService], + controllers: [PongController], exports: [PongService] }) export class PongModule {} diff --git a/back/volume/src/users/entity/user.entity.ts b/back/volume/src/users/entity/user.entity.ts index 6a8e5ec..a52ce7f 100644 --- a/back/volume/src/users/entity/user.entity.ts +++ b/back/volume/src/users/entity/user.entity.ts @@ -65,12 +65,6 @@ export class User { @JoinTable() results: Result[] - @OneToMany(() => Message, (message: Message) => message.author) - messages: Message[] - - @ManyToMany(() => Channel, (channel: Channel) => channel.users) - rooms: Channel[] - @ManyToMany(() => User) @JoinTable() blocked: User[] diff --git a/back/volume/src/users/users.controller.ts b/back/volume/src/users/users.controller.ts index 73d9d64..6673313 100644 --- a/back/volume/src/users/users.controller.ts +++ b/back/volume/src/users/users.controller.ts @@ -13,7 +13,6 @@ import { BadRequestException, Redirect } from '@nestjs/common' -import { PaginateQuery, type Paginated, Paginate } from 'nestjs-paginate' import { FileInterceptor } from '@nestjs/platform-express' import { diskStorage } from 'multer' @@ -31,14 +30,10 @@ import { ApiBody, ApiConsumes } from '@nestjs/swagger' import { type Request, Response } from 'express' import { createReadStream } from 'fs' import { join } from 'path' -import type Result from 'src/pong/entity/result.entity' -@Controller() +@Controller('users') export class UsersController { - constructor ( - private readonly usersService: UsersService, - private readonly pongService: PongService - ) {} + constructor (private readonly usersService: UsersService) {} @Get('all') async getAllUsers (): Promise { @@ -68,29 +63,12 @@ export class UsersController { return await this.usersService.getLeaderboard() } - @Get('rank/:id') + @Get(':id/rank') @UseGuards(AuthenticatedGuard) async getRank (@Param('id', ParseIntPipe) id: number): Promise { return await this.usersService.getRank(id) } - @Get('globalHistory') - @UseGuards(AuthenticatedGuard) - async getGlobalHistory ( - @Paginate() query: PaginateQuery - ): Promise> { - return await this.pongService.getHistory(query, 0) - } - - @Get('history/:id') - @UseGuards(AuthenticatedGuard) - async getHistoryById ( - @Param('id', ParseIntPipe) id: number, - @Paginate() query: PaginateQuery - ): Promise> { - return await this.pongService.getHistory(query, id) - } - @Post('avatar') @UseGuards(AuthenticatedGuard) @Redirect('http://localhost') @@ -130,16 +108,17 @@ export class UsersController { return await this.getAvatarById(profile.id, response) } - @Get('user/:name') + @Get(':name/byname') async getUserByName (@Param('name') username: string): Promise { const user = await this.usersService.findUserByName(username) user.socketKey = '' return user } - @Get('invit/:id/:username') + @Get('invit/:username') + @UseGuards(AuthenticatedGuard) async invitUser ( - @Param('id', ParseIntPipe) id: number, + @Profile42() profile: Profile, @Param('username') username: string ): Promise { const target: User | null = await this.usersService.findUserByName( @@ -148,14 +127,14 @@ export class UsersController { if (target === null) { throw new BadRequestException(`User ${username} not found.`) } - if (id === target.ftId) { + if (profile.id === target.ftId) { throw new BadRequestException("You can't invite yourself.") } - const ret: string = await this.usersService.invit(id, target.ftId) + const ret: string = await this.usersService.invit(profile.id, target.ftId) if (ret !== 'OK') throw new BadRequestException(ret) } - @Get('avatar/:id') + @Get(':id/avatar') async getAvatarById ( @Param('id', ParseIntPipe) ftId: number, @Res({ passthrough: true }) response: Response diff --git a/back/volume/src/users/users.service.ts b/back/volume/src/users/users.service.ts index 137d90a..ae2d26e 100644 --- a/back/volume/src/users/users.service.ts +++ b/back/volume/src/users/users.service.ts @@ -1,12 +1,13 @@ import { BadRequestException, Catch, Injectable } from '@nestjs/common' import { InjectRepository } from '@nestjs/typeorm' import { EntityNotFoundError, QueryFailedError, Repository } from 'typeorm' -import { User } from './entity/user.entity' -import { type UserDto } from './dto/user.dto' -import { type Channel } from 'src/chat/entity/channel.entity' import { Cron } from '@nestjs/schedule' import { randomUUID } from 'crypto' +import { type UserDto } from './dto/user.dto' +import type Channel from 'src/chat/entity/channel.entity' +import User from './entity/user.entity' + @Injectable() @Catch(QueryFailedError, EntityNotFoundError) export class UsersService { @@ -167,7 +168,7 @@ export class UsersService { ) { user.friends.push(target) target.friends.push(user) - user.followers = user.followers.slice(id, 1) + user.followers.splice(id, 1) await this.usersRepository.save(user) } else target.followers.push(user) await this.usersRepository.save(target) diff --git a/front/volume/src/App.svelte b/front/volume/src/App.svelte index 47d5df2..083e860 100644 --- a/front/volume/src/App.svelte +++ b/front/volume/src/App.svelte @@ -148,7 +148,7 @@ {:else}
- +
{/if} {/if} diff --git a/front/volume/src/Auth.ts b/front/volume/src/Auth.ts index 0cd6919..137f52d 100644 --- a/front/volume/src/Auth.ts +++ b/front/volume/src/Auth.ts @@ -11,8 +11,8 @@ export const API_URL = `http://${import.meta.env.VITE_HOST}:${ import.meta.env.VITE_BACK_PORT }`; -export async function getUser() { - const res = await fetch(API_URL, { +export async function getUser(bypass: boolean = false) { + const res = await fetch(API_URL + "/users", { method: "get", mode: "cors", cache: "no-cache", diff --git a/front/volume/src/FakeLogin.svelte b/front/volume/src/FakeLogin.svelte index a05f2b7..2f76ef5 100644 --- a/front/volume/src/FakeLogin.svelte +++ b/front/volume/src/FakeLogin.svelte @@ -5,7 +5,7 @@ export let ftId; async function doPost() { - await fetch(API_URL + "/" + ftId, { + await fetch(API_URL + "/users/" + ftId, { method: "POST", credentials: "include", mode: "cors", diff --git a/front/volume/src/components/Channels.svelte b/front/volume/src/components/Channels.svelte index 058ff5f..51d7baa 100644 --- a/front/volume/src/components/Channels.svelte +++ b/front/volume/src/components/Channels.svelte @@ -1,34 +1,31 @@