Esempio n. 1
0
 /**
  * Adds a device to the system, after sending a test notification to it
  * @param {array} $device
  * @param {string} $device.userId
  * @param {string} $device.deviceId
  * @param {string} [$device.formFactor]
  * @param {string} [$device.platform]
  * @param {string} [$device.version]
  * @param {string} [$device.sessionId]
  * @param {boolean} [$device.sandbox]
  * @param {string} [$device.passphrase]
  * @param {boolean} [$skipNotification=false] if true, skips sending notification
  * @return {Users_Device}
  */
 static function add($device, $skipNotification = false)
 {
     Q_Valid::requireFields(array('userId', 'deviceId'), $device, true);
     $userId = $device['userId'];
     $deviceId = $device['deviceId'];
     if (!$skipNotification) {
         $app = Q::app();
         $sandbox = Q::ifset($device, 'sandbox', null);
         if (!isset($sandbox)) {
             $sandbox = Q_Config::get($app, "cordova", "ios", "sandbox", false);
         }
         $env = $sandbox ? ApnsPHP_Abstract::ENVIRONMENT_SANDBOX : ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION;
         $s = $sandbox ? 'sandbox' : 'production';
         $cert = APP_LOCAL_DIR . DS . 'Users' . DS . 'certs' . DS . $app . DS . $s . DS . 'bundle.pem';
         $authority = USERS_PLUGIN_FILES_DIR . DS . 'Users' . DS . 'certs' . DS . 'EntrustRootCA.pem';
         $logger = new Users_ApnsPHP_Logger();
         $push = new ApnsPHP_Push($env, $cert);
         $push->setLogger($logger);
         $push->setRootCertificationAuthority($authority);
         if (isset($device['passphrase'])) {
             $push->setProviderCertificatePassphrase($device['passphrase']);
         }
         $push->connect();
         $message = new ApnsPHP_Message($deviceId);
         $message->setCustomIdentifier('Users_Device-adding');
         $message->setBadge(0);
         $message->setText(Q_Config::get($app, "cordova", "ios", "device", "text", "Notifications have been enabled"));
         $message->setCustomProperty('userId', $userId);
         $message->setExpiry(5);
         $push->add($message);
         $push->send();
         $push->disconnect();
         $errors = $push->getErrors();
         if (!empty($errors)) {
             $result = reset($errors);
             throw new Users_Exception_DeviceNotification($result['ERRORS'][0]);
         }
     }
     $sessionId = Q_Session::id();
     $user = Users::loggedInUser();
     $info = array_merge(Q_Request::userAgentInfo(), array('sessionId' => $sessionId, 'userId' => $user ? $user->id : null, 'deviceId' => null));
     $device2 = Q::take($device, $info);
     $d = new Users_Device($device2);
     $d->save(true);
     if ($sessionId) {
         $s = new Users_Session();
         $s->id = $sessionId;
         if (!$s->retrieve()) {
             $s->deviceId = $deviceId;
         }
     }
     $_SESSION['Users']['deviceId'] = $deviceId;
     $device2['Q/method'] = 'Users/device';
     Q_Utils::sendToNode($device2);
     return $d;
 }
Esempio n. 2
0
/**
 * This tool renders all user sessions opened.
 *
 * @param {array} $options An associative array of parameters, containing:
 * @param {string} [$options.userId]
 *   The user's id. Defaults to id of the logged-in user, if any.
 * @param {bool} [$options.editable=true]
 *   Whether user can delete sessions
 * @param {bool} [$options.devices=true]
 *   Whether to show devices info
 */
