Hi, <@498057949541826571> we have problem where GE...
# support-questions-legacy
b
Hi, @rp_st we have problem where GET /auth/user/email/verify is being called infinitely from some users. Can we get a sense why this might be happening?
r
Hey.
Are you using our pre built ui?
b
yeah.
react ui.
we don't make api calls by ourselves.
r
Right. And on which screen does this happen?
b
we have no idea. according to logs we are collecting, user is already inside and using website normally. my feeling is that it is happening some other inactive tabs or something.
r
So this api is called each time SessionAuth component mounts and if the user’s email is not verified.
So if your react setup is causing SessionAuth to remount a lot, this api will be called each time if the user’s email is yet unverified. Might wanna check that
b
user's email is verified already. still it can make api calls infinitely?
r
Then it shouldn’t.
I mean it makes it just once every 5 mins then (since the last time it was checked)
Can you reproduce this issue?
b
it is called like crazy. every 50ms or something.
It is difficult to reproduce. User just left page and it is not calling anymore.
r
Can you reproduce it though?
Hmm
b
i couldn't reproduce on my own.
so it is not about inactive tab.
r
This could also happen if there is some sort of time misconf on the user’s machine
Like if the user’s system time is way off than the real time
b
can u elaborate more about that case please?
r
If the user’s system time is let’s say, 5 mins ahead of the real time, then the frontend will think that it’s time to check for email verify status
Then it calls the api
The api correctly updated the time in the access token payload to current time
But then, the frontend (since it’s 5 mins ahead), still thinks that it’s been 5 mins since the last update, so calls it again
b
so if user set local time to 5 mins ahead of server's time, it will happen definitely?
r
I’m guessing, but yea I think it should
5 mins, or whatever the default time we have is
Default recheck time*
Yes. 5 mins is the default time
b
i think u r right. user's time is about 7 mins ahead of server's time.
r
Right. So that’s about it
b
what can be fix in this case?
r
There is not much to do here at the moment.
Other than tell the user to fix their system time
We do intend to tackle this issue by keeping track of server time on the frontend and normalising based on that
b
i mean it is not seriously harmful atm but it makes it impossible to analyze logs and/or irritate other api calss.
r
But it’s not something we will do anything in the next few months
You could extend the default time from 5 mins to 15 mins maybe
And this would reduce the chances of this issue happening
To do that, you can override the getGlobalClaimValidators recipe function on the frontend in session.init
And then replace the email validator we add with add the same validator with a different max time
b
can i ask why this is checked periodically?
r
In case the user’s email is unverified offline, then the frontend will eventually get the right value
But you can switch it off
By extending the time to 10 years or whatever
By overriding the function I mentioned above
b
and this is called periodically even when user's email is already verified?
r
Yes
b
i see.
thanks. got to understand better.
r
But you can change this behaviour
b
yeah, i will try to override the function u mentioned above.
You can see the isVerified claim validator
And the default time values
b
i personally think this can have serious consequence. not sure if this can act as DDoS or sth.
r
You can do this on the frontend session.init:
Copy code
tsx
Session.init({
    override: {
        functions: (oI) => {
            return {
                ...oI,
                getGlobalClaimValidators: function (input) {
                    // we first remove the default email verification validator
                    input.claimValidatorsAddedByOtherRecipes = input.claimValidatorsAddedByOtherRecipes.filter((validator) => {
                        return validator.id !== EmailVerification.EmailVerificationClaim.key;
                    })

                    // then we add the validator again with the new time values
                    // with checking for every 15 mins.
                    input.claimValidatorsAddedByOtherRecipes.push(EmailVerification.EmailVerificationClaim.validators.isVerified(undefined, 15 * 60));
                    return [...input.claimValidatorsAddedByOtherRecipes];
                }
            }
        }
    }
})
b
hi, @rp_st what if we want to change logic of EmailVerificationClaim?
@rp_st is there any way to override EmailVerificationClaim?
r
You could remove the validator entirely and make your own if you want
b
i couldn't create it because of these construct params. especially getRecipeImpl.
Copy code
export class EmailVerificationClaimClass extends BooleanClaim {
    constructor(
        getRecipeImpl: () => RecipeInterface,
        updateContextOnIsVerifiedFalse?: (userContext: any) => void | Promise<void>
    ) {
        super({
            id: "st-ev",
            refresh: async (userContext) => {
                await getRecipeImpl().isEmailVerified({
                    userContext,
                });
            },
        });
r
you want to create a custom validator right?
b
yeah
r
on the frontend or backend?
b
on the frontend.
r
and what would it do that's custom?
b
i am gonna calculate timediff between client and server and use it to avoid this situation.
how can i get EmailVerification instance outside? similar to
EmailVerification.getInstanceOrThrow()
?
r
right. So i this case, you can create your own logic like this:
Copy code
tsx
let myCustomValidator = (refetchTimeOnFalseInSeconds?: number | undefined, maxAgeInSeconds?: number | undefined) => {
    let isVerifiedValidator = EmailVerification.EmailVerificationClaim.validators.isVerified(refetchTimeOnFalseInSeconds, maxAgeInSeconds);

    return {
        ...isVerifiedValidator,
        shouldRefresh: (accessTokenPayload, userContext) => {
            // TODO: custom logic here.
            // See our default implementation of this function here: 
            // https://github.com/supertokens/supertokens-web-js/blob/master/lib/ts/recipe/emailverification/emailVerificationClaim.ts#L26
            return false;
        },
    }
}
And then, iun the previous code snippet i sent (overriding getGlobalClaimValidators), you can add
myCustomValidator
to the array
and you want to return
true
from
shouldRefresh
only if you want the API to the called.
b
is there any way to have access to recipe object outside of library?
r
you can use the EmailVerfiication receipe functions directly. It's the same thing
b
great, thanks.