feat: add forgot password UI flow
- ForgotPasswordPage: email input, sends reset request, shows success - ResetPasswordPage: reads token from ?token= query param, password + confirm inputs, validates min length, shows success with login link - LoginForm: added [FORGOT PASSWORD?] link below the form - App.tsx: /forgot-password and /reset-password routes (public, no auth) - auth store: requestPasswordReset + resetPassword actions - Backend routes already existed at POST /auth/request-password-reset and POST /auth/reset-password
This commit is contained in:
@@ -62,6 +62,8 @@ interface AuthState {
|
||||
currentPassword: string,
|
||||
newPassword: string,
|
||||
) => Promise<void>;
|
||||
requestPasswordReset: (email: string) => Promise<void>;
|
||||
resetPassword: (token: string, newPassword: string) => Promise<void>;
|
||||
getPublicProfile: (userId: string) => Promise<PublicProfile>;
|
||||
listBlocks: () => Promise<BlockedUser[]>;
|
||||
blockUser: (userId: string) => Promise<void>;
|
||||
@@ -178,6 +180,40 @@ export const useAuthStore = create<AuthState>((set) => ({
|
||||
}
|
||||
},
|
||||
|
||||
requestPasswordReset: async (email) => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
await api.post("/auth/request-password-reset", { email });
|
||||
set({ isLoading: false });
|
||||
} catch (error) {
|
||||
set({
|
||||
isLoading: false,
|
||||
error:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "Failed to request password reset",
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
resetPassword: async (token, newPassword) => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
await api.post("/auth/reset-password", { token, new_password: newPassword });
|
||||
set({ isLoading: false });
|
||||
} catch (error) {
|
||||
set({
|
||||
isLoading: false,
|
||||
error:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "Failed to reset password",
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
clearError: () => set({ error: null }),
|
||||
|
||||
getPublicProfile: async (userId) => api.get<PublicProfile>(`/users/${userId}/profile`),
|
||||
|
||||
Reference in New Issue
Block a user