git oauth WIP

This commit is contained in:
Alexey 2020-02-07 18:21:34 +03:00
parent 640443dc2d
commit d580a5e6fa
9 changed files with 141 additions and 62 deletions

View File

@ -3,14 +3,18 @@ AWS_SECRET_ACCESS_KEY=
AWS_S3_BUCKET= AWS_S3_BUCKET=
DISABLE_S3=false DISABLE_S3=false
MYSQL_USER=root MYSQL_USER=
MYSQL_PASSWORD=webmailpasswd MYSQL_PASSWORD=
MYSQL_DATABASE=phase2 MYSQL_DATABASE=phase2
TWITTER_CONSUMER_KEY= TWITTER_CONSUMER_KEY=
TWITTER_CONSUMER_SECRET= TWITTER_CONSUMER_SECRET=
TWITTER_CALLBACK_URL=http://localhost:3000/api/twitter_callback TWITTER_CALLBACK_URL=https://ceremony.tornado.cash/api/oauth_callback/twitter
GITHUB_CLIEND_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CALLBACK_URL=https://ceremony.tornado.cash/api/oauth_callback/github
SESSION_SECRET= SESSION_SECRET=
NUXT_HOST=0.0.0.0 NUXT_HOST=0.0.0.0
NUXT_PORT=3000

2
.gitignore vendored
View File

@ -90,3 +90,5 @@ sw.*
*.swp *.swp
.env.local .env.local
db.development.sqlite db.development.sqlite
.env.development
.env.production

View File

@ -13,10 +13,10 @@
</b-field> </b-field>
</div> </div>
<div v-else class="buttons"> <div v-else class="buttons">
<b-button @click="twitterLogIn" type="is-primary" outlined expanded> <b-button @click="logInVia('twitter')" type="is-primary" outlined expanded>
Sign in with Twitter Sign in with Twitter
</b-button> </b-button>
<b-button :disabled="true" type="is-primary" outlined expanded> <b-button @click="logInVia('github')" type="is-primary" outlined expanded>
Sign in with Github Sign in with Github
</b-button> </b-button>
</div> </div>
@ -52,7 +52,7 @@ export default {
} }
}, },
methods: { methods: {
...mapActions('user', ['makeTweet', 'twitterLogIn']) ...mapActions('user', ['makeTweet', 'logInVia'])
} }
} }
</script> </script>

View File

@ -9,14 +9,14 @@ services:
nginx_client_max_body_size: 50m nginx_client_max_body_size: 50m
nginx_proxy_read_timeout: 600s nginx_proxy_read_timeout: 600s
MYSQL_HOST: mysql MYSQL_HOST: mysql
env_file: .env env_file: .env.production
depends_on: depends_on:
- mysql - mysql
mysql: mysql:
image: mysql:5.7 image: mysql:5.7
restart: always restart: always
env_file: .env env_file: .env.production
environment: environment:
MYSQL_RANDOM_ROOT_PASSWORD: 'true' MYSQL_RANDOM_ROOT_PASSWORD: 'true'
volumes: volumes:

View File

