From ad4aaccca939fdf58b8e4a8b59b5185f19d29d5e Mon Sep 17 00:00:00 2001
From: thijsheijden <hi@thijsheijden.nl>
Date: Thu, 10 Feb 2022 20:07:30 +0100
Subject: [PATCH] feat(authorization): first version that works well

Need to add a authChanged hook.
---
 apps/graphpolaris/project.json                | 50 ++++++++++++++-----
 apps/graphpolaris/src/main.tsx                | 22 ++++----
 .../src/web/components/login/loginScreen.tsx  | 17 +++++--
 certs/local-cert.pem                          | 28 +++++++++++
 certs/local-key.pem                           | 28 +++++++++++
 .../src/lib/authorizationHandler.ts           | 32 ++++++++++++
 package.json                                  |  1 +
 yarn.lock                                     | 29 ++++++++++-
 8 files changed, 176 insertions(+), 31 deletions(-)
 create mode 100644 certs/local-cert.pem
 create mode 100644 certs/local-key.pem

diff --git a/apps/graphpolaris/project.json b/apps/graphpolaris/project.json
index 9b50ffffb..af6b8e1c6 100644
--- a/apps/graphpolaris/project.json
+++ b/apps/graphpolaris/project.json
@@ -3,9 +3,25 @@
   "sourceRoot": "apps/graphpolaris/src",
   "projectType": "application",
   "targets": {
+    "dev": {
+      "executor": "@nrwl/web:dev-server",
+      "options": {
+        "buildTarget": "graphpolaris:build",
+        "host": "local.datastrophe.science.uu.nl",
+        "port": 4200,
+        "watch": true,
+        "hmr": true,
+        "ssl": true,
+        "sslCert": "./certs/local-cert.pem",
+        "sslKey": "./certs/local-key.pem",
+        "open": true
+      }
+    },
     "build": {
       "executor": "@nrwl/web:webpack",
-      "outputs": ["{options.outputPath}"],
+      "outputs": [
+        "{options.outputPath}"
+      ],
       "defaultConfiguration": "production",
       "options": {
         "compiler": "babel",
@@ -19,18 +35,18 @@
           "apps/graphpolaris/src/favicon.ico",
           "apps/graphpolaris/src/assets"
         ],
-        "styles": ["apps/graphpolaris/src/styles.scss"],
+        "styles": [
+          "apps/graphpolaris/src/styles.scss"
+        ],
         "scripts": [],
         "webpackConfig": "@nrwl/react/plugins/webpack"
       },
       "configurations": {
         "production": {
-          "fileReplacements": [
-            {
-              "replace": "apps/graphpolaris/src/environments/environment.ts",
-              "with": "apps/graphpolaris/src/environments/environment.prod.ts"
-            }
-          ],
+          "fileReplacements": [{
+            "replace": "apps/graphpolaris/src/environments/environment.ts",
+            "with": "apps/graphpolaris/src/environments/environment.prod.ts"
+          }],
           "optimization": true,
           "outputHashing": "all",
           "sourceMap": false,
@@ -55,14 +71,20 @@
     },
     "lint": {
       "executor": "@nrwl/linter:eslint",
-      "outputs": ["{options.outputFile}"],
+      "outputs": [
+        "{options.outputFile}"
+      ],
       "options": {
-        "lintFilePatterns": ["apps/graphpolaris/**/*.{ts,tsx,js,jsx}"]
+        "lintFilePatterns": [
+          "apps/graphpolaris/**/*.{ts,tsx,js,jsx}"
+        ]
       }
     },
     "test": {
       "executor": "@nrwl/jest:jest",
-      "outputs": ["coverage/apps/graphpolaris"],
+      "outputs": [
+        "coverage/apps/graphpolaris"
+      ],
       "options": {
         "jestConfig": "apps/graphpolaris/jest.config.js",
         "passWithNoTests": true
@@ -91,7 +113,9 @@
     },
     "build-storybook": {
       "executor": "@nrwl/storybook:build",
-      "outputs": ["{options.outputPath}"],
+      "outputs": [
+        "{options.outputPath}"
+      ],
       "options": {
         "uiFramework": "@storybook/react",
         "outputPath": "dist/storybook/graphpolaris",
@@ -107,4 +131,4 @@
     }
   },
   "tags": []
-}
+}
\ No newline at end of file
diff --git a/apps/graphpolaris/src/main.tsx b/apps/graphpolaris/src/main.tsx
index f26b53e97..40681d3d2 100644
--- a/apps/graphpolaris/src/main.tsx
+++ b/apps/graphpolaris/src/main.tsx
@@ -8,17 +8,15 @@ import App from './app/app';
 import LoginPopupComponent from './web/components/login/popup';
 
 ReactDOM.render(
-  <StrictMode>
-    <Provider store={store}>
-      <Router>
-        <Routes>
-          {/* Route to auth component in popup */}
-          <Route path="/auth" element={<LoginPopupComponent />}></Route>
-          {/* App */}
-          <Route path="/" element={<App />}></Route>
-        </Routes>
-      </Router>
-    </Provider>
-  </StrictMode>,
+  <Provider store={store}>
+    <Router>
+      <Routes>
+        {/* Route to auth component in popup */}
+        <Route path="/auth" element={<LoginPopupComponent />}></Route>
+        {/* App */}
+        <Route path="/" element={<App />}></Route>
+      </Routes>
+    </Router>
+  </Provider>,
   document.getElementById('root')
 );
diff --git a/apps/graphpolaris/src/web/components/login/loginScreen.tsx b/apps/graphpolaris/src/web/components/login/loginScreen.tsx
index 903b4eba2..e5d4f467b 100644
--- a/apps/graphpolaris/src/web/components/login/loginScreen.tsx
+++ b/apps/graphpolaris/src/web/components/login/loginScreen.tsx
@@ -1,3 +1,4 @@
+import { AuthorizationHandler } from '@graphpolaris/shared/data-access/authorization';
 import styled from 'styled-components';
 
 const Wrapper = styled.div`
@@ -77,13 +78,15 @@ const LoginScreen = () => {
     window.addEventListener('message', (event) => receiveMessage(event), false);
   };
 
-  const receiveMessage = (event: any) => {
+  const receiveMessage = (event: MessageEvent) => {
     // Do we trust the sender of this message? (might be
     // different from what we originally opened)
-    if (event.origin !== 'http://localhost:4200') {
+    if (!event.isTrusted) {
       return;
     }
-    console.log(event);
+
+    // Set access token
+    AuthorizationHandler.instance().SetAccessToken(event.data);
   };
 
   return (
@@ -93,14 +96,18 @@ const LoginScreen = () => {
         <h1>Sign In</h1>
         <img
           onClick={() =>
-            openSignInWindow('http://localhost:3000/sign-in?provider=1')
+            openSignInWindow(
+              'https://datastrophe.science.uu.nl/user/sign-in?provider=1'
+            )
           }
           src="assets/login-screen/google.png"
           alt="sign up with google"
         />
         <img
           onClick={() =>
-            openSignInWindow('http://localhost:3000/sign-in?provider=2')
+            openSignInWindow(
+              'https://datastrophe.science.uu.nl/user/sign-in?provider=2'
+            )
           }
           src="assets/login-screen/github.png"
           alt="sign up with github"
diff --git a/certs/local-cert.pem b/certs/local-cert.pem
new file mode 100644
index 000000000..0db26ae7f
--- /dev/null
+++ b/certs/local-cert.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEwzCCAyugAwIBAgIRAIb+R7ZfGJ3oiTEycYz8cGUwDQYJKoZIhvcNAQELBQAw
+gckxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTFPME0GA1UECwxGdGhp
+anNoZWlqZGVuQFRoaWpzcy1NQlAuZG9tYWluX25vdF9zZXQuaW52YWxpZCAoVGhp
+anMgdmFuIGRlciBIZWlqZGVuKTFWMFQGA1UEAwxNbWtjZXJ0IHRoaWpzaGVpamRl
+bkBUaGlqc3MtTUJQLmRvbWFpbl9ub3Rfc2V0LmludmFsaWQgKFRoaWpzIHZhbiBk
+ZXIgSGVpamRlbikwHhcNMjIwMjA5MTYyOTQxWhcNMjQwNTA5MTUyOTQxWjB6MScw
+JQYDVQQKEx5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxTzBNBgNVBAsM
+RnRoaWpzaGVpamRlbkBUaGlqc3MtTUJQLmRvbWFpbl9ub3Rfc2V0LmludmFsaWQg
+KFRoaWpzIHZhbiBkZXIgSGVpamRlbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQC2w3PIK5efAeKzi/P5DTvoZ5pajZcqgxXnKWHwa4L/f9Jb//9QBuo4
+4I0wlnMePg3luFaJsLnI1znWiY/iuf53P68w8dNHlX4ZMP6JaPROAoix5bPGRjXY
+jeWUtsdOyfmVtALdYfmI/MWUxf3+D7gvMiBwngSYJn9xKDdkK8Pwj1i+CiJ15fUQ
+rKQHS3tFTFp8szzYtc8L6E+43/WfLj79YEfDE5vIV+35vgF+GCbVs7C9aw547oaE
+zIOmLDRNxjOUMQbESbIM8X/32FfKYGjYJPGWM+1MbSfcfQSFQ/mSephek25Gke/B
+W8m+20afeOPNq8n8Et0xvl2eEsydr/0tAgMBAAGjdDByMA4GA1UdDwEB/wQEAwIF
+oDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBTjYFGuSfA7hYlAtujE
+7clLgFRoKjAqBgNVHREEIzAhgh9sb2NhbC5kYXRhc3Ryb3BoZS5zY2llbmNlLnV1
+Lm5sMA0GCSqGSIb3DQEBCwUAA4IBgQCTnvdrsD8YUMXuOisyZgCBo9welMyvLTgJ
+/A782zv93qpJZ6PDu1R5ivKPOhEivHuzvB0ujza403Urj9w7KXjZQL9jQnFFcdDO
+07PD+dCmOjiPsHS7WP8GLHbSgKs6vmosxKwUA7znB8faDrOLmsDnnunOJ+U6u2BM
+p9k5/n85b9wp7MiHs+EBTKDqKaooZ9gqibDmSyXv6dNZyWDomLZiFB8U5V02oFVY
+sEh7Kl91A89M4fvJe45uMChbgAmbxUOofNlDMAr8tXs+E9Y8W6hV7CFqw6dU1bM+
+HoqawYPvMIJpSOmR8ZBCz9zd9noXybpE2SQdgaB3oLg7cz6FdO2VVnnyGSAE2bfT
+vM+a86rAl5BttyolDfgU+jfRqK9j7ZQs5oR5ab0Ck90bUbESzRQfzHfp9I9weYK3
+SNpsbZYMcjagZZPqVsxK8+rh3SRrdcwiJhO2Xm1DktnBJG6TMfN3zZG648iGGbMC
+K5BZL8VW6rrgbC9FvM2xq68KAnaZ06M=
+-----END CERTIFICATE-----
diff --git a/certs/local-key.pem b/certs/local-key.pem
new file mode 100644
index 000000000..8e69d4d5c
--- /dev/null
+++ b/certs/local-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC2w3PIK5efAeKz
+i/P5DTvoZ5pajZcqgxXnKWHwa4L/f9Jb//9QBuo44I0wlnMePg3luFaJsLnI1znW
+iY/iuf53P68w8dNHlX4ZMP6JaPROAoix5bPGRjXYjeWUtsdOyfmVtALdYfmI/MWU
+xf3+D7gvMiBwngSYJn9xKDdkK8Pwj1i+CiJ15fUQrKQHS3tFTFp8szzYtc8L6E+4
+3/WfLj79YEfDE5vIV+35vgF+GCbVs7C9aw547oaEzIOmLDRNxjOUMQbESbIM8X/3
+2FfKYGjYJPGWM+1MbSfcfQSFQ/mSephek25Gke/BW8m+20afeOPNq8n8Et0xvl2e
+Esydr/0tAgMBAAECggEBAImNj13PmV0egS5bHjOLB1TCbQTMXkKryFdj6QeXE1AT
+NxLxGIp1ueE2+GziPyA62iDUXaVh8mI7wpc6j6W4ENJVhxiSWU8eL3rsShbHfGAe
+Ph2OYYDQJQSov2rvKhCdqRBIHIPckn/MpzRy09hcomY7FvlLpO+SwgY7m3z0B5PM
+OWpy2qmHi3WZQ7f5ejdwb9A4kCVA6Max4NgMi637QY/ShQwqEQ20tB9XNDIpKyTV
+uwKgpZjAislpDwPmhyi5x9VMD9/qABFcg8JLnZ8MSebncFkteuIIR4eI3osg4bAx
+17O5u93juPOxGui2dEhPFf/YZrUWpsik3/RjAnuHPQ0CgYEA5gaeXk/S7zbgHq3g
+z5uj/m1lRb4XYVcL7PTkRuqzywXfqSRdOlmYbClevgDWlU2tcZ5N+Kjj4ee7Xxel
+PMtpoNDgGnB/Leb/F4pqHuxXNQvfN8KlnXuk0SDHs3VRd4YR54C0PFKcCpCQXMpb
+qFxUG0ob/+WmT30wFTz4PqYaktcCgYEAy2adjHpkG3jK9lShY3At8gX4ikDxKHUe
+SAGGYMNWe6cjlp5X5PHjALn1sJEnJ5d50y/jwn/pUz/GvbHuV54XqsWUW1Z28M+O
+I/IOOM/eFrY5I3+E7YX/gZv9XV+GPS5cDw2U9WMJBtSZFteqclhdK/YMGVexQ/ab
+OUEM0S+h85sCgYEA4T0H5BfL11tnmALxCLlBmwgpy2H46OLglZWy1dJKXXmR6cDm
+3RUQUJEt6WVOuYIHXSMC/IL8KZ/M9K9lqKMR+lutpZYUorD3hmiNw1vvhMzsNWCO
+5SdGW1T61zoAnMYWUBbR5eOKUjn+ci3gFHrcDKDDzA5mjJ1r8M/z0Py7Np8CgYB5
+pU5WRKB4WZ6xAd5flSi1VWLWdI6GDr1kfRz74/dmDojXPK3+a7fCqHTK+5S6NfqT
+FlIV8d/+fOcEblTIK/GlnXLjyWtrDAbLcqmUyqTdWnADzfEXCQvNXRiDbmzfTEmc
+axgKRgeRATbplWQH7NcUQpvr0ClhJyygakobFWy7PwKBgDH35TEzSrTSc3B++zHU
+OIM5MfQho9eOu844udnJq2M6DfymsE1ZFb7MB8nJkcivL+NJANaCExkfDr6a71+O
+BuElJlnd45w8bBt0y0Oxv2B6R/vbLwfs1UaA5Bd48exM+irYcivPqq6od0Y/zAC6
+85AtslKKD101x65j6Iy9fp69
+-----END PRIVATE KEY-----
diff --git a/libs/shared/data-access/authorization/src/lib/authorizationHandler.ts b/libs/shared/data-access/authorization/src/lib/authorizationHandler.ts
index 8f2455e22..061bebfd9 100644
--- a/libs/shared/data-access/authorization/src/lib/authorizationHandler.ts
+++ b/libs/shared/data-access/authorization/src/lib/authorizationHandler.ts
@@ -1,3 +1,5 @@
+import { Cookies } from 'react-cookie';
+
 export class AuthorizationHandler {
   private static _instance: AuthorizationHandler;
   private accessToken = '';
@@ -31,6 +33,9 @@ export class AuthorizationHandler {
       this.userID = authResponse.userID ?? '';
       this.sessionID = authResponse.sessionID ?? '';
 
+      // Init refresh token
+      this.initialiseRefreshToken();
+
       // Start the automatic refreshing every 10 minutes
       setInterval(() => {
         this.refreshTokens();
@@ -83,6 +88,7 @@ export class AuthorizationHandler {
    * refreshTokens refreshes tokens
    */
   private async refreshTokens() {
+    console.log('refreshing tokens');
     // Get a new access + refresh token pair
     const authResponse = await this.getNewAccessToken();
 
@@ -146,6 +152,26 @@ export class AuthorizationHandler {
   SessionID(): string {
     return this.sessionID;
   }
+
+  // MARK: Setters
+  /**
+   * SetAccessToken sets the current access token (should only be called by the sign-in component)
+   * @param accessToken
+   */
+  SetAccessToken(accessToken: string) {
+    this.accessToken = accessToken;
+
+    console.log(this.accessToken);
+
+    // Activate the refresh token
+    this.initialiseRefreshToken();
+
+    // TODO: Get the user info
+    // Start the automatic refreshing every 10 minutes
+    setInterval(() => {
+      this.refreshTokens();
+    }, 30 * 1000);
+  }
 }
 
 type authResponse = {
@@ -154,3 +180,9 @@ type authResponse = {
   userID?: string;
   sessionID?: string;
 };
+
+type userInfoResponse = {
+  userID: string;
+  userName: string;
+  userEmail: string;
+};
diff --git a/package.json b/package.json
index 958b95073..660fe748e 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
     "@types/styled-components": "^5.1.21",
     "core-js": "^3.6.5",
     "react": "17.0.2",
+    "react-cookie": "^4.1.1",
     "react-dom": "17.0.2",
     "react-grid-layout": "^1.3.3",
     "react-json-view": "^1.21.3",
diff --git a/yarn.lock b/yarn.lock
index c664650c9..35bf83bcf 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3966,6 +3966,11 @@
   dependencies:
     "@types/node" "*"
 
+"@types/cookie@^0.3.3":
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803"
+  integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==
+
 "@types/eslint-scope@^3.7.0":
   version "3.7.3"
   resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224"
@@ -4040,7 +4045,7 @@
   dependencies:
     "@types/unist" "*"
 
-"@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0":
+"@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.0.1", "@types/hoist-non-react-statics@^3.3.0":
   version "3.3.1"
   resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
   integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
@@ -6792,6 +6797,11 @@ cookie@0.4.1:
   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
   integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
 
+cookie@^0.4.0:
+  version "0.4.2"
+  resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
+  integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
+
 copy-concurrently@^1.0.0:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
@@ -13630,6 +13640,15 @@ react-colorful@^5.1.2:
   resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.5.1.tgz#29d9c4e496f2ca784dd2bb5053a3a4340cfaf784"
   integrity sha512-M1TJH2X3RXEt12sWkpa6hLc/bbYS0H6F4rIqjQZ+RxNBstpY67d9TrFXtqdZwhpmBXcCwEi7stKqFue3ZRkiOg==
 
+react-cookie@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/react-cookie/-/react-cookie-4.1.1.tgz#832e134ad720e0de3e03deaceaab179c4061a19d"
+  integrity sha512-ffn7Y7G4bXiFbnE+dKhHhbP+b8I34mH9jqnm8Llhj89zF4nPxPutxHT1suUqMeCEhLDBI7InYwf1tpaSoK5w8A==
+  dependencies:
+    "@types/hoist-non-react-statics" "^3.0.1"
+    hoist-non-react-statics "^3.0.0"
+    universal-cookie "^4.0.0"
+
 react-docgen-typescript@^2.0.0:
   version "2.2.2"
   resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c"
@@ -16086,6 +16105,14 @@ unist-util-visit@2.0.3, unist-util-visit@^2.0.0:
     unist-util-is "^4.0.0"
     unist-util-visit-parents "^3.0.0"
 
+universal-cookie@^4.0.0:
+  version "4.0.4"
+  resolved "https://registry.yarnpkg.com/universal-cookie/-/universal-cookie-4.0.4.tgz#06e8b3625bf9af049569ef97109b4bb226ad798d"
+  integrity sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw==
+  dependencies:
+    "@types/cookie" "^0.3.3"
+    cookie "^0.4.0"
+
 universalify@^0.1.0, universalify@^0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
-- 
GitLab