Registration

Type {{#dataTypeArticle objectTypeId}}{{objectTypeId}}{{/dataTypeArticle}}
Datastore Type {{#dataTypeArticle datastoreTypeId}}{{datastoreTypeId}}{{/dataTypeArticle}}
Supports {{#article "security/authorities"}}authorities{{/article}}, {{#article "security/permissions"}}permissions{{/article}}, {{#article "transfer"}}transfer{{/article}}

The minimum registration flow looks like this:

  1. The application collects the user's email
  2. The application creates an Registration object. It stores the emailProviderId of the email provider that the registration process will use to dispatch emails. It also fills in the email configurations that define the confirmation and welcome emails.
  3. The application plugs in the user's details onto the Registration object. It stores the userName and userDomainId to identify which domain the final user should be created on.
  4. The registration process sends a confirmation email to the end user.
  5. The user receives the email and clicks on the link to confirm their identity and intention of registering.
  6. The application collects any additional information and sets it onto the Registration object.
  7. The registration process confirms the registration. A user account is created on the target domain. A welcome email is sent to the end user.

The registration flow can also be used to register new sub-tenants for your platform. To do so, you must provide the tenantRegistrarId where the tenant should be created and also the tenantPlanKey that identifies the plan the tenant should be given. The plan must exist in the same registrar as the newly created tenant.

If your plan requires integrated billing, the registrar must be configured to support integrated billing. You then need to identify a payment method that the new tenant should use. You can do this by explicitly setting paymentMethodId or by passing in a payment method configuration upon confirmation. In the latter case, a new payment method object will be validated and created by the billing provider upon creation of the tenant.

Configuration

Emails maintain a configuration that you can adjust or consult as you create, update and query for them.

The following table presents you the configuration properties.

User Properties

Property Type Required Default Read-Only Description
userEmail text *required The email address of the domain user to create.
userName text *required The name of the domain user to create.
userDomainId text *required The id of the domain where the user should be created.
userProperties object An array of additional properties to apply to the user obejct when it is created.

Tenant Properties

Property Type Required Default Read-Only Description
tenantTitle text The title of the tenant to be created.
tenantDescription text The description of the tenant to be created.
tenantPlanKey text The planKey of the plan to use for the new tenant subscription.
tenantRegistrarId text The id of the registrar where the tenant should be created.

Email Properties

Property Type Required Default Read-Only Description
emailProviderId text *required The id of the email provider to use for any email-related handling.
emails object *required A collection of configuration objects that describe Emails that are to be sent by the registration process. These Email configuration objects are keyed by either: confirmation or welcome.

Billing Properties

Property Type Required Default Read-Only Description
paymentMethodId text The id of the payment method to use (if one already exists).
discounts array An array of text containing the discount codes to apply to the created tenant's subscription atop the specified plan.
addons array An array of text containing the addon codes to apply to the created tenant's subscription atop the specified plan.

Flow Control Properties

Property Type Required Default Read-Only Description
confirmationSent boolean Read-Only Whether the confirmation email was sent.
completed boolean Read-Only Whether the registration was completed.
completedPrincipalId boolean Read-Only The id of the principal that was created as a result of the registration completing.
completedTenantId boolean Read-Only The id of the tenant that was created as a result of the registration completing.

Other Properties

Property Type Required Default Read-Only Description
signupProperties object An array of additional properties. These are not used by the registration process but will be stored on the registration object as a remnant and may include additional data that the user provided such as the size of their company, project type, etc.
active boolean Whether this registration object is active. Active mean that it describes a live user account. If a user elects to cancel their registration, the registration object can either be deleted or it can be marked inactive. Inactive accounts remain in the system but are not utilized. They allow the user to register again.

Create a Registration

You can create as many registrations as you'd like. Here's an example:

// assume we have an application
var application = ...;

// assume we have a domain
var domain = ...;

// assume we have an email provider
var emailProvider = ...;

// create a registration
application.createRegistration({
    "userEmail": "user1@test.com",
    "userDomainId": domain.getId(),
    "emailProviderId": emailProvider.getId(),
    "emails": {
        "confirmation": {
            "body": "<a href='http://myserver.com?hash=${hash}'>Click me to confirm your email address</a>",
            "from": "buildtest@gitanasoftware.com"
        },
        "welcome": {
            "body": "Welcome!",
            "from": "buildtest@gitanasoftware.com"
        }
    }
});


Update a Registration

You can update properties on a registration:

// assume we have a registration
var registration = ...;

registration.update();

Delete a Registration

You can delete registrations just as you would any other object. However, if a registration has already been sent, deleting it will not cause any emails to be unsent (that much should be obvious).

registration.del();

In addition, if an email is sitting in someone's email inbox with a link to complete the next step in a registration flow, the URL may cease to work and the link may break. Consider setting the registration as inactive instead.

registration.del();

Read a Registration

You can read a Registration by its _doc ID field.

// registration id
var registrationId = "4b5b685c980c10f98beb";

application.readRegistration(registrationId).then(function() {
    console.log("Found Registration: " + this.getId());
});

List Registrations

You can retrieve a list of Registrations for your application. The following code hands back the full list.

application.listRegistrations();

You can then iterate over the list to pick at what you'd like.

application.listRegistrations().each(function() {
    console.log("Registration: " + this.getId());
});

Retrieving the full list is potentially an expensive operation, depending how many items you have. The more your retrieve, the more data goes over the wire and so forth. Thus, you might wish to paginate your call and retrieve a subset of the total list at a time.

Here is an example that retrieves in pages of size 10. It starts on the second page (by skipping to starting index 20). It also sorts by the title field in a descending sequence.

application.listRegistrations({
    "limit": 10,
    "skip": 20,
    "sort": { "title": -1 }
}).each(function() {
    console.log("Registration: " + this.getId());
});

You don't have to have all of the pagination parameters (limit, skip and sort). You might only want to include one or two. It's up to you.

Query Registrations

You can run custom queries against your Registrations to find exactly what you're looking for. Here is a query that looks for Registrations which are disabled.

application.queryRegistrations({
    "active": true
});

Here is that same query followed by an iteration over the result map.

application.queryRegistrations({
    "active": true
}).each(function(id) {
    console.log("Found a Registration: " + id);
});

Finally, you can mix queries with pagination to reduce data over the wire and speed up performance. Here is that same query with some pagination thrown in. We limit to pages of size 10 and sort by title.

application.queryRegistrations({
    "active": true
},{
    "limit": 10,
    "skip": 20,
    "sort": {
        "title": -1
    }
}).each(function(id) {
    console.log("Found a Registration: " + id);
});

Send the Confirmation Email

The first step in the registration process is to send a Confirmation Email.

// assume we have a registration
var registration = ...;

// send confirmation email
registration.sendConfirmationEmail();

Confirm the Registration

Once the end user clicks the link in their email, they come back into your application. You do what you have to do, update the Registration object and then confirm the registration. By confirming, you tell Cloud CMS to proceed and create any user objects, tenant objects and required billing objects.

Once Cloud CMS finishes, it will send the welcome email to the user.

// assume we have a registration
var registration = ...;

// confirm the registration
registration.confirm("password");


Send the Welcome Email

If you wish to send the welcome email again, you can do so at any time.

// assume we have a registration
var registration = ...;

// send welcome email
registration.sendWelcomeEmail();

Example: Tenant Creation with Payment Method

Here is a full example where we use a registration flow to register a new sub-tenant for our platform. This flow will send all the appropriate emails and create a payment method for the user.

First Step - Kick off the Registration Process

Suppose our application has asked the user to provide their email, first name and last name. We might collect those values from a form.

To kick off the registration process, we need to create a registration object as shown below. The code below provides a good sample of how you can do this. It loads two templates by opening URL connections to confirmation.html and welcome.html.

// assume we have an application
var application = ...;

// and let's say this stuff comes off a form
var email = "joe@smith.com";
var firstName = "joe";
var lastName = "smith";

//
// let's get to work
//

// our html templates
var htmls = {};

// the callback function which creates the registration
var start = function() {

    // create the registration + send confirmation email
    application
        .createRegistration({
            "userEmail": email,
            "userDomainId": "<domain id where our user will be created>",
            "userProperties": {
                "firstName": firstName,
                "lastName": lastName
            },
            "emailProviderId": "<email provider id>",
            "emails": {
                "confirmation": {
                    "body": htmls["confirmation"],
                    "from": "buildtest@gitanasoftware.com"
                },
                "welcome": {
                    "body": htmls["welcome"],
                    "from": "buildtest@gitanasoftware.com"
                }
            },
            "tenantPlanKey": "<plan key>",
            "tenantRegistrarId": "<registrar id where we will create the tenant>"
        })
        .sendConfirmationEmail();
};

// use jQuery to load the "confirmation.html" and "welcome.html" templates
// when we're finished, we'll call the start() method
var loadHtml = function(url, key, callback) {
    $.ajax(url, {
        type: "GET",
        contentType: "html",
        success: function(data) {
            htmls[key] = data;
            if (callback) { callback(); }
        }
    });
};
loadHtml("confirmation.html", "confirmation", function() {
    loadHtml("welcome.html", "welcome", function() {
        start();
    })
});



The confirmation.html and welcome.html HTML files might be something like this:

// assume we have an application
var application = ...;

// and let's say this stuff comes off a form
var email = "joe@smith.com";
var firstName = "joe";
var lastName = "smith";

//
// let's get to work
//

// our html templates
var htmls = {};

// the callback function which creates the registration
var start = function() {

    // create the registration + send confirmation email
    application
        .createRegistration({
            "userEmail": email,
            "userDomainId": "<domain id where our user will be created>",
            "userProperties": {
                "firstName": firstName,
                "lastName": lastName
            },
            "emailProviderId": "<email provider id>",
            "emails": {
                "confirmation": {
                    "body": htmls["confirmation"],
                    "from": "buildtest@gitanasoftware.com"
                },
                "welcome": {
                    "body": htmls["welcome"],
                    "from": "buildtest@gitanasoftware.com"
                }
            },
            "tenantPlanKey": "<plan key>",
            "tenantRegistrarId": "<registrar id where we will create the tenant>"
        })
        .sendConfirmationEmail();
};

// use jQuery to load the "confirmation.html" and "welcome.html" templates
// when we're finished, we'll call the start() method
var loadHtml = function(url, key, callback) {
    $.ajax(url, {
        type: "GET",
        contentType: "html",
        success: function(data) {
            htmls[key] = data;
            if (callback) { callback(); }
        }
    });
};
loadHtml("confirmation.html", "confirmation", function() {
    loadHtml("welcome.html", "welcome", function() {
        start();
    })
});



The templates are loaded and then the registration is created. The user's first name and last name are copied into the userProperties field. Finally, the registration confirmation emails are sent off.

Second Step - User Clicks on the Email Link

The user then receives the email and clicks on the link. This takes them back into the web application. You can then grab the hash request parameter argument and use it to retrieve the registration object.

// assume we have an application
var application = ...;

// we get this from the request
var hash = ...;

// the hash is the registration id
application.readRegistration(hash);

Third Step - Collect Additional Info and Confirm Registration

And then you can present the user with a screen to collect any additional information you wish. Fundamentally, we need to ask what password they would like.

In addition, let's assume that our plan requires billing and thus a payment method. We therefore need to collect credit card information which, at a minimum, must include:

  • holderName - the card holder name
  • number - the card number
  • expirationMonth - the two digit expiration month
  • expirationYear - the four digit expiration year

Once they click "Submit", we can confirm the registration and create their account. The code to do so might look like the following:

// assume we have an application
var application = ...;

// we get this from the form
var paymentObject = {
    "cardHolder": "Joe Smith",
    "number": "1234123412341234",
    "expirationMonth": "02",
    "expirationYear": "2014"
};
var password = "bazooka";

// we get this from the request
var hash = ...;

// the hash is the registration id
application.readRegistration(hash).confirm(password, paymentObject);

Email Templates

As shown above, you can define your own confirmation and welcome emails using templates that take advantage of model variables. The model will consist of some of the fields from your registration object so that you can utilize these fields in your email responses.

Specifically, the following email model variables are available:

  • id - the ID of the registration object
  • _doc - the ID of the registration object
  • hash - the generated registration hash (this should be used to pass back to your web app)
  • title - the optional title of your registration object
  • description - the optional description of your registration object
  • userName - the name of the user principal
  • userEmail - the email of the user principal
  • userProperties - the optional collection of additional user properties
  • signupProperties - the optional collection of additional signup properties
  • tenantTitle - the optional tenant title
  • tenantDescription - the optional tenant description
  • tenantPlanKey - the optional tenant plan key