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

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

<thead>
    <tr>
        <th>Property</th>
        <th>Type</th>
        <th>Required</th>
        <th>Default</th>
        <th nowrap>Read-Only</th>
        <th>Description</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>tenantTitle</td>
        <td>text</td>
        <td></td>
        <td></td>
        <td></td>
        <td>
            The <code>title</code> of the tenant to be created.
        </td>
    </tr>
    <tr>
        <td>tenantDescription</td>
        <td>text</td>
        <td></td>
        <td></td>
        <td></td>
        <td>
            The <code>description</code> of the tenant to be created.
        </td>
    </tr>
    <tr>
        <td>tenantPlanKey</td>
        <td>text</td>
        <td></td>
        <td></td>
        <td></td>
        <td>
            The <code>planKey</code> of the plan to use for the new tenant subscription.
        </td>
    </tr>
    <tr>
        <td>tenantRegistrarId</td>
        <td>text</td>
        <td></td>
        <td></td>
        <td></td>
        <td>
            The <code>id</code> of the registrar where the tenant should be created.
        </td>
    </tr>
</tbody>

Email Properties

<thead>
    <tr>
        <th>Property</th>
        <th>Type</th>
        <th>Required</th>
        <th>Default</th>
        <th nowrap>Read-Only</th>
        <th>Description</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>emailProviderId</td>
        <td>text</td>
        <td>*required</td>
        <td></td>
        <td></td>
        <td>
            The <code>id</code> of the email provider to use for any email-related handling.
        </td>
    </tr>
    <tr>
        <td>emails</td>
        <td>object</td>
        <td>*required</td>
        <td></td>
        <td></td>
        <td>
            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:
            <code>confirmation</code> or <code>welcome</code>.
        </td>
    </tr>
</tbody>

Billing Properties

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

Flow Control Properties

<thead>
    <tr>
        <th>Property</th>
        <th>Type</th>
        <th>Required</th>
        <th>Default</th>
        <th nowrap>Read-Only</th>
        <th>Description</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>confirmationSent</td>
        <td>boolean</td>
        <td></td>
        <td></td>
        <td>Read-Only</td>
        <td>
            Whether the confirmation email was sent.
        </td>
    </tr>
    <tr>
        <td>completed</td>
        <td>boolean</td>
        <td></td>
        <td></td>
        <td>Read-Only</td>
        <td>
            Whether the registration was completed.
        </td>
    </tr>
    <tr>
        <td>completedPrincipalId</td>
        <td>boolean</td>
        <td></td>
        <td></td>
        <td>Read-Only</td>
        <td>
            The id of the principal that was created as a result of the registration completing.
        </td>
    </tr>
    <tr>
        <td>completedTenantId</td>
        <td>boolean</td>
        <td></td>
        <td></td>
        <td>Read-Only</td>
        <td>
            The id of the tenant that was created as a result of the registration completing.
        </td>
    </tr>
</tbody>

Other Properties

<thead>
    <tr>
        <th>Property</th>
        <th>Type</th>
        <th>Required</th>
        <th>Default</th>
        <th nowrap>Read-Only</th>
        <th>Description</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>signupProperties</td>
        <td>object</td>
        <td></td>
        <td></td>
        <td></td>
        <td>
            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.
        </td>
    </tr>
    <tr>
        <td>active</td>
        <td>boolean</td>
        <td></td>
        <td></td>
        <td></td>
        <td>
            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.
        </td>
    </tr>
</tbody>

Create a Registration

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

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

registration.update();

Delete a Registration

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

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

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

List Registrations

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

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

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

// send confirmation email
registration.sendConfirmationEmail();

Confirm the Registration

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

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

// send welcome email
registration.sendWelcomeEmail();

Example: Tenant Creation with Payment Method

This flow will send all the appropriate emails and create a payment method for the user.

First Step - Kick off the Registration Process

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

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

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

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