mongodb / laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel (Moloquent)
https://www.mongodb.com/compatibility/mongodb-laravel-integration
MIT License
7k stars 1.43k forks source link

When I try to reset my password I get this error: FatalThrowableError in Carbon.php line 291: Type error: DateTime::__construct() expects parameter 1 to be string, array given #1164

Closed McMazalf closed 4 years ago

McMazalf commented 7 years ago

Hello guys, every time I try to reset my psw I get this error. Using Laravel with MongoDB:

Thanks in advance for the answers

in Carbon.php line 291 at DateTime->__construct(array('date' => '2017-03-28 12:45:33.000000', 'timezone_type' => '3', 'timezone' => 'UTC'), object(DateTimeZone)) in Carbon.php line 291 at Carbon->__construct(array('date' => '2017-03-28 12:45:33.000000', 'timezone_type' => '3', 'timezone' => 'UTC'), null) in Carbon.php line 324 at Carbon::parse(array('date' => '2017-03-28 12:45:33.000000', 'timezone_type' => '3', 'timezone' => 'UTC')) in DatabaseTokenRepository.php line 126 at DatabaseTokenRepository->tokenExpired(array('_id' => object(ObjectID), 'email' => 'ciaoale@gmail.com', 'token' => 'c1b01664ea63f3a7e2a745c29568cb4f595d8af7be19dd20baed8993096375f4', 'created_at' => array('date' => '2017-03-28 12:45:33.000000', 'timezone_type' => '3', 'timezone' => 'UTC'))) in DatabaseTokenRepository.php line 115 at DatabaseTokenRepository->exists(object(User), array('_id' => object(ObjectID), 'email' => 'ciaoale@gmail.com', 'token' => 'c1b01664ea63f3a7e2a745c29568cb4f595d8af7be19dd20baed8993096375f4', 'created_at' => array('date' => '2017-03-28 12:45:33.000000', 'timezone_type' => '3', 'timezone' => 'UTC'))) in PasswordBroker.php line 122 at PasswordBroker->validateReset(array('email' => 'ciaoale@gmail.com', 'password' => 'Alessaalessa656', 'password_confirmation' => 'Alessaalessa656', 'token' => 'c1b01664ea63f3a7e2a745c29568cb4f595d8af7be19dd20baed8993096375f4')) in PasswordBroker.php line 88 at PasswordBroker->reset(array('email' => 'ciaoale@gmail.com', 'password' => 'Alessaalessa656', 'password_confirmation' => 'Alessaalessa656', 'token' => 'c1b01664ea63f3a7e2a745c29568cb4f595d8af7be19dd20baed8993096375f4'), object(Closure)) in ResetsPasswords.php line 46 at ResetPasswordController->reset(object(Request)) at call_user_func_array(array(object(ResetPasswordController), 'reset'), array(object(Request))) in Controller.php line 55 at Controller->callAction('reset', array(object(Request))) in ControllerDispatcher.php line 44 at ControllerDispatcher->dispatch(object(Route), object(ResetPasswordController), 'reset') in Route.php line 189 at Route->runController() in Route.php line 144 at Route->run(object(Request)) in Router.php line 653 at Router->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 53 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in RedirectIfAuthenticated.php line 24 at RedirectIfAuthenticated->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in SubstituteBindings.php line 41 at SubstituteBindings->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in VerifyCsrfToken.php line 65 at VerifyCsrfToken->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ShareErrorsFromSession.php line 49 at ShareErrorsFromSession->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64 at StartSession->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37 at AddQueuedCookiesToResponse->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59 at EncryptCookies->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 104 at Pipeline->then(object(Closure)) in Router.php line 655 at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 629 at Router->dispatchToRoute(object(Request)) in Router.php line 607 at Router->dispatch(object(Request)) in Kernel.php line 268 at Kernel->Illuminate\Foundation\Http\{closure}(object(Request)) in Pipeline.php line 53 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 46 at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 137 at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33 at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 104 at Pipeline->then(object(Closure)) in Kernel.php line 150 at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 117 at Kernel->handle(object(Request)) in index.php line 53 at require('/Users/alessandro/Documents/Programmazione/Laravel/ASAP/public/index.php') in server.php line 133

