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

Call to a member function run() on null #106

Open
LarryBarker opened this issue Dec 11, 2023 · 5 comments · May be fixed by #114
Open

Call to a member function run() on null #106

LarryBarker opened this issue Dec 11, 2023 · 5 comments · May be fixed by #114

Comments

@LarryBarker
Copy link

We've been seeing this error more frequently which seems to happen when a user tries to use a magic link with an invalid token. We send magic links in an onboarding email to allow users access to complete their profile, and we think users are going back to this email and using the link to try and login again.

I've tracked this back to the getMagicLinkByToken method on the MagicLink class:

public static function getMagicLinkByToken($token)

In our case, this is returning null for whatever reason, and then when the MagicLinkController tries to call run(), its calling it on null and throwing the exception.

Do you have any ideas on how we can work around this? Ideally, if someone visits a link where the token is invalid, we could show them a page with more information and maybe a form to resend a magic link (we would implement this ourselves if possible)?

Thank you for taking time to share this package - it has been very helpful in getting our onboarding flow figured out. Any and all feedback is appreciated, and thank you again 🙏

@cesargb
Copy link
Owner

cesargb commented Dec 16, 2023

A MagicLink, by default, expires after 72 hours, but you can create a MagicLink without an expiration date.

To do this, when you generate the MagicLink, you can use the second argument to specify the expiration time in minutes. Optionally, you can pass null to ensure that it doesn't expire over time.

Please visit lifetime options

Let me provide you with an example:

$lifetime = null;

MagicLink::create($action, $lifetime);

Please tell me if this solves your issue.

@LarryBarker
Copy link
Author

@cesargb Thanks for your reply. The issue is not with creating magic links, or their expiration I don't believe; this is an issue where the record does not exist in the database for whatever reason. For example, if someone tried using a link like this:

myapp.com/magiclink/this-is-an-example-of-a-token-that-doesnt-exist-in-the-database

getMagicLinkByToken($token) in will return null and MagicLinkController will throw an exception.

@labomatik
Copy link

labomatik commented Mar 19, 2024

Same error on my side, to avoid that i've to use my own route and modify the getMagicLinkByToken function to test the validity of the token..

To reproduce: create a new link to login, pass the middleware, delete the record in the database and you got the error

@georgiarnaudov
Copy link

I'm getting the same error when listening for visited event and try to delete the link by using $event->magiclink->delete()

@jamesdb
Copy link
Contributor

jamesdb commented Jul 15, 2024

Same error on my side, to avoid that i've to use my own route and modify the getMagicLinkByToken function to test the validity of the token..

To reproduce: create a new link to login, pass the middleware, delete the record in the database and you got the error

Interesting, i wonder if its the HEAD requests which are triggering the errors. Explains why i've seen a few of these on production but no one has reported anything.

Might be worth trying something like this:

<?php

namespace MagicLink\Middlewares;

use Closure;
use Illuminate\Http\Request;
use MagicLink\MagicLink;
use MagicLink\Responses\Response;

class MagiclinkMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $token = (string) $request->route('token');

        $magicLink = MagicLink::getValidMagicLinkByToken($token);

        if ($request->method() === 'HEAD') {
            return response()->noContent(($magicLink) ? 200 : 404);
        }

        if (! $magicLink) {
            return $this->badResponse();
        }

        $responseAccessCode = $magicLink->getResponseAccessCode();

        if ($responseAccessCode) {
            return $responseAccessCode;
        }

        $magicLink->visited();

        return $next($request);
    }

    protected function badResponse()
    {
        $responseClass = config('magiclink.invalid_response.class', Response::class);

        $response = new $responseClass();

        return $response(config('magiclink.invalid_response.options', []));
    }
}

Instead of continuing on and executing the MagicLinkController.

@jamesdb jamesdb linked a pull request Jul 15, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants