UNPKG

r-oauth2

Version:

A RethinkDB and Express implementation of OAuth2

198 lines (194 loc) 7.11 kB
var r, db, oauthTable, tokenTable, expiry, useBcrypt; var crypto = require('crypto-js'); var async = require('async'); var bcrypt = require('bcrypt'); process.env.BLUEBIRD_DEBUG = 0; module.exports = { init: function(config) { var rCfg = {}; if (config) { if (config.db) { db = config.db } else { db = "oauth2" }; if (config.oauthTable) { oauthTable = config.oauthTable } else { oauthTable = "users" }; if (config.tokenTable) { tokenTable = config.tokenTable } else { tokenTable = "token" }; if (config.expiry) { expiry = config.expiry} else { expiry = 360000 } if (config.r) { r = config.r } else { r = require('rethinkdbdash')() } if (config.bcrypt) { useBcrypt = config.bcrypt } else { useBcrypt = false } } else { db = "oauth2"; oauthTable = "users"; tokenTable = "token"; expiry = 360000; useBcrypt = false; r = require('rethinkdbdash')(); } }, generateClient: function(clientId, clientSecret, grantType) { return function(req,res,next) { var client = {}; var unique = false; async.whilst( function() { return unique == false; }, function(callback) { var random = Math.random().toString(); if (useBcrypt == true) { if (!req.body.clientSecret) { return res.status(400).send({ "msg": "Must supply a client secret." }) } client.clientId = req.body.clientId var random = Math.random().toString(); var salt = bcrypt.genSaltSync(10); var hash = bcrypt.hashSync(req.body.clientSecret, salt); client.clientSecret = hash; unique = true; callback(null, unique); } else { client.clientId = clientId || crypto.HmacSHA3('clientId', random).toString().substr(0,50); client.clientSecret = crypto.HmacSHA3('clientSecret', random).toString().substr(0,50); } r.db(db).table(oauthTable).filter(client).then(function(result) { console.log(result.length); if (result.length > 0) { unique = false; callback(null, unique) } else { unique = true; callback(null, unique) } }) }, function(err) { var grantType = req.body.grantType; client.grantType = grantType; r.db(db).table(oauthTable).insert(client).then(function() { res.send(client); }) } ) } }, generateToken: function() { return function(req,res,next) { var obj = req.body.client; r.db(db).table(oauthTable).filter({ 'clientId': obj.clientId }).then(function(result) { if (result.length > 0) { if (useBcrypt == true) { var validate = bcrypt.compareSync(obj.clientSecret, result[0].clientSecret); if (validate == false) { console.log("Test"); return res.status(403).send({ 'msg': 'Invalid permissions' }); } } else if (useBcrypt == false && obj.clientSecret != result[0].clientSecret && obj.grantType != result[0].grantType) { return res.status(403).send({ 'msg': 'Invalid permissions' }); } var session = {}; session.clientId = obj.clientId; session.grantType = obj.grantType; session.expiry = new Number(new Date()) + expiry; var unique = false; async.whilst( function() { return unique == false; }, function(callback) { var random = Math.random().toString(); session.accessToken = crypto.HmacSHA3('accessToken', random).toString().substr(0,30); var random = Math.random().toString(); session.refreshToken = crypto.HmacSHA3('refreshToken', random).toString().substr(0,30); r.db(db).table(tokenTable).filter({ 'accessToken': session.accessToken, 'refreshToken': session.refreshToken }).then(function(result) { if (result.length > 0) { unique = false; callback(null, unique) } else { unique = true; callback(null, unique) } }) }, function(err) { if (obj.store) { session.store = obj.store; } r.db(db).table(tokenTable).insert(session).then(function() { res.send({ 'accessToken': session.accessToken, 'refreshToken': session.refreshToken, 'expiry': session.expiry }); }) } ) } else { res.status(403).send({ 'msg': 'No document with that id found.' }) } }) } }, refreshToken: function() { return function(req,res,next) { var refreshToken = req.body.refreshToken; r.db(db).table(tokenTable).filter({ refreshToken: refreshToken }).then(function(result) { if (result.length > 0) { var session = result[0]; var random = Math.random().toString(); session.accessToken = crypto.HmacSHA3('accessToken', random).toString().substr(0,30); var random = Math.random().toString(); session.refreshToken = crypto.HmacSHA3('refreshToken', random).toString().substr(0,30); session.expiry = new Number(new Date()) + expiry; r.db(db).table(oauthTable).insert(session).then(function() { res.send({ 'accessToken': session.accessToken, 'refreshToken': session.refreshToken, 'expiry': session.expiry }) }) } else { res.send({ 'msg': 'Invalid refresh token.' }) } }); } }, authenticate: function() { return function(req,res,next) { var accessToken = req.headers.authorization || req.query.accessToken; if (!accessToken) { return res.status(403).send({ message: 'No token provided.' }) } if (accessToken.indexOf('Bearer') !== -1) { accessToken = accessToken.replace('Bearer ', ''); } r.db(db).table(tokenTable).filter({ accessToken: accessToken }).then(function(result) { if (result.length > 0) { var session = result[0]; var expiryDate = session.expiry; if (expiryDate > Number(new Date())) { if (session.store) { req.store = session.store } req.grantType = session.grantType; req.clientId = session.clientId; next(); } else { return res.status(403).send({ msg: 'Token expired.' }) } } else { return res.status(403).send({ msg: 'Resource Forbidden.' }) } }) } } }