omidahn commented 7 years ago

i have the same problem. laravel 5.4 that's because i'm using wrong DatabaseTokenRepository : Illuminate/Auth/Passwords/DatabaseTokenRepository.php instead of \Moloquent\Auth\DatabaseTokenRepository. but the original problem was this error (using Moloquent\Auth\PasswordResetServiceProvider) : FatalThrowableError in DatabaseTokenRepository.php line 58: Type error: Argument 2 passed to Illuminate\Auth\Passwords\DatabaseTokenRepository::__construct() must implement interface Illuminate\Contracts\Hashing\Hasher, string given, called in /home/omid/tmp/b2c-wl/vendor/moloquent/moloquent/src/Auth/PasswordBrokerManager.php on line 22 so i had to use laravel default PasswordResetServiceProvider. (same error using "Jenssegers\Mongodb" or "Moloquent")

JuCarr commented 7 years ago

Same problem here with Laravel 5.4. How did you fix it?

McMazalf commented 7 years ago

I wildlands send you the screenshot asap.

Il giorno ven 21 apr 2017 alle 18:07 JuCarr notifications@github.com ha scritto:

Same problem here with Laravel 5.4. How did you fix it?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jenssegers/laravel-mongodb/issues/1164#issuecomment-296233177, or mute the thread https://github.com/notifications/unsubscribe-auth/AZdiGERdHk07ZZmfnonWrRdV3XAdNVZHks5ryNRPgaJpZM4MrkiJ .

McMazalf commented 7 years ago

Will send*

Il giorno ven 21 apr 2017 alle 18:08 Alessandro Mazzari < alessandro.mazzari.v.l@gmail.com> ha scritto:

I wildlands send you the screenshot asap.

Il giorno ven 21 apr 2017 alle 18:07 JuCarr notifications@github.com ha scritto:

Same problem here with Laravel 5.4. How did you fix it?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jenssegers/laravel-mongodb/issues/1164#issuecomment-296233177, or mute the thread https://github.com/notifications/unsubscribe-auth/AZdiGERdHk07ZZmfnonWrRdV3XAdNVZHks5ryNRPgaJpZM4MrkiJ .

JanisOzolins commented 7 years ago

Same problem here, any fixes for this? @jenssegers

McMazalf commented 7 years ago

Guys i fixed this by adding those classes to the user model.

`<?php

namespace App;

use Illuminate\Notifications\Notifiable; use Illuminate\Contracts\Auth\Authenticatable; use Jenssegers\Mongodb\Eloquent\Model as Eloquent; use Illuminate\Auth\Authenticatable as AuthenticableTrait; use App\Auth\Traits\MagicallyAuthenticatable as MagicallyAuthenticatable; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Eloquent implements Authenticatable, CanResetPasswordContract { use Notifiable, MagicallyAuthenticatable, AuthenticableTrait, CanResetPassword;`

btw, i'm pretty sure that : use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; solved it and implements it : class User extends Eloquent implements Authenticatable, CanResetPasswordContract

Hope i helped you all.

dasjet commented 7 years ago

Same problem here, any fixes for this? @jenssegers

Benstaar commented 7 years ago

As mentioned in the documentation, registering the service provider fixed my problem. Added Jenssegers\Mongodb\Auth\PasswordResetServiceProvider::class, in config/app.php

mikekamornikov commented 7 years ago

see my fix/hack for laravel 5.4 based project - https://github.com/jenssegers/laravel-mongodb/issues/1124#issuecomment-327965515

msankar1991 commented 6 years ago

Getting same problem here also any updates on this?

mcandylab commented 5 years ago

In Config/App.php replace Illuminate\Auth\Passwords\PasswordResetServiceProvider on Jenssegers\Mongodb\Auth\PasswordResetServiceProvider In App/Http/Controllers/Auth/ResetPasswordController.php add use MongoDB\BSON\UTCDateTime;

Timezone: Europe/Moscow Laravel: 5.7.* Jenssegers/mongodb: "^3.4"

ramsis23 commented 5 years ago

