diff options
author | Sam Wilkins <samwilkins333@gmail.com> | 2020-05-05 02:48:03 -0700 |
---|---|---|
committer | Sam Wilkins <samwilkins333@gmail.com> | 2020-05-05 02:48:03 -0700 |
commit | aa1eb6ba4217fb48ab10539ca0373b4a1f649192 (patch) | |
tree | 69cbc232d8e642cc91d431419d36297656240527 /src/client/apis/GoogleAuthenticationManager.tsx | |
parent | 3805029b253fcf224ad8b1effadfddf743704373 (diff) |
database, delete and google authentication simplifications and improvements, as well as formatted text box updates data state at field key not just data
Diffstat (limited to 'src/client/apis/GoogleAuthenticationManager.tsx')
-rw-r--r-- | src/client/apis/GoogleAuthenticationManager.tsx | 125 |
1 files changed, 82 insertions, 43 deletions
diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx index 417dc3c3b..018c980d8 100644 --- a/src/client/apis/GoogleAuthenticationManager.tsx +++ b/src/client/apis/GoogleAuthenticationManager.tsx @@ -1,10 +1,11 @@ -import { observable, action, reaction, runInAction } from "mobx"; +import { observable, action, reaction, runInAction, IReactionDisposer } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import MainViewModal from "../views/MainViewModal"; import { Opt } from "../../new_fields/Doc"; import { Networking } from "../Network"; import "./GoogleAuthenticationManager.scss"; +import { Scripting } from "../util/Scripting"; const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth"; const prompt = "Paste authorization code here..."; @@ -15,64 +16,89 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { private authenticationLink: Opt<string> = undefined; @observable private openState = false; @observable private authenticationCode: Opt<string> = undefined; - @observable private clickedState = false; + @observable private showPasteTargetState = false; @observable private success: Opt<boolean> = undefined; @observable private displayLauncher = true; - @observable private avatar: Opt<string> = undefined; - @observable private username: Opt<string> = undefined; + @observable private credentials: any; + private disposer: Opt<IReactionDisposer>; private set isOpen(value: boolean) { runInAction(() => this.openState = value); } - private set hasBeenClicked(value: boolean) { - runInAction(() => this.clickedState = value); + private set shouldShowPasteTarget(value: boolean) { + runInAction(() => this.showPasteTargetState = value); } - public fetchOrGenerateAccessToken = async () => { - const response = await Networking.FetchFromServer("/readGoogleAccessToken"); + public cancel() { + this.openState && this.resetState(0, 0); + } + + public fetchOrGenerateAccessToken = async (displayIfFound = false) => { + let response: any = await Networking.FetchFromServer("/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<string>(async resolve => { - const disposer = reaction( + this.disposer?.(); + this.disposer = reaction( () => this.authenticationCode, async authenticationCode => { - if (authenticationCode) { - disposer(); - const { access_token, avatar, name } = await Networking.PostToServer("/writeGoogleAccessToken", { authenticationCode }); + if (authenticationCode && /\d{1}\/[\w-]{55}/.test(authenticationCode)) { + this.disposer?.(); + const response = await Networking.PostToServer("/writeGoogleAccessToken", { authenticationCode }); runInAction(() => { - this.avatar = avatar; - this.username = name; - this.hasBeenClicked = false; - this.success = false; + this.success = true; + this.credentials = response; }); - this.beginFadeout(); - resolve(access_token); + this.resetState(); + resolve(response.access_token); } } ); }); } - // otherwise, we already have a valid, stored access token - return response; + + // otherwise, we already have a valid, stored access token and user info + response = JSON.parse(response); + if (displayIfFound) { + runInAction(() => { + this.success = true; + this.credentials = response; + }); + this.resetState(-1, -1); + this.isOpen = true; + } + return response.access_token; } - beginFadeout = action(() => { - this.success = true; + resetState = action((visibleForMS: number = 3000, fadesOutInMS: number = 500) => { + if (!visibleForMS && !fadesOutInMS) { + runInAction(() => { + this.isOpen = false; + this.success = undefined; + this.displayLauncher = true; + this.credentials = undefined; + this.shouldShowPasteTarget = false; + this.authenticationCode = undefined; + }); + return; + } this.authenticationCode = undefined; this.displayLauncher = false; - this.hasBeenClicked = false; - setTimeout(action(() => { - this.isOpen = false; + this.shouldShowPasteTarget = false; + if (visibleForMS > 0 && fadesOutInMS > 0) { setTimeout(action(() => { - this.success = undefined; - this.displayLauncher = true; - this.avatar = undefined; - this.username = undefined; - }), 500); - }), 3000); + this.isOpen = false; + setTimeout(action(() => { + this.success = undefined; + this.displayLauncher = true; + this.credentials = undefined; + }), fadesOutInMS); + }), visibleForMS); + } }); constructor(props: {}) { @@ -83,27 +109,38 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { private get renderPrompt() { return ( <div className={'authorize-container'}> + {this.displayLauncher ? <button className={"dispatch"} onClick={() => { window.open(this.authenticationLink); - setTimeout(() => this.hasBeenClicked = true, 500); + setTimeout(() => this.shouldShowPasteTarget = true, 500); }} - style={{ marginBottom: this.clickedState ? 15 : 0 }} + style={{ marginBottom: this.showPasteTargetState ? 15 : 0 }} >Authorize a Google account...</button> : (null)} - {this.clickedState ? <input + {this.showPasteTargetState ? <input className={'paste-target'} onChange={action(e => this.authenticationCode = e.currentTarget.value)} placeholder={prompt} /> : (null)} - {this.avatar ? <img - className={'avatar'} - src={this.avatar} - /> : (null)} - {this.username ? <span - className={'welcome'} - >Welcome to Dash, {this.username} - </span> : (null)} + {this.credentials ? + <> + <img + className={'avatar'} + src={this.credentials.userInfo.picture} + /> + <span + className={'welcome'} + >Welcome to Dash, {this.credentials.userInfo.name} + </span> + <div + className={'disconnect'} + onClick={async () => { + await Networking.FetchFromServer("/revokeGoogleAccessToken"); + this.resetState(0, 0); + }} + >Disconnect Account</div> + </> : (null)} </div> ); } @@ -125,4 +162,6 @@ export default class GoogleAuthenticationManager extends React.Component<{}> { ); } -}
\ No newline at end of file +} + +Scripting.addGlobal("GoogleAuthenticationManager", GoogleAuthenticationManager);
\ No newline at end of file |