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