From aab5f2ee42097a3867e4bf4e894d4eb8087b0527 Mon Sep 17 00:00:00 2001 From: celian Date: Wed, 24 Aug 2022 23:03:54 +0200 Subject: [PATCH] Delete dropy & Unblock user --- src/controllers/dropy.controller.ts | 22 +++++++++++++++++ src/controllers/users.controller.ts | 30 +++++++++++++++++++++++ src/interfaces/chat.interface.ts | 11 +++------ src/interfaces/user.interface.ts | 2 ++ src/routes/dropy.route.ts | 3 +++ src/routes/users.route.ts | 2 ++ src/services/chat.service.ts | 31 ++++++++++++++++++++--- src/services/dropy.service.ts | 28 +++++++++++++++++++++ src/services/users.service.ts | 38 ++++++++++++++++++++++++++++- 9 files changed, 155 insertions(+), 12 deletions(-) diff --git a/src/controllers/dropy.controller.ts b/src/controllers/dropy.controller.ts index a43712f..86fb706 100644 --- a/src/controllers/dropy.controller.ts +++ b/src/controllers/dropy.controller.ts @@ -93,3 +93,25 @@ export async function getDropy(req: AuthenticatedRequest, res: Response, next: N next(error); } } + +export async function userEmittedDropies(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { + try { + const drops = await dropyService.userEmittedDropies(req.user); + res.status(200).json(drops); + } catch (error) { + next(error); + } +} + +export async function deleteDropy(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { + try { + const dropyId = Number(req.params.id); + utils.throwIfNotNumber(dropyId); + + await dropyService.deleteDropy(dropyId, req.user); + + res.status(200).json(`Dropy with id ${dropyId} deleted`); + } catch (error) { + next(error); + } +} diff --git a/src/controllers/users.controller.ts b/src/controllers/users.controller.ts index 4e20482..accb375 100644 --- a/src/controllers/users.controller.ts +++ b/src/controllers/users.controller.ts @@ -4,6 +4,7 @@ import * as userService from '@services/users.service'; import * as utils from '@/utils/controller.utils'; import { User } from '@prisma/client'; import { UploadedFile } from 'express-fileupload'; +import { HttpException } from '@/exceptions/HttpException'; export async function updateDeviceToken(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { @@ -113,6 +114,10 @@ export async function reportUser(req: AuthenticatedRequest, res: Response, next: utils.throwIfNotNumber(dropyId); } + if (parseInt(userId) === req.user.id) { + throw new HttpException(301, 'You cannot report yourself'); + } + await userService.reportUser(parseInt(userId), req.user, dropyId); res.status(200).json('User reported'); } catch (error) { @@ -125,9 +130,34 @@ export async function blockUser(req: AuthenticatedRequest, res: Response, next: const { userId } = req.params; utils.throwIfNotNumber(userId); + if (parseInt(userId) === req.user.id) { + throw new HttpException(301, 'You cannot report block'); + } + await userService.blockUser(parseInt(userId), req.user); res.status(200).json('User blocked'); } catch (error) { next(error); } } + +export async function getBlockedUsers(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { + try { + const blockedUsers = await userService.getBlockedUsers(req.user); + res.status(200).json(blockedUsers); + } catch (error) { + next(error); + } +} + +export async function unblockUser(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { + try { + const { userId } = req.params; + utils.throwIfNotNumber(userId); + + await userService.unblockUser(parseInt(userId), req.user); + res.status(200).json('User unblocked'); + } catch (error) { + next(error); + } +} diff --git a/src/interfaces/chat.interface.ts b/src/interfaces/chat.interface.ts index 22bc393..c130651 100644 --- a/src/interfaces/chat.interface.ts +++ b/src/interfaces/chat.interface.ts @@ -1,11 +1,9 @@ import { DropyAround } from './dropy.interface'; +import { SimplifiedUser } from './user.interface'; export interface UserConversation { id: number; - user: { - displayName: string; - userId: number; - }; + user: SimplifiedUser; lastMessagePreview: string | null; lastMessageDate: Date | null; isOnline: boolean; @@ -17,8 +15,5 @@ export interface UserMessage { date: Date; content: string | DropyAround; read: boolean; - sender: { - displayName: string; - id: number; - }; + sender: SimplifiedUser; } diff --git a/src/interfaces/user.interface.ts b/src/interfaces/user.interface.ts index 013f3fa..4b0f3b3 100644 --- a/src/interfaces/user.interface.ts +++ b/src/interfaces/user.interface.ts @@ -22,3 +22,5 @@ export type Profile = Pick< }; export type UpdatableProfileInfos = Pick; + +export type SimplifiedUser = Pick; diff --git a/src/routes/dropy.route.ts b/src/routes/dropy.route.ts index fccedf0..2be1980 100644 --- a/src/routes/dropy.route.ts +++ b/src/routes/dropy.route.ts @@ -8,6 +8,9 @@ const path = '/dropy'; export function getRouter() { const router = Router(); + router.get(`${path}/userEmitted`, authMiddleware as any, dropyController.userEmittedDropies, errorMiddleware); + router.delete(`${path}/:id`, authMiddleware as any, dropyController.deleteDropy, errorMiddleware); + router.post(`${path}/add/:id/media`, authMiddleware as any, dropyController.createDropyMedia, errorMiddleware); router.get(`${path}/:id/media`, authMiddleware as any, dropyController.getDropyMedia, errorMiddleware); router.get(`${path}/:id`, authMiddleware as any, dropyController.getDropy, errorMiddleware); diff --git a/src/routes/users.route.ts b/src/routes/users.route.ts index 6c41df6..8c746e3 100644 --- a/src/routes/users.route.ts +++ b/src/routes/users.route.ts @@ -20,6 +20,8 @@ export function getRouter() { router.post(`${path}/report/:userId`, authMiddleware as any, usersController.reportUser, errorMiddleware); router.post(`${path}/block/:userId`, authMiddleware as any, usersController.blockUser, errorMiddleware); + router.get(`${path}/blocked`, authMiddleware as any, usersController.getBlockedUsers, errorMiddleware); + router.post(`${path}/unblock/:userId`, authMiddleware as any, usersController.unblockUser, errorMiddleware); return router; } diff --git a/src/services/chat.service.ts b/src/services/chat.service.ts index 5273dfc..6513595 100644 --- a/src/services/chat.service.ts +++ b/src/services/chat.service.ts @@ -18,6 +18,7 @@ export async function getAllMessages(conversationId: number): Promise { } export async function addMessage(user: User, connectedUsers: User[], content: string, conversationId: number): Promise { + const userWithBlockedUsers = await client.user.findUnique({ + where: { id: user.id }, + include: { blockedUsers: true }, + }); + const message = await client.chatMessage.create({ data: { conversationId: conversationId, @@ -74,15 +92,20 @@ export async function addMessage(user: User, connectedUsers: User[], content: st return !connectedUsers.some(connectedUser => connectedUser.id === user.id); }); + const filteredDisconnectedUsers = disconnectedUsers.filter(userToFilter => { + return userWithBlockedUsers.blockedUsers.some(blockedUser => blockedUser.id === userToFilter.id); + }); + sendPushNotification({ - users: disconnectedUsers, + users: filteredDisconnectedUsers, title: user.displayName, body: decryptMessage(content), sound: 'message_sound.mp3', payload: { id: conversation.id, user: { - userId: user.id, + id: user.id, + username: user.username, displayName: user.displayName, }, } as UserConversation, @@ -96,6 +119,7 @@ export async function addMessage(user: User, connectedUsers: User[], content: st sender: { displayName: user.displayName, id: user.id, + username: user.username, }, }; } @@ -128,7 +152,8 @@ export async function getAllUserConversations(user: User): Promise { + const userDropies = await client.dropy.findMany({ + where: { emitterId: user.id }, + orderBy: { creationDate: 'desc' }, + }); + + return userDropies; +} + +export async function deleteDropy(dropyId: number, user: User): Promise { + const dropy = await client.dropy.findUnique({ where: { id: dropyId } }); + + if (dropy == undefined) { + throw new HttpException(404, `Dropy with id ${dropyId} not found`); + } + + if (user.id != dropy.emitterId) { + throw new HttpException(403, `You can't delete this dropy`); + } + + if (dropy.mediaType === MediaType.PICTURE || dropy.mediaType === MediaType.VIDEO) { + fs.unlinkSync(dropy.filePath); + } + + await client.dropy.delete({ where: { id: dropyId } }); +} diff --git a/src/services/users.service.ts b/src/services/users.service.ts index cfe945d..0466d9a 100644 --- a/src/services/users.service.ts +++ b/src/services/users.service.ts @@ -3,7 +3,7 @@ import fs from 'fs'; import { sendPushNotification } from '../notification'; import client from '@/prisma/client'; import { getAvailableDropiesAroundLocation, getDistanceFromLatLonInMeters } from '@/utils/geolocation.utils'; -import { Profile, UpdatableProfileInfos } from '@/interfaces/user.interface'; +import { Profile, SimplifiedUser, UpdatableProfileInfos } from '@/interfaces/user.interface'; import { HttpException } from '@/exceptions/HttpException'; import { UploadedFile } from 'express-fileupload'; @@ -240,3 +240,39 @@ export async function blockUser(blockedId: number, sender: User): Promise data: { closed: true }, }); } + +export async function getBlockedUsers(user: User): Promise { + const userWithBlockedUsers = await client.user.findUnique({ + where: { id: user.id }, + include: { blockedUsers: true }, + }); + + const blockedProfiles = await userWithBlockedUsers.blockedUsers.map(blockedUser => { + return { + id: blockedUser.id, + username: blockedUser.username, + displayName: blockedUser.displayName, + }; + }); + + return blockedProfiles; +} + +export async function unblockUser(unblockedId: number, sender: User): Promise { + const userToUnblock = await client.user.findUnique({ where: { id: unblockedId } }); + + if (userToUnblock == null) { + throw new HttpException(404, `User with id ${unblockedId} not found`); + } + + await client.user.update({ + where: { id: sender.id }, + data: { + blockedUsers: { + disconnect: { + id: unblockedId, + }, + }, + }, + }); +}