From ddd157b349d220d72acc07a2d657278ae3885516 Mon Sep 17 00:00:00 2001 From: Bertin M Date: Wed, 19 Jun 2024 18:34:23 +0200 Subject: [PATCH] Auth: user can login with google auth --- package-lock.json | 44 ++++++++----------- package.json | 2 + src/App.tsx | 1 - src/__test__/registerUser.test.tsx | 7 +-- src/components/common/auth/GoogleAuthLink.tsx | 24 ++++++++++ src/pages/Login.tsx | 28 ++++++++---- src/pages/RegisterUser.tsx | 14 ++---- 7 files changed, 71 insertions(+), 49 deletions(-) create mode 100644 src/components/common/auth/GoogleAuthLink.tsx diff --git a/package-lock.json b/package-lock.json index 77dd675..b55f2f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", "jest-mock-extended": "^3.0.7", + "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", @@ -41,6 +42,7 @@ "devDependencies": { "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", + "@testing-library/dom": "^10.2.0", "@types/jest": "^29.5.12", "@types/node": "^20.14.8", "@types/react": "^18.2.66", @@ -3072,7 +3074,6 @@ "version": "10.2.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.2.0.tgz", "integrity": "sha512-CytIvb6tVOADRngTHGWNxH8LPgO/3hi/BdCEHOf7Qd2GvZVClhVP0Wo/QHzWhpki49Bk0b4VT6xpt3fx8HTSIw==", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -3091,7 +3092,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -3106,7 +3106,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3122,7 +3121,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -3133,8 +3131,7 @@ "node_modules/@testing-library/dom/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "peer": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/@testing-library/jest-dom": { "version": "6.4.6", @@ -3300,8 +3297,7 @@ "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "peer": true + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -3439,9 +3435,9 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", "dependencies": { "undici-types": "~5.26.4" } @@ -4543,9 +4539,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001637", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001637.tgz", + "integrity": "sha512-1x0qRI1mD1o9e+7mBI7XtzFAP4XszbHaVWsMiGbSPLYekKTJF7K+FNk6AsXH4sUpc+qrsI3pVgf1Jdl/uGkuSQ==", "funding": [ { "type": "opencollective", @@ -5326,8 +5322,7 @@ "node_modules/dom-accessibility-api": { "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "peer": true + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" }, "node_modules/dom-helpers": { "version": "5.2.1", @@ -5369,9 +5364,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.811", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.811.tgz", - "integrity": "sha512-CDyzcJ5XW78SHzsIOdn27z8J4ist8eaFLhdto2hSMSJQgsiwvbv2fbizcKUICryw1Wii1TI/FEkvzvJsR3awrA==" + "version": "1.4.812", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.812.tgz", + "integrity": "sha512-7L8fC2Ey/b6SePDFKR2zHAy4mbdp1/38Yk5TsARO66W3hC5KEaeKMMHoxwtuH+jcu2AYLSn9QX04i95t6Fl1Hg==" }, "node_modules/emittery": { "version": "0.13.1", @@ -9663,7 +9658,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -9773,9 +9767,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10589,7 +10583,6 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -10602,8 +10595,7 @@ "node_modules/pretty-format/node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "peer": true + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "node_modules/promise-polyfill": { "version": "8.3.0", diff --git a/package.json b/package.json index 1e51732..2704ae0 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", "jest-mock-extended": "^3.0.7", + "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", @@ -49,6 +50,7 @@ "devDependencies": { "@commitlint/cli": "^19.3.0", "@commitlint/config-conventional": "^19.2.2", + "@testing-library/dom": "^10.2.0", "@types/jest": "^29.5.12", "@types/node": "^20.14.8", "@types/react": "^18.2.66", diff --git a/src/App.tsx b/src/App.tsx index 01ecaec..65d23d5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,6 @@ import * as React from "react"; import "react-toastify/dist/ReactToastify.css"; import "./App.css"; -import "react-toastify/dist/ReactToastify.css"; import AppRoutes from "./routes/AppRoutes"; diff --git a/src/__test__/registerUser.test.tsx b/src/__test__/registerUser.test.tsx index 4567cce..3604e78 100644 --- a/src/__test__/registerUser.test.tsx +++ b/src/__test__/registerUser.test.tsx @@ -29,10 +29,11 @@ test("should render registration page correctly", async () => { expect(email).toBeInTheDocument(); expect(password).toBeInTheDocument(); - const googleButton = screen.getByRole("button", { - name: /Sign up with Google/i, + const linkElement = screen.getByRole("link", { + name: /Sign in with Google/i, }); - expect(googleButton).toBeInTheDocument(); + expect(linkElement).toBeDefined(); + expect(linkElement).toBeInTheDocument(); const loginLink = screen.getByRole("link", { name: /Login/i }); expect(loginLink).toBeInTheDocument(); diff --git a/src/components/common/auth/GoogleAuthLink.tsx b/src/components/common/auth/GoogleAuthLink.tsx new file mode 100644 index 0000000..3a69ed2 --- /dev/null +++ b/src/components/common/auth/GoogleAuthLink.tsx @@ -0,0 +1,24 @@ +import PropTypes from "prop-types"; +import { FcGoogle } from "react-icons/fc"; + +interface GoogleAuthLinkProps { + baseUrl?: string; +} + +export const GoogleAuthLink = ({ baseUrl }: GoogleAuthLinkProps) => { + const finalBaseUrl = baseUrl || ""; + + return ( + + + Sign in with Google + + ); +}; + +GoogleAuthLink.propTypes = { + baseUrl: PropTypes.string, +}; diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 8adfa99..e586d5f 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -1,4 +1,3 @@ -import { FcGoogle } from "react-icons/fc"; import { FaCircle } from "react-icons/fa"; import { useForm, SubmitHandler } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; @@ -6,6 +5,7 @@ import { useSelector, useDispatch } from "react-redux"; import { toast, ToastContainer } from "react-toastify"; import { AxiosError } from "axios"; import { useNavigate, Link } from "react-router-dom"; +import { useEffect } from "react"; import loginSchema from "../schemas/loginSchema"; import Button from "../components/common/auth/Button"; @@ -14,6 +14,7 @@ import { RootState } from "../redux/store"; import { login } from "../redux/api/loginApiSlice"; import sideImage from "../assets/sideImage.png"; import LinkPages from "../components/common/auth/LinkPages"; +import { GoogleAuthLink } from "../components/common/auth/GoogleAuthLink"; interface LoginFormInputs { email: string; @@ -56,6 +57,20 @@ const Login = () => { console.log(err); } }; + useEffect(() => { + const getTokenFromUrl = () => { + const urlSearchParams = new URLSearchParams(window.location.search); + const params = Object.fromEntries(urlSearchParams.entries()); + const { token } = params; + return token; + }; + + const token = getTokenFromUrl(); + if (token) { + localStorage.setItem("accessToken", token); + navigate("/"); + } + }); return (
@@ -91,7 +106,7 @@ const Login = () => { /> Forgot Password? @@ -102,13 +117,8 @@ const Login = () => { disabled={loading} data-testid="login-btn" /> - + +
{ const dispatch = useDispatch(); @@ -40,7 +40,7 @@ const RegisterUser = () => { } }; return ( -
+
registerImage
@@ -48,7 +48,7 @@ const RegisterUser = () => {

Create an account

-
Enter your details below
+
Enter your details below
{ > {loading ? "Loading..." : "Create Account"} - +