auth0-deploy-cli 7.5.1 → 7.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.eslintrc +7 -41
  2. package/.husky/pre-commit +4 -0
  3. package/.husky/pre-push +3 -1
  4. package/.prettierignore +10 -0
  5. package/.prettierrc.json +4 -0
  6. package/CHANGELOG.md +209 -7
  7. package/CONTRIBUTING.md +2 -2
  8. package/README.md +3 -0
  9. package/lib/args.js +16 -17
  10. package/lib/commands/export.js +3 -3
  11. package/lib/commands/import.js +7 -6
  12. package/lib/commands/index.js +1 -1
  13. package/lib/configFactory.js +5 -1
  14. package/lib/context/defaults.js +4 -3
  15. package/lib/context/directory/handlers/actions.js +6 -5
  16. package/lib/context/directory/handlers/attackProtection.js +7 -6
  17. package/lib/context/directory/handlers/branding.js +60 -0
  18. package/lib/context/directory/handlers/clientGrants.js +6 -4
  19. package/lib/context/directory/handlers/clients.js +4 -3
  20. package/lib/context/directory/handlers/connections.js +7 -4
  21. package/lib/context/directory/handlers/databases.js +30 -22
  22. package/lib/context/directory/handlers/emailProvider.js +6 -4
  23. package/lib/context/directory/handlers/emailTemplates.js +13 -11
  24. package/lib/context/directory/handlers/guardianFactorProviders.js +6 -4
  25. package/lib/context/directory/handlers/guardianFactorTemplates.js +6 -4
  26. package/lib/context/directory/handlers/guardianFactors.js +6 -4
  27. package/lib/context/directory/handlers/guardianPhoneFactorMessageTypes.js +4 -3
  28. package/lib/context/directory/handlers/guardianPhoneFactorSelectedProvider.js +4 -3
  29. package/lib/context/directory/handlers/guardianPolicies.js +4 -3
  30. package/lib/context/directory/handlers/hooks.js +5 -4
  31. package/lib/context/directory/handlers/index.js +5 -2
  32. package/lib/context/directory/handlers/migrations.js +8 -8
  33. package/lib/context/directory/handlers/organizations.js +4 -3
  34. package/lib/context/directory/handlers/pages.js +20 -20
  35. package/lib/context/directory/handlers/resourceServers.js +6 -4
  36. package/lib/context/directory/handlers/roles.js +4 -3
  37. package/lib/context/directory/handlers/rules.js +5 -4
  38. package/lib/context/directory/handlers/rulesConfigs.js +7 -5
  39. package/lib/context/directory/handlers/tenant.js +7 -4
  40. package/lib/context/directory/handlers/triggers.js +3 -2
  41. package/lib/context/directory/index.js +23 -22
  42. package/lib/context/index.js +66 -62
  43. package/lib/context/yaml/handlers/actions.js +12 -8
  44. package/lib/context/yaml/handlers/attackProtection.js +6 -12
  45. package/lib/context/yaml/handlers/branding.js +66 -0
  46. package/lib/context/yaml/handlers/clientGrants.js +5 -4
  47. package/lib/context/yaml/handlers/clients.js +9 -6
  48. package/lib/context/yaml/handlers/connections.js +10 -7
  49. package/lib/context/yaml/handlers/databases.js +15 -10
  50. package/lib/context/yaml/handlers/emailProvider.js +7 -5
  51. package/lib/context/yaml/handlers/emailTemplates.js +6 -5
  52. package/lib/context/yaml/handlers/guardianFactorProviders.js +6 -13
  53. package/lib/context/yaml/handlers/guardianFactorTemplates.js +6 -13
  54. package/lib/context/yaml/handlers/guardianFactors.js +6 -13
  55. package/lib/context/yaml/handlers/guardianPhoneFactorMessageTypes.js +6 -13
  56. package/lib/context/yaml/handlers/guardianPhoneFactorSelectedProvider.js +6 -13
  57. package/lib/context/yaml/handlers/guardianPolicies.js +6 -13
  58. package/lib/context/yaml/handlers/hooks.js +7 -5
  59. package/lib/context/yaml/handlers/index.js +5 -2
  60. package/lib/context/yaml/handlers/migrations.js +3 -2
  61. package/lib/context/yaml/handlers/organizations.js +6 -5
  62. package/lib/context/yaml/handlers/pages.js +6 -5
  63. package/lib/context/yaml/handlers/resourceServers.js +5 -4
  64. package/lib/context/yaml/handlers/roles.js +6 -5
  65. package/lib/context/yaml/handlers/rules.js +6 -5
  66. package/lib/context/yaml/handlers/rulesConfigs.js +6 -5
  67. package/lib/context/yaml/handlers/tenant.js +7 -5
  68. package/lib/context/yaml/handlers/triggers.js +5 -4
  69. package/lib/context/yaml/index.js +33 -24
  70. package/lib/index.js +20 -15
  71. package/lib/logger.js +4 -3
  72. package/lib/readonly.js +11 -16
  73. package/lib/sessionDurationsToMinutes.js +15 -0
  74. package/lib/tools/auth0/client.js +6 -6
  75. package/lib/tools/auth0/handlers/actions.js +21 -23
  76. package/lib/tools/auth0/handlers/attackProtection.js +14 -17
  77. package/lib/tools/auth0/handlers/branding.js +71 -13
  78. package/lib/tools/auth0/handlers/clientGrants.js +17 -10
  79. package/lib/tools/auth0/handlers/clients.js +15 -8
  80. package/lib/tools/auth0/handlers/connections.js +30 -10
  81. package/lib/tools/auth0/handlers/databases.js +24 -12
  82. package/lib/tools/auth0/handlers/default.js +47 -29
  83. package/lib/tools/auth0/handlers/emailTemplates.js +8 -10
  84. package/lib/tools/auth0/handlers/guardianFactorProviders.js +3 -3
  85. package/lib/tools/auth0/handlers/guardianFactorTemplates.js +3 -3
  86. package/lib/tools/auth0/handlers/guardianFactors.js +3 -3
  87. package/lib/tools/auth0/handlers/guardianPhoneFactorMessageTypes.js +11 -10
  88. package/lib/tools/auth0/handlers/guardianPhoneFactorSelectedProvider.js +10 -9
  89. package/lib/tools/auth0/handlers/guardianPolicies.js +5 -4
  90. package/lib/tools/auth0/handlers/hooks.js +34 -21
  91. package/lib/tools/auth0/handlers/index.js +31 -27
  92. package/lib/tools/auth0/handlers/migrations.js +2 -1
  93. package/lib/tools/auth0/handlers/organizations.js +67 -32
  94. package/lib/tools/auth0/handlers/pages.js +20 -14
  95. package/lib/tools/auth0/handlers/prompts.js +1 -0
  96. package/lib/tools/auth0/handlers/resourceServers.js +28 -15
  97. package/lib/tools/auth0/handlers/roles.js +61 -32
  98. package/lib/tools/auth0/handlers/rules.js +55 -32
  99. package/lib/tools/auth0/handlers/rulesConfigs.js +12 -6
  100. package/lib/tools/auth0/handlers/tenant.js +8 -4
  101. package/lib/tools/auth0/handlers/triggers.js +11 -12
  102. package/lib/tools/auth0/index.js +15 -31
  103. package/lib/tools/auth0/schema.js +7 -27
  104. package/lib/tools/calculateChanges.js +149 -0
  105. package/lib/tools/constants.js +162 -154
  106. package/lib/tools/deploy.js +1 -1
  107. package/lib/tools/index.js +1 -1
  108. package/lib/tools/logger.js +14 -8
  109. package/lib/tools/utils.js +3 -144
  110. package/lib/tools/{ValidationError.js → validationError.js} +3 -1
  111. package/lib/types.js +2 -0
  112. package/lib/utils.js +12 -22
  113. package/package.json +9 -2
  114. package/tsconfig.json +2 -3
  115. package/typescript-migration-progress.sh +1 -1
