refactor(app.js, auth.js): Extract all auth method to individual modules

This commit is contained in:
BoHong Li 2017-04-12 05:41:14 +08:00 committed by Raccoon Li
parent 766022378a
commit 69a9f7ca38
12 changed files with 406 additions and 351 deletions

View file

@ -0,0 +1,29 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const DropboxStrategy = require('passport-dropbox-oauth2').Strategy
const config = require('../../../config')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')
let dropboxAuth = module.exports = Router()
passport.use(new DropboxStrategy({
apiVersion: '2',
clientID: config.dropbox.clientID,
clientSecret: config.dropbox.clientSecret,
callbackURL: config.serverurl + '/auth/dropbox/callback'
}, passportGeneralCallback))
dropboxAuth.get('/auth/dropbox', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('dropbox-oauth2')(req, res, next)
})
// dropbox auth callback
dropboxAuth.get('/auth/dropbox/callback',
passport.authenticate('dropbox-oauth2', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)

View file

@ -0,0 +1,74 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const validator = require('validator')
const LocalStrategy = require('passport-local').Strategy
const config = require('../../../config')
const models = require('../../../models')
const logger = require('../../../logger')
const {setReturnToFromReferer} = require('../utils')
const {urlencodedParser} = require('../../utils')
const response = require('../../../response')
let emailAuth = module.exports = Router()
passport.use(new LocalStrategy({
usernameField: 'email'
}, function (email, password, done) {
if (!validator.isEmail(email)) return done(null, false)
models.User.findOne({
where: {
email: email
}
}).then(function (user) {
if (!user) return done(null, false)
if (!user.verifyPassword(password)) return done(null, false)
return done(null, user)
}).catch(function (err) {
logger.error(err)
return done(err)
})
}))
if (config.allowemailregister) {
emailAuth.post('/register', urlencodedParser, function (req, res, next) {
if (!req.body.email || !req.body.password) return response.errorBadRequest(res)
if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res)
models.User.findOrCreate({
where: {
email: req.body.email
},
defaults: {
password: req.body.password
}
}).spread(function (user, created) {
if (user) {
if (created) {
logger.debug('user registered: ' + user.id)
req.flash('info', "You've successfully registered, please signin.")
} else {
logger.debug('user found: ' + user.id)
req.flash('error', 'This email has been used, please try another one.')
}
return res.redirect(config.serverurl + '/')
}
req.flash('error', 'Failed to register your account, please try again.')
return res.redirect(config.serverurl + '/')
}).catch(function (err) {
logger.error('auth callback failed: ' + err)
return response.errorInternalError(res)
})
})
}
emailAuth.post('/login', urlencodedParser, function (req, res, next) {
if (!req.body.email || !req.body.password) return response.errorBadRequest(res)
if (!validator.isEmail(req.body.email)) return response.errorBadRequest(res)
setReturnToFromReferer(req)
passport.authenticate('local', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/',
failureFlash: 'Invalid email or password.'
})(req, res, next)
})

View file

@ -0,0 +1,29 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const FacebookStrategy = require('passport-facebook').Strategy
const config = require('../../../config')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')
let facebookAuth = module.exports = Router()
passport.use(new FacebookStrategy({
clientID: config.facebook.clientID,
clientSecret: config.facebook.clientSecret,
callbackURL: config.serverurl + '/auth/facebook/callback'
}, passportGeneralCallback))
facebookAuth.get('/auth/facebook', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('facebook')(req, res, next)
})
// facebook auth callback
facebookAuth.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)

View file

