ui/taskcluster-auth-callback/TaskclusterCallback.jsx (83 lines of code) (raw):
import React from 'react';
import { parseQueryParams } from '../helpers/url';
import { getData } from '../helpers/http';
import CallbackMessage from '../shared/CallbackMessage';
import { clientId, redirectURI, errorMessage } from './constants';
export default class TaskclusterCallback extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
errorMessage: '',
};
}
componentDidMount() {
// We're not using react router's location prop because we can't provide
// taskcluster with a redirect URI that contains a fragment (hash) per
// oath2 protocol (which is used by the hash router for parsing query params)
const { code, state, error } = parseQueryParams(window.location.search);
const requestState = localStorage.getItem('requestState');
if (code && requestState && requestState === state) {
this.getCredentials(code);
} else {
if (error)
// eslint-disable-next-line no-import-assign
errorMessage += `We received error: ${error} from Taskcluster.`;
this.setState({
errorMessage,
});
}
}
getCredentials = async (code) => {
const rootUrl = localStorage.getItem('tcRootUrl');
if (!rootUrl) {
this.setState({ errorMessage });
return;
}
let response = await this.fetchToken(code, rootUrl);
if (response.failureStatus) {
this.setState({ errorMessage: `errorMessage ${response.data}` });
return;
}
response = await this.fetchCredentials(response.data.access_token, rootUrl);
if (response.failureStatus) {
this.setState({ errorMessage: `errorMessage ${response.data}` });
return;
}
localStorage.setItem(
'userCredentials',
JSON.stringify({ [rootUrl]: response.data }),
);
if (window.opener) {
window.close();
} else {
window.location.href = window.origin;
}
};
fetchToken = async (code, rootUrl) => {
const options = {
method: 'POST',
body: `grant_type=authorization_code&code=${code}&redirect_uri=${redirectURI}&client_id=${clientId}`,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
};
return getData(`${rootUrl}/login/oauth/token`, options);
};
fetchCredentials = async (token, rootUrl) => {
const options = {
mode: 'cors',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
};
return getData(`${rootUrl}/login/oauth/credentials`, options);
};
render() {
const { errorMessage } = this.state;
return (
<CallbackMessage
errorMessage={errorMessage}
text="Getting Taskcluster credentials..."
/>
);
}
}