auth0-deploy-cli 8.30.0 → 8.32.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 (82) hide show
  1. package/.circleci/config.yml +17 -5
  2. package/AGENTS.md +21 -1
  3. package/CHANGELOG.md +48 -415
  4. package/CLAUDE.md +3 -0
  5. package/lib/args.d.ts +5 -0
  6. package/lib/args.js +23 -0
  7. package/lib/commands/export.js +5 -1
  8. package/lib/commands/import.js +40 -3
  9. package/lib/context/directory/handlers/actions.js +1 -2
  10. package/lib/context/directory/handlers/clients.js +14 -0
  11. package/lib/context/directory/handlers/connections.js +1 -0
  12. package/lib/context/directory/handlers/guardianFactors.js +8 -6
  13. package/lib/context/directory/handlers/tenant.d.ts +1 -6
  14. package/lib/context/directory/handlers/tenant.js +0 -1
  15. package/lib/context/directory/handlers/triggers.js +1 -3
  16. package/lib/context/index.js +5 -0
  17. package/lib/context/yaml/handlers/clients.js +12 -0
  18. package/lib/context/yaml/handlers/connections.js +1 -17
  19. package/lib/context/yaml/handlers/guardianFactors.js +3 -1
  20. package/lib/context/yaml/handlers/tenant.js +1 -1
  21. package/lib/context/yaml/index.js +2 -1
  22. package/lib/sessionDurationsToMinutes.d.ts +9 -7
  23. package/lib/sessionDurationsToMinutes.js +11 -10
  24. package/lib/tools/auth0/handlers/actions.d.ts +1 -0
  25. package/lib/tools/auth0/handlers/actions.js +36 -0
  26. package/lib/tools/auth0/handlers/attackProtection.js +15 -0
  27. package/lib/tools/auth0/handlers/branding.js +7 -0
  28. package/lib/tools/auth0/handlers/clientGrants.js +32 -4
  29. package/lib/tools/auth0/handlers/clients.d.ts +52 -2
  30. package/lib/tools/auth0/handlers/clients.js +175 -22
  31. package/lib/tools/auth0/handlers/connections.d.ts +1 -1
  32. package/lib/tools/auth0/handlers/connections.js +42 -6
  33. package/lib/tools/auth0/handlers/customDomains.d.ts +5 -0
  34. package/lib/tools/auth0/handlers/customDomains.js +26 -0
  35. package/lib/tools/auth0/handlers/databases.d.ts +91 -0
  36. package/lib/tools/auth0/handlers/databases.js +162 -2
  37. package/lib/tools/auth0/handlers/default.d.ts +4 -0
  38. package/lib/tools/auth0/handlers/default.js +82 -4
  39. package/lib/tools/auth0/handlers/emailProvider.js +8 -0
  40. package/lib/tools/auth0/handlers/emailTemplates.js +7 -0
  41. package/lib/tools/auth0/handlers/flowVaultConnections.js +6 -1
  42. package/lib/tools/auth0/handlers/flows.js +13 -4
  43. package/lib/tools/auth0/handlers/forms.js +10 -1
  44. package/lib/tools/auth0/handlers/guardianFactors.js +7 -1
  45. package/lib/tools/auth0/handlers/guardianPhoneFactorMessageTypes.js +8 -1
  46. package/lib/tools/auth0/handlers/guardianPhoneFactorSelectedProvider.js +8 -1
  47. package/lib/tools/auth0/handlers/guardianPolicies.js +7 -0
  48. package/lib/tools/auth0/handlers/hooks.d.ts +1 -0
  49. package/lib/tools/auth0/handlers/hooks.js +10 -0
  50. package/lib/tools/auth0/handlers/organizations.d.ts +11 -1
  51. package/lib/tools/auth0/handlers/organizations.js +48 -52
  52. package/lib/tools/auth0/handlers/pages.js +7 -0
  53. package/lib/tools/auth0/handlers/phoneProvider.js +7 -0
  54. package/lib/tools/auth0/handlers/prompts.js +7 -0
  55. package/lib/tools/auth0/handlers/resourceServers.d.ts +1 -2
  56. package/lib/tools/auth0/handlers/resourceServers.js +9 -25
  57. package/lib/tools/auth0/handlers/roles.js +7 -0
  58. package/lib/tools/auth0/handlers/rules.d.ts +1 -0
  59. package/lib/tools/auth0/handlers/rules.js +9 -0
  60. package/lib/tools/auth0/handlers/rulesConfigs.d.ts +1 -0
  61. package/lib/tools/auth0/handlers/rulesConfigs.js +3 -0
  62. package/lib/tools/auth0/handlers/scimHandler.js +8 -1
  63. package/lib/tools/auth0/handlers/selfServiceProfiles.d.ts +1 -1
  64. package/lib/tools/auth0/handlers/selfServiceProfiles.js +10 -17
  65. package/lib/tools/auth0/handlers/tenant.d.ts +13 -1
  66. package/lib/tools/auth0/handlers/tenant.js +48 -4
  67. package/lib/tools/auth0/handlers/themes.js +11 -2
  68. package/lib/tools/auth0/handlers/triggers.js +6 -0
  69. package/lib/tools/auth0/handlers/userAttributeProfiles.js +16 -10
  70. package/lib/tools/auth0/index.d.ts +3 -0
  71. package/lib/tools/auth0/index.js +204 -0
  72. package/lib/tools/calculateChanges.d.ts +2 -2
  73. package/lib/tools/calculateChanges.js +21 -6
  74. package/lib/tools/calculateDryRunChanges.d.ts +71 -0
  75. package/lib/tools/calculateDryRunChanges.js +492 -0
  76. package/lib/tools/deploy.js +25 -1
  77. package/lib/tools/utils.d.ts +5 -0
  78. package/lib/tools/utils.js +64 -3
  79. package/lib/types.d.ts +17 -0
  80. package/lib/utils.d.ts +7 -0
  81. package/lib/utils.js +46 -2
  82. package/package.json +10 -6
