Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

LielvdH's avatar

User Password Reset errors not working properly

Hey!

I have a User Reset Password page that lets an authenticated user reset their password by entering the following inputs: *current password, new password, and confirm new password

When entering the inputs accordingly, the password changes and everything is good. But whenever I enter something wrong, I still get the success message and no error messages. Fortunately, the password remains the same and nothing is changed in the back-end.

Here is my VueJS component:

<template>
    <div class="row">
        <h1>Account Authentication</h1>
        <a href="/dashboard/account">Account Profile</a>
        <a href="account/authentication">Account Authentication</a>
        <form class="form col-md-4 col-md-offset-4" role="form" @submit.prevent="onSubmit">
            <div class="form-group">
                <label for="password">{{ $t('form.old_password') }}</label>
                <input type="password" class="form-control" id="old_password" :placeholder="$t('form.old_password')" name="old_password" v-model="new_password.old_password">
            </div>
            <div class="form-group">
                <label for="password">{{ $t('form.new_password') }}</label>
                <input type="password" class="form-control" id="password" :placeholder="$t('form.new_password')" name="password" v-model="new_password.password">
            </div>
            <div class="form-group">
                <label for="new_password_confirmation">{{ $t('form.new_confirm_password') }}</label>
                <input type="password" class="form-control" id="new_password_confirmation" :placeholder="$t('form.new_confirm_password')" name="password_confirmation" v-model="new_password.password_confirmation">
            </div>
            <div class="form-group">
                <button type="submit" class="btn btn-primary">{{ $t('form.update') }}</button>
            </div>
        </form>
    </div>
</template>

<script>
import { stack_error } from 'config/helper'

export default {
    data() {
        return {
            errors: [],
            new_password: {
                old_password: '',
                password: '',
                password_confirmation: ''
            }
        }
    },
    methods: {
        onSubmit() {
            let url = 'password/change'
            let method = 'post'

            this.$http[method](url, this.new_password)
                .then((response) => {
                    this.new_password = {
                        old_password: '',
                        password: '',
                        password_confirmation: ''
                    };
                    swal({
                        title: 'Password Reset Successful!',
                        type: 'success',
                    });
                }).catch((response) => {
                    stack_error(response);
                });
        }
    },
}
</script>

Here is my UserController changePassword method:

public function changePassword(Request $request)
    {
        // Check if Current Password input field matches password in db 
        if (! Hash::check($request->get('old_password'), Auth::user()->password)) {
            return redirect()->back()->withErrors(['old_password' => 'The password must match the current password.']);
        }

        Validator::make($request->all(), [
            'old_password' => 'required|max:255',
            'password' => 'required|min:6|confirmed',
        ])->validate();

        // Call to UserRepository changPassword method
        $this->user->changePassword(Auth::user(), $request->get('password'));

        return redirect()->to('/dashboard/account');
    }

The call to stack_error sends response to a swal error template. But for some reason, the invalid response that should include errors still passes through then. If anyone could help me figure out why the invalid response still passes through then and why non of the errors don't show up it'll be greatly appreciated!

Please let me know if any more info is needed.

0 likes
4 replies
Helmchen's avatar

what is the response status and response from server? you can see them in the developer console in the XHR or Networking tab

failed validation should be an HTTP 422 including the errors as json

 if (! Hash::check($request->get('old_password'), Auth::user()->password)) {
            return redirect()->back()->withErrors(['old_password' => 'The password must match the current password.']);
        }

Redirects are 302 and probably another 200 at the target page - which in fact is a valid response for the "then"

you should return json if the request is an ajax request

if($request->ajax())
{
     return response()->json(['error' => 'something went wrong'], 422);
}
LielvdH's avatar

@Helmchen That's the thing... For invalid request, response status for POST request is 302 and response shows "Failed to load response data" and another GET request status is 200... It's like no matter what, the POST request always returns with a valid response

Helmchen's avatar

Yeah, cause your ajax request is following the redirect and returning the 200 response, which is not what you want.

try this instead:

if (! Hash::check($request->get('old_password'), Auth::user()->password))
{
    if($request->ajax())
    {
        return response()->json(['old_password' => 'The password must match the current password.'], 422);
    }

    return redirect()->back()->withErrors(['old_password' => 'The password must match the current password.']);
}

The builtin validation via Validator::validate() already does the same thing, so you dont have to change anything else.

hope that helps :)

biishmar's avatar

@lielvdh

public function changePassword(Request $request)
{
    if (! Hash::check($request->get('old_password'), Auth::user()->password)) {
        return [
            "success" => false,
            "reason" => 'Current password is wrong.'
        ];
    }
    
    $validator = Validator::make($request->all(), [
        'password' => 'required|min:6|confirmed',
    ]);
    
    if ( $validator->fails() ) {
        return [
            "success" => false,
            "reason" => 'Validation Error.',
            "data" => $validator->errors()
        ];
    }
    
    // Call to UserRepository changPassword method
    $updated = $this->user->changePassword(Auth::user(), $request->get('password')); //return true or false. use try catch for catching exception
    
    if ( ! $updated ) {
        return [
            "success" => false,
            "reason" => 'Updation Failed.',
        ];
    }
    
    return [
        "success" => true,
        "redirect" => route('usenameinroutefile'),
    ];
}

Your main problem is using laravel direct form submit approach in your ajax call.

Please or to participate in this conversation.