Skip to content

Instantly share code, notes, and snippets.

@tanepiper
Forked from sorensen/custom-dnode-session.js
Created December 8, 2011 23:09
Show Gist options
  • Save tanepiper/1449166 to your computer and use it in GitHub Desktop.
Save tanepiper/1449166 to your computer and use it in GitHub Desktop.
Mongoose Authentication
// Authentication middleware
// -------------------------
// Shim for DNode's current version of socket.io,
// which cannot pass `null` references, and turning
// the mongoose model to a pure JSON object
function shim(err, doc, fn) {
if (!err) err = 0
if (doc) doc = JSON.parse(JSON.stringify(doc))
return fn(err, doc)
}
module.exports = function(options) {
var database = options.database
, Store = options.store
return function(client, conn) {
var self = this
, User = database.model('user')
, Token = database.model('token')
, Session = database.model('session')
this.authenticate = function(data, fn) {
User.authenticate(data.username, data.password, function(err, doc) {
self.session(function(err, sess) {
if (err) return
sess.user = JSON.parse(JSON.stringify(doc))
sess.save()
})
shim(err, doc, fn)
})
}
this.authFromToken = function() {
self.cookies(function(cookies) {
if (cookies && cookies.token) {
Token.findOne({
_user: cookie._user
, series: cookie.series
, token: cookie.token
}, function(err, token) {
if (!token) return
User.findOne({_id: _user}, function(err, user) {
if (err) return
if (user) {
}
})
})
}
})
}
this.register = function(data, fn) {
User.register(data, function(err, doc) {
self.session(function(err, sess) {
if (err) return
sess.user = JSON.parse(JSON.stringify(doc))
sess.save()
})
shim(err, doc, fn)
})
}
this.logout = function(fn) {
delete conn.session.user
fn && fn()
}
}
}
function encryptPassword(model, next) {
if (model._password && !model.hash) {
bcrypt.gen_salt(10, function(err, salt) {
if (err) return next(err)
bcrypt.encrypt(model._password, salt, function(err, hash) {
if (err) return next(err)
model.hash = hash
next()
})
})
} else {
next()
}
}
function defineModels(mongoose, next) {
var Schema = mongoose.Schema
, ObjectId = Schema.ObjectId
var UserSchema = new Schema({
first_name: { type: String, trim: true }
, last_name: { type: String, trim: true }
, username: {
type: String
, lowercase: true
, required: true
, index: { unique: true }
}
, email: {
type: String
, lowercase: true
, set: emptyToNull
, index: { unique: true, sparse: true }
}
, hash: { type: String }
})
UserSchema
.virtual('password')
.get(function() {
return this.hash
})
.set(function(password) {
this._password = password
})
UserSchema
.pre('save', function(next) {
console.log('pre save', next)
encryptPassword(this, function(err) {
next()
})
})
UserSchema
.method('authenticate', function(password, next) {
bcrypt.compare(password, this.hash, next)
})
UserSchema
.static('authenticate', function(username, password, next) {
this.findOne({
username: username
}
, function(err, user) {
if (err) return next(err)
if (!user) return next('User does not exist')
user.authenticate(password, function(err, valid) {
if (err) return next(err)
if (valid) return next(null, user)
return next('Invalid password', null)
})
})
})
UserSchema
.static('register', function(attr, next) {
this.create(attr, function(err, user) {
if (err) {
console.log(err)
if (/duplicate key/.test(err)) {
return next('Username taken')
}
return next(err)
}
return next(null, user)
})
})
mongoose.model('user', UserSchema)
next && next()
}
exports.defineModels = defineModels
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment