src/modules/identity-config.js
import IdentityProperty from './identity-property';
import IdentityUser from './identity-user';
/**
* Identity SDK configuration
*
* The way the properties map works is that you specify any IdentityProperty overrides for
* standard properties or a complete IdentityProperty configuration for custom properties.
*
* For a list of standard properties see: {@link IdentityProperty.standardMap}.
*
* @property {string[]} redirectUrls - White list of redirect URLs to accept
* @property {Map<string, IdentityProperty>} properties - Map of user property keys to configurations
* @property {Map<string, string>} [facebook={}] - Facebook config
* @property {Map<string, string>} [google={}] - Google config
* @property {number} sessionTimeout - Session token timeout in seconds, default 1 year
* @property {number} userTimeout - User data cache timeout in seconds, default 1 hour
*/
class IdentityConfig {
/**
* Returns Promise of IdentityConfig from specified server and with specified App key
*
* For each NBC App an IdentityConfig should be stored at: https://id.nbc.com/sdk/config/<key>.json
* Where <key> is the App key, e.g: example => https://id.nbc.com/sdk/config/example.json
*
* For non production environments this URL will change accordingly, e.g. for dev:
* https://dev-id.nbc.com/sdk/config/example.json
*
* @example
* {
* "redirectUrls": [
* "https://id.nbc.com/sdk/example/"
* ],
* "properties": {
* "email": {}, // allow this credential to be used
* "firstName": { // extend config to request and require this whenever a user authenticates
* "request": true,
* "required": true
* },
* "lastName": { // request (but not require) this whenever a user authenticates
* "request": true
* },
* "sponsorOptIn": { // specify a complete configuration for custom properties (e.g: prefixed by app key)
* "label": "I want to get cool stuff from Sponsor",
* "type": "boolean",
* "required": true,
* "default_value": true
* }
* },
* "facebook": {
* "appId": "1234", // use a non standard Facebook App
* "permissions": ["email", "user_friends"] // besides the usual email, also ask for friends
* }
* }
*
* @param {IdentityServer} [options.server] - IdentityServer to get config from
* @param {String} [options.key] - Key of App to get configuration for
* @param {String} [options.configLocationHost] - Custom config host url
* @return {Promise<IdentityConfig, Error>} - Promise of IdentityConfig
*/
static request({
server,
key,
configLocationHost,
}) {
const replaceConfigLocation = configLocationHost ? configLocationHost.replace(/\/?$/, '/') : null;
return server.sdk(`${!replaceConfigLocation ? 'config/' : ''}${key}.json`, replaceConfigLocation).then(
(response) => new IdentityConfig(response),
(error) => {
// Fallback to nbc hosted config
if (configLocationHost) {
window.console.error('configLocationHost property error, falling back to nbc.com hosted config:', error);
return this.request({server, key});
}
},
);
}
/**
* IdentityConfig constructor
*
* @param {string} [defaultPage='signUp'] - The default page to load on init
* @param {string[]} [redirectUrls=[]] - White list of redirect URLs to accept
* @param {Map<string, Object>} [properties={}] - Map of user property keys to configurations
* @param {Map<string, string>} [facebook={}] - Facebook config
* @param {Map<string, string>} [google={}] - Google config
* @param {number} [sessionTimeout=31536000] - Session token timeout in seconds, default 1 year
* @param {number} [userTimeout=3600] - User data cache timeout in seconds, default 1 hour
* @param {Object} [theme={}] - Customizable theme parameters
* @param {Object} [analytics={}] - Analytics settings
* @param {Object} [zeroBounce={}] - ZeroBounce settings
*/
constructor({
defaultPage = 'signUp',
redirectUrls = [],
redirectDelay = 1000,
redirectTimeout = 5000,
logoutRedirectTimeout = 5000,
properties = {},
apple = {},
facebook = {},
google = {},
peacock = {},
sessionTimeout = 31536000,
userTimeout = 3600,
disableSmartLock = false,
theme = {},
analytics = {},
showAttributes = {},
launchdarkly = {},
zeroBounce = {},
}) {
// Validate property config Objects and convert them to IdentityProperty instances
const {credentialKeys} = IdentityProperty;
const {serverKeyMap} = IdentityUser;
const sdkKeys = Object.keys(serverKeyMap);
const serverKeys = Object.values(serverKeyMap);
// Ensure id and revisionId exist in the properties
if (!properties.id) properties.id = {};
if (!properties.revisionId) properties.revisionId = {};
// Ensure Facebook config defaults exist
if (!facebook.appId) facebook.appId = '1692464401052790';
if (!facebook.permissions) facebook.permissions = ['public_profile', 'email'];
if (!facebook.version) facebook.version = 'v3.1';
Object.entries(properties).forEach(([key, property = {}]) => {
if (credentialKeys.includes(key)) {
if (Object.keys(property).length > 0) {
throw new Error(`Credential properties can not be configured in IdentityConfig`);
}
}
const serverKeyIndex = serverKeys.indexOf(key);
if (serverKeyIndex >= 0) {
throw new Error(`Illegal property key in IdentityConfig: "${key}", use "${sdkKeys[serverKeyIndex]}" instead`);
}
properties[key] = new IdentityProperty({
...IdentityProperty.standardMap[key], // use standard property as base (if any)
...property, // extend with property config
});
});
Object.assign(this, {
defaultPage,
redirectUrls,
redirectDelay,
redirectTimeout,
logoutRedirectTimeout,
properties,
apple,
facebook,
google,
peacock,
sessionTimeout,
userTimeout,
disableSmartLock,
theme,
analytics,
showAttributes,
launchdarkly,
zeroBounce,
});
// Disable property modification
Object.freeze(this);
}
}
export default IdentityConfig;