Initial working google auth

This commit is contained in:
JBB0807 2025-04-16 10:49:46 -07:00
parent fb52d49f74
commit 00a40f6bba
1058 changed files with 114441 additions and 0 deletions

View file

@ -0,0 +1 @@
github: jaredhanson

36
auth-service/node_modules/passport-oauth2/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,36 @@
# 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).
## [Unreleased]
## [1.8.0] - 2024-02-02
### Fixed
- Fixed intermittent "Failed to obtain access token" error by updating `oauth`
dependency from 0.9.x to 0.10.x. This error seems to occur more frequently on
fast connections which get reset after receiving an access token response.
## [1.7.0] - 2023-03-02
### Added
- Support for authorization response parameters encoded as HTML form values, as
specified by [OAuth 2.0 Form Post Response Mode](https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html).
## [1.6.1] - 2021-09-24
### Fixed
- Error in cases where the authorization server returns a successful access
token response which is missing an `access_token` parameter.
## [1.6.0] - 2021-07-01
### Added
- Support for `store: true` option to `Strategy` constructor, which initializes
a state store capable of storing application-level state.
- Support for `state` object passed as option to `authenticate`, which will be
persisted in the session by state store.
- `callbackURL` property added to metadata passed to state store.
[Unreleased]: https://github.com/jaredhanson/passport-oauth2/compare/v1.7.0...HEAD
[1.7.0]: https://github.com/jaredhanson/passport-oauth2/compare/v1.6.1...v1.7.0

20
auth-service/node_modules/passport-oauth2/LICENSE generated vendored Normal file
View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2011-2016 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.

129
auth-service/node_modules/passport-oauth2/README.md generated vendored Normal file
View file

@ -0,0 +1,129 @@
# passport-oauth2
General-purpose OAuth 2.0 authentication strategy for [Passport](https://www.passportjs.org/).
This module lets you authenticate using OAuth 2.0 in your Node.js applications.
By plugging into Passport, OAuth 2.0-based sign in can be easily and
unobtrusively integrated into any application or framework that supports
[Connect](https://github.com/senchalabs/connect#readme)-style middleware, including
[Express](https://expressjs.com/).
Note that this strategy provides generic OAuth 2.0 support. In many cases, a
provider-specific strategy can be used instead, which cuts down on unnecessary
configuration, and accommodates any provider-specific quirks. See the
[list](https://github.com/jaredhanson/passport/wiki/Strategies) for supported
providers.
Developers who need to implement authentication against an OAuth 2.0 provider
that is not already supported are encouraged to sub-class this strategy. If you
choose to open source the new provider-specific strategy, please add it to the
list so other people can find it.
<div align="center">
:brain: [Understanding OAuth 2.0](https://www.passportjs.org/concepts/oauth2/?utm_source=github&utm_medium=referral&utm_campaign=passport-oauth2&utm_content=nav-concept) •
:heart: [Sponsors](https://www.passportjs.org/sponsors/?utm_source=github&utm_medium=referral&utm_campaign=passport-oauth2&utm_content=nav-sponsors)
</div>
---
<p align="center">
<sup>Advertisement</sup>
<br>
<a href="https://click.linksynergy.com/link?id=D*o7yui4/NM&offerid=507388.380582&type=2&murl=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Flearn-oauth-2%2F&u1=5I2riUEiNIRjPjdjxj6X4exzu3lhRkWY0et6Y8eyT3">Learn OAuth 2.0 - Get started as an API Security Expert</a><br>Just imagine what could happen to YOUR professional career if you had skills in OAuth > 8500 satisfied students
</p>
---
[![npm](https://img.shields.io/npm/v/passport-oauth2.svg)](https://www.npmjs.com/package/passport-oauth2)
[![build](https://img.shields.io/travis/jaredhanson/passport-oauth2.svg)](https://travis-ci.org/jaredhanson/passport-oauth2)
[![coverage](https://img.shields.io/coveralls/jaredhanson/passport-oauth2.svg)](https://coveralls.io/github/jaredhanson/passport-oauth2)
[...](https://github.com/jaredhanson/passport-oauth2/wiki/Status)
## Install
$ npm install passport-oauth2
## Usage
#### Configure Strategy
The OAuth 2.0 authentication strategy authenticates users using a third-party
account and OAuth 2.0 tokens. The provider's OAuth 2.0 endpoints, as well as
the client identifer and secret, are specified as options. The strategy
requires a `verify` callback, which receives an access token and profile,
and calls `cb` providing a user.
```js
passport.use(new OAuth2Strategy({
authorizationURL: 'https://www.example.com/oauth2/authorize',
tokenURL: 'https://www.example.com/oauth2/token',
clientID: EXAMPLE_CLIENT_ID,
clientSecret: EXAMPLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/example/callback"
},
function(accessToken, refreshToken, profile, cb) {
User.findOrCreate({ exampleId: profile.id }, function (err, user) {
return cb(err, user);
});
}
));
```
#### Authenticate Requests
Use `passport.authenticate()`, specifying the `'oauth2'` strategy, to
authenticate requests.
For example, as route middleware in an [Express](http://expressjs.com/)
application:
```js
app.get('/auth/example',
passport.authenticate('oauth2'));
app.get('/auth/example/callback',
passport.authenticate('oauth2', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
```
## Related Modules
- [passport-oauth1](https://github.com/jaredhanson/passport-oauth1) — OAuth 1.0 authentication strategy
- [passport-http-bearer](https://github.com/jaredhanson/passport-http-bearer) — Bearer token authentication strategy for APIs
- [OAuth2orize](https://github.com/jaredhanson/oauth2orize) — OAuth 2.0 authorization server toolkit
## Contributing
#### Tests
The test suite is located in the `test/` directory. All new features are
expected to have corresponding test cases. Ensure that the complete test suite
passes by executing:
```bash
$ make test
```
#### Coverage
All new feature development is expected to have test coverage. Patches that
increse test coverage are happily accepted. Coverage reports can be viewed by
executing:
```bash
$ make test-cov
$ make view-cov
```
## License
[The MIT License](http://opensource.org/licenses/MIT)
Copyright (c) 2011-2016 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>

View file

@ -0,0 +1,44 @@
/**
* `AuthorizationError` error.
*
* AuthorizationError represents an error in response to an authorization
* request. For details, refer to RFC 6749, section 4.1.2.1.
*
* References:
* - [The OAuth 2.0 Authorization Framework](http://tools.ietf.org/html/rfc6749)
*
* @constructor
* @param {String} [message]
* @param {String} [code]
* @param {String} [uri]
* @param {Number} [status]
* @api public
*/
function AuthorizationError(message, code, uri, status) {
if (!status) {
switch (code) {
case 'access_denied': status = 403; break;
case 'server_error': status = 502; break;
case 'temporarily_unavailable': status = 503; break;
}
}
Error.call(this);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = message;
this.code = code || 'server_error';
this.uri = uri;
this.status = status || 500;
}
/**
* Inherit from `Error`.
*/
AuthorizationError.prototype.__proto__ = Error.prototype;
/**
* Expose `AuthorizationError`.
*/
module.exports = AuthorizationError;

View file

@ -0,0 +1,49 @@
/**
* `InternalOAuthError` error.
*
* InternalOAuthError wraps errors generated by node-oauth. By wrapping these
* objects, error messages can be formatted in a manner that aids in debugging
* OAuth issues.
*
* @constructor
* @param {String} [message]
* @param {Object|Error} [err]
* @api public
*/
function InternalOAuthError(message, err) {
Error.call(this);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = message;
this.oauthError = err;
}
/**
* Inherit from `Error`.
*/
InternalOAuthError.prototype.__proto__ = Error.prototype;
/**
* Returns a string representing the error.
*
* @return {String}
* @api public
*/
InternalOAuthError.prototype.toString = function() {
var m = this.name;
if (this.message) { m += ': ' + this.message; }
if (this.oauthError) {
if (this.oauthError instanceof Error) {
m = this.oauthError.toString();
} else if (this.oauthError.statusCode && this.oauthError.data) {
m += ' (status: ' + this.oauthError.statusCode + ' data: ' + this.oauthError.data + ')';
}
}
return m;
};
/**
* Expose `InternalOAuthError`.
*/
module.exports = InternalOAuthError;

View file

@ -0,0 +1,36 @@
/**
* `TokenError` error.
*
* TokenError represents an error received from a token endpoint. For details,
* refer to RFC 6749, section 5.2.
*
* References:
* - [The OAuth 2.0 Authorization Framework](http://tools.ietf.org/html/rfc6749)
*
* @constructor
* @param {String} [message]
* @param {String} [code]
* @param {String} [uri]
* @param {Number} [status]
* @api public
*/
function TokenError(message, code, uri, status) {
Error.call(this);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.message = message;
this.code = code || 'invalid_request';
this.uri = uri;
this.status = status || 500;
}
/**
* Inherit from `Error`.
*/
TokenError.prototype.__proto__ = Error.prototype;
/**
* Expose `TokenError`.
*/
module.exports = TokenError;

16
auth-service/node_modules/passport-oauth2/lib/index.js generated vendored Normal file
View file

@ -0,0 +1,16 @@
// Load modules.
var Strategy = require('./strategy')
, AuthorizationError = require('./errors/authorizationerror')
, TokenError = require('./errors/tokenerror')
, InternalOAuthError = require('./errors/internaloautherror');
// Expose Strategy.
exports = module.exports = Strategy;
// Exports.
exports.Strategy = Strategy;
exports.AuthorizationError = AuthorizationError;
exports.TokenError = TokenError;
exports.InternalOAuthError = InternalOAuthError;

View file

@ -0,0 +1,13 @@
function NullStore(options) {
}
NullStore.prototype.store = function(req, cb) {
cb();
}
NullStore.prototype.verify = function(req, providedState, cb) {
cb(null, true);
}
module.exports = NullStore;

View file

@ -0,0 +1,89 @@
var uid = require('uid2');
/**
* Creates an instance of `SessionStore`.
*
* This is the state store implementation for the OAuth2Strategy used when
* the `state` option is enabled. It generates a random state and stores it in
* `req.session` and verifies it when the service provider redirects the user
* back to the application.
*
* This state store requires session support. If no session exists, an error
* will be thrown.
*
* Options:
*
* - `key` The key in the session under which to store the state
*
* @constructor
* @param {Object} options
* @api public
*/
function PKCESessionStore(options) {
if (!options.key) { throw new TypeError('Session-based state store requires a session key'); }
this._key = options.key;
}
/**
* Store request state.
*
* This implementation simply generates a random string and stores the value in
* the session, where it will be used for verification when the user is
* redirected back to the application.
*
* @param {Object} req
* @param {Function} callback
* @api protected
*/
PKCESessionStore.prototype.store = function(req, verifier, state, meta, callback) {
if (!req.session) { return callback(new Error('OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?')); }
var key = this._key;
var sstate = {
handle: uid(24),
code_verifier: verifier
};
if (state) { sstate.state = state; }
if (!req.session[key]) { req.session[key] = {}; }
req.session[key].state = sstate;
callback(null, sstate.handle);
};
/**
* Verify request state.
*
* This implementation simply compares the state parameter in the request to the
* value generated earlier and stored in the session.
*
* @param {Object} req
* @param {String} providedState
* @param {Function} callback
* @api protected
*/
PKCESessionStore.prototype.verify = function(req, providedState, callback) {
if (!req.session) { return callback(new Error('OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?')); }
var key = this._key;
if (!req.session[key]) {
return callback(null, false, { message: 'Unable to verify authorization request state.' });
}
var state = req.session[key].state;
if (!state) {
return callback(null, false, { message: 'Unable to verify authorization request state.' });
}
delete req.session[key].state;
if (Object.keys(req.session[key]).length === 0) {
delete req.session[key];
}
if (state.handle !== providedState) {
return callback(null, false, { message: 'Invalid authorization request state.' });
}
return callback(null, state.code_verifier, state.state);
};
// Expose constructor.
module.exports = PKCESessionStore;

View file

@ -0,0 +1,85 @@
var uid = require('uid2');
/**
* Creates an instance of `SessionStore`.
*
* This is the state store implementation for the OAuth2Strategy used when
* the `state` option is enabled. It generates a random state and stores it in
* `req.session` and verifies it when the service provider redirects the user
* back to the application.
*
* This state store requires session support. If no session exists, an error
* will be thrown.
*
* Options:
*
* - `key` The key in the session under which to store the state
*
* @constructor
* @param {Object} options
* @api public
*/
function SessionStore(options) {
if (!options.key) { throw new TypeError('Session-based state store requires a session key'); }
this._key = options.key;
}
/**
* Store request state.
*
* This implementation simply generates a random string and stores the value in
* the session, where it will be used for verification when the user is
* redirected back to the application.
*
* @param {Object} req
* @param {Function} callback
* @api protected
*/
SessionStore.prototype.store = function(req, callback) {
if (!req.session) { return callback(new Error('OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?')); }
var key = this._key;
var state = uid(24);
if (!req.session[key]) { req.session[key] = {}; }
req.session[key].state = state;
callback(null, state);
};
/**
* Verify request state.
*
* This implementation simply compares the state parameter in the request to the
* value generated earlier and stored in the session.
*
* @param {Object} req
* @param {String} providedState
* @param {Function} callback
* @api protected
*/
SessionStore.prototype.verify = function(req, providedState, callback) {
if (!req.session) { return callback(new Error('OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?')); }
var key = this._key;
if (!req.session[key]) {
return callback(null, false, { message: 'Unable to verify authorization request state.' });
}
var state = req.session[key].state;
if (!state) {
return callback(null, false, { message: 'Unable to verify authorization request state.' });
}
delete req.session[key].state;
if (Object.keys(req.session[key]).length === 0) {
delete req.session[key];
}
if (state !== providedState) {
return callback(null, false, { message: 'Invalid authorization request state.' });
}
return callback(null, true);
};
// Expose constructor.
module.exports = SessionStore;

View file

@ -0,0 +1,88 @@
var uid = require('uid2');
/**
* Creates an instance of `SessionStore`.
*
* This is the state store implementation for the OAuth2Strategy used when
* the `state` option is enabled. It generates a random state and stores it in
* `req.session` and verifies it when the service provider redirects the user
* back to the application.
*
* This state store requires session support. If no session exists, an error
* will be thrown.
*
* Options:
*
* - `key` The key in the session under which to store the state
*
* @constructor
* @param {Object} options
* @api public
*/
function SessionStore(options) {
if (!options.key) { throw new TypeError('Session-based state store requires a session key'); }
this._key = options.key;
}
/**
* Store request state.
*
* This implementation simply generates a random string and stores the value in
* the session, where it will be used for verification when the user is
* redirected back to the application.
*
* @param {Object} req
* @param {Function} callback
* @api protected
*/
SessionStore.prototype.store = function(req, state, meta, callback) {
if (!req.session) { return callback(new Error('OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?')); }
var key = this._key;
var sstate = {
handle: uid(24)
};
if (state) { sstate.state = state; }
if (!req.session[key]) { req.session[key] = {}; }
req.session[key].state = sstate;
callback(null, sstate.handle);
};
/**
* Verify request state.
*
* This implementation simply compares the state parameter in the request to the
* value generated earlier and stored in the session.
*
* @param {Object} req
* @param {String} providedState
* @param {Function} callback
* @api protected
*/
SessionStore.prototype.verify = function(req, providedState, callback) {
if (!req.session) { return callback(new Error('OAuth 2.0 authentication requires session support when using state. Did you forget to use express-session middleware?')); }
var key = this._key;
if (!req.session[key]) {
return callback(null, false, { message: 'Unable to verify authorization request state.' });
}
var state = req.session[key].state;
if (!state) {
return callback(null, false, { message: 'Unable to verify authorization request state.' });
}
delete req.session[key].state;
if (Object.keys(req.session[key]).length === 0) {
delete req.session[key];
}
if (state.handle !== providedState) {
return callback(null, false, { message: 'Invalid authorization request state.' });
}
return callback(null, true, state.state);
};
// Expose constructor.
module.exports = SessionStore;

View file

@ -0,0 +1,429 @@
// Load modules.
var passport = require('passport-strategy')
, url = require('url')
, uid = require('uid2')
, crypto = require('crypto')
, base64url = require('base64url')
, util = require('util')
, utils = require('./utils')
, OAuth2 = require('oauth').OAuth2
, NullStore = require('./state/null')
, NonceStore = require('./state/session')
, StateStore = require('./state/store')
, PKCEStateStore = require('./state/pkcesession')
, AuthorizationError = require('./errors/authorizationerror')
, TokenError = require('./errors/tokenerror')
, InternalOAuthError = require('./errors/internaloautherror');
/**
* Creates an instance of `OAuth2Strategy`.
*
* The OAuth 2.0 authentication strategy authenticates requests using the OAuth
* 2.0 framework.
*
* OAuth 2.0 provides a facility for delegated authentication, whereby users can
* authenticate using a third-party service such as Facebook. Delegating in
* this manner involves a sequence of events, including redirecting the user to
* the third-party service for authorization. Once authorization has been
* granted, the user is redirected back to the application and an authorization
* code can be used to obtain credentials.
*
* Applications must supply a `verify` callback, for which the function
* signature is:
*
* function(accessToken, refreshToken, profile, done) { ... }
*
* The verify callback is responsible for finding or creating the user, and
* invoking `done` with the following arguments:
*
* done(err, user, info);
*
* `user` should be set to `false` to indicate an authentication failure.
* Additional `info` can optionally be passed as a third argument, typically
* used to display informational messages. If an exception occured, `err`
* should be set.
*
* Options:
*
* - `authorizationURL` URL used to obtain an authorization grant
* - `tokenURL` URL used to obtain an access token
* - `clientID` identifies client to service provider
* - `clientSecret` secret used to establish ownership of the client identifer
* - `callbackURL` URL to which the service provider will redirect the user after obtaining authorization
* - `passReqToCallback` when `true`, `req` is the first argument to the verify callback (default: `false`)
*
* Examples:
*
* passport.use(new OAuth2Strategy({
* authorizationURL: 'https://www.example.com/oauth2/authorize',
* tokenURL: 'https://www.example.com/oauth2/token',
* clientID: '123-456-789',
* clientSecret: 'shhh-its-a-secret'
* callbackURL: 'https://www.example.net/auth/example/callback'
* },
* function(accessToken, refreshToken, profile, done) {
* User.findOrCreate(..., function (err, user) {
* done(err, user);
* });
* }
* ));
*
* @constructor
* @param {Object} options
* @param {Function} verify
* @api public
*/
function OAuth2Strategy(options, verify) {
if (typeof options == 'function') {
verify = options;
options = undefined;
}
options = options || {};
if (!verify) { throw new TypeError('OAuth2Strategy requires a verify callback'); }
if (!options.authorizationURL) { throw new TypeError('OAuth2Strategy requires a authorizationURL option'); }
if (!options.tokenURL) { throw new TypeError('OAuth2Strategy requires a tokenURL option'); }
if (!options.clientID) { throw new TypeError('OAuth2Strategy requires a clientID option'); }
passport.Strategy.call(this);
this.name = 'oauth2';
this._verify = verify;
// NOTE: The _oauth2 property is considered "protected". Subclasses are
// allowed to use it when making protected resource requests to retrieve
// the user profile.
this._oauth2 = new OAuth2(options.clientID, options.clientSecret,
'', options.authorizationURL, options.tokenURL, options.customHeaders);
this._callbackURL = options.callbackURL;
this._scope = options.scope;
this._scopeSeparator = options.scopeSeparator || ' ';
this._pkceMethod = (options.pkce === true) ? 'S256' : options.pkce;
this._key = options.sessionKey || ('oauth2:' + url.parse(options.authorizationURL).hostname);
if (options.store && typeof options.store == 'object') {
this._stateStore = options.store;
} else if (options.store) {
this._stateStore = options.pkce ? new PKCEStateStore({ key: this._key }) : new StateStore({ key: this._key });
} else if (options.state) {
this._stateStore = options.pkce ? new PKCEStateStore({ key: this._key }) : new NonceStore({ key: this._key });
} else {
if (options.pkce) { throw new TypeError('OAuth2Strategy requires `state: true` option when PKCE is enabled'); }
this._stateStore = new NullStore();
}
this._trustProxy = options.proxy;
this._passReqToCallback = options.passReqToCallback;
this._skipUserProfile = (options.skipUserProfile === undefined) ? false : options.skipUserProfile;
}
// Inherit from `passport.Strategy`.
util.inherits(OAuth2Strategy, passport.Strategy);
/**
* Authenticate request by delegating to a service provider using OAuth 2.0.
*
* @param {Object} req
* @api protected
*/
OAuth2Strategy.prototype.authenticate = function(req, options) {
options = options || {};
var self = this;
if (req.query && req.query.error) {
if (req.query.error == 'access_denied') {
return this.fail({ message: req.query.error_description });
} else {
return this.error(new AuthorizationError(req.query.error_description, req.query.error, req.query.error_uri));
}
}
var callbackURL = options.callbackURL || this._callbackURL;
if (callbackURL) {
var parsed = url.parse(callbackURL);
if (!parsed.protocol) {
// The callback URL is relative, resolve a fully qualified URL from the
// URL of the originating request.
callbackURL = url.resolve(utils.originalURL(req, { proxy: this._trustProxy }), callbackURL);
}
}
var meta = {
authorizationURL: this._oauth2._authorizeUrl,
tokenURL: this._oauth2._accessTokenUrl,
clientID: this._oauth2._clientId,
callbackURL: callbackURL
}
if ((req.query && req.query.code) || (req.body && req.body.code)) {
function loaded(err, ok, state) {
if (err) { return self.error(err); }
if (!ok) {
return self.fail(state, 403);
}
var code = (req.query && req.query.code) || (req.body && req.body.code);
var params = self.tokenParams(options);
params.grant_type = 'authorization_code';
if (callbackURL) { params.redirect_uri = callbackURL; }
if (typeof ok == 'string') { // PKCE
params.code_verifier = ok;
}
self._oauth2.getOAuthAccessToken(code, params,
function(err, accessToken, refreshToken, params) {
if (err) { return self.error(self._createOAuthError('Failed to obtain access token', err)); }
if (!accessToken) { return self.error(new Error('Failed to obtain access token')); }
self._loadUserProfile(accessToken, function(err, profile) {
if (err) { return self.error(err); }
function verified(err, user, info) {
if (err) { return self.error(err); }
if (!user) { return self.fail(info); }
info = info || {};
if (state) { info.state = state; }
self.success(user, info);
}
try {
if (self._passReqToCallback) {
var arity = self._verify.length;
if (arity == 6) {
self._verify(req, accessToken, refreshToken, params, profile, verified);
} else { // arity == 5
self._verify(req, accessToken, refreshToken, profile, verified);
}
} else {
var arity = self._verify.length;
if (arity == 5) {
self._verify(accessToken, refreshToken, params, profile, verified);
} else { // arity == 4
self._verify(accessToken, refreshToken, profile, verified);
}
}
} catch (ex) {
return self.error(ex);
}
});
}
);
}
var state = (req.query && req.query.state) || (req.body && req.body.state);
try {
var arity = this._stateStore.verify.length;
if (arity == 4) {
this._stateStore.verify(req, state, meta, loaded);
} else { // arity == 3
this._stateStore.verify(req, state, loaded);
}
} catch (ex) {
return this.error(ex);
}
} else {
var params = this.authorizationParams(options);
params.response_type = 'code';
if (callbackURL) { params.redirect_uri = callbackURL; }
var scope = options.scope || this._scope;
if (scope) {
if (Array.isArray(scope)) { scope = scope.join(this._scopeSeparator); }
params.scope = scope;
}
var verifier, challenge;
if (this._pkceMethod) {
verifier = base64url(crypto.pseudoRandomBytes(32))
switch (this._pkceMethod) {
case 'plain':
challenge = verifier;
break;
case 'S256':
challenge = base64url(crypto.createHash('sha256').update(verifier).digest());
break;
default:
return this.error(new Error('Unsupported code verifier transformation method: ' + this._pkceMethod));
}
params.code_challenge = challenge;
params.code_challenge_method = this._pkceMethod;
}
var state = options.state;
if (state && typeof state == 'string') {
// NOTE: In passport-oauth2@1.5.0 and earlier, `state` could be passed as
// an object. However, it would result in an empty string being
// serialized as the value of the query parameter by `url.format()`,
// effectively ignoring the option. This implies that `state` was
// only functional when passed as a string value.
//
// This fact is taken advantage of here to fall into the `else`
// branch below when `state` is passed as an object. In that case
// the state will be automatically managed and persisted by the
// state store.
params.state = state;
var parsed = url.parse(this._oauth2._authorizeUrl, true);
utils.merge(parsed.query, params);
parsed.query['client_id'] = this._oauth2._clientId;
delete parsed.search;
var location = url.format(parsed);
this.redirect(location);
} else {
function stored(err, state) {
if (err) { return self.error(err); }
if (state) { params.state = state; }
var parsed = url.parse(self._oauth2._authorizeUrl, true);
utils.merge(parsed.query, params);
parsed.query['client_id'] = self._oauth2._clientId;
delete parsed.search;
var location = url.format(parsed);
self.redirect(location);
}
try {
var arity = this._stateStore.store.length;
if (arity == 5) {
this._stateStore.store(req, verifier, state, meta, stored);
} else if (arity == 4) {
this._stateStore.store(req, state, meta, stored);
} else if (arity == 3) {
this._stateStore.store(req, meta, stored);
} else { // arity == 2
this._stateStore.store(req, stored);
}
} catch (ex) {
return this.error(ex);
}
}
}
};
/**
* Retrieve user profile from service provider.
*
* OAuth 2.0-based authentication strategies can overrride this function in
* order to load the user's profile from the service provider. This assists
* applications (and users of those applications) in the initial registration
* process by automatically submitting required information.
*
* @param {String} accessToken
* @param {Function} done
* @api protected
*/
OAuth2Strategy.prototype.userProfile = function(accessToken, done) {
return done(null, {});
};
/**
* Return extra parameters to be included in the authorization request.
*
* Some OAuth 2.0 providers allow additional, non-standard parameters to be
* included when requesting authorization. Since these parameters are not
* standardized by the OAuth 2.0 specification, OAuth 2.0-based authentication
* strategies can overrride this function in order to populate these parameters
* as required by the provider.
*
* @param {Object} options
* @return {Object}
* @api protected
*/
OAuth2Strategy.prototype.authorizationParams = function(options) {
return {};
};
/**
* Return extra parameters to be included in the token request.
*
* Some OAuth 2.0 providers allow additional, non-standard parameters to be
* included when requesting an access token. Since these parameters are not
* standardized by the OAuth 2.0 specification, OAuth 2.0-based authentication
* strategies can overrride this function in order to populate these parameters
* as required by the provider.
*
* @return {Object}
* @api protected
*/
OAuth2Strategy.prototype.tokenParams = function(options) {
return {};
};
/**
* Parse error response from OAuth 2.0 endpoint.
*
* OAuth 2.0-based authentication strategies can overrride this function in
* order to parse error responses received from the token endpoint, allowing the
* most informative message to be displayed.
*
* If this function is not overridden, the body will be parsed in accordance
* with RFC 6749, section 5.2.
*
* @param {String} body
* @param {Number} status
* @return {Error}
* @api protected
*/
OAuth2Strategy.prototype.parseErrorResponse = function(body, status) {
var json = JSON.parse(body);
if (json.error) {
return new TokenError(json.error_description, json.error, json.error_uri);
}
return null;
};
/**
* Load user profile, contingent upon options.
*
* @param {String} accessToken
* @param {Function} done
* @api private
*/
OAuth2Strategy.prototype._loadUserProfile = function(accessToken, done) {
var self = this;
function loadIt() {
return self.userProfile(accessToken, done);
}
function skipIt() {
return done(null);
}
if (typeof this._skipUserProfile == 'function' && this._skipUserProfile.length > 1) {
// async
this._skipUserProfile(accessToken, function(err, skip) {
if (err) { return done(err); }
if (!skip) { return loadIt(); }
return skipIt();
});
} else {
var skip = (typeof this._skipUserProfile == 'function') ? this._skipUserProfile() : this._skipUserProfile;
if (!skip) { return loadIt(); }
return skipIt();
}
};
/**
* Create an OAuth error.
*
* @param {String} message
* @param {Object|Error} err
* @api private
*/
OAuth2Strategy.prototype._createOAuthError = function(message, err) {
var e;
if (err.statusCode && err.data) {
try {
e = this.parseErrorResponse(err.data, err.statusCode);
} catch (_) {}
}
if (!e) { e = new InternalOAuthError(message, err); }
return e;
};
// Expose constructor.
module.exports = OAuth2Strategy;

32
auth-service/node_modules/passport-oauth2/lib/utils.js generated vendored Normal file
View file

@ -0,0 +1,32 @@
exports.merge = require('utils-merge');
/**
* Reconstructs the original URL of the request.
*
* This function builds a URL that corresponds the original URL requested by the
* client, including the protocol (http or https) and host.
*
* If the request passed through any proxies that terminate SSL, the
* `X-Forwarded-Proto` header is used to detect if the request was encrypted to
* the proxy, assuming that the proxy has been flagged as trusted.
*
* @param {http.IncomingMessage} req
* @param {Object} [options]
* @return {String}
* @api private
*/
exports.originalURL = function(req, options) {
options = options || {};
var app = req.app;
if (app && app.get && app.get('trust proxy')) {
options.proxy = true;
}
var trustProxy = options.proxy;
var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
, tls = req.connection.encrypted || (trustProxy && 'https' == proto.split(/\s*,\s*/)[0])
, host = (trustProxy && req.headers['x-forwarded-host']) || req.headers.host
, protocol = tls ? 'https' : 'http'
, path = req.url || '';
return protocol + '://' + host + path;
};

59
auth-service/node_modules/passport-oauth2/package.json generated vendored Normal file
View file

@ -0,0 +1,59 @@
{
"name": "passport-oauth2",
"version": "1.8.0",
"description": "OAuth 2.0 authentication strategy for Passport.",
"keywords": [
"passport",
"auth",
"authn",
"authentication",
"authz",
"authorization",
"oauth",
"oauth2"
],
"author": {
"name": "Jared Hanson",
"email": "jaredhanson@gmail.com",
"url": "http://www.jaredhanson.net/"
},
"repository": {
"type": "git",
"url": "git://github.com/jaredhanson/passport-oauth2.git"
},
"bugs": {
"url": "http://github.com/jaredhanson/passport-oauth2/issues"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/jaredhanson"
},
"license": "MIT",
"licenses": [
{
"type": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
],
"main": "./lib",
"dependencies": {
"base64url": "3.x.x",
"oauth": "0.10.x",
"passport-strategy": "1.x.x",
"uid2": "0.0.x",
"utils-merge": "1.x.x"
},
"devDependencies": {
"make-node": "0.4.6",
"mocha": "2.x.x",
"chai": "2.x.x",
"proxyquire": "0.6.x",
"chai-passport-strategy": "1.x.x"
},
"engines": {
"node": ">= 0.4.0"
},
"scripts": {
"test": "node_modules/.bin/mocha --reporter spec --require test/bootstrap/node test/*.test.js test/**/*.test.js"
}
}