Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] My account on save redirect to a 500 page #5753

Open
Mte90 opened this issue Jan 22, 2025 · 13 comments
Open

[Bug] My account on save redirect to a 500 page #5753

Mte90 opened this issue Jan 22, 2025 · 13 comments
Assignees
Labels

Comments

@Mte90
Copy link

Mte90 commented Jan 22, 2025

Bug report

Looking at postChangePasswordForm it is a return redirect()->back(); but the url of the form is edit-account-info not change-password.

Also I am trying to understand why the password is saved but doesn't work on login, the one saved with the PermissionManager works for all the users but I am looking at that.

Is it a bug in the latest version of Backpack?

Yes, just checked

Backpack, Laravel, PHP, DB version

When I run php artisan backpack:version the output is:

PHP VERSION:

8.2.26

PHP EXTENSIONS:

Core, date, libxml, openssl, pcre, zlib, filter, hash, json, pcntl, random, Reflection, SPL, session, standard, sodium, mysqlnd, PDO, xml, bcmath, bz2, calendar, ctype, curl, dom, mbstring, FFI, fileinfo, ftp, gd, gettext, iconv, exif, mcrypt, mysqli, pdo_mysql, Phar, posix, readline, shmop, SimpleXML, sockets, sysvmsg, sysvsem, sysvshm, tokenizer, xmlreader, xmlwriter, xsl, zip, Zend OPcache

LARAVEL VERSION:

11.33.2.0

BACKPACK PACKAGE VERSIONS:

backpack/basset: 1.3.6
backpack/crud: 6.7.50
backpack/generators: v4.0.7
backpack/permissionmanager: 7.2.1
backpack/pro: 2.2.25
backpack/theme-tabler: 1.2.15

@Mte90 Mte90 added the triage label Jan 22, 2025
Copy link

welcome bot commented Jan 22, 2025

Hello there! Thanks for opening your first issue on this repo!

Just a heads-up: Here at Backpack we use GitHub Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.