@@ -18,16 +18,16 @@ exports.schema = {
18
18
  type: 'object',
19
19
  properties: {
20
20
  breachedPasswordDetection: {
21
- type: 'object'
21
+ type: 'object',
22
22
  },
23
23
  bruteForceProtection: {
24
- type: 'object'
24
+ type: 'object',
25
25
  },
26
26
  suspiciousIpThrottling: {
27
- type: 'object'
28
- }
27
+ type: 'object',
28
+ },
29
29
  },
30
- additionalProperties: false
30
+ additionalProperties: false,
31
31
  };
32
32
  class AttackProtectionHandler extends default_1.default {
33
33
  constructor(config) {
@@ -36,14 +36,14 @@ class AttackProtectionHandler extends default_1.default {
36
36
  objString(item) {
37
37
  return super.objString({
38
38
  'breached-password-protection': {
39
- enabled: item.breachedPasswordDetection.enabled
39
+ enabled: item.breachedPasswordDetection.enabled,
40
40
  },
41
41
  'brute-force-protection': {
42
- enabled: item.bruteForceProtection.enabled
42
+ enabled: item.bruteForceProtection.enabled,
43
43
  },
44
44
  'suspicious-ip-throttling': {
45
- enabled: item.suspiciousIpThrottling.enabled
46
- }
45
+ enabled: item.suspiciousIpThrottling.enabled,
46
+ },
47
47
  });
48
48
  }
49
49
  getType() {
@@ -54,12 +54,12 @@ class AttackProtectionHandler extends default_1.default {
54
54
  const [breachedPasswordDetection, bruteForceProtection, suspiciousIpThrottling] = yield Promise.all([
55
55
  this.client.attackProtection.getBreachedPasswordDetectionConfig(),
56
56
  this.client.attackProtection.getBruteForceConfig(),
57
- this.client.attackProtection.getSuspiciousIpThrottlingConfig()
57
+ this.client.attackProtection.getSuspiciousIpThrottlingConfig(),
58
58
  ]);
59
59
  this.existing = {
60
60
  breachedPasswordDetection,
61
61
  bruteForceProtection,
62
- suspiciousIpThrottling
62
+ suspiciousIpThrottling,
63
63
  };
64
64
  return this.existing;
65
65
  });
@@ -71,12 +71,9 @@ class AttackProtectionHandler extends default_1.default {
71
71
  return;
72
72
  }
73
73
  Promise.all([
74
- this.client.attackProtection
75
- .updateBreachedPasswordDetectionConfig({}, attackProtection.breachedPasswordDetection),
76
- this.client.attackProtection
77
- .updateSuspiciousIpThrottlingConfig({}, attackProtection.suspiciousIpThrottling),
78
- this.client.attackProtection
79
- .updateBruteForceConfig({}, attackProtection.bruteForceProtection)
74
+ this.client.attackProtection.updateBreachedPasswordDetectionConfig({}, attackProtection.breachedPasswordDetection),
75
+ this.client.attackProtection.updateSuspiciousIpThrottlingConfig({}, attackProtection.suspiciousIpThrottling),
76
+ this.client.attackProtection.updateBruteForceConfig({}, attackProtection.bruteForceProtection),
80
77
  ]);
81
78
  this.updated += 1;
82
79
  this.didUpdate(attackProtection);
@@ -14,25 +14,59 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.schema = void 0;
16
16
  const default_1 = __importDefault(require("./default"));
17
- exports.schema = { type: 'object' };
17
+ const constants_1 = __importDefault(require("../../constants"));
18
+ const logger_1 = __importDefault(require("../../../logger"));
19
+ exports.schema = {
20
+ type: 'object',
21
+ properties: {
22
+ templates: {
23
+ type: 'array',
24
+ items: {
25
+ type: 'object',
26
+ properties: {
27
+ template: { type: 'string' },
28
+ body: { type: 'string' },
29
+ },
30
+ },
31
+ },
32
+ },
33
+ };
18
34
  class BrandingHandler extends default_1.default {
19
35
  constructor(options) {
20
36
  super(Object.assign(Object.assign({}, options), { type: 'branding' }));
21
37
  }
22
38
  getType() {
23
39
  return __awaiter(this, void 0, void 0, function* () {
24
- // in case client version does not support branding
25
- if (!this.client.branding || typeof this.client.branding.getSettings !== 'function') {
26
- return {};
27
- }
40
+ let branding = {};
28
41
  try {
29
- return yield this.client.branding.getSettings();
42
+ // in case client version does not support branding
43
+ if (this.client.branding && typeof this.client.branding.getSettings === 'function') {
44
+ branding = yield this.client.branding.getSettings();
45
+ }
46
+ // in case client version does not custom domains
47
+ if (this.client.customDomains && typeof this.client.customDomains.getAll === 'function') {
48
+ const customDomains = yield this.client.customDomains.getAll();
49
+ // templates are only supported if there's custom domains.
50
+ if (customDomains && customDomains.length) {
51
+ const payload = yield this.client.branding.getUniversalLoginTemplate();
52
+ branding.templates = [
53
+ {
54
+ template: constants_1.default.UNIVERSAL_LOGIN_TEMPLATE,
55
+ body: payload.body,
56
+ },
57
+ ];
58
+ }
59
+ }
60
+ return branding;
30
61
  }
31
62
  catch (err) {
63
+ logger_1.default.debug(`Error calling branding API, ${err.message}, status code: ${err.statusCode}`);
64
+ if (err.statusCode === 403)
65
+ return branding;
32
66
  if (err.statusCode === 404)
33
- return {};
67
+ return branding;
34
68
  if (err.statusCode === 501)
35
- return {};
69
+ return branding;
36
70
  throw err;
37
71
  }
38
72
  });
@@ -40,12 +74,36 @@ class BrandingHandler extends default_1.default {
40
74
  processChanges(assets) {
41
75
  return __awaiter(this, void 0, void 0, function* () {
42
76
  const { branding } = assets;
43
- // Do nothing if not set
44
- if (!branding || !Object.keys(branding).length)
77
+ // quit early if there's no branding to process.
78
+ if (!branding)
45
79
  return;
46
- yield this.client.branding.updateSettings({}, branding);
47
- this.updated += 1;
48
- this.didUpdate(branding);
80
+ // remove templates, we only want top level branding settings for this API call
81
+ const brandingSettings = Object.assign({}, branding);
82
+ delete brandingSettings.templates;
83
+ // Do nothing if not set
84
+ if (brandingSettings && Object.keys(brandingSettings).length) {
85
+ yield this.client.branding.updateSettings({}, brandingSettings);
86
+ this.updated += 1;
87
+ this.didUpdate(brandingSettings);
88
+ }
89
+ // handle templates
90
+ if (branding.templates && branding.templates.length) {
91
+ const unknownTemplates = branding.templates
92
+ .filter((t) => !constants_1.default.SUPPORTED_BRANDING_TEMPLATES.includes(t.template))
93
+ .map((t) => t.template);
94
+ if (unknownTemplates.length) {
95
+ // throw a helpful warning for unknown templates, the context handlers are unaware of which are supported, that's all handled here.
96
+ logger_1.default.warn(`Found unknown branding template(s): ${unknownTemplates
97
+ .join()
98
+ .toString()}. Supported branding templates are: ${constants_1.default.SUPPORTED_BRANDING_TEMPLATES.join()}.`);
99
+ }
100
+ const templateDefinition = branding.templates.find((t) => t.template === constants_1.default.UNIVERSAL_LOGIN_TEMPLATE);
101
+ if (templateDefinition && templateDefinition.body) {
102
+ yield this.client.branding.setUniversalLoginTemplate({}, { template: templateDefinition.body });
103
+ this.updated += 1;
104
+ this.didUpdate(branding.templates);
105
+ }
106
+ }
49
107
  });
50
108
  }
51
109
  }
@@ -51,15 +51,17 @@ exports.schema = {
51
51
  scope: {
52
52
  type: 'array',
53
53
  items: { type: 'string' },
54
- uniqueItems: true
55
- }
54
+ uniqueItems: true,
55
+ },
56
56
  },
57
- required: ['client_id', 'scope', 'audience']
58
- }
57
+ required: ['client_id', 'scope', 'audience'],
58
+ },
59
59
  };
