Skip to content

Instantly share code, notes, and snippets.

@lukebyrne
Created January 7, 2019 08:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lukebyrne/6d21605675abdd3424bca4466a59dbbd to your computer and use it in GitHub Desktop.
Save lukebyrne/6d21605675abdd3424bca4466a59dbbd to your computer and use it in GitHub Desktop.
require('dotenv').config()
const express = require('express')
const jwt = require('jsonwebtoken')
const passport = require('passport')
const GoogleStrategy = require('passport-google-oauth20').Strategy
const fs = require('fs')
const publicKey = fs.readFileSync('jwtRS256.key.pub', 'utf8')
const privateKey = fs.readFileSync('jwtRS256.key', 'utf8')
var knex = require('knex')({
client: 'pg',
connection: process.env.TWIGGY_DB
})
passport.serializeUser((user, done) => {
done(null, user)
})
// Setup Passport
passport.use(
new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.CALLBACK_URL
}, (accessToken, refreshToken, profile, done) => {
const email = profile.emails[0].value
knex('users').where({email: email}).first().then((user) => {
// !currentUser, pass it on
if(user){
console.log('currentUser is: ', user);
done(null, user);
} else {
// !currentUser, create user in our db
knex('users')
.insert({
email: email,
})
.returning(['id', 'email'])
.then((user) => {
console.log('newUser: ', user[0])
done(null, user[0])
})
}
})
})
)
const app = express()
app.use(passport.initialize())
app.get('/', (req, res) => {
res.send('Oauth2')
})
app.get('/oauth2', passport.authenticate('google', {
scope: ['profile', 'email'],
hostedDomain: process.env.HOSTED_DOMAIN
}))
// Set a function for our JWT token
const token = (userId, email, rolesArray) => {
// Set our JWT claims
let claims = {
sub: userId,
email: email,
'https://hasura.io/jwt/claims': {
'x-hasura-default-role': rolesArray.includes('admin') ? 'admin': 'user',
'x-hasura-user-id': userId,
'x-hasura-allowed-roles': rolesArray
}
}
// Sign the JWT and pass onto the REDIRECT_URL
const token = jwt.sign(claims, privateKey, { algorithm: 'RS256' })
// Check that we can decode things!
const decoded = jwt.verify(token, publicKey)
console.log(decoded)
return token
}
app.get('/redirect', passport.authenticate('google'), (req, res) => {
// Get our roles from the DB then once resolved set our claims and redirect
knex
.select('name')
.from('roles')
.leftJoin('users_roles', 'roles.id', 'users_roles.role_id')
.where({ 'users_roles.user_id': req.user.id })
.then((roles) => {
// Map the roles return to an array of names
const rolesArray = roles.map(role => role.name)
// Now redirect
res.redirect(`${process.env.REDIRECT_URL}?token=${token(req.user.id, req.user.email, rolesArray)}`)
})
})
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log(`app now listening for requests on port ${port}`)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment