react-oauth-flow
Advanced tools
Comparing version 1.1.1 to 1.1.2
@@ -1,1027 +0,2 @@ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('prop-types')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'react', 'prop-types'], factory) : | ||
(factory((global.ReactOauthFlow = {}),global.React,global.PropTypes)); | ||
}(this, (function (exports,React,PropTypes) { 'use strict'; | ||
PropTypes = PropTypes && PropTypes.hasOwnProperty('default') ? PropTypes['default'] : PropTypes; | ||
function createCommonjsModule(fn, module) { | ||
return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
} | ||
var utils = createCommonjsModule(function (module, exports) { | ||
var has = Object.prototype.hasOwnProperty; | ||
var hexTable = (function () { | ||
var array = []; | ||
for (var i = 0; i < 256; ++i) { | ||
array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); | ||
} | ||
return array; | ||
}()); | ||
var compactQueue = function compactQueue(queue) { | ||
var obj; | ||
while (queue.length) { | ||
var item = queue.pop(); | ||
obj = item.obj[item.prop]; | ||
if (Array.isArray(obj)) { | ||
var compacted = []; | ||
for (var j = 0; j < obj.length; ++j) { | ||
if (typeof obj[j] !== 'undefined') { | ||
compacted.push(obj[j]); | ||
} | ||
} | ||
item.obj[item.prop] = compacted; | ||
} | ||
} | ||
return obj; | ||
}; | ||
exports.arrayToObject = function arrayToObject(source, options) { | ||
var obj = options && options.plainObjects ? Object.create(null) : {}; | ||
for (var i = 0; i < source.length; ++i) { | ||
if (typeof source[i] !== 'undefined') { | ||
obj[i] = source[i]; | ||
} | ||
} | ||
return obj; | ||
}; | ||
exports.merge = function merge(target, source, options) { | ||
if (!source) { | ||
return target; | ||
} | ||
if (typeof source !== 'object') { | ||
if (Array.isArray(target)) { | ||
target.push(source); | ||
} else if (typeof target === 'object') { | ||
if (options.plainObjects || options.allowPrototypes || !has.call(Object.prototype, source)) { | ||
target[source] = true; | ||
} | ||
} else { | ||
return [target, source]; | ||
} | ||
return target; | ||
} | ||
if (typeof target !== 'object') { | ||
return [target].concat(source); | ||
} | ||
var mergeTarget = target; | ||
if (Array.isArray(target) && !Array.isArray(source)) { | ||
mergeTarget = exports.arrayToObject(target, options); | ||
} | ||
if (Array.isArray(target) && Array.isArray(source)) { | ||
source.forEach(function (item, i) { | ||
if (has.call(target, i)) { | ||
if (target[i] && typeof target[i] === 'object') { | ||
target[i] = exports.merge(target[i], item, options); | ||
} else { | ||
target.push(item); | ||
} | ||
} else { | ||
target[i] = item; | ||
} | ||
}); | ||
return target; | ||
} | ||
return Object.keys(source).reduce(function (acc, key) { | ||
var value = source[key]; | ||
if (has.call(acc, key)) { | ||
acc[key] = exports.merge(acc[key], value, options); | ||
} else { | ||
acc[key] = value; | ||
} | ||
return acc; | ||
}, mergeTarget); | ||
}; | ||
exports.assign = function assignSingleSource(target, source) { | ||
return Object.keys(source).reduce(function (acc, key) { | ||
acc[key] = source[key]; | ||
return acc; | ||
}, target); | ||
}; | ||
exports.decode = function (str) { | ||
try { | ||
return decodeURIComponent(str.replace(/\+/g, ' ')); | ||
} catch (e) { | ||
return str; | ||
} | ||
}; | ||
exports.encode = function encode(str) { | ||
// This code was originally written by Brian White (mscdex) for the io.js core querystring library. | ||
// It has been adapted here for stricter adherence to RFC 3986 | ||
if (str.length === 0) { | ||
return str; | ||
} | ||
var string = typeof str === 'string' ? str : String(str); | ||
var out = ''; | ||
for (var i = 0; i < string.length; ++i) { | ||
var c = string.charCodeAt(i); | ||
if ( | ||
c === 0x2D // - | ||
|| c === 0x2E // . | ||
|| c === 0x5F // _ | ||
|| c === 0x7E // ~ | ||
|| (c >= 0x30 && c <= 0x39) // 0-9 | ||
|| (c >= 0x41 && c <= 0x5A) // a-z | ||
|| (c >= 0x61 && c <= 0x7A) // A-Z | ||
) { | ||
out += string.charAt(i); | ||
continue; | ||
} | ||
if (c < 0x80) { | ||
out = out + hexTable[c]; | ||
continue; | ||
} | ||
if (c < 0x800) { | ||
out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); | ||
continue; | ||
} | ||
if (c < 0xD800 || c >= 0xE000) { | ||
out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); | ||
continue; | ||
} | ||
i += 1; | ||
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); | ||
out += hexTable[0xF0 | (c >> 18)] | ||
+ hexTable[0x80 | ((c >> 12) & 0x3F)] | ||
+ hexTable[0x80 | ((c >> 6) & 0x3F)] | ||
+ hexTable[0x80 | (c & 0x3F)]; | ||
} | ||
return out; | ||
}; | ||
exports.compact = function compact(value) { | ||
var queue = [{ obj: { o: value }, prop: 'o' }]; | ||
var refs = []; | ||
for (var i = 0; i < queue.length; ++i) { | ||
var item = queue[i]; | ||
var obj = item.obj[item.prop]; | ||
var keys = Object.keys(obj); | ||
for (var j = 0; j < keys.length; ++j) { | ||
var key = keys[j]; | ||
var val = obj[key]; | ||
if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { | ||
queue.push({ obj: obj, prop: key }); | ||
refs.push(val); | ||
} | ||
} | ||
} | ||
return compactQueue(queue); | ||
}; | ||
exports.isRegExp = function isRegExp(obj) { | ||
return Object.prototype.toString.call(obj) === '[object RegExp]'; | ||
}; | ||
exports.isBuffer = function isBuffer(obj) { | ||
if (obj === null || typeof obj === 'undefined') { | ||
return false; | ||
} | ||
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); | ||
}; | ||
}); | ||
var utils_1 = utils.arrayToObject; | ||
var utils_2 = utils.merge; | ||
var utils_3 = utils.assign; | ||
var utils_4 = utils.decode; | ||
var utils_5 = utils.encode; | ||
var utils_6 = utils.compact; | ||
var utils_7 = utils.isRegExp; | ||
var utils_8 = utils.isBuffer; | ||
var replace = String.prototype.replace; | ||
var percentTwenties = /%20/g; | ||
var formats = { | ||
'default': 'RFC3986', | ||
formatters: { | ||
RFC1738: function (value) { | ||
return replace.call(value, percentTwenties, '+'); | ||
}, | ||
RFC3986: function (value) { | ||
return value; | ||
} | ||
}, | ||
RFC1738: 'RFC1738', | ||
RFC3986: 'RFC3986' | ||
}; | ||
var arrayPrefixGenerators = { | ||
brackets: function brackets(prefix) { // eslint-disable-line func-name-matching | ||
return prefix + '[]'; | ||
}, | ||
indices: function indices(prefix, key) { // eslint-disable-line func-name-matching | ||
return prefix + '[' + key + ']'; | ||
}, | ||
repeat: function repeat(prefix) { // eslint-disable-line func-name-matching | ||
return prefix; | ||
} | ||
}; | ||
var toISO = Date.prototype.toISOString; | ||
var defaults = { | ||
delimiter: '&', | ||
encode: true, | ||
encoder: utils.encode, | ||
encodeValuesOnly: false, | ||
serializeDate: function serializeDate(date) { // eslint-disable-line func-name-matching | ||
return toISO.call(date); | ||
}, | ||
skipNulls: false, | ||
strictNullHandling: false | ||
}; | ||
var stringify = function stringify( // eslint-disable-line func-name-matching | ||
object, | ||
prefix, | ||
generateArrayPrefix, | ||
strictNullHandling, | ||
skipNulls, | ||
encoder, | ||
filter, | ||
sort, | ||
allowDots, | ||
serializeDate, | ||
formatter, | ||
encodeValuesOnly | ||
) { | ||
var obj = object; | ||
if (typeof filter === 'function') { | ||
obj = filter(prefix, obj); | ||
} else if (obj instanceof Date) { | ||
obj = serializeDate(obj); | ||
} else if (obj === null) { | ||
if (strictNullHandling) { | ||
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder) : prefix; | ||
} | ||
obj = ''; | ||
} | ||
if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || utils.isBuffer(obj)) { | ||
if (encoder) { | ||
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder); | ||
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder))]; | ||
} | ||
return [formatter(prefix) + '=' + formatter(String(obj))]; | ||
} | ||
var values = []; | ||
if (typeof obj === 'undefined') { | ||
return values; | ||
} | ||
var objKeys; | ||
if (Array.isArray(filter)) { | ||
objKeys = filter; | ||
} else { | ||
var keys = Object.keys(obj); | ||
objKeys = sort ? keys.sort(sort) : keys; | ||
} | ||
for (var i = 0; i < objKeys.length; ++i) { | ||
var key = objKeys[i]; | ||
if (skipNulls && obj[key] === null) { | ||
continue; | ||
} | ||
if (Array.isArray(obj)) { | ||
values = values.concat(stringify( | ||
obj[key], | ||
generateArrayPrefix(prefix, key), | ||
generateArrayPrefix, | ||
strictNullHandling, | ||
skipNulls, | ||
encoder, | ||
filter, | ||
sort, | ||
allowDots, | ||
serializeDate, | ||
formatter, | ||
encodeValuesOnly | ||
)); | ||
} else { | ||
values = values.concat(stringify( | ||
obj[key], | ||
prefix + (allowDots ? '.' + key : '[' + key + ']'), | ||
generateArrayPrefix, | ||
strictNullHandling, | ||
skipNulls, | ||
encoder, | ||
filter, | ||
sort, | ||
allowDots, | ||
serializeDate, | ||
formatter, | ||
encodeValuesOnly | ||
)); | ||
} | ||
} | ||
return values; | ||
}; | ||
var stringify_1 = function (object, opts) { | ||
var obj = object; | ||
var options = opts ? utils.assign({}, opts) : {}; | ||
if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { | ||
throw new TypeError('Encoder has to be a function.'); | ||
} | ||
var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; | ||
var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; | ||
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; | ||
var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; | ||
var encoder = typeof options.encoder === 'function' ? options.encoder : defaults.encoder; | ||
var sort = typeof options.sort === 'function' ? options.sort : null; | ||
var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; | ||
var serializeDate = typeof options.serializeDate === 'function' ? options.serializeDate : defaults.serializeDate; | ||
var encodeValuesOnly = typeof options.encodeValuesOnly === 'boolean' ? options.encodeValuesOnly : defaults.encodeValuesOnly; | ||
if (typeof options.format === 'undefined') { | ||
options.format = formats['default']; | ||
} else if (!Object.prototype.hasOwnProperty.call(formats.formatters, options.format)) { | ||
throw new TypeError('Unknown format option provided.'); | ||
} | ||
var formatter = formats.formatters[options.format]; | ||
var objKeys; | ||
var filter; | ||
if (typeof options.filter === 'function') { | ||
filter = options.filter; | ||
obj = filter('', obj); | ||
} else if (Array.isArray(options.filter)) { | ||
filter = options.filter; | ||
objKeys = filter; | ||
} | ||
var keys = []; | ||
if (typeof obj !== 'object' || obj === null) { | ||
return ''; | ||
} | ||
var arrayFormat; | ||
if (options.arrayFormat in arrayPrefixGenerators) { | ||
arrayFormat = options.arrayFormat; | ||
} else if ('indices' in options) { | ||
arrayFormat = options.indices ? 'indices' : 'repeat'; | ||
} else { | ||
arrayFormat = 'indices'; | ||
} | ||
var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; | ||
if (!objKeys) { | ||
objKeys = Object.keys(obj); | ||
} | ||
if (sort) { | ||
objKeys.sort(sort); | ||
} | ||
for (var i = 0; i < objKeys.length; ++i) { | ||
var key = objKeys[i]; | ||
if (skipNulls && obj[key] === null) { | ||
continue; | ||
} | ||
keys = keys.concat(stringify( | ||
obj[key], | ||
key, | ||
generateArrayPrefix, | ||
strictNullHandling, | ||
skipNulls, | ||
encode ? encoder : null, | ||
filter, | ||
sort, | ||
allowDots, | ||
serializeDate, | ||
formatter, | ||
encodeValuesOnly | ||
)); | ||
} | ||
var joined = keys.join(delimiter); | ||
var prefix = options.addQueryPrefix === true ? '?' : ''; | ||
return joined.length > 0 ? prefix + joined : ''; | ||
}; | ||
var has = Object.prototype.hasOwnProperty; | ||
var defaults$1 = { | ||
allowDots: false, | ||
allowPrototypes: false, | ||
arrayLimit: 20, | ||
decoder: utils.decode, | ||
delimiter: '&', | ||
depth: 5, | ||
parameterLimit: 1000, | ||
plainObjects: false, | ||
strictNullHandling: false | ||
}; | ||
var parseValues = function parseQueryStringValues(str, options) { | ||
var obj = {}; | ||
var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; | ||
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit; | ||
var parts = cleanStr.split(options.delimiter, limit); | ||
for (var i = 0; i < parts.length; ++i) { | ||
var part = parts[i]; | ||
var bracketEqualsPos = part.indexOf(']='); | ||
var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1; | ||
var key, val; | ||
if (pos === -1) { | ||
key = options.decoder(part, defaults$1.decoder); | ||
val = options.strictNullHandling ? null : ''; | ||
} else { | ||
key = options.decoder(part.slice(0, pos), defaults$1.decoder); | ||
val = options.decoder(part.slice(pos + 1), defaults$1.decoder); | ||
} | ||
if (has.call(obj, key)) { | ||
obj[key] = [].concat(obj[key]).concat(val); | ||
} else { | ||
obj[key] = val; | ||
} | ||
} | ||
return obj; | ||
}; | ||
var parseObject = function (chain, val, options) { | ||
var leaf = val; | ||
for (var i = chain.length - 1; i >= 0; --i) { | ||
var obj; | ||
var root = chain[i]; | ||
if (root === '[]') { | ||
obj = []; | ||
obj = obj.concat(leaf); | ||
} else { | ||
obj = options.plainObjects ? Object.create(null) : {}; | ||
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; | ||
var index = parseInt(cleanRoot, 10); | ||
if ( | ||
!isNaN(index) | ||
&& root !== cleanRoot | ||
&& String(index) === cleanRoot | ||
&& index >= 0 | ||
&& (options.parseArrays && index <= options.arrayLimit) | ||
) { | ||
obj = []; | ||
obj[index] = leaf; | ||
} else { | ||
obj[cleanRoot] = leaf; | ||
} | ||
} | ||
leaf = obj; | ||
} | ||
return leaf; | ||
}; | ||
var parseKeys = function parseQueryStringKeys(givenKey, val, options) { | ||
if (!givenKey) { | ||
return; | ||
} | ||
// Transform dot notation to bracket notation | ||
var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; | ||
// The regex chunks | ||
var brackets = /(\[[^[\]]*])/; | ||
var child = /(\[[^[\]]*])/g; | ||
// Get the parent | ||
var segment = brackets.exec(key); | ||
var parent = segment ? key.slice(0, segment.index) : key; | ||
// Stash the parent if it exists | ||
var keys = []; | ||
if (parent) { | ||
// If we aren't using plain objects, optionally prefix keys | ||
// that would overwrite object prototype properties | ||
if (!options.plainObjects && has.call(Object.prototype, parent)) { | ||
if (!options.allowPrototypes) { | ||
return; | ||
} | ||
} | ||
keys.push(parent); | ||
} | ||
// Loop through children appending to the array until we hit depth | ||
var i = 0; | ||
while ((segment = child.exec(key)) !== null && i < options.depth) { | ||
i += 1; | ||
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) { | ||
if (!options.allowPrototypes) { | ||
return; | ||
} | ||
} | ||
keys.push(segment[1]); | ||
} | ||
// If there's a remainder, just add whatever is left | ||
if (segment) { | ||
keys.push('[' + key.slice(segment.index) + ']'); | ||
} | ||
return parseObject(keys, val, options); | ||
}; | ||
var parse = function (str, opts) { | ||
var options = opts ? utils.assign({}, opts) : {}; | ||
if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { | ||
throw new TypeError('Decoder has to be a function.'); | ||
} | ||
options.ignoreQueryPrefix = options.ignoreQueryPrefix === true; | ||
options.delimiter = typeof options.delimiter === 'string' || utils.isRegExp(options.delimiter) ? options.delimiter : defaults$1.delimiter; | ||
options.depth = typeof options.depth === 'number' ? options.depth : defaults$1.depth; | ||
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults$1.arrayLimit; | ||
options.parseArrays = options.parseArrays !== false; | ||
options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults$1.decoder; | ||
options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults$1.allowDots; | ||
options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults$1.plainObjects; | ||
options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults$1.allowPrototypes; | ||
options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults$1.parameterLimit; | ||
options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults$1.strictNullHandling; | ||
if (str === '' || str === null || typeof str === 'undefined') { | ||
return options.plainObjects ? Object.create(null) : {}; | ||
} | ||
var tempObj = typeof str === 'string' ? parseValues(str, options) : str; | ||
var obj = options.plainObjects ? Object.create(null) : {}; | ||
// Iterate over the keys and setup the new object | ||
var keys = Object.keys(tempObj); | ||
for (var i = 0; i < keys.length; ++i) { | ||
var key = keys[i]; | ||
var newObj = parseKeys(key, tempObj[key], options); | ||
obj = utils.merge(obj, newObj, options); | ||
} | ||
return utils.compact(obj); | ||
}; | ||
var lib = { | ||
formats: formats, | ||
parse: parse, | ||
stringify: stringify_1 | ||
}; | ||
var defineStaticProp = function (obj, key, value) { | ||
Object.defineProperty(obj, key, { | ||
enumerable: false, | ||
configurable: false, | ||
writable: false, | ||
value: value | ||
}); | ||
return obj; | ||
}; | ||
function fetch2(url, opts) { | ||
var request = fetch(url, opts); | ||
return request.then(function (response) { | ||
if (!response.ok) throw response; | ||
return response.json(); | ||
}).catch(function (err) { | ||
return err.json().then(function (errJSON) { | ||
var error = new Error(err.statusText); | ||
defineStaticProp(error, 'response', err); | ||
defineStaticProp(error.response, 'data', errJSON); | ||
defineStaticProp(error, 'request', request); | ||
throw error; | ||
}); | ||
}); | ||
} | ||
function buildURL(url, params, paramsSerializer) { | ||
if (params == null) return url; | ||
var serializedParams = void 0; | ||
if (paramsSerializer != null) { | ||
serializedParams = paramsSerializer(params); | ||
} else { | ||
serializedParams = lib.stringify(params); | ||
} | ||
if (!serializedParams) return url; | ||
return '' + url + (url.indexOf('?') < 0 ? '?' : '&') + serializedParams; | ||
} | ||
var classCallCheck = function (instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
}; | ||
var createClass = function () { | ||
function defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
return function (Constructor, protoProps, staticProps) { | ||
if (protoProps) defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
}; | ||
}(); | ||
var _extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
var inherits = function (subClass, superClass) { | ||
if (typeof superClass !== "function" && superClass !== null) { | ||
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); | ||
} | ||
subClass.prototype = Object.create(superClass && superClass.prototype, { | ||
constructor: { | ||
value: subClass, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
} | ||
}); | ||
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; | ||
}; | ||
var possibleConstructorReturn = function (self, call) { | ||
if (!self) { | ||
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | ||
} | ||
return call && (typeof call === "object" || typeof call === "function") ? call : self; | ||
}; | ||
var OauthReceiver = function (_React$Component) { | ||
inherits(OauthReceiver, _React$Component); | ||
function OauthReceiver() { | ||
var _ref; | ||
var _temp, _this, _ret; | ||
classCallCheck(this, OauthReceiver); | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = OauthReceiver.__proto__ || Object.getPrototypeOf(OauthReceiver)).call.apply(_ref, [this].concat(args))), _this), _initialiseProps.call(_this), _temp), possibleConstructorReturn(_this, _ret); | ||
} | ||
createClass(OauthReceiver, [{ | ||
key: 'componentDidMount', | ||
value: function componentDidMount() { | ||
this.getAuthorizationCode(); | ||
} | ||
}, { | ||
key: 'render', | ||
value: function () { | ||
var _props = this.props, | ||
component = _props.component, | ||
render = _props.render, | ||
children = _props.children; | ||
var _state = this.state, | ||
processing = _state.processing, | ||
state = _state.state, | ||
error = _state.error; | ||
if (component != null) { | ||
return React.createElement(component, { processing: processing, state: state, error: error }); | ||
} | ||
if (render != null) { | ||
return render({ processing: processing, state: state, error: error }); | ||
} | ||
if (children != null) { | ||
React.Children.only(children); | ||
return children({ processing: processing, state: state, error: error }); | ||
} | ||
return null; | ||
} | ||
}]); | ||
return OauthReceiver; | ||
}(React.Component); | ||
OauthReceiver.propTypes = { | ||
tokenUrl: PropTypes.string.isRequired, | ||
clientId: PropTypes.string.isRequired, | ||
clientSecret: PropTypes.string.isRequired, | ||
redirectUri: PropTypes.string.isRequired, | ||
args: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object])), | ||
location: PropTypes.shape({ search: PropTypes.string.isRequired }), | ||
querystring: PropTypes.string, | ||
onAuthSuccess: PropTypes.func, | ||
onAuthError: PropTypes.func, | ||
render: PropTypes.func, | ||
component: PropTypes.element, | ||
children: PropTypes.func | ||
}; | ||
OauthReceiver.defaultProps = { | ||
args: {}, | ||
location: null, | ||
querystring: null, | ||
onAuthSuccess: null, | ||
onAuthError: null, | ||
render: null, | ||
component: null, | ||
children: null | ||
}; | ||
var _initialiseProps = function () { | ||
var _this2 = this; | ||
this.state = { | ||
processing: true, | ||
state: null, | ||
error: null | ||
}; | ||
this.getAuthorizationCode = function () { | ||
try { | ||
var _props2 = _this2.props, | ||
tokenUrl = _props2.tokenUrl, | ||
clientId = _props2.clientId, | ||
clientSecret = _props2.clientSecret, | ||
redirectUri = _props2.redirectUri, | ||
_args = _props2.args, | ||
onAuthSuccess = _props2.onAuthSuccess; | ||
var queryResult = _this2.parseQuerystring(); | ||
var error = queryResult.error, | ||
error_description = queryResult.error_description, | ||
code = queryResult.code; | ||
var state = JSON.parse(queryResult.state); | ||
_this2.setState(function () { | ||
return { state: state }; | ||
}); | ||
if (error != null) { | ||
var err = new Error(error_description); | ||
throw err; | ||
} | ||
var url = buildURL('' + tokenUrl, _extends({ | ||
code: code, | ||
grant_type: 'authorization_code', | ||
client_id: clientId, | ||
client_secret: clientSecret, | ||
redirect_uri: redirectUri | ||
}, _args)); | ||
var headers = new Headers({ 'Content-Type': 'application/json' }); | ||
fetch2(url, { method: 'POST', headers: headers }).then(function (response) { | ||
var accessToken = response.access_token; | ||
if (typeof onAuthSuccess === 'function') { | ||
onAuthSuccess(accessToken, { response: response, state: state }); | ||
} | ||
_this2.setState(function () { | ||
return { processing: false }; | ||
}); | ||
}).catch(function (err) { | ||
_this2.handleError(err); | ||
_this2.setState(function () { | ||
return { processing: false }; | ||
}); | ||
}); | ||
} catch (error) { | ||
_this2.handleError(error); | ||
_this2.setState(function () { | ||
return { processing: false }; | ||
}); | ||
} | ||
}; | ||
this.handleError = function (error) { | ||
var onAuthError = _this2.props.onAuthError; | ||
_this2.setState(function () { | ||
return { error: error }; | ||
}); | ||
if (typeof onAuthError === 'function') { | ||
onAuthError(error); | ||
} | ||
}; | ||
this.parseQuerystring = function () { | ||
var _props3 = _this2.props, | ||
location = _props3.location, | ||
querystring = _props3.querystring; | ||
var search = void 0; | ||
if (location != null) { | ||
search = location.search; // eslint-disable-line | ||
} else if (querystring != null) { | ||
search = querystring; | ||
} else { | ||
search = window.location.search; // eslint-disable-line | ||
} | ||
return lib.parse(search, { ignoreQueryPrefix: true }); | ||
}; | ||
}; | ||
var OauthSender = function (_React$Component) { | ||
inherits(OauthSender, _React$Component); | ||
function OauthSender() { | ||
classCallCheck(this, OauthSender); | ||
return possibleConstructorReturn(this, (OauthSender.__proto__ || Object.getPrototypeOf(OauthSender)).apply(this, arguments)); | ||
} | ||
createClass(OauthSender, [{ | ||
key: 'render', | ||
value: function () { | ||
var _props = this.props, | ||
authorizeUrl = _props.authorizeUrl, | ||
clientId = _props.clientId, | ||
redirectUri = _props.redirectUri, | ||
state = _props.state, | ||
args = _props.args, | ||
render = _props.render, | ||
component = _props.component, | ||
children = _props.children; | ||
var url = buildURL('' + authorizeUrl, _extends({ | ||
client_id: clientId, | ||
redirect_uri: redirectUri, | ||
response_type: 'code', | ||
state: state ? JSON.stringify(state) : undefined | ||
}, args || {})); | ||
if (component != null) { | ||
return React.createElement(component, { url: url }); | ||
} | ||
if (render != null) { | ||
return render({ url: url }); | ||
} | ||
if (children != null) { | ||
React.Children.only(children); | ||
return children({ url: url }); | ||
} | ||
return null; | ||
} | ||
}]); | ||
return OauthSender; | ||
}(React.Component); | ||
OauthSender.propTypes = { | ||
authorizeUrl: PropTypes.string.isRequired, | ||
clientId: PropTypes.string.isRequired, | ||
redirectUri: PropTypes.string.isRequired, | ||
state: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object])), | ||
args: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object])), | ||
render: PropTypes.func, | ||
component: PropTypes.element, | ||
children: PropTypes.func | ||
}; | ||
OauthSender.defaultProps = { | ||
state: null, | ||
args: null, | ||
render: null, | ||
component: null, | ||
children: null | ||
}; | ||
function createOauthFlow() { | ||
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, | ||
authorizeUrl = _ref.authorizeUrl, | ||
tokenUrl = _ref.tokenUrl, | ||
clientId = _ref.clientId, | ||
clientSecret = _ref.clientSecret, | ||
redirectUri = _ref.redirectUri, | ||
appName = _ref.appName; | ||
return { | ||
Sender: function Sender(props) { | ||
return React.createElement(OauthSender, _extends({ | ||
authorizeUrl: authorizeUrl, | ||
clientId: clientId, | ||
redirectUri: redirectUri | ||
}, props)); | ||
}, | ||
Receiver: function Receiver(props) { | ||
return React.createElement(OauthReceiver, _extends({ | ||
tokenUrl: tokenUrl, | ||
clientId: clientId, | ||
clientSecret: clientSecret, | ||
redirectUri: redirectUri, | ||
appName: appName | ||
}, props)); | ||
} | ||
}; | ||
} | ||
exports.createOauthFlow = createOauthFlow; | ||
exports.OauthSender = OauthSender; | ||
exports.OauthReceiver = OauthReceiver; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
}))); | ||
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("qs"),require("react"),require("prop-types")):"function"==typeof define&&define.amd?define(["exports","qs","react","prop-types"],r):r(e.reactOauthFlow={},e.qs,e.react,e.PropTypes)}(this,function(e,r,t,n){r=r&&r.hasOwnProperty("default")?r.default:r,n=n&&n.hasOwnProperty("default")?n.default:n;var o=function(e,r,t){return Object.defineProperty(e,r,{enumerable:!1,configurable:!1,writable:!1,value:t}),e};function i(e,t){if(null==t)return e;var n=r.stringify(t);return n?e+(e.indexOf("?")<0?"?":"&")+n:e}var s=function(e){function n(r){e.call(this,r),this.state={processing:!0,state:null,error:null},this.getAuthorizationCode=this.getAuthorizationCode.bind(this),this.handleError=this.handleError.bind(this),this.parseQuerystring=this.parseQuerystring.bind(this)}return e&&(n.__proto__=e),(n.prototype=Object.create(e&&e.prototype)).constructor=n,n.prototype.componentDidMount=function(){this.getAuthorizationCode()},n.prototype.getAuthorizationCode=function(){var e=this;try{var r=this.props,t=r.tokenUrl,n=r.tokenFetchArgs,s=r.clientId,c=r.clientSecret,u=r.redirectUri,l=r.args,a=r.onAuthSuccess,p=this.parseQuerystring(),d=p.error,h=p.error_description,f=p.code,g=JSON.parse(p.state||null);if(g&&this.setState(function(){return{state:g}}),null!=d)throw new Error(h);var y=i(""+t,Object.assign({},{code:f,grant_type:"authorization_code",client_id:s,client_secret:c,redirect_uri:u},l)),b=new Headers({"Content-Type":"application/json"});(function(e,r){var t=fetch(e,r);return t.then(function(e){if(!e.ok)throw e;return e.json()}).catch(function(e){return e.json().then(function(r){var n=new Error(e.statusText);throw o(n,"response",e),o(n.response,"data",r),o(n,"request",t),n})})})(y,Object.assign({method:"POST",headers:b},n)).then(function(r){"function"==typeof a&&a(r.access_token,{response:r,state:g}),e.setState(function(){return{processing:!1}})}).catch(function(r){e.handleError(r),e.setState(function(){return{processing:!1}})})}catch(e){this.handleError(e),this.setState(function(){return{processing:!1}})}},n.prototype.handleError=function(e){var r=this.props.onAuthError;this.setState(function(){return{error:e}}),"function"==typeof r&&r(e)},n.prototype.parseQuerystring=function(){var e,t=this.props,n=t.location,o=t.querystring;return e=null!=n?n.search:null!=o?o:window.location.search,r.parse(e,{ignoreQueryPrefix:!0})},n.prototype.render=function(){var e=this.props,r=e.component,n=e.render,o=e.children,i=this.state,s=i.processing,c=i.state,u=i.error;return null!=r?t.createElement(r,{processing:s,state:c,error:u}):null!=n?n({processing:s,state:c,error:u}):null!=o?(t.Children.only(o),o({processing:s,state:c,error:u})):null},n}(t.Component);s.propTypes={tokenUrl:n.string.isRequired,clientId:n.string.isRequired,clientSecret:n.string.isRequired,redirectUri:n.string.isRequired,args:n.objectOf(n.oneOfType([n.string,n.number,n.bool,n.object])),location:n.shape({search:n.string.isRequired}),querystring:n.string,onAuthSuccess:n.func,onAuthError:n.func,render:n.func,tokenFetchArgs:n.shape({method:n.string}),component:n.element,children:n.func},s.defaultProps={args:{},location:null,querystring:null,onAuthSuccess:null,onAuthError:null,render:null,tokenFetchArgs:{},component:null,children:null};var c=function(e){function r(){e.apply(this,arguments)}return e&&(r.__proto__=e),(r.prototype=Object.create(e&&e.prototype)).constructor=r,r.prototype.render=function(){var e=this.props,r=e.state,n=e.args,o=e.render,s=e.component,c=e.children,u=i(""+e.authorizeUrl,Object.assign({},{client_id:e.clientId,redirect_uri:e.redirectUri,response_type:"code",state:r?JSON.stringify(r):void 0},n||{}));return null!=s?t.createElement(s,{url:u}):null!=o?o({url:u}):null!=c?(t.Children.only(c),c({url:u})):null},r}(t.Component);c.propTypes={authorizeUrl:n.string.isRequired,clientId:n.string.isRequired,redirectUri:n.string.isRequired,state:n.objectOf(n.oneOfType([n.string,n.number,n.bool,n.object])),args:n.objectOf(n.oneOfType([n.string,n.number,n.bool,n.object])),render:n.func,component:n.element,children:n.func},c.defaultProps={state:null,args:null,render:null,component:null,children:null},e.createOauthFlow=function(e){void 0===e&&(e={});var r=e.authorizeUrl,t=e.tokenUrl,n=e.clientId,o=e.clientSecret,i=e.redirectUri,u=e.appName;return{Sender:function(e){return h(c,Object.assign({},{authorizeUrl:r,clientId:n,redirectUri:i},e))},Receiver:function(e){return h(s,Object.assign({},{tokenUrl:t,clientId:n,clientSecret:o,redirectUri:i,appName:u},e))}}},e.OauthSender=c,e.OauthReceiver=s}); | ||
//# sourceMappingURL=react-oauth-flow.umd.js.map |
@@ -1,15 +0,16 @@ | ||
const jestConfig = require('frans-scripts/jest'); | ||
jestConfig.setupFiles = jestConfig.setupFiles || []; | ||
jestConfig.setupFiles.push('<rootDir>/tests/setup.js'); | ||
jestConfig.coverageThreshold = { | ||
global: { | ||
branches: 30, | ||
functions: 30, | ||
lines: 30, | ||
statements: 30, | ||
module.exports = { | ||
setupFiles: ['<rootDir>/tests/setup.js'], | ||
setupTestFrameworkScriptFile: '<rootDir>/tests/setup-framework.js', | ||
collectCoverageFrom: [ | ||
'src/**/*.{js,jsx}', | ||
'!**/node_modules/**', | ||
], | ||
coverageThreshold: { | ||
global: { | ||
branches: 30, | ||
functions: 30, | ||
lines: 30, | ||
statements: 30, | ||
}, | ||
}, | ||
}; | ||
module.exports = jestConfig; |
@@ -1,1 +0,60 @@ | ||
{"name":"react-oauth-flow","version":"1.1.1","main":"dist/react-oauth-flow.cjs.js","jsnext:main":"dist/react-oauth-flow.esm.js","module":"dist/react-oauth-flow.esm.js","repository":"git@github.com:adambrgmn/react-oauth-flow.git","author":"Adam Bergman <adam@fransvilhelm.com>","license":"MIT","scripts":{"build":"frans-scripts build --bundle","test":"frans-scripts test","lint":"frans-scripts lint","format":"frans-scripts format","validate":"frans-scripts validate","add-contributor":"frans-scripts contributors add","precommit":"frans-scripts precommit","travis-after-success":"frans-scripts travis-after-success"},"devDependencies":{"cz-conventional-changelog":"^2.1.0","enzyme":"^3.2.0","enzyme-adapter-react-16":"^1.1.0","frans-scripts":"^1.0.1","isomorphic-fetch":"^2.2.1","nock":"^9.1.4","prop-types":"^15.6.0","react":"^16.1.1","react-dom":"^16.1.1"},"dependencies":{"qs":"^6.5.1"},"peerDependencies":{"prop-types":">=15","react":">=15"},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}} | ||
{ | ||
"name": "react-oauth-flow", | ||
"version": "1.1.2", | ||
"repository": "git@github.com:adambrgmn/react-oauth-flow.git", | ||
"author": "Adam Bergman <adam@fransvilhelm.com>", | ||
"license": "MIT", | ||
"main": "dist/react-oauth-flow.js", | ||
"umd:main": "dist/react-oauth-flow.umd.js", | ||
"module": "dist/react-oauth-flow.m.js", | ||
"source": "src/index.js", | ||
"scripts": { | ||
"build": "microbundle", | ||
"test": "jest", | ||
"lint": "eslint", | ||
"format": "prettier", | ||
"contributors": "all-contributors" | ||
}, | ||
"devDependencies": { | ||
"all-contributors-cli": "^5.4.0", | ||
"babel-eslint": "^8.2.6", | ||
"babel-jest": "^23.4.2", | ||
"babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"babel-preset-env": "^1.7.0", | ||
"babel-preset-react": "^6.24.1", | ||
"cz-conventional-changelog": "^2.1.0", | ||
"doctoc": "^1.3.1", | ||
"eslint": "^5.3.0", | ||
"eslint-config-airbnb": "^17.0.0", | ||
"eslint-config-prettier": "^3.0.1", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-jsx-a11y": "^6.1.1", | ||
"eslint-plugin-react": "^7.10.0", | ||
"husky": "^1.0.0-rc.13", | ||
"isomorphic-fetch": "^2.2.1", | ||
"jest": "^23.5.0", | ||
"jest-dom": "^1.12.0", | ||
"lint-staged": "^7.2.2", | ||
"microbundle": "^0.6.0", | ||
"prettier": "^1.14.2", | ||
"prop-types": "^15.6.0", | ||
"react": "^16.1.1", | ||
"react-dom": "^16.1.1", | ||
"react-testing-library": "^5.0.0" | ||
}, | ||
"dependencies": { | ||
"qs": "^6.5.1" | ||
}, | ||
"peerDependencies": { | ||
"prop-types": ">=15", | ||
"react": ">=15" | ||
}, | ||
"config": { | ||
"commitizen": { | ||
"path": "./node_modules/cz-conventional-changelog" | ||
} | ||
}, | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
} |
@@ -172,11 +172,12 @@ # React OAuth Flow | ||
| Prop | Type | Required | Default | Description | | ||
| :------------- | :------------------- | :------- | :------ | :-------------------------------------------------------------------------------------- | | ||
| `tokenUrl` | `string` | yes | - | The full url to the token endpoint, provided by the service | | ||
| `clientId` | `string` | yes | - | Your client id from the service provider (remember to keep it secret!) | | ||
| `clientSecret` | `string` | yes | - | Your client secret from the service provider (remember to keep it secret!) | | ||
| `redirectUri` | `string` | yes | - | The URL where the provider has redirected your user (used to verify auth) | | ||
| `args` | `object` | no | - | Args will be attatched to the request to the token endpoint. Will be serialized by `qz` | | ||
| `location` | `{ search: string }` | no | - | Used to extract info from querystring [(read more below)](#location-and-querystring) | | ||
| `querystring` | `string` | no | - | Used to extract info from querystring [(read more below)](#location-and-querystring) | | ||
| Prop | Type | Required | Default | Description | | ||
| :--------------- | :------------------- | :------- | :------ | :-------------------------------------------------------------------------------------- | | ||
| `tokenUrl` | `string` | yes | - | The full url to the token endpoint, provided by the service | | ||
| `clientId` | `string` | yes | - | Your client id from the service provider (remember to keep it secret!) | | ||
| `clientSecret` | `string` | yes | - | Your client secret from the service provider (remember to keep it secret!) | | ||
| `redirectUri` | `string` | yes | - | The URL where the provider has redirected your user (used to verify auth) | | ||
| `args` | `object` | no | - | Args will be attatched to the request to the token endpoint. Will be serialized by `qz` | | ||
| `location` | `{ search: string }` | no | - | Used to extract info from querystring [(read more below)](#location-and-querystring) | | ||
| `querystring` | `string` | no | - | Used to extract info from querystring [(read more below)](#location-and-querystring) | | ||
| `tokenFetchArgs` | `object` | no | `{}` | Used to fetch the token endpoint [(read more below)](#tokenfetchargs) | | ||
@@ -263,2 +264,16 @@ #### Events | ||
#### `tokenFetchArgs` | ||
The prop `tokenFetchArgs` can be used to change how the token is received from | ||
the service. For example, the token service for Facebook requires a `GET` | ||
request but the token service for Dropbox requires a `POST` request. You can | ||
change `tokenFetchArgs` to make this necessary change. | ||
The following are the default fetch args used to fetch the token but they can be | ||
merged and overriden with the `tokenFetchArgs`: | ||
``` | ||
{ method: 'GET', headers: { 'Content-Type': 'application/json' }} | ||
``` | ||
### `createOauthFlow` | ||
@@ -304,7 +319,5 @@ | ||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
<!-- prettier-ignore --> | ||
| [<img src="https://avatars1.githubusercontent.com/u/13746650?v=4" width="100px;"/><br /><sub><b>Adam Bergman</b></sub>](http://fransvilhelm.com)<br />[💻](https://github.com/adambrgmn/react-oauth-flow/commits?author=adambrgmn "Code") [📖](https://github.com/adambrgmn/react-oauth-flow/commits?author=adambrgmn "Documentation") | | ||
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | ||
| [<img src="https://avatars1.githubusercontent.com/u/13746650?v=4" width="100px;"/><br /><sub><b>Adam Bergman</b></sub>](http://fransvilhelm.com)<br />[💻](https://github.com/adambrgmn/react-oauth-flow/commits?author=adambrgmn "Code") [📖](https://github.com/adambrgmn/react-oauth-flow/commits?author=adambrgmn "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/35017?v=4" width="100px;"/><br /><sub><b>Jamie Wright</b></sub>](http://tatsu.io)<br />[💻](https://github.com/adambrgmn/react-oauth-flow/commits?author=jwright "Code") [📖](https://github.com/adambrgmn/react-oauth-flow/commits?author=jwright "Documentation") | | ||
| :---: | :---: | | ||
<!-- ALL-CONTRIBUTORS-LIST:END --> |
@@ -7,41 +7,16 @@ // @flow | ||
export class OauthReceiver extends React.Component { | ||
static propTypes = { | ||
tokenUrl: PropTypes.string.isRequired, | ||
clientId: PropTypes.string.isRequired, | ||
clientSecret: PropTypes.string.isRequired, | ||
redirectUri: PropTypes.string.isRequired, | ||
args: PropTypes.objectOf( | ||
PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number, | ||
PropTypes.bool, | ||
PropTypes.object, | ||
]), | ||
), | ||
location: PropTypes.shape({ search: PropTypes.string.isRequired }), | ||
querystring: PropTypes.string, | ||
onAuthSuccess: PropTypes.func, | ||
onAuthError: PropTypes.func, | ||
render: PropTypes.func, | ||
component: PropTypes.element, | ||
children: PropTypes.func, | ||
}; | ||
class OauthReceiver extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
static defaultProps = { | ||
args: {}, | ||
location: null, | ||
querystring: null, | ||
onAuthSuccess: null, | ||
onAuthError: null, | ||
render: null, | ||
component: null, | ||
children: null, | ||
}; | ||
this.state = { | ||
processing: true, | ||
state: null, | ||
error: null, | ||
}; | ||
state = { | ||
processing: true, | ||
state: null, | ||
error: null, | ||
}; | ||
this.getAuthorizationCode = this.getAuthorizationCode.bind(this); | ||
this.handleError = this.handleError.bind(this); | ||
this.parseQuerystring = this.parseQuerystring.bind(this); | ||
} | ||
@@ -52,6 +27,7 @@ componentDidMount() { | ||
getAuthorizationCode = () => { | ||
getAuthorizationCode() { | ||
try { | ||
const { | ||
tokenUrl, | ||
tokenFetchArgs, | ||
clientId, | ||
@@ -65,8 +41,10 @@ clientSecret, | ||
const queryResult = this.parseQuerystring(); | ||
const { error, error_description, code } = queryResult; | ||
const state = JSON.parse(queryResult.state); | ||
this.setState(() => ({ state })); | ||
const { error, error_description: errorDescription, code } = queryResult; | ||
const state = JSON.parse(queryResult.state || null); | ||
if (state) { | ||
this.setState(() => ({ state })); | ||
} | ||
if (error != null) { | ||
const err = new Error(error_description); | ||
const err = new Error(errorDescription); | ||
throw err; | ||
@@ -85,4 +63,6 @@ } | ||
const headers = new Headers({ 'Content-Type': 'application/json' }); | ||
const defaultFetchArgs = { method: 'POST', headers }; | ||
const fetchArgs = Object.assign(defaultFetchArgs, tokenFetchArgs); | ||
fetch2(url, { method: 'POST', headers }) | ||
fetch2(url, fetchArgs) | ||
.then(response => { | ||
@@ -105,5 +85,5 @@ const accessToken = response.access_token; | ||
} | ||
}; | ||
} | ||
handleError = error => { | ||
handleError(error) { | ||
const { onAuthError } = this.props; | ||
@@ -115,5 +95,5 @@ | ||
} | ||
}; | ||
} | ||
parseQuerystring = () => { | ||
parseQuerystring() { | ||
const { location, querystring } = this.props; | ||
@@ -131,3 +111,3 @@ let search; | ||
return qs.parse(search, { ignoreQueryPrefix: true }); | ||
}; | ||
} | ||
@@ -154,1 +134,40 @@ render() { | ||
} | ||
OauthReceiver.propTypes = { | ||
tokenUrl: PropTypes.string.isRequired, | ||
clientId: PropTypes.string.isRequired, | ||
clientSecret: PropTypes.string.isRequired, | ||
redirectUri: PropTypes.string.isRequired, | ||
args: PropTypes.objectOf( | ||
PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number, | ||
PropTypes.bool, | ||
PropTypes.object, | ||
]), | ||
), | ||
location: PropTypes.shape({ search: PropTypes.string.isRequired }), | ||
querystring: PropTypes.string, | ||
onAuthSuccess: PropTypes.func, | ||
onAuthError: PropTypes.func, | ||
render: PropTypes.func, | ||
tokenFetchArgs: PropTypes.shape({ | ||
method: PropTypes.string, | ||
}), | ||
component: PropTypes.element, | ||
children: PropTypes.func, | ||
}; | ||
OauthReceiver.defaultProps = { | ||
args: {}, | ||
location: null, | ||
querystring: null, | ||
onAuthSuccess: null, | ||
onAuthError: null, | ||
render: null, | ||
tokenFetchArgs: {}, | ||
component: null, | ||
children: null, | ||
}; | ||
export { OauthReceiver }; |
import React from 'react'; | ||
import { mount } from 'enzyme'; | ||
import { cleanup, render, waitForElement } from 'react-testing-library'; | ||
import qs from 'qs'; | ||
import nock from 'nock'; | ||
import { OauthReceiver } from './index'; | ||
import { fetch2 } from '../utils/fetch'; | ||
const delay = dur => new Promise(resolve => setTimeout(resolve, dur)); | ||
jest.mock('../utils/fetch.js', () => ({ | ||
fetch2: jest.fn(() => Promise.resolve({ access_token: 'foo' })), | ||
})); | ||
beforeAll(() => { | ||
const api = nock('https://api.service.com/'); | ||
afterEach(cleanup); | ||
api | ||
.post('/oauth2/token') | ||
.query({ | ||
code: 'abc', | ||
grant_type: 'authorization_code', | ||
client_id: 'abc', | ||
client_secret: 'abcdef', | ||
redirect_uri: 'https://www.test.com/redirect', | ||
}) | ||
.reply(200, { | ||
access_token: '123', | ||
token_type: 'bearer', | ||
account_id: '123456', | ||
}); | ||
}); | ||
describe('Component <OauthReceiver />', () => { | ||
test('with default fetch args', async () => { | ||
const onAuthSuccess = jest.fn(); | ||
const onAuthError = jest.fn(); | ||
test('Component <OauthReceiver />', async () => { | ||
const onAuthSuccess = jest.fn(); | ||
const onAuthError = jest.fn(); | ||
const props = { | ||
tokenUrl: 'https://api.service.com/oauth2/token', | ||
clientId: 'abc', | ||
clientSecret: 'abcdef', | ||
redirectUri: 'https://www.test.com/redirect', | ||
querystring: `?${qs.stringify({ | ||
code: 'abc', | ||
state: JSON.stringify({ from: '/success' }), | ||
})}`, | ||
onAuthSuccess, | ||
onAuthError, | ||
}; | ||
const props = { | ||
tokenUrl: 'https://api.service.com/oauth2/token', | ||
clientId: 'abc', | ||
clientSecret: 'abcdef', | ||
redirectUri: 'https://www.test.com/redirect', | ||
querystring: `?${qs.stringify({ | ||
code: 'abc', | ||
state: JSON.stringify({ from: '/settings' }), | ||
})}`, | ||
onAuthSuccess, | ||
onAuthError, | ||
}; | ||
const { getByTestId } = render( | ||
<OauthReceiver | ||
{...props} | ||
render={({ processing, state }) => ( | ||
<div> | ||
{processing && <span data-testid="done">done</span>} | ||
<span data-testid="state">{state && state.from}</span> | ||
</div> | ||
)} | ||
/>, | ||
); | ||
const wrapper = mount( | ||
<OauthReceiver | ||
{...props} | ||
render={({ processing, state }) => ( | ||
<div> | ||
<span className="processing">{processing ? 'yes' : 'no'}</span> | ||
<span className="state">{state && state.from}</span> | ||
</div> | ||
)} | ||
/>, | ||
); | ||
await waitForElement(() => getByTestId('done')); | ||
expect(wrapper.find('.processing').text()).toBe('yes'); | ||
await delay(10); | ||
expect(wrapper.find('.processing').text()).toBe('no'); | ||
expect(wrapper.find('.state').text()).toBe('/settings'); | ||
expect(onAuthSuccess).toHaveBeenCalledTimes(1); | ||
expect(onAuthError).not.toHaveBeenCalled(); | ||
const successCall = onAuthSuccess.mock.calls[0]; | ||
expect(onAuthSuccess.mock.calls.length).toBe(1); | ||
expect(successCall[0]).toBe('123'); | ||
expect(successCall[1]).toEqual({ | ||
response: { | ||
access_token: '123', | ||
token_type: 'bearer', | ||
account_id: '123456', | ||
}, | ||
state: { from: '/settings' }, | ||
expect(getByTestId('state')).toHaveTextContent('/success'); | ||
}); | ||
expect(onAuthError.mock.calls.length).toBe(0); | ||
test('with custom token uri fetch args', async () => { | ||
fetch2.mockClear(); | ||
const props = { | ||
tokenUrl: 'https://api.service.com/oauth2/token', | ||
tokenFetchArgs: { | ||
cache: 'no-cache', | ||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, | ||
}, | ||
clientId: 'abc', | ||
clientSecret: 'abcdef', | ||
redirectUri: 'https://www.test.com/redirect', | ||
querystring: `?${qs.stringify({ | ||
code: 'abc', | ||
state: JSON.stringify({ from: '/settings' }), | ||
})}`, | ||
}; | ||
const { getByTestId } = render( | ||
<OauthReceiver | ||
{...props} | ||
render={({ processing }) => ( | ||
<div>{processing && <span data-testid="done">done</span>}</div> | ||
)} | ||
/>, | ||
); | ||
await waitForElement(() => getByTestId('done')); | ||
expect(fetch2).toHaveBeenCalledWith( | ||
expect.stringContaining(props.tokenUrl), | ||
expect.objectContaining({ | ||
method: expect.stringMatching('POST'), | ||
cache: expect.stringMatching('no-cache'), | ||
headers: expect.objectContaining({ | ||
'Content-Type': expect.stringMatching( | ||
'application/x-www-form-urlencoded', | ||
), | ||
}), | ||
}), | ||
); | ||
}); | ||
}); |
@@ -6,36 +6,3 @@ // @flow | ||
export class OauthSender extends React.Component { | ||
static propTypes = { | ||
authorizeUrl: PropTypes.string.isRequired, | ||
clientId: PropTypes.string.isRequired, | ||
redirectUri: PropTypes.string.isRequired, | ||
state: PropTypes.objectOf( | ||
PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number, | ||
PropTypes.bool, | ||
PropTypes.object, | ||
]), | ||
), | ||
args: PropTypes.objectOf( | ||
PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number, | ||
PropTypes.bool, | ||
PropTypes.object, | ||
]), | ||
), | ||
render: PropTypes.func, | ||
component: PropTypes.element, | ||
children: PropTypes.func, | ||
}; | ||
static defaultProps = { | ||
state: null, | ||
args: null, | ||
render: null, | ||
component: null, | ||
children: null, | ||
}; | ||
class OauthSender extends React.Component { | ||
render() { | ||
@@ -77,1 +44,36 @@ const { | ||
} | ||
OauthSender.propTypes = { | ||
authorizeUrl: PropTypes.string.isRequired, | ||
clientId: PropTypes.string.isRequired, | ||
redirectUri: PropTypes.string.isRequired, | ||
state: PropTypes.objectOf( | ||
PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number, | ||
PropTypes.bool, | ||
PropTypes.object, | ||
]), | ||
), | ||
args: PropTypes.objectOf( | ||
PropTypes.oneOfType([ | ||
PropTypes.string, | ||
PropTypes.number, | ||
PropTypes.bool, | ||
PropTypes.object, | ||
]), | ||
), | ||
render: PropTypes.func, | ||
component: PropTypes.element, | ||
children: PropTypes.func, | ||
}; | ||
OauthSender.defaultProps = { | ||
state: null, | ||
args: null, | ||
render: null, | ||
component: null, | ||
children: null, | ||
}; | ||
export { OauthSender }; |
@@ -0,6 +1,9 @@ | ||
/* eslint-disable react/prop-types */ | ||
import React from 'react'; | ||
import { shallow } from 'enzyme'; | ||
import { render, cleanup } from 'react-testing-library'; | ||
import { OauthSender } from './index'; | ||
import { buildURL } from '../utils'; | ||
afterEach(cleanup); | ||
test('Component: <OauthSender />', () => { | ||
@@ -11,6 +14,4 @@ const props = { | ||
redirectUri: 'https://www.test.com/redirect', | ||
render: ( | ||
{ url }, // eslint-disable-line | ||
) => ( | ||
<a className="link" href={url}> | ||
render: ({ url }) => ( | ||
<a data-testid="link" href={url}> | ||
Connect | ||
@@ -21,4 +22,5 @@ </a> | ||
const wrapper = shallow(<OauthSender {...props} />); | ||
const expectedUrl = buildURL(`${props.authorizeUrl}`, { | ||
const { getByTestId } = render(<OauthSender {...props} />); | ||
const expectedUrl = buildURL(props.authorizeUrl, { | ||
client_id: props.clientId, | ||
@@ -29,3 +31,3 @@ redirect_uri: props.redirectUri, | ||
expect(wrapper.find('.link').prop('href')).toEqual(expectedUrl); | ||
expect(getByTestId('link')).toHaveAttribute('href', expectedUrl); | ||
}); |
@@ -1,17 +0,10 @@ | ||
// @flow | ||
import qs from 'qs'; | ||
import { fetch2 } from './fetch'; | ||
function buildURL(url, params, paramsSerializer): string { | ||
function buildURL(url, params) { | ||
if (params == null) return url; | ||
let serializedParams; | ||
if (paramsSerializer != null) { | ||
serializedParams = paramsSerializer(params); | ||
} else { | ||
serializedParams = qs.stringify(params); | ||
} | ||
const serializedParams = qs.stringify(params) | ||
if (!serializedParams) return url; | ||
return `${url}${url.indexOf('?') < 0 ? '?' : '&'}${serializedParams}`; | ||
@@ -18,0 +11,0 @@ } |
@@ -1,43 +0,14 @@ | ||
import nock from 'nock'; | ||
import * as utils from './index'; | ||
beforeAll(() => { | ||
const api = nock('https://api.github.com/'); | ||
api.get('/users/octocat').reply(200, { | ||
login: 'octocat', | ||
}); | ||
api.get('/users/404').reply(404, { | ||
message: 'User 404 not found', | ||
}); | ||
}); | ||
test('utils.buildURL', () => { | ||
const baseUrl = 'https://www.test.com'; | ||
let url = utils.buildURL(baseUrl, { | ||
expect(utils.buildURL(baseUrl, { | ||
a: 'hello', | ||
b: 'world', | ||
}); | ||
expect(url).toEqual(`${baseUrl}?a=hello&b=world`); | ||
})).toEqual(`${baseUrl}?a=hello&b=world`); | ||
url = utils.buildURL(baseUrl); | ||
expect(url).toBe(baseUrl); | ||
url = utils.buildURL(`${baseUrl}?a=hello`, { b: 'world' }); | ||
expect(url).toBe(`${baseUrl}?a=hello&b=world`); | ||
expect(utils.buildURL(baseUrl)).toBe(baseUrl); | ||
expect(utils.buildURL(`${baseUrl}?a=hello`, { b: 'world' })).toBe(`${baseUrl}?a=hello&b=world`); | ||
expect(utils.buildURL(baseUrl, {})).toBe(baseUrl); | ||
}); | ||
test('utils.fetch2', async () => { | ||
const data = await utils.fetch2('https://api.github.com/users/octocat'); | ||
expect(data.login).toBe('octocat'); | ||
try { | ||
await utils.fetch2('https://api.github.com/users/404'); | ||
expect(true).toBe(false); | ||
} catch (err) { | ||
expect(err.response.ok).toBe(false); | ||
expect(err.message).toBe('Not Found'); | ||
} | ||
}); |
@@ -1,7 +0,2 @@ | ||
/* eslint-disable import/first */ | ||
import './raf-polyfill'; | ||
import 'isomorphic-fetch'; | ||
import { configure } from 'enzyme'; | ||
import Adapter from 'enzyme-adapter-react-16'; | ||
configure({ adapter: new Adapter() }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
41
321
525509
25
628
3