Backpack communication channels:

  • Bug Reports, Feature Requests - GitHub Issues (here);
  • Quick help (How do I do X) - Gitter Chatroom;
  • Long questions (I have done X and Y and it won't do Z wtf) - Stackoverflow, using the backpack-for-laravel tag;
  • Showing off something you've made, asking for opinion on Backpack/Laravel matters - Reddit;

Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.

Thank you!

--
Justin Case
The Backpack Robot

Copy link

🚨 Bot is not sure about this answer. Please verify. 🚨

Based on the information provided in the knowledge sources, I don't have enough specific details to fully address your issue. However, I can provide some general guidance and suggestions based on similar issues reported in Backpack:

  1. Regarding the 500 error on save redirect:
    This could be related to a configuration issue or a problem with the save action. A similar issue was reported in this GitHub issue, where changing settings in the ui.php file caused a 500 error. You might want to check your configuration files, especially if you've recently made changes.

  2. For the password saving issue:
    There have been reports of password hashing issues in Backpack. In this GitHub issue, a user reported problems with changing the encryption method. Make sure you're using the correct hashing method in your configuration and that it's consistent across your application.

  3. Redirect issue:
    The mismatch between the form URL and the redirect might be causing problems. You could try overriding the postChangePasswordForm method in your controller to specify the correct redirect URL.

  4. General troubleshooting:
    As suggested in this community forum post, you could try clearing various caches:

    php artisan config:clear
    php artisan cache:clear
    php artisan view:clear
    php artisan basset:clear
    

    Also, check your error logs for more detailed information about the 500 error.

If these suggestions don't resolve your issue, you might want to create a new issue on the Backpack CRUD GitHub repository with more detailed information about your specific setup and the steps to reproduce the problem.

ℹ️ Please note our AI Bot does not reply to follow-ups, this will be the only AI answer in this thread. If the AI helped you find the answer, please mark it as answered or write details below so it can learn. Then close the conversation. If not, please give more information for when a human reads this. ℹ️

Relevant sources:

Github Issue (closed): Plan password in case of user create crud[Bug]
Bug report
Github Issue (closed): [Bug] Edit about now broken after automatic "required fields"
Github Issue (closed): [Bug] Upgrade BackPack v5 to v6
Github Issue (closed): [Bug] Method encoding cannot be changed (argon/argon2id)
Github Issue (closed): the create and edit function does not work after updating to 5 version
Fix save action redirect url
Github Issue (closed): [Bug]
Github Issue (closed): [Bug] After change settings get 500 error
Github Issue (closed): [Bug]
Github Issue (closed): [Bug] ValidateRequest on StoreFunction redirect to form
Github Issue (closed): [Bug] SCDM Backpack Admin Panel
Bug report
Github Issue (closed): [Bug] SQLSTATE[42S02]: Base table or view not found: 1146 Table 'my_db.password_resets' doesn't exist (Connection: mysql, SQL: select * from password_resets where email = myemail limit 1)
Github Issue (closed): [Bug] Unable to save empty input with relation HasOne

@Mte90
Copy link
Author

Mte90 commented Jan 22, 2025

So I have this code in my User model:

    public function setPasswordAttribute($value)
    {
        if (!empty($value) && Hash::needsRehash($value)) {
            $this->attributes['password'] = Hash::make($value);
        }
    }

In this way avoids to hash again the password and in the User edit view from PermissionManager when I change the password it is saved rightly and that works.

In the edit user profile, requires to insert the old password and change it I get that 500 error with a green alert that the changes were saved.
When I try to login the password changed from the profile was not saved at all and the previous one still works.

@Mte90
Copy link
Author

Mte90 commented Jan 22, 2025

In other cases I am able to login with the password but I am not able to change it because the old password is not the same as the one in the db.

So probably there is something wrong happening between permission manager and login, I am using the option to use the nickname and not the email.

@Mte90
Copy link
Author

Mte90 commented Jan 22, 2025

Testing the code on https://github.com/Laravel-Backpack/CRUD/blob/main/src/app/Http/Controllers/MyAccountController.php#L67

Seems that $this->guard()->logoutOtherDevices($request->new_password); fails as if I put a dd after that line is not executed.
If I comment that line the redirect is executed but I am still not getting saved the new password.

I was able to fix it with that change and:


    public function setPasswordAttribute($value)
    {
        if (!empty($value) && Hash::needsRehash($value)) {
            $this->attributes['password'] = Hash::make($value);
        }

        $this->attributes['password'] = $value;
    }

@jcastroa87
Copy link
Member

Hello @Mte90

Can you please share the model and if there is any override about user forms to replicate this in my side?
If you can, please share screenshots and step by step to see the problem in my side.

Cheers.

@Mte90
Copy link
Author

Mte90 commented Jan 27, 2025

<?php

namespace App\Models;

use app\Models\Bilancio;
use app\Models\Relazione;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Support\Facades\Hash;

class User extends Authenticatable
{
    use CrudTrait;
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;
    use HasRoles;

    public $identifiableAttribute = 'name';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected static function boot()
    {
        parent::boot();

        // Order by name ASC
        static::addGlobalScope('order', function (Builder $builder) {
            $builder->orderBy('name', 'asc');
        });
    }

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    public function setPasswordAttribute($value)
    {
        if (!empty($value) && Hash::needsRehash($value)) {
            $this->attributes['password'] = Hash::make($value);
        } else {
            $this->attributes['password'] = $value;
        }
    }
}

As you can see it is very basic.

@jcastroa87 jcastroa87 self-assigned this Jan 27, 2025
@jcastroa87
Copy link
Member

Hello @Mte90

I try to reproduce this error on a clean install and our demo, but I never get the redirect to "change-password" and password always is updated in normal way and works on login.

Can you please share here a step-by-step to reproduce this on my side?

Thanks.

Cheers.

@Mte90
Copy link
Author

Mte90 commented Jan 28, 2025

I don't know what else I can share to debug that issue, in the log there aren't any error for that 500 error also in debug mode.

@jcastroa87
Copy link
Member

You can try with a video maybe to follow all the process step-by-step or share if you customize the form or any other code for "login/register" or "my account" controllers/models.

Cheers.

@Mte90
Copy link
Author

Mte90 commented Jan 28, 2025

The step you did are the same I do so a video it willbe useless.
I just customized the edit profile page with just the password fields but the error it was already happening.

resources/views/vendor/backpack/theme-tabler/my_account.blade.php

@extends(backpack_view('blank'))

@section('after_styles')
    <style media="screen">
        .backpack-profile-form .required::after {
            content: ' *';
            color: red;
        }
    </style>
@endsection

@php
  $breadcrumbs = [
      trans('backpack::crud.admin') => url(config('backpack.base.route_prefix'), 'dashboard'),
      trans('backpack::base.my_account') => false,
  ];
@endphp

@section('header')
    <section class="content-header">
        <div class="container-fluid mb-3">
            <h1>{{ trans('backpack::base.my_account') }}</h1>
        </div>
    </section>
@endsection

@section('content')
    <div class="row">

        @if (session('success'))
        <div class="col-lg-8">
            <div class="alert alert-success">
                {{ session('success') }}
            </div>
        </div>
        @endif

        @if ($errors->count())
        <div class="col-lg-8">
            <div class="alert alert-danger">
                <ul class="mb-1">
                    @foreach ($errors->all() as $e)
                    <li>{{ $e }}</li>
                    @endforeach
                </ul>
            </div>
        </div>
        @endif

        {{-- CHANGE PASSWORD FORM --}}
        <div class="col-lg-8 mb-4">
            <form class="form" action="{{ route('backpack.account.password') }}" method="post">

                {!! csrf_field() !!}

                <div class="card padding-10">

                    <div class="card-header">
                        <h3 class="card-title">{{ trans('backpack::base.change_password') }}</h3>
                    </div>

                    <div class="card-body backpack-profile-form bold-labels">
                        <div class="row">
                            <div class="col-md-4 form-group">
                                @php
                                    $label = trans('backpack::base.old_password');
                                    $field = 'old_password';
                                @endphp
                                <label class="required">{{ $label }}</label>
                                <input autocomplete="new-password" required class="form-control" type="password" name="{{ $field }}" id="{{ $field }}" value="">
                            </div>

                            <div class="col-md-4 form-group">
                                @php
                                    $label = trans('backpack::base.new_password');
                                    $field = 'new_password';
                                @endphp
                                <label class="required">{{ $label }}</label>
                                <input autocomplete="new-password" required class="form-control" type="password" name="{{ $field }}" id="{{ $field }}" value="">
                            </div>

                            <div class="col-md-4 form-group">
                                @php
                                    $label = trans('backpack::base.confirm_password');
                                    $field = 'confirm_password';
                                @endphp
                                <label class="required">{{ $label }}</label>
                                <input autocomplete="new-password" required class="form-control" type="password" name="{{ $field }}" id="{{ $field }}" value="">
                            </div>
                        </div>
                    </div>

                    <div class="card-footer">
                            <button type="submit" class="btn btn-success"><i class="la la-save"></i> {{ trans('backpack::base.change_password') }}</button>
                            <a href="{{ backpack_url() }}" class="btn">{{ trans('backpack::base.cancel') }}</a>
                    </div>

                </div>

            </form>
        </div>

    </div>
@endsection

Instead about controllers, UserCrudController.php:

<?php

namespace App\Http\Controllers\Admin;

use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
use Backpack\PermissionManager\app\Http\Controllers\UserCrudController as BackpackUserCrudController;

/**
 * Class UserCrudController
 *
 * @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
 */
class UserCrudController extends BackpackUserCrudController
{
    use \App\Traits\CrudPermissionTrait;
    use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;

    /**
     * Configure the CrudPanel object. Apply settings to all operations.
     *
     * @return void
     */
    public function setup()
    {
        CRUD::setModel(\App\Models\User::class);
        CRUD::setRoute(config('backpack.base.route_prefix') . '/user');
        CRUD::setEntityNameStrings('user', 'users');

        CRUD::field('name')->label('Nome Sede');

        $this->setAccessUsingPermissions();
    }

    /**
     * Define what happens when the List operation is loaded.
     *
     * @see  https://backpackforlaravel.com/docs/crud-operation-list-entries
     *
     * @return void
     */
    public function setupListOperation()
    {
        CRUD::setFromDb(); // set columns from db columns.
    }

    /**
     * Define what happens when the Create operation is loaded.
     *
     * @return void
     */
    public function setupCreateOperation()
    {
        CRUD::setFromDb(); // set fields from db columns.

        CRUD::field('name')->validationRules('required|min:4');
        CRUD::field('email')->validationRules('required|email|unique:users,email');
        CRUD::field('password')->validationRules('required');
    }

    /**
     * Define what happens when the Update operation is loaded.
     *
     * @see https://backpackforlaravel.com/docs/crud-operation-update
     *
     * @return void
     */
    public function setupUpdateOperation()
    {
        CRUD::field('name')->validationRules('required|min:4');
        CRUD::field('email')->validationRules('required|email|unique:users,email,' . CRUD::getCurrentEntryId());
        CRUD::field('password')->hint('Type a password to change it.');
    }
}

I don't know if there is a way to turn on other kind of debugging to detect what is happening, like if the route is registered or something else.

@jcastroa87
Copy link
Member

I try many ways to reproduce this in my side and was impossible. Here what I try:

Config /config/backpack/base.php

'authentication_column' => 'username',
'authentication_column_name' => 'Username',

Model User.php

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Builder;
use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, CrudTrait, HasRoles;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'username',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected static function boot()
    {
        parent::boot();

        // Order by name ASC
        static::addGlobalScope('order', function (Builder $builder) {
            $builder->orderBy('name', 'asc');
        });
    }

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    public function setPasswordAttribute($value)
    {
        if (!empty($value) && Hash::needsRehash($value)) {
            $this->attributes['password'] = Hash::make($value);
        } else {
            $this->attributes['password'] = $value;
        }
    }
}