function Users_sessions_tool($options)
{
    $options = array_merge(array('editable' => true, 'devices' => true), $options);
    if (empty($options['userId'])) {
        $options['userId'] = Users::loggedInUser(true)->id;
    }
    Q_Response::addStylesheet('plugins/Users/css/tools/sessions.css');
    Q_Response::setToolOptions($options);
    $sessions = Users_Session::select("us.*, ud.deviceId, ud.platform, ud.version, ud.formFactor", "us")->join(Users_Device::table() . ' ud', array('us.userId' => 'ud.userId', 'us.id' => 'ud.sessionId'), "LEFT")->where(array('us.userId' => $options['userId']))->fetchDbRows();
    $noDevicesClass = $options['devices'] ? '' : "Users_sessions_noDevices";
    $html = "<table class='Users_sessions_container {$noDevicesClass}'><tr><th>Session Id</th><th class='Users_sessions_devicesData'>Platform</th><th class='Users_sessions_devicesData'>Version</th><th>Last Updated</th>";
    if ($options["editable"]) {
        $html .= '<th class="Users_sessions_actions"></th>';
    }
    $html .= '</tr>';
    foreach ($sessions as $session) {
        $updatedTime = date("M j, Y g:i A", strtotime($session->updatedTime));
        $html .= "<tr><td class='Users_sessions_sessionId'>{$session->id}</td>" . "<td class='Users_sessions_devicesData'>{$session->platform}</td>" . "<td class='Users_sessions_devicesData'>{$session->version}</td>" . "<td>{$updatedTime}</td>";
        if ($options["editable"]) {
            $html .= "<td class='Users_sessions_actions'><button name='delete'>Delete</button></td>";
        }
        $html .= '</tr>';
    }
    $html .= "</table>";
    return $html;
}
Esempio n. 3
0
/**
 * Adds a device to the current user id and session.
 * See Users_Device::add method for more details.
 * @param {string} $deviceId
 * @return {void}
 */
