Advertisement
Guest User

Untitled

a guest
Feb 25th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.83 KB | None | 0 0
  1. /*jshint esversion: 6 */
  2. /* jshint node: true */
  3. const express = require('express');
  4. const app = express();
  5. const path = require('path');
  6. const fs = require('fs');
  7.  
  8. const crypto = require('crypto');
  9. const session = require('express-session');
  10. const cookie = require('cookie');
  11.  
  12. app.use(session({
  13. secret: 'please change this secret. No.',
  14. resave: false,
  15. saveUninitialized: true
  16. }));
  17.  
  18. app.use(express.static('static'));
  19.  
  20. app.use(function (req, res, next){
  21. var cookies = cookie.parse(req.headers.cookie || '');
  22. req.username = (req.session.username) ? req.session.username : null;
  23. console.log("HTTP request", req.username, req.method, req.url, req.body);
  24. next();
  25. });
  26.  
  27. const bodyParser = require('body-parser');
  28. app.use(bodyParser.urlencoded({ extended: false }));
  29. app.use(bodyParser.json());
  30.  
  31. var multer = require('multer');
  32. var upload = multer({ dest: path.join(__dirname, 'uploads')});
  33.  
  34. var Datastore = require('nedb');
  35. var images = new Datastore({ filename: 'db/images.db', autoload: true, timestampData : true});
  36. var comments = new Datastore({ filename: 'db/comments.db', autoload: true, timestampData : true});
  37. var users = new Datastore({ filename: 'db/users.db', autoload: true});
  38.  
  39. /** 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
  40. declaring certain datatypes needed (same as A1) however,
  41. in tutorial we learned to get rid of that id for a generated
  42. 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) **/
  43.  
  44. var Cmt = (function(){
  45. var id = 0;
  46. return function item(comment){
  47. this.commentId = id++;
  48. this.imageId = comment.imageId;
  49. this.author = comment.author;
  50. this.content = comment.content;
  51. this.upvote = 0;
  52. this.downvote = 0;
  53. this.date = Date.now();
  54. };
  55. }());
  56.  
  57. var Img = (function(){
  58. var id = 0;
  59. return function item(image){
  60. this.imageId = id++;
  61. this.author = image.author;
  62. this.title = image.title;
  63. this.date = Date.now();
  64. };
  65. }());
  66.  
  67. var isAuthenticated = function(req, res, next){
  68. if (!req.session.username) return res.status(401).end("Not logged in");
  69. next();
  70. };
  71.  
  72. //Create
  73.  
  74. app.post('/api/signup/', function(req, res, next){
  75. var username = req.body.username;
  76. var password = req.body.password;
  77.  
  78. users.findOne({_id: username}, function(err, user){
  79. if (err) return res.status(500).end(err);
  80. if (user) return res.status(400).end(username + " already exists");
  81.  
  82. var salt = crypto.randomBytes(16).toString('base64');
  83. var hash = crypto.createHmac('sha512', salt);
  84. hash.update(password);
  85. var saltedHash = hash.digest('base64');
  86.  
  87. users.update({_id: username}, {_id: username, password: saltedHash, salt: salt}, {upsert: true}, function(err){
  88. if (err) return res.status(500).end(err);
  89. res.setHeader('Set-Cookie', cookie.serialize('username', username, {
  90. path: '/',
  91. maxAge: 31449600
  92. }));
  93. return res.json(username + " successfully signed up");
  94. });
  95. });
  96. });
  97.  
  98. app.post('/api/signin/', function(req, res, next){
  99. var username = req.body.username;
  100. var password = req.body.password;
  101.  
  102. users.findOne({_id: username}, function(err, user){
  103. if (err) return res.status(500).end(err);
  104. if (!user) return res.status(401).end("Access Denied");
  105.  
  106. var hash = crypto.createHmac('sha512', user.salt);
  107. hash.update(password);
  108. password = hash.digest('base64');
  109.  
  110. if(user.password !== password) return res.status(401).end("Access Denied");
  111. res.setHeader('Set-Cookie', cookie.serialize('username', username, {
  112. path: '/',
  113. maxAge: 60 * 60 * 24 * 7
  114. }));
  115.  
  116. req.session.cookie.maxAge = 60 * 60 * 24 * 7;
  117. req.session.cookie.path = '/';
  118. req.session.username = username;
  119.  
  120. return res.json(username + " successfully signed in");
  121. })
  122. });
  123.  
  124. app.post('/api/image/', upload.single('picture'), isAuthenticated, function(req, res, next){
  125. var img = new Img({"author": req.username, "title": req.body.title});
  126. images.insert({imageId: img.imageId, title: img.title, author: img.username, picture: req.file, date: img.date}, function(err, newImg){
  127. if(err) return res.status(500).end(err);
  128. return res.json(newImg);
  129. });
  130. });
  131.  
  132. app.post('/api/comment/', isAuthenticated, function(req, res, next){
  133. var comment = new Cmt({"imageId": req.body.imageId, "author": req.session.username, "content": req.body.content});
  134. 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){
  135. if(err) return res.status(500).end(err);
  136. return res.json(comment);
  137. });
  138. });
  139.  
  140. //Read
  141.  
  142. app.get('/api/signout/', isAuthenticated, function(req, res, next){
  143. res.setHeader('Set-Cookie', cookie.serialize('username', '', {
  144. path: '/',
  145. maxAge: 60 * 60 * 24 * 7
  146. }))
  147. res.redirect('/');
  148. })
  149.  
  150. app.get('/api/users/', isAuthenticated, function(req, res, next){
  151. users.find({}, function(err, users){
  152. if (err) returnres.status(500).end(err);
  153. else{
  154. var res_users = [];
  155. for(var i = 0; i < users.length; i++){
  156. res_users.push(users[i]._id);
  157. }
  158. return res.send(res_users);
  159. }
  160. })
  161. });
  162.  
  163. //Gets all image ids
  164. app.get('/api/images/:id/', isAuthenticated, function(req, res, next){
  165. images.find({author: req.params.id}, function(err, imgs){
  166. if(err) return res.status(500).end(err);
  167. else{
  168. var ids = [];
  169. for(var i = 0; i < imgs.length; i++){
  170. ids.push(imgs[i]._id);
  171. }
  172. return res.send(ids);
  173. }
  174. });
  175. });
  176.  
  177. // Gets the image given an id
  178. app.get('/api/image/:id/', isAuthenticated, function(req, res, next){
  179. images.findOne({_id: req.params.id}, function(err, img){
  180. if(err) return res.status(500).end(err);
  181. else if(!img) return res.status(404).end("Image with id: " + req.params.id + " does not exist");
  182. else{
  183. return res.json(img);
  184. }
  185. });
  186. });
  187.  
  188. // Gets 10 most recent comments given an offset
  189. app.get('/api/comments/:id', isAuthenticated, function(req, res, next){
  190. comments.find({imageId: req.params.id}).sort({createdAt: 1}).skip(req.query.page * 10).limit(10).exec(function(err, cmts){
  191. if(err) return res.status(500).end(err);
  192. return res.json(cmts);
  193. });
  194. });
  195.  
  196. //Update
  197. //Delete
  198.  
  199. app.delete('/api/image/:id/', isAuthenticated, function(req, res, next){
  200. images.findOne({_id: req.params.id}, function(err, img){
  201. if(err) return res.status(500).end(err);
  202. if(!img) return res.status(404).end("Image with id: " + req.params.id + " does not exist");
  203. if(req.session.username != img.author) return res.status(401).end("Access Denied");
  204. else{
  205. //deletes the picture from uploads
  206. fs.unlinkSync(img.picture.path);
  207. }
  208. //removes all comments associated with image
  209. comments.remove({imageId: req.params.id}, {multi: true}, function(err, numRemoved){
  210. if(err) return res.status(500).end(err);
  211. });
  212. //removes image from db
  213. images.remove({_id: req.params.id}, {multi: false}, function(err, numRemoved){
  214. if(err) return res.status(500).end(err);
  215. else if (numRemoved === 0) return res.status(404).end("Image with id: " + req.params.id + " does not exist");
  216. return res.json(img);
  217. });
  218. });
  219. });
  220.  
  221. //delete individual comment
  222. app.delete('/api/comment/:id/', isAuthenticated, function(req, res, next){
  223. comments.findOne({_id: req.params.id}, function(err, cmt){
  224. if(err) return res.status(500).end(err);
  225. if(!cmt) return res.status(404).end("Comment with id: " + req.params.id + " does not exist");
  226. if(req.session.username != cmt.author) return res.status(401).end("Access Denied");
  227. comments.remove({_id: req.params.id}, {multi: false}, function(err, numRemoved){
  228. if(err) return res.status(500).end(err);
  229. else if (numRemoved === 0) return res.status(404).end("Comment with id: " + req.params.id + " does not exist");
  230. return res.json(cmt);
  231. });
  232. });
  233. });
  234.  
  235. const http = require('http');
  236. const PORT = 3000;
  237.  
  238. http.createServer(app).listen(PORT, function (err) {
  239. if (err) console.log(err);
  240. else console.log("HTTP server on http://localhost:%s", PORT);
  241. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement