From fdd15a484d0a8914d123991352b0740c2c7c9518 Mon Sep 17 00:00:00 2001 From: Allan Kizito Date: Sat, 11 May 2024 18:19:53 -0400 Subject: [PATCH 1/9] Synch changes from branch 53 authenticate with microsoft (#79) Synching branch to pick up the latest changes from @mawandm --------- Co-authored-by: Michael Sekamanya Co-authored-by: Michael Sekamanya <86433807+mawandm@users.noreply.github.com> --- .../client/src/components/GoogleButton.js | 80 +++++++++++++++++++ .../frontend/client/src/images/GoogleIcon.svg | 1 + 2 files changed, 81 insertions(+) create mode 100644 nesis/frontend/client/src/components/GoogleButton.js create mode 100644 nesis/frontend/client/src/images/GoogleIcon.svg diff --git a/nesis/frontend/client/src/components/GoogleButton.js b/nesis/frontend/client/src/components/GoogleButton.js new file mode 100644 index 0000000..838989e --- /dev/null +++ b/nesis/frontend/client/src/components/GoogleButton.js @@ -0,0 +1,80 @@ +import React from 'react'; +import { GoogleLogin, useGoogleLogin } from '@react-oauth/google'; +import useClient from '../utils/useClient'; +import { useConfig } from '../ConfigContext'; +import parseApiErrorMessage from '../utils/parseApiErrorMessage'; +import {jwtDecode } from 'jwt-decode'; +import { ReactComponent as GoogleIcon } from '../images/GoogleIcon.svg'; +import classes from '../styles/SignInPage.module.css'; + +export default function GoogleButton({ onFailure, onSuccess}) { + const client = useClient(); + const config = useConfig(); + + + function login(response) { + console.log(response) + if (response.credential) { + const resp_token = jwtDecode(response.credential); + console.log('token: ' + resp_token) + client + .post('sessions', { google: resp_token }) + .then((response) => { + console.log('session resp: ' + response); + onSuccess(response?.body?.email, response); + }) + .catch((error) => { + console.log('session error: ' + error) + onFailure(parseApiErrorMessage(error)); + }); + } else if (onFailure) { + onFailure('Could not login using Google'); + } + } + + const googleLogin = useGoogleLogin( { + onSuccess: (tokenRespose) => { + console.log(tokenRespose); + client.post('sessions', { google: tokenRespose}) + .then((response) => { + onSuccess(response?.body?.email, response); + }) + .catch((error) => { + console.log('ERROR: ' + error); + console.log(error); + onFailure(parseApiErrorMessage(error)); + }) + }, + onError: (error) => { + handleFailure(error); + } + + }); + + function handleFailure(error) { + console.error(error); + onFailure('Could not login using Google'); + } + + + return ( + //
+ // + //
+ <> + + + ); +} diff --git a/nesis/frontend/client/src/images/GoogleIcon.svg b/nesis/frontend/client/src/images/GoogleIcon.svg new file mode 100644 index 0000000..c06982f --- /dev/null +++ b/nesis/frontend/client/src/images/GoogleIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file From 11c516a5a9518554a37e28fec9001f8ac0d62aaf Mon Sep 17 00:00:00 2001 From: Allan Kizito Date: Sat, 18 May 2024 17:17:33 -0400 Subject: [PATCH 2/9] Implementation for google authentication --- nesis/frontend/client/package-lock.json | 288 +++++++++++- nesis/frontend/client/package.json | 1 + .../frontend/client/src/GoogleAuthContext.js | 19 + .../client/src/components/GoogleButton.js | 47 +- .../src/components/GoogleButton.test.js | 12 + .../frontend/client/src/images/GoogleIcon.png | Bin 0 -> 1831 bytes nesis/frontend/client/src/index.js | 13 +- nesis/frontend/client/src/pages/SignInPage.js | 20 +- .../client/src/styles/SignInPage.module.css | 27 +- nesis/frontend/client/src/utils/testUtils.js | 51 +++ nesis/frontend/package-lock.json | 425 ++++++++++++++++++ nesis/frontend/package.json | 1 + nesis/frontend/server/api/config.js | 2 + nesis/frontend/server/api/sessions.js | 33 +- nesis/frontend/server/profile.js | 4 + 15 files changed, 864 insertions(+), 79 deletions(-) create mode 100644 nesis/frontend/client/src/GoogleAuthContext.js create mode 100644 nesis/frontend/client/src/components/GoogleButton.test.js create mode 100644 nesis/frontend/client/src/images/GoogleIcon.png create mode 100644 nesis/frontend/client/src/utils/testUtils.js diff --git a/nesis/frontend/client/package-lock.json b/nesis/frontend/client/package-lock.json index 4dabe38..9652d46 100644 --- a/nesis/frontend/client/package-lock.json +++ b/nesis/frontend/client/package-lock.json @@ -14,6 +14,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.3", "@mui/material": "^5.15.3", + "@react-oauth/google": "^0.12.1", "axios": "^1.5.1", "babel-plugin-named-exports-order": "^0.0.2", "babel-plugin-styled-components": "^2.1.4", @@ -5263,6 +5264,15 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@react-oauth/google": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.1.tgz", + "integrity": "sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@restart/hooks": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", @@ -10773,7 +10783,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -10838,6 +10847,14 @@ "node": "*" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -11075,6 +11092,11 @@ "node": "*" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -12779,6 +12801,14 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -13987,8 +14017,7 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/extract-zip": { "version": "1.7.0", @@ -14708,6 +14737,56 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gaxios": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", + "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gaxios/node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -14967,6 +15046,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/google-auth-library": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.10.0.tgz", + "integrity": "sha512-ol+oSa5NbcGdDqA+gZ3G3mev59OHBZksBTxY/tYwjtcp1H/scAFwJfSQU9/1RALoyZ7FslNbke8j4i3ipwlyuQ==", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -14988,6 +15083,18 @@ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/gunzip-maybe": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", @@ -18477,6 +18584,14 @@ "node": ">=4" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -18568,6 +18683,33 @@ "node": ">=4.0" } }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "engines": { + "node": ">=18" + } + }, "node_modules/keyv": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", @@ -19344,7 +19486,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -19369,20 +19510,17 @@ "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/node-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/node-fetch/node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -29779,6 +29917,12 @@ "@swc/helpers": "^0.5.0" } }, + "@react-oauth/google": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.1.tgz", + "integrity": "sha512-qagsy22t+7UdkYAiT5ZhfM4StXi9PPNvw0zuwNmabrWyMKddczMtBIOARflbaIj+wHiQjnMAsZmzsUYuXeyoSg==", + "requires": {} + }, "@restart/hooks": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", @@ -33839,8 +33983,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "batch": { "version": "0.6.1", @@ -33879,6 +34022,11 @@ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, + "bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -34050,6 +34198,11 @@ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -35316,6 +35469,14 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -36225,8 +36386,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extract-zip": { "version": "1.7.0", @@ -36770,6 +36930,46 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, + "gaxios": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", + "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", + "requires": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "dependencies": { + "agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "requires": { + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + } + } + }, + "gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "requires": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -36955,6 +37155,19 @@ "slash": "^3.0.0" } }, + "google-auth-library": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.10.0.tgz", + "integrity": "sha512-ol+oSa5NbcGdDqA+gZ3G3mev59OHBZksBTxY/tYwjtcp1H/scAFwJfSQU9/1RALoyZ7FslNbke8j4i3ipwlyuQ==", + "requires": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + } + }, "gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -36973,6 +37186,15 @@ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, + "gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "requires": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + } + }, "gunzip-maybe": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz", @@ -39469,6 +39691,14 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "requires": { + "bignumber.js": "^9.0.0" + } + }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -39541,6 +39771,30 @@ "object.values": "^1.1.6" } }, + "jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "requires": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==" + }, "keyv": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", @@ -40131,7 +40385,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, "requires": { "whatwg-url": "^5.0.0" }, @@ -40139,20 +40392,17 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/nesis/frontend/client/package.json b/nesis/frontend/client/package.json index 8741498..7696252 100644 --- a/nesis/frontend/client/package.json +++ b/nesis/frontend/client/package.json @@ -9,6 +9,7 @@ "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.3", "@mui/material": "^5.15.3", + "@react-oauth/google": "^0.12.1", "axios": "^1.5.1", "babel-plugin-named-exports-order": "^0.0.2", "babel-plugin-styled-components": "^2.1.4", diff --git a/nesis/frontend/client/src/GoogleAuthContext.js b/nesis/frontend/client/src/GoogleAuthContext.js new file mode 100644 index 0000000..e4d3031 --- /dev/null +++ b/nesis/frontend/client/src/GoogleAuthContext.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { GoogleOAuthProvider } from '@react-oauth/google'; +import { useConfig } from './ConfigContext'; + +const DefaultConfigContext = React.createContext({}); + + +export default function GoogleContextProvider({ children }) { + + const config = useConfig(); + const google_client_id = config?.auth?.OAUTH_GOOGLE_CLIENT_ID; + const googleAuthEnabled = google_client_id && config?.auth?.OAUTH_GOOGLE_ENABLED; + return ( + <> + {googleAuthEnabled ? {children} : {children}} + + + ); +} diff --git a/nesis/frontend/client/src/components/GoogleButton.js b/nesis/frontend/client/src/components/GoogleButton.js index 838989e..12c47ef 100644 --- a/nesis/frontend/client/src/components/GoogleButton.js +++ b/nesis/frontend/client/src/components/GoogleButton.js @@ -1,47 +1,20 @@ import React from 'react'; -import { GoogleLogin, useGoogleLogin } from '@react-oauth/google'; +import { useGoogleLogin } from '@react-oauth/google'; import useClient from '../utils/useClient'; -import { useConfig } from '../ConfigContext'; import parseApiErrorMessage from '../utils/parseApiErrorMessage'; -import {jwtDecode } from 'jwt-decode'; -import { ReactComponent as GoogleIcon } from '../images/GoogleIcon.svg'; +import GoogleIcon from '../images/GoogleIcon.png'; import classes from '../styles/SignInPage.module.css'; export default function GoogleButton({ onFailure, onSuccess}) { - const client = useClient(); - const config = useConfig(); - - - function login(response) { - console.log(response) - if (response.credential) { - const resp_token = jwtDecode(response.credential); - console.log('token: ' + resp_token) - client - .post('sessions', { google: resp_token }) - .then((response) => { - console.log('session resp: ' + response); - onSuccess(response?.body?.email, response); - }) - .catch((error) => { - console.log('session error: ' + error) - onFailure(parseApiErrorMessage(error)); - }); - } else if (onFailure) { - onFailure('Could not login using Google'); - } - } + const client = useClient(); const googleLogin = useGoogleLogin( { onSuccess: (tokenRespose) => { - console.log(tokenRespose); client.post('sessions', { google: tokenRespose}) .then((response) => { onSuccess(response?.body?.email, response); }) .catch((error) => { - console.log('ERROR: ' + error); - console.log(error); onFailure(parseApiErrorMessage(error)); }) }, @@ -52,24 +25,10 @@ export default function GoogleButton({ onFailure, onSuccess}) { }); function handleFailure(error) { - console.error(error); onFailure('Could not login using Google'); } - return ( - //
- // - //
<> diff --git a/nesis/frontend/client/src/components/GoogleButton.test.js b/nesis/frontend/client/src/components/GoogleButton.test.js index 6c4f28d..780d37a 100644 --- a/nesis/frontend/client/src/components/GoogleButton.test.js +++ b/nesis/frontend/client/src/components/GoogleButton.test.js @@ -8,5 +8,4 @@ describe('', () => { const buttonComponent = getByText('Sign in With Google'); expect(buttonComponent).toBeInTheDocument(); }); - }); diff --git a/nesis/frontend/client/src/index.js b/nesis/frontend/client/src/index.js index a60ce55..76463d6 100644 --- a/nesis/frontend/client/src/index.js +++ b/nesis/frontend/client/src/index.js @@ -1,5 +1,5 @@ import React from 'react'; -import {createRoot} from 'react-dom/client'; +import { createRoot } from 'react-dom/client'; import './index.css'; import App from './App'; import { BrowserRouter as Router, Route } from 'react-router-dom'; @@ -21,7 +21,7 @@ root.render( - + diff --git a/nesis/frontend/client/src/pages/SignInPage.js b/nesis/frontend/client/src/pages/SignInPage.js index b8d4675..bd73f36 100644 --- a/nesis/frontend/client/src/pages/SignInPage.js +++ b/nesis/frontend/client/src/pages/SignInPage.js @@ -95,7 +95,9 @@ const SignInPage = () => { const history = useHistory(); const config = useConfig(); const azureAuthEnabled = config?.auth?.OAUTH_AZURE_ENABLED; - const googleAuthEnabled = config?.auth?.OAUTH_GOOGLE_ENABLED && config?.auth?.OAUTH_GOOGLE_CLIENT_ID !== undefined; + const googleAuthEnabled = + config?.auth?.OAUTH_GOOGLE_ENABLED && + config?.auth?.OAUTH_GOOGLE_CLIENT_ID !== undefined; const oauthEnabled = azureAuthEnabled || googleAuthEnabled; function submit(session, actions) { @@ -147,7 +149,10 @@ const SignInPage = () => { {googleAuthEnabled && !toggleCreds && ( - + )} @@ -194,7 +199,8 @@ const SignInPage = () => { )} {oauthEnabled && (
- setToggleCreds(!toggleCreds)} > Use {!toggleCreds ? 'password' : 'Azure'} diff --git a/nesis/frontend/client/src/styles/SignInPage.module.css b/nesis/frontend/client/src/styles/SignInPage.module.css index d51e60c..a2c4ea6 100644 --- a/nesis/frontend/client/src/styles/SignInPage.module.css +++ b/nesis/frontend/client/src/styles/SignInPage.module.css @@ -51,5 +51,4 @@ cursor: pointer; min-width: 50%; background-color: #d5dee896; - } - +} diff --git a/nesis/frontend/client/src/utils/testUtils.js b/nesis/frontend/client/src/utils/testUtils.js index 6ddd193..cf9b9c0 100644 --- a/nesis/frontend/client/src/utils/testUtils.js +++ b/nesis/frontend/client/src/utils/testUtils.js @@ -12,7 +12,7 @@ export function renderWithRouter( { route = '/', history = createMemoryHistory({ initialEntries: [route] }), - } = {} + } = {}, ) { const Wrapper = ({ children }) => ( {children} @@ -23,7 +23,7 @@ export function renderWithRouter( }; } -const queryClient = new QueryClient() +const queryClient = new QueryClient(); export function renderWithContext(ui, options) { return { @@ -31,9 +31,9 @@ export function renderWithContext(ui, options) { {ui} - + , - options + options, ), }; } diff --git a/nesis/frontend/server/api/sessions.js b/nesis/frontend/server/api/sessions.js index b8a43ba..367cfd4 100644 --- a/nesis/frontend/server/api/sessions.js +++ b/nesis/frontend/server/api/sessions.js @@ -16,9 +16,8 @@ const post = (requests, profile) => async (request, response) => { if (session.azure) { oauthProvider = authenticateWithAzure(requests, profile, session.azure); - } else if(session.google){ + } else if (session.google) { oauthProvider = authenticateWithGoogle(requests, profile, session.google); - } else { oauthProvider = requests .post(`${url}/sessions`) @@ -94,30 +93,32 @@ function authenticateWithAzure(requests, profile, azure) { function authenticateWithGoogle(requests, profile, google) { const googleApiUrl = 'https://www.googleapis.com/oauth2/v3/userinfo'; - return requests - .get(googleApiUrl) - .set('Authorization', `Bearer ${google.access_token}`) - .set('Content-Type', 'application/json') - .send() - .then((res) => { - if (res.body?.email === undefined || res.error) { - // invalid credentials - const error = new Error('Invalid Google credentials'); - Object.assign(error, { - status:401, - response: { - body: 'Invalid google credentials', - } - }); - throw error; - } else { - return res.body;} - }) - .then((userInfo) => sendOauthSession(requests, userInfo.name, userInfo.email, profile)); - + return requests + .get(googleApiUrl) + .set('Authorization', `Bearer ${google.access_token}`) + .set('Content-Type', 'application/json') + .send() + .then((res) => { + if (res.body?.email === undefined || res.error) { + // invalid credentials + const error = new Error('Invalid Google credentials'); + Object.assign(error, { + status: 401, + response: { + body: 'Invalid google credentials', + }, + }); + throw error; + } else { + return res.body; + } + }) + .then((userInfo) => + sendOauthSession(requests, userInfo.name, userInfo.email, profile), + ); } -function sendOauthSession(requests, name, email, profile) { +function sendOauthSession(requests, name, email, profile) { const url = profile.SERVICE_ENDPOINT; const oauth_token_key = profile.NESIS_OAUTH_TOKEN_KEY; const oauth_token_value = profile.NESIS_OAUTH_TOKEN_VALUE; @@ -126,7 +127,7 @@ function sendOauthSession(requests, name, email, profile) { name: name, [oauth_token_key]: oauth_token_value, }; - + return requests .post(`${url}/sessions`) .set('Accept', 'application/json') From 4dbb68254cb9ebb64c48bf501cf1892ff9a08b54 Mon Sep 17 00:00:00 2001 From: Allan Kizito Date: Wed, 22 May 2024 00:02:29 -0400 Subject: [PATCH 5/9] Refactoring to use google redirect oauth path instead of pop up. --- .../client/src/components/GoogleButton.js | 31 ++++++-- nesis/frontend/server/api/config.js | 2 + nesis/frontend/server/api/sessions.js | 73 ++++++++++++------- nesis/frontend/server/profile.js | 4 + 4 files changed, 77 insertions(+), 33 deletions(-) diff --git a/nesis/frontend/client/src/components/GoogleButton.js b/nesis/frontend/client/src/components/GoogleButton.js index 1e57524..4b79a65 100644 --- a/nesis/frontend/client/src/components/GoogleButton.js +++ b/nesis/frontend/client/src/components/GoogleButton.js @@ -1,28 +1,43 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useGoogleLogin } from '@react-oauth/google'; import useClient from '../utils/useClient'; import parseApiErrorMessage from '../utils/parseApiErrorMessage'; import GoogleIcon from '../images/GoogleIcon.png'; import classes from '../styles/SignInPage.module.css'; +import { useConfig } from '../ConfigContext'; export default function GoogleButton({ onFailure, onSuccess }) { const client = useClient(); + const config = useConfig(); const googleLogin = useGoogleLogin({ - onSuccess: (tokenRespose) => { + ux_mode: 'redirect', + flow: 'auth-code', + redirect_uri: config?.auth?.OAUTH_GOOGLE_REDIRECTURI + }); + + useEffect(() => { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const codeParam = urlParams.get("code"); + + if (codeParam) { client - .post('sessions', { google: tokenRespose }) + .post('sessions', { + google: codeParam, + }) .then((response) => { onSuccess(response?.body?.email, response); }) .catch((error) => { onFailure(parseApiErrorMessage(error)); }); - }, - onError: (error) => { + } else { + const error = 'Failed to Login'; handleFailure(error); - }, - }); + } + + }, []); function handleFailure(error) { onFailure('Could not login using Google'); @@ -31,7 +46,7 @@ export default function GoogleButton({ onFailure, onSuccess }) { return ( <> diff --git a/nesis/frontend/server/api/config.js b/nesis/frontend/server/api/config.js index c692029..2abd359 100644 --- a/nesis/frontend/server/api/config.js +++ b/nesis/frontend/server/api/config.js @@ -12,6 +12,8 @@ const getConfig = (requests, profile) => (request, response) => { OAUTH_AZURE_SCOPES: profile.NESIS_OAUTH_AZURE_SCOPES || ['User.Read'], OAUTH_GOOGLE_ENABLED: profile.NESIS_OAUTH_GOOGLE_ENABLED, OAUTH_GOOGLE_CLIENT_ID: profile.NESIS_OAUTH_GOOGLE_CLIENT_ID, + OAUTH_GOOGLE_CLIENT_SECRET: process.env.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, + OAUTH_GOOGLE_REDIRECTURI: process.env.NESIS_OAUTH_GOOGLE_REDIRECTURI, }, }; response.status(200).send(JSON.stringify(config)); diff --git a/nesis/frontend/server/api/sessions.js b/nesis/frontend/server/api/sessions.js index 367cfd4..a920212 100644 --- a/nesis/frontend/server/api/sessions.js +++ b/nesis/frontend/server/api/sessions.js @@ -1,4 +1,6 @@ const logger = require('../util/logger'); +const querystring = require('querystring'); +const { OAuth2Client } = require('google-auth-library'); const post = (requests, profile) => async (request, response) => { const url = profile.SERVICE_ENDPOINT; @@ -55,8 +57,7 @@ const _delete = (requests, url) => (request, response) => { }) .catch((err) => { logger.error( - `Fail posting to ${url}: ${JSON.stringify(err)} with status ${ - err.status + `Fail posting to ${url}: ${JSON.stringify(err)} with status ${err.status }`, ); response.status(err.status).send(err.response.body); @@ -90,32 +91,54 @@ function authenticateWithAzure(requests, profile, azure) { .then(() => sendOauthSession(requests, name, email, profile)); } -function authenticateWithGoogle(requests, profile, google) { - const googleApiUrl = 'https://www.googleapis.com/oauth2/v3/userinfo'; +function authenticateWithGoogle(requests, profile, code) { + const grant_type = 'authorization_code'; + const googleApiUrl = 'https://oauth2.googleapis.com/token'; + const payload = { + client_id: profile.NESIS_OAUTH_GOOGLE_CLIENT_ID, + client_secret: profile.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, + redirect_uri: profile.NESIS_OAUTH_GOOGLE_REDIRECTURI, + grant_type: grant_type, + code: code + } + + const body = querystring.stringify(payload); return requests - .get(googleApiUrl) - .set('Authorization', `Bearer ${google.access_token}`) - .set('Content-Type', 'application/json') - .send() - .then((res) => { - if (res.body?.email === undefined || res.error) { - // invalid credentials - const error = new Error('Invalid Google credentials'); - Object.assign(error, { - status: 401, - response: { - body: 'Invalid google credentials', - }, - }); - throw error; - } else { - return res.body; - } - }) - .then((userInfo) => + .post(googleApiUrl) + .set('Content-Type', 'application/x-www-form-urlencoded') + .send(body) + .then((response) => { + const resp = response.body + return verifyToken(payload.client_id, resp.id_token); + + }).then((userInfo) => sendOauthSession(requests, userInfo.name, userInfo.email, profile), - ); + ) + .catch((e) => { + const messsage = 'Invalid azure access token'; + const error = new Error(messsage); + Object.assign(error, { + status: 401, + response: { + body: 'Invalid azure access token', + }, + }); + throw error; + }); +} + +async function verifyToken(client_id, jwtToken) { + const client = new OAuth2Client(client_id); + // Call the verifyIdToken to verify and decode it + const ticket = await client.verifyIdToken({ + idToken: jwtToken, + audience: client_id, + }); + // Get the JSON with all the user info + const payload = ticket.getPayload(); + // This is a JSON object that contains all the user info + return payload; } function sendOauthSession(requests, name, email, profile) { diff --git a/nesis/frontend/server/profile.js b/nesis/frontend/server/profile.js index c3aa246..80348d0 100644 --- a/nesis/frontend/server/profile.js +++ b/nesis/frontend/server/profile.js @@ -17,6 +17,8 @@ const profile = { ], NESIS_OAUTH_GOOGLE_ENABLED: process.env.NESIS_OAUTH_GOOGLE_ENABLED, NESIS_OAUTH_GOOGLE_CLIENT_ID: process.env.NESIS_OAUTH_GOOGLE_CLIENT_ID, + NESIS_OAUTH_GOOGLE_CLIENT_SECRET: process.env.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, + NESIS_OAUTH_GOOGLE_REDIRECTURI: process.env.NESIS_OAUTH_GOOGLE_REDIRECTURI, }, DEV: { SERVICE_ENDPOINT: `http://localhost:6000/v1`, @@ -36,6 +38,8 @@ const profile = { ], NESIS_OAUTH_GOOGLE_ENABLED: true, NESIS_OAUTH_GOOGLE_CLIENT_ID: process.env.NESIS_OAUTH_GOOGLE_CLIENT_ID, + NESIS_OAUTH_GOOGLE_CLIENT_SECRET: process.env.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, + NESIS_OAUTH_GOOGLE_REDIRECTURI: 'http://localhost:3000/', }, }; From 7271e2614c3078402fde4ed844397479c1303b33 Mon Sep 17 00:00:00 2001 From: Allan Kizito Date: Wed, 22 May 2024 00:04:43 -0400 Subject: [PATCH 6/9] Formatting files --- .../frontend/client/src/components/GoogleButton.js | 11 +++++++---- nesis/frontend/server/api/sessions.js | 13 +++++++------ nesis/frontend/server/profile.js | 6 ++++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/nesis/frontend/client/src/components/GoogleButton.js b/nesis/frontend/client/src/components/GoogleButton.js index 4b79a65..cd5b347 100644 --- a/nesis/frontend/client/src/components/GoogleButton.js +++ b/nesis/frontend/client/src/components/GoogleButton.js @@ -13,13 +13,13 @@ export default function GoogleButton({ onFailure, onSuccess }) { const googleLogin = useGoogleLogin({ ux_mode: 'redirect', flow: 'auth-code', - redirect_uri: config?.auth?.OAUTH_GOOGLE_REDIRECTURI + redirect_uri: config?.auth?.OAUTH_GOOGLE_REDIRECTURI, }); useEffect(() => { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); - const codeParam = urlParams.get("code"); + const codeParam = urlParams.get('code'); if (codeParam) { client @@ -36,7 +36,6 @@ export default function GoogleButton({ onFailure, onSuccess }) { const error = 'Failed to Login'; handleFailure(error); } - }, []); function handleFailure(error) { @@ -46,7 +45,11 @@ export default function GoogleButton({ onFailure, onSuccess }) { return ( <> diff --git a/nesis/frontend/server/api/sessions.js b/nesis/frontend/server/api/sessions.js index a920212..469d44c 100644 --- a/nesis/frontend/server/api/sessions.js +++ b/nesis/frontend/server/api/sessions.js @@ -57,7 +57,8 @@ const _delete = (requests, url) => (request, response) => { }) .catch((err) => { logger.error( - `Fail posting to ${url}: ${JSON.stringify(err)} with status ${err.status + `Fail posting to ${url}: ${JSON.stringify(err)} with status ${ + err.status }`, ); response.status(err.status).send(err.response.body); @@ -100,8 +101,8 @@ function authenticateWithGoogle(requests, profile, code) { client_secret: profile.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, redirect_uri: profile.NESIS_OAUTH_GOOGLE_REDIRECTURI, grant_type: grant_type, - code: code - } + code: code, + }; const body = querystring.stringify(payload); return requests @@ -109,10 +110,10 @@ function authenticateWithGoogle(requests, profile, code) { .set('Content-Type', 'application/x-www-form-urlencoded') .send(body) .then((response) => { - const resp = response.body + const resp = response.body; return verifyToken(payload.client_id, resp.id_token); - - }).then((userInfo) => + }) + .then((userInfo) => sendOauthSession(requests, userInfo.name, userInfo.email, profile), ) .catch((e) => { diff --git a/nesis/frontend/server/profile.js b/nesis/frontend/server/profile.js index 80348d0..920b01a 100644 --- a/nesis/frontend/server/profile.js +++ b/nesis/frontend/server/profile.js @@ -17,7 +17,8 @@ const profile = { ], NESIS_OAUTH_GOOGLE_ENABLED: process.env.NESIS_OAUTH_GOOGLE_ENABLED, NESIS_OAUTH_GOOGLE_CLIENT_ID: process.env.NESIS_OAUTH_GOOGLE_CLIENT_ID, - NESIS_OAUTH_GOOGLE_CLIENT_SECRET: process.env.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, + NESIS_OAUTH_GOOGLE_CLIENT_SECRET: + process.env.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, NESIS_OAUTH_GOOGLE_REDIRECTURI: process.env.NESIS_OAUTH_GOOGLE_REDIRECTURI, }, DEV: { @@ -38,7 +39,8 @@ const profile = { ], NESIS_OAUTH_GOOGLE_ENABLED: true, NESIS_OAUTH_GOOGLE_CLIENT_ID: process.env.NESIS_OAUTH_GOOGLE_CLIENT_ID, - NESIS_OAUTH_GOOGLE_CLIENT_SECRET: process.env.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, + NESIS_OAUTH_GOOGLE_CLIENT_SECRET: + process.env.NESIS_OAUTH_GOOGLE_CLIENT_SECRET, NESIS_OAUTH_GOOGLE_REDIRECTURI: 'http://localhost:3000/', }, }; From 846d722a96cb50525a5b96fced288aff515f00fc Mon Sep 17 00:00:00 2001 From: Allan Kizito Date: Thu, 23 May 2024 22:55:08 -0400 Subject: [PATCH 7/9] Fixing signout error --- nesis/frontend/client/src/SessionContext.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesis/frontend/client/src/SessionContext.js b/nesis/frontend/client/src/SessionContext.js index 89758cc..612c986 100644 --- a/nesis/frontend/client/src/SessionContext.js +++ b/nesis/frontend/client/src/SessionContext.js @@ -86,7 +86,7 @@ async function logoutMicrosoft(config) { }, }); await msalInstance.initialize(); - msalInstance.logoutRedirect(); + await msalInstance.logoutRedirect(); } catch (e) { /* ignored */ } From eb87f147b820353e19d2e8135bed243d6a27f0e6 Mon Sep 17 00:00:00 2001 From: Allan Kizito Date: Thu, 23 May 2024 23:26:48 -0400 Subject: [PATCH 8/9] Update nesis/frontend/server/api/sessions.js Co-authored-by: Michael Sekamanya <86433807+mawandm@users.noreply.github.com> --- nesis/frontend/server/api/sessions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nesis/frontend/server/api/sessions.js b/nesis/frontend/server/api/sessions.js index 469d44c..9b11e17 100644 --- a/nesis/frontend/server/api/sessions.js +++ b/nesis/frontend/server/api/sessions.js @@ -122,7 +122,7 @@ function authenticateWithGoogle(requests, profile, code) { Object.assign(error, { status: 401, response: { - body: 'Invalid azure access token', + body: 'Invalid google access token', }, }); throw error; From 0ffd4113a24f340fca026100b0e1ffb60161b495 Mon Sep 17 00:00:00 2001 From: Allan Kizito Date: Thu, 23 May 2024 23:27:04 -0400 Subject: [PATCH 9/9] Update nesis/frontend/package.json Co-authored-by: Michael Sekamanya <86433807+mawandm@users.noreply.github.com> --- nesis/frontend/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/nesis/frontend/package.json b/nesis/frontend/package.json index aebb732..1761480 100644 --- a/nesis/frontend/package.json +++ b/nesis/frontend/package.json @@ -33,7 +33,6 @@ "express": "^4.18.2", "google-auth-library": "^9.10.0", "jsonwebtoken": "^9.0.2", - "mindsdb-js-sdk": "^2.2.2", "superagent": "^8.1.2", "winston": "^3.10.0" },