get_param( 'username' ) ); $password = $request->get_param( 'password' ); if ( empty( $username ) || empty( $password ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Username and password are required', 'woonoow' ), ], 400 ); } // Authenticate user (same as wp-login.php) $user = wp_authenticate( $username, $password ); if ( is_wp_error( $user ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Invalid username or password', 'woonoow' ), ], 401 ); } // Check if user has WooCommerce permissions if ( ! user_can( $user, 'manage_woocommerce' ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'You do not have permission to access this area', 'woonoow' ), ], 403 ); } // CRITICAL: Clear old cookies first, then set new ones // This ensures no stale session data interferes with the new login wp_clear_auth_cookie(); wp_set_current_user( $user->ID ); wp_set_auth_cookie( $user->ID, true ); // Trigger login action (same as wp-login.php) do_action( 'wp_login', $user->user_login, $user ); // Debug logging if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log( '[AuthController::login] Login successful for user ID: ' . $user->ID ); error_log( '[AuthController::login] Current user ID: ' . get_current_user_id() ); error_log( '[AuthController::login] Cookies set: ' . ( headers_sent() ? 'Headers already sent!' : 'OK' ) ); } // Return user data and new nonce return new WP_REST_Response( [ 'success' => true, 'user' => [ 'id' => $user->ID, 'name' => $user->display_name, 'email' => $user->user_email, 'avatar' => get_avatar_url( $user->ID ), ], 'nonce' => wp_create_nonce( 'wp_rest' ), ], 200 ); } /** * Customer login endpoint (no admin permission required) * * @param WP_REST_Request $request Request object * @return WP_REST_Response Response object */ public static function customer_login( WP_REST_Request $request ): WP_REST_Response { $username = sanitize_text_field( $request->get_param( 'username' ) ); $password = $request->get_param( 'password' ); if ( empty( $username ) || empty( $password ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Username and password are required', 'woonoow' ), ], 400 ); } // Authenticate user $user = wp_authenticate( $username, $password ); if ( is_wp_error( $user ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Invalid username or password', 'woonoow' ), ], 401 ); } // Clear old cookies and set new ones wp_clear_auth_cookie(); wp_set_current_user( $user->ID ); wp_set_auth_cookie( $user->ID, true ); // Trigger login action do_action( 'wp_login', $user->user_login, $user ); // Get customer data $customer_data = [ 'id' => $user->ID, 'name' => $user->display_name, 'email' => $user->user_email, 'first_name' => get_user_meta( $user->ID, 'first_name', true ), 'last_name' => get_user_meta( $user->ID, 'last_name', true ), 'avatar' => get_avatar_url( $user->ID ), ]; return new WP_REST_Response( [ 'success' => true, 'user' => $customer_data, 'nonce' => wp_create_nonce( 'wp_rest' ), ], 200 ); } /** * Logout endpoint * * @return WP_REST_Response Response object */ public static function logout(): WP_REST_Response { wp_logout(); return new WP_REST_Response( [ 'success' => true, 'message' => __( 'Logged out successfully', 'woonoow' ), ], 200 ); } /** * Check auth status * * @return WP_REST_Response Response object */ public static function check(): WP_REST_Response { $is_logged_in = is_user_logged_in(); // Debug logging if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { error_log( '[AuthController::check] is_user_logged_in: ' . ( $is_logged_in ? 'true' : 'false' ) ); error_log( '[AuthController::check] Cookies: ' . print_r( $_COOKIE, true ) ); } if ( ! $is_logged_in ) { return new WP_REST_Response( [ 'authenticated' => false, 'debug' => 'Not logged in', ], 200 ); } $user = wp_get_current_user(); // Check WooCommerce permission if ( ! current_user_can( 'manage_woocommerce' ) ) { return new WP_REST_Response( [ 'authenticated' => false, 'message' => __( 'Insufficient permissions', 'woonoow' ), 'debug' => 'No manage_woocommerce permission', ], 200 ); } return new WP_REST_Response( [ 'authenticated' => true, 'user' => [ 'id' => $user->ID, 'name' => $user->display_name, 'email' => $user->user_email, 'avatar' => get_avatar_url( $user->ID ), ], ], 200 ); } /** * Forgot password endpoint - sends password reset email * * @param WP_REST_Request $request Request object * @return WP_REST_Response Response object */ public static function forgot_password( WP_REST_Request $request ): WP_REST_Response { $email = sanitize_email( $request->get_param( 'email' ) ); if ( empty( $email ) || ! is_email( $email ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Please enter a valid email address', 'woonoow' ), ], 400 ); } // Check if user exists $user = get_user_by( 'email', $email ); if ( ! $user ) { // For security, don't reveal if email exists or not // But still return success to prevent email enumeration attacks return new WP_REST_Response( [ 'success' => true, 'message' => __( 'If an account exists with this email, you will receive a password reset link.', 'woonoow' ), ], 200 ); } // Use WordPress's built-in password reset functionality $result = retrieve_password( $user->user_login ); if ( is_wp_error( $result ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Failed to send password reset email. Please try again.', 'woonoow' ), ], 500 ); } return new WP_REST_Response( [ 'success' => true, 'message' => __( 'Password reset email sent! Please check your inbox.', 'woonoow' ), ], 200 ); } /** * Validate password reset key * * @param WP_REST_Request $request Request object * @return WP_REST_Response Response object */ public static function validate_reset_key( WP_REST_Request $request ): WP_REST_Response { $key = sanitize_text_field( $request->get_param( 'key' ) ); $login = sanitize_text_field( $request->get_param( 'login' ) ); if ( empty( $key ) || empty( $login ) ) { return new WP_REST_Response( [ 'valid' => false, 'message' => __( 'Invalid password reset link', 'woonoow' ), ], 400 ); } // Check the reset key $user = check_password_reset_key( $key, $login ); if ( is_wp_error( $user ) ) { $error_code = $user->get_error_code(); $message = __( 'This password reset link has expired or is invalid.', 'woonoow' ); if ( $error_code === 'invalid_key' ) { $message = __( 'This password reset link is invalid.', 'woonoow' ); } elseif ( $error_code === 'expired_key' ) { $message = __( 'This password reset link has expired. Please request a new one.', 'woonoow' ); } return new WP_REST_Response( [ 'valid' => false, 'message' => $message, ], 400 ); } return new WP_REST_Response( [ 'valid' => true, 'user' => [ 'login' => $user->user_login, 'email' => $user->user_email, ], ], 200 ); } /** * Reset password with key * * @param WP_REST_Request $request Request object * @return WP_REST_Response Response object */ public static function reset_password( WP_REST_Request $request ): WP_REST_Response { $key = sanitize_text_field( $request->get_param( 'key' ) ); $login = sanitize_text_field( $request->get_param( 'login' ) ); $password = $request->get_param( 'password' ); if ( empty( $key ) || empty( $login ) || empty( $password ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Missing required fields', 'woonoow' ), ], 400 ); } // Validate password strength if ( strlen( $password ) < 8 ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'Password must be at least 8 characters long', 'woonoow' ), ], 400 ); } // Validate the reset key $user = check_password_reset_key( $key, $login ); if ( is_wp_error( $user ) ) { return new WP_REST_Response( [ 'success' => false, 'message' => __( 'This password reset link has expired or is invalid. Please request a new one.', 'woonoow' ), ], 400 ); } // Reset the password reset_password( $user, $password ); // Delete the password reset key so it can't be reused delete_user_meta( $user->ID, 'default_password_nag' ); // Trigger password changed action do_action( 'password_reset', $user, $password ); return new WP_REST_Response( [ 'success' => true, 'message' => __( 'Password reset successfully. You can now log in with your new password.', 'woonoow' ), ], 200 ); } }