frontend/app/LoginButton.jsx (60 lines of code) (raw):
import React from "react";
import PropTypes from "prop-types";
import LoadingIndicator from "./LoadingIndicator.jsx";
class LoginButton extends React.Component {
static propTypes = {
oAuthUri: PropTypes.string.isRequired,
tokenUri: PropTypes.string.isRequired,
clientId: PropTypes.string.isRequired,
redirectUri: PropTypes.string.isRequired,
scope: PropTypes.string.isRequired,
};
generateCodeChallenge() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
const str = array.reduce((acc, x) => acc + x.toString(16).padStart(2, '0'), "");
sessionStorage.setItem("cx", str);
return str;
}
makeLoginURL() {
const args = {
response_type: "code",
client_id: this.props.clientId,
scope: this.props.scope,
redirect_uri: this.props.redirectUri,
state: "/",
};
const encoded = Object.entries(args).map(
([k, v]) => `${k}=${encodeURIComponent(v)}`
);
return this.props.oAuthUri + "?" + encoded.join("&") + "&code_challenge=" + this.generateCodeChallenge();
}
constructor(props) {
super(props);
this.startLogin = this.startLogin.bind(this);
}
/**
* send the user out to the IdP to start the login process
*/
startLogin() {
window.location = this.makeLoginURL();
}
render() {
if (
!this.props.oAuthUri ||
!this.props.tokenUri ||
!this.props.clientId ||
!this.props.redirectUri
) {
console.error("Missing some openauth parameters: ", this.props);
return <LoadingIndicator blank={true} />;
} else {
return (
<button onClick={this.startLogin}>
> Log in <
</button>
);
}
}
}
export default LoginButton;