Fixes oAuth redirect behaviour in development (#1275)

This commit is contained in:
Mihovil Ilakovac 2023-06-22 10:47:47 +02:00 committed by GitHub
parent 67f88cc50e
commit e3873a6148
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 3 deletions

View File

@ -1,5 +1,5 @@
{{={= =}=}} {{={= =}=}}
import React, { useEffect } from 'react' import React, { useEffect, useRef } from 'react'
import { useHistory } from 'react-router-dom' import { useHistory } from 'react-router-dom'
import config from '../../config.js' import config from '../../config.js'
@ -14,12 +14,25 @@ import { initSession } from '../helpers/user'
export default function OAuthCodeExchange({ pathToApiServerRouteHandlingOauthRedirect }) { export default function OAuthCodeExchange({ pathToApiServerRouteHandlingOauthRedirect }) {
const history = useHistory() 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(() => { useEffect(() => {
if (!firstRender.current) {
return
}
// NOTE: Different auth methods will have different Wasp API server validation paths. // 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.). // This helps us reuse one component for various methods (e.g., Google, Facebook, etc.).
const apiServerUrlHandlingOauthRedirect = constructOauthRedirectApiServerUrl(pathToApiServerRouteHandlingOauthRedirect) const apiServerUrlHandlingOauthRedirect = constructOauthRedirectApiServerUrl(pathToApiServerRouteHandlingOauthRedirect)
exchangeCodeForJwtAndRedirect(history, apiServerUrlHandlingOauthRedirect) exchangeCodeForJwtAndRedirect(history, apiServerUrlHandlingOauthRedirect)
return () => {
firstRender.current = false
}
}, [history, pathToApiServerRouteHandlingOauthRedirect]) }, [history, pathToApiServerRouteHandlingOauthRedirect])
return ( return (

View File

@ -739,7 +739,7 @@
"file", "file",
"web-app/src/auth/pages/OAuthCodeExchange.jsx" "web-app/src/auth/pages/OAuthCodeExchange.jsx"
], ],
"180e07f82c8290f9cae71e0aef97b40cf1b72a5a5fb58317feaf4cf66e629e42" "7dbcc288201aafbb50b5f5319a28283546c81d006fe61c2a8a3c5f55c6833fb2"
], ],
[ [
[ [

View File

@ -1,4 +1,4 @@
import React, { useEffect } from 'react' import React, { useEffect, useRef } from 'react'
import { useHistory } from 'react-router-dom' import { useHistory } from 'react-router-dom'
import config from '../../config.js' import config from '../../config.js'
@ -13,12 +13,25 @@ import { initSession } from '../helpers/user'
export default function OAuthCodeExchange({ pathToApiServerRouteHandlingOauthRedirect }) { export default function OAuthCodeExchange({ pathToApiServerRouteHandlingOauthRedirect }) {
const history = useHistory() 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(() => { useEffect(() => {
if (!firstRender.current) {
return
}
// NOTE: Different auth methods will have different Wasp API server validation paths. // 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.). // This helps us reuse one component for various methods (e.g., Google, Facebook, etc.).
const apiServerUrlHandlingOauthRedirect = constructOauthRedirectApiServerUrl(pathToApiServerRouteHandlingOauthRedirect) const apiServerUrlHandlingOauthRedirect = constructOauthRedirectApiServerUrl(pathToApiServerRouteHandlingOauthRedirect)
exchangeCodeForJwtAndRedirect(history, apiServerUrlHandlingOauthRedirect) exchangeCodeForJwtAndRedirect(history, apiServerUrlHandlingOauthRedirect)
return () => {
firstRender.current = false
}
}, [history, pathToApiServerRouteHandlingOauthRedirect]) }, [history, pathToApiServerRouteHandlingOauthRedirect])
return ( return (