react-codechef-login
Version:
A react package to integrate codechef login to your react app.
322 lines (272 loc) • 8.51 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
/**
* Copyright (c) 2018 Jayjeet Chakraborty.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
*
* @description Converts the params object to an url query string
* @param {*} params
* @param {*} delimiter
*
*/
function toQueryString(params) {
var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '&';
var keys = Object.keys(params);
return keys.reduce(function (str, key, index) {
var query = '' + str + key + '=' + params[key];
if (index < keys.length - 1) {
query += delimiter;
}
return query;
}, '');
}
/**
* @description Parse params from url query string
* @param {*} queryString
*/
function getParams(queryString) {
var query = window.location.search.substring(1);
var vars = query.split('&');
var code = vars.map(function (i) {
var pair = i.split('=');
if (pair[0] === queryString) return pair[1];
return null;
}).filter(function (d) {
if (d) return true;
return false;
});
return code[0];
}
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css = "/* add css styles here (optional) */\n\n.styles_test__32Qsm {\n display: inline-block;\n margin: 2em auto;\n border: 2px solid #000;\n font-size: 2em;\n}\n\n.styles_loginButton__28Zq6 {\n display : inline-block;\n background : rgb(218, 216, 216);\n color : rgb(58, 38, 38);\n width: 200px;\n padding-top: 10px;\n padding-bottom: 10px;\n border-radius: 2px;\n border : 1px solid transparent;\n font-size: 16px;\n height:50px;\n}\n\n\n";
var styles = { "test": "styles_test__32Qsm", "loginButton": "styles_loginButton__28Zq6" };
styleInject(css);
/**
* Copyright (c) 2018 Jayjeet Chakraborty.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
*
* @description Describes urls as constants
* @constant
* @type {string}
* @default
*
*/
var AUTHORIZATION_URL = 'https://api.codechef.com/oauth/authorize?';
var TOKEN_URL = 'https://api.codechef.com/oauth/token';
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 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;
};
/**
* Copyright (c) 2018 Jayjeet Chakraborty.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
*
* @description Represents a class based component - CodechefLogin
* @class
*
*/
var CodechefLogin = function (_Component) {
inherits(CodechefLogin, _Component);
/**
*
* @description Initializes the CodechefLogin component
* @constructor
*
*/
function CodechefLogin(props) {
classCallCheck(this, CodechefLogin);
var _this = possibleConstructorReturn(this, (CodechefLogin.__proto__ || Object.getPrototypeOf(CodechefLogin)).call(this, props));
_this.getAccessToken = function (authorizationCode) {
return fetch(TOKEN_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify({
grant_type: 'authorization_code',
code: authorizationCode,
client_id: _this.props.clientId,
client_secret: _this.props.clientSecret,
redirect_uri: _this.props.redirectUri
})
}).then(function (response) {
return response.json();
}).catch(function (err) {
return _this.props.onFailure(err);
});
};
_this.onButtonClick = function () {
var _this$props = _this.props,
clientId = _this$props.clientId,
state = _this$props.state,
redirectUri = _this$props.redirectUri;
var queryString = toQueryString({
response_type: 'code',
client_id: clientId,
redirect_uri: redirectUri,
state: state
});
window.location.href = AUTHORIZATION_URL + queryString;
};
return _this;
}
/**
*
* @description Defines the type of props required to be passed through the component
* @static
* @memberof CodechefLogin
*
*/
/**
*
* @description Defines default values for props not specified through the component
* @static
* @memberof CodechefLogin
*
*/
createClass(CodechefLogin, [{
key: 'componentDidMount',
/**
*
* @description Called after the react component is rendered completely
* @function componentDidMount
*
*/
value: function componentDidMount() {
var _this2 = this;
if (window.location.search.includes('code')) {
this.getAccessToken(getParams('code').trim()).then(function (response) {
_this2.props.onSuccess(response);
});
} else if (window.location.search.includes('error')) {
this.props.onFailure(new Error(getParams('error')));
}
}
/**
*
* @description Get the access token from the authorization code
* @async
* @function getAccessToken
* @param {string} authorizationCode
*
*/
/**
*
* @description Responds to button click event
* @function onButtonClick
*
*/
}, {
key: 'render',
/**
*
* @description Renders the component in the browser
* @function render
*
*/
value: function render() {
var buttonStyle = this.props.className ? this.props.className : styles.loginButton;
return React.createElement(
'button',
{ className: buttonStyle, onClick: this.onButtonClick },
this.props.buttonText
);
}
}]);
return CodechefLogin;
}(Component);
CodechefLogin.propTypes = {
onSuccess: PropTypes.func.isRequired,
onFailure: PropTypes.func.isRequired,
clientId: PropTypes.string.isRequired,
clientSecret: PropTypes.string.isRequired,
buttonText: PropTypes.string,
state: PropTypes.string.isRequired,
className: PropTypes.string,
redirectUri: PropTypes.string.isRequired
};
CodechefLogin.defaultProps = {
buttonText: 'Login With Codechef'
};
/**
* Copyright (c) 2018 Jayjeet Chakraborty.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
export default CodechefLogin;
//# sourceMappingURL=index.es.js.map