60
- class ClientHandler extends default_1.default {
60
+ class ClientGrantsHandler extends default_1.default {
61
61
  constructor(config) {
62
- super(Object.assign(Object.assign({}, config), { type: 'clientGrants', id: 'id', identifiers: ['id', ['client_id', 'audience']], stripUpdateFields: ['audience', 'client_id'] }));
62
+ super(Object.assign(Object.assign({}, config), { type: 'clientGrants', id: 'id',
63
+ //@ts-ignore because not sure why two-dimensional array passed in
64
+ identifiers: ['id', ['client_id', 'audience']], stripUpdateFields: ['audience', 'client_id'] }));
63
65
  }
64
66
  objString(item) {
65
67
  return super.objString({ id: item.id, client_id: item.client_id, audience: item.audience });
@@ -103,15 +105,20 @@ class ClientHandler extends default_1.default {
103
105
  const { del, update, create, conflicts } = yield this.calcChanges(Object.assign(Object.assign({}, assets), { clientGrants: formatted }));
104
106
  const filterGrants = (list) => {
105
107
  if (excludedClients.length) {
106
- return list.filter((item) => item.client_id !== currentClient && ![...excludedClientsByNames, ...excludedClients].includes(item.client_id));
108
+ return list.filter((item) => item.client_id !== currentClient &&
109
+ ![...excludedClientsByNames, ...excludedClients].includes(item.client_id));
107
110
  }
108
111
  return list.filter((item) => item.client_id !== currentClient);
109
112
  };
110
113
  const changes = {
114
+ //@ts-ignore because this expects `client_id` and that's not yet typed on Asset
111
115
  del: filterGrants(del),
116
+ //@ts-ignore because this expects `client_id` and that's not yet typed on Asset
112
117
  update: filterGrants(update),
118
+ //@ts-ignore because this expects `client_id` and that's not yet typed on Asset
113
119
  create: filterGrants(create),
114
- conflicts: filterGrants(conflicts)
120
+ //@ts-ignore because this expects `client_id` and that's not yet typed on Asset
121
+ conflicts: filterGrants(conflicts),
115
122
  };
116
123
  yield _super.processChanges.call(this, assets, Object.assign({}, changes));
117
124
  });
@@ -119,5 +126,5 @@ class ClientHandler extends default_1.default {
119
126
  }
120
127
  __decorate([
121
128
  (0, default_1.order)('60')
122
- ], ClientHandler.prototype, "processChanges", null);
123
- exports.default = ClientHandler;
129
+ ], ClientGrantsHandler.prototype, "processChanges", null);
130
+ exports.default = ClientGrantsHandler;
@@ -19,16 +19,20 @@ exports.schema = {
19
19
  items: {
20
20
  type: 'object',
21
21
  properties: {
22
- name: { type: 'string', minLength: 1, pattern: '[^<>]+' }
22
+ name: { type: 'string', minLength: 1, pattern: '[^<>]+' },
23
23
  },
24
- required: ['name']
25
- }
24
+ required: ['name'],
25
+ },
26
26
  };