Controller UserCrudController.php

<?php

namespace App\Http\Controllers\Admin;

use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
use Backpack\PermissionManager\app\Http\Controllers\UserCrudController as BackpackUserCrudController;

/**
 * Class UserCrudController
 *
 * @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
 */
class UserCrudController extends BackpackUserCrudController
{
    use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;

    /**
     * Configure the CrudPanel object. Apply settings to all operations.
     *
     * @return void
     */
    public function setup()
    {
        CRUD::setModel(\App\Models\User::class);
        CRUD::setRoute(config('backpack.base.route_prefix') . '/user');
        CRUD::setEntityNameStrings('user', 'users');

        CRUD::field('name')->label('Nome Sede');

        //$this->setAccessUsingPermissions();
    }

    /**
     * Define what happens when the List operation is loaded.
     *
     * @see  https://backpackforlaravel.com/docs/crud-operation-list-entries
     *
     * @return void
     */
    public function setupListOperation()
    {
        CRUD::setFromDb(); // set columns from db columns.
    }

    /**
     * Define what happens when the Create operation is loaded.
     *
     * @return void
     */
    public function setupCreateOperation()
    {
        CRUD::setFromDb(); // set fields from db columns.

        CRUD::field('name')->validationRules('required|min:4');
        CRUD::field('email')->validationRules('required|email|unique:users,email');
        CRUD::field('password')->validationRules('required');
    }

