frontend/app/index.jsx (192 lines of code) (raw):

import React from 'react'; import {render} from 'react-dom'; import {BrowserRouter, Link, Route, Switch} from 'react-router-dom'; import Raven from 'raven-js'; import axios from 'axios'; import { authenticatedFetch } from "./auth"; import NotFoundComponent from './NotFoundComponent.jsx'; import FrontPage from './FrontPage.jsx'; import NewFrontPage from './NewFrontPage.jsx'; import OAuthCallbackComponent from "./OAuthCallbackComponent.jsx"; import LoginComponentNew from "./LoginComponentNew"; import { library } from '@fortawesome/fontawesome-svg-core' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faHdd, faUserAlt, faMinusCircle, faExclamationCircle, faExclamationTriangle, faCheck, faCheckCircle, faNetworkWired, faTimesCircle } from '@fortawesome/free-solid-svg-icons' import { faChevronCircleDown,faChevronCircleRight,faTrashAlt, faFilm, faVolumeUp,faImage, faFile } from '@fortawesome/free-solid-svg-icons' library.add(faHdd, faUserAlt, faMinusCircle, faExclamationCircle, faExclamationTriangle, faCheck, faCheckCircle, faNetworkWired, faTimesCircle); library.add(faFilm, faVolumeUp, faImage, faFilm, faFile); window.React = require('react'); class App extends React.Component { constructor(props){ super(props); axios.get("/system/publicdsn").then(response=> { Raven .config(response.data.publicDsn) .install(); console.log("Sentry initialised for " + response.data.publicDsn); }).catch(error => { console.error("Could not intialise sentry", error); }); this.state = { isLoggedIn: false, currentUsername: "", isAdmin: false, loading: true, loginDetail: null, redirectingTo: null, clientId: "", resource: "", oAuthUri: "", tokenUri: "", startup: true, scope: "" }; this.returnToRoot = this.returnToRoot.bind(this); const currentUri = new URL(window.location.href); this.redirectUri = currentUri.protocol + "//" + currentUri.host + "/oauth2/callback"; } returnToRoot() { this.props.history.push("/"); } setStatePromise(newstate) { return new Promise((resolve, reject) => this.setState(newstate, () => resolve()) ); } checkLogin() { return new Promise((resolve, reject) => this.setState({ loading: true, haveChecked: true }, async () => { const response = await authenticatedFetch("/api/isLoggedIn"); if (response.status === 200) { const responseJson = await response.json(); this.setState( { isLoggedIn: true, loading: false, currentUsername: responseJson.uid, isAdmin: responseJson.isAdmin, }, () => resolve() ); } else if (response.status === 403 || response.status === 401) { try { const responseJson = await response.json(); this.setState({ isLoggedIn: false, loading: false, loginDetail: responseJson.detail, }); } catch (e) { const responseText = await response.text(); console.error( "Permission denied but response invalid: ", responseText ); this.setState({ isLoggedIn: false, loading: false, loginDetail: "Permission denied, but response was invalid", }); } } else { const serverError = await response.text(); this.setState( { isLoggedIn: false, loginDetail: serverError, loading: false, currentUsername: "", }, () => resolve() ); } }) ); } async loadOauthData() { const response = await fetch("/meta/oauth/config.json"); switch (response.status) { case 200: console.log("got response data"); try { const content = await response.json(); return this.setStatePromise({ clientId: content.clientId, oAuthUri: content.oAuthUri, tokenUri: content.tokenUri, scope: content.scope, startup: false, }); } catch (err) { console.error("Could not load oauth config: ", err); return this.setStatePromise({ loginDetail: "Could not load auth configuration, please contact multimediatech", startup: false, }); } case 404: await response.text(); //consume body and discard it return this.setStatePromise({ startup: false, lastError: "Metadata not found on server, please contact administrator", }); default: await response.text(); //consume body and discard it return this.setStatePromise({ startup: false, lastError: "Server returned a " + response.status + " error trying to access metadata", }); } } async componentDidMount() { await this.loadOauthData(); await this.checkLogin(); if (!this.state.loading && !this.state.isLoggedIn) { this.setState({ redirectingTo: "/" }); } } render(){ return <div> <Switch> <Route exact path="/oauth2/callback" render={(props) => ( <OAuthCallbackComponent {...props} oAuthUri={this.state.oAuthUri} tokenUri={this.state.tokenUri} clientId={this.state.clientId} redirectUri={this.redirectUri} scope={this.state.scope} /> )} /> <Route path="/" exact={true} component={() => ( <NewFrontPage currentUsername={this.state.currentUsername} isLoggedIn={this.state.isLoggedIn} loginErrorDetail={this.state.loginDetail} isAdmin={this.state.isAdmin} oAuthUri={this.state.oAuthUri} tokenUri={this.state.tokenUri} clientId={this.state.clientId} scope={this.state.scope} resource={this.state.resource} /> )} /> <Route default component={NotFoundComponent}/> </Switch> <LoginComponentNew /> </div> } } render(<BrowserRouter root="/"><App/></BrowserRouter>, document.getElementById('app'));