From 7ea837e2d9eb5d7463be6c5258b9a61a67d0fbe8 Mon Sep 17 00:00:00 2001 From: potravniy Date: Tue, 18 Aug 2015 12:39:23 +0300 Subject: [PATCH 1/3] Not completed with mongoDB. --- README.md | 20 +- ...0Network%20Project.json.postman_collection | 341 ++++++++++++++++++ app.js | 68 ++-- controllers/follow.js | 93 +++++ controllers/post.js | 82 ++++- controllers/user.js | 111 +++--- db.json | 2 +- package.json | 27 +- 8 files changed, 660 insertions(+), 84 deletions(-) create mode 100644 Social%20Network%20Project.json.postman_collection create mode 100644 controllers/follow.js diff --git a/README.md b/README.md index 2f10b94..b0ffc93 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Отрефакторить /registration запрос: - сделать проверки + сделать проверки OK хэшировать пароль @@ -10,30 +10,30 @@ GET : - /post - возвращает список всех записей + /post - возвращает список всех записей OK - /posts/:id - возвращает запись с заданным id (req.param.id) + /posts/:id - возвращает запись с заданным id (req.param.id) OK - /user/:id/following - возвращает список кумиров указанного юзера (кого этот юзер фолловит, отслеживает) + /user/:id/following - возвращает список кумиров указанного юзера (кого этот юзер фолловит, отслеживает) OK - /user/:id/folowers - возвращает список фанатов указанного юзера (кто отслеживает указанного юзера) + /user/:id/folowers - возвращает список фанатов указанного юзера (кто отслеживает указанного юзера) OK DELETE: - /posts/:id - удаляет запись с заданным id (только если currentUser.id == author.id || currentUser.id == owner.id) + /posts/:id - удаляет запись с заданным id (только если currentUser.id == author.id || currentUser.id == owner.id) OK - /user/:id/follow - отписаться (перестать отслеживать) от юзера с заданным id + /user/:id/follow - отписаться (перестать отслеживать) от юзера с заданным id OK PUT: - /me - редактировать данные о себе + /me - редактировать данные о себе OK - /posts/:id редактировать запись (только если currentUser.id == author.id) + /posts/:id редактировать запись (только если currentUser.id == author.id) OK POST: - /user/:id/follow - подписаться на юзера с заданным id + /user/:id/follow - подписаться на юзера с заданным id OK diff --git a/Social%20Network%20Project.json.postman_collection b/Social%20Network%20Project.json.postman_collection new file mode 100644 index 0000000..49cd1e5 --- /dev/null +++ b/Social%20Network%20Project.json.postman_collection @@ -0,0 +1,341 @@ +{ + "id": "5e033b16-8151-c70f-c605-aae95c988855", + "name": "Social Network Project", + "description": "", + "order": [ + "1a2ef65c-0abb-0221-f322-c53163f10dce", + "939d616a-0028-1bfd-34c1-78a1e9b1f13d", + "e21a8734-8e8c-ad5a-3fe3-b53b12ed21b2", + "c9a62701-3fe8-f06b-a18e-81289ba24f24", + "bda1c237-b1cd-a984-1fa2-123f19c63c19", + "e9caca8e-1d55-1040-8392-7934708a38a4", + "bef8ea8b-fe43-d350-f253-0bcc1c53e0e9", + "25e93113-5298-1ad0-7c19-301e03088aad", + "ee8239e4-7996-5261-0d21-c0d8f06c0b75", + "c6e0d4c7-0e38-a69a-b615-28dba23268b9", + "8ab80377-2d4c-3f9c-097e-99a4df147cdc", + "39354428-48ed-3696-8c84-87bce170a377", + "a8d5f618-7cc2-eb10-8332-4c2786daa29f", + "fbb2183d-5d75-2cf1-4f44-b395fdd43a7f", + "124203f4-6fde-c67a-c332-c2169f274227" + ], + "folders": [], + "timestamp": 1439307457010, + "owner": "", + "remoteLink": "", + "public": false, + "requests": [ + { + "id": "124203f4-6fde-c67a-c332-c2169f274227", + "headers": "authorization: vl:123456\nContent-Type: application/json\n", + "url": "127.0.0.10:100/posts/:id", + "preRequestScript": "", + "pathVariables": { + "id": "1439462753604" + }, + "method": "PUT", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439468997772, + "name": "127.0.0.10:100/posts/:id", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [], + "rawModeData": "{\n \"content\": \"Hamsters. Full lifecycle from birth to death.\"\n}" + }, + { + "id": "1a2ef65c-0abb-0221-f322-c53163f10dce", + "headers": "Content-Type: application/json\n", + "url": "127.0.0.10:100/register", + "preRequestScript": "", + "pathVariables": {}, + "method": "POST", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439371930549, + "name": "127.0.0.10:100/register", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "rawModeData": "{\n \"email\": \"am@dfg.com\",\n \"nick\": \"vl\",\n \"pwd\": \"123456\",\n \"repeatPwd\": \"123456\"\n}" + }, + { + "id": "25e93113-5298-1ad0-7c19-301e03088aad", + "headers": "authorization: vl:123456\n", + "url": "127.0.0.10:100/posts/:id", + "preRequestScript": "", + "pathVariables": { + "id": "1439225509193" + }, + "method": "GET", + "data": [], + "dataMode": "params", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439405728620, + "name": "127.0.0.10:100/posts/:id", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [] + }, + { + "id": "39354428-48ed-3696-8c84-87bce170a377", + "headers": "authorization: vl:123456\nContent-Type: application/json\n", + "url": "127.0.0.10:100/user/:id/followers", + "preRequestScript": "", + "pathVariables": { + "id": "1439225345875" + }, + "method": "GET", + "data": [], + "dataMode": "params", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439414341991, + "name": "127.0.0.10:100/user/:id/followers", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [] + }, + { + "id": "8ab80377-2d4c-3f9c-097e-99a4df147cdc", + "headers": "authorization: vl:123456\nContent-Type: application/json\n", + "url": "127.0.0.10:100/user/:id/following", + "preRequestScript": "", + "pathVariables": { + "id": "1439315897737" + }, + "method": "GET", + "data": [], + "dataMode": "params", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439457875184, + "name": "127.0.0.10:100/user/:id/following", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [] + }, + { + "id": "939d616a-0028-1bfd-34c1-78a1e9b1f13d", + "headers": "authorization: vl:123456\n", + "url": "127.0.0.10:100/user", + "preRequestScript": "", + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "params", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439318933936, + "name": "127.0.0.10:100/user", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [] + }, + { + "id": "a8d5f618-7cc2-eb10-8332-4c2786daa29f", + "headers": "authorization: vl:123456\n", + "url": "127.0.0.10:100/posts/:id", + "pathVariables": { + "id": "1439404599850" + }, + "preRequestScript": "", + "method": "DELETE", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "data": [], + "dataMode": "params", + "name": "127.0.0.10:100/posts/:id", + "description": "", + "descriptionFormat": "html", + "time": 1439461994243, + "version": 2, + "responses": [], + "tests": "", + "currentHelper": "normal", + "helperAttributes": {} + }, + { + "id": "bda1c237-b1cd-a984-1fa2-123f19c63c19", + "headers": "authorization: vl:123456\n", + "url": "127.0.0.10:100/user/:id/wall", + "preRequestScript": "", + "pathVariables": { + "id": "1439225345875" + }, + "method": "GET", + "data": [], + "dataMode": "params", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439413547495, + "name": "127.0.0.10:100/user/:id/wall", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [] + }, + { + "id": "bef8ea8b-fe43-d350-f253-0bcc1c53e0e9", + "headers": "authorization: vl:123456\n", + "url": "127.0.0.10:100/post", + "pathVariables": {}, + "preRequestScript": "", + "method": "GET", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "data": [], + "dataMode": "params", + "name": "127.0.0.10:100/post", + "description": "", + "descriptionFormat": "html", + "time": 1439405042038, + "version": 2, + "responses": [], + "tests": "", + "currentHelper": "normal", + "helperAttributes": {} + }, + { + "id": "c6e0d4c7-0e38-a69a-b615-28dba23268b9", + "headers": "authorization: vl:123456\nContent-Type: application/json\n", + "url": "127.0.0.10:100/user/:id/follow", + "preRequestScript": "", + "pathVariables": { + "id": "1439225345875" + }, + "method": "DELETE", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439413508410, + "name": "127.0.0.10:100/user/:id/follow", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [], + "rawModeData": "" + }, + { + "id": "c9a62701-3fe8-f06b-a18e-81289ba24f24", + "headers": "authorization: vl:123456\n", + "url": "127.0.0.10:100/user/:id", + "preRequestScript": "", + "pathVariables": { + "id": "1439222467622" + }, + "method": "GET", + "data": [], + "dataMode": "params", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439413561093, + "name": "127.0.0.10:100/user/:id", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [] + }, + { + "id": "e21a8734-8e8c-ad5a-3fe3-b53b12ed21b2", + "headers": "authorization: vl:333\n", + "url": "127.0.0.10:100/me", + "preRequestScript": "", + "pathVariables": {}, + "method": "GET", + "data": [], + "dataMode": "params", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439467598695, + "name": "127.0.0.10:100/me", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [] + }, + { + "id": "e9caca8e-1d55-1040-8392-7934708a38a4", + "headers": "authorization: vl:123456\nContent-Type: application/json\n", + "url": "127.0.0.10:100/user/:id/wall", + "preRequestScript": "", + "pathVariables": { + "id": "1439315897737" + }, + "method": "POST", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439462636334, + "name": "127.0.0.10:100/user/:id/wall", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [], + "rawModeData": "{" + }, + { + "id": "ee8239e4-7996-5261-0d21-c0d8f06c0b75", + "headers": "authorization: vl:123456\nContent-Type: application/json\n", + "url": "127.0.0.10:100/user/:id/follow", + "preRequestScript": "", + "pathVariables": { + "id": "1439225345875" + }, + "method": "POST", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439408388243, + "name": "127.0.0.10:100/user/:id/follow", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [], + "rawModeData": "" + }, + { + "id": "fbb2183d-5d75-2cf1-4f44-b395fdd43a7f", + "headers": "authorization: vl:123456\nContent-Type: application/json\n", + "url": "127.0.0.10:100/me", + "preRequestScript": "", + "pathVariables": {}, + "method": "PUT", + "data": [], + "dataMode": "raw", + "version": 2, + "tests": "", + "currentHelper": "normal", + "helperAttributes": {}, + "time": 1439468025878, + "name": "127.0.0.10:100/me", + "description": "", + "collectionId": "5e033b16-8151-c70f-c605-aae95c988855", + "responses": [], + "rawModeData": "{\n \"pwd\":\"123456\"\n}" + } + ] +} \ No newline at end of file diff --git a/app.js b/app.js index 41a2eb0..fbc8290 100644 --- a/app.js +++ b/app.js @@ -3,45 +3,69 @@ var bodyParser = require('body-parser'); GLOBAL._ = require('underscore'); var fs= require('fs') var app = express(); -GLOBAL.DB = { - save:function(){ - fs.writeFileSync('./db.json',JSON.stringify(this)) - }, - restore: function(){ - GLOBAL.DB = _.extend(GLOBAL.DB,JSON.parse(fs.readFileSync('./db.json','utf-8'))) - } -} -GLOBAL.DB.restore(); -DB.users = DB.users || []; -DB.posts = DB.posts || []; +var async = require('async') + +var MongoClient = require('mongodb').MongoClient +var ObjectID = require('mongodb').ObjectID; +var url = 'mongodb://127.0.0.10:27017/socialNetwork'; + +MongoClient.connect(url, function (err, db) { + GLOBAL.DB = db; + app.listen(100, '127.0.0.10'); +}) +//GLOBAL.DB = { +// save:function(){ +// fs.writeFileSync('./db.json', JSON.stringify(this)) +// }, +// restore: function(){ +// GLOBAL.DB = _.extend(GLOBAL.DB,JSON.parse(fs.readFileSync('./db.json','utf-8'))) +// } +//} +//GLOBAL.DB.restore(); +//DB.users = DB.users || []; +//DB.posts = DB.posts || []; +//DB.follow = DB.follow || []; app.use(bodyParser.json()) + app.use(function (req, res, next) { - console.log(req.originalUrl) + if(req.originalUrl =='/register'){ next(null); return; } if (!req.headers['authorization']) { - res.status(401).send({message: "No auth"}); + res.status(401).send({ message: "Authorization is required" }); return; } var parts = req.headers['authorization'].split(":") var nick = parts[0]; var pwd = parts[1]; - var user = _.find(DB.users, function (usr) { - return usr.nick == nick && pwd == usr.pwd; - }) - if (!user) { - res.status(401).send({message: "invalid user or password"}) - return; - } - req.currentUser =user; + + //var parts = req.headers['authorization'].split(" ") + //var nick = parts[1].split("=")[1]; + //var pwd = parts[5].split("=")[1]; + //console.log(req.headers['authorization']); + //console.log(nick); + //console.log(pwd); + + + DB.collection('users').find({ nick: nick, pwd: pwd }).toArray(function (err, data) { + if (data.lenght = 0) { + res.status(401).send({ message: "invalid user or password" }) + return; + } + }); + //var user = _.find(DB.users, function (usr) { + // return usr.nick == nick && pwd == usr.pwd; + //}) + + req.currentUser = data[0]; next(null); }) require('./controllers/user')(app) require('./controllers/post')(app) +require('./controllers/follow')(app) -app.listen(100) \ No newline at end of file diff --git a/controllers/follow.js b/controllers/follow.js new file mode 100644 index 0000000..f9d5f2c --- /dev/null +++ b/controllers/follow.js @@ -0,0 +1,93 @@ +module.exports = function (app) { + + app.post('/user/:id/follow',function(req,res){ + var user = _.clone(_.find(DB.users, function(usr){ + return usr.id === +req.params.id; + })); + if (!user) { + res.status(404).send({ message: "User not found" }) + return; + } + if (_.some(DB.follow, function(flw){return flw.follower.id === req.currentUser.id && flw.following.id === user.id})) { + res.status(422).send({ message: "You already are following this user" }); + return; + } + delete user.pwd; + delete user.email; + + var currentUser = _.clone(req.currentUser); + delete currentUser.pwd; + delete currentUser.email; + + var follow = { + follower: currentUser, + following: user + }; + DB.follow.push(follow); + DB.save(); + res.send(follow); + }) + + app.get('/user/:id/following', function (req, res) { + var user = _.findWhere(DB.users, { id: +req.params.id }); + if (!user) { + res.status(404).send({ message: "User not found" }) + return; + } + var list = _.filter(DB.follow, function (flw) { + return flw.follower.id == user.id; + }) + if (!list.length) { + res.status(422).send({ message: "This user does not follow anybody" }) + return; + } + var result = _.clone(_.map(list, function (item) { + return item.following; + })) + res.send(result); + }) + + app.get('/user/:id/followers', function (req, res) { + var user = _.findWhere(DB.users, { id: +req.params.id }); + if (!user) { + res.status(404).send({ message: "User not found" }) + return; + } + var list = _.filter(DB.follow, function (flw) { + return flw.following.id == user.id; + }) + if (!list.length) { + res.status(422).send({ message: "Nobody is following this user" }) + return; + } + var result = _.clone(_.map(list, function (item) { + return item.follower; + })) + res.send(result); + }) + + app.delete('/user/:id/follow', function (req, res) { + var user = _.clone(_.findWhere(DB.users, { id: +req.params.id })); + if (!user) { + res.status(404).send({ message: "User not found" }) + return; + } + var index = -1; + var found = _.some(DB.follow, function (item, i) { + var isFound = (item.follower.id == req.currentUser.id && item.following.id == req.params.id); + if (isFound) index = i; + return isFound; + }) + if (!found) { + res.status(422).send({ message: "You do not follow this user" }) + return; + } + + DB.follow.splice(index, 1); + DB.save(); + delete user.email; + delete user.pwd; + res.send({ message: "You are not following anymore:", "user": user }); + }) + +} \ No newline at end of file diff --git a/controllers/post.js b/controllers/post.js index 48c5b69..0a6bbf1 100644 --- a/controllers/post.js +++ b/controllers/post.js @@ -1,18 +1,84 @@ module.exports=function(app){ - app.post('/user/:id/wall',function(req,res){ + + app.get('/user/:id/wall', function (req, res) { + res.send(_.where(DB.posts, { ownerId: +req.params.id })); + }) + + app.post('/user/:id/wall', function (req, res) { if(!req.body.content){ res.status(400).send({message:'content required'}) return; } var post = { - content:req.body.content, - id:Date.now(), - authorId:req.currentUser.id, - ownerId:req.params.id + content: req.body.content, + authorId: { $ref: "users", _id:new ObjectID(req.currentUser.id)}, + ownerId: { $ref: "users", _id:new ObjectID(+req.params.id)} }; - DB.posts.push(post) - DB.save(); - res.send(post); + DB.collection('posts').insert(post, function (err, data) { + res.send(post); + }) }) + app.get('/post', function (req, res) { + res.send(DB.posts); + return; + }) + + app.get('/posts/:id', function (req, res) { + res.send(_.where(DB.posts, { id: +req.params.id })); + return; + }) + + app.put('/posts/:id', function (req, res) { + var index = -1; + var postFound; + var found = _.some(DB.posts, function (post, i) { + var isFound = (req.params.id == post.id); + if (isFound) { + index = i; + postFound = _.clone(post); + } + return isFound; + }) + if (!found) { + res.status(404).send({ message: "Post not found" }); + return; + } + if (postFound.authorId != req.currentUser.id) { + res.status(403).send({ message: "You cannot change this post" }); + return; + } + if (req.body.id || req.body.authorId || req.body.ownerId) { + res.status(403).send({ message: "You can change content only" }); + return; + } + postFound.content = req.body.content; + DB.posts[index] = postFound; + DB.save(); + res.send(postFound); + }) + + app.delete('/posts/:id', function (req, res) { + + var index = -1; + var found = _.some(DB.posts, function (item, i) { + var isFound = (item.id == req.params.id); + if (isFound) index = i; + return isFound; + }) + if (!found) { + res.status(404).send({ message: "Post not found" }); + return; + } + var post = _.clone(DB.posts[index]); + console.log(index, found, post); + if (req.currentUser.id != post.authorId && req.currentUser.id != post.ownerId) { + res.status(403).send({ message: "Privilege violation" }); + return; + } + + DB.posts.splice(index, 1); + DB.save(); + res.send({ message: "Following post has been deleted:", "post": post }) + }) } \ No newline at end of file diff --git a/controllers/user.js b/controllers/user.js index f543dd0..062be73 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -1,47 +1,76 @@ var uniqueId = Date.now(); + module.exports = function(app){ - app.get('/me',function(req,res){ - res.send(req.currentUser); - }) - app.get('/user', function (req, res) { - res.send(DB.users); - }) - app.get('/user/:id',function(req,res){ - var user = _.clone(_.find(DB.users,function(usr){ - return usr.id ==req.params.id; - })); - delete user.pwd; - if(!user){ - res.status(404).send({message:"not found"}) - return; - } - res.send(user) - }) - app.get('/user/:id/wall',function(req,res){ - res.send(_.where( DB.posts,{ownerId:req.params.id})); + app.post('/register', function (req, res) { + if (!req.body.email) { + res.status(400).send({ message: "Email is required" }) + return; + } else if (!req.body.nick) { + res.status(400).send({ message: "Nick is required" }) + return; + } else if (!req.body.pwd || !req.body.repeatPwd || req.body.pwd != req.body.repeatPwd) { + res.status(400).send({ message: "Passwords do not match" }) + return; + } else if (_.some(DB.users, function (usr) { return usr.nick == req.body.nick; })) { + res.status(400).send({ message: "User with this nick already exists" }); + return; + } else if (_.some(DB.users, function (usr) { return usr.email == req.body.email; })) { + res.status(400).send({ message: "User with this email already exists" }); + return; + } + var user = { + email: req.body.email, + nick: req.body.nick, + pwd: req.body.pwd, + id: uniqueId + }; + + DB.collection('users').insert(user, function (err, user) { + delete user.pwd; + res.send(user); + }) + }) + + app.put('/me', function (req, res) { + if (req.body.nick || req.body.id) { + res.status(403).send({ message: "You cannot change your Nick and ID" }); + return; + } + req.currentUser = { + email: req.body.email || req.currentUser.email, + nick: req.currentUser.nick, + pwd: req.body.pwd || req.currentUser.pwd, + }; + DB.collection('users').update({ nick: req.currentUser.nick }, req.currentUser, function (err, user) { + if (user.lenght = 0) { + res.status(401).send({ message: "Invalid user or password" }) + return; + } else { + delete user.pwd; + res.send(user); + } + }); + }) + + app.get('/me', function (req, res) { + res.send(req.currentUser); }) - app.post('/register', function (req, res) { - //проверить свободен ли ник и имейл - if (!req.body.email) { - res.status(400).send({message: "Email is required"}) - return; - } else if (!req.body.nick) { - res.status(400).send({message: "Nick is required"}) - return; - } else if (!req.body.pwd || !req.body.repeatPwd || req.body.pwd != req.body.repeatPwd) { - res.status(400).send({message: "Passwords do not match"}) - return; - } - var user = { - email: req.body.email, - nick: req.body.nick, - pwd: req.body.pwd, - id: ++uniqueId - }; - DB.users.push(_.clone(user)) - DB.save(); - delete user.pwd; - res.send(user) + app.get('/user', function (req, res) { + DB.collection('users').find({}).toArray(function (err, users) { + res.send(users); + }); + }) + + app.get('/user/:id', function (req, res) { + DB.collection('users').find({ _id: new ObjectID(req.params.id) }).toArray(function (err, user) { + if (user.lenght = 0) { + res.status(401).send({ message: "Invalid user or password" }) + return; + } else { + delete user.pwd; + res.send(user); + } + }); }) } \ No newline at end of file diff --git a/db.json b/db.json index d7084f4..42fdb44 100644 --- a/db.json +++ b/db.json @@ -1 +1 @@ -{"users":[{"email":"gg@gg.gg","nick":"second","pwd":"123","id":1439224467621},{"email":"gg@gg.gg","nick":"second","pwd":"123","id":1439224467622},{"email":"gg@gg.gg","nick":"gena","pwd":"123","id":1439225345875}],"posts":[{"content":"Hellofrom gena","id":1439225509193,"authorId":1439225345875,"ownerId":"1439224467621"}]} \ No newline at end of file +{"users":[{"email":"gg@gg.gg","nick":"gena","pwd":"123","id":1439225345875},{"email":"am@dfg.com","nick":"vl","pwd":"123456","id":1439315897737}],"posts":[{"content":"Hellofrom gena","id":1439225509193,"authorId":1439225345875,"ownerId":"1439224467621"},{"content":"Hamsters. Full lifecycle from birth to death.","id":1439462753604,"authorId":1439315897737,"ownerId":1439315897737}],"follow":[]} \ No newline at end of file diff --git a/package.json b/package.json index 0d8bcba..4825492 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,32 @@ { - "name": "application-name", + "name": "app.js", "version": "0.0.1", "dependencies": { "body-parser": "^1.13.3", "express": "^4.13.3", + "fs": "0.0.2", + "mongodb": "^2.0.41", "underscore": "^1.8.3" - } + }, + "description": "Отрефакторить /registration запрос:", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/potravniy/SocialNetworkServer.git" + }, + "keywords": [ + "Social", + "Network", + "Learning", + "Project" + ], + "author": "Gena Moroz", + "license": "ISC", + "bugs": { + "url": "https://github.com/potravniy/SocialNetworkServer/issues" + }, + "homepage": "https://github.com/potravniy/SocialNetworkServer#readme" } From 5e372c748a3a3a25b400b740b97e0650a86457ca Mon Sep 17 00:00:00 2001 From: potravniy Date: Wed, 26 Aug 2015 19:02:15 +0300 Subject: [PATCH 2/3] Completed with MongoDB --- app.js | 69 +++++++++--------- controllers/follow.js | 160 +++++++++++++++++++++--------------------- controllers/post.js | 122 +++++++++++++++++--------------- controllers/user.js | 81 ++++++++++++--------- package.json | 2 +- 5 files changed, 224 insertions(+), 210 deletions(-) diff --git a/app.js b/app.js index fbc8290..eca6887 100644 --- a/app.js +++ b/app.js @@ -1,37 +1,33 @@ var express = require('express'); var bodyParser = require('body-parser'); GLOBAL._ = require('underscore'); -var fs= require('fs') var app = express(); -var async = require('async') - -var MongoClient = require('mongodb').MongoClient -var ObjectID = require('mongodb').ObjectID; +var MongoClient = require('mongodb').MongoClient; +GLOBAL.ObjectID = require('mongodb').ObjectID; var url = 'mongodb://127.0.0.10:27017/socialNetwork'; MongoClient.connect(url, function (err, db) { GLOBAL.DB = db; + GLOBAL.UsersCollection = DB.collection('users'); + GLOBAL.PostsCollection = DB.collection('posts'); + GLOBAL.FollowCollection = DB.collection('follow'); + app.listen(100, '127.0.0.10'); + console.log("Connected to server correctly"); }) -//GLOBAL.DB = { -// save:function(){ -// fs.writeFileSync('./db.json', JSON.stringify(this)) -// }, -// restore: function(){ -// GLOBAL.DB = _.extend(GLOBAL.DB,JSON.parse(fs.readFileSync('./db.json','utf-8'))) -// } -//} -//GLOBAL.DB.restore(); -//DB.users = DB.users || []; -//DB.posts = DB.posts || []; -//DB.follow = DB.follow || []; +app.use(function (req, res, next) { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); + res.header('Access-Control-Allow-Headers', 'Content-Type'); + next(); +}); app.use(bodyParser.json()) app.use(function (req, res, next) { - if(req.originalUrl =='/register'){ + if (req.originalUrl == '/register') { next(null); return; } @@ -41,31 +37,32 @@ app.use(function (req, res, next) { } var parts = req.headers['authorization'].split(":") var nick = parts[0]; - var pwd = parts[1]; + var pwd = require('crypto').createHash('md5').update(parts[1]).digest('hex'); - //var parts = req.headers['authorization'].split(" ") - //var nick = parts[1].split("=")[1]; - //var pwd = parts[5].split("=")[1]; - //console.log(req.headers['authorization']); - //console.log(nick); - //console.log(pwd); - - - DB.collection('users').find({ nick: nick, pwd: pwd }).toArray(function (err, data) { - if (data.lenght = 0) { - res.status(401).send({ message: "invalid user or password" }) + UsersCollection.find({ nick: nick, pwd: pwd }).toArray(function (err, data) { + if (data.length==0) { + res.status(401).send({ message: "Invalid user or password" }); return; } + req.currentUser = data[0]; + next(null); }); - //var user = _.find(DB.users, function (usr) { - // return usr.nick == nick && pwd == usr.pwd; - //}) - - req.currentUser = data[0]; - next(null); }) require('./controllers/user')(app) require('./controllers/post')(app) require('./controllers/follow')(app) +//var fs= require('fs') +//GLOBAL.DB = { +// save:function(){ +// fs.writeFileSync('./db.json', JSON.stringify(this)) +// }, +// restore: function(){ +// GLOBAL.DB = _.extend(GLOBAL.DB,JSON.parse(fs.readFileSync('./db.json','utf-8'))) +// } +//} +//GLOBAL.DB.restore(); +//DB.users = DB.users || []; +//DB.posts = DB.posts || []; +//DB.follow = DB.follow || []; diff --git a/controllers/follow.js b/controllers/follow.js index f9d5f2c..f627490 100644 --- a/controllers/follow.js +++ b/controllers/follow.js @@ -1,93 +1,91 @@ -module.exports = function (app) { + +module.exports = function (app) { - app.post('/user/:id/follow',function(req,res){ - var user = _.clone(_.find(DB.users, function(usr){ - return usr.id === +req.params.id; - })); - if (!user) { - res.status(404).send({ message: "User not found" }) - return; - } - if (_.some(DB.follow, function(flw){return flw.follower.id === req.currentUser.id && flw.following.id === user.id})) { - res.status(422).send({ message: "You already are following this user" }); - return; - } - delete user.pwd; - delete user.email; - - var currentUser = _.clone(req.currentUser); - delete currentUser.pwd; - delete currentUser.email; - - var follow = { - follower: currentUser, - following: user - }; - DB.follow.push(follow); - DB.save(); - res.send(follow); + app.post('/user/:id/follow', function (req, res) { + UsersCollection.findOne({ _id: new ObjectID(req.params.id) }, + function (err, user) { + if (!user) { + res.status(404).send({ message: "Invalid user ID" }); + return; + } + var follow = { + follower: req.currentUser._id.toString(), + following: user._id.toString() + }; + FollowCollection.findOne(follow, function (err, flw) { + if (flw) { + res.status(403).send({ message: "You are following this user already" }); + return; + } + FollowCollection.insert(follow, function (err, data) { + res.send(data); + }) + }) + }); }) app.get('/user/:id/following', function (req, res) { - var user = _.findWhere(DB.users, { id: +req.params.id }); - if (!user) { - res.status(404).send({ message: "User not found" }) - return; - } - var list = _.filter(DB.follow, function (flw) { - return flw.follower.id == user.id; - }) - if (!list.length) { - res.status(422).send({ message: "This user does not follow anybody" }) - return; - } - var result = _.clone(_.map(list, function (item) { - return item.following; - })) - res.send(result); + UsersCollection.findOne({ _id: new ObjectID(req.params.id) }, + function (err, user) { + if (!user) { + res.status(404).send({ message: "Invalid user ID" }); + return; + } + FollowCollection.find({ follower: req.params.id.toString() }).toArray(function (err, flw) { + if (flw.length === 0) { + res.status(422).send({ message: "This user does not follow anybody" }); + return; + } + var result = flw.map(function(item){ + item = item.following; + return item; + }) + res.send(result); + }) + }); }) app.get('/user/:id/followers', function (req, res) { - var user = _.findWhere(DB.users, { id: +req.params.id }); - if (!user) { - res.status(404).send({ message: "User not found" }) - return; - } - var list = _.filter(DB.follow, function (flw) { - return flw.following.id == user.id; - }) - if (!list.length) { - res.status(422).send({ message: "Nobody is following this user" }) - return; - } - var result = _.clone(_.map(list, function (item) { - return item.follower; - })) - res.send(result); + UsersCollection.findOne({ _id: new ObjectID(req.params.id) }, + function (err, user) { + if (!user) { + res.status(404).send({ message: "Invalid user ID" }); + return; + } + FollowCollection.find({ following: req.params.id.toString() }).toArray(function (err, flw) { + if (flw.length === 0) { + res.status(422).send({ message: "Nobody is following this user" }); + return; + } + var result = flw.map(function (item) { + item = item.follower; + return item; + }) + res.send(result); + }) + }); }) app.delete('/user/:id/follow', function (req, res) { - var user = _.clone(_.findWhere(DB.users, { id: +req.params.id })); - if (!user) { - res.status(404).send({ message: "User not found" }) - return; - } - var index = -1; - var found = _.some(DB.follow, function (item, i) { - var isFound = (item.follower.id == req.currentUser.id && item.following.id == req.params.id); - if (isFound) index = i; - return isFound; - }) - if (!found) { - res.status(422).send({ message: "You do not follow this user" }) - return; - } - - DB.follow.splice(index, 1); - DB.save(); - delete user.email; - delete user.pwd; - res.send({ message: "You are not following anymore:", "user": user }); + UsersCollection.findOne({ _id: new ObjectID(req.params.id) }, + function (err, user) { + if (!user) { + res.status(404).send({ message: "Invalid user ID" }); + return; + } + var follow = { + follower: req.currentUser._id.toString(), + following: user._id.toString() + }; + FollowCollection.findOne(follow, function (err, flw) { + if (!flw) { + res.status(404).send({ message: "You are not following this user" }); + return; + } + FollowCollection.remove(flw, function (err, data) { + res.send(data); + }) + }) + }); }) - } \ No newline at end of file diff --git a/controllers/post.js b/controllers/post.js index 0a6bbf1..4217716 100644 --- a/controllers/post.js +++ b/controllers/post.js @@ -1,84 +1,92 @@ -module.exports=function(app){ + +module.exports = function (app) { app.get('/user/:id/wall', function (req, res) { - res.send(_.where(DB.posts, { ownerId: +req.params.id })); + PostsCollection.find({ ownerId: req.params.id.toString() }).toArray(function (err, posts) { + if (posts.length == 0) { + res.status(404).send({ message: "Not found" }); + return + } + res.send(posts); + }); }) app.post('/user/:id/wall', function (req, res) { if(!req.body.content){ - res.status(400).send({message:'content required'}) + res.status(400).send({message:'Content required'}) return; } + var post = { content: req.body.content, - authorId: { $ref: "users", _id:new ObjectID(req.currentUser.id)}, - ownerId: { $ref: "users", _id:new ObjectID(+req.params.id)} + authorId: req.currentUser._id.toString(), //{ $ref: "users", _id: new ObjectID(req.currentUser.id)}, + ownerId: req.params.id.toString() //{ $ref: "users", _id: new ObjectID(req.params.id)} }; - DB.collection('posts').insert(post, function (err, data) { - res.send(post); + console.log(post); + PostsCollection.insert(post, function (err, data) { + res.send(data); }) }) app.get('/post', function (req, res) { - res.send(DB.posts); - return; + PostsCollection.find({}).toArray(function (err, posts) { + if (posts.length == 0) { + res.status(404).send({ message: "Not found" }); + return; + } + res.send(posts); + }); }) app.get('/posts/:id', function (req, res) { - res.send(_.where(DB.posts, { id: +req.params.id })); - return; + PostsCollection.find({ _id: new ObjectID(req.params.id) }).toArray(function (err, posts) { + if (posts.length == 0) { + res.status(404).send({ message: "Not found" }); + return + } + res.send(posts[0]); + }); }) app.put('/posts/:id', function (req, res) { - var index = -1; - var postFound; - var found = _.some(DB.posts, function (post, i) { - var isFound = (req.params.id == post.id); - if (isFound) { - index = i; - postFound = _.clone(post); + PostsCollection.find({ _id: new ObjectID(req.params.id) }).toArray(function (err, posts) { + if (posts.length == 0) { + res.status(404).send({ message: "Post not found" }); + return; + } + if (posts[0].authorId != req.currentUser._id.toString()) { + res.status(403).send({ message: "Privilege violation" }); + return; } - return isFound; - }) - if (!found) { - res.status(404).send({ message: "Post not found" }); - return; - } - if (postFound.authorId != req.currentUser.id) { - res.status(403).send({ message: "You cannot change this post" }); - return; - } - if (req.body.id || req.body.authorId || req.body.ownerId) { - res.status(403).send({ message: "You can change content only" }); - return; - } - postFound.content = req.body.content; - DB.posts[index] = postFound; - DB.save(); - res.send(postFound); + if (req.body.id || req.body.authorId || req.body.ownerId) { + res.status(403).send({ message: "You can change content only" }); + return; + } + if (!req.body.content) { + res.status(404).send({ message: "New content not found" }); + return; + } + posts[0].content = req.body.content; + PostsCollection.update({ _id: new ObjectID(req.params.id) }, posts[0], function (err, answer) { + res.send(answer); + }); + }); }) app.delete('/posts/:id', function (req, res) { - - var index = -1; - var found = _.some(DB.posts, function (item, i) { - var isFound = (item.id == req.params.id); - if (isFound) index = i; - return isFound; - }) - if (!found) { - res.status(404).send({ message: "Post not found" }); - return; - } - var post = _.clone(DB.posts[index]); - console.log(index, found, post); - if (req.currentUser.id != post.authorId && req.currentUser.id != post.ownerId) { - res.status(403).send({ message: "Privilege violation" }); - return; - } - - DB.posts.splice(index, 1); - DB.save(); - res.send({ message: "Following post has been deleted:", "post": post }) + var currentUserID = req.currentUser._id.toString(); + PostsCollection.find({ _id: new ObjectID(req.params.id) }).toArray(function (err, posts) { + if (posts.length == 0) { + res.status(404).send({ message: "Post not found" }); + return; + } + if (posts[0].authorId != currentUserID && posts[0].ownerId != currentUserID) { + res.status(403).send({ message: "Privilege violation" }); + return; + } + PostsCollection.remove({ _id: new ObjectID(req.params.id) }, function (err, answer) { + res.send(answer); + }) + }); }) } \ No newline at end of file diff --git a/controllers/user.js b/controllers/user.js index 062be73..538989b 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -1,4 +1,3 @@ -var uniqueId = Date.now(); module.exports = function(app){ app.post('/register', function (req, res) { @@ -11,44 +10,53 @@ module.exports = function(app){ } else if (!req.body.pwd || !req.body.repeatPwd || req.body.pwd != req.body.repeatPwd) { res.status(400).send({ message: "Passwords do not match" }) return; - } else if (_.some(DB.users, function (usr) { return usr.nick == req.body.nick; })) { - res.status(400).send({ message: "User with this nick already exists" }); - return; - } else if (_.some(DB.users, function (usr) { return usr.email == req.body.email; })) { - res.status(400).send({ message: "User with this email already exists" }); - return; } - var user = { - email: req.body.email, - nick: req.body.nick, - pwd: req.body.pwd, - id: uniqueId - }; - DB.collection('users').insert(user, function (err, user) { - delete user.pwd; - res.send(user); - }) + UsersCollection.find({}).toArray(function (err, users) { + var emailExists = false; + var nickExists = false; + _.some(users, function (user) { + emailExists = (user.email == req.body.email); + nickExists = (user.nick == req.body.nick); + return emailExists || nickExists; + }); + + if (emailExists) { + res.status(400).send({ message: "User with this email already exists" }); + } else if (nickExists) { + res.status(400).send({ message: "User with this nick already exists" }); + } else { + var user = { + email: req.body.email, + nick: req.body.nick, + pwd: require('crypto').createHash('md5').update(req.body.pwd).digest('hex'), + }; + UsersCollection.insert(user, function (err, user) { + delete user.pwd; + res.send(user); + }) + } + }); }) app.put('/me', function (req, res) { if (req.body.nick || req.body.id) { - res.status(403).send({ message: "You cannot change your Nick and ID" }); + res.status(403).send({ message: "You cannot change your Nick and/or ID" }); return; } req.currentUser = { email: req.body.email || req.currentUser.email, nick: req.currentUser.nick, - pwd: req.body.pwd || req.currentUser.pwd, + pwd: req.body.pwd ? require('crypto').createHash('md5').update(req.body.pwd).digest('hex') : req.currentUser.pwd }; - DB.collection('users').update({ nick: req.currentUser.nick }, req.currentUser, function (err, user) { - if (user.lenght = 0) { - res.status(401).send({ message: "Invalid user or password" }) - return; - } else { - delete user.pwd; - res.send(user); - } + UsersCollection.update({ nick: req.currentUser.nick }, req.currentUser, function (err, user) { + UsersCollection.find({ nick: req.currentUser.nick }).toArray(function (err, data) { + if (data.length == 0) { + res.status(401).send({ message: "Invalid user" }); + return; + } + res.send(data[0]); + }); }); }) @@ -57,20 +65,23 @@ module.exports = function(app){ }) app.get('/user', function (req, res) { - DB.collection('users').find({}).toArray(function (err, users) { - res.send(users); + UsersCollection.find({}).toArray(function (err, users) { + res.send(users.map(function (user) { + delete user.pwd; + return user; + })); }); }) app.get('/user/:id', function (req, res) { - DB.collection('users').find({ _id: new ObjectID(req.params.id) }).toArray(function (err, user) { - if (user.lenght = 0) { - res.status(401).send({ message: "Invalid user or password" }) - return; - } else { + UsersCollection.findOne({ _id: new ObjectID(req.params.id) }, + function (err, user) { + if (!user) { + res.status(404).send({ message: "Invalid user ID" }); + return; + } delete user.pwd; res.send(user); - } }); }) } \ No newline at end of file diff --git a/package.json b/package.json index 4825492..5adb8ce 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "version": "0.0.1", "dependencies": { "body-parser": "^1.13.3", + "crypto": "0.0.3", "express": "^4.13.3", - "fs": "0.0.2", "mongodb": "^2.0.41", "underscore": "^1.8.3" }, From c5c7d3e4ce999fab92b639be52049cf25e9e25d1 Mon Sep 17 00:00:00 2001 From: potravniy Date: Wed, 26 Aug 2015 19:09:31 +0300 Subject: [PATCH 3/3] Completed with MongoDB --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0ffc93..762e530 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Отрефакторить /registration запрос: сделать проверки OK - хэшировать пароль + хэшировать пароль OK Сделать API для следующих запросов: