From 45b97084b3d49d521ff39963f250e9cd9efe3f8e Mon Sep 17 00:00:00 2001
From: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
Date: Wed, 9 Oct 2019 05:00:23 -0400
Subject: client side google api authentication UI

---
 src/client/apis/AuthenticationManager.tsx | 90 +++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 src/client/apis/AuthenticationManager.tsx

(limited to 'src/client/apis/AuthenticationManager.tsx')

diff --git a/src/client/apis/AuthenticationManager.tsx b/src/client/apis/AuthenticationManager.tsx
new file mode 100644
index 000000000..75a50d8f9
--- /dev/null
+++ b/src/client/apis/AuthenticationManager.tsx
@@ -0,0 +1,90 @@
+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";
+
+@observer
+export default class AuthenticationManager extends React.Component<{}> {
+    public static Instance: AuthenticationManager;
+    @observable private openState = false;
+    private authenticationLink: Opt<string> = undefined;
+    @observable private authenticationCode: Opt<string> = undefined;
+    @observable private clickedState = false;
+
+    private get isOpen() {
+        return this.openState;
+    }
+
+    private set isOpen(value: boolean) {
+        runInAction(() => this.openState = value);
+    }
+
+    private get hasBeenClicked() {
+        return this.clickedState;
+    }
+
+    private set hasBeenClicked(value: boolean) {
+        runInAction(() => this.clickedState = value);
+    }
+
+    public executeFullRoutine = async (authenticationLink: string) => {
+        this.authenticationLink = authenticationLink;
+        this.isOpen = true;
+        return new Promise<string>(async resolve => {
+            const disposer = reaction(
+                () => this.authenticationCode,
+                authenticationCode => {
+                    if (authenticationCode) {
+                        Identified.PostToServer(RouteStore.writeGooglePhotosAccessToken, { authenticationCode }).then(token => {
+                            this.isOpen = false;
+                            this.hasBeenClicked = false;
+                            resolve(token);
+                            disposer();
+                        });
+                    }
+                }
+            );
+        });
+    }
+
+    constructor(props: {}) {
+        super(props);
+        AuthenticationManager.Instance = this;
+    }
+
+    private handleClick = () => {
+        window.open(this.authenticationLink);
+        this.hasBeenClicked = true;
+    }
+
+    private handlePaste = action((e: React.ChangeEvent<HTMLInputElement>) => {
+        this.authenticationCode = e.currentTarget.value;
+    })
+
+    private get renderPrompt() {
+        return (
+            <div style={{ display: "flex", flexDirection: "column" }}>
+                <button onClick={this.handleClick}>Please click here to authorize a Google account...</button>
+                {this.clickedState ? <input
+                    onChange={this.handlePaste}
+                    placeholder={"Please paste the external authetication code here..."}
+                    style={{ marginTop: 15 }}
+                /> : (null)}
+            </div>
+        )
+    }
+
+    render() {
+        return (
+            <MainViewModal
+                isDisplayed={this.openState}
+                interactive={true}
+                contents={this.renderPrompt}
+            />
+        );
+    }
+
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 0d1d884ae24c74cc92b3be7a429873bde3d4370c Mon Sep 17 00:00:00 2001
From: Sam Wilkins <35748010+samwilkins333@users.noreply.github.com>
Date: Wed, 9 Oct 2019 05:38:16 -0400
Subject: clean up and extensibility for authentication manager

---
 src/client/apis/AuthenticationManager.tsx          | 42 +++++++++++++---------
 .../apis/google_docs/GooglePhotosClientUtils.ts    |  8 +----
 2 files changed, 26 insertions(+), 24 deletions(-)

(limited to 'src/client/apis/AuthenticationManager.tsx')

diff --git a/src/client/apis/AuthenticationManager.tsx b/src/client/apis/AuthenticationManager.tsx
index 75a50d8f9..7d8d4f534 100644
--- a/src/client/apis/AuthenticationManager.tsx
+++ b/src/client/apis/AuthenticationManager.tsx
@@ -6,6 +6,8 @@ import { Opt } from "../../new_fields/Doc";
 import { Identified } from "../Network";
 import { RouteStore } from "../../server/RouteStore";
 
+const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth";
+
 @observer
 export default class AuthenticationManager extends React.Component<{}> {
     public static Instance: AuthenticationManager;
@@ -30,24 +32,30 @@ export default class AuthenticationManager extends React.Component<{}> {
         runInAction(() => this.clickedState = value);
     }
 
-    public executeFullRoutine = async (authenticationLink: string) => {
-        this.authenticationLink = authenticationLink;
-        this.isOpen = true;
-        return new Promise<string>(async resolve => {
-            const disposer = reaction(
-                () => this.authenticationCode,
-                authenticationCode => {
-                    if (authenticationCode) {
-                        Identified.PostToServer(RouteStore.writeGooglePhotosAccessToken, { authenticationCode }).then(token => {
-                            this.isOpen = false;
-                            this.hasBeenClicked = false;
-                            resolve(token);
-                            disposer();
-                        });
+    public executeFullRoutine = async (service: string) => {
+        let response = await Identified.FetchFromServer(`/read${service}AccessToken`);
+        // 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.authenticationCode,
+                    authenticationCode => {
+                        if (authenticationCode) {
+                            Identified.PostToServer(`/write${service}AccessToken`, { authenticationCode }).then(token => {
+                                this.isOpen = false;
+                                this.hasBeenClicked = false;
+                                resolve(token);
+                                disposer();
+                            });
+                        }
                     }
-                }
-            );
-        });
+                );
+            });
+        }
+        // otherwise, we already have a valid, stored access token
+        return response;
     }
 
     constructor(props: {}) {
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index dd1492f51..8e88040db 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -19,14 +19,8 @@ import { List } from "../../../new_fields/List";
 
 export namespace GooglePhotos {
 
-    const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth";
-
     const endpoint = async () => {
-        let response = await Identified.FetchFromServer(RouteStore.readGooglePhotosAccessToken);
-        if (new RegExp(AuthenticationUrl).test(response)) {
-            response = await AuthenticationManager.Instance.executeFullRoutine(response);
-        }
-        return new Photos(response);
+        return new Photos(await AuthenticationManager.Instance.executeFullRoutine("GooglePhotos"));
     };
 
     export enum MediaType {
-- 
cgit v1.2.3-70-g09d2


From 8f935493d8db08d4c1173f0dafb1fe7f2d414f54 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Wed, 9 Oct 2019 05:41:11 -0400
Subject: semicolons

---
 src/client/apis/AuthenticationManager.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/client/apis/AuthenticationManager.tsx')

diff --git a/src/client/apis/AuthenticationManager.tsx b/src/client/apis/AuthenticationManager.tsx
index 7d8d4f534..360554b8e 100644
--- a/src/client/apis/AuthenticationManager.tsx
+++ b/src/client/apis/AuthenticationManager.tsx
@@ -70,7 +70,7 @@ export default class AuthenticationManager extends React.Component<{}> {
 
     private handlePaste = action((e: React.ChangeEvent<HTMLInputElement>) => {
         this.authenticationCode = e.currentTarget.value;
-    })
+    });
 
     private get renderPrompt() {
         return (
@@ -82,7 +82,7 @@ export default class AuthenticationManager extends React.Component<{}> {
                     style={{ marginTop: 15 }}
                 /> : (null)}
             </div>
-        )
+        );
     }
 
     render() {
-- 
cgit v1.2.3-70-g09d2


From 33841ef7ca23348dd03017768504e536cf567177 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Wed, 9 Oct 2019 05:42:15 -0400
Subject: cleanup

---
 src/client/apis/AuthenticationManager.tsx | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

(limited to 'src/client/apis/AuthenticationManager.tsx')

diff --git a/src/client/apis/AuthenticationManager.tsx b/src/client/apis/AuthenticationManager.tsx
index 360554b8e..d8f6b675b 100644
--- a/src/client/apis/AuthenticationManager.tsx
+++ b/src/client/apis/AuthenticationManager.tsx
@@ -4,9 +4,9 @@ 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";
 
 const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth";
+const prompt = "Please paste the external authetication code here...";
 
 @observer
 export default class AuthenticationManager extends React.Component<{}> {
@@ -16,18 +16,10 @@ export default class AuthenticationManager extends React.Component<{}> {
     @observable private authenticationCode: Opt<string> = undefined;
     @observable private clickedState = false;
 
-    private get isOpen() {
-        return this.openState;
-    }
-
     private set isOpen(value: boolean) {
         runInAction(() => this.openState = value);
     }
 
-    private get hasBeenClicked() {
-        return this.clickedState;
-    }
-
     private set hasBeenClicked(value: boolean) {
         runInAction(() => this.clickedState = value);
     }
@@ -78,7 +70,7 @@ export default class AuthenticationManager extends React.Component<{}> {
                 <button onClick={this.handleClick}>Please click here to authorize a Google account...</button>
                 {this.clickedState ? <input
                     onChange={this.handlePaste}
-                    placeholder={"Please paste the external authetication code here..."}
+                    placeholder={prompt}
                     style={{ marginTop: 15 }}
                 /> : (null)}
             </div>
-- 
cgit v1.2.3-70-g09d2

