public function verify(Request $req, AuthManager $auth)
    {
        if (!$this->isValid()) {
            return false;
        }

        // verify the user agent matches the one in the request
        if ($this->userAgent != $req->agent()) {
            return false;
        }

        // look up the user with a matching email address
        try {
            $userClass = $auth->getUserClass();
            $user = $userClass::where('email', $this->email)
                ->first();
        } catch (ModelException $e) {
            // fail open when unable to look up the user
            return false;
        }

        if (!$user) {
            return false;
        }

        // hash series for matching with the db
        $seriesHash = $this->hash($this->series);

        // First, make sure all of the parameters match, except the token.
        // We match the token separately to detect if an older session is
        // being used, in which case we cowardly run away.
        $expiration = time() - $this->getExpires();
        $db = $auth->getApp()['database']->getDefault();
        $query = $db->select('token,two_factor_verified')
                    ->from('PersistentSessions')
                    ->where('email', $this->email)
                    ->where('created_at', U::unixToDb($expiration), '>')
                    ->where('series', $seriesHash);

        $persistentSession = $query->one();

        if ($query->rowCount() !== 1) {
            return false;
        }

        // if there is a match, sign the user in
        $tokenHash = $this->hash($this->token);

        // Same series, but different token, meaning the user is trying
        // to use an older token. It's most likely an attack, so flush
        // all sessions.
        if (!hash_equals($persistentSession['token'], $tokenHash)) {
            $db->delete('PersistentSessions')
               ->where('email', $this->email)
               ->execute();

            return false;
        }

        // remove the token once used
        $db->delete('PersistentSessions')
           ->where('email', $this->email)
           ->where('series', $seriesHash)
           ->where('token', $tokenHash)
           ->execute();

        // mark the user as 2fa verified
        if ($persistentSession['two_factor_verified']) {
            $user->markTwoFactorVerified();
        }

        return $user;
    }