Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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;
Expand All @@ -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

Expand All @@ -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) {
Expand Down
26 changes: 26 additions & 0 deletions config/gridfs.js
Original file line number Diff line number Diff line change
@@ -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 };
78 changes: 62 additions & 16 deletions controllers/imageControllers.js
Original file line number Diff line number Diff line change
@@ -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");
Expand Down Expand Up @@ -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');
Expand Down
112 changes: 112 additions & 0 deletions controllers/pdfControllers.js
Original file line number Diff line number Diff line change
@@ -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,
};
14 changes: 14 additions & 0 deletions middleware/index.js
Original file line number Diff line number Diff line change
@@ -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;
35 changes: 35 additions & 0 deletions models/profile_image.js
Original file line number Diff line number Diff line change
@@ -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;
30 changes: 7 additions & 23 deletions routes/image.js
Original file line number Diff line number Diff line change
@@ -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')
Expand Down Expand Up @@ -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;
};
Loading