diff --git a/apps/web/public/locales/en/auth.json b/apps/web/public/locales/en/auth.json
index 18d879b1d..1da985cf3 100644
--- a/apps/web/public/locales/en/auth.json
+++ b/apps/web/public/locales/en/auth.json
@@ -76,6 +76,7 @@
"methodMagicLink": "email link",
"methodOauth": "social sign-in",
"methodOauthWithProvider": "{{provider}}",
+ "methodDefault": "another method",
"existingAccountHint": "You previously signed in with {{method}}. Already have an account?",
"errors": {
"Invalid login credentials": "The credentials entered are invalid",
diff --git a/packages/features/auth/src/components/existing-account-hint.tsx b/packages/features/auth/src/components/existing-account-hint.tsx
index 9e043b404..281b94636 100644
--- a/packages/features/auth/src/components/existing-account-hint.tsx
+++ b/packages/features/auth/src/components/existing-account-hint.tsx
@@ -4,6 +4,7 @@ import { useMemo } from 'react';
import dynamic from 'next/dynamic';
import Link from 'next/link';
+import { useSearchParams } from 'next/navigation';
import { UserCheck } from 'lucide-react';
@@ -33,6 +34,14 @@ export function ExistingAccountHintImpl({
const { hasLastMethod, methodType, providerName, isOAuth } =
useLastAuthMethod();
+ const params = useSearchParams();
+
+ const isInvite = params.get('invite_token');
+
+ if (isInvite) {
+ signInPath = signInPath + '?invite_token=' + isInvite;
+ }
+
// Get the appropriate method description for the hint
// This must be called before any conditional returns to follow Rules of Hooks
const methodDescription = useMemo(() => {
@@ -42,13 +51,13 @@ export function ExistingAccountHintImpl({
switch (methodType) {
case 'password':
- return 'email and password';
+ return 'auth:methodPassword';
case 'otp':
- return 'email verification';
+ return 'auth:methodOtp';
case 'magic_link':
- return 'email link';
+ return 'auth:methodMagicLink';
default:
- return 'another method';
+ return 'auth:methodDefault';
}
}, [methodType, isOAuth, providerName]);
diff --git a/packages/features/auth/src/components/otp-sign-in-container.tsx b/packages/features/auth/src/components/otp-sign-in-container.tsx
index 3f0883a9b..7890eb60f 100644
--- a/packages/features/auth/src/components/otp-sign-in-container.tsx
+++ b/packages/features/auth/src/components/otp-sign-in-container.tsx
@@ -34,17 +34,16 @@ import { AuthErrorAlert } from './auth-error-alert';
const EmailSchema = z.object({ email: z.string().email() });
const OtpSchema = z.object({ token: z.string().min(6).max(6) });
-export function OtpSignInContainer({
- onSignIn,
- shouldCreateUser,
-}: {
- onSignIn?: (userId?: string) => void;
+type OtpSignInContainerProps = {
shouldCreateUser: boolean;
-}) {
+ inviteToken?: string;
+};
+
+export function OtpSignInContainer(props: OtpSignInContainerProps) {
const verifyMutation = useVerifyOtp();
const router = useRouter();
- const params = useSearchParams();
const { recordAuthMethod } = useLastAuthMethod();
+ const params = useSearchParams();
const otpForm = useForm({
resolver: zodResolver(OtpSchema.merge(EmailSchema)),
@@ -61,6 +60,9 @@ export function OtpSignInContainer({
const isEmailStep = !email;
+ const shouldCreateUser =
+ 'shouldCreateUser' in props && props.shouldCreateUser;
+
const handleVerifyOtp = async ({
token,
email,
@@ -68,7 +70,7 @@ export function OtpSignInContainer({
token: string;
email: string;
}) => {
- const result = await verifyMutation.mutateAsync({
+ await verifyMutation.mutateAsync({
type: 'email',
email,
token,
@@ -77,14 +79,18 @@ export function OtpSignInContainer({
// Record successful OTP sign-in
recordAuthMethod('otp', { email });
- if (onSignIn) {
- return onSignIn(result?.user?.id);
- }
+ // on sign ups we redirect to the app home
+ const inviteToken = props.inviteToken;
+ const next = params.get('next') ?? '/home';
- // on sign ups we redirect to the app home
- if (shouldCreateUser) {
- const next = params.get('next') ?? '/home';
+ if (inviteToken) {
+ const params = new URLSearchParams({
+ invite_token: inviteToken,
+ next,
+ });
+ router.replace(`/join?${params.toString()}`);
+ } else {
router.replace(next);
}
};
diff --git a/packages/features/auth/src/components/sign-in-methods-container.tsx b/packages/features/auth/src/components/sign-in-methods-container.tsx
index 51772e318..475952218 100644
--- a/packages/features/auth/src/components/sign-in-methods-container.tsx
+++ b/packages/features/auth/src/components/sign-in-methods-container.tsx
@@ -74,7 +74,10 @@ export function SignInMethodsContainer(props: {
-
+
diff --git a/packages/features/auth/src/components/sign-up-methods-container.tsx b/packages/features/auth/src/components/sign-up-methods-container.tsx
index a11d552a0..38b949240 100644
--- a/packages/features/auth/src/components/sign-up-methods-container.tsx
+++ b/packages/features/auth/src/components/sign-up-methods-container.tsx
@@ -51,7 +51,10 @@ export function SignUpMethodsContainer(props: {
-
+
diff --git a/packages/features/auth/src/hooks/use-sign-up-flow.ts b/packages/features/auth/src/hooks/use-sign-up-flow.ts
index 88f182bbd..cda3427c9 100644
--- a/packages/features/auth/src/hooks/use-sign-up-flow.ts
+++ b/packages/features/auth/src/hooks/use-sign-up-flow.ts
@@ -87,6 +87,7 @@ export function usePasswordSignUpFlow({
router,
onSignUp,
resetCaptchaToken,
+ recordAuthMethod,
],
);