27
27
  class ClientHandler extends default_1.default {
28
28
  constructor(config) {
29
29
  super(Object.assign(Object.assign({}, config), { type: 'clients', id: 'client_id', identifiers: ['client_id', 'name'], objectFields: ['client_metadata'], stripUpdateFields: [
30
30
  // Fields not allowed during updates
31
- 'callback_url_template', 'signing_keys', 'global', 'tenant', 'jwt_configuration.secret_encoded'
31
+ 'callback_url_template',
32
+ 'signing_keys',
33
+ 'global',
34
+ 'tenant',
35
+ 'jwt_configuration.secret_encoded',
32
36
  ] }));
33
37
  }
34
38
  objString(item) {
@@ -58,17 +62,20 @@ class ClientHandler extends default_1.default {
58
62
  del: filterClients(del),
59
63
  update: filterClients(update),
60
64
  create: filterClients(create),
61
- conflicts: filterClients(conflicts)
65
+ conflicts: filterClients(conflicts),
62
66
  };
63
67
  yield _super.processChanges.call(this, assets, Object.assign({}, changes));
64
68
  });
65
69
  }
66
70
  getType() {
67
71
  return __awaiter(this, void 0, void 0, function* () {
68
- if (this.existing) {
72
+ if (this.existing)
69
73
  return this.existing;
70
- }
71
- this.existing = yield this.client.clients.getAll({ paginate: true, include_totals: true, is_global: false });
74
+ this.existing = yield this.client.clients.getAll({
75
+ paginate: true,
76
+ include_totals: true,
77
+ is_global: false,
78
+ });
72
79
  return this.existing;
73
80
  });
74
81
  }
