Authentification Module

License

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Description

This module contains all functions about authentification of MyPads users. It's mainly based upon the excellent passport Node library.

TODO : usage of JWT instead of session-based strategy.

External dependencies

ld = require 'lodash'
express = require 'express'
passport = require 'passport'
localStrategy = require('passport-local').Strategy

Local dependencies

conf = require './configuration.js'
user = require './model/user.js'

module.exports = do ->

Authentification functions

  auth = {}

Internal functions

These functions are not private like with closures, for testing purposes, but they are expected be used only internally by other MyPads functions.

  auth.fn = {}

local

local is a synchronous function used to set up local strategy.

  auth.fn.local = ->
    passport.serializeUser (user, done) -> done null, user._id
    passport.deserializeUser (id, done) -> user.get id, done
    passport.use new localStrategy {
      usernameField: 'login'
      passwordField: 'password'
    }, (login, password, callback) ->
      isFS = (s) -> ld.isString(s) and not ld.isEmpty(s)
      throw new TypeError 'login must be a string' if not isFS login
      throw new TypeError 'password must be a string' if not isFS password
      if not ld.isFunction callback
        throw new TypeError 'callback must be a function'
      auth.fn.localFn.apply null, arguments

localFn

localFn is the function used by localStrategy for verifying if login and password are correct. It takes :

  auth.fn.localFn = (login, password, callback) ->
    user.get login, (err, u) ->
      return callback err if err
      auth.fn.isPasswordValid u, password, (err, isValid) ->
        return callback err if err
        if not isValid
          callback new Error 'password is not correct', false
        else
          callback null, u

isPasswordValid

isPasswordValid compares the hash of given password and saved salt with the one saved in database. It takes :

  auth.fn.isPasswordValid = (u, password, callback) ->
    user.fn.hashPassword u.password.salt, password, (err, res) ->
      callback err if err
      if res.hash is u.password.hash
        callback null, true
      else
        callback null, false

Public functions

init

iniƧ is a synchronous function used to set up authentification. It :

  auth.init = (app) ->
    auth.fn.local()
    app.use express.cookieParser()
    app.use passport.initialize()
    app.use passport.session()
    conf.get 'sessionSecret', (err, res) ->
      throw new Error err if err
      app.use(express.session secret: res)

  return auth