• Welcome to the Chevereto user community!

    Here users from all over the world gather around to learn the latest about Chevereto and contribute with ideas to improve the software.

    Please keep in mind:

    • 😌 This community is user driven. Be polite with other users.
    • 👉 Is required to purchase a Chevereto license to participate in this community (doesn't apply to Pre-sales).
    • 💸 Purchase a Pro Subscription to get access to active software support and faster ticket response times.

Facebook login

Status
Not open for further replies.
Is very strange because the username is taken directly from Facebook API. I can't imagine where it could be the error.
 
I've tried installing different hosting and it still has error. I don't know why.
1. Because of Facebook apps
2. Chevereto (not)
But i creat a Facebook apps, enable Status and Review, add my url, and get ID & secret. After that fill it in Chevereto. What wrong?
I see that Chevereto demo get friend list, my apps none. It's only difference.
 
i see that most of websites using Chevereto has this error except demo.chevereto.com
Nope, is not a Chevereto error. Facebook changed the API and they thought that it will be a brilliant idea to get rid of the user names in the return array. I will have to think in something.
 
Last edited:
I see that you are finding out the new way. (in demo ;) with API v2 show when i connect)
But i find out new error.
Example i haven't set username Facebook, CHV gets MYNAME to username, but in Vietnamese, is has error.
Ex: My name is Nguyễn Tăng Lai ----> it gets: nguyntnglai
it don't get special charecter in Vietnames.
I think has better if it gets: nguyentanglai
Change special charecter in Vietnames into international languege
 
Last edited:
That is because the system only allows alphanumeric values. It will strip any non alpha char. System allows users to change the username so that fits that problem.
 
Anyway, back to Facebook. Here is the thing: https://developers.facebook.com/docs/apps/upgrading/

Facebook changed the API and now usernames are forbidden. There is no way to get the user username (among other information). If you ask me this is very stupid because it was the only way to actually link a Facebook profile to a Chevereto user and be 110% sure that the profile was related to the Chevereto user. Most likely Facebook removed this because username allows you to get the profile URL and some guys thinks that security is about don'pt guess a URL rather than set the privacy scope.

Anyway, the solution is pretty bold. Facebook profiles will be removed from Chevereto and usernames will be composed using the Facebook name variable.

Regarding international names like "Nguyễn" or similar I will add a function to unaccent the chars but that will only work in alphanumeric base only, I can't replace Chinese or Russian chars with alphanumeric chars.
 
app/routes/route.connect.php

PHP:
<?php

/* --------------------------------------------------------------------

  Chevereto
  http://chevereto.com/

  @version    3.3.0
  @author    Rodolfo Berrios A. <http://rodolfoberrios.com/>
            <inbox@rodolfoberrios.com>

  Copyright (C) 2014 Rodolfo Berrios A. All rights reserved.
 
  BY USING THIS SOFTWARE YOU DECLARE TO ACCEPT THE CHEVERETO EULA
  http://chevereto.com/license

  --------------------------------------------------------------------- */

