diff --git a/backend/src/resolvers/UploadResolver.ts b/backend/src/resolvers/UploadResolver.ts index 2a801e2..8d0576b 100644 --- a/backend/src/resolvers/UploadResolver.ts +++ b/backend/src/resolvers/UploadResolver.ts @@ -1,177 +1,178 @@ -import {Upload} from "../entities/upload"; -import {Arg, Authorized, Ctx, Mutation, Query, Resolver} from "type-graphql"; -import {Visitor} from "../entities/visitor"; -import {User} from "../entities/user"; -import {File} from "../entities/file"; -import {createDownloadToken, generateDownloadLink,} from "../helpers/linkGenerator"; +import { Upload } from "../entities/upload"; +import { Arg, Authorized, Ctx, Mutation, Query, Resolver } from "type-graphql"; +import { Visitor } from "../entities/visitor"; +import { User } from "../entities/user"; +import { File } from "../entities/file"; +import { + createDownloadToken, + generateDownloadLink, +} from "../helpers/linkGenerator"; import jwt from "jsonwebtoken"; -import {Context} from "../index"; +import { Context } from "../index"; @Resolver(Upload) class UploadResolver { - @Query(() => [Upload]) - async getAllUpload() { - return await Upload.find(); - } - - @Query(() => [Upload]) - async getUploadsByUserId(@Ctx() context: Context) { - try { - //@ts-ignore - return await Upload.find({ - where: {user: {id: context.id}}, - relations: ["files"], - }); - } catch (err) { - throw new Error("Internal server error"); - } - } - - @Authorized() - @Mutation(() => String) - async changeUploadActivatedStatus(@Arg("uploadId") uploadId: number) { - const upload = await Upload.findOneByOrFail({id: uploadId}); - - if (!upload) { - throw new Error("Upload not found"); - } - - upload.is_activated = !upload.is_activated; - - try { - await upload.save(); - return `Upload ${ - upload.is_activated ? "activated" : "deactivated" - }`; - } catch (err) { - throw new Error("Internal server error"); - } - } - - @Mutation(() => String) - async createUpload( - @Arg("receiversEmails", () => [String]) receivers: string[], - @Arg("senderEmail", () => String) senderEmail: string, - @Arg("message", () => String) message: string, - @Arg("title", () => String) title: string, - @Arg("fileData", () => String) fileData: string - ): Promise { - try { - const user = await userOrVisitor(senderEmail); - - if (!user) { - throw new Error("User not found"); - } - - const uploadFiles: File[] = []; - const parsedFiles = JSON.parse(fileData); - - for (const file of parsedFiles) { - const newFile = await File.create({ - name: file.original_name, - size: file.size, - default_name: file.default_name, - type: file.mimetype, - path: file.path, - file_uid: file.uuid, - }).save(); - - uploadFiles.push(newFile); - } - - const newUpload = Upload.create({ - receivers, - message, - title, - files: uploadFiles, - }) - - if (user instanceof User) newUpload.user = user; - if (user instanceof Visitor) newUpload.visitor = user; - - await newUpload.save(); - - if (newUpload) { - const downloadToken = createDownloadToken( - { - uploadId: newUpload.id, - receivers, - senderEmail: user.email, - }, - "1h" - ); - - const downloadLink: string = - generateDownloadLink(downloadToken); - - return downloadLink; - } - - throw new Error("Failed to create upload"); - } catch (err) { - throw new Error("Internal server error"); - } - } - - @Mutation(() => [File]) - async getFilesFromUpload( - @Arg("token", () => String) token: string - ): Promise { - // Décoder le token pour récupérer upload id - // Initie fonction pour chercher les files en relation avec cet upload - // Envoyer les files - - try { - if (!process.env.JWT_SECRET_KEY) { - throw new Error( - "JWT_SECRET_KEY is not defined in environment variables" - ); - } - - const payload = jwt.verify( - token, - process.env.JWT_SECRET_KEY as string - ) as jwt.JwtPayload; - - const uploadId = payload.uploadId; - if (!uploadId) { - throw new Error("Invalid token: uploadId not found"); - } - console.log(uploadId); - - const upload = await Upload.findOne({ - where: {id: uploadId}, - relations: ["files"], - }); - - if (!upload || !upload.files) { - throw new Error("No files found for this upload"); - } - console.log(uploadId); - - return upload.files; - } catch (err: unknown) { - console.error("Error retrieving files from upload:", err); - - if (err instanceof Error) { - throw new Error("Invalid or expired token: " + err.message); - } - - throw new Error("An unknown error occurred"); - } - } + @Query(() => [Upload]) + async getAllUpload() { + return await Upload.find(); + } + + @Query(() => [Upload]) + async getUploadsByUserId(@Ctx() context: Context) { + try { + //@ts-ignore + return await Upload.find({ + where: { user: { id: context.id } }, + relations: ["files"], + }); + } catch (err) { + throw new Error("Internal server error"); + } + } + + @Authorized() + @Mutation(() => String) + async changeUploadActivatedStatus(@Arg("uploadId") uploadId: number) { + const upload = await Upload.findOneByOrFail({ id: uploadId }); + + if (!upload) { + throw new Error("Upload not found"); + } + + upload.is_activated = !upload.is_activated; + + try { + await upload.save(); + return `Upload ${upload.is_activated ? "activated" : "deactivated"}`; + } catch (err) { + throw new Error("Internal server error"); + } + } + + @Mutation(() => String) + async createUpload( + @Arg("receiversEmails", () => [String]) receivers: string[], + @Arg("senderEmail", () => String) senderEmail: string, + @Arg("message", () => String) message: string, + @Arg("title", () => String) title: string, + @Arg("fileData", () => String) fileData: string + ): Promise { + try { + const user = await userOrVisitor(senderEmail); + + if (!user) { + throw new Error("User not found"); + } + + const uploadFiles: File[] = []; + const parsedFiles = JSON.parse(fileData); + + for (const file of parsedFiles) { + const newFile = await File.create({ + name: file.original_name, + size: file.size, + default_name: file.default_name, + type: file.mimetype, + path: file.path, + file_uid: file.uuid, + }).save(); + + uploadFiles.push(newFile); + } + + const newUpload = Upload.create({ + receivers, + message, + title, + files: uploadFiles, + }); + + if (user instanceof User) newUpload.user = user; + if (user instanceof Visitor) newUpload.visitor = user; + + await newUpload.save(); + + if (newUpload) { + const downloadToken = createDownloadToken( + { + uploadId: newUpload.id, + receivers, + senderEmail: user.email, + }, + "1h" + ); + + const downloadLink: string = generateDownloadLink(downloadToken); + + return downloadLink; + } + + throw new Error("Failed to create upload"); + } catch (err) { + throw new Error("Internal server error"); + } + } + + @Mutation(() => [File]) + async getFilesFromUpload( + @Arg("token", () => String) token: string + ): Promise { + // Décoder le token pour récupérer upload id + // Initie fonction pour chercher les files en relation avec cet upload + // Envoyer les files + + try { + if (!process.env.JWT_SECRET_KEY) { + throw new Error( + "JWT_SECRET_KEY is not defined in environment variables" + ); + } + + const payload = jwt.verify( + token, + process.env.JWT_SECRET_KEY as string + ) as jwt.JwtPayload; + + const uploadId = payload.uploadId; + if (!uploadId) { + throw new Error("Invalid token: uploadId not found"); + } + console.log(uploadId); + + const upload = await Upload.findOne({ + where: { id: uploadId }, + relations: ["files"], + }); + + if (!upload || !upload.files) { + throw new Error("No files found for this upload"); + } + console.log(uploadId); + + return upload.files; + } catch (err: unknown) { + console.error("Error retrieving files from upload:", err); + + if (err instanceof Error) { + throw new Error("Invalid or expired token: " + err.message); + } + + throw new Error("An unknown error occurred"); + } + } } const userOrVisitor = async (email: string): Promise => { - let user: User | null = await User.findOneBy({email}); - if (user) return user; + const user: User | null = await User.findOneBy({ email }); + if (user) return user; - let visitor: Visitor | null = await Visitor.findOneBy({email}); - if (!visitor) { - visitor = await Visitor.create({email}).save(); - } + let visitor: Visitor | null = await Visitor.findOneBy({ email }); - return visitor; + if (!visitor) { + visitor = await Visitor.create({ email }).save(); + } + + return visitor; }; export default UploadResolver; diff --git a/frontend/src/components/user/dashboard/UploadFile.tsx b/frontend/src/components/user/dashboard/UploadFile.tsx index 257162b..c84f7d0 100644 --- a/frontend/src/components/user/dashboard/UploadFile.tsx +++ b/frontend/src/components/user/dashboard/UploadFile.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useContext } from "react"; import styled from "@emotion/styled"; import { PlusOutlined } from "@ant-design/icons"; import { Button, Upload, message } from "antd"; @@ -10,23 +10,17 @@ import { GET_CONNECTED_USER } from "../../../graphql/queries"; const { Dragger } = Upload; const UploadFile: React.FC = () => { - const [email, setEmail] = useState(""); + const [receiverEmail, setReceiverEmail] = useState(""); const [emails, setEmails] = useState([]); const [fileList, setFileList] = useState([]); const [isLoading, setIsLoading] = useState(false); const { data, loading, error } = useQuery(GET_CONNECTED_USER); - useEffect(() => { - if (data && data.getConnectedUser) { - setEmails([data.getConnectedUser.email]); - } - }, [data]); - const handleAddEmail = () => { - if (email && !emails.includes(email)) { - setEmails([...emails, email]); - setEmail(""); + if (receiverEmail && !emails.includes(receiverEmail)) { + setEmails([...emails, receiverEmail]); + setReceiverEmail(""); } }; @@ -80,8 +74,8 @@ const UploadFile: React.FC = () => { } }); - formData.append("senderEmail", emails[0]); formData.append("receiversEmails", emails.join(",")); + formData.append("senderEmail", data.getConnectedUser.email); try { const response = await axios.post( @@ -138,8 +132,8 @@ const UploadFile: React.FC = () => { setEmail(e.target.value)} + value={receiverEmail} + onChange={(e) => setReceiverEmail(e.target.value)} onKeyPress={handleKeyPress} placeholder="Enter email" /> @@ -149,19 +143,19 @@ const UploadFile: React.FC = () => { ))} - - - + Transfer Files diff --git a/frontend/src/context/UserContext.tsx b/frontend/src/context/UserContext.tsx index b270be1..f043907 100644 --- a/frontend/src/context/UserContext.tsx +++ b/frontend/src/context/UserContext.tsx @@ -1,33 +1,42 @@ -import React, {createContext, FC, ReactNode, useContext, useState} from 'react'; +import React, { + createContext, + FC, + ReactNode, + useContext, + useState, +} from "react"; interface UserContextType { - isLoggedIn: boolean; - email: string; - role: string; - firstname: string; - lastname: string; - setUser: (userData: Partial) => void; + isLoggedIn: boolean; + email: string; + role: string; + firstname: string; + lastname: string; + setUser: (userData: Partial) => void; } const UserContext = createContext(undefined); -export const UserProvider: FC<{ children: ReactNode }> = ({children}) => { - const [user, setUser] = useState({ - isLoggedIn: false, - email: '', - role: '', - firstname: '', - lastname: '', - setUser: (userData) => setUser((prev) => ({...prev, ...userData})), - }); +export const UserProvider: FC<{ children: ReactNode }> = ({ children }) => { + const [user, setUser] = useState({ + isLoggedIn: false, + email: "", + role: "", + firstname: "", + lastname: "", + setUser: (userData) => setUser((prev) => ({ ...prev, ...userData })), + }); - return {children}; + return {children}; }; export const useUserContext = () => { - const context = useContext(UserContext); - if (!context) { - throw new Error("useUserContext must be used within a UserProvider"); - } - return context; + const context = useContext(UserContext); + + console.log(context); + + if (!context) { + throw new Error("useUserContext must be used within a UserProvider"); + } + return context; };