g33k57
7/11/2019 - 10:49 AM

passport-auth-knex.js

require('dotenv').config()

const http            = require('http')
const express         = require('express')
const session         = require('express-session')
const FileStore       = require('session-file-store')(session)
const bodyParser      = require('body-parser')
const morgan          = require('morgan')
const cors            = require('cors')
const passport        = require('passport')
const TwitterStrategy = require('passport-twitter').Strategy
const knex            = require('./db/knex.js')

const app             = module.exports = express()
const server          = http.createServer(app)
const port            = parseInt(process.env.PORT || 3000)

passport.use(new TwitterStrategy({
    consumerKey: process.env.TWITTER_PUBLIC,
    consumerSecret: process.env.TWITTER_SECRET,
    callbackURL: "http://localhost:" + port + "/auth/twitter/callback"
  },
  function(token, tokenSecret, profile, done) {
    
    console.log('About to create user w/ profile data', profile)
    console.log('Got TOKEN:', token)
  
    knex('users')
    .where({id: profile.id})
    .then(results => {
      if (results.length < 1) {
        console.log('About to create user:', results)
        return knex('users')
        .insert({...profile})
        .returning('*')
        .then(user => {
          console.log('Created user:', user)
          return done(null, user)
        })
      } else {
        return done(null, results[0])
      }
    })
  }
));

passport.serializeUser(function(user, done) {
  console.log('serializeUser (save unique id) from: ', user)
  
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  console.log('deserializeUser (lookup) ' + id)
  
  knex('users')
  .where({id: id})
  .then(([user]) => {
    if (!user) { done(new Error('User not found! ' + id))}
    done(null, user)    
  })
})


app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
app.use(morgan(process.env.NODE_ENV !== 'production' ? 'dev' : 'combined'))
app.use(cors({origin: true}))
app.use(session({
  secret: 'gnioqgou33cnds389dvsk',
  resave: true,
  saveUninitialized: true,
  store: new FileStore({path: '/tmp/session'})
}))
app.use(passport.initialize())
app.use(passport.session())

// handler to return any user data as json (if not logged in, wont work) 
app.get('/', function getCurrentUser(req, res, next) {
  console.log('current session:', req.session)
  console.log('current user:', req.user)
  res.send({user: req.user})
})


// Redirect the user to Twitter for authentication.  When complete, Twitter
// will redirect the user back to the application at
//   /auth/twitter/callback
app.get('/auth/twitter', passport.authenticate('twitter'))

// Twitter will redirect the user to this URL after approval.  Finish the
// authentication process by attempting to obtain an access token.  If
// access was granted, the user will be logged in.  Otherwise,
// authentication has failed.
app.get('/auth/twitter/callback',
  passport.authenticate('twitter', { successRedirect: '/',
                                     failureRedirect: '/login' }));

// ^^^ Example: app.use('/v1/kitten', require('./routes/kitten'))
// ^^^ Example: app.use('/cats', require('./routes/kitten'))

app.use(notFound)
app.use(errorHandler)

server.listen(port)
  .on('error',     console.error.bind(console))
  .on('listening', console.log.bind(console, 'Listening on ' + port));

function notFound(req, res, next) {
  const url = req.originalUrl
  if (!/favicon\.ico$/.test(url) && !/robots\.txt$/.test(url)) {
    // Don't log less important auto requests
    console.error('[404: Requested file not found] ', url)
  }
  res.status(404).send({error: 'Url not found', status: 404, url})
}

function errorHandler(err, req, res, next) {
  console.error('ERROR', err)
  const stack =  process.env.NODE_ENV !== 'production' ? err.stack : undefined
  res.status(500).send({error: err.message, stack, url: req.originalUrl})
}