pax_global_header00006660000000000000000000000064141232025400014503gustar00rootroot0000000000000052 comment=f5dc1da878cff5135d60b31b8d99d33e48ab4161 passport-0.5.0/000077500000000000000000000000001412320254000133605ustar00rootroot00000000000000passport-0.5.0/.github/000077500000000000000000000000001412320254000147205ustar00rootroot00000000000000passport-0.5.0/.github/FUNDING.yml000066400000000000000000000000741412320254000165360ustar00rootroot00000000000000github: jaredhanson patreon: jaredhanson ko_fi: jaredhanson passport-0.5.0/.github/ISSUE_TEMPLATE.md000066400000000000000000000035511412320254000174310ustar00rootroot00000000000000** READ THIS FIRST! ** #### Are you looking for help? Reminder: The issue tracker is not a support forum. Issues should only be filed in this project once they are able to be reproduced and confirmed as a flaw in the software or incorrect information in associated documention. If you are encountering problems integrating this module into your application, please post a question on the [discussion forum](https://github.com/passport/discuss) rather than filing an issue. #### Is this a security issue? Do not open issues that might have security implications. Potential security vulnerabilities should be reported privately to jaredhanson@gmail.com. Once any vulerabilities have been repaired, the details will be disclosed publicly in a responsible manner. This also allows time for coordinating with affected parties in order to mitigate negative consequences. If neither of the above two scenarios apply to your situation, you should open an issue. Delete this paragraph and the text above, and fill in the information requested below. ### Expected behavior ### Actual behavior ### Steps to reproduce ```js // Format code using Markdown code blocks ``` ### Environment * Operating System: * Node version: * passport version: passport-0.5.0/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000035621412320254000205270ustar00rootroot00000000000000** READ THIS FIRST! ** #### Are you implementing a new feature? Requests for new features should first be discussed on the [developer forum](https://github.com/passport/develop). This allows the community to gather feedback and assess whether or not there is an existing way to achieve the desired functionality. If it is determined that a new feature needs to be implemented, include a link to the relevant discussion along with the pull request. #### Is this a security patch? Do not open pull requests that might have security implications. Potential security vulnerabilities should be reported privately to jaredhanson@gmail.com. Once any vulerabilities have been repaired, the details will be disclosed publicly in a responsible manner. This also allows time for coordinating with affected parties in order to mitigate negative consequences. If neither of the above two scenarios apply to your situation, you should open a pull request. Delete this paragraph and the text above, and fill in the information requested below. ### Checklist - [ ] I have read the [CONTRIBUTING](https://github.com/jaredhanson/passport/blob/master/CONTRIBUTING.md) guidelines. - [ ] I have added test cases which verify the correct operation of this feature or patch. - [ ] I have added documentation pertaining to this feature or patch. - [ ] The automated test suite (`$ make test`) executes successfully. - [ ] The automated code linting (`$ make lint`) executes successfully. passport-0.5.0/.gitignore000066400000000000000000000001131412320254000153430ustar00rootroot00000000000000docs/ reports/ # Mac OS X .DS_Store # Node.js node_modules npm-debug.log passport-0.5.0/.jshintrc000066400000000000000000000004531412320254000152070ustar00rootroot00000000000000{ "node": true, "bitwise": true, "camelcase": true, "curly": true, "forin": true, "immed": true, "latedef": true, "newcap": true, "noarg": true, "noempty": true, "nonew": true, "quotmark": "single", "undef": true, "unused": true, "trailing": true, "laxcomma": true } passport-0.5.0/.npmignore000066400000000000000000000001441412320254000153560ustar00rootroot00000000000000CONTRIBUTING.md Makefile SPONSORS.md docs/ examples/ reports/ test/ .github/ .jshintrc .travis.yml passport-0.5.0/.travis.yml000066400000000000000000000005411412320254000154710ustar00rootroot00000000000000language: "node_js" node_js: - "13" - "12" - "11" - "10" - "9" - "8" - "7" - "6" - "5" - "4" - "3" # io.js - "2" # io.js - "1" # io.js - "0.12" - "0.10" # - "0.8" before_install: - "npm install make-node@0.3.x -g" - "preinstall-compat" script: - "make test-cov" after_success: - "make report-cov" sudo: false passport-0.5.0/CHANGELOG.md000066400000000000000000000016561412320254000152010ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.5.0] - 2021-09-23 ### Changed - `initialize()` middleware extends request with `login()`, `logIn()`, `logout()`, `logOut()`, `isAuthenticated()`, and `isUnauthenticated()` functions. ### Removed - `login()`, `logIn()`, `logout()`, `logOut()`, `isAuthenticated()`, and `isUnauthenticated()` functions no longer added to `http.IncomingMessage.prototype`. ### Fixed - `userProperty` option to `initialize()` middleware only affects the current request, rather than all requests processed via singleton Passport instance, eliminating a race condition in situations where `initialize()` middleware is used multiple times in an application with `userProperty` set to different values. passport-0.5.0/CONTRIBUTING.md000066400000000000000000000006331412320254000156130ustar00rootroot00000000000000## Contributing ### Tests The test suite is located in the `test/` directory. All new features are expected to have corresponding test cases with complete code coverage. Patches that increase test coverage are happily accepted. Ensure that the test suite passes by executing: ```bash $ make test ``` Coverage reports can be generated and viewed by executing: ```bash $ make test-cov $ make view-cov ``` passport-0.5.0/LICENSE000066400000000000000000000020741412320254000143700ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2011-2019 Jared Hanson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. passport-0.5.0/Makefile000066400000000000000000000006301412320254000150170ustar00rootroot00000000000000include node_modules/make-node/main.mk SOURCES = lib/*.js lib/**/*.js TESTS = test/*.test.js test/**/*.test.js LCOVFILE = ./reports/coverage/lcov.info MOCHAFLAGS = --require ./test/bootstrap/node view-docs: open ./docs/index.html view-cov: open ./reports/coverage/lcov-report/index.html clean: clean-docs clean-cov -rm -r $(REPORTSDIR) clobber: clean -rm -r node_modules .PHONY: clean clobber passport-0.5.0/README.md000066400000000000000000000213551412320254000146450ustar00rootroot00000000000000[![passport banner](http://cdn.auth0.com/img/passport-banner-github.png)](http://passportjs.org) # Passport Passport is [Express](http://expressjs.com/)-compatible authentication middleware for [Node.js](http://nodejs.org/). Passport's sole purpose is to authenticate requests, which it does through an extensible set of plugins known as _strategies_. Passport does not mount routes or assume any particular database schema, which maximizes flexibility and allows application-level decisions to be made by the developer. The API is simple: you provide Passport a request to authenticate, and Passport provides hooks for controlling what occurs when authentication succeeds or fails. ---