$route = function($handler) {
    try {
        $doing = $handler->request[0];
       
        if(empty($doing)) {
            return $handler->issue404();
        }
       
        $logged_user = CHV\Login::getUser();
       
        // User status override redirect
        CHV\User::statusRedirect($logged_user['status']);
       
        $do_connect = false;
       
        // Include the connect stuff
        require_once(CHV_APP_PATH_LIB_VENDOR . $doing.'/'.$doing.'.php');
       
        if($_REQUEST['return']) {
            $_SESSION['connect_return'] = $_REQUEST['return'];
        }
       
        if($_SESSION['login']['type'] == $doing) {
            G\redirect($logged_user['url']);
        }
       
        if(!CHV\get_chv_setting($doing)) {
            return $handler->issue404();
        }
       
        switch($doing) {
           
            case 'facebook':

                $facebook = new Facebook([
                    'appId'  => CHV\get_chv_setting('facebook_app_id'),
                    'secret' => CHV\get_chv_setting('facebook_app_secret')
                ]);
       
                $get_user = $facebook->getUser();
               
                if($get_user) {
                    $get_user = $facebook->api($get_user);
                   
                    // Ugly profile url https://www.facebook.com/app_scoped_user_id/<ID>
                   
                    $social_pictures = [
                        'avatar'        => 'http://graph.facebook.com/'.$get_user['id'].'/picture',
                        'background'    => NULL
                    ];
                    $connect_user = [
                        'id'        => $get_user['id'],
                        'username'    => G\sanitize_string(G\unaccent_string($get_user['name']), true, true),
                        'name'        => $get_user['name'],
                        'avatar'    => $social_pictures['avatar'],
                        'url'        => $get_user['link'],
                        'website'    => NULL
                    ];
                    $connect_tokens = [
                        'secret'    => $facebook->getAccessToken(),
                        'token_hash'=> NULL
                    ];
                    $do_connect = true;
                } else {
                    G\redirect($facebook->getLoginUrl(['redirect_uri' => G\get_base_url('connect/facebook/?callback')]));
                }
               
            break;
           
            case 'twitter':
               
                $twitter = [
                    'key'        => CHV\get_chv_setting('twitter_api_key'),
                    'secret'    => CHV\get_chv_setting('twitter_api_secret')
                ];
               
                if($_REQUEST['oauth_verifier'] and $_SESSION['twitter']['oauth_token'] and $_SESSION['twitter']['oauth_token_secret']){
                       
                    // Handle the twitter callback
                    $twitteroauth = new TwitterOAuth($twitter['key'], $twitter['secret'], $_SESSION['twitter']['oauth_token'], $_SESSION['twitter']['oauth_token_secret']);
                    $access_token = $twitteroauth->getAccessToken($_REQUEST['oauth_verifier']);
                   
                    if($access_token) {
                        $twitteroauth = new TwitterOAuth($twitter['key'], $twitter['secret'], $access_token['oauth_token'], $access_token['oauth_token_secret']);
                        $get_user = $twitteroauth->get('account/verify_credentials');
                       
                        if($get_user->errors) {
                            G\redirect('connect/'.$doing);
                        } else {
                            $social_pictures = [
                                'avatar'        => str_replace('_normal.', '.', $get_user->profile_image_url_https),
                                'background'    => $get_user->profile_background_image_url
                            ];
                            $connect_user = [
                                'id'        => $get_user->id,
                                'username'    => $get_user->screen_name,
                                'name'        => $get_user->name,
                                'avatar'    => $social_pictures['avatar'],
                                'url'        => 'http://twitter.com/'.$get_user->screen_name,
                                'website'    => $get_user->entities->url ? $get_user->entities->url->urls[0]->expanded_url : NULL
                            ];
                            $connect_tokens = [
                                'secret'    => $access_token['oauth_token_secret'],
                                'token_hash'=> $access_token['oauth_token']
                            ];
                            $do_connect = true;
                        }
                    } else {
                        throw new Exception('Twitter connect error code:'.$twitteroauth->http_code, 400);
                    }
               
                } else {
                   
                    // Request the twitter login
                   
                    $twitteroauth = new TwitterOAuth($twitter['key'], $twitter['secret']);
                    $request_token = $twitteroauth->getRequestToken(G\get_base_url('connect/twitter'));

                    if($twitteroauth->http_code == 200){
                        $_SESSION['twitter']['oauth_token'] = $request_token['oauth_token']; 
                        $_SESSION['twitter']['oauth_token_secret'] = $request_token['oauth_token_secret'];
                        $url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']);
                        G\redirect($url);
                    } else {
                        unset($_SESSION['twitter']);
                        throw new Exception('Twitter connect error code:'.$twitteroauth->http_code, 400);
                    } 
                }

            break;
           
            case 'google':
               
                $google = [
                    'id'        => CHV\get_chv_setting('google_client_id'),
                    'secret'    => CHV\get_chv_setting('google_client_secret')
                ];
               
                // Validate agains CSRF
                if($_REQUEST['state'] and $_SESSION['google']['state'] !== $_REQUEST['state']) {
                    G\set_status_header(403);
                    $handler->template = "request-denied";
                } else {
                    $_SESSION['google']['state'] = md5(uniqid(mt_rand(), true));
                }
               
                // User cancelled the login flow
                if($_REQUEST['error'] == 'access_denied') {
                    G\redirect('login');
                }
               
                $client = new Google_Client();
                $client->setApplicationName(CHV\get_chv_setting('website_name') . ' connect');
                $client->setClientId($google['id']);
                $client->setClientSecret($google['secret']);
                $client->setRedirectUri(G\get_base_url('connect/google'));
                $client->setState($_SESSION['google']['state']);
                $client->setScopes(['https://www.googleapis.com/auth/plus.login']); // https://developers.google.com/+/api/oauth
               
                require_once(CHV_APP_PATH_LIB_VENDOR . 'google/contrib/Google_PlusService.php');
               
                $plus = new Google_PlusService($client);
               
                if(isset($_GET['code'])) {
                    $client->authenticate();
                    $_SESSION['google']['token'] = $client->getAccessToken();
                }

                if($_SESSION['google']['token']) {
                    $client->setAccessToken($_SESSION['google']['token']);
                }

                if($client->getAccessToken()) {
                    $get_user = $plus->people->get('me');
                   
                    if($get_user) {
                        $social_pictures = [
                            'avatar'        => preg_replace('/\?.*/', '', $get_user['image']['url']),
                            'background'    => NULL
                        ];
                        $connect_user = [
                            'id'        => $get_user['id'],
                            'username'    => G\sanitize_string(G\unaccent_string($get_user['displayName']), true, true),
                            'name'        => $get_user['displayName'],
                            'avatar'    => $get_user['image']['url'],
                            'url'        => $get_user['url'],
                            'website'    => preg_match('#https?:\/\/profiles\.google\.com\/.*#', $get_user['urls'][0]['value']) ? NULL : $get_user['urls'][0]['value']
                        ];
                        $google_token = json_decode($client->getAccessToken());
                        $connect_tokens = [
                            'secret'    => $client->getAccessToken(),
                            'token_hash'=> $google_token->access_token
                        ];
                        $do_connect = true;
                    }
                } else {
                    G\redirect($client->createAuthUrl());
                }
               
            break;
        }
       
        if($do_connect) {
           
            $login_array_db = ['type' => $doing, 'resource_id' => $connect_user['id']];
            $login = CHV\Login::get($login_array_db, NULL, 1);
           
            // Populate the token stuff
            $login_array_db = array_merge($login_array_db, $connect_tokens);
           
            // Pupulate the rest
            $login_array_db = array_merge($login_array_db, [
                'resource_name'        => $connect_user['name'],
                'resource_avatar'    => $connect_user['avatar'],
                'resource_url'        => $connect_user['url'],
                'date'                => G\datetime(),
                'date_gmt'            => G\datetimegmt()
            ]);   
           
            // Login exists then update login
            if($login) {
               
                $updated_login = CHV\Login::update($login['login_id'], $login_array_db);
               
                // Session user doesn't match. Stop bugging
                if($_SESSION["login"] and $login['login_user_id'] !== $_SESSION["login"]['id']) {
                    $logout = CHV\Login::logout($_SESSION["login"]['id']);
                }
               
                $user_id = $login['login_user_id'];
               
            } else { // Login needs to be inserted
               
                if(!CHV\get_chv_setting('enable_signups')) {
                    return $handler->issue404();
                }
               
                // User already logged in?
                if($_SESSION["login"]) {
                    $user_id = $_SESSION["login"]['id'];
                    $login_array_db['user_id'] = $_SESSION["login"]['id'];
                }
               
                $inserted_login = CHV\Login::insert($login_array_db);
            }
           
            // Get user candidate if any
            $user = $user_id ? CHV\User::getSingle($user_id, 'id') : false;
           
            // We need to create or update the user?
            // Edit user
            if($user) {
                if(in_array($doing, ['twitter', 'facebook'])) {
                    $user_array[$doing.'_username'] = $connect_user['username'];
                }
                if(count($user_array) > 0) {
                    CHV\User::update($user_id, $user_array);
                }
            } else { // Create user
                // Wait a second, username already exists?   
                $username = '';
                preg_match_all('/[\w]/', $connect_user['username'], $user_matches);
                foreach($user_matches[0] as $match) {
                    $username .= $match;
                }
                $username = substr(strtolower($username), 0, CHV\get_chv_setting('username_max_length'));
               
                $i = 1;
                while(CHV\User::getSingle($username, 'username', false)) {
                    $i++;
                    $username = $connect_user['username'] . G\random_values(2, $i, 1)[0];
                }
               
                $insert_user_values = [
                    'username'    => $username,
                    'name'        => $connect_user['name'],
                    'status'    => 'awaiting-email',
                    'website'    => $connect_user['website'],
                    'timezone'    => CHV\get_chv_setting('default_timezone'),
                    'language'    => CHV_LANGUAGE_CODE, // nota. fail
                ];
               
                if(in_array($doing, ['twitter', 'facebook'])) {
                    $insert_user_values[$doing.'_username'] = $connect_user['username'];
                }
               
                $inserted_user = CHV\User::insert($insert_user_values);
                $updated_login = CHV\Login::update($login ? $login['login_id'] : $inserted_login, ['user_id' => $inserted_user]);
               
            }
           
            $user_id = $inserted_user ? $inserted_user : $user_id;
            $user = CHV\User::getSingle($user_id, 'id');
           
            // Fetch the social network images
           
            if(!$user or !$user['avatar']['filename'] or !$user['background']['filename']) {
               
                $avatar_needed = !$user ? true : !$user['avatar']['filename'];
                $background_needed = !$user ? true : !$user['background']['filename'];
               
                try {
                    if($avatar_needed and $social_pictures['avatar']) {
                        CHV\User::uploadPicture($user, 'avatar', $social_pictures['avatar']);
                    }
                    if($background_needed and $social_pictures['background']) {
                        CHV\User::uploadPicture($user, 'background', $social_pictures['background']);
                    }
                } catch(Exception $e) {} // Silence
               
            }

            $logged_user = CHV\Login::login($user_id, $doing);
           
            $token = $connect_tokens['secret'].$connect_tokens['token_hash'];
            $hash = password_hash($token, PASSWORD_BCRYPT);
           
            $cookie = implode(':', [CHV\encodeID($user_id), $doing, $hash]) . ':' . strtotime($login_array_db['date_gmt']);
            setcookie("KEEP_LOGIN_SOCIAL", $cookie, time()+(60*60*24*30), G_ROOT_PATH_RELATIVE);
           
            $redirect_to = $_SESSION['connect_return'] ? urldecode($_SESSION['connect_return']) : $logged_user['url'];
            unset($_SESSION['connect_return']);
           
            G\redirect($redirect_to);
       
        }
   
    } catch(Exception $e) {
        G\exception_to_error($e);
    }
   
};
 
Status
Not open for further replies.
Back
Top