    /**
     * Define what happens when the Update operation is loaded.
     *
     * @see https://backpackforlaravel.com/docs/crud-operation-update
     *
     * @return void
     */
    public function setupUpdateOperation()
    {
        CRUD::field('name')->validationRules('required|min:4');
        CRUD::field('email')->validationRules('required|email|unique:users,email,' . CRUD::getCurrentEntryId());
        CRUD::field('password')->hint('Type a password to change it.');
    }
}

AppServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->bind(
            \Backpack\PermissionManager\app\Http\Controllers\UserCrudController::class, //this is package controller
            \App\Http\Controllers\Admin\UserCrudController::class //this should be your own controller
        );
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        //
    }
}

View /resources/views/vendor/backpack/theme-tabler/my_account.blade.php

@extends(backpack_view('blank'))

@section('after_styles')
    <style media="screen">
        .backpack-profile-form .required::after {
            content: ' *';
            color: red;
        }
    </style>
@endsection

@php
  $breadcrumbs = [
      trans('backpack::crud.admin') => url(config('backpack.base.route_prefix'), 'dashboard'),
      trans('backpack::base.my_account') => false,
  ];
@endphp

@section('header')
    <section class="content-header">
        <div class="container-fluid mb-3">
            <h1>{{ trans('backpack::base.my_account') }}</h1>
        </div>
    </section>
