auth0-deploy-cli 8.23.2 → 8.25.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 (31) hide show
  1. package/CHANGELOG.md +25 -1
  2. package/lib/context/directory/handlers/index.js +2 -0
  3. package/lib/context/directory/handlers/riskAssessment.d.ts +6 -0
  4. package/lib/context/directory/handlers/riskAssessment.js +40 -0
  5. package/lib/context/directory/handlers/tenant.js +7 -2
  6. package/lib/context/directory/index.js +3 -0
  7. package/lib/context/index.js +10 -0
  8. package/lib/context/yaml/handlers/index.js +2 -0
  9. package/lib/context/yaml/handlers/riskAssessment.d.ts +6 -0
  10. package/lib/context/yaml/handlers/riskAssessment.js +23 -0
  11. package/lib/context/yaml/handlers/tenant.js +7 -2
  12. package/lib/context/yaml/index.js +5 -0
  13. package/lib/sessionDurationsToMinutes.d.ts +5 -1
  14. package/lib/sessionDurationsToMinutes.js +5 -1
  15. package/lib/tools/auth0/handlers/connections.d.ts +56 -1
  16. package/lib/tools/auth0/handlers/connections.js +200 -5
  17. package/lib/tools/auth0/handlers/index.d.ts +1 -0
  18. package/lib/tools/auth0/handlers/index.js +2 -0
  19. package/lib/tools/auth0/handlers/riskAssessment.d.ts +39 -0
  20. package/lib/tools/auth0/handlers/riskAssessment.js +95 -0
  21. package/lib/tools/auth0/handlers/scimHandler.js +2 -0
  22. package/lib/tools/auth0/handlers/tokenExchangeProfiles.d.ts +0 -14
  23. package/lib/tools/auth0/handlers/tokenExchangeProfiles.js +27 -34
  24. package/lib/tools/auth0/schema.d.ts +7 -0
  25. package/lib/tools/auth0/schema.js +11 -0
  26. package/lib/tools/constants.d.ts +1 -0
  27. package/lib/tools/constants.js +1 -0
  28. package/lib/tools/utils.d.ts +1 -0
  29. package/lib/tools/utils.js +14 -0
  30. package/lib/types.d.ts +7 -1
  31. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [8.25.0] - 2026-01-08
