<commit_before>#
# Uses [passport.js](http://passportjs.org/) to setup authentication for Arena

_ = require 'underscore'
request = require 'superagent'
express = require 'express'
passport = require 'passport'
LocalStrategy = require('passport-local').Strategy
qs = require 'querystring'
crypto = require 'crypto'
{ parse } = require 'url'

arenaXappToken = null

# Default options
opts =
  SECURE_ARENA_URL: 'http://api.are.na'
  loginPath: '/me/sign_in'
  signupPath: '/me/invitation/accept'
  userKeys: ['id', 'first_name', 'last_name', 'email', 'slug', 'following_ids', 'notification_count', 'username', 'authentication_token']

#
# Main function that overrides/injects any options, sets up passport, sets up an app to
# handle routing and injecting locals, and returns that app to be mounted as middleware.
#
module.exports = (options) =>
  module.exports.options = _.extend opts, options
  initPassport()
  initApp()
  app

#
# Setup the mounted app that routes signup/login and injects necessary locals.
#
module.exports.app = app = express()

initApp = ->
  app.use passport.initialize()
  app.use passport.session()
  app.post opts.loginPath, localAuth, afterLocalAuth
  app.post opts.signupPath, signup, passport.authenticate('local'), afterLocalAuth
  app.use headerLogin
  app.use addLocals

localAuth = (req, res, next) ->
  passport.authenticate('local', (err, user, info) ->
    return req.login(user, next) if user

    res.authError = info; next()
  )(req, res, next)

afterLocalAuth = (req, res, next) ->
  if res.authError
    res.send 403, { success: false, error: res.authError }
  else if req.xhr and req.user?
    res.send { success: true }
  else if req.xhr and not req.user?
    res.send { success: false, error: "Missing user." }
  else
    next()

signup = (req, res, next) ->
  request.put(opts.SECURE_ARENA_URL + '/v2/accounts/invitation').send(
    name: req.body.name
    email: req.body.email
    password: <PASSWORD>
    xapp_token: res.locals.artsyXappToken
  ).end onCreateUser(next)

onCreateUser = (next) ->
  (err, res) ->
    if res.status isnt 201
      errMsg = res.body.message
    else
      errMsg = err?.text
    if errMsg then next(errMsg) else next()

addLocals = (req, res, next) ->
  if req.user
    res.locals.user = req.user
    res.locals.sd?.CURRENT_USER = req.user.toJSON()
    res.locals.sd?.XAuthToken = req.user.get('authentication_token')
  next()

headerLogin = (req, res, next) ->
  if token = req.get('X-AUTH-TOKEN') or req.query.access_token
    req.login new opts.CurrentUser(accessToken: token), next
  else
    next()

#
# Setup passport.
#
initPassport = ->
  passport.serializeUser serializeUser
  passport.deserializeUser deserializeUser
  passport.use new LocalStrategy { usernameField: 'email' }, arenaCallback

#
# Passport callbacks
#
arenaCallback = (username, password, done) ->
  request.post("#{opts.SECURE_ARENA_URL}/v2/tokens").query(
    email: username
    password: password
  ).end accessTokenCallback(done)

accessTokenCallback = (done, params) ->
  return (e, res) ->
    # Catch the various forms of error Arena could encounter<commit_msg>rm v2 in url<commit_after>#
# Uses [passport.js](http://passportjs.org/) to setup authentication for Arena

_ = require 'underscore'
request = require 'superagent'
express = require 'express'
passport = require 'passport'
LocalStrategy = require('passport-local').Strategy
qs = require 'querystring'
crypto = require 'crypto'
{ parse } = require 'url'

arenaXappToken = null

# Default options
opts =
  SECURE_ARENA_URL: 'http://api.are.na'
  loginPath: '/me/sign_in'
  signupPath: '/me/invitation/accept'
  userKeys: ['id', 'first_name', 'last_name', 'email', 'slug', 'following_ids', 'notification_count', 'username', 'authentication_token']

#
# Main function that overrides/injects any options, sets up passport, sets up an app to
# handle routing and injecting locals, and returns that app to be mounted as middleware.
#
module.exports = (options) =>
  module.exports.options = _.extend opts, options
  initPassport()
  initApp()
  app

#
# Setup the mounted app that routes signup/login and injects necessary locals.
#
module.exports.app = app = express()

initApp = ->
  app.use passport.initialize()
  app.use passport.session()
  app.post opts.loginPath, localAuth, afterLocalAuth
  app.post opts.signupPath, signup, passport.authenticate('local'), afterLocalAuth
  app.use headerLogin
  app.use addLocals

localAuth = (req, res, next) ->
  passport.authenticate('local', (err, user, info) ->
    return req.login(user, next) if user

    res.authError = info; next()
  )(req, res, next)

afterLocalAuth = (req, res, next) ->
  if res.authError
    res.send 403, { success: false, error: res.authError }
  else if req.xhr and req.user?
    res.send { success: true }
  else if req.xhr and not req.user?
    res.send { success: false, error: "Missing user." }
  else
    next()

signup = (req, res, next) ->
  request.put(opts.SECURE_ARENA_URL + '/accounts/invitation').send(
    name: req.body.name
    email: req.body.email
    password: <PASSWORD>
    xapp_token: res.locals.artsyXappToken
  ).end onCreateUser(next)

onCreateUser = (next) ->
  (err, res) ->
    if res.status isnt 201
      errMsg = res.body.message
    else
      errMsg = err?.text
    if errMsg then next(errMsg) else next()

addLocals = (req, res, next) ->
  if req.user
    res.locals.user = req.user
    res.locals.sd?.CURRENT_USER = req.user.toJSON()
    res.locals.sd?.XAuthToken = req.user.get('authentication_token')
  next()

headerLogin = (req, res, next) ->
  if token = req.get('X-AUTH-TOKEN') or req.query.access_token
    req.login new opts.CurrentUser(accessToken: token), next
  else
    next()

#
# Setup passport.
#
initPassport = ->
  passport.serializeUser serializeUser
  passport.deserializeUser deserializeUser
  passport.use new LocalStrategy { usernameField: 'email' }, arenaCallback

#
# Passport callbacks
#
arenaCallback = (username, password, done) ->
  request.post("#{opts.SECURE_ARENA_URL}/tokens").query(
    email: username
    password: password
  ).end accessTokenCallback(done)

accessTokenCallback = (done, params) ->
  return (e, res) ->
    # Catch the various forms of error Arena could encounter
{'fraction_non_alphanumeric': 0.12750280313951626, 'fraction_numerical': 0.002402691013935608, 'mean_word_length': 3.878125, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3981143', 'n_tokens_mistral': 2077, 'n_tokens_neox': 2040, 'n_words': 558}