@@ -56,19 +56,20 @@ exports.schema = {
56
56
  options: { type: 'object' },
57
57
  enabled_clients: { type: 'array', items: { type: 'string' } },
58
58
  realms: { type: 'array', items: { type: 'string' } },
59
- metadata: { type: 'object' }
59
+ metadata: { type: 'object' },
60
60
  },
61
- required: ['name', 'strategy']
62
- }
61
+ required: ['name', 'strategy'],
62
+ },
63
63
  };
64
64
  // addExcludedConnectionPropertiesToChanges superimposes excluded properties on the `options` object. The Auth0 API
65
65
  // will overwrite the options property when updating connections, so it is necessary to add excluded properties back in to prevent those excluded properties from being deleted.
66
66
  // This use case is common because organizations may not want to expose sensitive connection details, but want to preserve them in the tenant.
67
67
  // exported only for unit testing purposes
68
- const addExcludedConnectionPropertiesToChanges = ({ proposedChanges, existingConnections, config }) => {
68
+ const addExcludedConnectionPropertiesToChanges = ({ proposedChanges, existingConnections, config, }) => {
69
69
  var _a, _b;
70
70
  if (proposedChanges.update.length === 0)
71
71
  return proposedChanges;
72
+ //@ts-ignore because this expects a parameter to be passed
72
73
  const excludedFields = ((_b = (_a = config()) === null || _a === void 0 ? void 0 : _a.EXCLUDED_PROPS) === null || _b === void 0 ? void 0 : _b.connections) || [];
73
74
  if (excludedFields.length === 0)
74
75
  return proposedChanges;
@@ -84,7 +85,9 @@ const addExcludedConnectionPropertiesToChanges = ({ proposedChanges, existingCon
84
85
  const currentExcludedFieldValue = dot_prop_1.default.get(currConnection, excludedField);
85
86
  dot_prop_1.default.set(agg, excludedField, currentExcludedFieldValue);
86
87
  return agg;
87
- }, {});
88
+ }, {
89
+ options: {},
90
+ });
88
91
  return Object.assign(Object.assign({}, proposedConnection), { options: Object.assign(Object.assign({}, proposedConnection.options), currentExcludedPropertyValues.options) });
89
92
  });
90
93
  return Object.assign(Object.assign({}, proposedChanges), { update: newProposedUpdates });