@@ -26,6 +26,9 @@ export declare const schema: {
26
26
  connection_id: {
27
27
  type: string;
28
28
  };
29
+ organization_connection_name: {
30
+ type: string;
31
+ };
29
32
  assign_membership_on_login: {
30
33
  type: string;
31
34
  };
@@ -35,6 +38,13 @@ export declare const schema: {
35
38
  is_signup_enabled: {
36
39
  type: string;
37
40
  };
41
+ organization_access_level: {
42
+ type: string;
43
+ enum: ("none" | "readonly" | "limited" | "full")[];
44
+ };
45
+ is_enabled: {
46
+ type: string;
47
+ };
38
48
  };
39
49
  };
40
50
  };
@@ -118,7 +128,7 @@ export default class OrganizationsHandler extends DefaultHandler {
118
128
  updateOrganizations(updates: CalculatedChanges['update'], orgs: Asset[]): Promise<void>;
119
129
  getType(): Promise<Asset[]>;
120
130
  processChanges(assets: Assets): Promise<void>;
121
- getOrganizationEnabledConnections(organizationId: string): Promise<Management.OrganizationConnection[]>;
131
+ getOrganizationConnections(organizationId: string): Promise<Management.OrganizationConnection[]>;
122
132
  getOrganizationClientGrants(organizationId: string): Promise<Management.OrganizationClientGrant[]>;
123
133
  createOrganizationClientGrants(organizationId: string, grantId: string): Promise<Management.AssociateOrganizationClientGrantResponseContent>;
124
134
  deleteOrganizationClientGrants(organizationId: string, grantId: string): Promise<void>;
@@ -44,11 +44,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.schema = void 0;
46
46
  const lodash_1 = require("lodash");
47
+ const auth0_1 = require("auth0");
47
48
  const default_1 = __importStar(require("./default"));
48
49
  const calculateChanges_1 = require("../../calculateChanges");
49
50
  const logger_1 = __importDefault(require("../../../logger"));
50
51
  const client_1 = require("../client");
51
52
  const utils_1 = require("../../../utils");
53
+ const utils_2 = require("../../utils");
52
54
  exports.schema = {
53
55
  type: 'array',
54
56
  items: {
@@ -64,9 +66,15 @@ exports.schema = {
64
66
  type: 'object',
65
67
  properties: {
66
68
  connection_id: { type: 'string' },
69
+ organization_connection_name: { type: 'string' },
67
70
  assign_membership_on_login: { type: 'boolean' },
68
71
  show_as_button: { type: 'boolean' },
69
72
  is_signup_enabled: { type: 'boolean' },
73
+ organization_access_level: {
74
+ type: 'string',
75
+ enum: Object.values(auth0_1.Management.OrganizationAccessLevelEnum),
76
+ },
77
+ is_enabled: { type: 'boolean' },
70
78
  },
71
79
  },
72
80
  },
@@ -163,26 +171,25 @@ class OrganizationsHandler extends default_1.default {
163
171
  if ('discovery_domains' in organization) {
164
172
  delete organization.discovery_domains;
165
173
  }
166
- const { data: created } = await this.client.organizations.create(organization);
174
+ const created = await this.client.organizations.create(organization);
175
+ if (!created.id) {
176
+ throw new Error(`Organization "${organization.name}" was created but the response did not include an ID. Skipping connection/grant association.`);
177
+ }
178
+ const createdId = created.id;
167
179
  if (typeof org.connections !== 'undefined' && org.connections.length > 0) {
168
- await Promise.all(org.connections.map((conn) => this.client.organizations.enabledConnections.add(created.id, conn)));
180
+ await Promise.all(org.connections.map((conn) => this.client.organizations.connections.create(createdId, conn)));
169
181
  }
170
182
  if (typeof org.client_grants !== 'undefined' && org.client_grants.length > 0) {
171
- await Promise.all(org.client_grants.map((organizationClientGrants) => this.createOrganizationClientGrants(created.id, this.getClientGrantIDByClientName(organizationClientGrants.client_id))));
183
+ await Promise.all(org.client_grants.map((organizationClientGrants) => this.createOrganizationClientGrants(createdId, this.getClientGrantIDByClientName(organizationClientGrants.client_id))));
172
184
  }
173
185
  if (typeof org.discovery_domains !== 'undefined' && org.discovery_domains.length > 0) {
174
- await this.client.pool
175
- .addEachTask({
176
- data: org.discovery_domains,
177
- generator: (discoveryDomain) => this.createOrganizationDiscoveryDomain(created.id, {
178
- domain: discoveryDomain?.domain,
179
- status: discoveryDomain?.status,
180
- use_for_organization_discovery: discoveryDomain?.use_for_organization_discovery,
181
- }).catch((err) => {
182
- throw new Error(`Problem creating discovery domain ${discoveryDomain?.domain} for organization ${created.id}\n${err}`);
183
- }),
184
- })
185
- .promise();
186
+ await Promise.all(org.discovery_domains.map((discoveryDomain) => this.createOrganizationDiscoveryDomain(createdId, {
187
+ domain: discoveryDomain?.domain,
188
+ status: discoveryDomain?.status,
189
+ use_for_organization_discovery: discoveryDomain?.use_for_organization_discovery,
190
+ }).catch((err) => {
191
+ throw new Error(`Problem creating discovery domain ${discoveryDomain?.domain} for organization ${createdId}\n${err}`);
192
+ })));
186
193
  }
187
194
  return created;
188
195
  }
@@ -217,23 +224,29 @@ class OrganizationsHandler extends default_1.default {
217
224
  const connectionsToUpdate = connections.filter((c) => existingConnections.find((x) => x.connection_id === c.connection_id &&
218
225
  (x.assign_membership_on_login !== c.assign_membership_on_login ||
219
226
  x.show_as_button !== c.show_as_button ||
220
- x.is_signup_enabled !== c.is_signup_enabled)));
227
+ x.is_signup_enabled !== c.is_signup_enabled ||
228
+ x.organization_access_level !== c.organization_access_level ||
229
+ x.organization_connection_name !== c.organization_connection_name ||
230
+ x.is_enabled !== (c.is_enabled ?? true))));
221
231
  // Handle updates first