@ -132,7 +132,7 @@ export default {
}, },
async mounted() { async mounted() {
this.loading = true this.loading = true
this.status.msg = 'Loading...' this.status.msg = 'Loading'
this.status.type = '' this.status.type = ''
await this.getUserData() await this.getUserData()
this.loading = false this.loading = false

View File

@ -3,64 +3,137 @@ const router = express.Router()
const oauth = require('oauth') const oauth = require('oauth')
const logger = require('morgan') const logger = require('morgan')
const consumer = new oauth.OAuth( 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(
'https://twitter.com/oauth/request_token', 'https://twitter.com/oauth/request_token',
'https://twitter.com/oauth/access_token', 'https://twitter.com/oauth/access_token',
process.env.TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_KEY,
process.env.TWITTER_CONSUMER_SECRET, TWITTER_CONSUMER_SECRET,
'1.0A', '1.0A',
process.env.TWITTER_CALLBACK_URL || 'http://localhost:3000/api/twitter_callback', TWITTER_CALLBACK_URL,
'HMAC-SHA1' 'HMAC-SHA1'
) )
router.get('/user_data', (req, res) => { // github uses OAuth2
let userData = { name: 'Anonymous' } const github = new oauth.OAuth2(
consumer.get( GITHUB_CLIEND_ID,
'https://api.twitter.com/1.1/account/verify_credentials.json', GITHUB_CLIENT_SECRET,
req.session.oauthAccessToken, 'https://github.com/',
req.session.oauthAccessTokenSecret, 'login/oauth/authorize',
function(error, data) { 'login/oauth/access_token'
if (!error) { )
userData = JSON.parse(data)
userData.handle = userData.screen_name
req.session.handle = userData.screen_name
req.session.socialType = 'twitter'
}
res.json(userData)
}
)
})
router.get('/connect', (req, res) => { router.get('/connect/:provider', (req, res) => {
consumer.getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret) { const { provider } = req.params
if (error) { if (!providers.includes(provider)) {
res.status(500).send(error) res.status(404).send('Wrong provider')
} else { }
req.session.oauthRequestToken = oauthToken
req.session.oauthRequestTokenSecret = oauthTokenSecret
res.redirect(
'https://twitter.com/oauth/authorize?oauth_token=' + req.session.oauthRequestToken
)
}
})
})
router.get('/twitter_callback', (req, res) => { if (provider === 'github') {
consumer.getOAuthAccessToken( const authorizeUrl = github.getAuthorizeUrl({
req.query.oauth_token, redirect_uri: GITHUB_CALLBACK_URL,
req.session.oauthRequestTokenSecret, scope: [], // 'gist' - https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/
req.query.oauth_verifier, state: 'some random string to protect against cross-site request forgery attacks'
(error, oauthAccessToken, oauthAccessTokenSecret) => { })
res.redirect(authorizeUrl)
} else if (provider === 'twitter') {
twitter.getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret) {
if (error) { if (error) {
logger.error(error)
res.status(500).send(error) res.status(500).send(error)
} else { } else {
req.session.oauthAccessToken = oauthAccessToken req.session.oauthRequestToken = oauthToken
req.session.oauthAccessTokenSecret = oauthAccessTokenSecret req.session.oauthRequestTokenSecret = oauthTokenSecret
res.redirect(
'https://twitter.com/oauth/authorize?oauth_token=' + req.session.oauthRequestToken
)
}
})
}
})
router.get('/oauth_callback/:provider', (req, res) => {
const { provider } = req.params
if (!providers.includes(provider)) {
res.status(404).send('Wrong provider')
}
if (provider === 'github') {
github.getOAuthAccessToken(req.query.code, {}, function(
error,
accessToken,
refreshToken,
results
) {
if (error || results.error) {
logger.error('getOAuthAccessToken error', error || results.error)
res.status(500).send(error || results.error)
} else {
req.session.refreshToken = refreshToken
req.session.accessToken = accessToken
res.redirect('/make-contribution') res.redirect('/make-contribution')
} }
} })
) } else if (provider === 'twitter') {
twitter.getOAuthAccessToken(
req.query.oauth_token,
req.session.oauthRequestTokenSecret,
req.query.oauth_verifier,
(error, oauthAccessToken, oauthAccessTokenSecret) => {
if (error) {
logger.error(error)
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)
}
}) })
router.get('/logout', (req, res) => { router.get('/logout', (req, res) => {

View File

@ -1,6 +1,7 @@
require('dotenv').config()
const fs = require('fs')
const path = require('path') const path = require('path')
const { NODE_ENV } = process.env
require('dotenv').config({ path: path.join(__dirname, `../.env.${NODE_ENV}`) })
const fs = require('fs')
const express = require('express') const express = require('express')
const bodyParser = require('body-parser') const bodyParser = require('body-parser')
const morgan = require('morgan') const morgan = require('morgan')
@ -14,7 +15,7 @@ const models = require('./models')
const app = express() const app = express()
async function start() { async function start() {
config.dev = process.env.NODE_ENV !== 'production' config.dev = NODE_ENV !== 'production'
await models.sequelize.sync() await models.sequelize.sync()
const nuxt = new Nuxt(config) const nuxt = new Nuxt(config)

Binary file not shown.

View File

@ -49,8 +49,8 @@ const getters = {
} }
const actions = { const actions = {
twitterLogIn() { logInVia({ state }, provider) {
window.location.replace('/api/connect') window.location.replace(`/api/connect/${provider}`)
}, },
makeTweet({ state }) { makeTweet({ state }) {
const tweetText = `Just made the contribution %23${state.contributionIndex} to Tornado.cash Trusted Setup Ceremony! 🚀` const tweetText = `Just made the contribution %23${state.contributionIndex} to Tornado.cash Trusted Setup Ceremony! 🚀`
@ -90,8 +90,7 @@ const actions = {
if (data.name !== 'Anonymous') { if (data.name !== 'Anonymous') {
commit('SET_HANDLE', data.handle) commit('SET_HANDLE', data.handle)
commit('SET_NAME', data.name) commit('SET_NAME', data.name)
// TODO check whether it's github or twitter commit('SET_CONTRIBUTION_TYPE', data.socialType)
commit('SET_CONTRIBUTION_TYPE', 'twitter')
} }
} catch (e) { } catch (e) {
console.error('user_data fail', e) console.error('user_data fail', e)