@ -0,0 +1,28 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const GithubStrategy = require('passport-github').Strategy
const config = require('../../../config')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')
let githubAuth = module.exports = Router()
passport.use(new GithubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: config.serverurl + '/auth/github/callback'
}, passportGeneralCallback))
githubAuth.get('/auth/github', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('github')(req, res, next)
})
// github auth callback
githubAuth.get('/auth/github/callback',
passport.authenticate('github', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)

View file

@ -0,0 +1,36 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const GitlabStrategy = require('passport-gitlab2').Strategy
const config = require('../../../config')
const response = require('../../../response')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')
let gitlabAuth = module.exports = Router()
passport.use(new GitlabStrategy({
baseURL: config.gitlab.baseURL,
clientID: config.gitlab.clientID,
clientSecret: config.gitlab.clientSecret,
scope: config.gitlab.scope,
callbackURL: config.serverurl + '/auth/gitlab/callback'
}, passportGeneralCallback))
gitlabAuth.get('/auth/gitlab', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('gitlab')(req, res, next)
})
// gitlab auth callback
gitlabAuth.get('/auth/gitlab/callback',
passport.authenticate('gitlab', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)
if (!config.gitlab.scope || config.gitlab.scope === 'api') {
// gitlab callback actions
gitlabAuth.get('/auth/gitlab/callback/:noteId/:action', response.gitlabActions)
}

View file

@ -0,0 +1,27 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
var GoogleStrategy = require('passport-google-oauth20').Strategy
const config = require('../../../config')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')
let facebookAuth = module.exports = Router()
passport.use(new GoogleStrategy({
clientID: config.google.clientID,
clientSecret: config.google.clientSecret,
callbackURL: config.serverurl + '/auth/google/callback'
}, passportGeneralCallback))
facebookAuth.get('/auth/google', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('google', { scope: ['profile'] })(req, res, next)
})
// google auth callback
facebookAuth.get('/auth/google/callback',
passport.authenticate('google', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)

26
lib/web/auth/index.js Normal file
View file

@ -0,0 +1,26 @@
'use strict'
const Router = require('express').Router
const config = require('../../config')
const logger = require('../../logger')
const authRouter = module.exports = Router()
if (config.facebook) authRouter.use('/', require('./facebook'))
if (config.twitter) authRouter.use('/', require('./twitter'))
if (config.github) authRouter.use('/', require('./github'))
if (config.gitlab) authRouter.use('/', require('./gitlab'))
if (config.dropbox) authRouter.use('/', require('./dropbox'))
if (config.google) authRouter.use('/', require('./google'))
if (config.ldap) authRouter.use('/', require('./ldap'))
if (config.email) authRouter.use('/', require('./email'))
// logout
authRouter.get('/logout', function (req, res) {
if (config.debug && req.isAuthenticated()) {
logger.debug('user logout: ' + req.user.id)
}
req.logout()
res.redirect(config.serverurl + '/')
})

View file

@ -0,0 +1,74 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const LDAPStrategy = require('passport-ldapauth')
const config = require('../../../config')
const models = require('../../../models')
const logger = require('../../../logger')
const {setReturnToFromReferer} = require('../utils')
const {urlencodedParser} = require('../../utils')
const response = require('../../../response')
let ldapAuth = module.exports = Router()
passport.use(new LDAPStrategy({
server: {
url: config.ldap.url || null,
bindDn: config.ldap.bindDn || null,
bindCredentials: config.ldap.bindCredentials || null,
searchBase: config.ldap.searchBase || null,
searchFilter: config.ldap.searchFilter || null,
searchAttributes: config.ldap.searchAttributes || null,
tlsOptions: config.ldap.tlsOptions || null
}
}, function (user, done) {
var profile = {
id: 'LDAP-' + user.uidNumber,
username: user.uid,
displayName: user.displayName,
emails: user.mail ? [user.mail] : [],
avatarUrl: null,
profileUrl: null,
provider: 'ldap'
}
var stringifiedProfile = JSON.stringify(profile)
models.User.findOrCreate({
where: {
profileid: profile.id.toString()
},
defaults: {
profile: stringifiedProfile
}
}).spread(function (user, created) {
if (user) {
var needSave = false
if (user.profile !== stringifiedProfile) {
user.profile = stringifiedProfile
needSave = true
}
if (needSave) {
user.save().then(function () {
if (config.debug) { logger.debug('user login: ' + user.id) }
return done(null, user)
})
} else {
if (config.debug) { logger.debug('user login: ' + user.id) }
return done(null, user)
}
}
}).catch(function (err) {
logger.error('ldap auth failed: ' + err)
return done(err, null)
})
}))
ldapAuth.post('/auth/ldap', urlencodedParser, function (req, res, next) {
if (!req.body.username || !req.body.password) return response.errorBadRequest(res)
setReturnToFromReferer(req)
passport.authenticate('ldapauth', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/',
failureFlash: true
})(req, res, next)
})

View file

@ -0,0 +1,29 @@
'use strict'
const Router = require('express').Router
const passport = require('passport')
const TwitterStrategy = require('passport-twitter').Strategy
const config = require('../../../config')
const {setReturnToFromReferer, passportGeneralCallback} = require('../utils')
let twitterAuth = module.exports = Router()
passport.use(new TwitterStrategy({
consumerKey: config.twitter.consumerKey,
consumerSecret: config.twitter.consumerSecret,
callbackURL: config.serverurl + '/auth/twitter/callback'
}, passportGeneralCallback))
twitterAuth.get('/auth/twitter', function (req, res, next) {
setReturnToFromReferer(req)
passport.authenticate('twitter')(req, res, next)
})
// twitter auth callback
twitterAuth.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successReturnToOrRedirect: config.serverurl + '/',
failureRedirect: config.serverurl + '/'
})
)

53
lib/web/auth/utils.js Normal file
View file

@ -0,0 +1,53 @@
'use strict'
const models = require('../../models')
const config = require('../../config')
const logger = require('../../logger')
exports.setReturnToFromReferer = function setReturnToFromReferer (req) {
var referer = req.get('referer')
if (!req.session) req.session = {}
req.session.returnTo = referer
}
exports.passportGeneralCallback = function callback (accessToken, refreshToken, profile, done) {
var stringifiedProfile = JSON.stringify(profile)
models.User.findOrCreate({
where: {
profileid: profile.id.toString()
},
defaults: {
profile: stringifiedProfile,
accessToken: accessToken,
refreshToken: refreshToken
}
}).spread(function (user, created) {
if (user) {
var needSave = false
if (user.profile !== stringifiedProfile) {
user.profile = stringifiedProfile
needSave = true
}
if (user.accessToken !== accessToken) {
user.accessToken = accessToken
needSave = true
}
if (user.refreshToken !== refreshToken) {
user.refreshToken = refreshToken
needSave = true
}
if (needSave) {
user.save().then(function () {
if (config.debug) { logger.info('user login: ' + user.id) }
return done(null, user)
})
} else {
if (config.debug) { logger.info('user login: ' + user.id) }
return done(null, user)
}
}
}).catch(function (err) {
logger.error('auth callback failed: ' + err)
return done(err, null)
})
}