All files / src/hooks usePasswordChange.ts

100% Statements 62/62
92.3% Branches 12/13
100% Functions 1/1
100% Lines 62/62

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 631x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 29x 29x 29x 29x 29x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 9x 10x 5x 10x 4x 4x 4x 4x 4x 10x 1x 1x 10x 10x 10x 29x 29x 29x 29x 29x 29x 29x 29x 29x  
import { useState, useCallback } from "react";
import { clientLogger } from "@/lib/logging/clientLogger";
import { UsePasswordChangeReturn, UserMessage } from "@/types/user";
 
/**
 * usePasswordChange Hook
 *
 * Provides password change functionality with API integration.
 * Works with the PasswordForm component which manages its own form state.
 *
 * @example
 * ```tsx
 * const { savingPassword, passwordMessage, changePassword } = usePasswordChange();
 *
 * <PasswordForm
 *   savingPassword={savingPassword}
 *   onSubmit={changePassword}
 * />
 * ```
 */
export function usePasswordChange(): UsePasswordChangeReturn {
  const [savingPassword, setSavingPassword] = useState(false);
  const [passwordMessage, setPasswordMessage] = useState<UserMessage | null>(null);
 
  const changePassword = useCallback(async (currentPassword: string, newPassword: string) => {
    setSavingPassword(true);
    setPasswordMessage(null);
 
    try {
      const response = await fetch("/api/user/password", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          oldPassword: currentPassword,
          newPassword,
          confirmPassword: newPassword,
        }),
      });
 
      if (response.ok) {
        setPasswordMessage({ type: "success", text: "Password changed successfully!" });
      } else {
        const result = await response.json();
        // Handle both new wrapped format and legacy format
        const errorMessage = result.error?.message ?? result.error ?? "Failed to change password";
        setPasswordMessage({ type: "error", text: errorMessage });
      }
    } catch (error) {
      setPasswordMessage({ type: "error", text: "An error occurred while changing password" });
      clientLogger.error("Failed to change password", error instanceof Error ? error : new Error(String(error)));
    } finally {
      setSavingPassword(false);
    }
  }, []);
 
  return {
    savingPassword,
    passwordMessage,
    setPasswordMessage,
    changePassword,
  };
}