diff --git a/app.js b/app.js index 1446be9d..c729fdc8 100644 --- a/app.js +++ b/app.js @@ -8,7 +8,8 @@ var passport = require("passport"); var dotenv = require("dotenv"); var session = require("express-session"); var mongoose = require("mongoose"); - +var task = require("./backend/task"); +var cron = require('node-cron'); dotenv.config({path: './.env'}); require('./util/passport')(passport); @@ -62,7 +63,6 @@ app.use("/deploy", require("./routes/deploy")); app.use("/dashboard", require("./routes/dashboard")); app.use("/ci", require("./routes/ci")); app.use("/repository", require("./routes/repository")); - /** * Server-side Event Handling */ @@ -92,6 +92,13 @@ io.on('connection', function(socket){ }) }); + +// Tasks runs on every 24 hrs + +cron.schedule('* 23 * * *', function(){ + task.checkExpiredToken(); +}); + // catch 404 and forward to error handler app.use(function(req, res, next) { res.status(404); diff --git a/backend/github.js b/backend/github.js index 3ce7d9d8..0acb3461 100644 --- a/backend/github.js +++ b/backend/github.js @@ -96,3 +96,25 @@ exports.deleteHook = function (name, hook, accessToken, callback) { } }); }; + +/** + * Get user details by access token + * @param accessToken: Access Token of the user + * @param callback: callback + */ + +exports.retriveUser = function (accessToken, callback) { + request({ + url: 'https://api.github.com/users/', + headers: { + 'User-Agent': 'Yaydoc', + 'Authorization': 'token ' + crypter.decrypt(accessToken) + } + }, function (error, response, body) { + if (response.status !== 200) { + callback({statusCode: response.status}, null) + } else { + callback(error, JSON.parse(body)) + } + }) +}; diff --git a/backend/mailer.js b/backend/mailer.js index 8be0c5ec..036273e2 100644 --- a/backend/mailer.js +++ b/backend/mailer.js @@ -77,3 +77,24 @@ exports.sendMailOnBuild = function (buildStatus, email, repository) { } }); }; + +exports.sendMailOnTokenFailure = function (email) { + var client = nodemailer.createTransport(sgTransport(options)); + + var textContent = 'Access token for Yaydoc is expired. Sign in once again to continue the service'; + var htmlContent = 'Access token for Yaydoc is expired. Sign in once again to continue the service'; + + client.sendMail({ + from: 'info@yaydoc.com', + to: email, + subject: 'Token expired - Yaydoc', + text: textContent, + html: htmlContent + }, function (error, info) { + if (error) { + console.log(error); + } else { + console.log('Message sent: ' + info.response); + } + }); +}; diff --git a/backend/queue.js b/backend/queue.js new file mode 100644 index 00000000..c0a7e817 --- /dev/null +++ b/backend/queue.js @@ -0,0 +1,27 @@ +const github = require("./github.js"); +const mailer = require("./mailer"); +const async = require("async"); +User = require("../model/user"); +var tokenRevokedQueue = async.queue(function (user, done) { + github.retriveUser(user.token, function (error, userData) { + if (error) { + if (user.expired === false) { + mailer.sendMailOnTokenFailure(user.email); + User.updateUserById(user.id, { + expired: true + }, function(error, data) { + if (error) { + console.log(error); + } + }); + } + done(); + } else { + done(); + } + }) +}, 2); + +exports.addTokenRevokedJob = function(user) { + tokenRevokedQueue.push(user); +}; diff --git a/backend/task.js b/backend/task.js new file mode 100644 index 00000000..d156c7c2 --- /dev/null +++ b/backend/task.js @@ -0,0 +1,34 @@ +const github = require("./github") +const queue = require("./queue") + +User = require("../model/user"); + +exports.checkExpiredToken = function () { + User.count(function (error, count) { + if (error) { + console.log(error); + } else { + var page = 0; + if (count < 10) { + page = 1; + } else { + page = count / 10; + if (page * 10 < count) { + page = (count + 10) /10; + } + } + for (var i = 0; i <= page; i++) { + User.paginateUsers(i, 10, + function (error, users) { + if (error) { + console.log(error); + } else { + users.forEach(function(user) { + queue.addTokenRevokedJob(user); + }) + } + }) + } + } + }) +} diff --git a/model/user.js b/model/user.js index 3bd78f9b..91d6a101 100644 --- a/model/user.js +++ b/model/user.js @@ -5,7 +5,8 @@ const userSchema = mongoose.Schema({ token: String, email: String, name: String, - username: String + username: String, + expired: Boolean }); const User = module.exports = mongoose.model('User', userSchema); @@ -27,3 +28,36 @@ module.exports.getUserById = function(id, callback) { module.exports.getUserByUsername = function(username, callback) { User.findOne({username: username}, callback); }; + +/** + * Count the number of repository + */ + +module.exports.countUsers = function (callback) { + User.count({}, callback); +}; + +/** + * paginates repositories + * @param page: n'th page + * @param limit: limit for number of repository to return + */ + +module.exports.paginateUsers = function (page, limit, callback) { + var skip = 0; + if (page > 1) { + skip = page * limit; + } + User.find({}).skip(skip).limit(limit).exec(callback); +}; + +/** + * Update the user by Github's Users id + * @param id: Github's user id + * @param update: user update + */ +module.exports.updateUserById = function(id, update, callback) { + User.update({id: id}, update, function(error, data) { + callback(error, data); + }); +}; diff --git a/package.json b/package.json index 4e388a29..9d056c7e 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "mocha": "^3.4.2", "mongoose": "^4.11.0", "morgan": "~1.8.1", + "node-cron": "^1.2.0", "nodemailer": "^4.0.1", "nodemailer-sendgrid-transport": "^0.2.0", "passport": "^0.3.2", diff --git a/util/passport.js b/util/passport.js index 17d6ecb8..993acd80 100644 --- a/util/passport.js +++ b/util/passport.js @@ -26,7 +26,14 @@ module.exports = function (passport) { return done(error); } if (user) { - + User.updateUserById(profile.id, { + expired: false, + token: crypter.encrypt(accessToken) + }, function(error, data) { + if (error) { + console.log(error); + } + }); return done(null, user); } else { let newUser = new User(); @@ -35,6 +42,7 @@ module.exports = function (passport) { newUser.name = profile.displayName; newUser.email = profile.emails[0].value; newUser.username = profile.username; + newUser.expired = false; newUser.save(function (error) { if (error) { @@ -56,5 +64,4 @@ module.exports = function (passport) { cb(null, profile); } )); - };