From e3873a6148430ab0f492c09e4563d1f990ef0c14 Mon Sep 17 00:00:00 2001 From: Mihovil Ilakovac Date: Thu, 22 Jun 2023 10:47:47 +0200 Subject: [PATCH] Fixes oAuth redirect behaviour in development (#1275) --- .../src/auth/pages/OAuthCodeExchange.jsx | 15 ++++++++++++++- .../waspComplexTest/.wasp/out/.waspchecksums | 2 +- .../web-app/src/auth/pages/OAuthCodeExchange.jsx | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/waspc/data/Generator/templates/react-app/src/auth/pages/OAuthCodeExchange.jsx b/waspc/data/Generator/templates/react-app/src/auth/pages/OAuthCodeExchange.jsx index 363cc2259..fdc0fbbcc 100644 --- a/waspc/data/Generator/templates/react-app/src/auth/pages/OAuthCodeExchange.jsx +++ b/waspc/data/Generator/templates/react-app/src/auth/pages/OAuthCodeExchange.jsx @@ -1,5 +1,5 @@ {{={= =}=}} -import React, { useEffect } from 'react' +import React, { useEffect, useRef } from 'react' import { useHistory } from 'react-router-dom' import config from '../../config.js' @@ -14,12 +14,25 @@ import { initSession } from '../helpers/user' export default function OAuthCodeExchange({ pathToApiServerRouteHandlingOauthRedirect }) { const history = useHistory() + // We are using a ref to prevent sending the OAuth token twice in development. + // Since React 18 and using their StrictMode, useEffect is called twice in development. + + // Fixing it this way is not recommended by the docs, but they don't offer any alternatives + // for this particular use case (oauth redirect page): + // https://react.dev/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development + const firstRender = useRef(true) useEffect(() => { + if (!firstRender.current) { + return + } // NOTE: Different auth methods will have different Wasp API server validation paths. // This helps us reuse one component for various methods (e.g., Google, Facebook, etc.). const apiServerUrlHandlingOauthRedirect = constructOauthRedirectApiServerUrl(pathToApiServerRouteHandlingOauthRedirect) exchangeCodeForJwtAndRedirect(history, apiServerUrlHandlingOauthRedirect) + return () => { + firstRender.current = false + } }, [history, pathToApiServerRouteHandlingOauthRedirect]) return ( diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums index e13383efb..98bfe22a1 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums @@ -739,7 +739,7 @@ "file", "web-app/src/auth/pages/OAuthCodeExchange.jsx" ], - "180e07f82c8290f9cae71e0aef97b40cf1b72a5a5fb58317feaf4cf66e629e42" + "7dbcc288201aafbb50b5f5319a28283546c81d006fe61c2a8a3c5f55c6833fb2" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/web-app/src/auth/pages/OAuthCodeExchange.jsx b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/web-app/src/auth/pages/OAuthCodeExchange.jsx index c59e46143..83ffc0ee9 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/web-app/src/auth/pages/OAuthCodeExchange.jsx +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/web-app/src/auth/pages/OAuthCodeExchange.jsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react' +import React, { useEffect, useRef } from 'react' import { useHistory } from 'react-router-dom' import config from '../../config.js' @@ -13,12 +13,25 @@ import { initSession } from '../helpers/user' export default function OAuthCodeExchange({ pathToApiServerRouteHandlingOauthRedirect }) { const history = useHistory() + // We are using a ref to prevent sending the OAuth token twice in development. + // Since React 18 and using their StrictMode, useEffect is called twice in development. + + // Fixing it this way is not recommended by the docs, but they don't offer any alternatives + // for this particular use case (oauth redirect page): + // https://react.dev/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development + const firstRender = useRef(true) useEffect(() => { + if (!firstRender.current) { + return + } // NOTE: Different auth methods will have different Wasp API server validation paths. // This helps us reuse one component for various methods (e.g., Google, Facebook, etc.). const apiServerUrlHandlingOauthRedirect = constructOauthRedirectApiServerUrl(pathToApiServerRouteHandlingOauthRedirect) exchangeCodeForJwtAndRedirect(history, apiServerUrlHandlingOauthRedirect) + return () => { + firstRender.current = false + } }, [history, pathToApiServerRouteHandlingOauthRedirect]) return (