diff --git a/packages/stack/src/components-page/auth-page.tsx b/packages/stack/src/components-page/auth-page.tsx
index 8f075aced..45ee9b605 100644
--- a/packages/stack/src/components-page/auth-page.tsx
+++ b/packages/stack/src/components-page/auth-page.tsx
@@ -16,10 +16,12 @@ import { useEffect } from 'react';
export function AuthPage({
fullPage=false,
type,
+ automaticRedirect,
mockProject,
}: {
fullPage?: boolean,
type: 'sign-in' | 'sign-up',
+ automaticRedirect?: boolean,
mockProject?: {
config: {
credentialEnabled: boolean,
@@ -36,10 +38,12 @@ export function AuthPage({
const project = mockProject || projectFromHook;
useEffect(() => {
- if (user && !mockProject) {
- runAsynchronously(type === 'sign-in' ? stackApp.redirectToAfterSignIn() : stackApp.redirectToAfterSignUp());
+ if (automaticRedirect) {
+ if (user && !mockProject) {
+ runAsynchronously(type === 'sign-in' ? stackApp.redirectToAfterSignIn() : stackApp.redirectToAfterSignUp());
+ }
}
- }, [user, mockProject, stackApp]);
+ }, [user, mockProject, stackApp, automaticRedirect]);
if (user && !mockProject) {
return ;
diff --git a/packages/stack/src/components-page/oauth-callback.tsx b/packages/stack/src/components-page/oauth-callback.tsx
index 183d66ee8..e9a0115cd 100644
--- a/packages/stack/src/components-page/oauth-callback.tsx
+++ b/packages/stack/src/components-page/oauth-callback.tsx
@@ -5,6 +5,7 @@ import { useStackApp } from "..";
import { runAsynchronously } from "@stackframe/stack-shared/dist/utils/promises";
import { MessageCard } from "../components/message-cards/message-card";
import { StyledLink } from "@stackframe/stack-ui";
+import { captureError } from "@stackframe/stack-shared/dist/utils/errors";
export function OAuthCallback(props: { fullPage?: boolean }) {
const app = useStackApp();
@@ -19,10 +20,11 @@ export function OAuthCallback(props: { fullPage?: boolean }) {
try {
hasRedirected = await app.callOAuthCallback();
} catch (e: any) {
+ captureError("", e);
setError(e);
}
if (!hasRedirected && (!error || process.env.NODE_ENV === 'production')) {
- await app.redirectToSignIn();
+ await app.redirectToSignIn({ noRedirectBack: true });
}
}), []);
diff --git a/packages/stack/src/components-page/stack-handler.tsx b/packages/stack/src/components-page/stack-handler.tsx
index cd562441a..d57c67509 100644
--- a/packages/stack/src/components-page/stack-handler.tsx
+++ b/packages/stack/src/components-page/stack-handler.tsx
@@ -2,7 +2,7 @@ import { SignUp } from "./sign-up";
import { SignIn } from "./sign-in";
import { RedirectType, notFound, redirect } from 'next/navigation';
import { EmailVerification } from "./email-verification";
-import { StackServerApp } from "..";
+import { AuthPage, StackServerApp } from "..";
import { MessageCard } from "../components/message-cards/message-card";
import { HandlerUrls } from "../lib/stack-app";
import { SignOut } from "./sign-out";
@@ -67,11 +67,11 @@ export default async function StackHandler({
switch (path) {
case availablePaths.signIn: {
redirectIfNotHandler('signIn');
- return ;
+ return ;
}
case availablePaths.signUp: {
redirectIfNotHandler('signUp');
- return ;
+ return ;
}
case availablePaths.emailVerification: {
redirectIfNotHandler('emailVerification');
diff --git a/packages/stack/src/components/message-cards/predefined-message-card.tsx b/packages/stack/src/components/message-cards/predefined-message-card.tsx
index f2c37b692..8c21c01b1 100644
--- a/packages/stack/src/components/message-cards/predefined-message-card.tsx
+++ b/packages/stack/src/components/message-cards/predefined-message-card.tsx
@@ -45,14 +45,14 @@ export function PredefinedMessageCard({
case 'passwordReset': {
title = "Password reset successfully!";
message = 'Your password has been reset. You can now sign in with your new password.';
- primaryAction = () => stackApp.redirectToSignIn();
+ primaryAction = () => stackApp.redirectToSignIn({ noRedirectBack: true });
primaryButton = "Sign in";
break;
}
case 'emailVerified': {
title = "Email verified!";
message = 'Your have successfully verified your email.';
- primaryAction = () => stackApp.redirectToSignIn();
+ primaryAction = () => stackApp.redirectToSignIn({ noRedirectBack: true });
primaryButton = "Sign in";
break;
}
diff --git a/packages/stack/src/lib/auth.ts b/packages/stack/src/lib/auth.ts
index 81818d516..9b9ad9410 100644
--- a/packages/stack/src/lib/auth.ts
+++ b/packages/stack/src/lib/auth.ts
@@ -1,6 +1,6 @@
import { StackClientInterface } from "@stackframe/stack-shared";
import { InternalSession } from "@stackframe/stack-shared/dist/sessions";
-import { StackAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
+import { StackAssertionError, captureError } from "@stackframe/stack-shared/dist/utils/errors";
import { neverResolve } from "@stackframe/stack-shared/dist/utils/promises";
import { constructRedirectUrl } from "../utils/url";
import { getVerifierAndState, saveVerifierAndState } from "./cookie";
@@ -64,6 +64,7 @@ function consumeOAuthCallbackQueryParams(expectedState: string): null | URL {
const originalUrl = new URL(window.location.href);
for (const param of requiredParams) {
if (!originalUrl.searchParams.has(param)) {
+ captureError("consumeOAuthCallbackQueryParams", new Error(`Missing required query parameter on OAuth callback: ${param}`));
return null;
}
}
@@ -71,6 +72,7 @@ function consumeOAuthCallbackQueryParams(expectedState: string): null | URL {
if (expectedState !== originalUrl.searchParams.get("state")) {
// If the state doesn't match, then the callback wasn't meant for us.
// Maybe the website uses another OAuth library?
+ captureError("consumeOAuthCallbackQueryParams", new Error(`Invalid OAuth callback state: Was this meant for someone else, or did cookies fail?`));
return null;
}
diff --git a/packages/stack/src/lib/stack-app.ts b/packages/stack/src/lib/stack-app.ts
index 50c8282cc..492f27706 100644
--- a/packages/stack/src/lib/stack-app.ts
+++ b/packages/stack/src/lib/stack-app.ts
@@ -881,29 +881,31 @@ class _StackClientAppImpl =