From 9a11f8849efb718a2e39d649d41f1ec839d62dba Mon Sep 17 00:00:00 2001 From: Vikash Kumar Date: Fri, 29 Nov 2024 11:09:39 +0530 Subject: [PATCH 1/2] Privacy checkup --- models/profile_image.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 models/profile_image.js diff --git a/models/profile_image.js b/models/profile_image.js new file mode 100644 index 0000000..e69de29 From 37835cd1ab7e9299bf6a9dada5de467158196655 Mon Sep 17 00:00:00 2001 From: Vikash Kumar Date: Fri, 29 Nov 2024 12:59:07 +0530 Subject: [PATCH 2/2] Pdf uploader update --- app.js | 9 ++- config/gridfs.js | 26 ++++++++ controllers/imageControllers.js | 78 +++++++++++++++++----- controllers/pdfControllers.js | 112 ++++++++++++++++++++++++++++++++ middleware/index.js | 14 ++++ models/profile_image.js | 35 ++++++++++ routes/image.js | 30 ++------- routes/pdf.js | 16 +++++ 8 files changed, 279 insertions(+), 41 deletions(-) create mode 100644 config/gridfs.js create mode 100644 controllers/pdfControllers.js create mode 100644 middleware/index.js create mode 100644 routes/pdf.js diff --git a/app.js b/app.js index 3e2ee8a..5099445 100644 --- a/app.js +++ b/app.js @@ -11,6 +11,7 @@ const crypto = require('crypto'); const cors = require('cors'); const imageRouter = require('./routes/image'); +const pdfRouter = require('./routes/pdf'); const app = express(); @@ -29,6 +30,8 @@ app.use(methodOverride('_method')); app.use(express.static(path.join(__dirname, 'public'))); const mongoose = require('mongoose'); +const { initGridFS } = require('./config/gridfs'); +const apiProtection = require('./middleware'); mongoose.Promise = require('bluebird'); const url = config.mongoURI; @@ -40,8 +43,9 @@ const connect = mongoose.connect(url, { useNewUrlParser: true, useUnifiedTopolog // connect to the database connect.then(() => { - console.log(`\nConnected to database: gridfs\nBase URL:http://localhost:${process.env.PORT || '9890'}`); + console.log(`\nConnected to database: gridfs\nBase URL:http://localhost:${process.env.PORT || '8000'}`); }, (err) => console.log(`Error connecting to database: ${err}`)); +initGridFS(); //GridFs Configuration @@ -67,7 +71,8 @@ const storage = new GridFsStorage({ const upload = multer({ storage }); -app.use('/', imageRouter(upload, app)); +app.use('/', apiProtection, imageRouter(upload, app)); +app.use('/', apiProtection, pdfRouter(upload, app)); // catch 404 and forward to error handler app.use(function (req, res, next) { diff --git a/config/gridfs.js b/config/gridfs.js new file mode 100644 index 0000000..3822944 --- /dev/null +++ b/config/gridfs.js @@ -0,0 +1,26 @@ +// gridfs.js +const mongoose = require("mongoose"); +const config = require('../config'); +let gfs; + +const initGridFS = () => { + const url = config.mongoURI; + const connect = mongoose.createConnection(url, { useNewUrlParser: true, useUnifiedTopology: true }); + + connect.once("open", () => { + gfs = new mongoose.mongo.GridFSBucket(connect.db, { + bucketName: "uploads" + }); + }); + + return connect; +}; + +const getGridFS = () => { + if (!gfs) { + throw new Error("GridFS is not initialized yet"); + } + return gfs; +}; + +module.exports = { initGridFS, getGridFS }; diff --git a/controllers/imageControllers.js b/controllers/imageControllers.js index 2d8247f..676a463 100644 --- a/controllers/imageControllers.js +++ b/controllers/imageControllers.js @@ -1,8 +1,12 @@ const responseObjects = require("../helpers/response-objects"); const Image = require("../models/image"); +const gfsFun = require("../config/gridfs"); const addImageInDB = async (req, res) => { try { + if (!req.file) { + return responseObjects.badRequest(res, null, 'No file found', 'No file found'); + } const isCaptionImageIsExist = await Image.findOne({ caption: req.body.caption }); if (isCaptionImageIsExist) { return responseObjects.conflict(res, null, 'Image already exists', "Image already exists"); @@ -73,34 +77,76 @@ const uploadMultipleFiles = async (req, res) => { } } +// const renderSingleImageOnBrowser = async (req, res) => { +// try { +// const fileName = req.params.filename; +// const gfs = gfsFun.getGridFS(); +// if (!fileName) { +// return responseObjects.badRequest(res, null, 'No file name found', 'No file name found'); +// } +// const findFile = await Image.findOne({ filename: fileName }); +// if (!findFile) { +// return responseObjects.notFound(res, null, 'File not found', 'File not found'); +// } +// if (!gfs) { +// return responseObjects.serverError(res, {}, "Gridfs image not found", "Gridfs image not found") +// } +// console.log('gfs', gfs); + +// gfs.find({ filename: fileName }).toArray((err, files) => { +// if (!files[0] || files.length === 0) { +// return res.status(200).json({ +// success: false, +// message: 'No files available', +// }); +// } +// if (files[0].contentType === 'image/jpeg' || files[0].contentType === 'image/png' || files[0].contentType === 'image/svg+xml') { +// gfs.openDownloadStreamByName(fileName).pipe(res); +// } else { +// return responseObjects.badRequest(res, null, 'File is not an image', 'File is not an image'); +// } +// }); +// } catch (error) { +// return responseObjects.error(res, error.message, 'Internal server error', 'Internal server error'); +// } +// } const renderSingleImageOnBrowser = async (req, res) => { try { const fileName = req.params.filename; + const gfs = gfsFun.getGridFS(); + if (!fileName) { return responseObjects.badRequest(res, null, 'No file name found', 'No file name found'); } - const gfs = req.ImageGridFs; - gfs.find({ filename: fileName }).toArray((err, files) => { - if (!files[0] || files.length === 0) { - return res.status(200).json({ - success: false, - message: 'No files available', - }); - } - if (files[0].contentType === 'image/jpeg' || files[0].contentType === 'image/png' || files[0].contentType === 'image/svg+xml') { - gfs.openDownloadStreamByName(fileName).pipe(res); - } else { - return responseObjects.badRequest(res, null, 'File is not an image', 'File is not an image'); - } - }); + const findFile = await Image.findOne({ filename: fileName }); + if (!findFile) { + return responseObjects.notFound(res, null, 'File not found', 'File not found'); + } + + if (!gfs) { + return responseObjects.serverError(res, {}, "GridFS not found", "GridFS not found"); + } + const file = await gfs.find({ filename: fileName }).toArray(); + if (!file[0]) { + return responseObjects.notFound(res, null, 'File not found in GridFS', 'File not found in GridFS'); + } + if (['image/jpeg', 'image/png', 'image/svg+xml'].includes(file[0].contentType)) { + const downloadStream = gfs.openDownloadStreamByName(fileName); + res.setHeader('Content-Type', file[0].contentType); + downloadStream.pipe(res); + } else { + return responseObjects.badRequest(res, null, 'File is not a supported image type', 'File is not a supported image type'); + } } catch (error) { - return responseObjects.error(res, error, 'Internal server error', 'Internal server error'); + console.error(error); + return responseObjects.error(res, error.message || 'Internal Server Error', 'Internal server error', 'Internal server error'); } } + const deletePerticularFileById = async (req, res) => { try { - const gfs = req.ImageGridFs; + const gfs = gfsFun.getGridFS(); gfs.delete(new mongoose.Types.ObjectId(req.params.id), (err, data) => { if (err) { return responseObjects.error(res, err, 'Internal server error', 'Internal server error'); diff --git a/controllers/pdfControllers.js b/controllers/pdfControllers.js new file mode 100644 index 0000000..26cb519 --- /dev/null +++ b/controllers/pdfControllers.js @@ -0,0 +1,112 @@ +const responseObjects = require("../helpers/response-objects"); +const Pdf = require("../models/pdf"); +const gfsFun = require("../config/gridfs"); + +const addPdfToDb = async (req, res) => { + try { + if (!req.file) { + return responseObjects.badRequest(res, null, 'No file found', 'No file found'); + } + const isCaptionImageIsExist = await Pdf.findOne({ pdfCaption: req.body.caption }); + if (isCaptionImageIsExist) { + return responseObjects.conflict(res, null, 'Image already exists', "Image already exists"); + } + + const newPdf = new Pdf({ + pdfCaption: req.body.caption, + pdfFileName: req.file.filename, + pdfFileId: req.file.id, + }); + await newPdf.save(); + return responseObjects.created(res, newPdf, 'Pdf added successfully', 'Pdf added successfully'); + } catch (error) { + return responseObjects.error(res, error, 'Internal server error', 'Internal server error'); + } +} + +const getAllPdfsFromDb = async (req, res) => { + try { + const pdfs = await Pdf.find({}).lean(); + return responseObjects.success(res, pdfs, 'Pdfs fetched successfully', 'Pdfs fetched successfully'); + } catch (error) { + return responseObjects.error(res, error, 'Internal server error', 'Internal server error'); + } +} + +const deletePdfFromDb = async (req, res) => { + try { + const isPdfExist = await Pdf.findOne({ _id: req.params.id }); + if (!isPdfExist) { + return responseObjects.notFound(res, null, 'Pdf not found', 'Pdf not found'); + } + const deletedPdf = await Pdf.deleteOne({ _id: req.params.id }); + return responseObjects.success(res, deletedPdf, 'Pdf deleted successfully', 'Pdf deleted successfully'); + } catch (error) { + return responseObjects.error(res, error, 'Internal server error', 'Internal server error'); + } +} + +const fetchMostRecentPdf = async (req, res) => { + try { + const pdf = await Pdf.findOne({}, {}, { sort: { '_id': -1 } }); + return responseObjects.success(res, pdf, 'Pdf fetched successfully', 'Pdf fetched successfully'); + } catch (error) { + return responseObjects.error(res, error, 'Internal server error', 'Internal server error'); + } +} + +const uploadMultipleFiles = async (req, res) => { + try { + const files = req?.files; + if (!files) { + return responseObjects.badRequest(res, null, 'No files found', 'No files found'); + } + let pdfs = []; + files.map(async (file) => { + const newPdf = new Pdf({ + pdfCaption: req.body.caption, + pdfFileName: file.filename, + pdfFileId: file.id, + }); + pdfs.push(newPdf); + }); + await Pdf.insertMany(pdfs); + return responseObjects.created(res, pdfs, 'Pdfs added successfully', 'Pdfs added successfully'); + } catch (error) { + return responseObjects.error(res, error, 'Internal server error', 'Internal server error'); + } +} + +const renderPdf = async (req, res) => { + try { + const fileName = req.params.filename; + const pdf = await Pdf.findOne({ pdfFileName: fileName }); + if (!pdf) { + return responseObjects.notFound(res, null, 'Pdf not found', 'Pdf not found'); + } + const gfs = gfsFun.getGridFS(); + const fileFind=await gfs.find({filename:pdf.pdfFileName}).toArray(); + if(!fileFind[0]){ + return responseObjects.notFound(res, null, 'File not found in GridFS', 'File not found in GridFS'); + } + if (fileFind[0].contentType !== 'application/pdf') { + return responseObjects.badRequest(res, null, 'File is not a pdf', 'File is not a pdf'); + } + res.setHeader('Content-Type', 'application/pdf'); + res.setHeader('Content-Disposition', `attachment; filename=${pdf.pdfFileName}`); + const downloadStream = gfs.openDownloadStreamByName(pdf.pdfFileName); + downloadStream.pipe(res); + } + catch (error) { + return responseObjects.error(res, error.message, 'Internal server error', 'Internal server error'); + } +} + +module.exports = { + addPdfToDb, + getAllPdfsFromDb, + deletePdfFromDb, + fetchMostRecentPdf, + uploadMultipleFiles, + renderPdf, +}; \ No newline at end of file diff --git a/middleware/index.js b/middleware/index.js new file mode 100644 index 0000000..c08d676 --- /dev/null +++ b/middleware/index.js @@ -0,0 +1,14 @@ +const responseObjects = require("../helpers/response-objects"); + +const apiProtection = (req, res, next) => { + const token = req.headers['authorization']; + if (!token) { + return responseObjects.unauthorized(res, null, "Unauthorized access to this resource is denied", "Unauthorized access to this resource is denied"); + } + if (token !== process.env.API_TOKEN) { + return responseObjects.unauthorized(res, null, 'Unauthorized access to this resource is denied', 'Unauthorized access to this resource is denied'); + } + next(); +}; + +module.exports = apiProtection; \ No newline at end of file diff --git a/models/profile_image.js b/models/profile_image.js index e69de29..d8ca904 100644 --- a/models/profile_image.js +++ b/models/profile_image.js @@ -0,0 +1,35 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const ImageSchema = new Schema({ + userId: { + required: true, + type: String, + }, + userName: { + required: true, + type: String, + }, + userRole: { + required: true, + type: String, + }, + caption: { + required: true, + type: String, + }, + filename: { + required: true, + type: String, + }, + fileId: { + required: true, + type: String, + } +}, { + timestamps: true, +}); + +const Image = mongoose.model('User_Profile', ImageSchema); + +module.exports = Image; \ No newline at end of file diff --git a/routes/image.js b/routes/image.js index 7d44dec..89e2343 100644 --- a/routes/image.js +++ b/routes/image.js @@ -1,35 +1,19 @@ const express = require('express'); const imageRouter = express.Router(); -const mongoose = require('mongoose'); -const config = require('../config'); const { addImageInDB, getAllImagesFromDB, deleteImageInDB, fetchMostRecentImage, uploadMultipleFiles, renderSingleImageOnBrowser, deletePerticularFileById } = require('../controllers/imageControllers'); - module.exports = (upload, app) => { - const url = config.mongoURI; - const connect = mongoose.createConnection(url, { useNewUrlParser: true, useUnifiedTopology: true }); - - let gfs; - connect.once('open', () => { - // initialize stream - gfs = new mongoose.mongo.GridFSBucket(connect.db, { - bucketName: "uploads" - }); - }); - - app.set("ImageGridFs", gfs); - //POST: Upload a single image/file to Image collection - imageRouter.route('/upload/image').post(upload.single('file'), addImageInDB); - imageRouter.route('/get-all-images').get(getAllImagesFromDB); + imageRouter.route('/assets/images/upload').post(upload.single('file'), addImageInDB); + imageRouter.route('/assets/get-all-images').get(getAllImagesFromDB); //GET: Delete an image from the collection - imageRouter.route('/image/delete/:id').post(deleteImageInDB); + imageRouter.route('/assets/images/delete/:id').post(deleteImageInDB); //GET: Fetch most recently added record - imageRouter.route('/image/recent').get(fetchMostRecentImage); + imageRouter.route('/assets/images/recent').get(fetchMostRecentImage); //POST: Upload multiple files upto 20 - imageRouter.route('/multiple/image/upload').post(upload.array('files', 20), uploadMultipleFiles); + imageRouter.route('/assets/multiple/images/upload').post(upload.array('files', 20), uploadMultipleFiles); //GET: Fetches all the files in the uploads collection // imageRouter.route('/files') @@ -76,10 +60,10 @@ module.exports = (upload, app) => { // }); //GET: Fetches a particular image and render on browser - imageRouter.route('/get-image/:filename').get(renderSingleImageOnBrowser); + imageRouter.route('/assets/images/content/:filename').get(renderSingleImageOnBrowser); //DELETE: Delete a particular file by an ID - imageRouter.route('/file/del/:id').post(deletePerticularFileById); + imageRouter.route('/assets/images/file/del/:id').post(deletePerticularFileById); return imageRouter; }; \ No newline at end of file diff --git a/routes/pdf.js b/routes/pdf.js new file mode 100644 index 0000000..151cafc --- /dev/null +++ b/routes/pdf.js @@ -0,0 +1,16 @@ +const express = require('express'); +const pdfRouter = express.Router(); +const { addPdfToDb, getAllPdfsFromDb, fetchMostRecentPdf, uploadMultipleFiles, deletePdfFromDb, renderPdf } = require("../controllers/pdfControllers"); + +module.exports = (upload, app) => { + //POST: Upload a single pdf/file to Pdf collection + pdfRouter.route('/assets/upload/pdf').post(upload.single('file'), addPdfToDb); + pdfRouter.route('/assets/get-all-pdfs').get(getAllPdfsFromDb); + //GET: Fetch most recently added record + pdfRouter.route('/assets/pdf/recent').get(fetchMostRecentPdf); + //POST: Upload multiple files upto 20 + pdfRouter.route('/assets/multiple/pdf/upload').post(upload.array('files', 20), uploadMultipleFiles); + pdfRouter.route('/assets/pdf/delete/:id').post(deletePdfFromDb); + pdfRouter.route('/assets/pdf/content/:filename').get(renderPdf); + return pdfRouter; +}; \ No newline at end of file