Embed a Deputy install via iFrame
How to initiate SSO, configure navigation and embed the install
This guide covers how to embed a Deputy embedded account into your app, including how to manage SSO and iFramed navigation.
Before beginning to embed a Deputy account
Ensure the following:
- A Deputy embedded account has been created via the provisioning APIs.
- Third party cookies are enabled (if cookies have been disabled by a user, or the browser accessing your app is Safari / Firefox, iFramed accounts may fail to load.)
Calling APIs on behalf of a created provisioned account
Before you embed a Deputy account into the app, you will need to ensure that you can call the regular Deputy APIs on behalf of the provisioned account.
This is essential for both onboarding users into Deputy, and additionally is a precursor to allowing you to SSO into provisioned accounts.
Some example of use cases in calling APIs on behalf of provisioned customers:
- Calling the Location API to add locations to an account - Locations
- Calling the People API to add users to an account, and change their details. Employees
- Calling our Timesheet API to pull over time and attendance information. - Timesheets
To configure this, you will need to call our access-token endpoint, which will return to you an access token for a specific hostname.
cURL 'https://api.usw2.deputy.com/connect/v1/partner/{partnername}/auth/token'
With the body
{
"hostname": "{install}.{geo}.deputy.com",
"clientId": "{{clientid}}", // your client ID
"clientSecret": "{{clientsecret}}", // your client secret
"redirectUri": "http://localhost/",
"scope": "longlife_refresh_token"
}
Note: The clientID, clientSecret and redirectUri are from the client you have created.
To this request the response would be:
{
"success": true,
"data": {
"accessToken": "{{access_token}}",
"refreshToken": "{{refresh_token}}",
"expiresIn": "86400",
"tokenType": "OAuth"
}
}
Which will include an access token to pass with your API requests. You are able to refresh the token per our guide here.
Mapping Users
After ensuring that you can call the app on behalf of an account, the second step is creating and mapping users in Deputy to accounts within your app. This is necessary to ensure that the correct user is logged into Deputy when they log into your application.
When using our Employee API, you are able to assign a user a unique identifier. This identifier should be a one to one mapping with a user from your application.
cURL --POST 'https://{install}.{geo}.deputy.com/api/management/v2/employees'
{
"data": {
"firstName": "Ed",
"lastName": "Jacobs",
"displayName": "Ed Jacobs",
"otherName": "Eden Jacobs",
"salutation": "Mr.",
"position": "Employee",
"primaryLocation": {
"id": "1"
},
"contact": {
"email1": "[email protected]", // This is the identifier and is mandatory.
"phone1": "0123456789",
"phone2": "0123456788",
"email2": "[email protected]",
"notes": "notes here",
"web": "",
"fax": ""
},
"user":{
"partnerUserId": "{{partnerCode-uniqueId}}"
//This is the identifier that will mark the created user as being partner managed.
}
}
}
Patching Users
You are able to patch users to update their details, including their email address.
cURL --PATCH 'https://{install}.{geo}.deputy.com/api/management/v2/employees'
{
"data": {
"firstName": "Ed",
"lastName": "Jacobs",
"displayName": "Ed Jacobs",
"otherName": "Eden Jacobs",
"salutation": "Mr.",
"position": "Employee",
"primaryLocation": {
"id": "1"
},
"contact": {
"email1": "[email protected]", // Updated email value
"phone1": "0123456789",
"phone2": "0123456788",
"email2": "[email protected]",
"notes": "notes here",
"web": "",
"fax": ""
},
"user":{
"partnerUserId": "{{partnerCode-uniqueId}}" //the same identifier sent when user was created
//This is the identifier that will mark the created user as being partner managed.
}
}
}
NOTE: Remember to always pass in the partnerUserId when patching your users!
NOTE: Updating of a users email should happen immediately. If the user is actively logged in, they will not be signed out or need to re-SSO.
iFraming an account
To iFrame a Deputy install, you will need to use the following URL construct
cURL --GET 'https://once.deputy.com/connect/embed/?provider=[provider]&host=[host]&code=[nonce]'
Where
- Provider is your embedded partner ID, given by Deputy.
- Host is the hostname you are trying to embed.
- Code is a nonce. To sign into a Deputy account of behalf of a user, you will need to generate a nonce for your account that can be passed into the Deputy iFrame. Deputy will use this nonce to retrieve an access token from the partner, and make calls to ensure that the user attempting to login is indeed logged into the partners account. Note: if the Deputy session expires, you will need to create a new nonce to initiate a new session.
If you wish to test in a staging environment, you will need to add an additional parameter of staging=1
. Passing any other value or missing the parameter will default to the partner's production environment.
cURL --GET 'https://once.deputy.com/connect/embed/?provider=[provider]&host=[host]&code=[nonce]&staging=1'
After the user is logged in, the Deputy iFrame will load the home page / dashboard as configured in the navigation.
Navigation
After embedding a Deputy install, the next step will be to configure navigation.
Deputy Embed has no top level navigation of its own, so applications will need to implement their own system to manage switching between the different Deputy components.
Navigation can be managed via postMessage
as an example below :
function navigate (route) {
document.querySelector('iframe#deputy-embed').contentWindow.postMessage({
type: 'partner-navigation',
route
}, 'https://'+hostname+'/');
}
document.querySelector('#me').addEventListener('click', e => navigate('#me'));
document.querySelector('#news-feed').addEventListener('click', e => navigat('#newsfeed'));
document.querySelector('#tasks').addEventListener('click', e => navigate('#tasks'));
document.querySelector('#locations').addEventListener('click', e => navigate ('#locations'));
document.querySelector('#people').addEventListener('click', e => navigate ('#team'));
document.querySelector('#schedule').addEventListener('click', e => navigate ('#roster'));
document.querySelector('#timesheet-approval').addEventListener('click', e => navigate ('#approve'));
document.querySelector('#timesheet-export').addEventListener('click', e => navigate('#export'));
document.querySelector('#reports').addEventListener('click', e => navigate('#report'));
Or alternatively using a third party tool such as framebus.
Opening Business Settings via Deputy Embed
Business settings is the home of all instance settings at Deputy. Through the Business settings modal, a user can configure:
- New leave rules
- Time/date formats
- Schedule settings
For more information on business settings, see the help guide here.
Business settings is usually opened via the the top level user menu in Deputy, which is hidden in Deputy Embed. An example of how to open business settings in the iFrame is as follows:
document.querySelector('#business-settings').addEventListener('click', e => toggleModal('#modal-location-install-config', 'toggle'));
function toggleModal(id, action) {
document.querySelector('iframe#deputy-embed').contentWindow.postMessage({
type: 'toggle-modal',
action,
id
}, 'https://'+hostname+'/');
}
Logging out
You will need to ensure that your users are logged out of their sessions once they are logged out of the partner app.
This can be achieved by calling the logout
endpoint as below :
cURL --POST 'https://{install}.{geo}.deputy.com/login?dologout=true'
Note: If the Deputy sessions gets expired before the Partner session, the user will see the iFrame with the Deputy login screen. To avoid this, at each point that the partner shows Deputy in their App, this login flow should be triggered.
An example of how a logout can be initiated is as follows:
document.querySelector('#logout').addEventListener('click', function () {
var url = 'https://' + hostname + '/login?dologout=true';
// Create a new XMLHttpRequest object
var xhr = new XMLHttpRequest();
// Set up the HTTP request
xhr.open('GET', url, true);
// Set the appropriate headers if needed
// xhr.setRequestHeader('Content-Type', 'application/json');
// Set up a callback function to handle the response
xhr.onload = function () {
if (xhr.status === 200) {
// Request succeeded
console.log('Logout request sent successfully.');
} else {
// Request failed
console.log('Logout request failed.');
}
};
// Send the request
xhr.send();
// reload the iframe with baseurl to handle slow connections
var iframe = document.querySelector('iframe#deputy-embed');
iframe.src = deputyBaseURL;
document.body.appendChild(iframe);
});
Updated about 1 year ago