From 70a142b84d01e89b56d027b24e37122fa90fe25b Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Wed, 9 Oct 2019 16:53:16 -0400 Subject: better authentication feedback, cleanup --- src/client/apis/GoogleAuthenticationManager.tsx | 114 ++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/client/apis/GoogleAuthenticationManager.tsx (limited to 'src/client/apis/GoogleAuthenticationManager.tsx') diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx new file mode 100644 index 000000000..1ab6380ef --- /dev/null +++ b/src/client/apis/GoogleAuthenticationManager.tsx @@ -0,0 +1,114 @@ +import { observable, action, reaction, runInAction } from "mobx"; +import { observer } from "mobx-react"; +import * as React from "react"; +import MainViewModal from "../views/MainViewModal"; +import { Opt } from "../../new_fields/Doc"; +import { Identified } from "../Network"; +import { RouteStore } from "../../server/RouteStore"; +import "./GoogleAuthenticationManager.scss"; + +const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth"; +const prompt = "Paste authorization code here..."; + +@observer +export default class GoogleAuthenticationManager extends React.Component<{}> { + public static Instance: GoogleAuthenticationManager; + @observable private openState = false; + private authenticationLink: Opt = undefined; + @observable private authenticationCode: Opt = undefined; + @observable private clickedState = false; + @observable private success: Opt = undefined; + @observable private displayLauncher = true; + + private set isOpen(value: boolean) { + runInAction(() => this.openState = value); + } + + private set hasBeenClicked(value: boolean) { + runInAction(() => this.clickedState = value); + } + + public fetchOrGenerateAccessToken = async () => { + let response = await Identified.FetchFromServer(RouteStore.readGoogleAccessToken); + // if this is an authentication url, activate the UI to register the new access token + if (new RegExp(AuthenticationUrl).test(response)) { + this.isOpen = true; + this.authenticationLink = response; + return new Promise(async resolve => { + const disposer = reaction( + () => this.authenticationCode, + authenticationCode => { + if (authenticationCode) { + Identified.PostToServer(RouteStore.writeGoogleAccessToken, { authenticationCode }).then( + token => { + runInAction(() => this.success = true); + setTimeout(() => { + this.isOpen = false; + runInAction(() => this.displayLauncher = false); + setTimeout(() => { + runInAction(() => this.success = undefined); + runInAction(() => this.displayLauncher = true); + this.hasBeenClicked = false; + }, 500); + }, 1000); + disposer(); + resolve(token); + }, + () => { + this.hasBeenClicked = false; + runInAction(() => this.success = false); + } + ); + } + } + ); + }); + } + // otherwise, we already have a valid, stored access token + return response; + } + + constructor(props: {}) { + super(props); + GoogleAuthenticationManager.Instance = this; + } + + private handleClick = () => { + window.open(this.authenticationLink); + setTimeout(() => this.hasBeenClicked = true, 500); + } + + private handlePaste = action((e: React.ChangeEvent) => { + this.authenticationCode = e.currentTarget.value; + }); + + private get renderPrompt() { + return ( +
+ {this.displayLauncher ? : (null)} + {this.clickedState ? : (null)} +
+ ); + } + + render() { + return ( + + ); + } + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2