From 0b4ac6391d6bd764b9b7927685f89aec12c28995 Mon Sep 17 00:00:00 2001 From: Paolo Arena Date: Wed, 13 Feb 2019 18:47:58 +0100 Subject: [PATCH] fix: WebPush Notification --- server/middleware/authenticate.js | 3 +- server/models/user.js | 16 ++++++ server/router/subscribe_router.js | 8 ++- server/router/todos_router.js | 32 ++++++------ server/router/users_router.js | 86 +++++++++++++------------------ server/server.js | 1 + server/tests/server.test.js | 51 +++++++++++------- server/tools/general.js | 6 ++- 8 files changed, 115 insertions(+), 88 deletions(-) diff --git a/server/middleware/authenticate.js b/server/middleware/authenticate.js index 48f2248..d48f1f2 100644 --- a/server/middleware/authenticate.js +++ b/server/middleware/authenticate.js @@ -13,7 +13,8 @@ var authenticate = (req, res, next) => { User.findByToken(token, access).then((user) => { if (!user) { - tools.mylog("TOKEN " + token + " NOT FOUND! (Maybe Connected to other Page) ACCESS: '" + access + "'"); + tools.mylog("TOKEN " + token); + tools.mylog(" NOT FOUND! (Maybe Connected to other Page) ACCESS: '" + access + "'"); return Promise.reject(server_constants.RIS_CODE_HTTP_INVALID_TOKEN); // res.status().send(); } diff --git a/server/models/user.js b/server/models/user.js index f8c6c04..8bab6fa 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -127,6 +127,22 @@ UserSchema.statics.findByToken = function (token, typeaccess) { }); }; +UserSchema.statics.findByTokenAnyAccess = function (token) { + var User = this; + var decoded; + + try { + decoded = jwt.verify(token, process.env.SIGNCODE); + } catch (e) { + return Promise.resolve(null); + } + + return User.findOne({ + '_id': decoded._id, + 'tokens.token': token, + }); +}; + UserSchema.statics.findByCredentials = function (username, password) { var User = this; var pwd = ""; diff --git a/server/router/subscribe_router.js b/server/router/subscribe_router.js index 1aebca3..55767b9 100644 --- a/server/router/subscribe_router.js +++ b/server/router/subscribe_router.js @@ -4,6 +4,8 @@ const mongoose = require('mongoose'); const Subscription = mongoose.model('subscribers'); const webpush = require('web-push'); +const tools = require('../tools/general'); + var { authenticate } = require('../middleware/authenticate'); const isValidSaveRequest = (req, res) => { @@ -47,8 +49,12 @@ router.post('/', (req, res) => { }) .then(myitem => { - if (myitem === null) + if (myitem === null) { myitem = subscriptionModel; + tools.mylogshow('Subscription NOT EXISTED IN DB, so I use this created!', myitem) + }else + tools.mylogshow('Subscription already Existed!', myitem) + myitem.save((err, subscription) => { if (err) { diff --git a/server/router/todos_router.js b/server/router/todos_router.js index d2d28b1..e79bb00 100644 --- a/server/router/todos_router.js +++ b/server/router/todos_router.js @@ -25,7 +25,6 @@ const _ = require('lodash'); const { ObjectID } = require('mongodb'); - router.post('/', authenticate, (req, res) => { var body = _.pick(req.body, tools.allfieldTodoWithId()); @@ -36,7 +35,7 @@ router.post('/', authenticate, (req, res) => { tools.mylog('ID :', todo._id, todo.descr, todo.userId, req.user._id); - if (!('descr' in req.body)){ + if (!('descr' in req.body)) { return res.status(400).send({ code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC }); } @@ -58,14 +57,15 @@ router.post('/', authenticate, (req, res) => { Todo.findById(idobj) .then(record => { tools.mylog('REC SAVED :', record.descr); - res.send({record}); - - try { - sendNotificationToUser(todo.userId, 'Todo: ' + record.descr, record.descr, '/' + todo.category, 'todo'); - } catch (e) { - - } + sendNotificationToUser(todo.userId, 'Todo: ' + record.descr, record.descr, '/todo/' + todo.category, 'todo') + .then(ris => { + if (ris) { + res.send({ record }); + } else { + // already sent the error on calling sendNotificationToUser + } + }) }) }).catch((e) => { console.log('ERRORE in TODO POST', e.message); @@ -81,19 +81,20 @@ function sendNotificationToUser(userId, title, content, openUrl, tag) { message: content, url: openUrl, tag, - // ttl: req.body.ttl, + // ttl: req.body.ttl, // icon: req.body.icon, // image: req.body.image, // badge: req.body.badge, // tag: req.body.tag }; - Subscription.find({ userId }, (err, subscriptions) => { + return Subscription.find({ userId }, (err, subscriptions) => { if (err) { console.error(`Error occurred while getting subscriptions`); res.status(500).json({ error: 'Technical error occurred' }); + return false; } else { let parallelSubscriptionCalls = subscriptions.map((subscription) => { return new Promise((resolve, reject) => { @@ -147,6 +148,7 @@ function sendNotificationToUser(userId, title, content, openUrl, tag) { // res.json({ // data: 'Push triggered' // }); + return true; } }); @@ -164,7 +166,7 @@ router.patch('/:id', authenticate, (req, res) => { } - Todo.findByIdAndUpdate(id, {$set: body}, {new: true}).then((todo) => { + Todo.findByIdAndUpdate(id, { $set: body }, { new: true }).then((todo) => { tools.mylogshow(' TODO TO MODIFY: ', todo.descr, todo.expiring_at); if (!todo) { return res.status(404).send(); @@ -179,14 +181,14 @@ router.patch('/:id', authenticate, (req, res) => { tools.mylog('PATCH ', todo.descr, todo._id); - res.send({todo}); + res.send({ todo }); }).catch((e) => { + tools.mylogserr('Error patch TODO: ', e); res.status(400).send(); }) }); - router.get('/:userId', authenticate, (req, res) => { var userId = req.params.userId; @@ -228,7 +230,7 @@ router.delete('/:id', authenticate, (req, res) => { tools.mylog('DELETED ', todo.descr, todo._id); - res.send({todo}); + res.send({ todo }); }).catch((e) => { res.status(400).send(); }); diff --git a/server/router/users_router.js b/server/router/users_router.js index da4c453..8bc404f 100644 --- a/server/router/users_router.js +++ b/server/router/users_router.js @@ -88,7 +88,7 @@ router.get('/:username', (req, res) => { router.post('/login', (req, res) => { var body = _.pick(req.body, ['username', 'password', 'idapp', 'keyappid', 'lang']); var user = new User(body); - const subs = _.pick(req.body, ['subs']); + // const subs = _.pick(req.body, ['subs']); tools.mylog("LOGIN: username: " + user.username + " pwd = " + user.password); @@ -97,6 +97,7 @@ router.post('/login', (req, res) => { if (body.keyappid !== process.env.KEY_APP_ID) return res.status(400).send(); + let resalreadysent = false; User.findByCredentials(user.username, user.password) .then((user) => { @@ -108,70 +109,53 @@ router.post('/login', (req, res) => { return user }) .then(user => { - return user.generateAuthToken(req).then((token) => { - var usertosend = User(); - usertosend.username = user.username; - usertosend.email = user.email; - usertosend.userId = user._id.toHexString(); - usertosend.verified_email = user.verified_email; + if (user) { + return user.generateAuthToken(req).then((token) => { + var usertosend = User(); + usertosend.username = user.username; + usertosend.email = user.email; + usertosend.userId = user._id.toHexString(); + usertosend.verified_email = user.verified_email; - // tools.mylog("user.verified_email:" + user.verified_email); - tools.mylog("usertosend.userId", usertosend.userId); + // tools.mylog("user.verified_email:" + user.verified_email); + tools.mylog("usertosend.userId", usertosend.userId); - // tools.mylog("usertosend:"); - // tools.mylog(usertosend); - return { usertosend, token } - }) - .then((myris) => { - const useragent = req.get('User-Agent'); - const access = 'auth ' + useragent; - // if (usertosend.tokens.length > 0) - // access = usertosend.tokens[usertosend.tokens.length - 1].access; - return existSubScribe(myris.usertosend.userId, access).then(subscribe => { - let subscriptionModel = null; - if (subscribe === null) { - // Doesn't exist, so save sub passed in INPUT - subscriptionModel = new Subscription(subs); - subscriptionModel.userId = myris.usertosend.userId; - subscriptionModel.access = access; + // tools.mylog("usertosend:"); + // tools.mylog(usertosend); + return { usertosend, token } - } - return {usertosend: myris.usertosend, token: myris.token, subscriptionModel } - }).then(myris => { - if (myris.subscriptionModel !== null) { - return myris.subscriptionModel.save().then((err, subscription) => { - if (err) { - console.error(`Error occurred while saving subscription. Err: ${err}`); - res.status(500).json({ - error: 'Technical error occurred:' + err - }); - } else { - // Send 201 - resource created - // res.status(201).json({ data: 'Subscription saved.' }); - // res.send({ data: 'Subscription saved.' }); - - tools.sendBackNotif(subscription, req.body.options) - } - return { usertosend: myris.usertosend, token: myris.token } - }); - } else { - return { usertosend: myris.usertosend, token: myris.token } - } - }).catch(e => { - console.log('Err subscribing:', e); }) + .then((myris) => { + const useragent = req.get('User-Agent'); + const access = 'auth ' + useragent; + + // Check if already exist Subscribe + return existSubScribe(myris.usertosend.userId, access).then(subscribe => { + return (subscribe !== null) + }).then(subsExistonDb => { + return { usertosend: myris.usertosend, token: myris.token, subsExistonDb } + }).catch(err => { + return { usertosend: myris.usertosend, token: myris.token, subsExistonDb:false } + }) }).then(myris => { console.log('res', myris.token, myris.usertosend); - res.header('x-auth', myris.token).send({ usertosend: myris.usertosend, code: server_constants.RIS_CODE_OK }); + // SEND TOKEN AND CODE RESULT + res.header('x-auth', myris.token).send({ + usertosend: myris.usertosend, + code: server_constants.RIS_CODE_OK, + subsExistonDb: myris.subsExistonDb + }); // tools.mylog("TROVATOOO!"); tools.mylog('FINE LOGIN') }); + } }) .catch((e) => { tools.mylog("ERRORE IN LOGIN: " + e); - res.status(400).send({ code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC }); + if (!resalreadysent) + res.status(400).send({ code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC }); }); }); diff --git a/server/server.js b/server/server.js index be45e5a..7bed679 100644 --- a/server/server.js +++ b/server/server.js @@ -26,6 +26,7 @@ require('./models/todo'); require('./models/user'); require('./models/subscribers'); + const index_router = require('./router/index_router'); const push_router = require('./router/push_router'); const subscribe_router = require('./router/subscribe_router'); diff --git a/server/tests/server.test.js b/server/tests/server.test.js index 83f806c..4e8fc3e 100644 --- a/server/tests/server.test.js +++ b/server/tests/server.test.js @@ -36,28 +36,41 @@ const IndexTodoToCreate = 3; // const useragent = "auth Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36"; const useragent = "node-superagent/2.3.0"; -const testsingolo = false; +const testsingolo = true; if (testsingolo) { - it('should create a new Todos', (done) => { - request(app) - .post('/todos') - .set('x-auth', users[0].tokens[0].token) - .send(todos[IndexTodoToCreate]) - .expect(200) - .end((err, res) => { - if (err) { - return done(err); - } + describe('POST /users/login', () => { + it('should login user and return auth token', (done) => { + request(app) + .post('/users/login') + // .set('x-auth', users[0].tokens[0].token) + .send({ + username: users[0].username, + password: mypwdchiaro, + idapp: users[0].idapp, + keyappid: users[0].keyappid, + lang: users[0].lang, + subs: null, + }) + .expect(200) + .expect((res) => { + expect(res.headers['x-auth']).toExist(); + }) + .end((err, res) => { + if (err) { + return done(err); + } - Todo.find({ descr: todos[IndexTodoToCreate].descr }).then((arr_todos) => { - expect(arr_todos.length).toBe(1); - expect(arr_todos[0].descr).toBe(todos[IndexTodoToCreate].descr); - expect(String(arr_todos[0]._id)).toBe(String(todos[IndexTodoToCreate]._id)); - expect(String(arr_todos[0].userId)).toBe(String(users[0]._id)); - done(); - }).catch((e) => done(e)); - }); + User.findById(users[0]._id).then((user) => { + expect(user.tokens[0]).toInclude({ + access: 'auth ' + useragent, + // token: res.headers['x-auth'], + date_login: date_login + }); + done(); + }).catch((e) => done(e)); + }); + }); }); } else { diff --git a/server/tools/general.js b/server/tools/general.js index fe8356c..dfbfc64 100644 --- a/server/tools/general.js +++ b/server/tools/general.js @@ -28,6 +28,10 @@ module.exports = { console.log(args) }, + mylogserr: function (...args) { + console.error(args) + }, + allfieldTodo: function () { return ['userId', 'pos', 'category', 'descr', 'priority', 'completed', 'created_at', 'modify_at', 'completed_at', 'expiring_at', 'enableExpiring', 'id_prev', 'id_next', 'progress', 'modified'] @@ -39,7 +43,7 @@ module.exports = { sendBackNotif: function (subscription, payload) { - // console.log('sendBackNotif:', subscription, payload); + console.log('sendBackNotif:', subscription, payload); // Pass object into sendNotification webpush.sendNotification(subscription, JSON.stringify(payload)).catch(err => console.error(err));