function Authenticator() {
this._key = 'passport';
this._strategies = {};
this._serializers = [];
this._deserializers = [];
this._infoTransformers = [];
this._framework = null;
this._userProperty = 'user';
this.init();
}n/a
function Authenticator() {
this._key = 'passport';
this._strategies = {};
this._serializers = [];
this._deserializers = [];
this._infoTransformers = [];
this._framework = null;
this._userProperty = 'user';
this.init();
}n/a
function Strategy() {
}n/a
function SessionStrategy() {
Strategy.call(this);
this.name = 'session';
}n/a
function Authenticator() {
this._key = 'passport';
this._strategies = {};
this._serializers = [];
this._deserializers = [];
this._infoTransformers = [];
this._framework = null;
this._userProperty = 'user';
this.init();
}n/a
_strategy = function (name) {
return this._strategies[name];
}...
var layer = name[i];
// If no more strategies exist in the chain, authentication has failed.
if (!layer) { return allFailed(); }
// Get the strategy, which will be used as prototype from which to create
// a new instance. Action functions will then be bound to the strategy
// within the context of the HTTP request/response pair.
var prototype = passport._strategy(layer);
if (!prototype) { return next(new Error('Unknown authentication strategy "' + layer + '"')); }
var strategy = Object.create(prototype);
// ----- BEGIN STRATEGY AUGMENTATION -----
// Augment the new strategy instance with action functions. These action
...authenticate = function (strategy, options, callback) {
return this._framework.authenticate(this, strategy, options, callback);
}...
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...authorize = function (strategy, options, callback) {
options = options || {};
options.assignProperty = 'account';
var fn = this._framework.authorize || this._framework.authenticate;
return fn(this, strategy, options, callback);
}...
* `req.user` will be unaffected.
*
* This function is particularly useful when connecting third-party accounts
* to the local account of a user that is currently authenticated.
*
* Examples:
*
* passport.authorize('twitter-authz', { failureRedirect: '/account
' });
*
* @param {String} strategy
* @param {Object} options
* @return {Function} middleware
* @api public
*/
Authenticator.prototype.authorize = function(strategy, options, callback) {
...deserializeUser = function (fn, req, done) {
if (typeof fn === 'function') {
return this._deserializers.push(fn);
}
// private implementation that traverses the chain of deserializers,
// attempting to deserialize a user
var obj = fn;
// For backwards compatibility
if (typeof req === 'function') {
done = req;
req = undefined;
}
var stack = this._deserializers;
(function pass(i, err, user) {
// deserializers use 'pass' as an error to skip processing
if ('pass' === err) {
err = undefined;
}
// an error or deserialized user was obtained, done
if (err || user) { return done(err, user); }
// a valid user existed when establishing the session, but that user has
// since been removed
if (user === null || user === false) { return done(null, false); }
var layer = stack[i];
if (!layer) {
return done(new Error('Failed to deserialize user out of session'));
}
function deserialized(e, u) {
pass(i + 1, e, u);
}
try {
var arity = layer.length;
if (arity == 3) {
layer(req, obj, deserialized);
} else {
layer(obj, deserialized);
}
} catch(e) {
return done(e);
}
})(0);
}...
};
/**
* Registers a function used to deserialize user objects out of the session.
*
* Examples:
*
* passport.deserializeUser(function(id, done) {
* User.findById(id, function (err, user) {
* done(err, user);
* });
* });
*
* @api public
*/
...framework = function (fw) {
this._framework = fw;
return this;
}...
/**
* Initialize authenticator.
*
* @api protected
*/
Authenticator.prototype.init = function() {
this.framework(require('./framework/connect')());
this.use(new SessionStrategy());
};
/**
* Utilize the given `strategy` with optional `name`, overridding the strategy's
* default name.
*
...init = function () {
this.framework(require('./framework/connect')());
this.use(new SessionStrategy());
}...
this._strategies = {};
this._serializers = [];
this._deserializers = [];
this._infoTransformers = [];
this._framework = null;
this._userProperty = 'user';
this.init();
}
/**
* Initialize authenticator.
*
* @api protected
*/
...initialize = function (options) {
options = options || {};
this._userProperty = options.userProperty || 'user';
return this._framework.initialize(this, options);
}...
* Passport to operate.
*
* Options:
* - `userProperty` Property to set on `req` upon login, defaults to _user_
*
* Examples:
*
* app.use(passport.initialize());
*
* app.use(passport.initialize({ userProperty: 'currentUser' }));
*
* @param {Object} options
* @return {Function} middleware
* @api public
*/
...serializeUser = function (fn, req, done) {
if (typeof fn === 'function') {
return this._serializers.push(fn);
}
// private implementation that traverses the chain of serializers, attempting
// to serialize a user
var user = fn;
// For backwards compatibility
if (typeof req === 'function') {
done = req;
req = undefined;
}
var stack = this._serializers;
(function pass(i, err, obj) {
// serializers use 'pass' as an error to skip processing
if ('pass' === err) {
err = undefined;
}
// an error or serialized object was obtained, done
if (err || obj || obj === 0) { return done(err, obj); }
var layer = stack[i];
if (!layer) {
return done(new Error('Failed to serialize user into session'));
}
function serialized(e, o) {
pass(i + 1, e, o);
}
try {
var arity = layer.length;
if (arity == 3) {
layer(req, user, serialized);
} else {
layer(user, serialized);
}
} catch(e) {
return done(e);
}
})(0);
}...
};
/**
* Registers a function used to serialize user objects into the session.
*
* Examples:
*
* passport.serializeUser(function(user, done) {
* done(null, user.id);
* });
*
* @api public
*/
Authenticator.prototype.serializeUser = function(fn, req, done) {
if (typeof fn === 'function') {
...session = function (options) {
return this.authenticate('session', options);
}...
* However, as a general rule, most web applications will make use of sessions.
* An exception to this rule would be an API server, which expects each HTTP
* request to provide credentials in an Authorization header.
*
* Examples:
*
* app.use(connect.cookieParser());
* app.use(connect.session({ secret: 'keyboard cat' }));
* app.use(passport.initialize());
* app.use(passport.session());
*
* Options:
* - `pauseStream` Pause the request stream before deserializing the user
* object from the session. Defaults to _false_. Should
* be set to true in cases where middleware consuming the
...transformAuthInfo = function (fn, req, done) {
if (typeof fn === 'function') {
return this._infoTransformers.push(fn);
}
// private implementation that traverses the chain of transformers,
// attempting to transform auth info
var info = fn;
// For backwards compatibility
if (typeof req === 'function') {
done = req;
req = undefined;
}
var stack = this._infoTransformers;
(function pass(i, err, tinfo) {
// transformers use 'pass' as an error to skip processing
if ('pass' === err) {
err = undefined;
}
// an error or transformed info was obtained, done
if (err || tinfo) { return done(err, tinfo); }
var layer = stack[i];
if (!layer) {
// if no transformers are registered (or they all pass), the default
// behavior is to use the un-transformed info as-is
return done(null, info);
}
function transformed(e, t) {
pass(i + 1, e, t);
}
try {
var arity = layer.length;
if (arity == 1) {
// sync
var t = layer(info);
transformed(null, t);
} else if (arity == 3) {
layer(req, info, transformed);
} else {
layer(info, transformed);
}
} catch(e) {
return done(e);
}
})(0);
}...
* allowing the full set of client properties to be convieniently accessed.
*
* If no transforms are registered, `info` supplied by the strategy will be left
* unmodified.
*
* Examples:
*
* passport.transformAuthInfo(function(info, done) {
* Client.findById(info.clientID, function (err, client) {
* info.client = client;
* done(err, info);
* });
* });
*
* @api public
...unuse = function (name) {
delete this._strategies[name];
return this;
}...
*
* However, in certain situations, applications may need dynamically configure
* and de-configure authentication strategies. The `use()`/`unuse()`
* combination satisfies these scenarios.
*
* Examples:
*
* passport.unuse('legacy-api');
*
* @param {String} name
* @return {Authenticator} for chaining
* @api public
*/
Authenticator.prototype.unuse = function(name) {
delete this._strategies[name];
...use = function (name, strategy) {
if (!strategy) {
strategy = name;
name = strategy.name;
}
if (!name) { throw new Error('Authentication strategies must have a name'); }
this._strategies[name] = strategy;
return this;
}...
/**
* Initialize authenticator.
*
* @api protected
*/
Authenticator.prototype.init = function() {
this.framework(require('./framework/connect')());
this.use(new SessionStrategy());
};
/**
* Utilize the given `strategy` with optional `name`, overridding the strategy's
* default name.
*
* Examples:
...function Strategy() {
}n/a
authenticate = function (req, options) {
throw new Error('Strategy#authenticate must be overridden by subclass');
}...
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...function authenticate(passport, name, options, callback) {
if (typeof options == 'function') {
callback = options;
options = {};
}
options = options || {};
var multi = true;
// Cast `name` to an array, allowing authentication to pass through a chain of
// strategies. The first strategy to succeed, redirect, or error will halt
// the chain. Authentication failures will proceed through each strategy in
// series, ultimately failing if all strategies fail.
//
// This is typically used on API endpoints to allow clients to authenticate
// using their preferred choice of Basic, Digest, token-based schemes, etc.
// It is not feasible to construct a chain of multiple strategies that involve
// redirection (for example both Facebook and Twitter), since the first one to
// redirect will halt the chain.
if (!Array.isArray(name)) {
name = [ name ];
multi = false;
}
return function authenticate(req, res, next) {
if (http.IncomingMessage.prototype.logIn
&& http.IncomingMessage.prototype.logIn !== IncomingMessageExt.logIn) {
require('../framework/connect').__monkeypatchNode();
}
// accumulator for failures from each strategy in the chain
var failures = [];
function allFailed() {
if (callback) {
if (!multi) {
return callback(null, false, failures[0].challenge, failures[0].status);
} else {
var challenges = failures.map(function(f) { return f.challenge; });
var statuses = failures.map(function(f) { return f.status; });
return callback(null, false, challenges, statuses);
}
}
// Strategies are ordered by priority. For the purpose of flashing a
// message, the first failure will be displayed.
var failure = failures[0] || {}
, challenge = failure.challenge || {}
, msg;
if (options.failureFlash) {
var flash = options.failureFlash;
if (typeof flash == 'string') {
flash = { type: 'error', message: flash };
}
flash.type = flash.type || 'error';
var type = flash.type || challenge.type || 'error';
msg = flash.message || challenge.message || challenge;
if (typeof msg == 'string') {
req.flash(type, msg);
}
}
if (options.failureMessage) {
msg = options.failureMessage;
if (typeof msg == 'boolean') {
msg = challenge.message || challenge;
}
if (typeof msg == 'string') {
req.session.messages = req.session.messages || [];
req.session.messages.push(msg);
}
}
if (options.failureRedirect) {
return res.redirect(options.failureRedirect);
}
// When failure handling is not delegated to the application, the default
// is to respond with 401 Unauthorized. Note that the WWW-Authenticate
// header will be set according to the strategies in use (see
// actions#fail). If multiple strategies failed, each of their challenges
// will be included in the response.
var rchallenge = []
, rstatus, status;
for (var j = 0, len = failures.length; j < len; j++) {
failure = failures[j];
challenge = failure.challenge;
status = failure.status;
rstatus = rstatus || status;
if (typeof challenge == 'string') {
rchallenge.push(challenge);
}
}
res.statusCode = rstatus || 401;
if (res.statusCode == 401 && rchallenge.length) {
res.setHeader('WWW-Authenticate', rchallenge);
}
if (options.failWithError) {
return next(new AuthenticationError(http.STATUS_CODES[res.statusCode], rstatus));
}
res.end(http.STATUS_CODES[res.statusCode]);
}
(function attempt(i) {
var layer = name[i];
// If no more strategies exist in the chain, authentication has failed.
if (!layer) { return allFailed(); }
// Get the strategy, which will be used as prot ......
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...function initialize(passport) {
return function initialize(req, res, next) {
req._passport = {};
req._passport.instance = passport;
if (req.session && req.session[passport._key]) {
// load data from existing session
req._passport.session = req.session[passport._key];
}
next();
};
}...
* Passport to operate.
*
* Options:
* - `userProperty` Property to set on `req` upon login, defaults to _user_
*
* Examples:
*
* app.use(passport.initialize());
*
* app.use(passport.initialize({ userProperty: 'currentUser' }));
*
* @param {Object} options
* @return {Function} middleware
* @api public
*/
...function SessionStrategy() {
Strategy.call(this);
this.name = 'session';
}n/a
function SessionStrategy() {
Strategy.call(this);
this.name = 'session';
}n/a
function Strategy() {
}n/a
authenticate = function (req, options) {
if (!req._passport) { return this.error(new Error('passport.initialize() middleware not in use')); }
options = options || {};
var self = this,
su;
if (req._passport.session) {
su = req._passport.session.user;
}
if (su || su === 0) {
// NOTE: Stream pausing is desirable in the case where later middleware is
// listening for events emitted from request. For discussion on the
// matter, refer to: https://github.com/jaredhanson/passport/pull/106
var paused = options.pauseStream ? pause(req) : null;
req._passport.instance.deserializeUser(su, req, function(err, user) {
if (err) { return self.error(err); }
if (!user) {
delete req._passport.session.user;
self.pass();
if (paused) {
paused.resume();
}
return;
}
var property = req._passport.instance._userProperty || 'user';
req[property] = user;
self.pass();
if (paused) {
paused.resume();
}
});
} else {
self.pass();
}
}...
/**
* Middleware that will authenticate a request using the given `strategy` name,
* with optional `options` and `callback`.
*
* Examples:
*
* passport.authenticate('local', { successRedirect: '/', failureRedirect
: '/login' })(req, res);
*
* passport.authenticate('local', function(err, user) {
* if (!user) { return res.redirect('/login'); }
* res.end('Authenticated!');
* })(req, res);
*
* passport.authenticate('basic', { session: false })(req, res);
...