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=
DISABLE_S3=false
MYSQL_USER=root
MYSQL_PASSWORD=webmailpasswd
MYSQL_USER=
MYSQL_PASSWORD=
MYSQL_DATABASE=phase2
TWITTER_CONSUMER_KEY=
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=
NUXT_HOST=0.0.0.0
NUXT_PORT=3000

2
.gitignore vendored
View File

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

View File

@ -13,10 +13,10 @@
</b-field>
</div>
<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
</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
</b-button>
</div>
@ -52,7 +52,7 @@ export default {
}
},
methods: {
...mapActions('user', ['makeTweet', 'twitterLogIn'])
...mapActions('user', ['makeTweet', 'logInVia'])
}
}
</script>

View File

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

View File

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

View File

@ -3,36 +3,51 @@ const router = express.Router()
const oauth = require('oauth')
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/access_token',
process.env.TWITTER_CONSUMER_KEY,
process.env.TWITTER_CONSUMER_SECRET,
TWITTER_CONSUMER_KEY,
TWITTER_CONSUMER_SECRET,
'1.0A',
process.env.TWITTER_CALLBACK_URL || 'http://localhost:3000/api/twitter_callback',
TWITTER_CALLBACK_URL,
'HMAC-SHA1'
)
router.get('/user_data', (req, res) => {
let userData = { name: 'Anonymous' }
consumer.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
req.session.handle = userData.screen_name
req.session.socialType = 'twitter'
}
res.json(userData)
}
// github uses OAuth2
const github = new oauth.OAuth2(
GITHUB_CLIEND_ID,
GITHUB_CLIENT_SECRET,
'https://github.com/',
'login/oauth/authorize',
'login/oauth/access_token'
)
})
router.get('/connect', (req, res) => {
consumer.getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret) {
router.get('/connect/:provider', (req, res) => {
const { provider } = req.params
if (!providers.includes(provider)) {
res.status(404).send('Wrong provider')
}
if (provider === 'github') {
const authorizeUrl = github.getAuthorizeUrl({
redirect_uri: GITHUB_CALLBACK_URL,
scope: [], // 'gist' - https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/
state: 'some random string to protect against cross-site request forgery attacks'
})
res.redirect(authorizeUrl)
} else if (provider === 'twitter') {
twitter.getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret) {
if (error) {
res.status(500).send(error)
} else {
@ -43,10 +58,33 @@ router.get('/connect', (req, res) => {
)
}
})
}
})
router.get('/twitter_callback', (req, res) => {
consumer.getOAuthAccessToken(
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')
}
})
} else if (provider === 'twitter') {
twitter.getOAuthAccessToken(
req.query.oauth_token,
req.session.oauthRequestTokenSecret,
req.query.oauth_verifier,
@ -61,6 +99,41 @@ router.get('/twitter_callback', (req, res) => {
}
}
)
}
})
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) => {

View File

@ -1,6 +1,7 @@
require('dotenv').config()
const fs = require('fs')
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 bodyParser = require('body-parser')
const morgan = require('morgan')
@ -14,7 +15,7 @@ const models = require('./models')
const app = express()
async function start() {
config.dev = process.env.NODE_ENV !== 'production'
config.dev = NODE_ENV !== 'production'
await models.sequelize.sync()
const nuxt = new Nuxt(config)

Binary file not shown.

View File

@ -49,8 +49,8 @@ const getters = {
}
const actions = {
twitterLogIn() {
window.location.replace('/api/connect')
logInVia({ state }, provider) {
window.location.replace(`/api/connect/${provider}`)
},
makeTweet({ state }) {
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') {
commit('SET_HANDLE', data.handle)
commit('SET_NAME', data.name)
// TODO check whether it's github or twitter
commit('SET_CONTRIBUTION_TYPE', 'twitter')
commit('SET_CONTRIBUTION_TYPE', data.socialType)
}
} catch (e) {
console.error('user_data fail', e)