@@ -100,7 +103,7 @@ class ConnectionsHandler extends default_1.default {
100
103
  getFormattedOptions(connection, clients) {
101
104
  try {
102
105
  return {
103
- options: Object.assign(Object.assign({}, connection.options), { idpinitiated: Object.assign(Object.assign({}, connection.options.idpinitiated), { client_id: (0, utils_1.convertClientNameToId)(connection.options.idpinitiated.client_id, clients) }) })
106
+ options: Object.assign(Object.assign({}, connection.options), { idpinitiated: Object.assign(Object.assign({}, connection.options.idpinitiated), { client_id: (0, utils_1.convertClientNameToId)(connection.options.idpinitiated.client_id, clients) }) }),
104
107
  };
105
108
  }
106
109
  catch (e) {
@@ -111,9 +114,14 @@ class ConnectionsHandler extends default_1.default {
111
114
  return __awaiter(this, void 0, void 0, function* () {
112
115
  if (this.existing)
113
116
  return this.existing;
114
- const connections = yield this.client.connections.getAll({ paginate: true, include_totals: true });
117
+ const connections = yield this.client.connections.getAll({
118
+ paginate: true,
119
+ include_totals: true,
120
+ });
115
121
  // Filter out database connections
116
122
  this.existing = connections.filter((c) => c.strategy !== 'auth0');
123
+ if (this.existing === null)
124
+ return [];
117
125
  return this.existing;
118
126
  });
119
127
  }
@@ -125,13 +133,25 @@ class ConnectionsHandler extends default_1.default {
125
133
  const { connections } = assets;
126
134
  // Do nothing if not set
127
135
  if (!connections)
128
- return {};
136
+ return {
137
+ del: [],
138
+ create: [],
139
+ update: [],
140
+ conflicts: [],
141
+ };
129
142
  // Convert enabled_clients by name to the id
130
143
  const clients = yield this.client.clients.getAll({ paginate: true, include_totals: true });
131
- const existingConnections = yield this.client.connections.getAll({ paginate: true, include_totals: true });
144
+ const existingConnections = yield this.client.connections.getAll({
145
+ paginate: true,
146
+ include_totals: true,
147
+ });
132
148
  const formatted = assets.connections.map((connection) => (Object.assign(Object.assign(Object.assign({}, connection), this.getFormattedOptions(connection, clients)), { enabled_clients: (0, utils_1.getEnabledClients)(assets, connection, existingConnections, clients) })));
133
149
  const proposedChanges = yield _super.calcChanges.call(this, Object.assign(Object.assign({}, assets), { connections: formatted }));
134
- const proposedChangesWithExcludedProperties = (0, exports.addExcludedConnectionPropertiesToChanges)({ proposedChanges, existingConnections, config: this.config });
150
+ const proposedChangesWithExcludedProperties = (0, exports.addExcludedConnectionPropertiesToChanges)({
151
+ proposedChanges,
152
+ existingConnections,
153
+ config: this.config,
154
+ });
135
155
  return proposedChangesWithExcludedProperties;
136
156
  });
137
157
  }
@@ -57,13 +57,13 @@ exports.schema = {
57
57
  properties: {
58
58
  customScripts: {
59
59
  type: 'object',
60
- properties: Object.assign({}, constants_1.default.DATABASE_SCRIPTS.reduce((o, script) => (Object.assign(Object.assign({}, o), { [script]: { type: 'string' } })), {}))
61
- }
62
- }
63
- }
60
+ properties: Object.assign({}, constants_1.default.DATABASE_SCRIPTS.reduce((o, script) => (Object.assign(Object.assign({}, o), { [script]: { type: 'string' } })), {})),
61
+ },
62
+ },
63
+ },
64
64
  },
65
- required: ['name']
66
- }
65
+ required: ['name'],
66
+ },
67
67
  };