In Config/App.php replace Illuminate\Auth\Passwords\PasswordResetServiceProvider on Jenssegers\Mongodb\Auth\PasswordResetServiceProvider In App/Http/Controllers/Auth/ResetPasswordController.php add use MongoDB\BSON\UTCDateTime;

Timezone: Europe/Moscow Laravel: 5.7.* Jenssegers/mongodb: "^3.4"

Wow thank you so much, this solves my problem.

"jenssegers/mongodb": "^3.5", "laravel/framework": "5.8.*",

yehanny commented 5 years ago

According to the documentation, registering the service provider fixed my problem. Added Jenssegers\Mongodb\Auth\PasswordResetServiceProvider::class, in config/app.php

Adding only this solve the issue for me, great!

ibraah88 commented 4 years ago

for Laravel 6.0, jenssegers/mongodb 3.6 timezone' => 'Europe/Paris

In Config/App.php replace Illuminate\Auth\Passwords\PasswordResetServiceProvider on Jenssegers\Mongodb\Auth\PasswordResetServiceProvider

Important: dont forget to clean the password_resets table in your database before testing.

AngusDV commented 4 years ago

after once "forgot password" work fine but after twice "forgot password" on one user not work and error is : Exception DateTime::__construct(): Failed to parse time string (1577012550000) at position 12 (0): Unexpected character

AngusDV commented 4 years ago

ok i am change carbon on /vendor/nesbot/carbon/src/Carbon/Traits/Creator.php line 80 from parent::construct($time ?: 'now', $timezone); to parent::construct(strtotime($time) ?: 'now', $timezone); and my problem solved

jansgescheit commented 4 years ago

for Laravel 6.0, jenssegers/mongodb 3.6 timezone' => 'Europe/Paris

In Config/App.php replace Illuminate\Auth\Passwords\PasswordResetServiceProvider on Jenssegers\Mongodb\Auth\PasswordResetServiceProvider

Important: dont forget to clean the password_resets table in your database before testing.

Yeah, thanks.

I thought I was stupid. Because everything was configured correctly, but there was still an old data set in the collection.

jansgescheit commented 4 years ago

for Laravel 6.0, jenssegers/mongodb 3.6 timezone' => 'Europe/Paris In Config/App.php replace Illuminate\Auth\Passwords\PasswordResetServiceProvider on Jenssegers\Mongodb\Auth\PasswordResetServiceProvider Important: dont forget to clean the password_resets table in your database before testing.

Yeah, thanks.

I thought I was stupid. Because everything was configured correctly, but there was still an old data set in the collection.

Okay, happy too early. If i run a second password reset call for the same email i got this Error. Looks like the wrong DatabaseTokenRepository is used. But the correct ServiceProvider Jenssegers\Mongodb\Auth\PasswordResetServiceProvider is added to the config/app.php