222
- await Promise.all(connectionsToUpdate.map((conn) => this.client.organizations.enabledConnections
232
+ await Promise.all(connectionsToUpdate.map((conn) => this.client.organizations.connections
223
233
  .update(params.id, conn.connection_id, {
234
+ organization_connection_name: conn.organization_connection_name,
224
235
  assign_membership_on_login: conn.assign_membership_on_login,
225
236
  show_as_button: conn.show_as_button,
226
237
  is_signup_enabled: conn.is_signup_enabled,
238
+ is_enabled: conn.is_enabled,
239
+ organization_access_level: conn.organization_access_level,
227
240
  })
228
241
  .catch(() => {
229
242
  throw new Error(`Problem updating Enabled Connection ${conn.connection_id} for organizations ${params.id}`);
230
243
  })));
231
- await Promise.all(connectionsToAdd.map((conn) => this.client.organizations.enabledConnections
232
- .add(params.id, (0, lodash_1.omit)(conn, 'connection'))
244
+ await Promise.all(connectionsToAdd.map((conn) => this.client.organizations.connections
245
+ .create(params.id, (0, lodash_1.omit)(conn, 'connection'))
233
246
  .catch(() => {
234
247
  throw new Error(`Problem adding Enabled Connection ${conn.connection_id} for organizations ${params.id}`);
235
248
  })));
236
- await Promise.all(connectionsToRemove.map((conn) => this.client.organizations.enabledConnections
249
+ await Promise.all(connectionsToRemove.map((conn) => this.client.organizations.connections
237
250
  .delete(params.id, conn.connection_id)
238
251
  .catch(() => {
239
252
  throw new Error(`Problem removing Enabled Connection ${conn.connection_id} for organizations ${params.id}`);
@@ -366,7 +379,7 @@ class OrganizationsHandler extends default_1.default {
366
379
  if (!org?.id) {
367
380
  throw new Error(`Organization ${index} is missing an ID`);
368
381
  }
369
- const connections = await this.getOrganizationEnabledConnections(org.id);
382
+ const connections = await this.getOrganizationConnections(org.id);
370
383
  org.connections = connections;
371
384
  const organizationClientGrants = await this.getOrganizationClientGrants(org.id);
372
385
  org.client_grants = organizationClientGrants?.map((clientGrant) => ({
@@ -394,6 +407,12 @@ class OrganizationsHandler extends default_1.default {
394
407
  // Do nothing if not set
395
408
  if (!organizations)
396
409
  return;
410
+ if ((0, utils_2.isDryRun)(this.config)) {
411
+ const { del, update, create } = await this.calcChanges(assets);
412
+ if (create.length === 0 && update.length === 0 && del.length === 0) {
413
+ return;
414
+ }
415
+ }
397
416
  // Gets organizations from destination tenant
398
417
  const existing = await this.getType();
399
418
  const existingConnections = await (0, client_1.paginate)(this.client.connections.list, {
@@ -432,9 +451,9 @@ class OrganizationsHandler extends default_1.default {
432
451
  await this.updateOrganizations(changes.update, existing);
433
452
  }
434
453
  }
435
- async getOrganizationEnabledConnections(organizationId) {
454
+ async getOrganizationConnections(organizationId) {
436
455
  const allOrganizationConnections = [];
437
- let organizationConnections = await this.client.organizations.enabledConnections.list(organizationId);
456
+ let organizationConnections = await this.client.organizations.connections.list(organizationId);
438
457
  // Process first page
439
458
  allOrganizationConnections.push(...organizationConnections.data);
440
459
  // Fetch remaining pages
@@ -498,14 +517,7 @@ class OrganizationsHandler extends default_1.default {
498
517
  }
499
518
  async createOrganizationDiscoveryDomain(organizationId, discoveryDomain) {
500
519
  logger_1.default.debug(`Creating discovery domain ${discoveryDomain.domain} for organization ${organizationId}`);
501
- const orgDiscoveryDomain = await this.client.pool
502
- .addSingleTask({
503
- data: {
504
- id: organizationId,
505
- },
506
- generator: (args) => this.client.organizations.discoveryDomains.create(args.id, discoveryDomain),
507
- })
508
- .promise();
520
+ const orgDiscoveryDomain = await this.client.organizations.discoveryDomains.create(organizationId, discoveryDomain);
509
521
  return orgDiscoveryDomain;
510
522
  }
511
523
  async updateOrganizationDiscoveryDomain(organizationId, discoveryDomainId, discoveryDomain, discoveryDomainUpdate) {
@@ -513,31 +525,15 @@ class OrganizationsHandler extends default_1.default {
513
525
  // stripUpdateFields does not support in sub modules
514
526
  const stripUpdateFields = ['verification_host', 'verification_txt'];
515
527
  logger_1.default.debug(`Stripping ${this.type} discovery domain read-only fields ${JSON.stringify(stripUpdateFields)}`);
516
- const discoveryDomainUpdated = await this.client.pool
517
- .addSingleTask({
518
- data: {
519
- id: organizationId,
520
- discoveryDomainId: discoveryDomainId,
521
- },
522
- generator: (args) => this.client.organizations.discoveryDomains.update(args.id, args.discoveryDomainId, {
523
- status: discoveryDomainUpdate.status,
524
- use_for_organization_discovery: discoveryDomainUpdate.use_for_organization_discovery,
525
- }),
526
- })
527
- .promise();
528
+ const discoveryDomainUpdated = await this.client.organizations.discoveryDomains.update(organizationId, discoveryDomainId, {
529
+ status: discoveryDomainUpdate.status,
530
+ use_for_organization_discovery: discoveryDomainUpdate.use_for_organization_discovery,
531
+ });
528
532
  return discoveryDomainUpdated;
529
533
  }
530
534
  async deleteOrganizationDiscoveryDomain(organizationId, discoveryDomain, discoveryDomainId) {
531
535
  logger_1.default.debug(`Deleting discovery domain ${discoveryDomain} for organization ${organizationId}`);
532
- await this.client.pool
533
- .addSingleTask({
534
- data: {
535
- id: organizationId,
536
- discoveryDomainId: discoveryDomainId,
537
- },
538
- generator: (args) => this.client.organizations.discoveryDomains.delete(args.id, args.discoveryDomainId),
539
- })
540
- .promise();
536
+ await this.client.organizations.discoveryDomains.delete(organizationId, discoveryDomainId);
541
537
  }
542
538
  }
543
539
  exports.default = OrganizationsHandler;
@@ -7,6 +7,7 @@ exports.schema = exports.pageNameMap = exports.supportedPages = void 0;
7
7
  const default_1 = __importDefault(require("./default"));
8
8
  const constants_1 = __importDefault(require("../../constants"));
9
9
  const client_1 = require("../client");
10
+ const utils_1 = require("../../utils");
10
11
  exports.supportedPages = constants_1.default.PAGE_NAMES.filter((p) => p.includes('.json')).map((p) => p.replace('.json', ''));
11
12
  exports.pageNameMap = {
12
13
  guardian_multifactor: 'guardian_mfa_page',
@@ -113,6 +114,12 @@ class PagesHandler extends default_1.default {
113
114
  // Do nothing if not set
114
115
  if (!pages)
115
116
  return;
117
+ if ((0, utils_1.isDryRun)(this.config)) {
118
+ const { del, update, create } = await this.calcChanges(assets);
119
+ if (create.length === 0 && update.length === 0 && del.length === 0) {
120
+ return;
121
+ }
122
+ }
116
123
  // Login page is handled via the global client
117
124
  const loginPage = pages.find((p) => p.name === 'login');
118
125
  if (loginPage !== undefined) {
@@ -45,6 +45,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.schema = void 0;
46
46
  const default_1 = __importStar(require("./default"));
47
47
  const logger_1 = __importDefault(require("../../../logger"));
48
+ const utils_1 = require("../../utils");
48
49
  const TwilioConfigurationSchema = {
49
50
  type: 'object',
50
51
  required: ['sid', 'delivery_methods'],
@@ -164,6 +165,12 @@ class PhoneProviderHandler extends default_1.default {
164
165
  // Non-existing section means themes doesn't need to be processed
165
166
  if (!phoneProviders)
166
167
  return;
168
+ if ((0, utils_1.isDryRun)(this.config)) {
169
+ const { del, update, create } = await this.calcChanges(assets);
170
+ if (create.length === 0 && update.length === 0 && del.length === 0) {
171
+ return;
172
+ }
173
+ }
167
174
  // Empty array means themes should be deleted
168
175
  if (phoneProviders.length === 0) {
169
176
  await this.deletePhoneProviders();
@@ -48,6 +48,7 @@ const auth0_1 = require("auth0");
48
48
  const default_1 = __importStar(require("./default"));
49
49
  const types_1 = require("../../../types");
50
50
  const logger_1 = __importDefault(require("../../../logger"));
51
+ const utils_1 = require("../../utils");
51
52
  const client_1 = require("../client");
52
53
  const promptTypes = [
53
54
  'login',
@@ -414,6 +415,12 @@ class PromptsHandler extends default_1.default {
414
415
  const { prompts } = assets;
415
416
  if (!prompts)
416
417
  return;
418
+ if ((0, utils_1.isDryRun)(this.config)) {
419
+ const { del, update, create } = await this.calcChanges(assets);
420
+ if (create.length === 0 && update.length === 0 && del.length === 0) {
421
+ return;
422
+ }
423
+ }
417
424
  const { partials, customText, screenRenderers, ...promptSettings } = prompts;
418
425
  if (!(0, lodash_1.isEmpty)(promptSettings)) {
419
426
  await this.client.prompts.updateSettings(promptSettings);
@@ -1,6 +1,6 @@
1
1
  import { Management } from 'auth0';
2
2
  import DefaultHandler from './default';
3
- import { Assets, CalculatedChanges } from '../../../types';
3
+ import { Assets } from '../../../types';
4
4
  export declare const excludeSchema: {
5
5
  type: string;
6
6
  items: {
@@ -96,7 +96,6 @@ export default class ResourceServersHandler extends DefaultHandler {
96
96
  constructor(options: DefaultHandler);
97
97
  objString(resourceServer: any): string;
98
98
  getType(): Promise<ResourceServer[]>;
99
- calcChanges(assets: Assets): Promise<CalculatedChanges>;
100
99
  validate(assets: Assets): Promise<void>;
101
100
  processChanges(assets: Assets): Promise<void>;
102
101
  updateResourceServer(id: string, update: ResourceServer): Promise<Management.UpdateResourceServerResponseContent>;
@@ -8,7 +8,6 @@ const auth0_1 = require("auth0");
8
8
  const validationError_1 = __importDefault(require("../../validationError"));
9
9
  const constants_1 = __importDefault(require("../../constants"));
10
10
  const default_1 = __importDefault(require("./default"));
11
- const calculateChanges_1 = require("../../calculateChanges");
12
11
  const client_1 = require("../client");
13
12
  exports.excludeSchema = {
14
13
  type: 'array',
@@ -132,29 +131,6 @@ class ResourceServersHandler extends default_1.default {
132
131
  this.existing = sanitizeResourceServersFields(resourceServers);
133
132
  return this.existing;
134
133
  }
135
- async calcChanges(assets) {
136
- let { resourceServers } = assets;
137
- // Do nothing if not set
138
- if (!resourceServers)
139
- return {
140
- del: [],
141
- create: [],
142
- conflicts: [],
143
- update: [],
144
- };
145
- const excluded = (assets.exclude && assets.exclude.resourceServers) || [];
146
- let existing = await this.getType();
147
- // Filter excluded
148
- resourceServers = resourceServers.filter((r) => r.name && !excluded.includes(r.name));
149
- existing = existing.filter((r) => r.name && !excluded.includes(r.name));
150
- return (0, calculateChanges_1.calculateChanges)({
151
- handler: this,
152
- assets: resourceServers,
153
- existing,
154
- identifiers: this.identifiers,
155
- allowDelete: !!this.config('AUTH0_ALLOW_DELETE'),
156
- });
157
- }
158
134
  async validate(assets) {
159
135
  const { resourceServers } = assets;
160
136
  // Do nothing if not set
@@ -171,7 +147,15 @@ class ResourceServersHandler extends default_1.default {
171
147
  // Do nothing if not set
172
148
  if (!resourceServers)
173
149
  return;
174
- const changes = await this.calcChanges(assets);
150
+ const excluded = (assets.exclude && assets.exclude.resourceServers) || [];
151
+ const filterResourceServer = (items) => items.filter((r) => !excluded.includes(r.name));
152
+ const { del, update, create, conflicts } = await this.calcChanges(assets);
153
+ const changes = {
154
+ del: filterResourceServer(del),
155
+ update: filterResourceServer(update),
156
+ create: filterResourceServer(create),
157
+ conflicts: filterResourceServer(conflicts),
158
+ };
175
159
  await super.processChanges(assets, {
176
160
  ...changes,
177
161
  });
@@ -47,6 +47,7 @@ const default_1 = __importStar(require("./default"));
47
47
  const calculateChanges_1 = require("../../calculateChanges");
48
48
  const logger_1 = __importDefault(require("../../../logger"));
49
49
  const client_1 = require("../client");
50
+ const utils_1 = require("../../utils");
50
51
  exports.schema = {
51
52
  type: 'array',
52
53
  items: {
@@ -223,6 +224,12 @@ class RolesHandler extends default_1.default {
223
224
  // Do nothing if not set
224
225
  if (!roles)
225
226
  return;
227
+ if ((0, utils_1.isDryRun)(this.config)) {
228
+ const { del, update, create } = await this.calcChanges(assets);
229
+ if (create.length === 0 && update.length === 0 && del.length === 0) {
230
+ return;
231
+ }
232
+ }
226
233
  // Gets roles from destination tenant
227
234
  const existing = await this.getType();
228
235
  const changes = (0, calculateChanges_1.calculateChanges)({
@@ -50,6 +50,7 @@ export default class RulesHandler extends DefaultHandler {
50
50
  calcChanges(assets: any, includeExcluded?: boolean): Promise<CalculatedChanges & {
51
51
  reOrder: Asset[];
52
52
  }>;
53
+ dryRunChanges(assets: Assets): Promise<CalculatedChanges>;
53
54
  validate(assets: Assets): Promise<void>;
54
55
  processChanges(assets: Assets): Promise<void>;
55
56
  }
@@ -134,6 +134,15 @@ class RulesHandler extends default_1.default {
134
134
  conflicts,
135
135
  };
136
136
  }
137
+ async dryRunChanges(assets) {
138
+ const { del, update, create, conflicts } = await this.calcChanges(assets);
139
+ return {
140
+ del,
141
+ update,
142
+ create,
143
+ conflicts,
144
+ };
145
+ }
137
146
  async validate(assets) {
138
147
  const { rules } = assets;
139
148
  // Do nothing if not set
@@ -22,4 +22,5 @@ export default class RulesConfigsHandler extends DefaultHandler {
22
22
  getType(): Promise<Asset[] | null>;
23
23
  objString(item: any): string;
24
24
  calcChanges(assets: Assets): Promise<CalculatedChanges>;
25
+ dryRunChanges(assets: Assets): Promise<CalculatedChanges>;
25
26
  }
@@ -63,5 +63,8 @@ class RulesConfigsHandler extends default_1.default {
63
63
  conflicts: [],
64
64
  };
65
65
  }
66
+ async dryRunChanges(assets) {
67
+ return this.calcChanges(assets);
68
+ }
66
69
  }
67
70
  exports.default = RulesConfigsHandler;
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const nconf_1 = __importDefault(require("nconf"));
6
7
  const logger_1 = __importDefault(require("../../../logger"));
7
8
  /**
8
9
  * The current version of this sdk use `node-auth0` v3. But `SCIM` features are not natively supported by v3.
@@ -39,7 +40,13 @@ class ScimHandler {
39
40
  */
40
41
  async createIdMap(connections) {
41
42
  this.idMap.clear();
42
- logger_1.default.info('Reviewing connections for SCIM support. This may take a while...');
43
+ const logMsg = 'Reviewing connections for SCIM support. This may take a while...';
44
+ if (nconf_1.default.get('AUTH0_DRY_RUN')) {
45
+ logger_1.default.debug(logMsg);
46
+ }
47
+ else {
48
+ logger_1.default.info(logMsg);
49
+ }
43
50
  await this.poolClient
44
51
  .addEachTask({
45
52
  data: connections || [],
@@ -53,7 +53,7 @@ export declare const schema: {
53
53
  description: string;
54
54
  items: {
55
55
  type: string;
56
- enum: ("pingfederate" | "adfs" | "waad" | "google-apps" | "okta" | "oidc" | "samlp" | "auth0-samlp" | "okta-samlp" | "keycloak-samlp")[];
56
+ enum: ("samlp" | "pingfederate" | "adfs" | "waad" | "google-apps" | "okta" | "oidc" | "auth0-samlp" | "okta-samlp" | "keycloak-samlp")[];
57
57
  };
58
58
  };
59
59
  branding: {
@@ -47,8 +47,8 @@ const auth0_1 = require("auth0");
47
47
  const lodash_1 = require("lodash");
48
48
  const logger_1 = __importDefault(require("../../../logger"));
49
49
  const default_1 = __importStar(require("./default"));
50
- const calculateChanges_1 = require("../../calculateChanges");
51
50
  const client_1 = require("../client");
51
+ const utils_1 = require("../../utils");
52
52
  const userAttributeProfiles_1 = require("./userAttributeProfiles");
53
53
  const SelfServiceProfileCustomTextLanguageEnum = {
54
54
  en: 'en',
@@ -180,8 +180,6 @@ class SelfServiceProfileHandler extends default_1.default {
180
180
  // Do nothing if not set
181
181
  if (!selfServiceProfiles)
182
182
  return;
183
- // Gets SsProfileWithCustomText from destination tenant
184
- const existing = await this.getType();
185
183
  const userAttributeProfiles = await this.getUserAttributeProfiles(this.client, selfServiceProfiles);
186
184
  selfServiceProfiles = selfServiceProfiles.map((ssProfile) => {
187
185
  if (this.hasConflictingUserAttribute(ssProfile)) {
@@ -202,26 +200,21 @@ class SelfServiceProfileHandler extends default_1.default {
202
200
  }
203
201
  return profile;
204
202
  });
205
- const changes = (0, calculateChanges_1.calculateChanges)({
206
- handler: this,
207
- assets: selfServiceProfiles,
208
- existing,
209
- identifiers: this.identifiers,
210
- allowDelete: !!this.config('AUTH0_ALLOW_DELETE'),
211
- });
212
- logger_1.default.debug(`Start processChanges for selfServiceProfiles [delete:${changes.del.length}] [update:${changes.update.length}], [create:${changes.create.length}]`);
213
- const myChanges = [
214
- { del: changes.del },
215
- { create: changes.create },
216
- { update: changes.update },
217
- ];
203
+ const { del, update, create } = await this.calcChanges({ ...assets, selfServiceProfiles });
204
+ if ((0, utils_1.isDryRun)(this.config)) {
205
+ if (create.length === 0 && update.length === 0 && del.length === 0) {
206
+ return;
207
+ }
208
+ }
209
+ logger_1.default.debug(`Start processChanges for selfServiceProfiles [delete:${del.length}] [update:${update.length}], [create:${create.length}]`);
210
+ const myChanges = [{ del: del }, { create: create }, { update: update }];
218
211
  await Promise.all(myChanges.map(async (change) => {
219
212
  switch (true) {
220
213
  case change.del && change.del.length > 0:
221
214
  await this.deleteSelfServiceProfiles(change.del || []);
222
215
  break;
223
216
  case change.create && change.create.length > 0:
224
- await this.createSelfServiceProfiles(changes.create);
217
+ await this.createSelfServiceProfiles(change.create);
225
218
  break;
226
219
  case change.update && change.update.length > 0:
227
220
  if (change.update)
@@ -4,6 +4,10 @@ import { Asset, Assets } from '../../../types';
4
4
  export declare const schema: {
5
5
  type: string;
6
6
  properties: {
7
+ client_id_metadata_document_supported: {
8
+ type: string;
9
+ description: string;
10
+ };
7
11
  default_token_quota: {
8
12
  type: string;
9
13
  properties: {
@@ -65,9 +69,17 @@ export declare const schema: {
65
69
  type: string[];
66
70
  description: string;
67
71
  };
72
+ resource_parameter_profile: {
73
+ type: string;
74
+ enum: string[];
75
+ description: string;
76
+ };
68
77
  };
69
78
  };
70
- export type Tenant = Management.GetTenantSettingsResponseContent;
79
+ export interface Tenant extends Management.GetTenantSettingsResponseContent {
80
+ client_id_metadata_document_supported?: boolean;
81
+ resource_parameter_profile?: Management.TenantSettingsResourceParameterProfile;
82
+ }
71
83
  type TenantSettingsFlags = Management.TenantSettingsFlags;
72
84
  export declare const allowedTenantFlags: string[];
73
85
  export declare const removeUnallowedTenantFlags: (proposedFlags: TenantSettingsFlags | undefined) => TenantSettingsFlags;
@@ -43,11 +43,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.removeUnallowedTenantFlags = exports.allowedTenantFlags = exports.schema = void 0;
46
+ const lodash_1 = require("lodash");
47
+ const nconf_1 = __importDefault(require("nconf"));
46
48
  const validationError_1 = __importDefault(require("../../validationError"));
47
49
  const default_1 = __importStar(require("./default"));
48
50
  const pages_1 = require("./pages");
49
51
  const utils_1 = require("../../utils");
50
52
  const logger_1 = __importDefault(require("../../../logger"));
53
+ const sessionDurationsToMinutes_1 = __importDefault(require("../../../sessionDurationsToMinutes"));
51
54
  const tokenQuotaConfigurationSchema = {
52
55
  type: 'object',
53
56
  properties: {
@@ -76,6 +79,10 @@ const tokenQuotaConfigurationSchema = {
76
79
  exports.schema = {
77
80
  type: 'object',
78
81
  properties: {
82
+ client_id_metadata_document_supported: {
83
+ type: 'boolean',
84
+ description: 'Whether the authorization server supports retrieving client metadata from a client_id URL.',
85
+ },
79
86
  default_token_quota: {
80
87
  type: 'object',
81
88
  properties: {
@@ -89,6 +96,11 @@ exports.schema = {
89
96
  type: ['boolean', 'null'],
90
97
  description: 'Whether to skip the confirmation prompt for non-verifiable callback URIs',
91
98
  },
99
+ resource_parameter_profile: {
100
+ type: 'string',
101
+ enum: ['audience', 'compatibility'],
102
+ description: 'OAuth resource parameter compatibility mode for specifying the protected resource.',
103
+ },
92
104
  },
93
105
  };
94
106
  const blockPageKeys = [
@@ -148,8 +160,14 @@ const removeUnallowedTenantFlags = (proposedFlags) => {
148
160
  };
149
161
  }, {});
150
162
  if (removedFlags.length > 0) {
151
- logger_1.default.warn(`The following tenant flag${removedFlags.length > 1 ? 's have not been' : ' has not been'} updated because deemed incompatible with the target tenant: ${removedFlags.join(', ')}
152
- ${removedFlags.length > 1 ? 'These flags' : 'This flag'} can likely be removed from the tenant definition file. If you believe this removal is an error, please report via a Github issue.`);
163
+ const logMsg = `The following tenant flag${removedFlags.length > 1 ? 's have not been' : ' has not been'} updated because deemed incompatible with the target tenant: ${removedFlags.join(', ')}
164
+ ${removedFlags.length > 1 ? 'These flags' : 'This flag'} can likely be removed from the tenant definition file. If you believe this removal is an error, please report via a Github issue.`;
165
+ if (nconf_1.default.get('AUTH0_DRY_RUN')) {
166
+ logger_1.default.debug(logMsg);
167
+ }
168
+ else {
169
+ logger_1.default.warn(logMsg);
170
+ }
153
171
  }
154
172
  return filteredFlags;
155
173
  };
@@ -187,6 +205,12 @@ class TenantHandler extends default_1.default {
187
205
  // Do nothing if not set
188
206
  if (!tenant)
189
207
  return;
208
+ if ((0, utils_1.isDryRun)(this.config)) {
209
+ const { update } = await this.calcChanges(assets);
210
+ if (update.length === 0) {
211
+ return;
212
+ }
213
+ }
190
214
  const updatedTenant = {
191
215
  ...tenant,
192
216
  flags: tenant.flags
@@ -198,10 +222,30 @@ class TenantHandler extends default_1.default {
198
222
  delete updatedTenant.flags;
199
223
  }
200
224
  }
225
+ if (tenant.flags?.enable_custom_domain_in_emails !== undefined) {
226
+ logger_1.default.warn('The "enable_custom_domain_in_emails" tenant flag is deprecated. ' +
227
+ 'Use the "is_default" field on customDomains to configure the default domain instead. ' +
228
+ 'The flag will still be applied for now but will be removed in a future release.');
229
+ }
201
230
  if (updatedTenant && Object.keys(updatedTenant).length > 0) {
202
- await this.client.tenants.settings.update(updatedTenant);
231
+ const sessionDurations = (0, sessionDurationsToMinutes_1.default)({
232
+ session_lifetime: updatedTenant?.session_lifetime,
233
+ idle_session_lifetime: updatedTenant?.idle_session_lifetime,
234
+ ephemeral_session_lifetime: updatedTenant?.ephemeral_session_lifetime,
235
+ idle_ephemeral_session_lifetime: updatedTenant?.idle_ephemeral_session_lifetime,
236
+ });
237
+ let updateTenantPayload = updatedTenant;
238
+ if (!(0, lodash_1.isEmpty)(sessionDurations)) {
239
+ updateTenantPayload = { ...updateTenantPayload, ...sessionDurations };
240
+ // context: https://github.com/auth0/auth0-deploy-cli/pull/471
241
+ delete updateTenantPayload.session_lifetime;
242
+ delete updateTenantPayload.idle_session_lifetime;
243
+ delete updateTenantPayload.ephemeral_session_lifetime;
244
+ delete updateTenantPayload.idle_ephemeral_session_lifetime;
245
+ }
246
+ await this.client.tenants.settings.update(updateTenantPayload);
203
247
  this.updated += 1;
204
- this.didUpdate(updatedTenant);
248
+ this.didUpdate(updateTenantPayload);
205
249
  }
206
250
  }
207
251
  }