11
+
12
+ ### Added
13
+
14
+ - `AUTH0_INCLUDED_CONNECTIONS` config property to include only selected `connection`. [#1242]
15
+
16
+ ### Fixed
17
+
18
+ - Fix `tokenExchangeProfiles` profiles handling. [#1253]
19
+ - Fix `idle_ephemeral_session_lifetime` and `ephemeral_session_lifetime` handling while importing [#1261]
20
+
21
+ ## [8.24.0] - 2025-12-22
22
+
23
+ ### Added
24
+
25
+ - Add support for managing `riskAssessment` settings. [#1217]
26
+ - Add directory provisioning support for `google-apps` connections. [#1246]
27
+
10
28
  ## [8.23.2] - 2025-12-18
11
29
 
12
30
  ### Fixed
@@ -1575,6 +1593,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1575
1593
  [#1211]: https://github.com/auth0/auth0-deploy-cli/issues/1211
1576
1594
  [#1212]: https://github.com/auth0/auth0-deploy-cli/issues/1212
1577
1595
  [#1214]: https://github.com/auth0/auth0-deploy-cli/issues/1214
1596
+ [#1217]: https://github.com/auth0/auth0-deploy-cli/issues/1217
1578
1597
  [#1221]: https://github.com/auth0/auth0-deploy-cli/issues/1221
1579
1598
  [#1223]: https://github.com/auth0/auth0-deploy-cli/issues/1223
1580
1599
  [#1224]: https://github.com/auth0/auth0-deploy-cli/issues/1224
@@ -1583,8 +1602,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1583
1602
  [#1232]: https://github.com/auth0/auth0-deploy-cli/issues/1232
1584
1603
  [#1239]: https://github.com/auth0/auth0-deploy-cli/issues/1239
1585
1604
  [#1240]: https://github.com/auth0/auth0-deploy-cli/issues/1240
1605
+ [#1242]: https://github.com/auth0/auth0-deploy-cli/issues/1242
1586
1606
  [#1244]: https://github.com/auth0/auth0-deploy-cli/issues/1244
1587
- [Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.23.2...HEAD
1607
+ [#1246]: https://github.com/auth0/auth0-deploy-cli/issues/1246
1608
+ [#1253]: https://github.com/auth0/auth0-deploy-cli/issues/1253
1609
+ [Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.25.0...HEAD
1610
+ [8.25.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.24.0...v8.25.0
1611
+ [8.24.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.23.2...v8.24.0
1588
1612
  [8.23.2]: https://github.com/auth0/auth0-deploy-cli/compare/v8.23.1...v8.23.2
1589
1613
  [8.23.1]: https://github.com/auth0/auth0-deploy-cli/compare/v8.23.0...v8.23.1
1590
1614
  [8.23.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.22.0...v8.23.0
@@ -23,6 +23,7 @@ const actions_1 = __importDefault(require("./actions"));
23
23
  const organizations_1 = __importDefault(require("./organizations"));
24
24
  const triggers_1 = __importDefault(require("./triggers"));
25
25
  const attackProtection_1 = __importDefault(require("./attackProtection"));
26
+ const riskAssessment_1 = __importDefault(require("./riskAssessment"));
26
27
  const branding_1 = __importDefault(require("./branding"));
27
28
  const phoneProvider_1 = __importDefault(require("./phoneProvider"));
28
29
  const phoneTemplates_1 = __importDefault(require("./phoneTemplates"));
@@ -65,6 +66,7 @@ const directoryHandlers = {
65
66
  organizations: organizations_1.default,
66
67
  triggers: triggers_1.default,
67
68
  attackProtection: attackProtection_1.default,
69
+ riskAssessment: riskAssessment_1.default,
68
70
  branding: branding_1.default,
69
71
  phoneProviders: phoneProvider_1.default,
70
72
  phoneTemplates: phoneTemplates_1.default,
@@ -0,0 +1,6 @@
1
+ import { DirectoryHandler } from '.';
2
+ import { ParsedAsset } from '../../../types';
3
+ import { RiskAssessment } from '../../../tools/auth0/handlers/riskAssessment';
4
+ type ParsedRiskAssessment = ParsedAsset<'riskAssessment', RiskAssessment>;
5
+ declare const riskAssessmentHandler: DirectoryHandler<ParsedRiskAssessment>;
6
+ export default riskAssessmentHandler;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const tools_1 = require("../../../tools");
9
+ const utils_1 = require("../../../utils");
10
+ function parse(context) {
11
+ const riskAssessmentDirectory = path_1.default.join(context.filePath, tools_1.constants.RISK_ASSESSMENT_DIRECTORY);
12
+ const riskAssessmentFile = path_1.default.join(riskAssessmentDirectory, 'settings.json');
13
+ if (!(0, utils_1.existsMustBeDir)(riskAssessmentDirectory)) {
14
+ return { riskAssessment: null };
15
+ }
16
+ if (!(0, utils_1.isFile)(riskAssessmentFile)) {
17
+ return { riskAssessment: null };
18
+ }
19
+ const riskAssessment = (0, utils_1.loadJSON)(riskAssessmentFile, {
20
+ mappings: context.mappings,
21
+ disableKeywordReplacement: context.disableKeywordReplacement,
22
+ });
23
+ return {
24
+ riskAssessment,
25
+ };
26
+ }
27
+ async function dump(context) {
28
+ const { riskAssessment } = context.assets;
29
+ if (!riskAssessment)
30
+ return;
31
+ const riskAssessmentDirectory = path_1.default.join(context.filePath, tools_1.constants.RISK_ASSESSMENT_DIRECTORY);
32
+ const riskAssessmentFile = path_1.default.join(riskAssessmentDirectory, 'settings.json');
33
+ fs_extra_1.default.ensureDirSync(riskAssessmentDirectory);
34
+ (0, utils_1.dumpJSON)(riskAssessmentFile, riskAssessment);
35
+ }
36
+ const riskAssessmentHandler = {
37
+ parse,
38
+ dump,
39
+ };
40
+ exports.default = riskAssessmentHandler;
@@ -15,12 +15,17 @@ function parse(context) {
15
15
  return { tenant: null };
16
16
  }
17
17
  /* eslint-disable camelcase */
18
- const { session_lifetime, idle_session_lifetime, ...tenant } = (0, utils_1.loadJSON)(tenantFile, {
18
+ const { session_lifetime, idle_session_lifetime, idle_ephemeral_session_lifetime, ephemeral_session_lifetime, ...tenant } = (0, utils_1.loadJSON)(tenantFile, {
19
19
  mappings: context.mappings,
20
20
  disableKeywordReplacement: context.disableKeywordReplacement,
21
21
  });
22
22
  (0, utils_1.clearTenantFlags)(tenant);
23
- const sessionDurations = (0, sessionDurationsToMinutes_1.sessionDurationsToMinutes)({ session_lifetime, idle_session_lifetime });
23
+ const sessionDurations = (0, sessionDurationsToMinutes_1.sessionDurationsToMinutes)({
24
+ session_lifetime,
25
+ idle_session_lifetime,
26
+ idle_ephemeral_session_lifetime,
27
+ ephemeral_session_lifetime,
28
+ });
24
29
  return {
25
30
  //@ts-ignore
26
31
  tenant: {
@@ -63,6 +63,9 @@ class DirectoryContext {
63
63
  resourceServers: config.AUTH0_EXCLUDED_RESOURCE_SERVERS || [],
64
64
  defaults: config.AUTH0_EXCLUDED_DEFAULTS || [],
65
65
  };
66
+ this.assets.include = {
67
+ connections: config.AUTH0_INCLUDED_CONNECTIONS || [],
68
+ };
66
69
  }
67
70
  loadFile(f, folder) {
68
71
  const basePath = path.join(this.filePath, folder);
@@ -26,6 +26,7 @@ const nonPrimitiveProps = [
26
26
  'AUTH0_INCLUDED_ONLY',
27
27
  'EXCLUDED_PROPS',
28
28
  'INCLUDED_PROPS',
29
+ 'AUTH0_INCLUDED_CONNECTIONS',
29
30
  ];
30
31
  const EA_FEATURES = [];
31
32
  const setupContext = async (config, command) => {
@@ -97,6 +98,15 @@ const setupContext = async (config, command) => {
97
98
  logger_1.default.warn(`Usage of the ${usedDeprecatedParams.join(', ')} exclusion ${usedDeprecatedParams.length > 1 ? 'params are' : 'param is'} deprecated and may be removed from future major versions. See: https://github.com/auth0/auth0-deploy-cli/issues/451#user-content-deprecated-exclusion-props for details.`);
98
99
  }
99
100
  })(config);
101
+ ((config) => {
102
+ const hasIncludedConnections = config.AUTH0_INCLUDED_CONNECTIONS !== undefined &&
103
+ config.AUTH0_INCLUDED_CONNECTIONS.length > 0;
104
+ const hasExcludedConnections = config.AUTH0_EXCLUDED_CONNECTIONS !== undefined &&
105
+ config.AUTH0_EXCLUDED_CONNECTIONS.length > 0;
106
+ if (hasIncludedConnections && hasExcludedConnections) {
107
+ throw new Error('Both AUTH0_INCLUDED_CONNECTIONS and AUTH0_EXCLUDED_CONNECTIONS configuration values are defined, only one can be configured at a time.');
108
+ }
109
+ })(config);
100
110
  ((config) => {
101
111
  // Check if experimental early access features are enabled
102
112
  if (config.AUTH0_EXPERIMENTAL_EA) {
@@ -23,6 +23,7 @@ const organizations_1 = __importDefault(require("./organizations"));
23
23
  const actions_1 = __importDefault(require("./actions"));
24
24
  const triggers_1 = __importDefault(require("./triggers"));
25
25
  const attackProtection_1 = __importDefault(require("./attackProtection"));
26
+ const riskAssessment_1 = __importDefault(require("./riskAssessment"));
26
27
  const branding_1 = __importDefault(require("./branding"));
27
28
  const phoneProvider_1 = __importDefault(require("./phoneProvider"));
28
29
  const phoneTemplates_1 = __importDefault(require("./phoneTemplates"));
@@ -65,6 +66,7 @@ const yamlHandlers = {
65
66
  organizations: organizations_1.default,
66
67
  triggers: triggers_1.default,
67
68
  attackProtection: attackProtection_1.default,
69
+ riskAssessment: riskAssessment_1.default,
68
70
  branding: branding_1.default,
69
71
  phoneProviders: phoneProvider_1.default,
70
72
  phoneTemplates: phoneTemplates_1.default,
@@ -0,0 +1,6 @@
1
+ import { YAMLHandler } from '.';
2
+ import { RiskAssessment } from '../../../tools/auth0/handlers/riskAssessment';
3
+ import { ParsedAsset } from '../../../types';
4
+ type ParsedRiskAssessment = ParsedAsset<'riskAssessment', RiskAssessment>;
5
+ declare const riskAssessmentHandler: YAMLHandler<ParsedRiskAssessment>;
6
+ export default riskAssessmentHandler;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ async function parse(context) {
4
+ const { riskAssessment } = context.assets;
5
+ if (!riskAssessment)
6
+ return { riskAssessment: null };
7
+ return {
8
+ riskAssessment,
9
+ };
10
+ }
11
+ async function dump(context) {
12
+ const { riskAssessment } = context.assets;
13
+ if (!riskAssessment)
14
+ return { riskAssessment: null };
15
+ return {
16
+ riskAssessment,
17
+ };
18
+ }
19
+ const riskAssessmentHandler = {
20
+ parse,
21
+ dump,
22
+ };
23
+ exports.default = riskAssessmentHandler;
@@ -6,9 +6,14 @@ async function parse(context) {
6
6
  if (!context.assets.tenant)
7
7
  return { tenant: null };
8
8
  /* eslint-disable camelcase */
9
- const { session_lifetime, idle_session_lifetime, ...tenant } = context.assets.tenant;
9
+ const { session_lifetime, idle_session_lifetime, idle_ephemeral_session_lifetime, ephemeral_session_lifetime, ...tenant } = context.assets.tenant;
10
10
  (0, utils_1.clearTenantFlags)(tenant);
11
- const sessionDurations = (0, sessionDurationsToMinutes_1.sessionDurationsToMinutes)({ session_lifetime, idle_session_lifetime });
11
+ const sessionDurations = (0, sessionDurationsToMinutes_1.sessionDurationsToMinutes)({
12
+ session_lifetime,
13
+ idle_session_lifetime,
14
+ idle_ephemeral_session_lifetime,
15
+ ephemeral_session_lifetime,
16
+ });
12
17
  return {
13
18
  tenant: {
14
19
  ...tenant,
@@ -32,6 +32,9 @@ class YAMLContext {
32
32
  resourceServers: config.AUTH0_EXCLUDED_RESOURCE_SERVERS || [],
33
33
  defaults: config.AUTH0_EXCLUDED_DEFAULTS || [],
34
34
  };
35
+ this.assets.include = {
36
+ connections: config.AUTH0_INCLUDED_CONNECTIONS || [],
37
+ };
35
38
  this.basePath = (() => {
36
39
  if (!!config.AUTH0_BASE_PATH)
37
40
  return config.AUTH0_BASE_PATH;
@@ -80,6 +83,7 @@ class YAMLContext {
80
83
  }, {});
81
84
  const initialAssets = {
82
85
  exclude: this.assets.exclude, // Keep the exclude rules in result assets
86
+ include: this.assets.include, // Keep the include rules in result assets
83
87
  };
84
88
  this.assets = Object.keys(this.assets).reduce((acc, key) => {
85
89
  // Get the list of asset types to include
@@ -173,6 +177,7 @@ class YAMLContext {
173
177
  let cleaned = (0, readonly_1.default)(this.assets, this.config);
174
178
  // Delete exclude as it's not part of the auth0 tenant config
175
179
  delete cleaned.exclude;
180
+ delete cleaned.include;
176
181
  // Optionally Strip identifiers
177
182
  if (!this.config.AUTH0_EXPORT_IDENTIFIERS) {
178
183
  cleaned = (0, utils_1.stripIdentifiers)(auth0, cleaned);
@@ -1,7 +1,11 @@
1
- export declare const sessionDurationsToMinutes: ({ session_lifetime, idle_session_lifetime, }: {
1
+ export declare const sessionDurationsToMinutes: ({ session_lifetime, idle_session_lifetime, idle_ephemeral_session_lifetime, ephemeral_session_lifetime, }: {
2
2
  session_lifetime?: number;
3
3
  idle_session_lifetime?: number;
4
+ idle_ephemeral_session_lifetime?: number;
5
+ ephemeral_session_lifetime?: number;
4
6
  }) => {
5
7
  session_lifetime_in_minutes?: number;
6
8
  idle_session_lifetime_in_minutes?: number;
9
+ idle_ephemeral_session_lifetime_in_minutes?: number;
10
+ ephemeral_session_lifetime_in_minutes?: number;
7
11
  };
@@ -4,12 +4,16 @@ exports.sessionDurationsToMinutes = void 0;
4
4
  function hoursToMinutes(hours) {
5
5
  return Math.round(hours * 60);
6
6
  }
7
- const sessionDurationsToMinutes = ({ session_lifetime, idle_session_lifetime, }) => {
7
+ const sessionDurationsToMinutes = ({ session_lifetime, idle_session_lifetime, idle_ephemeral_session_lifetime, ephemeral_session_lifetime, }) => {
8
8
  const sessionDurations = {};
9
9
  if (!!session_lifetime)
10
10
  sessionDurations.session_lifetime_in_minutes = hoursToMinutes(session_lifetime);
11
11
  if (!!idle_session_lifetime)
12
12
  sessionDurations.idle_session_lifetime_in_minutes = hoursToMinutes(idle_session_lifetime);
13
+ if (!!idle_ephemeral_session_lifetime)
14
+ sessionDurations.idle_ephemeral_session_lifetime_in_minutes = hoursToMinutes(idle_ephemeral_session_lifetime);
15
+ if (!!ephemeral_session_lifetime)
16
+ sessionDurations.ephemeral_session_lifetime_in_minutes = hoursToMinutes(ephemeral_session_lifetime);
13
17
  return sessionDurations;
14
18
  };
15
19
  exports.sessionDurationsToMinutes = sessionDurationsToMinutes;
@@ -78,11 +78,40 @@ export declare const schema: {
78
78
  required: string[];
79
79
  additionalProperties: boolean;
80
80
  };
81
+ directory_provisioning_configuration: {
82
+ type: string;
83
+ properties: {
84
+ mapping: {
85
+ type: string;
86
+ items: {
87
+ type: string;
88
+ properties: {
89
+ auth0: {
90
+ type: string;
91
+ description: string;
92
+ };
93
+ idp: {
94
+ type: string;
95
+ description: string;
96
+ };
97
+ };
98
+ };
99
+ };
100
+ synchronize_automatically: {
101
+ type: string;
102
+ description: string;
103
+ };
104
+ };
105
+ };
81
106
  };
82
107
  required: string[];
83
108
  };
84
109
  };
85
- export type Connection = Management.ConnectionForList;
110
+ type DirectoryProvisioningConfig = Management.GetDirectoryProvisioningResponseContent;
111
+ export type Connection = Management.ConnectionForList & {
112
+ enabled_clients?: string[];
113
+ directory_provisioning_configuration?: DirectoryProvisioningConfig;
114
+ };
86
115
  export declare const addExcludedConnectionPropertiesToChanges: ({ proposedChanges, existingConnections, config, }: {
87
116
  proposedChanges: CalculatedChanges;
88
117
  existingConnections: Asset[];
@@ -135,7 +164,33 @@ export default class ConnectionsHandler extends DefaultAPIHandler {
135
164
  } | {
136
165
  options?: undefined;
137
166
  };
167
+ /**
168
+ * Retrieves directory provisioning configuration for a specific Auth0 connection.
169
+ * @param connectionId - The unique identifier of the connection
170
+ * @returns A promise that resolves to the configuration object, or null if not configured/supported
171
+ */
172
+ getConnectionDirectoryProvisioning(connectionId: string): Promise<DirectoryProvisioningConfig | null>;
173
+ /**
174
+ * Creates directory provisioning configuration for a connection.
175
+ */
176
+ private createConnectionDirectoryProvisioning;
177
+ /**
178
+ * Updates directory provisioning configuration for a connection.
179
+ */
180
+ private updateConnectionDirectoryProvisioning;
181
+ /**
182
+ * Deletes directory provisioning configuration for a connection.
183
+ */
184
+ private deleteConnectionDirectoryProvisioning;
185
+ /**
186
+ * This function processes directory provisioning for create, update, and conflict operations.
187
+ * Directory provisioning is only supported for google-apps strategy connections.
188
+ *
189
+ * @param changes - Object containing arrays of connections to create, update, and resolve conflicts for
190
+ */
191
+ processConnectionDirectoryProvisioning(changes: CalculatedChanges): Promise<void>;
138
192
  getType(): Promise<Asset[] | null>;
139
193
  calcChanges(assets: Assets): Promise<CalculatedChanges>;
140
194
  processChanges(assets: Assets): Promise<void>;
141
195
  }
196
+ export {};
@@ -93,6 +93,25 @@ exports.schema = {
93
93
  required: ['active'],
94
94
  additionalProperties: false,
95
95
  },
96
+ directory_provisioning_configuration: {
97
+ type: 'object',
98
+ properties: {
99
+ mapping: {
100
+ type: 'array',
101
+ items: {
102
+ type: 'object',
103
+ properties: {
104
+ auth0: { type: 'string', description: 'The field location in the Auth0 schema' },
105
+ idp: { type: 'string', description: 'The field location in the IDP schema' },
106
+ },
107
+ },
108
+ },
109
+ synchronize_automatically: {
110
+ type: 'boolean',
111
+ description: 'The field whether periodic automatic synchronization is enabled',
112
+ },
113
+ },
114
+ },
96
115
  },
97
116
  required: ['name', 'strategy'],
98
117
  },
@@ -286,6 +305,169 @@ class ConnectionsHandler extends default_1.default {
286
305
  return {};
287
306
  }
288
307
  }
308
+ /**
309
+ * Retrieves directory provisioning configuration for a specific Auth0 connection.
310
+ * @param connectionId - The unique identifier of the connection
311
+ * @returns A promise that resolves to the configuration object, or null if not configured/supported
312
+ */
313
+ async getConnectionDirectoryProvisioning(connectionId) {
314
+ if (!connectionId)
315
+ return null;
316
+ const creates = [connectionId];
317
+ let config = null;
318
+ try {
319
+ await this.client.pool
320
+ .addEachTask({
321
+ data: creates || [],
322
+ generator: async (id) => this.client.connections.directoryProvisioning
323
+ .get(id)
324
+ .then((resp) => {
325
+ config = resp;
326
+ })
327
+ .catch((err) => {
328
+ throw new auth0_1.ManagementError(err);
329
+ }),
330
+ })
331
+ .promise();
332
+ const stripKeysFromOutput = [
333
+ 'connection_id',
334
+ 'connection_name',
335
+ 'strategy',
336
+ 'created_at',
337
+ 'updated_at',
338
+ ];
339
+ stripKeysFromOutput.forEach((key) => {
340
+ if (config && key in config) {
341
+ delete config[key];
342
+ }
343
+ });
344
+ return config;
345
+ }
346
+ catch (error) {
347
+ const errLog = `Unable to fetch directory provisioning for connection '${connectionId}'. `;
348
+ if (error instanceof auth0_1.ManagementError) {
349
+ const bodyMessage = error.body?.message;
350
+ logger_1.default.warn(errLog + bodyMessage);
351
+ }
352
+ else {
353
+ logger_1.default.error(errLog, error?.message);
354
+ }
355
+ return null;
356
+ }
357
+ }
358
+ /**
359
+ * Creates directory provisioning configuration for a connection.
360
+ */
361
+ async createConnectionDirectoryProvisioning(connectionId, payload) {
362
+ if (!connectionId) {
363
+ throw new Error('Connection ID is required to create directory provisioning configuration.');
364
+ }
365
+ const createPayload = {
366
+ mapping: payload.mapping,
367
+ synchronize_automatically: payload.synchronize_automatically,
368
+ };
369
+ await this.client.connections.directoryProvisioning.create(connectionId, createPayload);
370
+ logger_1.default.debug(`Created directory provisioning for connection '${connectionId}'`);
371
+ }
372
+ /**
373
+ * Updates directory provisioning configuration for a connection.
374
+ */
375
+ async updateConnectionDirectoryProvisioning(connectionId, payload) {
376
+ if (!connectionId) {
377
+ throw new Error('Connection ID is required to update directory provisioning configuration.');
378
+ }
379
+ const updatePayload = {
380
+ mapping: payload.mapping,
381
+ synchronize_automatically: payload.synchronize_automatically,
382
+ };
383
+ await this.client.connections.directoryProvisioning.update(connectionId, updatePayload);
384
+ logger_1.default.debug(`Updated directory provisioning for connection '${connectionId}'`);
385
+ }
386
+ /**
387
+ * Deletes directory provisioning configuration for a connection.
388
+ */
389
+ async deleteConnectionDirectoryProvisioning(connectionId) {
390
+ if (!connectionId) {
391
+ throw new Error('Connection ID is required to delete directory provisioning configuration.');
392
+ }
393
+ await this.client.connections.directoryProvisioning.delete(connectionId);
394
+ logger_1.default.debug(`Deleted directory provisioning for connection '${connectionId}'`);
395
+ }
396
+ /**
397
+ * This function processes directory provisioning for create, update, and conflict operations.
398
+ * Directory provisioning is only supported for google-apps strategy connections.
399
+ *
400
+ * @param changes - Object containing arrays of connections to create, update, and resolve conflicts for
401
+ */
402
+ async processConnectionDirectoryProvisioning(changes) {
403
+ const { create, update, conflicts } = changes;
404
+ // Build a map of existing connections by ID for quick lookup
405
+ const existingConnectionsMap = (0, lodash_1.keyBy)(this.existing || [], 'id');
406
+ // Filter to only google-apps connections
407
+ const googleAppsWithDirProvFilter = (conn) => conn.strategy === 'google-apps';
408
+ const connectionsToProcess = [
409
+ ...update.filter(googleAppsWithDirProvFilter),
410
+ ...create.filter(googleAppsWithDirProvFilter),
411
+ ...conflicts.filter(googleAppsWithDirProvFilter),
412
+ ];
413
+ if (connectionsToProcess.length === 0) {
414
+ return;
415
+ }
416
+ const directoryConnectionsToUpdate = [];
417
+ const directoryConnectionsToCreate = [];
418
+ const directoryConnectionsToDelete = [];
419
+ for (const conn of connectionsToProcess) {
420
+ if (!conn.id)
421
+ continue;
422
+ const existingConn = existingConnectionsMap[conn.id];
423
+ const existingConfig = existingConn?.directory_provisioning_configuration;
424
+ const proposedConfig = conn.directory_provisioning_configuration;
425
+ if (existingConfig && proposedConfig) {
426
+ directoryConnectionsToUpdate.push(conn);
427
+ }
428
+ else if (!existingConfig && proposedConfig) {
429
+ directoryConnectionsToCreate.push(conn);
430
+ }
431
+ else if (existingConfig && !proposedConfig) {
432
+ directoryConnectionsToDelete.push(conn);
433
+ }
434
+ }
435
+ // Process updates first
436
+ await this.client.pool
437
+ .addEachTask({
438
+ data: directoryConnectionsToUpdate || [],
439
+ generator: (conn) => this.updateConnectionDirectoryProvisioning(conn.id, conn.directory_provisioning_configuration).catch((err) => {
440
+ throw new Error(`Failed to update directory provisioning for connection '${conn.id}':\n${err}`);
441
+ }),
442
+ })
443
+ .promise();
444
+ // Process creates
445
+ await this.client.pool
446
+ .addEachTask({
447
+ data: directoryConnectionsToCreate || [],
448
+ generator: (conn) => this.createConnectionDirectoryProvisioning(conn.id, conn.directory_provisioning_configuration).catch((err) => {
449
+ throw new Error(`Failed to create directory provisioning for connection '${conn.id}':\n${err}`);
450
+ }),
451
+ })
452
+ .promise();
453
+ // Process deletes
454
+ if (this.config('AUTH0_ALLOW_DELETE') === 'true' ||
455
+ this.config('AUTH0_ALLOW_DELETE') === true) {
456
+ await this.client.pool
457
+ .addEachTask({
458
+ data: directoryConnectionsToDelete || [],
459
+ generator: (conn) => this.deleteConnectionDirectoryProvisioning(conn.id).catch((err) => {
460
+ throw new Error(`Failed to delete directory provisioning for connection '${conn.id}':\n${err}`);
461
+ }),
462
+ })
463
+ .promise();
464
+ }
465
+ else if (directoryConnectionsToDelete.length) {
466
+ logger_1.default.warn(`Detected directory provisioning configs to delete. Deletes are disabled (set 'AUTH0_ALLOW_DELETE' to true to allow).\n${directoryConnectionsToDelete
467
+ .map((i) => this.objString(i))
468
+ .join('\n')}`);
469
+ }
470
+ }
289
471
  async getType() {
290
472
  if (this.existing)
291
473
  return this.existing;
@@ -306,10 +488,18 @@ class ConnectionsHandler extends default_1.default {
306
488
  if (!con?.id)
307
489
  return con;
308
490
  const enabledClients = await (0, exports.getConnectionEnabledClients)(this.client, con.id);
491
+ // Cast to Asset to allow adding properties
492
+ let connection = { ...con };
309
493
  if (enabledClients && enabledClients?.length) {
310
- return { ...con, enabled_clients: enabledClients };
494
+ connection.enabled_clients = enabledClients;
495
+ }
496
+ if (connection.strategy === 'google-apps') {
497
+ const dirProvConfig = await this.getConnectionDirectoryProvisioning(con.id);
498
+ if (dirProvConfig) {
499
+ connection.directory_provisioning_configuration = dirProvConfig;
500
+ }
311
501
  }
312
- return con;
502
+ return connection;
313
503
  }));
314
504
  this.existing = connectionsWithEnabledClients;
315
505
  // Apply `scim_configuration` to all the relevant `SCIM` connections. This method mutates `this.existing`.
@@ -361,11 +551,16 @@ class ConnectionsHandler extends default_1.default {
361
551
  if (!isOptionExists) {
362
552
  logger_1.default.warn(`Insufficient scope the update:connections_options scope is required to update ${this.type} options.`);
363
553
  }
554
+ const includedConnections = (assets.include && assets.include.connections) || [];
364
555
  const excludedConnections = (assets.exclude && assets.exclude.connections) || [];
365
- const changes = await this.calcChanges(assets);
366
- await super.processChanges(assets, (0, utils_1.filterExcluded)(changes, excludedConnections));
556
+ let changes = await this.calcChanges(assets);
557
+ changes = (0, utils_1.filterExcluded)(changes, excludedConnections);
558
+ changes = (0, utils_1.filterIncluded)(changes, includedConnections);
559
+ await super.processChanges(assets, changes);
367
560
  // process enabled clients
368
- await (0, exports.processConnectionEnabledClients)(this.client, this.type, (0, utils_1.filterExcluded)(changes, excludedConnections));
561
+ await (0, exports.processConnectionEnabledClients)(this.client, this.type, changes);
562
+ // process directory provisioning
563
+ await this.processConnectionDirectoryProvisioning(changes);
369
564
  }
370
565
  }
371
566
  exports.default = ConnectionsHandler;
@@ -4,5 +4,6 @@ declare const _default: { [key in AssetTypes]: {
4
4
  default: typeof APIHandler;
5
5
  excludeSchema?: any;
6
6
  schema: any;
7
+ includeSchema?: any;
7
8
  }; };
8
9
  export default _default;
@@ -60,6 +60,7 @@ const actions = __importStar(require("./actions"));
60
60
  const triggers = __importStar(require("./triggers"));
61
61
  const organizations = __importStar(require("./organizations"));
62
62
  const attackProtection = __importStar(require("./attackProtection"));
63
+ const riskAssessment = __importStar(require("./riskAssessment"));
63
64
  const logStreams = __importStar(require("./logStreams"));
64
65
  const customDomains = __importStar(require("./customDomains"));
65
66
  const themes = __importStar(require("./themes"));
@@ -100,6 +101,7 @@ const auth0ApiHandlers = {
100
101
  triggers,
101
102
  organizations,
102
103
  attackProtection,
104
+ riskAssessment,
103
105
  logStreams,
104
106
  customDomains,
105
107
  themes,
@@ -0,0 +1,39 @@
1
+ import DefaultAPIHandler from './default';
2
+ import { Assets } from '../../../types';
3
+ import { Management } from 'auth0';
4
+ export declare const schema: {
5
+ type: string;
6
+ properties: {
7
+ settings: {
8
+ type: string;
9
+ properties: {
10
+ enabled: {
11
+ type: string;
12
+ description: string;
13
+ };
14
+ };
15
+ required: string[];
16
+ };
17
+ new_device: {
18
+ type: string;
19
+ properties: {
20
+ remember_for: {
21
+ type: string;
22
+ description: string;
23
+ };
24
+ };
25
+ required: string[];
26
+ };
27
+ };
28
+ required: string[];
29
+ };
30
+ export type RiskAssessment = {
31
+ settings: Management.GetRiskAssessmentsSettingsResponseContent;
32
+ new_device?: Management.GetRiskAssessmentsSettingsNewDeviceResponseContent;
33
+ };
34
+ export default class RiskAssessmentHandler extends DefaultAPIHandler {
35
+ existing: RiskAssessment;
36
+ constructor(config: DefaultAPIHandler);
37
+ getType(): Promise<RiskAssessment>;
38
+ processChanges(assets: Assets): Promise<void>;
39
+ }
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.schema = void 0;
7
+ const default_1 = __importDefault(require("./default"));
8
+ const auth0_1 = require("auth0");
9
+ exports.schema = {
10
+ type: 'object',
11
+ properties: {
12
+ settings: {
13
+ type: 'object',
14
+ properties: {
15
+ enabled: {
16
+ type: 'boolean',
17
+ description: 'Whether or not risk assessment is enabled.',
18
+ },
19
+ },
20
+ required: ['enabled'],
21
+ },
22
+ new_device: {
23
+ type: 'object',
24
+ properties: {
25
+ remember_for: {
26
+ type: 'number',
27
+ description: 'Length of time to remember devices for, in days.',
28
+ },
29
+ },
30
+ required: ['remember_for'],
31
+ },
32
+ },
33
+ required: ['settings'],
34
+ };
35
+ class RiskAssessmentHandler extends default_1.default {
36
+ constructor(config) {
37
+ super({
38
+ ...config,
39
+ type: 'riskAssessment',
40
+ });
41
+ }
42
+ async getType() {
43
+ if (this.existing) {
44
+ return this.existing;
45
+ }
46
+ try {
47
+ const [settings, newDeviceSettings] = await Promise.all([
48
+ this.client.riskAssessments.settings.get(),
49
+ this.client.riskAssessments.settings.newDevice.get().catch((err) => {
50
+ if (err instanceof auth0_1.ManagementError && err?.statusCode === 404) {
51
+ return { remember_for: 0 };
52
+ }
53
+ throw err;
54
+ }),
55
+ ]);
56
+ const riskAssessment = {
57
+ settings: settings,
58
+ new_device: newDeviceSettings,
59
+ ...(newDeviceSettings.remember_for > 0 && {
60
+ new_device: newDeviceSettings,
61
+ }),
62
+ };
63
+ this.existing = riskAssessment;
64
+ return this.existing;
65
+ }
66
+ catch (err) {
67
+ if (err instanceof auth0_1.ManagementError && err.statusCode === 404) {
68
+ const riskAssessment = {
69
+ settings: { enabled: false },
70
+ };
71
+ this.existing = riskAssessment;
72
+ return this.existing;
73
+ }
74
+ throw err;
75
+ }
76
+ }
77
+ async processChanges(assets) {
78
+ const { riskAssessment } = assets;
79
+ // Non-existing section means it doesn't need to be processed
80
+ if (!riskAssessment) {
81
+ return;
82
+ }
83
+ const updates = [];
84
+ // Update main settings (enabled flag)
85
+ updates.push(this.client.riskAssessments.settings.update(riskAssessment?.settings));
86
+ // Update new device settings if provided
87
+ if (riskAssessment.new_device) {
88
+ updates.push(this.client.riskAssessments.settings.newDevice.update(riskAssessment.new_device));
89
+ }
90
+ await Promise.all(updates);
91
+ this.updated += 1;
92
+ this.didUpdate(riskAssessment);
93
+ }
94
+ }
95
+ exports.default = RiskAssessmentHandler;
@@ -190,6 +190,7 @@ class ScimHandler {
190
190
  // Remove `scim_configuration` from `bodyParams`, because `connections.update` doesn't accept it.
191
191
  const { scim_configuration: scimBodyParams } = bodyParams;
192
192
  delete bodyParams.scim_configuration;
193
+ delete bodyParams.directory_provisioning_configuration;
193
194
  // First, update `connections`.
194
195
  const updated = await this.connectionsManager.update(requestParams.id, bodyParams);
195
196
  const idMapEntry = this.idMap.get(requestParams.id);
@@ -223,6 +224,7 @@ class ScimHandler {
223
224
  // Remove `scim_configuration` from `bodyParams`, because `connections.create` doesn't accept it.
224
225
  const { scim_configuration: scimBodyParams } = bodyParams;
225
226
  delete bodyParams.scim_configuration;
227
+ delete bodyParams.directory_provisioning_configuration;
226
228
  // First, create the new `connection`.
227
229
  const data = await this.connectionsManager.create(bodyParams);
228
230
  if (data?.id && scimBodyParams && this.scimScopes.create) {
@@ -11,10 +11,6 @@ export declare const schema: {
11
11
  type: string;
12
12
  description: string;
13
13
  };
14
- id: {
15
- type: string;
16
- description: string;
17
- };
18
14
  subject_token_type: {
19
15
  type: string;
20
16
  description: string;
@@ -28,16 +24,6 @@ export declare const schema: {
28
24
  enum: string[];
29
25
  description: string;
30
26
  };
31
- created_at: {
32
- type: string;
33
- format: string;
34
- description: string;
35
- };
36
- updated_at: {
37
- type: string;
38
- format: string;
39
- description: string;
40
- };
41
27
  };
42
28
  required: string[];
43
29
  };
@@ -55,10 +55,6 @@ exports.schema = {
55
55
  type: 'string',
56
56
  description: 'The name of the token exchange profile',
57
57
  },
58
- id: {
59
- type: 'string',
60
- description: 'The unique identifier of the token exchange profile',
61
- },
62
58
  subject_token_type: {
63
59
  type: 'string',
64
60
  description: 'The URI representing the subject token type',
@@ -72,16 +68,6 @@ exports.schema = {
72
68
  enum: ['custom_authentication'],
73
69
  description: 'The type of token exchange profile',
74
70
  },
75
- created_at: {
76
- type: 'string',
77
- format: 'date-time',
78
- description: 'The timestamp when the profile was created',
79
- },
80
- updated_at: {
81
- type: 'string',
82
- format: 'date-time',
83
- description: 'The timestamp when the profile was last updated',
84
- },
85
71
  },
86
72
  required: ['name', 'subject_token_type', 'action', 'type'],
87
73
  },
@@ -92,10 +78,10 @@ class TokenExchangeProfilesHandler extends default_1.default {
92
78
  ...config,
93
79
  type: 'tokenExchangeProfiles',
94
80
  id: 'id',
95
- identifiers: ['id', 'name'],
81
+ identifiers: ['id', 'subject_token_type'],
96
82
  // Only name and subject_token_type can be updated
97
- stripUpdateFields: ['id', 'created_at', 'updated_at', 'action_id', 'type'],
98
- stripCreateFields: ['id', 'created_at', 'updated_at'],
83
+ stripUpdateFields: ['created_at', 'updated_at', 'action_id', 'type'],
84
+ stripCreateFields: ['created_at', 'updated_at'],
99
85
  });
100
86
  }
101
87
  sanitizeForExport(profile, actions) {
@@ -145,9 +131,9 @@ class TokenExchangeProfilesHandler extends default_1.default {
145
131
  paginate: true,
146
132
  });
147
133
  // Fetch all actions to map action_id to action name
148
- const actions = await this.getActions();
134
+ this.actions = await this.getActions();
149
135
  // Map action_id to action name for each profile
150
- this.existing = profiles.map((profile) => this.sanitizeForExport(profile, actions));
136
+ this.existing = profiles.map((profile) => this.sanitizeForExport(profile, this.actions ?? []));
151
137
  return this.existing;
152
138
  }
153
139
  catch (err) {
@@ -163,31 +149,34 @@ class TokenExchangeProfilesHandler extends default_1.default {
163
149
  // Do nothing if not set
164
150
  if (!tokenExchangeProfiles)
165
151
  return;
166
- // Fetch actions to resolve action names to IDs
167
- const actions = await this.getActions();
168
- // Map action names to action_ids before processing
169
- const sanitizedProfiles = tokenExchangeProfiles.map((profile) => this.sanitizeForAPI(profile, actions));
170
- // Create modified assets with sanitized profiles
171
- const modifiedAssets = {
172
- ...assets,
173
- tokenExchangeProfiles: sanitizedProfiles,
174
- };
175
152
  // Calculate changes
176
- const { del, update, create, conflicts } = await this.calcChanges(modifiedAssets);
153
+ const { del, update, create, conflicts } = await this.calcChanges(assets);
177
154
  logger_1.default.debug(`Start processChanges for tokenExchangeProfiles [delete:${del.length}] [update:${update.length}], [create:${create.length}], [conflicts:${conflicts.length}]`);
155
+ // Fetch actions to resolve action names to IDs
156
+ if (!this.actions || this.actions.length === 0) {
157
+ this.actions = await this.getActions();
158
+ }
178
159
  // Process changes in order: delete, create, update
179
160
  if (del.length > 0) {
180
- await this.deleteTokenExchangeProfiles(del);
161
+ await this.deleteTokenExchangeProfiles(del.map((profile) => this.sanitizeForAPI(profile, this.actions ?? [])));
181
162
  }
182
163
  if (create.length > 0) {
183
- await this.createTokenExchangeProfiles(create);
164
+ await this.createTokenExchangeProfiles(create.map((profile) => this.sanitizeForAPI(profile, this.actions ?? [])));
184
165
  }
185
166
  if (update.length > 0) {
186
- await this.updateTokenExchangeProfiles(update);
167
+ await this.updateTokenExchangeProfiles(update.map((profile) => this.sanitizeForAPI(profile, this.actions ?? [])));
187
168
  }
188
169
  }
189
170
  async createTokenExchangeProfile(profile) {
190
- const { id, created_at, updated_at, ...createParams } = profile;
171
+ if (!profile.name || !profile.subject_token_type || !profile.action_id || !profile.type) {
172
+ throw new Error(`Cannot create token exchange profile missing required fields`);
173
+ }
174
+ const createParams = {
175
+ name: profile.name,
176
+ subject_token_type: profile.subject_token_type,
177
+ action_id: profile.action_id,
178
+ type: profile.type,
179
+ };
191
180
  const created = await this.client.tokenExchangeProfiles.create(createParams);
192
181
  return created;
193
182
  }
@@ -207,10 +196,14 @@ class TokenExchangeProfilesHandler extends default_1.default {
207
196
  .promise();
208
197
  }
209
198
  async updateTokenExchangeProfile(profile) {
210
- const { id, created_at, updated_at, action_id, type, ...updateParams } = profile;
199
+ const { id, name, subject_token_type } = profile;
211
200
  if (!id) {
212
201
  throw new Error(`Cannot update token exchange profile "${profile.name}" - missing id`);
213
202
  }
203
+ const updateParams = {
204
+ name,
205
+ subject_token_type,
206
+ };
214
207
  await this.client.tokenExchangeProfiles.update(id, updateParams);
215
208
  }
216
209
  async updateTokenExchangeProfiles(updates) {
@@ -9,6 +9,13 @@ declare const _default: {
9
9
  };
10
10
  default: {};
11
11
  };
12
+ include: {
13
+ type: string;
14
+ properties: {
15
+ [key: string]: Object;
16
+ };
17
+ default: {};
18
+ };
12
19
  };
13
20
  additionalProperties: boolean;
14
21
  };
@@ -14,6 +14,12 @@ const excludeSchema = Object.entries(handlers_1.default).reduce((map, [name, obj
14
14
  }
15
15
  return map;
16
16
  }, {});
17
+ const includeSchema = Object.entries(handlers_1.default).reduce((map, [name, obj]) => {
18
+ if (obj.includeSchema) {
19
+ map[name] = obj.includeSchema;
20
+ }
21
+ return map;
22
+ }, {});
17
23
  exports.default = {
18
24
  type: 'object',
19
25
  $schema: 'http://json-schema.org/draft-07/schema#',
@@ -24,6 +30,11 @@ exports.default = {
24
30
  properties: { ...excludeSchema },
25
31
  default: {},
26
32
  },
33
+ include: {
34
+ type: 'object',
35
+ properties: { ...includeSchema },
36
+ default: {},
37
+ },
27
38
  },
28
39
  additionalProperties: false,
29
40
  };
@@ -57,6 +57,7 @@ declare const constants: {
57
57
  CONNECTIONS_ID_NAME: string;
58
58
  ROLES_DIRECTORY: string;
59
59
  ATTACK_PROTECTION_DIRECTORY: string;
60
+ RISK_ASSESSMENT_DIRECTORY: string;
60
61
  GUARDIAN_FACTORS: string[];
61
62
  GUARDIAN_POLICIES: string[];
62
63
  GUARDIAN_PHONE_PROVIDERS: string[];
@@ -103,6 +103,7 @@ const constants = {
103
103
  CONNECTIONS_ID_NAME: 'id',
104
104
  ROLES_DIRECTORY: 'roles',
105
105
  ATTACK_PROTECTION_DIRECTORY: 'attack-protection',
106
+ RISK_ASSESSMENT_DIRECTORY: 'risk-assessment',
106
107
  GUARDIAN_FACTORS: [
107
108
  'sms',
108
109
  'push-notification',
@@ -19,6 +19,7 @@ export declare function stripFields(obj: Asset, fields: string[]): Asset;
19
19
  export declare function getEnabledClients(assets: Assets, connection: Asset, existing: Asset[], clients: Asset[]): string[] | undefined;
20
20
  export declare function duplicateItems(arr: Asset[], key: string): Asset[];
21
21
  export declare function filterExcluded(changes: CalculatedChanges, exclude: string[]): CalculatedChanges;
22
+ export declare function filterIncluded(changes: CalculatedChanges, include: string[]): CalculatedChanges;
22
23
  export declare function areArraysEquals(x: any[], y: any[]): boolean;
23
24
  export declare const obfuscateSensitiveValues: (data: Asset | Asset[] | null, sensitiveFieldsToObfuscate: string[]) => Asset | Asset[] | null;
24
25
  export declare const stripObfuscatedFieldsFromPayload: (data: Asset | Asset[] | null, obfuscatedFields: string[]) => Asset | Asset[] | null;
@@ -50,6 +50,7 @@ exports.stripFields = stripFields;
50
50
  exports.getEnabledClients = getEnabledClients;
51
51
  exports.duplicateItems = duplicateItems;
52
52
  exports.filterExcluded = filterExcluded;
53
+ exports.filterIncluded = filterIncluded;
53
54
  exports.areArraysEquals = areArraysEquals;
54
55
  exports.sleep = sleep;
55
56
  exports.maskSecretAtPath = maskSecretAtPath;
@@ -213,6 +214,19 @@ function filterExcluded(changes, exclude) {
213
214
  conflicts: filter(conflicts),
214
215
  };
215
216
  }
217
+ function filterIncluded(changes, include) {
218
+ const { del, update, create, conflicts } = changes;
219
+ if (!include || !include.length) {
220
+ return changes;
221
+ }
222
+ const filter = (list) => list.filter((item) => include.includes(item.name));
223
+ return {
224
+ del: filter(del),
225
+ update: filter(update),
226
+ create: filter(create),
227
+ conflicts: filter(conflicts),
228
+ };
229
+ }
216
230
  function areArraysEquals(x, y) {
217
231
  return lodash_1.default.isEqual(x && x.sort(), y && y.sort());
218
232
  }
package/lib/types.d.ts CHANGED
@@ -18,6 +18,7 @@ import { NetworkACL } from './tools/auth0/handlers/networkACLs';
18
18
  import { UserAttributeProfile } from './tools/auth0/handlers/userAttributeProfiles';
19
19
  import { AttackProtection } from './tools/auth0/handlers/attackProtection';
20
20
  import { TokenExchangeProfile } from './tools/auth0/handlers/tokenExchangeProfiles';
21
+ import { RiskAssessment } from './tools/auth0/handlers/riskAssessment';
21
22
  type SharedPaginationParams = {
22
23
  checkpoint?: boolean;
23
24
  paginate?: boolean;
@@ -75,6 +76,7 @@ export type Config = {
75
76
  INCLUDED_PROPS?: {
76
77
  [key: string]: string[];
77
78
  };
79
+ AUTH0_INCLUDED_CONNECTIONS?: string[];
78
80
  AUTH0_IGNORE_UNAVAILABLE_MIGRATIONS?: boolean;
79
81
  AUTH0_EXCLUDED_RULES?: string[];
80
82
  AUTH0_EXCLUDED_CLIENTS?: string[];
@@ -90,6 +92,7 @@ export type Asset = {
90
92
  export type Assets = Partial<{
91
93
  actions: Action[] | null;
92
94
  attackProtection: AttackProtection | null;
95
+ riskAssessment: RiskAssessment | null;
93
96
  branding: (Asset & {
94
97
  templates?: {
95
98
  template: string;
@@ -129,6 +132,9 @@ export type Assets = Partial<{
129
132
  exclude?: {
130
133
  [key: string]: string[];
131
134
  };
135
+ include?: {
136
+ [key: string]: string[];
137
+ };
132
138
  clientsOrig: Asset[] | null;
133
139
  themes: Theme[] | null;
134
140
  forms: Form[] | null;
@@ -147,7 +153,7 @@ export type CalculatedChanges = {
147
153
  conflicts: Asset[];
148
154
  create: Asset[];
149
155
  };
150
- export type AssetTypes = 'rules' | 'rulesConfigs' | 'hooks' | 'pages' | 'databases' | 'clientGrants' | 'resourceServers' | 'clients' | 'connections' | 'tenant' | 'emailProvider' | 'emailTemplates' | 'guardianFactors' | 'guardianFactorProviders' | 'guardianFactorTemplates' | 'guardianPhoneFactorMessageTypes' | 'guardianPhoneFactorSelectedProvider' | 'guardianPolicies' | 'roles' | 'actions' | 'organizations' | 'triggers' | 'attackProtection' | 'branding' | 'phoneProviders' | 'phoneTemplates' | 'logStreams' | 'prompts' | 'customDomains' | 'themes' | 'forms' | 'flows' | 'flowVaultConnections' | 'selfServiceProfiles' | 'networkACLs' | 'userAttributeProfiles' | 'connectionProfiles' | 'tokenExchangeProfiles';
156
+ export type AssetTypes = 'rules' | 'rulesConfigs' | 'hooks' | 'pages' | 'databases' | 'clientGrants' | 'resourceServers' | 'clients' | 'connections' | 'tenant' | 'emailProvider' | 'emailTemplates' | 'guardianFactors' | 'guardianFactorProviders' | 'guardianFactorTemplates' | 'guardianPhoneFactorMessageTypes' | 'guardianPhoneFactorSelectedProvider' | 'guardianPolicies' | 'roles' | 'actions' | 'organizations' | 'triggers' | 'attackProtection' | 'riskAssessment' | 'branding' | 'phoneProviders' | 'phoneTemplates' | 'logStreams' | 'prompts' | 'customDomains' | 'themes' | 'forms' | 'flows' | 'flowVaultConnections' | 'selfServiceProfiles' | 'networkACLs' | 'userAttributeProfiles' | 'connectionProfiles' | 'tokenExchangeProfiles';
151
157
  export type KeywordMappings = {
152
158
  [key: string]: (string | number)[] | string | number;
153
159
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auth0-deploy-cli",
3
- "version": "8.23.2",
3
+ "version": "8.25.0",
4
4
  "description": "A command line tool for deploying updates to your Auth0 tenant",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -42,7 +42,7 @@
42
42
  "nconf": "^0.13.0",
43
43
  "promise-pool-executor": "^1.1.1",
44
44
  "sanitize-filename": "^1.6.3",
45
- "undici": "^7.16.0",
45
+ "undici": "^7.18.0",
46
46
  "winston": "^3.19.0",
47
47
  "yargs": "^15.4.1"
48
48
  },
@@ -52,8 +52,8 @@
52
52
  "@types/mocha": "^10.0.10",
53
53
  "@types/nconf": "^0.10.7",
54
54
  "@eslint/js": "^9.39.2",
55
- "@typescript-eslint/eslint-plugin": "^8.50.0",
56
- "@typescript-eslint/parser": "^8.50.0",
55
+ "@typescript-eslint/eslint-plugin": "^8.52.0",
56
+ "@typescript-eslint/parser": "^8.52.0",
57
57
  "chai": "^4.5.0",
58
58
  "chai-as-promised": "^7.1.2",
59
59
  "eslint": "^9.39.2",