{
    "message": "DateTime::__construct(): Failed to parse time string (1579858647000) at position 12 (0): Unexpected character",
    "exception": "Exception",
    "file": "/var/www/html/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php",
    "line": 77,
    "trace": [
        {
            "file": "/var/www/html/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php",
            "line": 77,
            "function": "__construct",
            "class": "DateTime",
            "type": "->"
        },
        {
            "file": "/var/www/html/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php",
            "line": 145,
            "function": "__construct",
            "class": "Carbon\\Carbon",
            "type": "->"
        },
        {
            "file": "/var/www/html/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php",
            "line": 172,
            "function": "rawParse",
            "class": "Carbon\\Carbon",
            "type": "::"
        },
        {
            "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php",
            "line": 179,
            "function": "parse",
            "class": "Carbon\\Carbon",
            "type": "::"
        },
        {
            "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php",
            "line": 164,
            "function": "tokenRecentlyCreated",
            "class": "Illuminate\\Auth\\Passwords\\DatabaseTokenRepository",
            "type": "->"
        },
        {
            "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBroker.php",
            "line": 59,
            "function": "recentlyCreatedToken",
            "class": "Illuminate\\Auth\\Passwords\\DatabaseTokenRepository",
            "type": "->"
        },
Smolevich commented 4 years ago

Please write steps for reproducing

jansgescheit commented 4 years ago

Run php artisan tinker or call the method somewhere twice:

Password::broker()->sendResetLink(['email' => 'valid@email.com'])

First: passwords.sent Second: DateTime::__construct(): Failed to parse time string (1579964877000) at position 12 (0): Unexpected character'

jansgescheit commented 4 years ago

I also overload the tokenRecentlyCreated method and convert the date to a string. With this changes the password reset works also on a second try. No idea if that's the right way.

<?php

namespace Jenssegers\Mongodb\Auth;

use DateTime;
use DateTimeZone;
use Illuminate\Auth\Passwords\DatabaseTokenRepository as BaseDatabaseTokenRepository;
use MongoDB\BSON\UTCDateTime;

class DatabaseTokenRepository extends BaseDatabaseTokenRepository
{
    /**
     * @inheritdoc
     */
    protected function getPayload($email, $token)
    {
        return [
            'email' => $email,
            'token' => $this->hasher->make($token),
            'created_at' => new UTCDateTime(time() * 1000),
        ];
    }

    /**
     * @inheritdoc
     */
    protected function tokenExpired($createdAt)
    {
        return parent::tokenExpired(
            $this->convertDateToString($createdAt)
        );
    }

    /**
     * @inheritdoc
     */
    protected function tokenRecentlyCreated($createdAt)
    {
        return parent::tokenRecentlyCreated(
            $this->convertDateToString($createdAt)
        );
    }

    /**
     * Convert UTCDateTime to a date string
     *
     * @param mixed $date
     * @return mixed
     */
    private function convertDateToString($date)
    {
        if ($date instanceof UTCDateTime) {
            $date = $date->toDateTime();
            $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
            $createdAt = $date->format('Y-m-d H:i:s');
        } elseif (is_array($date) && isset($date['date'])) {
            $date = new DateTime($date['date'], new DateTimeZone(isset($date['timezone']) ? $date['timezone'] : 'UTC'));
            $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
            $date = $date->format('Y-m-d H:i:s');
        }

        return $date;
    }
}
jansgescheit commented 4 years ago

@Smolevich i created a fork of your demo project with a basic setup of the issue above https://github.com/codenascherin/demo-mongo-application

for testing run docker-compose exec php php artisan check:password:reset

Smolevich commented 4 years ago

@Jannnnnn i check it now

Smolevich commented 4 years ago

@Jannnnnn After running command i catch error Symfony\Component\Routing\Exception\RouteNotFoundException : Route [password.reset] not defined.

jansgescheit commented 4 years ago

@Jannnnnn After running command i catch error Symfony\Component\Routing\Exception\RouteNotFoundException : Route [password.reset] not defined.

You have to set Auth::routes() to routes/web.php https://github.com/Smolevich/demo-mongo-application/compare/master...codenascherin:issue-laravel6-password-reset?expand=1#diff-7e3ce459dfcc113722bdf4667ceffc11

Smolevich commented 4 years ago

@Jannnnnn i find problem, see https://github.com/jenssegers/laravel-mongodb/pull/1903

Smolevich commented 4 years ago

@Jannnnnn as soon new release will be ready, it fill be fixed. See new about release https://github.com/jenssegers/laravel-mongodb/issues/1926

alsemany commented 4 years ago

ok, the problem that if someone try to send the rest email while there's still an reset request on the database it will check with the created_at , for quick resolve just delete the exists request from the database in

Http/Controllers/Auth/ForgotPasswordController.php ForgotPasswordController

use Illuminate\Support\Facades\DB; public function __construct() { DB::collection('password_resets')->where('email' , request('email'))->delete(); }

pedrocalado commented 3 years ago

ok, the problem that if someone try to send the rest email while there's still an reset request on the database it will check with the created_at , for quick resolve just delete the exists request from the database in

Http/Controllers/Auth/ForgotPasswordController.php ForgotPasswordController

use Illuminate\Support\Facades\DB; public function __construct() { DB::collection('password_resets')->where('email' , request('email'))->delete(); }

This helps fixing the error, but on the downside it disables the throttle password reset feature. Since the existing records for the given email are deleted, there is no data for Laravel to compare and deny the password reset request, when the throttle option is configured.

I don't find it too serious, and we can make our own validations before deleting those records and, again, this quick fix works just fine.