feat: reset password in accounts page (#5219)

Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
Co-authored-by: Johannes <johannes@formbricks.com>
This commit is contained in:
Kunal Garg
2025-07-01 21:11:14 +05:30
committed by GitHub
parent 1be23eebbb
commit 979fd71a11
28 changed files with 249 additions and 72 deletions
+7 -1
View File
@@ -13,7 +13,13 @@ export const logSignOutAction = async (
userId: string,
userEmail: string,
context: {
reason?: "user_initiated" | "account_deletion" | "email_change" | "session_timeout" | "forced_logout";
reason?:
| "user_initiated"
| "account_deletion"
| "email_change"
| "session_timeout"
| "forced_logout"
| "password_reset";
redirectUrl?: string;
organizationId?: string;
}
@@ -1,9 +1,11 @@
"use server";
import { PASSWORD_RESET_DISABLED } from "@/lib/constants";
import { actionClient } from "@/lib/utils/action-client";
import { getUserByEmail } from "@/modules/auth/lib/user";
import { sendForgotPasswordEmail } from "@/modules/email";
import { z } from "zod";
import { OperationNotAllowedError } from "@formbricks/types/errors";
import { ZUserEmail } from "@formbricks/types/user";
const ZForgotPasswordAction = z.object({
@@ -13,9 +15,15 @@ const ZForgotPasswordAction = z.object({
export const forgotPasswordAction = actionClient
.schema(ZForgotPasswordAction)
.action(async ({ parsedInput }) => {
if (PASSWORD_RESET_DISABLED) {
throw new OperationNotAllowedError("Password reset is disabled");
}
const user = await getUserByEmail(parsedInput.email);
if (user) {
if (user && user.identityProvider === "email") {
await sendForgotPasswordEmail(user);
}
return { success: true };
});
+13 -1
View File
@@ -1,13 +1,21 @@
import { FORMBRICKS_ENVIRONMENT_ID_LS } from "@/lib/localStorage";
import { logSignOutAction } from "@/modules/auth/actions/sign-out";
import { signOut } from "next-auth/react";
import { logger } from "@formbricks/logger";
interface UseSignOutOptions {
reason?: "user_initiated" | "account_deletion" | "email_change" | "session_timeout" | "forced_logout";
reason?:
| "user_initiated"
| "account_deletion"
| "email_change"
| "session_timeout"
| "forced_logout"
| "password_reset";
redirectUrl?: string;
organizationId?: string;
redirect?: boolean;
callbackUrl?: string;
clearEnvironmentId?: boolean;
}
interface SessionUser {
@@ -36,6 +44,10 @@ export const useSignOut = (sessionUser?: SessionUser | null) => {
}
}
if (options?.clearEnvironmentId) {
localStorage.removeItem(FORMBRICKS_ENVIRONMENT_ID_LS);
}
// Call NextAuth signOut
return await signOut({
redirect: options?.redirect,
+1
View File
@@ -78,6 +78,7 @@ export const getUserByEmail = reactCache(async (email: string) => {
email: true,
emailVerified: true,
isActive: true,
identityProvider: true,
},
});
+7 -1
View File
@@ -283,7 +283,13 @@ export const logSignOut = (
userId: string,
userEmail: string,
context?: {
reason?: "user_initiated" | "account_deletion" | "email_change" | "session_timeout" | "forced_logout";
reason?:
| "user_initiated"
| "account_deletion"
| "email_change"
| "session_timeout"
| "forced_logout"
| "password_reset";
redirectUrl?: string;
organizationId?: string;
}