Sponsors

LoginRadius is built for the developer community to integrate robust Authentication and Single Sign-On in just a few lines of code.
FREE Signup


Your app, enterprise-ready.
Start selling to enterprise customers with just a few lines of code. Add Single Sign-On (and more) in minutes instead of months.

--- Status: [![Build](https://travis-ci.org/jaredhanson/passport.svg?branch=master)](https://travis-ci.org/jaredhanson/passport) [![Coverage](https://coveralls.io/repos/jaredhanson/passport/badge.svg?branch=master)](https://coveralls.io/r/jaredhanson/passport) [![Dependencies](https://david-dm.org/jaredhanson/passport.svg)](https://david-dm.org/jaredhanson/passport) ## Install ``` $ npm install passport ``` ## Usage #### Strategies Passport uses the concept of strategies to authenticate requests. Strategies can range from verifying username and password credentials, delegated authentication using [OAuth](http://oauth.net/) (for example, via [Facebook](http://www.facebook.com/) or [Twitter](http://twitter.com/)), or federated authentication using [OpenID](http://openid.net/). Before authenticating requests, the strategy (or strategies) used by an application must be configured. ```javascript passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username }, function (err, user) { if (err) { return done(err); } if (!user) { return done(null, false); } if (!user.verifyPassword(password)) { return done(null, false); } return done(null, user); }); } )); ``` There are 480+ strategies. Find the ones you want at: [passportjs.org](http://passportjs.org) #### Sessions Passport will maintain persistent login sessions. In order for persistent sessions to work, the authenticated user must be serialized to the session, and deserialized when subsequent requests are made. Passport does not impose any restrictions on how your user records are stored. Instead, you provide functions to Passport which implements the necessary serialization and deserialization logic. In a typical application, this will be as simple as serializing the user ID, and finding the user by ID when deserializing. ```javascript passport.serializeUser(function(user, done) { done(null, user.id); }); passport.deserializeUser(function(id, done) { User.findById(id, function (err, user) { done(err, user); }); }); ``` #### Middleware To use Passport in an [Express](http://expressjs.com/) or [Connect](http://senchalabs.github.com/connect/)-based application, configure it with the required `passport.initialize()` middleware. If your application uses persistent login sessions (recommended, but not required), `passport.session()` middleware must also be used. ```javascript var app = express(); app.use(require('serve-static')(__dirname + '/../../public')); app.use(require('cookie-parser')()); app.use(require('body-parser').urlencoded({ extended: true })); app.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session()); ``` #### Authenticate Requests Passport provides an `authenticate()` function, which is used as route middleware to authenticate requests. ```javascript app.post('/login', passport.authenticate('local', { failureRedirect: '/login' }), function(req, res) { res.redirect('/'); }); ``` ## Strategies Passport has a comprehensive set of **over 480** authentication strategies covering social networking, enterprise integration, API services, and more. ## Search all strategies There is a **Strategy Search** at [passportjs.org](http://passportjs.org) The following table lists commonly used strategies: |Strategy | Protocol |Developer | |---------------------------------------------------------------|--------------------------|------------------------------------------------| |[Local](https://github.com/jaredhanson/passport-local) | HTML form |[Jared Hanson](https://github.com/jaredhanson) | |[OpenID](https://github.com/jaredhanson/passport-openid) | OpenID |[Jared Hanson](https://github.com/jaredhanson) | |[BrowserID](https://github.com/jaredhanson/passport-browserid) | BrowserID |[Jared Hanson](https://github.com/jaredhanson) | |[Facebook](https://github.com/jaredhanson/passport-facebook) | OAuth 2.0 |[Jared Hanson](https://github.com/jaredhanson) | |[Google](https://github.com/jaredhanson/passport-google) | OpenID |[Jared Hanson](https://github.com/jaredhanson) | |[Google](https://github.com/jaredhanson/passport-google-oauth) | OAuth / OAuth 2.0 |[Jared Hanson](https://github.com/jaredhanson) | |[Twitter](https://github.com/jaredhanson/passport-twitter) | OAuth |[Jared Hanson](https://github.com/jaredhanson) | |[Azure Active Directory](https://github.com/AzureAD/passport-azure-ad) | OAuth 2.0 / OpenID / SAML |[Azure](https://github.com/azuread) | ## Examples - For a complete, working example, refer to the [example](https://github.com/passport/express-4.x-local-example) that uses [passport-local](https://github.com/jaredhanson/passport-local). - **Local Strategy**: Refer to the following tutorials for setting up user authentication via LocalStrategy (`passport-local`): - Mongo - Express v3x - [Tutorial](http://mherman.org/blog/2016/09/25/node-passport-and-postgres/#.V-govpMrJE5) / [working example](https://github.com/mjhea0/passport-local-knex) - Express v4x - [Tutorial](http://mherman.org/blog/2015/01/31/local-authentication-with-passport-and-express-4/) / [working example](https://github.com/mjhea0/passport-local-express4) - Postgres - [Tutorial](http://mherman.org/blog/2015/01/31/local-authentication-with-passport-and-express-4/) / [working example](https://github.com/mjhea0/passport-local-express4) - **Social Authentication**: Refer to the following tutorials for setting up various social authentication strategies: - Express v3x - [Tutorial](http://mherman.org/blog/2013/11/10/social-authentication-with-passport-dot-js/) / [working example](https://github.com/mjhea0/passport-examples) - Express v4x - [Tutorial](http://mherman.org/blog/2015/09/26/social-authentication-in-node-dot-js-with-passport) / [working example](https://github.com/mjhea0/passport-social-auth) ## Related Modules - [Locomotive](https://github.com/jaredhanson/locomotive) — Powerful MVC web framework - [OAuthorize](https://github.com/jaredhanson/oauthorize) — OAuth service provider toolkit - [OAuth2orize](https://github.com/jaredhanson/oauth2orize) — OAuth 2.0 authorization server toolkit - [connect-ensure-login](https://github.com/jaredhanson/connect-ensure-login) — middleware to ensure login sessions The [modules](https://github.com/jaredhanson/passport/wiki/Modules) page on the [wiki](https://github.com/jaredhanson/passport/wiki) lists other useful modules that build upon or integrate with Passport. ## License [The MIT License](http://opensource.org/licenses/MIT) Copyright (c) 2011-2019 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)> passport-0.5.0/SPONSORS.md000066400000000000000000000005771412320254000152010ustar00rootroot00000000000000## Gold Sponsors [![LoginRadius](https://raw.githubusercontent.com/jaredhanson/passport/master/sponsors/loginradius.png)](https://www.loginradius.com/)

[![WorkOS](https://raw.githubusercontent.com/jaredhanson/passport/master/sponsors/workos.png)](https://workos.com/) ## Sponsors - [CodePilot.ai](https://codepilot.ai/) - Kelly Burke - [Matt Miller](https://mmiller.me/) passport-0.5.0/lib/000077500000000000000000000000001412320254000141265ustar00rootroot00000000000000passport-0.5.0/lib/authenticator.js000066400000000000000000000320601412320254000173370ustar00rootroot00000000000000/** * Module dependencies. */ var SessionStrategy = require('./strategies/session') , SessionManager = require('./sessionmanager'); /** * `Authenticator` constructor. * * @api public */ function Authenticator() { this._key = 'passport'; this._strategies = {}; this._serializers = []; this._deserializers = []; this._infoTransformers = []; this._framework = null; this.init(); } /** * Initialize authenticator. * * @api protected */ Authenticator.prototype.init = function() { this.framework(require('./framework/connect')()); this.use(new SessionStrategy({ key: this._key }, this.deserializeUser.bind(this))); this._sm = new SessionManager({ key: this._key }, this.serializeUser.bind(this)); }; /** * Utilize the given `strategy` with optional `name`, overridding the strategy's * default name. * * Examples: * * passport.use(new TwitterStrategy(...)); * * passport.use('api', new http.BasicStrategy(...)); * * @param {String|Strategy} name * @param {Strategy} strategy * @return {Authenticator} for chaining * @api public */ Authenticator.prototype.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; }; /** * Un-utilize the `strategy` with given `name`. * * In typical applications, the necessary authentication strategies are static, * configured once and always available. As such, there is often no need to * invoke this function. * * 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]; return this; }; /** * Setup Passport to be used under framework. * * By default, Passport exposes middleware that operate using Connect-style * middleware using a `fn(req, res, next)` signature. Other popular frameworks * have different expectations, and this function allows Passport to be adapted * to operate within such environments. * * If you are using a Connect-compatible framework, including Express, there is * no need to invoke this function. * * Examples: * * passport.framework(require('hapi-passport')()); * * @param {Object} name * @return {Authenticator} for chaining * @api public */ Authenticator.prototype.framework = function(fw) { this._framework = fw; return this; }; /** * Passport's primary initialization middleware. * * This middleware must be in use by the Connect/Express application for * 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 */ Authenticator.prototype.initialize = function(options) { options = options || {}; return this._framework.initialize(this, options); }; /** * 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); * * app.get('/auth/twitter', passport.authenticate('twitter'), function(req, res) { * // request will be redirected to Twitter * }); * app.get('/auth/twitter/callback', passport.authenticate('twitter'), function(req, res) { * res.json(req.user); * }); * * @param {String} strategy * @param {Object} options * @param {Function} callback * @return {Function} middleware * @api public */ Authenticator.prototype.authenticate = function(strategy, options, callback) { return this._framework.authenticate(this, strategy, options, callback); }; /** * Middleware that will authorize a third-party account using the given * `strategy` name, with optional `options`. * * If authorization is successful, the result provided by the strategy's verify * callback will be assigned to `req.account`. The existing login session and * `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) { options = options || {}; options.assignProperty = 'account'; var fn = this._framework.authorize || this._framework.authenticate; return fn(this, strategy, options, callback); }; /** * Middleware that will restore login state from a session. * * Web applications typically use sessions to maintain login state between * requests. For example, a user will authenticate by entering credentials into * a form which is submitted to the server. If the credentials are valid, a * login session is established by setting a cookie containing a session * identifier in the user's web browser. The web browser will send this cookie * in subsequent requests to the server, allowing a session to be maintained. * * If sessions are being utilized, and a login session has been established, * this middleware will populate `req.user` with the current user. * * Note that sessions are not strictly required for Passport to operate. * 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 * request body is configured after passport and the * deserializeUser method is asynchronous. * * @param {Object} options * @return {Function} middleware * @api public */ Authenticator.prototype.session = function(options) { return this.authenticate('session', options); }; // TODO: Make session manager pluggable /* Authenticator.prototype.sessionManager = function(mgr) { this._sm = mgr; return this; } */ /** * 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') { 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 deserialize user objects out of the session. * * Examples: * * passport.deserializeUser(function(id, done) { * User.findById(id, function (err, user) { * done(err, user); * }); * }); * * @api public */ Authenticator.prototype.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 transform auth info. * * In some circumstances authorization details are contained in authentication * credentials or loaded as part of verification. * * For example, when using bearer tokens for API authentication, the tokens may * encode (either directly or indirectly in a database), details such as scope * of access or the client to which the token was issued. * * Such authorization details should be enforced separately from authentication. * Because Passport deals only with the latter, this is the responsiblity of * middleware or routes further along the chain. However, it is not optimal to * decode the same data or execute the same database query later. To avoid * this, Passport accepts optional `info` along with the authenticated `user` * in a strategy's `success()` action. This info is set at `req.authInfo`, * where said later middlware or routes can access it. * * Optionally, applications can register transforms to proccess this info, * which take effect prior to `req.authInfo` being set. This is useful, for * example, when the info contains a client ID. The transform can load the * client from the database and include the instance in the transformed info, * 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 */ Authenticator.prototype.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); }; /** * Return strategy with given `name`. * * @param {String} name * @return {Strategy} * @api private */ Authenticator.prototype._strategy = function(name) { return this._strategies[name]; }; /** * Expose `Authenticator`. */ module.exports = Authenticator; passport-0.5.0/lib/errors/000077500000000000000000000000001412320254000154425ustar00rootroot00000000000000passport-0.5.0/lib/errors/authenticationerror.js000066400000000000000000000006661412320254000221010ustar00rootroot00000000000000/** * `AuthenticationError` error. * * @constructor * @api private */ function AuthenticationError(message, status) { Error.call(this); Error.captureStackTrace(this, arguments.callee); this.name = 'AuthenticationError'; this.message = message; this.status = status || 401; } // Inherit from `Error`. AuthenticationError.prototype.__proto__ = Error.prototype; // Expose constructor. module.exports = AuthenticationError; passport-0.5.0/lib/framework/000077500000000000000000000000001412320254000161235ustar00rootroot00000000000000passport-0.5.0/lib/framework/connect.js000066400000000000000000000007701412320254000201160ustar00rootroot00000000000000/** * Module dependencies. */ var initialize = require('../middleware/initialize') , authenticate = require('../middleware/authenticate'); /** * Framework support for Connect/Express. * * This module provides support for using Passport with Express. It exposes * middleware that conform to the `fn(req, res, next)` signature. * * @return {Object} * @api protected */ exports = module.exports = function() { return { initialize: initialize, authenticate: authenticate }; }; passport-0.5.0/lib/http/000077500000000000000000000000001412320254000151055ustar00rootroot00000000000000passport-0.5.0/lib/http/request.js000066400000000000000000000034151412320254000171360ustar00rootroot00000000000000var req = exports = module.exports = {}; /** * Initiate a login session for `user`. * * Options: * - `session` Save login state in session, defaults to _true_ * * Examples: * * req.logIn(user, { session: false }); * * req.logIn(user, function(err) { * if (err) { throw err; } * // session saved * }); * * @param {User} user * @param {Object} options * @param {Function} done * @api public */ req.login = req.logIn = function(user, options, done) { if (typeof options == 'function') { done = options; options = {}; } options = options || {}; var property = this._userProperty || 'user'; var session = (options.session === undefined) ? true : options.session; this[property] = user; if (session) { if (!this._passport) { throw new Error('passport.initialize() middleware not in use'); } if (typeof done != 'function') { throw new Error('req#login requires a callback function'); } var self = this; this._passport.instance._sm.logIn(this, user, function(err) { if (err) { self[property] = null; return done(err); } done(); }); } else { done && done(); } }; /** * Terminate an existing login session. * * @api public */ req.logout = req.logOut = function() { var property = this._userProperty || 'user'; this[property] = null; if (this._passport) { this._passport.instance._sm.logOut(this); } }; /** * Test if request is authenticated. * * @return {Boolean} * @api public */ req.isAuthenticated = function() { var property = this._userProperty || 'user'; return (this[property]) ? true : false; }; /** * Test if request is unauthenticated. * * @return {Boolean} * @api public */ req.isUnauthenticated = function() { return !this.isAuthenticated(); }; passport-0.5.0/lib/index.js000066400000000000000000000007321412320254000155750ustar00rootroot00000000000000/** * Module dependencies. */ var Passport = require('./authenticator') , SessionStrategy = require('./strategies/session'); /** * Export default singleton. * * @api public */ exports = module.exports = new Passport(); /** * Expose constructors. */ exports.Passport = exports.Authenticator = Passport; exports.Strategy = require('passport-strategy'); /** * Expose strategies. */ exports.strategies = {}; exports.strategies.SessionStrategy = SessionStrategy; passport-0.5.0/lib/middleware/000077500000000000000000000000001412320254000162435ustar00rootroot00000000000000passport-0.5.0/lib/middleware/authenticate.js000066400000000000000000000322421412320254000212620ustar00rootroot00000000000000/** * Module dependencies. */ var http = require('http') , IncomingMessageExt = require('../http/request') , AuthenticationError = require('../errors/authenticationerror'); /** * Authenticates requests. * * Applies the `name`ed strategy (or strategies) to the incoming request, in * order to authenticate the request. If authentication is successful, the user * will be logged in and populated at `req.user` and a session will be * established by default. If authentication fails, an unauthorized response * will be sent. * * Options: * - `session` Save login state in session, defaults to _true_ * - `successRedirect` After successful login, redirect to given URL * - `successMessage` True to store success message in * req.session.messages, or a string to use as override * message for success. * - `successFlash` True to flash success messages or a string to use as a flash * message for success (overrides any from the strategy itself). * - `failureRedirect` After failed login, redirect to given URL * - `failureMessage` True to store failure message in * req.session.messages, or a string to use as override * message for failure. * - `failureFlash` True to flash failure messages or a string to use as a flash * message for failures (overrides any from the strategy itself). * - `assignProperty` Assign the object provided by the verify callback to given property * * An optional `callback` can be supplied to allow the application to override * the default manner in which authentication attempts are handled. The * callback has the following signature, where `user` will be set to the * authenticated user on a successful authentication attempt, or `false` * otherwise. An optional `info` argument will be passed, containing additional * details provided by the strategy's verify callback - this could be information about * a successful authentication or a challenge message for a failed authentication. * An optional `status` argument will be passed when authentication fails - this could * be a HTTP response code for a remote authentication failure or similar. * * app.get('/protected', function(req, res, next) { * passport.authenticate('local', function(err, user, info, status) { * if (err) { return next(err) } * if (!user) { return res.redirect('/signin') } * res.redirect('/account'); * })(req, res, next); * }); * * Note that if a callback is supplied, it becomes the application's * responsibility to log-in the user, establish a session, and otherwise perform * the desired operations. * * Examples: * * passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' }); * * passport.authenticate('basic', { session: false }); * * passport.authenticate('twitter'); * * @param {Strategy|String|Array} name * @param {Object} options * @param {Function} callback * @return {Function} * @api public */ module.exports = 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) { // 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 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 strategy, prototype; if (typeof layer.authenticate == 'function') { strategy = layer; } else { prototype = passport._strategy(layer); if (!prototype) { return next(new Error('Unknown authentication strategy "' + layer + '"')); } strategy = Object.create(prototype); } // ----- BEGIN STRATEGY AUGMENTATION ----- // Augment the new strategy instance with action functions. These action // functions are bound via closure the the request/response pair. The end // goal of the strategy is to invoke *one* of these action methods, in // order to indicate successful or failed authentication, redirect to a // third-party identity provider, etc. /** * Authenticate `user`, with optional `info`. * * Strategies should call this function to successfully authenticate a * user. `user` should be an object supplied by the application after it * has been given an opportunity to verify credentials. `info` is an * optional argument containing additional user information. This is * useful for third-party authentication strategies to pass profile * details. * * @param {Object} user * @param {Object} info * @api public */ strategy.success = function(user, info) { if (callback) { return callback(null, user, info); } info = info || {}; var msg; if (options.successFlash) { var flash = options.successFlash; if (typeof flash == 'string') { flash = { type: 'success', message: flash }; } flash.type = flash.type || 'success'; var type = flash.type || info.type || 'success'; msg = flash.message || info.message || info; if (typeof msg == 'string') { req.flash(type, msg); } } if (options.successMessage) { msg = options.successMessage; if (typeof msg == 'boolean') { msg = info.message || info; } if (typeof msg == 'string') { req.session.messages = req.session.messages || []; req.session.messages.push(msg); } } if (options.assignProperty) { req[options.assignProperty] = user; return next(); } req.logIn(user, options, function(err) { if (err) { return next(err); } function complete() { if (options.successReturnToOrRedirect) { var url = options.successReturnToOrRedirect; if (req.session && req.session.returnTo) { url = req.session.returnTo; delete req.session.returnTo; } return res.redirect(url); } if (options.successRedirect) { return res.redirect(options.successRedirect); } next(); } if (options.authInfo !== false) { passport.transformAuthInfo(info, req, function(err, tinfo) { if (err) { return next(err); } req.authInfo = tinfo; complete(); }); } else { complete(); } }); }; /** * Fail authentication, with optional `challenge` and `status`, defaulting * to 401. * * Strategies should call this function to fail an authentication attempt. * * @param {String} challenge * @param {Number} status * @api public */ strategy.fail = function(challenge, status) { if (typeof challenge == 'number') { status = challenge; challenge = undefined; } // push this failure into the accumulator and attempt authentication // using the next strategy failures.push({ challenge: challenge, status: status }); attempt(i + 1); }; /** * Redirect to `url` with optional `status`, defaulting to 302. * * Strategies should call this function to redirect the user (via their * user agent) to a third-party website for authentication. * * @param {String} url * @param {Number} status * @api public */ strategy.redirect = function(url, status) { // NOTE: Do not use `res.redirect` from Express, because it can't decide // what it wants. // // Express 2.x: res.redirect(url, status) // Express 3.x: res.redirect(status, url) -OR- res.redirect(url, status) // - as of 3.14.0, deprecated warnings are issued if res.redirect(url, status) // is used // Express 4.x: res.redirect(status, url) // - all versions (as of 4.8.7) continue to accept res.redirect(url, status) // but issue deprecated versions res.statusCode = status || 302; res.setHeader('Location', url); res.setHeader('Content-Length', '0'); res.end(); }; /** * Pass without making a success or fail decision. * * Under most circumstances, Strategies should not need to call this * function. It exists primarily to allow previous authentication state * to be restored, for example from an HTTP session. * * @api public */ strategy.pass = function() { next(); }; /** * Internal error while performing authentication. * * Strategies should call this function when an internal error occurs * during the process of performing authentication; for example, if the * user directory is not available. * * @param {Error} err * @api public */ strategy.error = function(err) { if (callback) { return callback(err); } next(err); }; // ----- END STRATEGY AUGMENTATION ----- strategy.authenticate(req, options); })(0); // attempt }; }; passport-0.5.0/lib/middleware/initialize.js000066400000000000000000000041421412320254000207430ustar00rootroot00000000000000/** * Module dependencies. */ var IncomingMessageExt = require('../http/request'); /** * Passport initialization. * * Intializes Passport for incoming requests, allowing authentication strategies * to be applied. * * If sessions are being utilized, applications must set up Passport with * functions to serialize a user into and out of a session. For example, a * common pattern is to serialize just the user ID into the session (due to the * fact that it is desirable to store the minimum amount of data in a session). * When a subsequent request arrives for the session, the full User object can * be loaded from the database by ID. * * Note that additional middleware is required to persist login state, so we * must use the `connect.session()` middleware _before_ `passport.initialize()`. * * If sessions are being used, this middleware must be in use by the * Connect/Express application for Passport to operate. If the application is * entirely stateless (not using sessions), this middleware is not necessary, * but its use will not have any adverse impact. * * Examples: * * app.use(connect.cookieParser()); * app.use(connect.session({ secret: 'keyboard cat' })); * app.use(passport.initialize()); * app.use(passport.session()); * * passport.serializeUser(function(user, done) { * done(null, user.id); * }); * * passport.deserializeUser(function(id, done) { * User.findById(id, function (err, user) { * done(err, user); * }); * }); * * @return {Function} * @api public */ module.exports = function initialize(passport, options) { options = options || {}; return function initialize(req, res, next) { req.login = req.logIn = IncomingMessageExt.logIn; req.logout = req.logOut = IncomingMessageExt.logOut; req.isAuthenticated = IncomingMessageExt.isAuthenticated; req.isUnauthenticated = IncomingMessageExt.isUnauthenticated; if (options.userProperty) { req._userProperty = options.userProperty; } req._passport = {}; req._passport.instance = passport; next(); }; }; passport-0.5.0/lib/sessionmanager.js000066400000000000000000000015511412320254000175040ustar00rootroot00000000000000function SessionManager(options, serializeUser) { if (typeof options == 'function') { serializeUser = options; options = undefined; } options = options || {}; this._key = options.key || 'passport'; this._serializeUser = serializeUser; } SessionManager.prototype.logIn = function(req, user, cb) { var self = this; this._serializeUser(user, req, function(err, obj) { if (err) { return cb(err); } // TODO: Error if session isn't available here. if (!req.session) { req.session = {}; } if (!req.session[self._key]) { req.session[self._key] = {}; } req.session[self._key].user = obj; cb(); }); } SessionManager.prototype.logOut = function(req, cb) { if (req.session && req.session[this._key]) { delete req.session[this._key].user; } cb && cb(); } module.exports = SessionManager; passport-0.5.0/lib/strategies/000077500000000000000000000000001412320254000163005ustar00rootroot00000000000000passport-0.5.0/lib/strategies/session.js000066400000000000000000000040341412320254000203220ustar00rootroot00000000000000/** * Module dependencies. */ var pause = require('pause') , util = require('util') , Strategy = require('passport-strategy'); /** * `SessionStrategy` constructor. * * @api public */ function SessionStrategy(options, deserializeUser) { if (typeof options == 'function') { deserializeUser = options; options = undefined; } options = options || {}; Strategy.call(this); this.name = 'session'; this._key = options.key || 'passport'; this._deserializeUser = deserializeUser; } /** * Inherit from `Strategy`. */ util.inherits(SessionStrategy, Strategy); /** * Authenticate request based on the current session state. * * The session authentication strategy uses the session to restore any login * state across requests. If a login session has been established, `req.user` * will be populated with the current user. * * This strategy is registered automatically by Passport. * * @param {Object} req * @param {Object} options * @api protected */ SessionStrategy.prototype.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.session[this._key]) { su = req.session[this._key].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; this._deserializeUser(su, req, function(err, user) { if (err) { return self.error(err); } if (!user) { delete req.session[self._key].user; } else { var property = req._userProperty || 'user'; req[property] = user; } self.pass(); if (paused) { paused.resume(); } }); } else { self.pass(); } }; /** * Expose `SessionStrategy`. */ module.exports = SessionStrategy; passport-0.5.0/package.json000066400000000000000000000023431412320254000156500ustar00rootroot00000000000000{ "name": "passport", "version": "0.5.0", "description": "Simple, unobtrusive authentication for Node.js.", "keywords": [ "express", "connect", "auth", "authn", "authentication" ], "author": { "name": "Jared Hanson", "email": "jaredhanson@gmail.com", "url": "http://www.jaredhanson.net/" }, "homepage": "http://passportjs.org/", "repository": { "type": "git", "url": "git://github.com/jaredhanson/passport.git" }, "bugs": { "url": "http://github.com/jaredhanson/passport/issues" }, "funding": { "type": "github", "url": "https://github.com/sponsors/jaredhanson" }, "license": "MIT", "licenses": [ { "type": "MIT", "url": "http://opensource.org/licenses/MIT" } ], "main": "./lib", "dependencies": { "passport-strategy": "1.x.x", "pause": "0.0.1" }, "devDependencies": { "make-node": "0.3.x", "mocha": "2.x.x", "chai": "2.x.x", "chai-connect-middleware": "0.3.x", "chai-passport-strategy": "0.2.x", "proxyquire": "1.4.x" }, "engines": { "node": ">= 0.4.0" }, "scripts": { "test": "node_modules/.bin/mocha --reporter spec --require test/bootstrap/node test/*.test.js test/**/*.test.js" } } passport-0.5.0/sponsors/000077500000000000000000000000001412320254000152465ustar00rootroot00000000000000passport-0.5.0/sponsors/loginradius.png000066400000000000000000000252101412320254000202740ustar00rootroot00000000000000PNG  IHDR2B.sRGB pHYs  #iTXtXML:com.adobe.xmp 2 0 72 1 72 243 1 50 2020-12-11T11:12:93 Pixelmator 3.9 o%IDATx} ŝ]3 aP9 :jĿfn\k52 + D#Ѩ@\`8BaPfޛ~^ B^Mw__ZPgV!}̾$2vOH9~[H-}@>|c bIaN]_$D"{7iF44m;?Eh϶,3 NB&A2U5t1yy h?1OzV:tq Jyp Tĭ> =FثtݨSc.|l}ЦIޖ{&lXj\By h1߷Z-~%=OnpTфK0BzXj4[\U[shVsyR?XUф|_l BՊPVmvPi ʪ$r/D.@PD|ALԹ<ִ.0]FL6hCqVt(%^wRYU :Hl ٌbI4&Y5R MI -l">G| 6ב-AJG#=N!<881^9!rKvKOl6ckנ?3vy+8kO"i~#]%rFݱ|7l U%`>"cy[ s,Y4[Vt'tRRs06oSkuπ~gd@BzFFr[#N~IXLU"K s_A] dEV=Bq#[ ٘.wL¶7-M<4Ar ^~ӑŋܴ#᚝}{P XAa|; K֜>+rXq|e4/iCR$&i[_ڨT\Wj`檱 ;2ScyNQZ*j-kKÒ;TMVS x;N$g xFLM<ƞ5nô7Pc K7#剹CaѪ`iŝ婂/7KVRdKJf3 1,~}?Fuzp`cB+!1* Y9?m<ufдV K|#ZJI`& NsҞ1"{4m[8F};R_[5ܲœaY/Iɼc 3$ /?Yяg_OՃ1)Dt`2 kЀ E{$zKP5~6nOEfJ{cy2a>o΢_xdɤibY ee>H_jP *v^k'u'Tq]J;"i2b3۞5ьقiRn _Qo^G[@>[5`>&M*%S(WQo2{icXÀC>ƤnkLŖ' M7%%kYU hthΩ) ܇qa W^b @<5 8sfA_% /is SqJK[Il )X!@@'f0987f@xYzNpF1b2cѧ2 Z>,CkW5KB%'#ut4u 9X]C8<Ky) dfO7+ҏ &*$[6gb.,hSaW8K-ۤO~oãPv[ tK)j h7)d!#,4~$;KKweZs 30.U-\F*osX8ej'b.빃s8 X;մ%7չ.?>jmmYe(P2Ѝ:W? $lmLPo~جPe2ϕc-hvT㯤@d W /j}GuӰf"̝/KW]j x|8a6&N%ILJ3Hs׼3чl3kPd`gPF ?(GwT63MllyA$a*?⤅KO&,0`GKRxbhFirM/[`w-)k0hN,괥".OJ+*L)A^0"@Ը{};1Eƭȁ6`N7Ո{ f 4 8: Kn"㮸Nu@o<ϳbv+3 Y c. -p+Nb1p3"{=ٴd^|^gIbÒ-sgZhMr38\h V U Opg\Wlgǿ3 iq)s:.ĵd+97 o(iVQ'sO8yяi-~,C6ˏ=Q+D䛎bcO)i[fͅ`[:i.m&ܜkFX_2~00&\H r~!nS8/peUQ ]ButꅃcP (onj:T<vҍbH=n,K]pU%rx9/ A!NELSt Y؎a:'Z`+è>!fE. Z8|m Syю&F P.'TtoHKoY %tm#kDۥߖcI̶`R1^w=YѓStC5G/ŊsEӭjfjLWbw wvI{f[R]i N^07v x:k7d|UB;9b^A"0fj! k,,B?(*F?gIYkS{-=e٫ߥ)U7> v}rmsŻ2໔V~$xI%)(]T1eCm} %%q`FcFʏ /$WJ*O5qTiU&@~7Am?lGbn/lhu`Xb bp4@0|RHf<$CUQ/Z+1K0/ZR8QssLH'+.TrEjM[(a^Lʜ[j.,<"E:ܬx= 8p4c'X sc\JU^쀶*dgaG#B/čI^u.!Vq>%((39Re|=4XAx4q)Yqz"MhC)Ӝpc m3uR~ b#RC9L&d v :ē 3!:vp _|JXƙN,<;%([yRqh*#ʓN3X K='XZ0o)7AX{저߇bj31~IqQ: RcAUT6"`~dvjUL2ϡ-7ɯZn1&)݆>F@xe9K,%ck pJf<w(T,_vIBX ºczJg`487`'Y$j6 fHtbVo)%oGLm8VMH'&:h=+rfOm\O89?9sQvڂH'snN,,*нp=dXE f<sǽ9aW07~$\-]{ڏ3qǷBvP0 ש:)$ "Ω4jfI>! ȕRڮmM'ܟ(D~̭ GH?P9>n eM8ʮ>"./-GM oB1fZd .ROt@Ia%v[^^R ڼ~.ސ_H?  q茅1Խ3 tB5%#, >z7vjb.ϧemTޜ|t+±=ar=<HTȉ$X'v6/>WӰM視GRƹbddcOgank`' ȝ/5qu\E)|-]ֲ/w MLG !)ɀaLŶ^ t#vZyi{ᵪ&$7dV@- w= :Kt@"z[YC5 ~o†զů/2ԲQՙkYb2h+Ltw ˾2P #Dіx3G:Gѧn|,ϕP F!R* C X(3F,O[6 W{Ɔ;oh1h~'=m]f9r~٢ʁ/""* $I3E;п0]ЬlǑIi⟨לCHr(*vɐʬ"M LmWue8  ڽě+ܠcvG-+ݻ%:gY l b&>th:k4pm>X),B76$vjGA}s5=loٰ6WYHr :{4fp|L66`%|%#g9vx['cDt4Ėq|q17Ip٧[Ky_4'!5îij;}&9Tjՙ#~qc 78w% _LY/!&31Dq6ݨ6_0y-V_, u/i憛A!bTpg5.֐G㠄 !V)aɾ@h7p?fDqsJ{# DsW?) 8\qIRIYk(˕w/D$Y* 11 Q!J񭧷5bRZ[f)KTb FK!Ē@jtjaǮ,,pbV V: +pvag].*K+o;PinFRx_-8'>}'6$2Ƥq.aX~Z6~i" xt/|Q\{L|  J @ccSۼ Ӵ$1snj"Wag[ |A>M3W^Hdџ5 i>7曵!YE|6ifXOu@m~u&Hgy:ybpj_xa8: v(#̨&g G]i竌Kjp 2e ߋS -S0- j'f{2`SW\[b@(K28p8qPĶ~ڕL]gb*iYO}1*t⺋0.KU||2^VnV([{;4Z;F^"N~ }w Ӫ#`H U#^ľޅ/YƜ[5%Y@o> u: M *o<00!7[]|fendҸ&'2Z>"S Czm"-׍8Pe4N"AՃ: ~"78`勣ŐN {)bHuj>+BV,!sjr KP΂$e7g2'={Ry#G`촭e@MX)ctp] Jz4B]pLi-^\Fjk[d#Ĉ瀳~3*LD!s"~h/sИ ҆܋1hN6m{Eaq]5R/Oc[h$߻N0/4ׁ}|κlu`Zk#iǡ->>yfUW3/0r=H CR% U;cbW%/LnbOn8cbݑW'0tcnVVP"8RDQI kmXXdʐУ-A>d'f.ڟOa]L> W!4wu l5U$RVC%N?,qⴾfՓЌQF8 BPɈM)scu쁏֕lf^.X{+hY m`UŲ>& Y ò%ϣ$?z1SG,ļ!'Dqj8xgߵ1c,{reS/AIg\B~5wˆ|8OXvɇ<881sE8g"$2eyzp$S+UsAO`be!zf4?zS+E(y[@ ]p1JQ8d$M!GG]c]ck`򐝍l8<{}'Wn@Ԛ4K37iM1S 0!J|ZOn;0Oog^XA03̮[5ZX:aIoE܀=8vB<2YenB?&bfn>cIq݉316`J"+\WB&r@J+bG=!++00 ?ީ+|a2 yg8fm^{_}.qпn 59iǎagV%lmA$k8j GTA>1B?~IENDB`passport-0.5.0/sponsors/workos.png000066400000000000000000000160061412320254000173030ustar00rootroot00000000000000PNG  IHDR2#+sRGBeXIfMM*JR(iZHH2J pHYs  YiTXtXML:com.adobe.xmp 1 ^IDATx qWՍ  a#+'L0`L*Ʀ8.W6 >8pˁ$pjZ@q d!$[w>fmСK ISoG'jqpVXe)(nZ)z -5xtFD<W]7>\2zgN˖-{A:p8Xb"v --Lu2⿡NգMH믿3vis㒀j'hw(:4tT焨!:6`0]ɾ\Rzh:5q5wQ)~ގobq»":e50t=@_thD~Ih1م6xhPNÐWOìZŒ\E`V,bnmIIR~ZK/7v] ԬUFEzYäie5i}!p 7Ih9Cເo;S^GҺz뉴{t,oP?<"귞Zj"3m_*\ 8wSASxcJrFAv8yg9$Ё:G l-:Em5P+-'W_,[][Rv-JQ|rz2;HW(BĖ|(vuG@;h=Nx\=8 lkX< ,g"0aC ]F h37ɏEMʁWcF: CH8'r^LyuP]*~~ԗ9fu_bee۾ poJXnxxyNb dzJ .g|[ F?_r''p| GndZL.x,f[;WO8̡mhOʭ r&FޑaáJh@d݆$ GP ~* G*^>ɈAg~]V1`>*&6otEt|'cX'-ts%=дBA}׮]{m}hQ@li$AcS@ ma0uP &Nc]-2s bBa.ZR^u F2z>m{++>jw~σ}A^>ߋXt|Oб7羆sZu8.dLBr{49SI*k`WX %VCw{[C x- ʪ3w'/"i۶A h€ mjrt~3lG+y><+<~͚5̇$MwF&z póvz4sI'g]bVˋeTR/+:teқ'I_Iʭwu/ #o~~#4U&SjxC,RrZ po nHkcJNg@*tߚu|Xq$g_- Zow_bp$-#p9ߑ?2y| =eV)kCX!W ԓA ~GR^(A^w:yuq~`W]W m+]=&,n^`򂣎+An0~yeOY,EYx?v~@6PK瞄얚gq-{o"L|s;Nc,y/uB\lo>eiI{uX .O:7er!a?DY ]k'a,;V[83; TNhLb*ks^mj֭[x]`_/H@7+Ю" z3m>C*6) a$ _'XiC 6iFG!i'uF8 v1)90v=.1NĎ+e'ٞ&ȧloˁx)ndB0>XTeϋ1yL*gyVO>dd`^Ʃ#9WmNtc7^bC}` Lz~&cVc1+/?T+MO<7R#MIz~8gҼ[HmoaEޓ~:jU)- eMjIjjP,V o8b?~mW0kkuŘݝx>}t\ⳛ>^Fy>)O M퇐.Į{G^Jjؑ yp~)c%m'7i\H:4bU[ ×8HӬLN!|뭏,~i ?Kr˿*辯?vdyrEK̔` Oϒ7EPӹ)VcyOg,u\!|L/~9pRKufer5E'oQCK$vSM mvXQLOj8qTXqs%r]}h_9mWuRRWb5ı):[Cnt[-p63a@e3>НeO9jepI/[n_m7xi)|eD>lf_:uSF CwG(*S*slo9\{==) E9%J_bFxfA[Y%pHsA 3>QV&Twf󬿁3a7^#ݗBQkD4O>HQ|ȉWlQXO*4+$_LT6|E} ԋ`#4X H,^$#wܢ33g^yJl)'M o9vĬE]4L)ge*8UnD|$(ཕ,qWoJ+mV>9cl-u2΋x"pd~By7ORe-զߊӋvAwOK:Hp?@JrYC+יR[{&Ȏ2-~0Z!hLzܾFrxI_A%%; (x 8?!`OfE wgCF۴d!W?G0><:}CXtmWYH_m٧YoTꢏɶ TVU~b@%lsTF'"XϞq$o=iy VTu@WadpT++oFw3X~P˕8)~or{yqGLJooo_?0_03rߕ3'S>A ;' Cy7EۜL#!t+(QkR['pu E@]RUo6V ]t:v; {,b,8VGhq?xjPS{pEZ='1QAC hcR'tg/,(Z#&>S;+Ӡ+aW3멷f&? 2<(~'BO H3lg'hД#}x s{?\@ձ :[#'D4O7|(v_l݂ WH,`)Lx[;`:`@8xu!bm4lӴ5`y9ȴMZȼYF.j|~v9@2'mg9| 44|!k%ʎqgp[ ˘LD>(Bz2$?[ta#eXT켪 uTZsf!4G?>t&U% vڇXQ 寈*C,UL]I]{ȥA,0:1&},Ǥ'{!G)믢~E?$w'Bórho U9TG_?h^UˣC0U{cMc~]Nkl%~T+UyTj܇fG:튓|iGaM]cU@ퟗѽi%l|jFaQOA78 ?Y/d"F[w}tvn$'Lr9)