PageRenderTime 61ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/node_modules/stormpath/node_modules/stormpath-config/lib/strategy/EnrichIntegrationFromRemoteConfigStrategy.js

https://gitlab.com/DamZou/myMeteoApp
JavaScript | 245 lines | 177 code | 41 blank | 27 comment | 33 complexity | 75826682a08f6d920452c095f878d19f MD5 | raw file
  1. 'use strict';
  2. var async = require('async');
  3. var extend = require('cloneextend').extend;
  4. var strings = require('../strings');
  5. /**
  6. * Retrieves Stormpath settings from the API service, and ensures the local
  7. * configuration object properly reflects these settings.
  8. *
  9. * @class
  10. */
  11. function EnrichIntegrationFromRemoteConfigStrategy (clientFactory) {
  12. this.clientFactory = clientFactory;
  13. }
  14. EnrichIntegrationFromRemoteConfigStrategy.prototype._resolveApplication = function (config, callback) {
  15. var application = config.application;
  16. if (!application || !application.href || !application.getAccountStoreMappings) {
  17. callback(new Error(strings.UNABLE_TO_RESOLVE_APP));
  18. } else {
  19. callback(null, config.application);
  20. }
  21. };
  22. EnrichIntegrationFromRemoteConfigStrategy.prototype._validateAccountStore = function (config, app, callback) {
  23. app.getAccountStoreMappings(function (err, mappings) {
  24. if (err) {
  25. return callback(err);
  26. }
  27. if (mappings.size === 0) {
  28. return callback(new Error(strings.NO_ACCOUNT_STORES_MAPPED));
  29. } else if (config.web.register.enabled && app.defaultAccountStoreMapping === null) {
  30. return callback(new Error(strings.NO_DEFAULT_ACCOUNT_STORE_MAPPED));
  31. }
  32. callback(null, app);
  33. });
  34. };
  35. // Returns the OAuth policy of the Stormpath Application.
  36. EnrichIntegrationFromRemoteConfigStrategy.prototype._enrichWithOAuthPolicy = function (app, callback) {
  37. app.getOAuthPolicy(function(err, policy) {
  38. if (err) {
  39. return callback(err);
  40. }
  41. app.oAuthPolicy = policy;
  42. return callback(null, app);
  43. });
  44. };
  45. // Iterate over all account stores on the given Application, looking for all
  46. // Social providers. We'll then create a config.providers array which we'll
  47. // use later on to dynamically populate all social login configurations ^^
  48. EnrichIntegrationFromRemoteConfigStrategy.prototype._enrichWithSocialProviders = function (config, application, callback) {
  49. application.getAccountStoreMappings(function(err, mappings) {
  50. if (err) {
  51. return callback(err);
  52. }
  53. if (!config.web.social) {
  54. config.web.social = {};
  55. }
  56. mappings.each(function (mapping, next) {
  57. mapping.getAccountStore(function (err, accountStore) {
  58. if (err) {
  59. return next(err);
  60. }
  61. // Iterate directories
  62. if (/\/directories/.test(accountStore.href)) {
  63. accountStore.getProvider(function(err, remoteProvider) {
  64. if (err) {
  65. return next(err);
  66. }
  67. var providerId = remoteProvider.providerId;
  68. // If the provider isn't a Stormpath, AD, or LDAP directory it's a social directory.
  69. if (['stormpath', 'ad', 'ldap'].indexOf(providerId) === -1) {
  70. // Remove unnecessary properties that clutter our config.
  71. delete remoteProvider.href;
  72. delete remoteProvider.createdAt;
  73. delete remoteProvider.updatedAt;
  74. var localProvider = config.web.social[providerId];
  75. if (!localProvider) {
  76. localProvider = config.web.social[providerId] = {};
  77. }
  78. if (!localProvider.uri) {
  79. localProvider.uri = '/callbacks/' + remoteProvider.providerId;
  80. }
  81. extend(remoteProvider, { enabled: true });
  82. extend(localProvider, remoteProvider);
  83. }
  84. next();
  85. });
  86. } else {
  87. next();
  88. }
  89. });
  90. }, function(err) {
  91. callback(err, application);
  92. });
  93. });
  94. };
  95. // Finds and returns an Application's default Account Store (Directory)
  96. // object. If one doesn't exist, nothing will be returned.
  97. EnrichIntegrationFromRemoteConfigStrategy.prototype._resolveDirectoryHref = function (app, callback) {
  98. var outerScope = this;
  99. app.getAccountStoreMappings(function(err, mappings) {
  100. if (err) {
  101. return callback(err);
  102. }
  103. mappings.detect(function(mapping, detectCallback) {
  104. detectCallback(mapping.isDefaultAccountStore);
  105. }, function(defaultMapping) {
  106. if (defaultMapping) {
  107. var href = defaultMapping.accountStore.href;
  108. if (href.match(/directories/)) {
  109. return callback(null, href);
  110. }
  111. if (href.match(/group/)) {
  112. outerScope.client.getGroup(href, function(err, group) {
  113. return callback(err, group && group.directory.href);
  114. });
  115. } else {
  116. return callback(null, null);
  117. }
  118. } else {
  119. return callback(null, null);
  120. }
  121. });
  122. });
  123. };
  124. // Pulls down all of a Directory's configuration settings,
  125. // and applies them to the local configuration.
  126. EnrichIntegrationFromRemoteConfigStrategy.prototype._enrichWithDirectoryPolicies = function (client, config, directoryHref, callback) {
  127. if (!directoryHref) {
  128. return callback(null, null);
  129. }
  130. // Helper method that checks if a status is set to "enabled".
  131. var isEnabled = function (status) {
  132. return status === 'ENABLED';
  133. };
  134. // Returns the callback immediately if there is an error.
  135. // Continues processing if there isn't.
  136. var stopIfError = function (process) {
  137. return function (err, result) {
  138. if (err) {
  139. callback(err);
  140. } else {
  141. process(result);
  142. }
  143. }
  144. };
  145. // Enrich config with with directory policies.
  146. client.getDirectory(directoryHref, { expand: 'passwordPolicy,accountCreationPolicy' }, stopIfError(function (directory) {
  147. var resetEmailStatusEnabled = isEnabled(directory.passwordPolicy.resetEmailStatus);
  148. // Enrich config with account policies.
  149. extend(config, {
  150. web: {
  151. forgotPassword: {
  152. enabled: resetEmailStatusEnabled
  153. },
  154. changePassword: {
  155. enabled: resetEmailStatusEnabled
  156. },
  157. verifyEmail: {
  158. enabled: isEnabled(directory.accountCreationPolicy.verificationEmailStatus)
  159. }
  160. }
  161. });
  162. // Validate that auto login and email verification aren't enabled at the same time.
  163. if (config.web.register.autoLogin && config.web.verifyEmail.enabled) {
  164. return callback(new Error(strings.CONFLICTING_AUTO_LOGIN_AND_EMAIL_VERIFICATION_CONFIG));
  165. }
  166. // Enrich config with password policies.
  167. directory.getPasswordPolicy(stopIfError(function (policy) {
  168. policy.getStrength(stopIfError(function (strength) {
  169. // Remove the href property from the Strength Resource, we don't want
  170. // this to clutter up our nice passwordPolicy configuration
  171. // dictionary!
  172. delete strength.href;
  173. config.passwordPolicy = strength;
  174. callback(null, null);
  175. }));
  176. }));
  177. }));
  178. };
  179. EnrichIntegrationFromRemoteConfigStrategy.prototype.process = function (config, callback) {
  180. var tasks = [];
  181. if (config.skipRemoteConfig) {
  182. return callback(null, config);
  183. }
  184. var client = this.clientFactory(config);
  185. if (config.application && config.application.href) {
  186. tasks = tasks.concat([
  187. this._resolveApplication.bind(this, config),
  188. this._validateAccountStore.bind(this, config),
  189. this._enrichWithOAuthPolicy.bind(this),
  190. this._enrichWithSocialProviders.bind(this, config),
  191. this._resolveDirectoryHref.bind(this),
  192. this._enrichWithDirectoryPolicies.bind(this, client, config)
  193. ]);
  194. }
  195. client.on('error', function (err) {
  196. callback(err);
  197. });
  198. client.on('ready', function () {
  199. async.waterfall(tasks, function (err) {
  200. callback(err, err ? null : config);
  201. });
  202. });
  203. };
  204. module.exports = EnrichIntegrationFromRemoteConfigStrategy;