Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*jshint esversion: 6 */
- /* jshint node: true */
- const express = require('express');
- const app = express();
- const path = require('path');
- const fs = require('fs');
- const crypto = require('crypto');
- const session = require('express-session');
- const cookie = require('cookie');
- app.use(session({
- secret: 'please change this secret. No.',
- resave: false,
- saveUninitialized: true
- }));
- app.use(express.static('static'));
- app.use(function (req, res, next){
- var cookies = cookie.parse(req.headers.cookie || '');
- req.username = (req.session.username) ? req.session.username : null;
- console.log("HTTP request", req.username, req.method, req.url, req.body);
- next();
- });
- const bodyParser = require('body-parser');
- app.use(bodyParser.urlencoded({ extended: false }));
- app.use(bodyParser.json());
- var multer = require('multer');
- var upload = multer({ dest: path.join(__dirname, 'uploads')});
- var Datastore = require('nedb');
- var images = new Datastore({ filename: 'db/images.db', autoload: true, timestampData : true});
- var comments = new Datastore({ filename: 'db/comments.db', autoload: true, timestampData : true});
- var users = new Datastore({ filename: 'db/users.db', autoload: true});
- /** Note to the marker: I did not know whether it would be autotested and in the starter file of api.js there is a header
- declaring certain datatypes needed (same as A1) however,
- in tutorial we learned to get rid of that id for a generated
- one by nedb. I assume this id is the one is given when getting, removing, etc. However, I have left the old way of generating id in case of automarking (this is also true for date) **/
- var Cmt = (function(){
- var id = 0;
- return function item(comment){
- this.commentId = id++;
- this.imageId = comment.imageId;
- this.author = comment.author;
- this.content = comment.content;
- this.upvote = 0;
- this.downvote = 0;
- this.date = Date.now();
- };
- }());
- var Img = (function(){
- var id = 0;
- return function item(image){
- this.imageId = id++;
- this.author = image.author;
- this.title = image.title;
- this.date = Date.now();
- };
- }());
- var isAuthenticated = function(req, res, next){
- if (!req.session.username) return res.status(401).end("Not logged in");
- next();
- };
- //Create
- app.post('/api/signup/', function(req, res, next){
- var username = req.body.username;
- var password = req.body.password;
- users.findOne({_id: username}, function(err, user){
- if (err) return res.status(500).end(err);
- if (user) return res.status(400).end(username + " already exists");
- var salt = crypto.randomBytes(16).toString('base64');
- var hash = crypto.createHmac('sha512', salt);
- hash.update(password);
- var saltedHash = hash.digest('base64');
- users.update({_id: username}, {_id: username, password: saltedHash, salt: salt}, {upsert: true}, function(err){
- if (err) return res.status(500).end(err);
- res.setHeader('Set-Cookie', cookie.serialize('username', username, {
- path: '/',
- maxAge: 31449600
- }));
- return res.json(username + " successfully signed up");
- });
- });
- });
- app.post('/api/signin/', function(req, res, next){
- var username = req.body.username;
- var password = req.body.password;
- users.findOne({_id: username}, function(err, user){
- if (err) return res.status(500).end(err);
- if (!user) return res.status(401).end("Access Denied");
- var hash = crypto.createHmac('sha512', user.salt);
- hash.update(password);
- password = hash.digest('base64');
- if(user.password !== password) return res.status(401).end("Access Denied");
- res.setHeader('Set-Cookie', cookie.serialize('username', username, {
- path: '/',
- maxAge: 60 * 60 * 24 * 7
- }));
- req.session.cookie.maxAge = 60 * 60 * 24 * 7;
- req.session.cookie.path = '/';
- req.session.username = username;
- return res.json(username + " successfully signed in");
- })
- });
- app.post('/api/image/', upload.single('picture'), isAuthenticated, function(req, res, next){
- var img = new Img({"author": req.username, "title": req.body.title});
- images.insert({imageId: img.imageId, title: img.title, author: img.username, picture: req.file, date: img.date}, function(err, newImg){
- if(err) return res.status(500).end(err);
- return res.json(newImg);
- });
- });
- app.post('/api/comment/', isAuthenticated, function(req, res, next){
- var comment = new Cmt({"imageId": req.body.imageId, "author": req.session.username, "content": req.body.content});
- comments.insert({commentId: comment.commentId, imageId: comment.imageId, author: comment.author, content: comment.content, upvote: comment.upvote, downvote: comment.downvote, date: comment.date}, function(err, newComment){
- if(err) return res.status(500).end(err);
- return res.json(comment);
- });
- });
- //Read
- app.get('/api/signout/', isAuthenticated, function(req, res, next){
- res.setHeader('Set-Cookie', cookie.serialize('username', '', {
- path: '/',
- maxAge: 60 * 60 * 24 * 7
- }))
- res.redirect('/');
- })
- app.get('/api/users/', isAuthenticated, function(req, res, next){
- users.find({}, function(err, users){
- if (err) returnres.status(500).end(err);
- else{
- var res_users = [];
- for(var i = 0; i < users.length; i++){
- res_users.push(users[i]._id);
- }
- return res.send(res_users);
- }
- })
- });
- //Gets all image ids
- app.get('/api/images/:id/', isAuthenticated, function(req, res, next){
- images.find({author: req.params.id}, function(err, imgs){
- if(err) return res.status(500).end(err);
- else{
- var ids = [];
- for(var i = 0; i < imgs.length; i++){
- ids.push(imgs[i]._id);
- }
- return res.send(ids);
- }
- });
- });
- // Gets the image given an id
- app.get('/api/image/:id/', isAuthenticated, function(req, res, next){
- images.findOne({_id: req.params.id}, function(err, img){
- if(err) return res.status(500).end(err);
- else if(!img) return res.status(404).end("Image with id: " + req.params.id + " does not exist");
- else{
- return res.json(img);
- }
- });
- });
- // Gets 10 most recent comments given an offset
- app.get('/api/comments/:id', isAuthenticated, function(req, res, next){
- comments.find({imageId: req.params.id}).sort({createdAt: 1}).skip(req.query.page * 10).limit(10).exec(function(err, cmts){
- if(err) return res.status(500).end(err);
- return res.json(cmts);
- });
- });
- //Update
- //Delete
- app.delete('/api/image/:id/', isAuthenticated, function(req, res, next){
- images.findOne({_id: req.params.id}, function(err, img){
- if(err) return res.status(500).end(err);
- if(!img) return res.status(404).end("Image with id: " + req.params.id + " does not exist");
- if(req.session.username != img.author) return res.status(401).end("Access Denied");
- else{
- //deletes the picture from uploads
- fs.unlinkSync(img.picture.path);
- }
- //removes all comments associated with image
- comments.remove({imageId: req.params.id}, {multi: true}, function(err, numRemoved){
- if(err) return res.status(500).end(err);
- });
- //removes image from db
- images.remove({_id: req.params.id}, {multi: false}, function(err, numRemoved){
- if(err) return res.status(500).end(err);
- else if (numRemoved === 0) return res.status(404).end("Image with id: " + req.params.id + " does not exist");
- return res.json(img);
- });
- });
- });
- //delete individual comment
- app.delete('/api/comment/:id/', isAuthenticated, function(req, res, next){
- comments.findOne({_id: req.params.id}, function(err, cmt){
- if(err) return res.status(500).end(err);
- if(!cmt) return res.status(404).end("Comment with id: " + req.params.id + " does not exist");
- if(req.session.username != cmt.author) return res.status(401).end("Access Denied");
- comments.remove({_id: req.params.id}, {multi: false}, function(err, numRemoved){
- if(err) return res.status(500).end(err);
- else if (numRemoved === 0) return res.status(404).end("Comment with id: " + req.params.id + " does not exist");
- return res.json(cmt);
- });
- });
- });
- const http = require('http');
- const PORT = 3000;
- http.createServer(app).listen(PORT, function (err) {
- if (err) console.log(err);
- else console.log("HTTP server on http://localhost:%s", PORT);
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement