diff --git a/.gitignore b/.gitignore
index 1ae1622..5c9b7bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,6 +41,7 @@ build/Release
# Dependency directories
node_modules/
jspm_packages/
+mongo-backup/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
diff --git a/client/.env.development b/client/.env.development
index e37f392..d1374e8 100644
--- a/client/.env.development
+++ b/client/.env.development
@@ -1,2 +1,3 @@
VITE_BACKEND_URL=http://localhost:4400
VITE_BACKEND_SOCKET_URL=http://localhost:4400
+VITE_IMG_URL=http://localhost:4400
diff --git a/client/.env.example b/client/.env.example
index 944dcbb..787c0f6 100644
--- a/client/.env.example
+++ b/client/.env.example
@@ -1,2 +1,3 @@
VITE_BACKEND_URL=http://localhost:4400
-VITE_AZURE_BACKEND_URL=http://localhost:4400
\ No newline at end of file
+VITE_AZURE_BACKEND_URL=http://localhost:4400
+VITE_IMG_URL=http://localhost:4400
\ No newline at end of file
diff --git a/client/package-lock.json b/client/package-lock.json
index e2c6890..59608af 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -43,6 +43,7 @@
"@babel/preset-typescript": "^7.23.3",
"@eslint/js": "^9.21.0",
"@testing-library/dom": "^10.4.0",
+ "@testing-library/user-event": "^14.6.1",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
"@types/jest": "^29.5.13",
@@ -4436,6 +4437,20 @@
}
}
},
+ "node_modules/@testing-library/user-event": {
+ "version": "14.6.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
+ "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ },
+ "peerDependencies": {
+ "@testing-library/dom": ">=7.21.4"
+ }
+ },
"node_modules/@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
diff --git a/client/package.json b/client/package.json
index b6d62e4..78f60be 100644
--- a/client/package.json
+++ b/client/package.json
@@ -47,6 +47,7 @@
"@babel/preset-typescript": "^7.23.3",
"@eslint/js": "^9.21.0",
"@testing-library/dom": "^10.4.0",
+ "@testing-library/user-event": "^14.6.1",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
"@types/jest": "^29.5.13",
diff --git a/client/src/Types/ImageType.tsx b/client/src/Types/ImageType.tsx
new file mode 100644
index 0000000..d0a1541
--- /dev/null
+++ b/client/src/Types/ImageType.tsx
@@ -0,0 +1,17 @@
+export interface ImageType {
+ id: string;
+ file_content: string;
+ file_name: string;
+ mime_type: string;
+}
+
+export interface ImagesResponse {
+ images: ImageType[];
+ total: number;
+}
+
+export interface ImagesParams {
+ page: number;
+ limit: number;
+ uid?: string;
+}
\ No newline at end of file
diff --git a/client/src/Types/Images.tsx b/client/src/Types/Images.tsx
new file mode 100644
index 0000000..8cfe170
--- /dev/null
+++ b/client/src/Types/Images.tsx
@@ -0,0 +1,17 @@
+export interface Images {
+ id: string;
+ file_content: string;
+ file_name: string;
+ mime_type: string;
+}
+
+export interface ImagesResponse {
+ images: Images[];
+ total: number;
+}
+
+export interface ImagesParams {
+ page: number;
+ limit: number;
+ uid?: string;
+}
\ No newline at end of file
diff --git a/client/src/__tests__/components/ImageGallery/ImageGallery.test.tsx b/client/src/__tests__/components/ImageGallery/ImageGallery.test.tsx
new file mode 100644
index 0000000..d2b3fd0
--- /dev/null
+++ b/client/src/__tests__/components/ImageGallery/ImageGallery.test.tsx
@@ -0,0 +1,147 @@
+import React, { act } from "react";
+import "@testing-library/jest-dom";
+import { render, screen, fireEvent, waitFor } from "@testing-library/react";
+import ImageGallery from "../../../components/ImageGallery/ImageGallery";
+import ApiService from "../../../services/ApiService";
+import { Images } from "../../../Types/Images";
+import userEvent from "@testing-library/user-event";
+
+jest.mock("../../../services/ApiService");
+
+const mockImages: Images[] = [
+ { id: "1", file_name: "image1.jpg", mime_type: "image/jpeg", file_content: "mockBase64Content1" },
+ { id: "2", file_name: "image2.jpg", mime_type: "image/jpeg", file_content: "mockBase64Content2" },
+ { id: "3", file_name: "image3.jpg", mime_type: "image/jpeg", file_content: "mockBase64Content3" },
+];
+
+beforeAll(() => {
+ global.URL.createObjectURL = jest.fn(() => 'mockedObjectUrl');
+ Object.assign(navigator, {
+ clipboard: {
+ writeText: jest.fn(),
+ },
+ });
+});
+
+describe("ImageGallery", () => {
+ let mockHandleDelete: jest.Mock;
+
+ beforeEach(async () => {
+ (ApiService.getUserImages as jest.Mock).mockResolvedValue({ images: mockImages, total: 3 });
+ (ApiService.deleteImage as jest.Mock).mockResolvedValue(true);
+ (ApiService.uploadImage as jest.Mock).mockResolvedValue('mockImageUrl');
+ await act(async () => {
+ render(
{
const url: string = this.constructRequestUrl(`/auth/getRoomsRequireAuth`);
@@ -1167,7 +1184,99 @@ public async login(email: string, password: string): Promise {
return `ERROR : Une erreur inattendue s'est produite.`
}
}
- // NOTE : Get Image pas necessaire
+
+ public async getImages(page: number, limit: number): Promise {
+ try {
+ const url: string = this.constructRequestUrl(`/image/getImages`);
+ const headers = this.constructRequestHeaders();
+ let params : ImagesParams = { page: page, limit: limit };
+
+ const result: AxiosResponse = await axios.get(url, { params: params, headers: headers });
+
+ if (result.status !== 200) {
+ throw new Error(`L'affichage des images a échoué. Status: ${result.status}`);
+ }
+ const images = result.data;
+
+ return images;
+
+ } catch (error) {
+ console.log("Error details: ", error);
+
+ if (axios.isAxiosError(error)) {
+ const err = error as AxiosError;
+ const data = err.response?.data as { error: string } | undefined;
+ const msg = data?.error || 'Erreur serveur inconnue lors de la requête.';
+ throw new Error(`L'enregistrement a échoué. Status: ${msg}`);
+ }
+
+ throw new Error(`ERROR : Une erreur inattendue s'est produite.`);
+ }
+ }
+
+ public async getUserImages(page: number, limit: number): Promise {
+ try {
+ const url: string = this.constructRequestUrl(`/image/getUserImages`);
+ const headers = this.constructRequestHeaders();
+ let params : ImagesParams = { page: page, limit: limit };
+
+ const uid = this.getUserID();
+ if(uid !== ''){
+ params.uid = uid;
+ }
+
+ const result: AxiosResponse = await axios.get(url, { params: params, headers: headers });
+
+ if (result.status !== 200) {
+ throw new Error(`L'affichage des images de l'utilisateur a échoué. Status: ${result.status}`);
+ }
+ const images = result.data;
+
+ return images;
+
+ } catch (error) {
+ console.log("Error details: ", error);
+
+ if (axios.isAxiosError(error)) {
+ const err = error as AxiosError;
+ const data = err.response?.data as { error: string } | undefined;
+ const msg = data?.error || 'Erreur serveur inconnue lors de la requête.';
+ throw new Error(`L'enregistrement a échoué. Status: ${msg}`);
+ }
+
+ throw new Error(`ERROR : Une erreur inattendue s'est produite.`);
+ }
+ }
+
+ public async deleteImage(imgId: string): Promise {
+ try {
+ const url: string = this.constructRequestUrl(`/image/delete`);
+ const headers = this.constructRequestHeaders();
+ const uid = this.getUserID();
+ let params = { uid: uid, imgId: imgId };
+
+ const result: AxiosResponse = await axios.delete(url, { params: params, headers: headers });
+
+ if (result.status !== 200) {
+ throw new Error(`La suppression de l'image a échoué. Status: ${result.status}`);
+ }
+
+ const deleted = result.data.deleted;
+ return deleted;
+
+ } catch (error) {
+ console.log("Error details: ", error);
+
+ if (axios.isAxiosError(error)) {
+ const err = error as AxiosError;
+ const data = err.response?.data as { error: string } | undefined;
+ const msg = data?.error || 'Erreur serveur inconnue lors de la requête.';
+ throw new Error(`L'enregistrement a échoué. Status: ${msg}`);
+ }
+
+ throw new Error(`ERROR : Une erreur inattendue s'est produite.`);
+ }
+ }
}
diff --git a/docker-compose-local.yaml b/docker-compose-local.yaml
index 0d8d61a..b77c340 100644
--- a/docker-compose-local.yaml
+++ b/docker-compose-local.yaml
@@ -7,6 +7,8 @@ services:
context: ./client
dockerfile: Dockerfile
container_name: frontend
+ environment:
+ VITE_IMG_URL: http://localhost
ports:
- "5173:5173"
restart: always
@@ -54,7 +56,7 @@ services:
image: mongo
container_name: mongo
ports:
- - "27017:27017"
+ - "27019:27017"
tty: true
volumes:
- mongodb_data:/data/db
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 539c800..d133982 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -10,6 +10,7 @@ services:
- VITE_BACKEND_URL=
# Define empty VITE_BACKEND_SOCKET_URL so it will default to window.location.host
- VITE_BACKEND_SOCKET_URL=
+ - VITE_IMG_URL=https://evalsa.etsmtl.ca
ports:
- "5173:5173"
restart: always
diff --git a/server/__tests__/image.test.js b/server/__tests__/image.test.js
index 488d27b..7ce4ad1 100644
--- a/server/__tests__/image.test.js
+++ b/server/__tests__/image.test.js
@@ -7,6 +7,9 @@
// const BASE_URL = '/image'
+const Images = require('../models/images');
+const ObjectId = require('mongodb').ObjectId;
+
describe.skip("POST /upload", () => {
describe("when the jwt is not sent", () => {
@@ -64,3 +67,289 @@ describe.skip("GET /get", () => {
})
})
+
+jest.mock('mongodb', () => {
+ const originalModule = jest.requireActual('mongodb');
+ return {
+ ...originalModule,
+ ObjectId: {
+ ...originalModule.ObjectId,
+ createFromHexString: jest.fn().mockReturnValue('507f191e810c19729de860ea'), // Return a valid 24-character ObjectId string
+ },
+ };
+});
+
+describe('Images', () => {
+ let db;
+ let images;
+ let dbConn;
+ let mockImagesCollection;
+ let mockFindCursor;
+
+ beforeEach(() => {
+
+ const mockImagesCursor = {
+ sort: jest.fn().mockReturnThis(),
+ skip: jest.fn().mockReturnThis(),
+ limit: jest.fn().mockReturnThis(),
+ toArray: jest.fn()
+ };
+
+ const mockFilesCursor = {
+ sort: jest.fn().mockReturnThis(),
+ skip: jest.fn().mockReturnThis(),
+ limit: jest.fn().mockReturnThis(),
+ toArray: jest.fn()
+ };
+
+ mockImagesCollection = {
+ insertOne: jest.fn().mockResolvedValue({ insertedId: 'image123' }),
+ findOne: jest.fn(),
+ find: jest.fn().mockReturnValue(mockImagesCursor),
+ countDocuments: jest.fn(),
+ deleteOne: jest.fn()
+ };
+
+ mockFilesCollection = {
+ find: jest.fn().mockReturnValue(mockFilesCursor)
+ };
+
+ dbConn = {
+ collection: jest.fn((name) => {
+ if (name === 'images') {
+ return mockImagesCollection;
+ } else if (name === 'files') {
+ return mockFilesCollection;
+ }
+ })
+ };
+
+ db = {
+ connect: jest.fn().mockResolvedValue(),
+ getConnection: jest.fn().mockReturnValue(dbConn)
+ };
+
+ images = new Images(db);
+ });
+
+ describe('upload', () => {
+ it('should upload an image and return the inserted ID', async () => {
+ const testFile = { originalname: 'test.png', buffer: Buffer.from('dummydata'), mimetype: 'image/png' };
+ const userId = 'user123';
+
+ const result = await images.upload(testFile, userId);
+
+ expect(db.connect).toHaveBeenCalled();
+ expect(db.getConnection).toHaveBeenCalled();
+ expect(dbConn.collection).toHaveBeenCalledWith('images');
+ expect(mockImagesCollection.insertOne).toHaveBeenCalledWith({
+ userId: userId,
+ file_name: 'test.png',
+ file_content: testFile.buffer.toString('base64'),
+ mime_type: 'image/png',
+ created_at: expect.any(Date)
+ });
+ expect(result).toBe('image123');
+ });
+ });
+
+ describe('get', () => {
+ it('should retrieve the image if found', async () => {
+ const imageId = '65d9a8f9b5e8d1a5e6a8c9f0';
+ const testImage = {
+ file_name: 'test.png',
+ file_content: Buffer.from('dummydata').toString('base64'),
+ mime_type: 'image/png'
+ };
+ mockImagesCollection.findOne.mockResolvedValue(testImage);
+
+ const result = await images.get(imageId);
+
+ expect(db.connect).toHaveBeenCalled();
+ expect(db.getConnection).toHaveBeenCalled();
+ expect(dbConn.collection).toHaveBeenCalledWith('images');
+ expect(mockImagesCollection.findOne).toHaveBeenCalledWith({ _id: ObjectId.createFromHexString(imageId) });
+ expect(result).toEqual({
+ file_name: 'test.png',
+ file_content: Buffer.from('dummydata'),
+ mime_type: 'image/png'
+ });
+ });
+
+ it('should return null if image is not found', async () => {
+ const imageId = '65d9a8f9b5e8d1a5e6a8c9f0';
+ mockImagesCollection.findOne.mockResolvedValue(null);
+
+ const result = await images.get(imageId);
+
+ expect(result).toBeNull();
+ });
+ });
+
+ describe('getImages', () => {
+ it('should retrieve a paginated list of images', async () => {
+ const mockImages = [
+ { _id: '1', userId: 'user1', file_name: 'image1.png', file_content: Buffer.from('data1'), mime_type: 'image/png' },
+ { _id: '2', userId: 'user2', file_name: 'image2.png', file_content: Buffer.from('data2'), mime_type: 'image/png' }
+ ];
+
+ mockImagesCollection.countDocuments.mockResolvedValue(2);
+ // Create a mock cursor for images collection
+ const mockFindCursor = {
+ sort: jest.fn().mockReturnThis(),
+ skip: jest.fn().mockReturnThis(),
+ limit: jest.fn().mockReturnThis(),
+ toArray: jest.fn().mockResolvedValue(mockImages), // Return mock images when toArray is called
+ };
+
+ // Mock the find method to return the mock cursor
+ mockImagesCollection.find.mockReturnValue(mockFindCursor);
+ const result = await images.getImages(1, 10);
+
+ expect(db.connect).toHaveBeenCalled();
+ expect(db.getConnection).toHaveBeenCalled();
+ expect(dbConn.collection).toHaveBeenCalledWith('images');
+ expect(mockImagesCollection.find).toHaveBeenCalledWith({});
+ expect(mockFindCursor.sort).toHaveBeenCalledWith({ created_at: 1 });
+ expect(mockFindCursor.skip).toHaveBeenCalledWith(0);
+ expect(mockFindCursor.limit).toHaveBeenCalledWith(10);
+ expect(result).toEqual({
+ images: [
+ { id: '1', user: 'user1', file_name: 'image1.png', file_content: 'ZGF0YTE=', mime_type: 'image/png' },
+ { id: '2', user: 'user2', file_name: 'image2.png', file_content: 'ZGF0YTI=', mime_type: 'image/png' }
+ ],
+ total: 2,
+ });
+ });
+
+ it('should return an empty array if no images are found', async () => {
+ mockImagesCollection.countDocuments.mockResolvedValue(0);
+
+ const result = await images.getImages(1, 10);
+
+ expect(result).toEqual({ images: [], total: 0 });
+ });
+ });
+
+ describe('getUserImages', () => {
+ it('should return empty images array when no images exist', async () => {
+ mockImagesCollection.countDocuments.mockResolvedValue(0);
+
+ const result = await images.getUserImages(1, 10, 'user123');
+
+ expect(result).toEqual({ images: [], total: 0 });
+ expect(db.connect).toHaveBeenCalled();
+ expect(mockImagesCollection.countDocuments).toHaveBeenCalledWith({ userId: 'user123' });
+ });
+
+ it('should return images when they exist', async () => {
+ const mockImages = [
+ {
+ _id: 'img1',
+ userId: 'user123',
+ file_name: 'image1.png',
+ file_content: Buffer.from('testdata'),
+ mime_type: 'image/png'
+ }
+ ];
+
+ mockImagesCollection.countDocuments.mockResolvedValue(1);
+ mockImagesCollection.find.mockReturnValue({
+ sort: jest.fn().mockReturnThis(),
+ skip: jest.fn().mockReturnThis(),
+ limit: jest.fn().mockReturnThis(),
+ toArray: jest.fn().mockResolvedValue(mockImages)
+ });
+
+ const result = await images.getUserImages(1, 10, 'user123');
+
+ expect(result).toEqual({
+ images: [
+ {
+ id: 'img1',
+ user: 'user123',
+ file_name: 'image1.png',
+ file_content: Buffer.from('testdata').toString('base64'),
+ mime_type: 'image/png'
+ }
+ ],
+ total: 1
+ });
+ expect(db.connect).toHaveBeenCalled();
+ expect(mockImagesCollection.countDocuments).toHaveBeenCalledWith({ userId: 'user123' });
+ });
+ });
+ describe('delete', () => {
+ it('should not delete the image when it exists in the files collection', async () => {
+ const uid = 'user123';
+ const imgId = '507f191e810c19729de860ea'; // A valid 24-character ObjectId string
+
+ // Mock the files collection cursor to simulate an image found
+ const mockFilesCursor = {
+ toArray: jest.fn().mockResolvedValue([{ _id: imgId }]) // Image found
+ };
+
+ mockFilesCollection.find.mockReturnValue(mockFilesCursor);
+ mockImagesCollection.deleteOne.mockResolvedValue({ deletedCount: 0 });
+
+ const result = await images.delete(uid, imgId);
+
+ // Ensure the files collection is queried
+ expect(dbConn.collection).toHaveBeenCalledWith('files');
+ expect(mockFilesCollection.find).toHaveBeenCalledWith({
+ userId: uid,
+ content: { $regex: new RegExp(`/api/image/get/${imgId}`) },
+ });
+
+ // Ensure the images collection is queried for deletion
+ expect(dbConn.collection).toHaveBeenCalledWith('files');
+ expect(mockImagesCollection.deleteOne).not.toHaveBeenCalledWith({
+ _id: ObjectId.createFromHexString(imgId), // Ensure the ObjectId is created correctly
+ });
+
+ expect(result).toEqual({ deleted: false });
+ });
+
+ it('should delete the image if not found in the files collection', async () => {
+ const uid = 'user123';
+ const imgId = '507f191e810c19729de860ea';
+
+ // Mock the files collection cursor to simulate the image not being found
+ const mockFindCursor = {
+ toArray: jest.fn().mockResolvedValue([]) // Empty array means image not found
+ };
+
+ mockFilesCollection.find.mockReturnValue(mockFindCursor);
+ mockImagesCollection.deleteOne.mockResolvedValue({ deletedCount: 1 });
+
+ const result = await images.delete(uid, imgId);
+
+ // Ensure the deleteOne is not called if the image is not found
+ expect(mockImagesCollection.deleteOne).toHaveBeenCalled();
+ expect(result).toEqual({ deleted: true });
+ });
+
+ it('should return false if the delete operation fails in the images collection', async () => {
+ const uid = 'user123';
+ const imgId = '507f191e810c19729de860ea';
+
+ // Mock the files collection cursor to simulate the image being found
+ const mockFindCursor = {
+ toArray: jest.fn().mockResolvedValue([{ _id: imgId }]) // Image found
+ };
+
+ mockFilesCollection.find.mockReturnValue(mockFindCursor);
+ mockImagesCollection.deleteOne.mockResolvedValue({ deletedCount: 0 }); // Simulate failure
+
+ const result = await images.delete(uid, imgId);
+
+ // Ensure the images collection deletion is called
+ expect(mockImagesCollection.deleteOne).not.toHaveBeenCalledWith({
+ _id: ObjectId.createFromHexString(imgId), // Ensure the ObjectId is created correctly
+ });
+
+ expect(result).toEqual({ deleted: false });
+ });
+
+ });
+});
\ No newline at end of file
diff --git a/server/controllers/images.js b/server/controllers/images.js
index b77ed96..7de02ad 100644
--- a/server/controllers/images.js
+++ b/server/controllers/images.js
@@ -50,6 +50,58 @@ class ImagesController {
}
};
+ getImages = async (req, res, next) => {
+ try {
+ const page = parseInt(req.query.page) || 1;
+ const limit = parseInt(req.query.limit) || 5;
+ const images = await this.images.getImages(page, limit);
+
+ if (!images || images.length === 0) {
+ throw new AppError(IMAGE_NOT_FOUND);
+ }
+
+ res.setHeader('Content-Type', 'application/json');
+ return res.status(200).json(images);
+ } catch (error) {
+ return next(error);
+ }
+ };
+
+ getUserImages = async (req, res, next) => {
+ try {
+ const page = parseInt(req.query.page) || 1;
+ const limit = parseInt(req.query.limit) || 5;
+ const uid = req.query.uid;
+ const images = await this.images.getUserImages(page, limit, uid);
+
+ if (!images || images.length === 0) {
+ throw new AppError(IMAGE_NOT_FOUND);
+ }
+
+ res.setHeader('Content-Type', 'application/json');
+ return res.status(200).json(images);
+ } catch (error) {
+ return next(error);
+ }
+ };
+
+ delete = async (req, res, next) => {
+ try {
+ const uid = req.query.uid;
+ const imgId = req.query.imgId;
+
+ if (!uid || !imgId) {
+ throw new AppError(MISSING_REQUIRED_PARAMETER);
+ }
+ const images = await this.images.delete(uid, imgId);
+
+ res.setHeader('Content-Type', 'application/json');
+ return res.status(200).json(images);
+ } catch (error) {
+ return next(error);
+ }
+ };
+
}
module.exports = ImagesController;
diff --git a/server/models/images.js b/server/models/images.js
index 67a6583..e3b6afd 100644
--- a/server/models/images.js
+++ b/server/models/images.js
@@ -42,6 +42,84 @@ class Images {
};
}
+ async getImages(page, limit) {
+ await this.db.connect()
+ const conn = this.db.getConnection();
+
+ const imagesCollection = conn.collection('images');
+
+
+ const total = await imagesCollection.countDocuments();
+ if (!total || total === 0) return { images: [], total };
+
+ const result = await imagesCollection.find({})
+ .sort({ created_at: 1 })
+ .skip((page - 1) * limit)
+ .limit(limit)
+ .toArray();
+
+ const objImages = result.map(image => ({
+ id: image._id,
+ user: image.userId,
+ file_name: image.file_name,
+ file_content: image.file_content.toString('base64'),
+ mime_type: image.mime_type
+ }));
+
+ let respObj = {
+ images: objImages,
+ total: total
+ }
+
+ return respObj;
+ }
+
+ async getUserImages(page, limit, uid) {
+ await this.db.connect()
+ const conn = this.db.getConnection();
+ const imagesCollection = conn.collection('images');
+ const total = await imagesCollection.countDocuments({ userId: uid });
+ if (!total || total === 0) return { images: [], total };
+
+ const result = await imagesCollection.find({ userId: uid })
+ .sort({ created_at: -1 })
+ .skip((page - 1) * limit)
+ .limit(limit)
+ .toArray();
+
+ const objImages = result.map(image => ({
+ id: image._id,
+ user: image.userId,
+ file_name: image.file_name,
+ file_content: image.file_content.toString('base64'),
+ mime_type: image.mime_type
+ }));
+
+ let respObj = {
+ images: objImages,
+ total: total
+ }
+
+ return respObj;
+ }
+
+ async delete(uid, imgId) {
+ let resp = false;
+ await this.db.connect()
+ const conn = this.db.getConnection();
+ const quizColl = conn.collection('files');
+ const rgxImg = new RegExp(`/api/image/get/${imgId}`);
+
+ const result = await quizColl.find({ userId: uid, content: { $regex: rgxImg }}).toArray();
+ if(!result || result.length < 1){
+ const imgsColl = conn.collection('images');
+ const isDeleted = await imgsColl.deleteOne({ _id: ObjectId.createFromHexString(imgId) });
+ if(isDeleted){
+ resp = true;
+ }
+ }
+ return { deleted: resp };
+ }
}
module.exports = Images;
diff --git a/server/routers/images.js b/server/routers/images.js
index 06e2830..f2d601a 100644
--- a/server/routers/images.js
+++ b/server/routers/images.js
@@ -12,5 +12,8 @@ const upload = multer({ storage: storage });
router.post("/upload", jwt.authenticate, upload.single('image'), asyncHandler(images.upload));
router.get("/get/:id", asyncHandler(images.get));
+router.get("/getImages", asyncHandler(images.getImages));
+router.get("/getUserImages", asyncHandler(images.getUserImages));
+router.delete("/delete", asyncHandler(images.delete));
module.exports = router;