@endsection

@section('content')
    <div class="row">

        @if (session('success'))
        <div class="col-lg-8">
            <div class="alert alert-success">
                {{ session('success') }}
            </div>
        </div>
        @endif

        @if ($errors->count())
        <div class="col-lg-8">
            <div class="alert alert-danger">
                <ul class="mb-1">
                    @foreach ($errors->all() as $e)
                    <li>{{ $e }}</li>
                    @endforeach
                </ul>
            </div>
        </div>
        @endif

        {{-- CHANGE PASSWORD FORM --}}
        <div class="col-lg-8 mb-4">
            <form class="form" action="{{ route('backpack.account.password') }}" method="post">

                {!! csrf_field() !!}

                <div class="card padding-10">

                    <div class="card-header">
                        <h3 class="card-title">{{ trans('backpack::base.change_password') }}</h3>
                    </div>

                    <div class="card-body backpack-profile-form bold-labels">
                        <div class="row">
                            <div class="col-md-4 form-group">
                                @php
                                    $label = trans('backpack::base.old_password');
                                    $field = 'old_password';
                                @endphp
                                <label class="required">{{ $label }}</label>
                                <input autocomplete="new-password" required class="form-control" type="password" name="{{ $field }}" id="{{ $field }}" value="">
                            </div>

                            <div class="col-md-4 form-group">
                                @php
                                    $label = trans('backpack::base.new_password');
                                    $field = 'new_password';
                                @endphp
                                <label class="required">{{ $label }}</label>
                                <input autocomplete="new-password" required class="form-control" type="password" name="{{ $field }}" id="{{ $field }}" value="">
                            </div>

                            <div class="col-md-4 form-group">
                                @php
                                    $label = trans('backpack::base.confirm_password');
                                    $field = 'confirm_password';
                                @endphp
                                <label class="required">{{ $label }}</label>
                                <input autocomplete="new-password" required class="form-control" type="password" name="{{ $field }}" id="{{ $field }}" value="">
                            </div>
                        </div>
                    </div>

                    <div class="card-footer">
                            <button type="submit" class="btn btn-success"><i class="la la-save"></i> {{ trans('backpack::base.change_password') }}</button>
                            <a href="{{ backpack_url() }}" class="btn">{{ trans('backpack::base.cancel') }}</a>
                    </div>

                </div>

            </form>
        </div>

    </div>
@endsection

I can change the password anywhere and always work for login. I never get the 500 error on update password and redirect always work.

Here is the versions where i try:

### PHP VERSION:
8.3.14

### PHP EXTENSIONS:
Core, date, libxml, openssl, pcre, sqlite3, zlib, ctype, curl, dom, fileinfo, filter, hash, iconv, json, mbstring, SPL, session, PDO, pdo_sqlite, standard, posix, random, readline, Reflection, Phar, SimpleXML, tokenizer, xml, xmlreader, xmlwriter, mysqlnd, bcmath, exif, gd, pcntl, pdo_mysql, sodium, zip, xdebug

### LARAVEL VERSION:
11.41.0.0

### BACKPACK PACKAGE VERSIONS:
backpack/basset: 1.3.6
backpack/crud: 6.7.50
backpack/generators: v4.0.7
backpack/permissionmanager: 7.2.1
backpack/pro: 2.2.32
backpack/theme-coreuiv2: 1.2.7
backpack/theme-coreuiv4: 1.1.5
backpack/theme-tabler: 1.2.17
backpack/translation-manager: 1.0.5

So maybe there is a problem with a customize or something different you try here.

Let me know if I miss anything on this tests or if you can publish a project with the error to reproduce will be useful to fix this if there is a problem.

Cheers.

@Mte90
Copy link
Author

Mte90 commented Jan 30, 2025

So the differences I have:

    'authentication_column' => 'name',
    'authentication_column_name' => 'name',

In my base.php

and


    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Gate::before(function ($user, $ability) {
            return $user->hasRole('admin') ? true : null;
        });
    }

In appserviceprovider.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

No branches or pull requests

2 participants