2020-02-08 15:00:16 +01:00
|
|
|
/* eslint-disable no-console */
|
|
|
|
const crypto = require('crypto')
|
2020-01-29 12:30:50 +01:00
|
|
|
const express = require('express')
|
|
|
|
const router = express.Router()
|
|
|
|
const oauth = require('oauth')
|
|
|
|
|
2020-02-07 16:21:34 +01:00
|
|
|
const {
|
|
|
|
TWITTER_CONSUMER_KEY,
|
|
|
|
TWITTER_CONSUMER_SECRET,
|
|
|
|
TWITTER_CALLBACK_URL,
|
|
|
|
GITHUB_CLIEND_ID,
|
|
|
|
GITHUB_CLIENT_SECRET,
|
|
|
|
GITHUB_CALLBACK_URL
|
|
|
|
} = process.env
|
|
|
|
const providers = ['github', 'twitter']
|
|
|
|
|
|
|
|
// twitter uses OAuth1
|
|
|
|
const twitter = new oauth.OAuth(
|
2020-01-29 12:30:50 +01:00
|
|
|
'https://twitter.com/oauth/request_token',
|
|
|
|
'https://twitter.com/oauth/access_token',
|
2020-02-07 16:21:34 +01:00
|
|
|
TWITTER_CONSUMER_KEY,
|
|
|
|
TWITTER_CONSUMER_SECRET,
|
2020-01-29 12:30:50 +01:00
|
|
|
'1.0A',
|
2020-02-07 16:21:34 +01:00
|
|
|
TWITTER_CALLBACK_URL,
|
2020-01-29 12:30:50 +01:00
|
|
|
'HMAC-SHA1'
|
|
|
|
)
|
|
|
|
|
2020-02-07 16:21:34 +01:00
|
|
|
// github uses OAuth2
|
|
|
|
const github = new oauth.OAuth2(
|
|
|
|
GITHUB_CLIEND_ID,
|
|
|
|
GITHUB_CLIENT_SECRET,
|
|
|
|
'https://github.com/',
|
|
|
|
'login/oauth/authorize',
|
|
|
|
'login/oauth/access_token'
|
|
|
|
)
|
2020-01-30 13:15:42 +01:00
|
|
|
|
2020-02-08 15:00:16 +01:00
|
|
|
function validateProvider(req, res, next) {
|
2020-02-07 16:21:34 +01:00
|
|
|
const { provider } = req.params
|
|
|
|
if (!providers.includes(provider)) {
|
|
|
|
res.status(404).send('Wrong provider')
|
2020-02-08 15:00:16 +01:00
|
|
|
} else {
|
|
|
|
next()
|
2020-02-07 16:21:34 +01:00
|
|
|
}
|
2020-02-08 15:00:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
router.get('/connect/:provider', validateProvider, (req, res) => {
|
|
|
|
const { provider } = req.params
|
2020-01-29 12:30:50 +01:00
|
|
|
|
2020-02-07 16:21:34 +01:00
|
|
|
if (provider === 'github') {
|
2020-02-08 15:00:16 +01:00
|
|
|
const CSRFToken = crypto.randomBytes(32).toString('hex')
|
2020-02-07 16:21:34 +01:00
|
|
|
const authorizeUrl = github.getAuthorizeUrl({
|
|
|
|
redirect_uri: GITHUB_CALLBACK_URL,
|
|
|
|
scope: [], // 'gist' - https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/
|
2020-02-08 15:00:16 +01:00
|
|
|
state: CSRFToken
|
2020-02-07 16:21:34 +01:00
|
|
|
})
|
2020-02-08 15:00:16 +01:00
|
|
|
req.session.CSRFToken = CSRFToken
|
2020-02-07 16:21:34 +01:00
|
|
|
res.redirect(authorizeUrl)
|
|
|
|
} else if (provider === 'twitter') {
|
|
|
|
twitter.getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret) {
|
2020-01-29 12:30:50 +01:00
|
|
|
if (error) {
|
|
|
|
res.status(500).send(error)
|
|
|
|
} else {
|
2020-02-07 16:21:34 +01:00
|
|
|
req.session.oauthRequestToken = oauthToken
|
|
|
|
req.session.oauthRequestTokenSecret = oauthTokenSecret
|
|
|
|
res.redirect(
|
|
|
|
'https://twitter.com/oauth/authorize?oauth_token=' + req.session.oauthRequestToken
|
|
|
|
)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2020-02-08 15:00:16 +01:00
|
|
|
router.get('/oauth_callback/:provider', validateProvider, (req, res) => {
|
2020-02-07 16:21:34 +01:00
|
|
|
const { provider } = req.params
|
|
|
|
|
|
|
|
if (provider === 'github') {
|
2020-02-08 15:00:16 +01:00
|
|
|
const { code, state } = req.query
|
|
|
|
if (state !== req.session.CSRFToken) {
|
|
|
|
res.status(404).send('Malformed request')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
github.getOAuthAccessToken(code, {}, function(error, accessToken, refreshToken, results) {
|
2020-02-07 16:21:34 +01:00
|
|
|
if (error || results.error) {
|
2020-02-08 15:00:16 +01:00
|
|
|
console.error('getOAuthAccessToken error', error || results.error)
|
2020-02-07 16:21:34 +01:00
|
|
|
res.status(500).send(error || results.error)
|
|
|
|
} else {
|
|
|
|
req.session.refreshToken = refreshToken
|
|
|
|
req.session.accessToken = accessToken
|
2020-02-05 11:53:45 +01:00
|
|
|
res.redirect('/make-contribution')
|
2020-01-29 12:30:50 +01:00
|
|
|
}
|
2020-02-07 16:21:34 +01:00
|
|
|
})
|
|
|
|
} else if (provider === 'twitter') {
|
|
|
|
twitter.getOAuthAccessToken(
|
|
|
|
req.query.oauth_token,
|
|
|
|
req.session.oauthRequestTokenSecret,
|
|
|
|
req.query.oauth_verifier,
|
|
|
|
(error, oauthAccessToken, oauthAccessTokenSecret) => {
|
|
|
|
if (error) {
|
2020-02-08 15:00:16 +01:00
|
|
|
console.error('getOAuthAccessToken error', error)
|
2020-02-07 16:21:34 +01:00
|
|
|
res.status(500).send(error)
|
|
|
|
} else {
|
|
|
|
req.session.oauthAccessToken = oauthAccessToken
|
|
|
|
req.session.oauthAccessTokenSecret = oauthAccessTokenSecret
|
|
|
|
res.redirect('/make-contribution')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
router.get('/user_data/', (req, res) => {
|
|
|
|
let userData = { name: 'Anonymous' }
|
|
|
|
if (req.session.accessToken) {
|
|
|
|
github.get('https://api.github.com/user', req.session.accessToken, function(error, data) {
|
|
|
|
if (!error) {
|
|
|
|
userData = JSON.parse(data)
|
|
|
|
userData.handle = userData.login
|
|
|
|
userData.socialType = 'github'
|
|
|
|
req.session.handle = userData.login
|
|
|
|
req.session.socialType = 'github'
|
|
|
|
}
|
|
|
|
res.json(userData)
|
|
|
|
})
|
|
|
|
} else if (req.session.oauthAccessToken && req.session.oauthAccessTokenSecret) {
|
|
|
|
twitter.get(
|
|
|
|
'https://api.twitter.com/1.1/account/verify_credentials.json',
|
|
|
|
req.session.oauthAccessToken,
|
|
|
|
req.session.oauthAccessTokenSecret,
|
|
|
|
function(error, data) {
|
|
|
|
if (!error) {
|
|
|
|
userData = JSON.parse(data)
|
|
|
|
userData.handle = userData.screen_name
|
|
|
|
userData.socialType = 'twitter'
|
|
|
|
req.session.handle = userData.screen_name
|
|
|
|
req.session.socialType = 'twitter'
|
|
|
|
}
|
|
|
|
res.json(userData)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
res.json(userData)
|
|
|
|
}
|
2020-01-29 12:30:50 +01:00
|
|
|
})
|
|
|
|
|
2020-02-06 16:32:24 +01:00
|
|
|
router.get('/logout', (req, res) => {
|
|
|
|
req.session.destroy()
|
|
|
|
})
|
|
|
|
|
2020-01-29 12:30:50 +01:00
|
|
|
module.exports = router
|