function Users_device_post()
{
    Q_Request::requireFields(array('deviceId'));
    $deviceId = $_REQUEST['deviceId'];
    $user = Users::loggedInUser(true);
    $device = Users_Device::add(array_merge($_REQUEST, array('userId' => $user->id)));
    Q_Response::setSlot('data', $device);
}
Esempio n. 4
0
function Users_device_post()
{
    $user = Users::loggedInUser(true);
    $token = isset($_REQUEST['token']) ? $_REQUEST['token'] : null;
    $platform = Q_Request::platform();
    $version = Q_Request::OSVersion();
    $formFactor = Q_Request::isMobile() ? 'mobile' : (Q_Request::isTablet() ? 'tablet' : null);
    $device = new Users_Device();
    $device->userId = $user->id;
    $device->deviceId = $token;
    $device->platform = $platform;
    $device->version = $version;
    $device->formFactor = $formFactor;
    $device->sessionId = Q_Session::id();
    $_SESSION['Users']['deviceId'] = $token;
    Q_Response::setSlot('data', !!$device->save(true));
    Q_Utils::sendToNode(array("Q/method" => "Users/device", "userId" => $user->id, "deviceId" => $token));
}
Esempio n. 5
0
function Users_oAuth_post()
{
    // Validate the inputs
    $fields = array('response_type', 'token_type', 'access_token', 'expires_in', 'scope', 'state', 'Q_Users_oAuth');
    Q_Request::requireFields($fields, true);
    $params = Q::take($_REQUEST, $fields);
    $params['Q.Users.oAuth'] = $params['Q_Users_oAuth'];
    unset($params['Q_Users_oAuth']);
    Q_Valid::signature(true, $params, array('Q.Users.oAuth'));
    // Set the session id to the access_token
    Q_Session::id($params['access_token']);
    // Add a device, if any
    if ($deviceId = Q::ifset($_REQUEST, 'deviceId', null)) {
        $fields2 = array('deviceId', 'platform', 'version', 'formFactor');
        Q_Request::requireFields($fields2);
        $device = Q::take($_REQUEST, $fields2);
        $device['userId'] = Users::loggedInUser(true)->id;
        Users_Device::add($device);
    }
}
Esempio n. 6
0
 /**
  * Registers a user in the system.
  * @method register
  * @static
  * @param {string} $username The name of the user
  * @param {string|array} $identifier Can be an email address or mobile number. Or it could be an array of $type => $info
  * @param {string} [$identifier.identifier] an email address or phone number
  * @param {array} [$identifier.device] an array with keys "deviceId", "platform", "version"
  *   to store in the Users_Device table for sending notifications
  * @param {array|string} [$icon=array()] Array of filename => url pairs
  * @param {string} [$provider=null] Provider such as "facebook"
  * @param {array} [$options=array()] An array of options that could include:
  * @param {string} [$options.activation] The key under "Users"/"transactional" config to use for sending an activation message. Set to false to skip sending the activation message for some reason.
  * @return {Users_User}
  * @throws {Q_Exception_WrongType} If identifier is not e-mail or modile
  * @throws {Q_Exception} If user was already verified for someone else
  * @throws {Users_Exception_AlreadyVerified} If user was already verified
  * @throws {Users_Exception_UsernameExists} If username exists
  */
 static function register($username, $identifier, $icon = array(), $provider = null, $options = array())
 {
     if (is_array($provider)) {
         $options = $provider;
         $provider = null;
     }
     /**
      * @event Users/register {before}
      * @param {string} username
      * @param {string|array} identifier
      * @param {string} icon
      * @param {string} provider
      * @return {Users_User}
      */
     $return = Q::event('Users/register', compact('username', 'identifier', 'icon', 'provider', 'options'), 'before');
     if (isset($return)) {
         return $return;
     }
     $during = 'register';
     if (is_array($identifier)) {
         reset($identifier);
         switch (key($identifier)) {
             case 'device':
                 $fields = array('deviceId', 'platform', 'version');
                 Q_Valid::requireFields($fields, $identifier, true);
                 $device = $identifier;
                 if (isset($identifier['identifier'])) {
                     $identifier = $identifier['identifier'];
                 }
                 break;
             default:
                 throw new Q_Exception_WrongType(array('field' => 'identifier', 'type' => 'an array with entry named "device"'));
         }
     }
     if (Q_Valid::email($identifier, $emailAddress)) {
         $ui_identifier = $emailAddress;
         $key = 'email address';
         $type = 'email';
     } else {
         if (Q_Valid::phone($identifier, $mobileNumber)) {
             $key = 'mobile number';
             $ui_identifier = $mobileNumber;
             $type = 'mobile';
         } else {
             throw new Q_Exception_WrongType(array('field' => 'identifier', 'type' => 'email address or mobile number'), array('emailAddress', 'mobileNumber'));
         }
     }
     $user = false;
     if ($provider) {
         if ($provider != 'facebook') {
             throw new Q_Exception_WrongType(array('field' => 'provider', 'type' => '"facebook"'));
         }
         $facebook = Users::facebook();
         if ($facebook) {
             $uid = $facebook->getUser();
             try {
                 // authenticate (and possibly adopt) an existing provider user
                 // or insert a new user during this authentication
                 $user = Users::authenticate($provider, null, $authenticated, true);
             } catch (Exception $e) {
             }
             if ($user) {
                 // the user is also logged in
                 $adopted = true;
                 // Adopt this provider user
                 /**
                  * @event Users/adoptFutureUser {before}
                  * @param {Users_User} user
                  * @param {string} during
                  * @return {Users_User}
                  */
                 $ret = Q::event('Users/adoptFutureUser', compact('user', 'during'), 'before');
                 if ($ret) {
                     $user = $ret;
                 }
             }
         }
     }
     if (!$user) {
         $user = new Users_User();
         // the user we will save in the database
     }
     if (empty($adopted)) {
         // We will be inserting a new user into the database, so check if
         // this identifier was already verified for someone else.
         $ui = Users::identify($type, $ui_identifier);
         if ($ui) {
             throw new Users_Exception_AlreadyVerified(compact('key'), array('emailAddress', 'mobileNumber', 'identifier'));
         }
     }
     // Insert a new user into the database, or simply modify an existing (adopted) user
     $user->username = $username;
     if (!isset($user->signedUpWith) or $user->signedUpWith == 'none') {
         $user->signedUpWith = $type;
     }
     $user->icon = 'default';
     $user->passphraseHash = '';
     $url_parts = parse_url(Q_Request::baseUrl());
     if (isset($url_parts['host'])) {
         // By default, the user's url would be this:
         $user->url = $username ? "http://{$username}." . $url_parts['host'] : "";
     }
     /**
      * @event Users/insertUser {before}
      * @param {string} during
      * @param {Users_User} user
      */
     Q::event('Users/insertUser', compact('user', 'during'), 'before');
     $user->save();
     // sets the user's id
     /**
      * @event Users/insertUser {after}
      * @param {string} during
      * @param {Users_User} user
      */
     Q::event('Users/insertUser', compact('user', 'during'), 'after');
     $sizes = Q_Config::expect('Users', 'icon', 'sizes');
     sort($sizes);
     if (empty($icon)) {
         switch ($provider) {
             case 'facebook':
                 // let's get this user's icon on facebook
                 if (empty($uid)) {
                     break;
                 }
                 $icon = array();
                 foreach ($sizes as $size) {
                     $icon["{$size}.png"] = "https://graph.facebook.com/{$uid}/picture?width={$size}&height={$size}";
                 }
                 break;
         }
     } else {
         // Import the user's icon and save it
         if (is_string($icon)) {
             // assume it's from gravatar
             $iconString = $icon;
             $icon = array();
             foreach ($sizes as $size) {
                 $icon["{$size}.png"] = "{$iconString}&s={$size}";
             }
         } else {
             // locally generated icons
             $hash = md5(strtolower(trim($identifier)));
             $icon = array();
             foreach ($sizes as $size) {
                 $icon["{$size}.png"] = array('hash' => $hash, 'size' => $size);
             }
         }
     }
     if (!Q_Config::get('Users', 'register', 'icon', 'leaveDefault', false)) {
         self::importIcon($user, $icon);
         $user->save();
     }
     if (empty($user->emailAddress) and empty($user->mobileNumber)) {
         // Add an email address or mobile number to the user, that they'll have to verify
         try {
             $activation = Q::ifset($options, 'activation', 'activation');
             if ($activation) {
                 $subject = Q_Config::get('Users', 'transactional', $activation, "subject", null);
                 $body = Q_Config::get('Users', 'transactional', $activation, "body", null);
             } else {
                 $subject = $body = null;
             }
             if ($type === 'email') {
                 $user->addEmail($identifier, $subject, $body, array(), $options);
             } else {
                 if ($type === 'mobile') {
                     $p = $options;
                     if ($delay = Q_Config::get('Users', 'register', 'delaySms', 0)) {
                         $p['delay'] = $delay;
                     }
                     $sms = Q_Config::get('Users', 'transactional', $activation, "sms", null);
                     $user->addMobile($mobileNumber, $sms, array(), $p);
                 }
             }
         } catch (Exception $e) {
             // The activation message could not be sent, so remove this user
             // from the database. This way, this username will be
             // back on the market.
             $user->remove();
             throw $e;
         }
     }
     if (!empty($device)) {
         $device['userId'] = $user->id;
         Users_Device::add($device);
     }
     /**
      * @event Users/register {after}
      * @param {string} username
      * @param {string|array} identifier
      * @param {string} icon
      * @param {Users_User} user
      * @param {string} provider
      * @return {Users_User}
      */
     $return = Q::event('Users/register', compact('username', 'identifier', 'icon', 'user', 'provider', 'options', 'device'), 'after');
     return $user;
 }
Esempio n. 7
0
 /**
  * Logs a user out
  * @method logout
  * @static
  */
 static function logout()
 {
     // Access the session, if we haven't already.
     $user = self::loggedInUser();
     $sessionId = Q_Session::id();
     // One last chance to do something.
     // Hooks shouldn't be able to cancel the logout.
     /**
      * @event Users/logout {before}
      * @param {Users_User} user
      */
     Q::event('Users/logout', compact('user'), 'before');
     $deviceId = isset($_SESSION['Users']['deviceId']) ? $_SESSION['Users']['deviceId'] : null;
     $device = new Users_Device();
     $device->sessionId = $sessionId;
     // WARNING: NON-PK LOOKUP. Should store device id in session!
     if ($user) {
         Q_Utils::sendToNode(array("Q/method" => "Users/logout", "sessionId" => Q_Session::id(), "userId" => $user->id, "deviceId" => $deviceId));
         // forget the device for this user/session
         Users_Device::delete()->where(array('userId' => $user->id, 'sessionId' => $sessionId))->execute();
     }
     // Destroy the current session, which clears the $_SESSION and all notices, etc.
     Q_Session::destroy();
 }