Skip to content

Commit

Permalink
feat: create upload a image route
Browse files Browse the repository at this point in the history
  • Loading branch information
mrinjamul committed Feb 16, 2024
1 parent 718bf5e commit c15bce3
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,6 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# uploaded files
/uploads
65 changes: 65 additions & 0 deletions controllers/pictureController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const constants = require("../constants");

const pictureRepository = require("../repository/pictureRepository");

const fs = require("fs");
const path = require("path");

const pictureController = {
uploadPicture: async (req, res, next) => {
try {
if (!req.file) {
res.status(constants.http.StatusInternalServerError).json({
status: false,
code: constants.http.StatusBadRequest,
error: "No file uploaded",
message: "",
});
return;
}

const filename = req.file.filename; // Get the filename
// Move the uploaded file to the user's private directory
const userId = req.user.id;
const userDir = path.join("uploads", userId);
if (!fs.existsSync(userDir)) {
fs.mkdirSync(userDir);
}
fs.renameSync(req.file.path, path.join(userDir, filename));

// Parse picture meta informations
const url = path.join(userDir, filename);

// create picture
const newPicture = {
userId: userId,
title: filename,
description: null,
url: url,
dateTaken: null,
location: null,
tags: [],
privacy: "private",
likes: 0,
comments: [],
};
const picture = await pictureRepository.addPicture(newPicture);

res.status(constants.http.StatusOK).json({
status: true,
message: `${filename} uploaded successfully`,
data: picture,
});
} catch (err) {
console.error(err);
res.status(constants.http.StatusInternalServerError).json({
status: false,
code: constants.http.StatusInternalServerError,
error: "Internal Server Error",
message: err,
});
}
},
};

module.exports = pictureController;
1 change: 1 addition & 0 deletions helpers/jwt.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const expireIn = 3 * 24 * 60 * 60;
// default payload
function getPayload(user) {
var payload = {
id: user._id,
name: user.name,
username: user.username,
email: user.email,
Expand Down
26 changes: 26 additions & 0 deletions helpers/multer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const multer = require("multer");

const fs = require("fs");
const path = require("path");

// Set up storage for uploaded files
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const uploadDir = "uploads/";
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir);
}
cb(null, uploadDir);
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9); // Generate unique identifier
const ext = path.extname(file.originalname); // Get original file extension
cb(null, uniqueSuffix + ext); // Set filename with unique identifier and original extension
// cb(null, file.originalname);
},
});

// Create the multer instance
const upload = multer({ storage: storage });

module.exports = upload;
47 changes: 47 additions & 0 deletions middlewares/authenticated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const jwt = require("../helpers/jwt");
const constants = require("../constants");

const authenticated = (req, res, next) => {
var token;
try {
token = req.headers.authorization.split(" ")[1];
} catch (err) {
// console.log("error: failed to get token from header");
}
// get cookie
token = req.cookies.token;
// if unable to get token
if (!token) {
res.status(constants.http.StatusUnauthorized).json({
status: false,
code: constants.http.StatusUnauthorized,
error: "token not provided",
message: "Unauthorized",
data: null,
});
}

var verifyOpts = jwt.getVerifyingOptions();
var decodedToken;
try {
decodedToken = jwt.verifyToken(token, verifyOpts);
} catch (error) {
console.log(error);
}
// decodedToken is null
if (!decodedToken) {
res.status(constants.http.StatusUnauthorized).json({
status: false,
code: constants.http.StatusUnauthorized,
error: "invalid token",
message: "Unauthorized",
data: null,
});
} else {
// set payload to the request
req.user = decodedToken;
next();
}
};

module.exports = authenticated;
18 changes: 18 additions & 0 deletions models/picture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const mongoose = require("mongoose");

const pictureSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
title: String,
description: String,
url: String,
dateTaken: Date,
location: String,
tags: [String],
privacy: { type: String, enum: ["public", "private", "shared"] },
likes: { type: Number, default: 0 },
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: "Comment" }],
});

const Picture = mongoose.model("Picture", pictureSchema);

module.exports = Picture;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"express": "~4.16.1",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.1.1",
"morgan": "~1.9.1"
"morgan": "~1.9.1",
"multer": "1.4.5-lts.1"
},
"devDependencies": {
"nodemon": "^3.0.3"
Expand Down
96 changes: 96 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions repository/pictureRepository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const Picture = require("../models/picture");

const pictureRepository = {
addPicture: async (picture) => {
try {
const newPicture = new Picture(picture);
return await newPicture.save();
} catch (error) {
throw new Error(`Error creating picture: ${error.message}`);
}
},
};

module.exports = pictureRepository;
Loading

0 comments on commit c15bce3

Please sign in to comment.