stack icon indicating copy to clipboard operation
stack copied to clipboard

I cant find the after_auth_return_to option when trying to create custom component with stack auth

Open firstaxel opened this issue 9 months ago • 5 comments

i am having issue when trying to redirect the user on my app, i tried setting up the after_auth_return_to but i cant find and looked in the document but it was only mentioned not used. @fomalhautb can you look at it

firstaxel avatar Mar 22 '25 04:03 firstaxel

example.ts

stackClientApp.signInWithOAuth(provider) Initiates the OAuth sign-in process with the specified provider. This method:

Redirects the user to the OAuth provider’s sign-in page. After successful authentication, redirects the user back to your application. The final redirect destination is determined as follows: If an after_auth_return_to query parameter was provided when calling this function, it uses that URL. Otherwise, it uses the afterSignIn URL configured in the app settings.

firstaxel avatar Mar 22 '25 04:03 firstaxel

@fomalhautb @davidgomes evening i tried redirecting the user to the required url by passing the after_auth_return_to through the middleware but what i noticed is that instead of redirecting the user to the url after signin it just adds the url to the handler and since nextjs cant find it, it shows 404 error to me,

https://github.com/user-attachments/assets/20dde40f-0bdd-425f-9daf-1eb3b82009f4

firstaxel avatar Mar 23 '25 19:03 firstaxel

@N2D4 @fomalhautb it will be okay if we are allowed to set the redirecturl in nextjs and a proper auth middleware like clerk does

firstaxel avatar Mar 23 '25 20:03 firstaxel

can i get a guide to fully implement this cause it working on stack auth dashboard

firstaxel avatar Mar 24 '25 11:03 firstaxel

I opted to redirect the user on my end instead. Using the REST API, I can determine when to redirect based on the response.

For instance:

useEffect(() => {
    if (code.length === 6 && nonce && !isCheckingCode) {
      setIsCheckingCode(true);
      setError('');

      // First verify the code
      fetch("https://api.stack-auth.com/api/v1/auth/otp/sign-in/check-code", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-Stack-Access-Type": "client",
          "X-Stack-Project-Id": process.env.NEXT_PUBLIC_STACK_PROJECT_ID!,
          "X-Stack-Publishable-Client-Key": process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY!,
        },
        body: JSON.stringify({
          "code": `${code}${nonce}`
        }),
      })
      .then(response => response.json())
      .then(data => {
        if (!data.error) {
          // If code is valid, sign in with magic link
          console.log('signing in with magic link', code + nonce);
          return app.signInWithMagicLink(code + nonce);
        }
        throw new Error(data.message || data.error || 'Invalid verification code');
      })
      .then(async (result) => {
        if (result.status === 'error') {
          throw new Error(result.error.message);
        }
        
        try {
          // Only perform client-side user creation in development mode
          const isDevelopment = process.env.NEXT_PUBLIC_APP_ENV === 'development';
          console.log('Environment mode:', isDevelopment ? 'DEVELOPMENT' : 'PRODUCTION');
          
          if (isDevelopment) {
            console.log('[DEV MODE] Getting user info for database creation');
            // Wait a moment for auth state to be fully updated
            await new Promise(resolve => setTimeout(resolve, 500));
            
            const userInfo = await app.getUser();
            console.log('[DEV MODE] User info retrieved:', userInfo ? 'SUCCESS' : 'FAILED', userInfo);
            
            if (userInfo) {
              console.log('[DEV MODE] Creating user in database via client-side for:', userInfo.id);
              // Call our API to ensure user exists in our database
              const response = await fetch('/api/auth/sync-user', {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                  id: userInfo.id,
                  email: userInfo.primaryEmail,
                  name: userInfo.displayName,
                  emailVerified: userInfo.primaryEmailVerified,
                  imageUrl: userInfo.profileImageUrl
                })
              });
              
              if (!response.ok) {
                throw new Error(`API error: ${response.status}`);
              }
              
              const syncResult = await response.json();
              console.log('[DEV MODE] User sync API response:', syncResult);
            } else {
              console.error('[DEV MODE] Failed to get user info after sign-in');
            }
          } else {
            console.log('[PRODUCTION MODE] Using webhooks for user creation');
          }
          
          // Redirect to dashboard after successful login
          console.log('Sign-in successful, redirecting to dashboard');
          window.location.href = '/dashboard';
        } catch (error) {
          console.error('Error during post-authentication process:', error);
          // Still redirect to dashboard - don't block the user's experience
          window.location.href = '/dashboard';
        }
      })
      .catch(err => {
        setError(err.message || 'Failed to verify code. Please try again.');
      })
      .finally(() => {
        setIsCheckingCode(false);
        setCode('');
      });
    }
  }, [code, nonce, isCheckingCode, app]);

madster456 avatar Mar 30 '25 17:03 madster456