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:
- The application collects the user's email
- 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 theemail
configurations that define theconfirmation
andwelcome
emails. - The application plugs in the user's details onto the Registration object. It stores the
userName
anduserDomainId
to identify which domain the final user should be created on. - The registration process sends a confirmation email to the end user.
- The user receives the email and clicks on the link to confirm their identity and intention of registering.
- The application collects any additional information and sets it onto the Registration object.
- 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 thetenantPlanKey
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 namenumber
- the card numberexpirationMonth
- the two digit expiration monthexpirationYear
- 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