68
68
  class DatabaseHandler extends default_1.default {
69
69
  constructor(config) {
@@ -75,9 +75,8 @@ class DatabaseHandler extends default_1.default {
75
75
  getClientFN(fn) {
76
76
  // Override this as a database is actually a connection but we are treating them as a different object
77
77
  // If we going to update database, we need to get current options first
78
- if (fn === this.functions.update) {
79
- return (params, payload) => this.client.connections.get(params)
80
- .then((connection) => {
78
+ if (fn === 'update') {
79
+ return (params, payload) => this.client.connections.get(params).then((connection) => {
81
80
  payload.options = Object.assign(Object.assign({}, connection.options), payload.options);
82
81
  return this.client.connections.update(params, payload);
83
82
  });
@@ -88,7 +87,11 @@ class DatabaseHandler extends default_1.default {
88
87
  return __awaiter(this, void 0, void 0, function* () {
89
88
  if (this.existing)
90
89
  return this.existing;
91
- this.existing = this.client.connections.getAll({ strategy: 'auth0', paginate: true, include_totals: true });
90
+ this.existing = this.client.connections.getAll({
91
+ strategy: 'auth0',
92
+ paginate: true,
93
+ include_totals: true,
94
+ });
92
95
  return this.existing;
93
96
  });
94
97
  }
@@ -100,10 +103,19 @@ class DatabaseHandler extends default_1.default {
100
103
  const { databases } = assets;
101
104
  // Do nothing if not set
102
105
  if (!databases)
103
- return {};
106
+ return {
107
+ del: [],
108
+ create: [],
109
+ update: [],
110
+ conflicts: [],
111
+ };
104
112
  // Convert enabled_clients by name to the id
105
113
  const clients = yield this.client.clients.getAll({ paginate: true, include_totals: true });
106
- const existingDatabasesConecctions = yield this.client.connections.getAll({ strategy: 'auth0', paginate: true, include_totals: true });
114
+ const existingDatabasesConecctions = yield this.client.connections.getAll({
115
+ strategy: 'auth0',
116
+ paginate: true,
117
+ include_totals: true,
118
+ });
107
119
  const formatted = databases.map((db) => {
108
120
  if (db.enabled_clients) {
109
121
  return Object.assign(Object.assign({}, db), { enabled_clients: (0, utils_1.getEnabledClients)(assets, db, existingDatabasesConecctions, clients) });
@@ -13,9 +13,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.order = void 0;
16
- const ValidationError_1 = __importDefault(require("../../ValidationError"));
16
+ const validationError_1 = __importDefault(require("../../validationError"));
17
17
  const logger_1 = __importDefault(require("../../logger"));
18
18
  const utils_1 = require("../../utils");
19
+ const calculateChanges_1 = require("../../calculateChanges");
19
20
  function order(value) {
20
21
  return function decorator(t, n, descriptor) {
21
22
  descriptor.value.order = value; // eslint-disable-line
@@ -23,7 +24,7 @@ function order(value) {
23
24
  };
24
25
  }
25
26
  exports.order = order;
26
- class DefaultHandler {
27
+ class APIHandler {
27
28
  constructor(options) {
28
29
  this.config = options.config;
29
30
  this.type = options.type;
@@ -32,11 +33,8 @@ class DefaultHandler {
32
33
  this.existing = null;
33
34
  this.identifiers = options.identifiers || ['id', 'name'];
34
35
  this.objectFields = options.objectFields || [];
35
- this.stripUpdateFields = [
36
- ...options.stripUpdateFields || [],
37
- this.id
38
- ];
39
- this.functions = Object.assign({ getAll: 'getAll', create: 'create', update: 'update', delete: 'delete' }, options.functions || {});
36
+ this.stripUpdateFields = [...(options.stripUpdateFields || []), this.id];
37
+ this.functions = Object.assign({ getAll: 'getAll', create: 'create', delete: 'delete', update: 'update' }, (options.functions || {}));
40
38
  this.updated = 0;
41
39
  this.created = 0;
42
40
  this.deleted = 0;
@@ -79,10 +77,21 @@ class DefaultHandler {
79
77
  const typeAssets = assets[this.type];
80
78
  // Do nothing if not set
81
79
  if (!typeAssets)
82
- return {};
80
+ return {
81
+ del: [],
82
+ create: [],
83
+ conflicts: [],
84
+ update: [],
85
+ };
83
86
  const existing = yield this.getType();
84
87
  // Figure out what needs to be updated vs created
85
- return (0, utils_1.calcChanges)(this, typeAssets, existing, this.identifiers);
88
+ return (0, calculateChanges_1.calculateChanges)({
89
+ handler: this,
90
+ assets: typeAssets,
91
+ //@ts-ignore TODO: investigate what happens when `existing` is null
92
+ existing,
93
+ identifiers: this.identifiers,
94
+ });
86
95
  });
87
96
  }
88
97
  validate(assets) {
@@ -96,7 +105,7 @@ class DefaultHandler {
96
105
  const duplicateNames = (0, utils_1.duplicateItems)(typeAssets, 'name');
97
106
  if (duplicateNames.length > 0) {
98
107
  const formatted = duplicateNames.map((dups) => dups.map((d) => `${d.name}`));
99
- throw new ValidationError_1.default(`There are multiple ${this.type} with the same name combinations
108
+ throw new validationError_1.default(`There are multiple ${this.type} with the same name combinations
100
109
  ${(0, utils_1.dumpJSON)(formatted)}.
101
110
  Names must be unique.`);
102
111
  }
@@ -104,7 +113,7 @@ class DefaultHandler {
104
113
  const duplicateIDs = (0, utils_1.duplicateItems)(typeAssets, this.id);
105
114
  if (duplicateIDs.length > 0) {
106
115
  const formatted = duplicateIDs.map((dups) => dups.map((d) => `${d[this.id]}`));
107
- throw new ValidationError_1.default(`There are multiple ${this.type} for the following stage-order combinations
116
+ throw new validationError_1.default(`There are multiple ${this.type} for the following stage-order combinations
108
117
  ${(0, utils_1.dumpJSON)(formatted)}.
109
118
  Only one rule must be defined for the same order number in a stage.`);
110
119
  }
@@ -123,7 +132,8 @@ class DefaultHandler {
123
132
  // Process Deleted
124
133
  if (del.length > 0) {
125
134
  const allowDelete = this.config('AUTH0_ALLOW_DELETE') === 'true' || this.config('AUTH0_ALLOW_DELETE') === true;
126
- const byExtension = this.config('EXTENSION_SECRET') && (this.type === 'rules' || this.type === 'resourceServers');
135
+ const byExtension = this.config('EXTENSION_SECRET') &&
136
+ (this.type === 'rules' || this.type === 'resourceServers');
127
137
  const shouldDelete = allowDelete || byExtension;
128
138
  if (!shouldDelete) {
129
139
  logger_1.default.warn(`Detected the following ${this.type} should be deleted. Doing so may be destructive.\nYou can enable deletes by setting 'AUTH0_ALLOW_DELETE' to true in the config
@@ -131,10 +141,11 @@ class DefaultHandler {
131
141
  `);
132
142
  }
133
143
  else {
134
- yield this.client.pool.addEachTask({
144
+ yield this.client.pool
145
+ .addEachTask({
135
146
  data: del || [],
136
147
  generator: (delItem) => {
137
- const delFunction = this.getClientFN(this.functions.delete);
148
+ const delFunction = this.getClientFN('delete');
138
149
  return delFunction({ [this.id]: delItem[this.id] })
139
150
  .then(() => {
140
151
  this.didDelete(delItem);
@@ -143,15 +154,17 @@ class DefaultHandler {
143
154
  .catch((err) => {
144
155
  throw new Error(`Problem deleting ${this.type} ${this.objString(delItem)}\n${err}`);
145
156
  });
146
- }
147
- }).promise();
157
+ },
158
+ })
159
+ .promise();
148
160
  }
149
161
  }
150
162
  // Process Renaming Entries Temp due to conflicts in names
151
- yield this.client.pool.addEachTask({
163
+ yield this.client.pool
164
+ .addEachTask({
152
165
  data: conflicts || [],
153
166
  generator: (updateItem) => {
154
- const updateFN = this.getClientFN(this.functions.update);
167
+ const updateFN = this.getClientFN('update');
155
168
  const params = { [this.id]: updateItem[this.id] };
156
169
  const payload = (0, utils_1.stripFields)(Object.assign({}, updateItem), this.stripUpdateFields);
157
170
  return updateFN(params, payload)
@@ -159,13 +172,15 @@ class DefaultHandler {
159
172
  .catch((err) => {
160
173
  throw new Error(`Problem updating ${this.type} ${this.objString(updateItem)}\n${err}`);
161
174
  });
162
- }
163
- }).promise();
175
+ },
176
+ })
177
+ .promise();
164
178
  // Process Creations
165
- yield this.client.pool.addEachTask({
179
+ yield this.client.pool
180
+ .addEachTask({
166
181
  data: create || [],
167
182
  generator: (createItem) => {
168
- const createFunction = this.getClientFN(this.functions.create);
183
+ const createFunction = this.getClientFN('create');
169
184
  return createFunction(createItem)
170
185
  .then((data) => {
171
186
  this.didCreate(data);
@@ -174,13 +189,15 @@ class DefaultHandler {
174
189
  .catch((err) => {
175
190
  throw new Error(`Problem creating ${this.type} ${this.objString(createItem)}\n${err}`);
176
191
  });
177
- }
178
- }).promise();
192
+ },
193
+ })
194
+ .promise();
179
195
  // Process Updates and strip fields not allowed in updates
180
- yield this.client.pool.addEachTask({
196
+ yield this.client.pool
197
+ .addEachTask({
181
198
  data: update || [],
182
199
  generator: (updateItem) => {
183
- const updateFN = this.getClientFN(this.functions.update);
200
+ const updateFN = this.getClientFN('update');
184
201
  const params = { [this.id]: updateItem[this.id] };
185
202
  const payload = (0, utils_1.stripFields)(Object.assign({}, updateItem), this.stripUpdateFields);
186
203
  return updateFN(params, payload)
@@ -191,9 +208,10 @@ class DefaultHandler {
191
208
  .catch((err) => {
192
209
  throw new Error(`Problem updating ${this.type} ${this.objString(updateItem)}\n${err}`);
193
210
  });
194
- }
195
- }).promise();
211
+ },
212
+ })
213
+ .promise();
196
214
  });
197
215
  }
198
216
  }
199
- exports.default = DefaultHandler;
217
+ exports.default = APIHandler;