• log out

User Accounts

Every good social app needs to support user accounts. The Users plugin in Qbix has been designed to take care of all the details in managing them, including:

  • Registration and logging in
  • Authentication with external identity providers
  • Security issues and selecting passphrases
  • Password reset, unsubscribing from emails
  • Confirmation of emails, mobile numbers
  • Database schema and persistence
  • Session management
  • Voting for things when logged in
  • Contacts and contact labels
  • Support for 3rd party apps, including OAuth

A user in Qbix can represent a person, an organization, or even an app. Every app can support multiple users, with their own contacts. Users can publish streams wherever Qbix apps are hosted, invite other users, manage access and privacy, and much more.

Registration and Login

The power and expressiveness of the Qbix API becomes apparent when you consider how apps can log people in. All you have to do is include the Users plugin and write:

Q.Users.login();

A streamlined (and customizable) interface appears, which takes care of all the issues above. It and is integrated with the rest of the system, and "just works".

The function above, like many other API functions, supports options (with default values) including:

  • identifierType: can be "email", "mobile" or "email,mobile"
  • using: can be "native", "facebook" or "native,facebook"
  • perms: the permissions to ask for if when authenticating with "facebook"
  • tryQuietly: if true, attempts to authenticate the user via an existing session
  • prompt: used with tryQuietly, whether to show a prompt in some circumstances, or stay completely silent
  • accountStatusUrl: if passed, this URL is queried for whether the user's profile is complete
  • onRequireComplete: event for when the app requires a user to complete their profile
  • onSuccess: event for when a user successfully (registers and) logs in
  • onCancel: event for when the flow is canceled for any reason

You can also modify the contents of Q.text.Users to customize any text that appears in the Users interface.

The Q.Users.onLogin and Q.Users.onLogout events are fired when the user successfully logs in and out, respectively. The Q.Users.loggedInUser and Q.Users.roles objects contains the data corresponding to the logged-in user. Here is how you can test for basic things relating to the user:

if (Q.Users.loggedInUser) { ... }
var userId = Q.Users.loggedInUserId();
if (Q.Users.roles["Websites/admins"]) {
  // the user is logged in,
  // and has this role in the app
}

Logging out is just as easy:

Q.Users.logout();

You can obtain a Q.Users.User object via the batched getter Q.Users.User.get(id, callback). Or, if your app uses the Streams plugin, you can get a Q.Streams.Avatar object via the batched getter Q.Streams.Avatar.get(id, callback). Just use them any time you need a user or avatar, and they'll get it for you.

Onboarding

Qbix provides standard functionality for helping onboard new users, to get them started with the app. Call this function when it's time to show a hint a user, and remember not to show it again:

Q.Users.hint(key, elementOrPoint, options);

The app keeps track of what hints have been shown and to how many people by using the voting mechanism.

Using the Facebook API

Any Javascript code that uses the Facebook API should wait for the Q.Users.onInitFacebook event, like this:

Q.Users.onInitFacebook.add({
  FB.ui(...);
}, key);

User accounts may be connected with facebook accounts, or not. If the user logs in "using" facebook then the account is connected automatically. Otherwise, you can call, for instance:

Q.Users.login({
  tryQuietly: true, 
  using: "facebook",
  onSuccess: function (user) {
    // if loggedInUser hasn't changed,
    // user is null here
  }	
});

Other parts of your code might want to subscribe to the Q.Users.onConnected and Q.Users.onLostConnection events.

PHP Interface

The Users plugin also provides classes in PHP which you can interact with. Not surprisingly, almost all these classes correspond to the database tables in the Users db connection, since they were originally autogenerated from that schema.

To reference the logged-in user, if any:

// Obtain a Users_User object or null:
$user = Users::loggedInUser();

// The following can throw Users_NotLoggedIn:
$user = Users::loggedInUser(true);

You can also set the logged-in user on the server. You should have a good reason for doing this:

// bypasses authentication on server:
Users::setLoggedInUser($user);

// log a user out on the server:
Users::logout();
Users::logout($user);

Note: once the front-end code detects that the user cookies changed, it will trigger the appropriate Q.Users.onLogin or Q.Users.onLogout event.

Configuration

Your app's config file is typically going to be used to override some config options in the Users plugin. Some of these options are are set in config/app.json:

{
  "Users": {
    "uris": {
      "QP/afterActivate": "QP/home"
    },
    "login": {
      "identifierType": "mobile"
    },
    "transactional": {
      "activation": {
        "subject": "Welcome to $app!",
        "body": "Users/email/activate.php",
        "sms": "Users/sms/activate.php"
      },
      "identifier": {
        "subject": "Verify this address",
        "body": "Users/email/add.php",
        "sms": "Users/sms/add.php"
      },
      "resend": {
        "subject": "Forgot your password?",
        "body": "Users/email/resend.php",
        "sms": "Users/sms/resend.php"
      },
      "authenticated": {
        "subject": false,
        "body": false
      }
    }
  }
}

Other settings should be set in local/app.json, because (just like database credentials) they are different for different environments:

...
"Users": {
  "apps": {
    "platforms": ["facebook", "ios"],
	"facebook": {
      "MyApp": {
        "appId": "2398457890234750895",
        ...
      }
	},
    "ios": {
      "MyApp": {
        "appId": "328785904735034",
        ...
      }
    }
  },
  "email": {
    "from": ["qp@qbix.com", "Qbix Platform"],  
    "smtp": {
      "auth": "login",
      "username": "something@something.com",
      "password": "PASSWORD",
      "ssl": "ssl",
      "port": 465,
      "host": "smtp.sendgrid.net"
    }
  },
  "mobile": {
    "twilio": {
      "sid": "SID GOES HERE",
      "token": "TOKEN GOES HERE"
    },
    "from": "+1234567890",
    "debug": true,
    "logKey": "SMS"
  }
}

Rationale

Qbix has many good reasons to standardize the user system. Besides making it easy to create social apps out of the box, Qbix also helps ensure best practices for users of those apps, and promotes a common experience so that users can know what to expect. Apps built on Qbix can all make use of functionality built for users, invitations, contact labels, access control (roles and permissions around contacts), in a way that people can get accustomed to and plugin developers can rely on, improving the social app ecosystem.

The Users plugin also correctly implements oAuth 2 and more. But it goes far beyond oAuth 2, allowing Qbix apps to run on a completely decentralized social network, where all the users -- people and organizations -- can own and publish their own data, and interoperate with one another.