flixoflax
08/23/2022, 10:19 AMrp_st
08/23/2022, 10:43 AMflixoflax
08/23/2022, 10:43 AMflixoflax
08/23/2022, 10:45 AMflixoflax
08/23/2022, 10:46 AMimport { useRouter } from 'next/router'
import { ReactElement, useEffect, useState } from 'react'
import { useSessionContext } from 'supertokens-auth-react/recipe/session'
import { isEmailVerified as tpIsEmailVerified } from 'supertokens-auth-react/recipe/thirdpartyemailpassword'
const AuthWrapper = ({ children }: { children: ReactElement }) => {
  const sessionContext = useSessionContext()
  const router = useRouter()
  const [verified, setVerified] = useState<boolean>(false)
  useEffect(() => {
    console.log('running useEffect')
    const redirectToPath = new URL(window.location.href).searchParams.get(
      'redirectToPath'
    )
    async function isEmailVerified() {
      const { isVerified } = await tpIsEmailVerified()
      setVerified(isVerified)
    }
    isEmailVerified()
    if (sessionContext.loading === false) {
      if (sessionContext.doesSessionExist) {
        const atp = sessionContext.accessTokenPayload
        const { isUsernameSet } = atp
        if (isUsernameSet === false) {
          router.replace({
            pathname: '/auth/set-username',
            query: { redirectToPath },
          })
        }
        if (verified === false) {
          router.replace({
            pathname: '/auth/verify-email',
            query: { redirectToPath },
          })
        }
        if (
          router.asPath.includes('/auth') &&
          verified === true &&
          isUsernameSet === true
        ) {
          router.replace(redirectToPath || '/')
        }
      } else {
        router.replace({
          pathname: '/auth/signin',
          query: { redirectToPath },
        })
      }
    }
  }, [router, sessionContext, verified])
  if (sessionContext.loading === true) {
    return null
  }
  return children
}
export default AuthWrapperrp_st
08/23/2022, 10:47 AMflixoflax
08/23/2022, 10:47 AMporcellus
08/23/2022, 10:50 AMflixoflax
08/23/2022, 10:50 AMporcellus
08/23/2022, 10:52 AMisEmailVerified (or setVerified)?flixoflax
08/23/2022, 10:54 AMflixoflax
08/23/2022, 10:55 AMporcellus
08/23/2022, 10:58 AMloading?flixoflax
08/23/2022, 10:59 AMflixoflax
08/23/2022, 10:59 AMporcellus
08/23/2022, 11:01 AMisEmailVerified before the session is loaded. Also, the loading state is mostly for SSR support and anything you wrap with <SessionAuth requireAuth={true> should not be affected by it at all.porcellus
08/23/2022, 11:02 AMloading in your components?flixoflax
08/23/2022, 11:03 AMflixoflax
08/23/2022, 11:03 AMisEmailVerified below the if(sessionContext.doesSessionExist) and it's still an infinite loopporcellus
08/23/2022, 11:04 AMflixoflax
08/23/2022, 11:04 AMflixoflax
08/23/2022, 11:05 AMuseEffect hook run infiniteflixoflax
08/23/2022, 11:05 AMporcellus
08/23/2022, 11:06 AMporcellus
08/23/2022, 11:06 AMflixoflax
08/23/2022, 11:07 AMflixoflax
08/23/2022, 11:07 AMflixoflax
08/23/2022, 11:07 AMporcellus
08/23/2022, 11:07 AMporcellus
08/23/2022, 11:09 AM/auth route, and a session doesn't exists, then this useEffect will keep calling router.replaceporcellus
08/23/2022, 11:10 AMflixoflax
08/23/2022, 11:11 AMflixoflax
08/23/2022, 11:11 AMflixoflax
08/23/2022, 11:11 AMporcellus
08/23/2022, 11:12 AMflixoflax
08/23/2022, 11:16 AMflixoflax
08/23/2022, 11:16 AMflixoflax
08/23/2022, 11:16 AMflixoflax
08/23/2022, 11:23 AMflixoflax
08/23/2022, 11:25 AMconst AuthWrapper = ({ children }: { children: ReactElement }) => {
  const sessionContext = useSessionContext()
  const router = useRouter()
  useEffect(() => {
    console.log('running useEffect')
    const redirectToPath = new URL(window.location.href).searchParams.get(
      'redirectToPath'
    )
    if (sessionContext.loading === false) {
      if (sessionContext.doesSessionExist) {
        const atp = sessionContext.accessTokenPayload
        const { isUsernameSet, isEmailVerified } = atp
        if (isUsernameSet === false) {
          console.log('Username is not set')
          if (!router.asPath.includes('/auth/set-username')) {
            router.replace({
              pathname: '/auth/set-username',
              query: { redirectToPath },
            })
          }
        }
        if (isEmailVerified === false) {
          if (!router.asPath.includes('/auth/verify-email')) {
            router.replace({
              pathname: '/auth/verify-email',
              query: { redirectToPath },
            })
          }
        }
        if (
          router.asPath.includes('/auth') &&
          isEmailVerified === true &&
          isUsernameSet === true
        ) {
          router.replace(redirectToPath || '/')
        }
      } else if (!router.asPath.includes('/auth')) {
        router.replace({
          pathname: '/auth/signin',
          query: { redirectToPath },
        })
      }
    }
  }, [router, sessionContext]
  if (sessionContext.loading === true) {
    return null
  }
  return children
}
export default AuthWrapper The email part only works because I save the thing in the accesstokenpayload on session creation ....porcellus
08/23/2022, 11:26 AMisEmailVerified from the access token?flixoflax
08/23/2022, 11:26 AMflixoflax
08/23/2022, 11:26 AMporcellus
08/23/2022, 11:27 AMset-username and then redirect to auth/verify-emailporcellus
08/23/2022, 11:27 AMflixoflax
08/23/2022, 11:33 AMflixoflax
08/23/2022, 11:37 AMflixoflax
08/23/2022, 11:37 AMflixoflax
08/23/2022, 11:37 AMflixoflax
08/23/2022, 11:38 AMflixoflax
08/23/2022, 11:38 AMflixoflax
08/23/2022, 11:38 AMporcellus
08/23/2022, 11:39 AMcreateNewSession?flixoflax
08/23/2022, 11:40 AMflixoflax
08/23/2022, 11:41 AMflixoflax
08/23/2022, 11:41 AMOverride: &tpepmodels.OverrideStruct{
                    EmailVerificationFeature: &evmodels.OverrideStruct{
                        APIs: func(originalImplementation evmodels.APIInterface) evmodels.APIInterface {
                            originalVerifyEmailPOST := *originalImplementation.VerifyEmailPOST
                            (*originalImplementation.VerifyEmailPOST) = func(token string, options evmodels.APIOptions, userContext supertokens.UserContext) (evmodels.VerifyEmailPOSTResponse, error) {
                                resp, err := originalVerifyEmailPOST(token, options, userContext)
                                if err != nil {
                                    return evmodels.VerifyEmailPOSTResponse{}, err
                                }
                                if resp.OK != nil {
                                    // TODO: Update ATP
                                }
                                return resp, nil
                            }
                            return originalImplementation
                        },
                    },
                },flixoflax
08/23/2022, 11:42 AMflixoflax
08/23/2022, 11:42 AMflixoflax
08/23/2022, 11:42 AMporcellus
08/23/2022, 11:44 AMporcellus
08/23/2022, 11:45 AMporcellus
08/23/2022, 11:45 AMporcellus
08/23/2022, 11:46 AMflixoflax
08/23/2022, 11:47 AMflixoflax
08/23/2022, 11:48 AMflixoflax
08/23/2022, 11:49 AMverified has to be in the dependency array of useEffectporcellus
08/23/2022, 11:55 AM[sessionContext.loading, sessionContext.doesSessionExist] for that)
2. redirect in the other oneporcellus
08/23/2022, 11:57 AMflixoflax
08/23/2022, 11:57 AMporcellus
08/23/2022, 12:00 PMrouter.replace taking effect after you render children. there are multiple solutions, the simplest (IMHO) is using an extra state variable (showChildren) that you can set to true after you run your checks for redirection.flixoflax
08/23/2022, 12:02 PMflixoflax
08/23/2022, 12:02 PMflixoflax
08/23/2022, 12:35 PMflixoflax
08/23/2022, 12:36 PMflixoflax
08/23/2022, 12:36 PMrp_st
08/23/2022, 12:36 PMflixoflax
08/23/2022, 12:40 PMflixoflax
08/23/2022, 12:40 PMrp_st
08/23/2022, 12:41 PMrp_st
08/23/2022, 12:41 PMrp_st
08/23/2022, 12:41 PMflixoflax
08/23/2022, 12:45 PMOverride: &tpepmodels.OverrideStruct{
                    EmailVerificationFeature: &evmodels.OverrideStruct{
                        APIs: func(originalImplementation evmodels.APIInterface) evmodels.APIInterface {
                            originalVerifyEmailPOST := *originalImplementation.VerifyEmailPOST
                            (*originalImplementation.VerifyEmailPOST) = func(token string, options evmodels.APIOptions, userContext supertokens.UserContext) (evmodels.VerifyEmailPOSTResponse, error) {
                                resp, err := originalVerifyEmailPOST(token, options, userContext)
                                if err != nil {
                                    return evmodels.VerifyEmailPOSTResponse{}, err
                                }
                                if resp.OK != nil {
                                    // TODO: Update ATP
                                }
                                return resp, nil
                            }
                            return originalImplementation
                        },
                    },
                }, This is what I have. The response has no attribute session.... so how would I do this?porcellus
08/23/2022, 12:47 PMrp_st
08/23/2022, 12:47 PMflixoflax
08/23/2022, 12:49 PMflixoflax
08/23/2022, 12:49 PMrp_st
08/23/2022, 12:50 PM