auth0-deploy-cli 9.0.0-beta.2 → 9.1.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.
- package/AGENTS.md +2 -357
- package/CHANGELOG.md +185 -10
- package/CLAUDE.md +138 -2
- package/README.md +1 -1
- package/lib/context/defaults.d.ts +7 -0
- package/lib/context/defaults.js +74 -30
- package/lib/context/directory/handlers/actionModules.js +1 -4
- package/lib/context/directory/handlers/actions.js +1 -4
- package/lib/context/directory/handlers/attackProtection.js +11 -1
- package/lib/context/directory/handlers/branding.js +4 -1
- package/lib/context/directory/handlers/clientAuthCredentials.d.ts +5 -0
- package/lib/context/directory/handlers/clientAuthCredentials.js +13 -0
- package/lib/context/directory/handlers/clientGrants.js +78 -24
- package/lib/context/directory/handlers/clients.js +20 -3
- package/lib/context/directory/handlers/connections.js +19 -5
- package/lib/context/directory/handlers/databases.js +1 -4
- package/lib/context/directory/handlers/emailTemplates.js +5 -0
- package/lib/context/directory/handlers/guardianEmailFactorSettings.d.ts +5 -0
- package/lib/context/directory/handlers/guardianEmailFactorSettings.js +38 -0
- package/lib/context/directory/handlers/guardianPhoneFactorSettings.d.ts +5 -0
- package/lib/context/directory/handlers/guardianPhoneFactorSettings.js +38 -0
- package/lib/context/directory/handlers/guardianSettings.d.ts +5 -0
- package/lib/context/directory/handlers/guardianSettings.js +38 -0
- package/lib/context/directory/handlers/hooks.js +1 -4
- package/lib/context/directory/handlers/index.js +12 -0
- package/lib/context/directory/handlers/networkACLKeys.d.ts +6 -0
- package/lib/context/directory/handlers/networkACLKeys.js +54 -0
- package/lib/context/directory/handlers/prompts.js +7 -3
- package/lib/context/directory/handlers/rateLimitPolicies.d.ts +6 -0
- package/lib/context/directory/handlers/rateLimitPolicies.js +53 -0
- package/lib/context/directory/handlers/rules.js +1 -4
- package/lib/context/directory/index.js +1 -4
- package/lib/context/index.js +32 -31
- package/lib/context/yaml/handlers/attackProtection.js +5 -2
- package/lib/context/yaml/handlers/branding.js +4 -1
- package/lib/context/yaml/handlers/clientAuthCredentials.d.ts +5 -0
- package/lib/context/yaml/handlers/clientAuthCredentials.js +13 -0
- package/lib/context/yaml/handlers/clients.js +19 -1
- package/lib/context/yaml/handlers/connections.js +8 -1
- package/lib/context/yaml/handlers/flows.js +3 -0
- package/lib/context/yaml/handlers/forms.js +3 -0
- package/lib/context/yaml/handlers/guardianEmailFactorSettings.d.ts +5 -0
- package/lib/context/yaml/handlers/guardianEmailFactorSettings.js +15 -0
- package/lib/context/yaml/handlers/guardianPhoneFactorSettings.d.ts +5 -0
- package/lib/context/yaml/handlers/guardianPhoneFactorSettings.js +15 -0
- package/lib/context/yaml/handlers/guardianSettings.d.ts +5 -0
- package/lib/context/yaml/handlers/guardianSettings.js +15 -0
- package/lib/context/yaml/handlers/index.js +12 -0
- package/lib/context/yaml/handlers/networkACLKeys.d.ts +6 -0
- package/lib/context/yaml/handlers/networkACLKeys.js +42 -0
- package/lib/context/yaml/handlers/prompts.js +3 -1
- package/lib/context/yaml/handlers/rateLimitPolicies.d.ts +6 -0
- package/lib/context/yaml/handlers/rateLimitPolicies.js +27 -0
- package/lib/context/yaml/index.js +85 -7
- package/lib/keywordPreservation.d.ts +1 -1
- package/lib/keywordPreservation.js +2 -1
- package/lib/readonly.js +5 -0
- package/lib/tools/auth0/handlers/attackProtection.d.ts +12 -0
- package/lib/tools/auth0/handlers/attackProtection.js +66 -6
- package/lib/tools/auth0/handlers/clientAuthCredentials.d.ts +27 -0
- package/lib/tools/auth0/handlers/clientAuthCredentials.js +234 -0
- package/lib/tools/auth0/handlers/clientAuthCredentialsPre.d.ts +38 -0
- package/lib/tools/auth0/handlers/clientAuthCredentialsPre.js +123 -0
- package/lib/tools/auth0/handlers/clientGrants.d.ts +1 -1
- package/lib/tools/auth0/handlers/clients.d.ts +106 -0
- package/lib/tools/auth0/handlers/clients.js +207 -3
- package/lib/tools/auth0/handlers/connectionProfiles.d.ts +27 -0
- package/lib/tools/auth0/handlers/connectionProfiles.js +30 -0
- package/lib/tools/auth0/handlers/connections.d.ts +34 -6
- package/lib/tools/auth0/handlers/connections.js +75 -11
- package/lib/tools/auth0/handlers/databases.d.ts +28 -0
- package/lib/tools/auth0/handlers/databases.js +58 -24
- package/lib/tools/auth0/handlers/default.d.ts +23 -0
- package/lib/tools/auth0/handlers/default.js +47 -29
- package/lib/tools/auth0/handlers/eventStreams.js +10 -2
- package/lib/tools/auth0/handlers/guardianEmailFactorSettings.d.ts +22 -0
- package/lib/tools/auth0/handlers/guardianEmailFactorSettings.js +77 -0
- package/lib/tools/auth0/handlers/guardianFactorTemplates.js +13 -4
- package/lib/tools/auth0/handlers/guardianPhoneFactorMessageTypes.js +11 -9
- package/lib/tools/auth0/handlers/guardianPhoneFactorSelectedProvider.js +11 -9
- package/lib/tools/auth0/handlers/guardianPhoneFactorSettings.d.ts +22 -0
- package/lib/tools/auth0/handlers/guardianPhoneFactorSettings.js +77 -0
- package/lib/tools/auth0/handlers/guardianPolicies.js +11 -1
- package/lib/tools/auth0/handlers/guardianSettings.d.ts +30 -0
- package/lib/tools/auth0/handlers/guardianSettings.js +85 -0
- package/lib/tools/auth0/handlers/hooks.js +1 -1
- package/lib/tools/auth0/handlers/index.js +16 -0
- package/lib/tools/auth0/handlers/networkACLKeys.d.ts +45 -0
- package/lib/tools/auth0/handlers/networkACLKeys.js +177 -0
- package/lib/tools/auth0/handlers/networkACLs.d.ts +132 -2
- package/lib/tools/auth0/handlers/networkACLs.js +100 -16
- package/lib/tools/auth0/handlers/organizations.d.ts +33 -1
- package/lib/tools/auth0/handlers/organizations.js +177 -19
- package/lib/tools/auth0/handlers/phoneProvider.js +10 -2
- package/lib/tools/auth0/handlers/phoneTemplates.d.ts +4 -1
- package/lib/tools/auth0/handlers/phoneTemplates.js +67 -10
- package/lib/tools/auth0/handlers/prompts.d.ts +17 -0
- package/lib/tools/auth0/handlers/prompts.js +47 -14
- package/lib/tools/auth0/handlers/rateLimitPolicies.d.ts +81 -0
- package/lib/tools/auth0/handlers/rateLimitPolicies.js +203 -0
- package/lib/tools/auth0/handlers/resourceServers.d.ts +48 -0
- package/lib/tools/auth0/handlers/resourceServers.js +56 -2
- package/lib/tools/auth0/handlers/riskAssessment.d.ts +1 -1
- package/lib/tools/auth0/handlers/riskAssessment.js +19 -1
- package/lib/tools/auth0/handlers/roles.d.ts +4 -0
- package/lib/tools/auth0/handlers/roles.js +27 -9
- package/lib/tools/auth0/handlers/rules.js +19 -7
- package/lib/tools/auth0/handlers/scimHandler.js +8 -3
- package/lib/tools/auth0/handlers/tenant.d.ts +45 -0
- package/lib/tools/auth0/handlers/tenant.js +48 -0
- package/lib/tools/auth0/handlers/themes.d.ts +37 -1
- package/lib/tools/auth0/handlers/themes.js +64 -0
- package/lib/tools/auth0/handlers/tokenExchangeProfiles.js +3 -1
- package/lib/tools/auth0/index.js +12 -6
- package/lib/tools/calculateDryRunChanges.js +12 -8
- package/lib/tools/constants.d.ts +3 -0
- package/lib/tools/constants.js +8 -0
- package/lib/tools/utils.d.ts +3 -0
- package/lib/tools/utils.js +41 -2
- package/lib/types.d.ts +10 -1
- package/lib/utils.d.ts +6 -0
- package/lib/utils.js +17 -2
- package/package.json +2 -2
- package/references/code-style.md +133 -0
- package/references/commands.md +98 -0
- package/references/docs-update.md +34 -0
- package/references/git-workflow.md +135 -0
- package/references/pitfalls.md +62 -0
- package/references/testing.md +118 -0
|
@@ -59,13 +59,76 @@ const myOrganizationConfigurationSchema = {
|
|
|
59
59
|
enum: Object.values(auth0_1.Management.ClientMyOrganizationDeletionBehaviorEnum),
|
|
60
60
|
description: 'The deletion behavior for My Organization connections created by this client',
|
|
61
61
|
},
|
|
62
|
+
third_party_client_access: {
|
|
63
|
+
type: 'object',
|
|
64
|
+
description: 'Controls whether third-party clients can access the organization via the My Organization API.',
|
|
65
|
+
properties: {
|
|
66
|
+
default_value: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
enum: Object.values(auth0_1.Management.ClientMyOrganizationConfigurationThirdPartyClientAccessDefaultValueEnum),
|
|
69
|
+
description: 'The default third-party client access value.',
|
|
70
|
+
},
|
|
71
|
+
allowed_values: {
|
|
72
|
+
type: 'array',
|
|
73
|
+
items: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
enum: Object.values(auth0_1.Management.ClientMyOrganizationConfigurationThirdPartyClientAccessAllowedValuesEnum),
|
|
76
|
+
},
|
|
77
|
+
uniqueItems: true,
|
|
78
|
+
description: 'The allowed third-party client access values.',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
required: ['default_value', 'allowed_values'],
|
|
82
|
+
},
|
|
62
83
|
invitation_landing_client_id: {
|
|
63
84
|
type: 'string',
|
|
64
85
|
description: 'The client ID of the invitation landing client for the My Organization configuration',
|
|
65
86
|
},
|
|
87
|
+
enforce_permission_ceiling: {
|
|
88
|
+
type: 'boolean',
|
|
89
|
+
description: 'When true, limits the permissions that organization admins can assign to members to only those held by the admin themselves. Early Access, gated by the my_org_member_management_ea feature flag.',
|
|
90
|
+
},
|
|
91
|
+
enforce_self_assignment_restriction: {
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
description: 'When true, prevents organization admins from assigning permissions to themselves. Early Access, gated by the my_org_member_management_ea feature flag.',
|
|
94
|
+
},
|
|
66
95
|
},
|
|
67
96
|
required: ['allowed_strategies', 'connection_deletion_behavior'],
|
|
68
97
|
};
|
|
98
|
+
const tokenVaultPrivilegedAccessSchema = {
|
|
99
|
+
type: ['object', 'null'],
|
|
100
|
+
description: 'Settings for Token Vault Privileged Access, hardening a privileged client by restricting the caller IPs, connections, and scopes it may use at runtime. Early Access, gated by the token_vault_subject_type_jwt_ea_rollout feature flag. Export-only: this object is exported for visibility but is not deployed by the Deploy CLI (it is stripped from create/update payloads because the required credentials are tenant-specific ids). Manage it directly on the tenant.',
|
|
101
|
+
properties: {
|
|
102
|
+
ip_allowlist: {
|
|
103
|
+
type: 'array',
|
|
104
|
+
description: 'IPv4/IPv6 addresses or CIDR ranges permitted to call token exchange on behalf of this privileged client. When the EA flag is on, this is required (non-empty) on create if token_vault_privileged_access is being set.',
|
|
105
|
+
items: {
|
|
106
|
+
type: 'string',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
grants: {
|
|
110
|
+
type: 'array',
|
|
111
|
+
description: 'Connection/scope pin objects restricting which federated connections and OAuth scopes the privileged client may use at runtime. Maximum 5 connections; maximum 20 scopes in total across all connections.',
|
|
112
|
+
items: {
|
|
113
|
+
type: 'object',
|
|
114
|
+
properties: {
|
|
115
|
+
connection: {
|
|
116
|
+
type: 'string',
|
|
117
|
+
description: 'The connection name (e.g. google-oauth2). Validated at runtime; the connection need not exist at configuration time.',
|
|
118
|
+
},
|
|
119
|
+
scopes: {
|
|
120
|
+
type: 'array',
|
|
121
|
+
description: 'The OAuth scopes permitted for that connection.',
|
|
122
|
+
items: {
|
|
123
|
+
type: 'string',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
required: ['connection', 'scopes'],
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
};
|
|
69
132
|
exports.schema = {
|
|
70
133
|
type: 'array',
|
|
71
134
|
items: {
|
|
@@ -221,10 +284,51 @@ exports.schema = {
|
|
|
221
284
|
},
|
|
222
285
|
additionalProperties: true,
|
|
223
286
|
},
|
|
287
|
+
identity_assertion_authorization_grant: {
|
|
288
|
+
type: 'object',
|
|
289
|
+
description: 'Settings for Cross App Access (ID-JAG) token exchange. Early Access. Enables the client to request identity assertion authorization grants.',
|
|
290
|
+
properties: {
|
|
291
|
+
active: {
|
|
292
|
+
type: 'boolean',
|
|
293
|
+
description: 'Indicates whether the client can request an identity assertion authorization grant (ID-JAG) via token exchange.',
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
required: ['active'],
|
|
297
|
+
additionalProperties: false,
|
|
298
|
+
},
|
|
299
|
+
anonymous_sessions: {
|
|
300
|
+
type: 'object',
|
|
301
|
+
description: 'Configuration for anonymous sessions for this client.',
|
|
302
|
+
properties: {
|
|
303
|
+
active: {
|
|
304
|
+
type: 'boolean',
|
|
305
|
+
description: 'Whether anonymous sessions are enabled for this client.',
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
required: ['active'],
|
|
309
|
+
additionalProperties: false,
|
|
310
|
+
},
|
|
224
311
|
app_type: {
|
|
225
312
|
type: 'string',
|
|
226
313
|
description: 'The type of application this client represents',
|
|
227
314
|
},
|
|
315
|
+
b2b_integration_configuration: {
|
|
316
|
+
type: ['object', 'null'],
|
|
317
|
+
description: 'B2B integration configuration. Early Access. Required feature flag: enterprise_connect_entitled.',
|
|
318
|
+
properties: {
|
|
319
|
+
integration_type: {
|
|
320
|
+
type: 'string',
|
|
321
|
+
enum: ['custom_auth_server', 'third_party', 'application'],
|
|
322
|
+
description: 'The type of integration used to connect to this B2B integration client.',
|
|
323
|
+
},
|
|
324
|
+
sso_profiles: {
|
|
325
|
+
type: 'array',
|
|
326
|
+
description: 'List of SSO profile IDs linked to this B2B integration client. Maximum 1 entry.',
|
|
327
|
+
items: { type: 'string' },
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
additionalProperties: false,
|
|
331
|
+
},
|
|
228
332
|
resource_server_identifier: {
|
|
229
333
|
type: 'string',
|
|
230
334
|
description: 'The identifier of a resource server in your tenant. This property links a client to a resource server indicating that the client IS that resource server. Can only be set when app_type=resource_server.',
|
|
@@ -250,7 +354,7 @@ exports.schema = {
|
|
|
250
354
|
description: 'An ordered array of notification channels enabled for CIBA (Client-Initiated Backchannel Authentication) requests. Channels are evaluated in the order specified.',
|
|
251
355
|
items: {
|
|
252
356
|
type: 'string',
|
|
253
|
-
enum: ['guardian-push', 'email'],
|
|
357
|
+
enum: ['guardian-push', 'email', 'my-account'],
|
|
254
358
|
},
|
|
255
359
|
},
|
|
256
360
|
skip_non_verifiable_callback_uri_confirmation_prompt: {
|
|
@@ -332,6 +436,7 @@ exports.schema = {
|
|
|
332
436
|
},
|
|
333
437
|
},
|
|
334
438
|
},
|
|
439
|
+
token_vault_privileged_access: tokenVaultPrivilegedAccessSchema,
|
|
335
440
|
third_party_security_mode: {
|
|
336
441
|
type: 'string',
|
|
337
442
|
enum: ['strict', 'permissive'],
|
|
@@ -460,6 +565,40 @@ const createClientSanitizer = (clients) => {
|
|
|
460
565
|
},
|
|
461
566
|
};
|
|
462
567
|
};
|
|
568
|
+
/**
|
|
569
|
+
* On export, remove `credentials` from `token_vault_privileged_access`.
|
|
570
|
+
*
|
|
571
|
+
* Auth0 returns these as tenant-specific credential references (`{ id }`) — never
|
|
572
|
+
* names or key material — so they are not portable across tenants and must never be
|
|
573
|
+
* written to disk. `ip_allowlist` and `grants` are kept for visibility. Mutates and
|
|
574
|
+
* returns the same client.
|
|
575
|
+
*/
|
|
576
|
+
const stripTokenVaultCredentialsOnExport = (client) => {
|
|
577
|
+
const tvpa = client
|
|
578
|
+
.token_vault_privileged_access;
|
|
579
|
+
if (tvpa && 'credentials' in tvpa) {
|
|
580
|
+
delete tvpa.credentials;
|
|
581
|
+
}
|
|
582
|
+
return client;
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* On write (create/update), remove the entire `token_vault_privileged_access` object.
|
|
586
|
+
*
|
|
587
|
+
* The Management API requires `credentials` whenever `token_vault_privileged_access`
|
|
588
|
+
* is present in the payload, but those credentials are tenant-specific ids that the
|
|
589
|
+
* Deploy CLI intentionally never persists (see stripTokenVaultCredentialsOnExport).
|
|
590
|
+
* Sending the object without `credentials` fails validation ("Missing required
|
|
591
|
+
* property: credentials"); sending it with exported ids would re-send stale ids on a
|
|
592
|
+
* cross-tenant deploy. The Deploy CLI therefore does not manage this field — it is
|
|
593
|
+
* export-only. Manage `token_vault_privileged_access` directly on the tenant.
|
|
594
|
+
* Mutates and returns the same client.
|
|
595
|
+
*/
|
|
596
|
+
const stripTokenVaultPrivilegedAccessOnWrite = (client) => {
|
|
597
|
+
if ('token_vault_privileged_access' in client) {
|
|
598
|
+
delete client.token_vault_privileged_access;
|
|
599
|
+
}
|
|
600
|
+
return client;
|
|
601
|
+
};
|
|
463
602
|
class ClientHandler extends default_1.default {
|
|
464
603
|
constructor(config) {
|
|
465
604
|
super({
|
|
@@ -482,6 +621,9 @@ class ClientHandler extends default_1.default {
|
|
|
482
621
|
'jwks_uri',
|
|
483
622
|
// third_party_security_mode is immutable after creation; PATCH returns 400
|
|
484
623
|
'third_party_security_mode',
|
|
624
|
+
// API-generated timestamps; PATCH returns 400 if present
|
|
625
|
+
'created_at',
|
|
626
|
+
'updated_at',
|
|
485
627
|
],
|
|
486
628
|
functions: {
|
|
487
629
|
create: (client) => this.createClient(client),
|
|
@@ -566,6 +708,21 @@ class ClientHandler extends default_1.default {
|
|
|
566
708
|
delete item.refresh_token;
|
|
567
709
|
}
|
|
568
710
|
}
|
|
711
|
+
// Strip client_authentication_methods — the clientAuthCredentials handler (order 70)
|
|
712
|
+
// owns this field entirely. Auth0 rejects credential objects with name/credential_type in PATCH.
|
|
713
|
+
// Strip token_endpoint_auth_method only when client_authentication_methods is present in config:
|
|
714
|
+
// Auth0 rejects it in PATCH while a client has active credentials. For these clients the
|
|
715
|
+
// clientAuthCredentials handler (order 70) owns token_endpoint_auth_method too.
|
|
716
|
+
// For clients without client_authentication_methods, credentials were already cleared by
|
|
717
|
+
// clientAuthCredentialsPre (order 40), so token_endpoint_auth_method passes through safely.
|
|
718
|
+
if (item.client_authentication_methods) {
|
|
719
|
+
delete item.token_endpoint_auth_method;
|
|
720
|
+
}
|
|
721
|
+
delete item.client_authentication_methods;
|
|
722
|
+
// token_vault_privileged_access requires tenant-specific credential ids that
|
|
723
|
+
// the Deploy CLI never persists. Strip the whole object on write so we neither
|
|
724
|
+
// re-send stale ids nor fail validation for the missing credentials property.
|
|
725
|
+
stripTokenVaultPrivilegedAccessOnWrite(item);
|
|
569
726
|
return item;
|
|
570
727
|
});
|
|
571
728
|
};
|
|
@@ -587,7 +744,38 @@ class ClientHandler extends default_1.default {
|
|
|
587
744
|
is_global: false,
|
|
588
745
|
...((0, utils_1.shouldExcludeThirdPartyClients)(this.config) && { is_first_party: true }),
|
|
589
746
|
});
|
|
590
|
-
|
|
747
|
+
const sanitized = createClientSanitizer(clients)
|
|
748
|
+
.sanitizeCrossOriginAuth(false)
|
|
749
|
+
.get()
|
|
750
|
+
// token_vault_privileged_access.credentials are returned as tenant-specific
|
|
751
|
+
// ids — strip them so they are never exported to disk.
|
|
752
|
+
.map(stripTokenVaultCredentialsOnExport);
|
|
753
|
+
// Enrich credential stubs with name and credential_type for export.
|
|
754
|
+
// Auth0 does not return pem on read — it is never exported.
|
|
755
|
+
await Promise.all(sanitized.map(async (client) => {
|
|
756
|
+
if (!client.client_authentication_methods)
|
|
757
|
+
return;
|
|
758
|
+
try {
|
|
759
|
+
const creds = await this.client.clients.credentials.list(client.client_id);
|
|
760
|
+
const credMap = new Map(creds.map((c) => [c.id, c]));
|
|
761
|
+
Object.values(client.client_authentication_methods).forEach((method) => {
|
|
762
|
+
if (method?.credentials) {
|
|
763
|
+
method.credentials = method.credentials
|
|
764
|
+
.map((stub) => {
|
|
765
|
+
const full = credMap.get(stub.id);
|
|
766
|
+
if (!full?.name)
|
|
767
|
+
return null;
|
|
768
|
+
return { name: full.name, credential_type: full.credential_type };
|
|
769
|
+
})
|
|
770
|
+
.filter(Boolean);
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
catch (_) {
|
|
775
|
+
// leave stubs as-is if the credentials API call fails
|
|
776
|
+
}
|
|
777
|
+
}));
|
|
778
|
+
this.existing = sanitized;
|
|
591
779
|
return this.existing;
|
|
592
780
|
}
|
|
593
781
|
isCimdClient(client) {
|
|
@@ -625,7 +813,23 @@ class ClientHandler extends default_1.default {
|
|
|
625
813
|
async updateClient(clientId, client) {
|
|
626
814
|
// For non-CIMD clients
|
|
627
815
|
if (!this.isCimdClient(client)) {
|
|
628
|
-
|
|
816
|
+
const payload = { ...client };
|
|
817
|
+
// b2b_integration_configuration: PATCH only allowed if client already has the object.
|
|
818
|
+
// Sending it to a client that lacks it returns 400 invalid_body.
|
|
819
|
+
// null clears the object — but only for clients that already have it; stripping
|
|
820
|
+
// null for a client without the field is a safe no-op.
|
|
821
|
+
if ('b2b_integration_configuration' in payload) {
|
|
822
|
+
const existing = (this.existing || []).find((c) => c.client_id === (client.client_id || clientId));
|
|
823
|
+
if (!existing?.b2b_integration_configuration) {
|
|
824
|
+
if (payload.b2b_integration_configuration !== null) {
|
|
825
|
+
logger_1.default.warn(`b2b_integration_configuration cannot be added to an existing client via PATCH ` +
|
|
826
|
+
`(client: ${client.name || clientId}). Skipping field. ` +
|
|
827
|
+
`Re-create the client to set this field.`);
|
|
828
|
+
}
|
|
829
|
+
delete payload.b2b_integration_configuration;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
return this.client.clients.update(clientId, payload);
|
|
629
833
|
}
|
|
630
834
|
const updatePayload = this.getCIMDEditableFields(client);
|
|
631
835
|
const registrationClientId = client.client_id || clientId;
|
|
@@ -36,6 +36,33 @@ export declare const schema: {
|
|
|
36
36
|
connection_config: {
|
|
37
37
|
type: string[];
|
|
38
38
|
};
|
|
39
|
+
cross_app_access_resource_app: {
|
|
40
|
+
type: string;
|
|
41
|
+
description: string;
|
|
42
|
+
properties: {
|
|
43
|
+
status: {
|
|
44
|
+
type: string;
|
|
45
|
+
properties: {
|
|
46
|
+
default_value: {
|
|
47
|
+
type: string;
|
|
48
|
+
enum: ("enabled" | "disabled")[];
|
|
49
|
+
description: string;
|
|
50
|
+
};
|
|
51
|
+
allowed_values: {
|
|
52
|
+
type: string;
|
|
53
|
+
items: {
|
|
54
|
+
type: string;
|
|
55
|
+
enum: ("enabled" | "disabled")[];
|
|
56
|
+
};
|
|
57
|
+
uniqueItems: boolean;
|
|
58
|
+
description: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
required: string[];
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
required: string[];
|
|
65
|
+
};
|
|
39
66
|
strategy_overrides: {
|
|
40
67
|
type: string[];
|
|
41
68
|
properties: {
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getConnectionProfile = exports.schema = void 0;
|
|
7
|
+
const auth0_1 = require("auth0");
|
|
7
8
|
const default_1 = __importDefault(require("./default"));
|
|
8
9
|
const client_1 = require("../client");
|
|
9
10
|
const logger_1 = __importDefault(require("../../../logger"));
|
|
@@ -42,6 +43,35 @@ exports.schema = {
|
|
|
42
43
|
connection_config: {
|
|
43
44
|
type: ['object', 'null'],
|
|
44
45
|
},
|
|
46
|
+
cross_app_access_resource_app: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
description: 'Controls whether organization admins may enable Cross App Access (XAA) on their Identity Providers.',
|
|
49
|
+
properties: {
|
|
50
|
+
status: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
default_value: {
|
|
54
|
+
type: 'string',
|
|
55
|
+
enum: Object.values(auth0_1.Management.ConnectionProfileCrossAppAccessResourceAppStatusDefaultValueEnum),
|
|
56
|
+
description: 'The default Cross App Access resource app status.',
|
|
57
|
+
},
|
|
58
|
+
allowed_values: {
|
|
59
|
+
type: 'array',
|
|
60
|
+
items: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
enum: Object.values(auth0_1.Management.ConnectionProfileCrossAppAccessResourceAppStatusValueEnum),
|
|
63
|
+
},
|
|
64
|
+
uniqueItems: true,
|
|
65
|
+
description: 'The allowed Cross App Access resource app status values.',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
// allowed_values is optional per the SDK type (unlike the client's
|
|
69
|
+
// third_party_client_access, which requires both fields).
|
|
70
|
+
required: ['default_value'],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
required: ['status'],
|
|
74
|
+
},
|
|
45
75
|
strategy_overrides: {
|
|
46
76
|
type: ['object', 'null'],
|
|
47
77
|
properties: {
|
|
@@ -103,6 +103,27 @@ export declare const schema: {
|
|
|
103
103
|
required: string[];
|
|
104
104
|
additionalProperties: boolean;
|
|
105
105
|
};
|
|
106
|
+
cross_app_access_requesting_app: {
|
|
107
|
+
type: string;
|
|
108
|
+
properties: {
|
|
109
|
+
active: {
|
|
110
|
+
type: string;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
required: string[];
|
|
114
|
+
additionalProperties: boolean;
|
|
115
|
+
};
|
|
116
|
+
cross_app_access_resource_app: {
|
|
117
|
+
type: string;
|
|
118
|
+
properties: {
|
|
119
|
+
status: {
|
|
120
|
+
type: string;
|
|
121
|
+
enum: string[];
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
required: string[];
|
|
125
|
+
additionalProperties: boolean;
|
|
126
|
+
};
|
|
106
127
|
directory_provisioning_configuration: {
|
|
107
128
|
type: string;
|
|
108
129
|
properties: {
|
|
@@ -138,6 +159,15 @@ export declare const schema: {
|
|
|
138
159
|
id: {
|
|
139
160
|
type: string;
|
|
140
161
|
};
|
|
162
|
+
name: {
|
|
163
|
+
type: string;
|
|
164
|
+
};
|
|
165
|
+
email: {
|
|
166
|
+
type: string;
|
|
167
|
+
};
|
|
168
|
+
direct_members_count: {
|
|
169
|
+
type: string;
|
|
170
|
+
};
|
|
141
171
|
};
|
|
142
172
|
required: string[];
|
|
143
173
|
};
|
|
@@ -152,9 +182,7 @@ type DirectoryProvisioningConfig = Management.DirectoryProvisioning;
|
|
|
152
182
|
export type Connection = Management.ConnectionForList & {
|
|
153
183
|
enabled_clients?: string[];
|
|
154
184
|
directory_provisioning_configuration?: Pick<DirectoryProvisioningConfig, 'mapping' | 'synchronize_automatically' | 'synchronize_groups'> & {
|
|
155
|
-
synchronized_groups?:
|
|
156
|
-
id: string;
|
|
157
|
-
}>;
|
|
185
|
+
synchronized_groups?: Management.SynchronizedGroupPayload[];
|
|
158
186
|
};
|
|
159
187
|
};
|
|
160
188
|
export declare const addExcludedConnectionPropertiesToChanges: ({ proposedChanges, existingConnections, config, }: {
|
|
@@ -202,6 +230,7 @@ export declare const processConnectionEnabledClients: (auth0Client: Auth0APIClie
|
|
|
202
230
|
export default class ConnectionsHandler extends DefaultAPIHandler {
|
|
203
231
|
existing: Connection[] | null;
|
|
204
232
|
scimHandler: ScimHandler;
|
|
233
|
+
private enabledClientsEnrichmentFilter;
|
|
205
234
|
constructor(config: DefaultAPIHandler);
|
|
206
235
|
objString(connection: any): string;
|
|
207
236
|
getFormattedOptions(connection: any, clients: any): {
|
|
@@ -230,9 +259,7 @@ export default class ConnectionsHandler extends DefaultAPIHandler {
|
|
|
230
259
|
/**
|
|
231
260
|
* Retrieves all synchronized groups for a connection using checkpoint pagination.
|
|
232
261
|
*/
|
|
233
|
-
getConnectionSynchronizedGroups(connectionId: string): Promise<
|
|
234
|
-
id: string;
|
|
235
|
-
}> | null>;
|
|
262
|
+
getConnectionSynchronizedGroups(connectionId: string): Promise<Management.SynchronizedGroupPayload[] | null>;
|
|
236
263
|
/**
|
|
237
264
|
* Replaces the synchronized groups for a connection (PUT replace-all semantics).
|
|
238
265
|
*/
|
|
@@ -244,6 +271,7 @@ export default class ConnectionsHandler extends DefaultAPIHandler {
|
|
|
244
271
|
* @param changes - Object containing arrays of connections to create, update, and resolve conflicts for
|
|
245
272
|
*/
|
|
246
273
|
processConnectionDirectoryProvisioning(changes: CalculatedChanges): Promise<void>;
|
|
274
|
+
private setEnabledClientsEnrichmentFilter;
|
|
247
275
|
getType(): Promise<Asset[] | null>;
|
|
248
276
|
calcChanges(assets: Assets): Promise<CalculatedChanges>;
|
|
249
277
|
dryRunChanges(assets: Assets): Promise<CalculatedChanges>;
|
|
@@ -129,6 +129,22 @@ exports.schema = {
|
|
|
129
129
|
required: ['active'],
|
|
130
130
|
additionalProperties: false,
|
|
131
131
|
},
|
|
132
|
+
cross_app_access_requesting_app: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
properties: {
|
|
135
|
+
active: { type: 'boolean' },
|
|
136
|
+
},
|
|
137
|
+
required: ['active'],
|
|
138
|
+
additionalProperties: false,
|
|
139
|
+
},
|
|
140
|
+
cross_app_access_resource_app: {
|
|
141
|
+
type: 'object',
|
|
142
|
+
properties: {
|
|
143
|
+
status: { type: 'string', enum: ['enabled', 'disabled'] },
|
|
144
|
+
},
|
|
145
|
+
required: ['status'],
|
|
146
|
+
additionalProperties: false,
|
|
147
|
+
},
|
|
132
148
|
directory_provisioning_configuration: {
|
|
133
149
|
type: 'object',
|
|
134
150
|
properties: {
|
|
@@ -156,6 +172,9 @@ exports.schema = {
|
|
|
156
172
|
type: 'object',
|
|
157
173
|
properties: {
|
|
158
174
|
id: { type: 'string' },
|
|
175
|
+
name: { type: 'string' },
|
|
176
|
+
email: { type: 'string' },
|
|
177
|
+
direct_members_count: { type: 'number' },
|
|
159
178
|
},
|
|
160
179
|
required: ['id'],
|
|
161
180
|
},
|
|
@@ -353,6 +372,10 @@ class ConnectionsHandler extends default_1.default {
|
|
|
353
372
|
create: async (bodyParams) => this.scimHandler.createOverride(bodyParams),
|
|
354
373
|
},
|
|
355
374
|
});
|
|
375
|
+
// On import, limits getType()'s enabled_clients enrichment to connections in
|
|
376
|
+
// the local config, skipping an API call per remote-only connection on large
|
|
377
|
+
// tenants. Null on export, where every connection is enriched.
|
|
378
|
+
this.enabledClientsEnrichmentFilter = null;
|
|
356
379
|
// @ts-ignore
|
|
357
380
|
this.scimHandler = new scimHandler_1.default(this.config, this.client.connections, this.client.pool);
|
|
358
381
|
}
|
|
@@ -361,12 +384,15 @@ class ConnectionsHandler extends default_1.default {
|
|
|
361
384
|
}
|
|
362
385
|
getFormattedOptions(connection, clients) {
|
|
363
386
|
try {
|
|
387
|
+
const { idpinitiated } = connection.options;
|
|
364
388
|
return {
|
|
365
389
|
options: {
|
|
366
390
|
...connection.options,
|
|
367
391
|
idpinitiated: {
|
|
368
|
-
...
|
|
369
|
-
|
|
392
|
+
...idpinitiated,
|
|
393
|
+
...(idpinitiated.client_id && {
|
|
394
|
+
client_id: (0, utils_1.convertClientNameToId)(idpinitiated.client_id, clients),
|
|
395
|
+
}),
|
|
370
396
|
},
|
|
371
397
|
},
|
|
372
398
|
};
|
|
@@ -467,12 +493,28 @@ class ConnectionsHandler extends default_1.default {
|
|
|
467
493
|
try {
|
|
468
494
|
const groups = [];
|
|
469
495
|
let page = await this.client.connections.directoryProvisioning.listSynchronizedGroups(connectionId, {});
|
|
470
|
-
for (const g of page.data ?? [])
|
|
471
|
-
groups.push({
|
|
496
|
+
for (const g of page.data ?? []) {
|
|
497
|
+
groups.push({
|
|
498
|
+
id: g.id,
|
|
499
|
+
...(g.name !== undefined && { name: g.name }),
|
|
500
|
+
...(g.email !== undefined && { email: g.email }),
|
|
501
|
+
...(g.direct_members_count !== undefined && {
|
|
502
|
+
direct_members_count: g.direct_members_count,
|
|
503
|
+
}),
|
|
504
|
+
});
|
|
505
|
+
}
|
|
472
506
|
while (page.hasNextPage?.()) {
|
|
473
507
|
page = await page.getNextPage();
|
|
474
|
-
for (const g of page.data ?? [])
|
|
475
|
-
groups.push({
|
|
508
|
+
for (const g of page.data ?? []) {
|
|
509
|
+
groups.push({
|
|
510
|
+
id: g.id,
|
|
511
|
+
...(g.name !== undefined && { name: g.name }),
|
|
512
|
+
...(g.email !== undefined && { email: g.email }),
|
|
513
|
+
...(g.direct_members_count !== undefined && {
|
|
514
|
+
direct_members_count: g.direct_members_count,
|
|
515
|
+
}),
|
|
516
|
+
});
|
|
517
|
+
}
|
|
476
518
|
}
|
|
477
519
|
return groups;
|
|
478
520
|
}
|
|
@@ -583,9 +625,19 @@ class ConnectionsHandler extends default_1.default {
|
|
|
583
625
|
})
|
|
584
626
|
.promise();
|
|
585
627
|
}
|
|
628
|
+
// Scopes getType()'s enabled_clients enrichment to the local config's
|
|
629
|
+
// connection names. Called on import; export leaves it unset (enrich all).
|
|
630
|
+
setEnabledClientsEnrichmentFilter(connections) {
|
|
631
|
+
this.enabledClientsEnrichmentFilter = new Set(connections
|
|
632
|
+
.map((connection) => connection.name)
|
|
633
|
+
.filter((name) => typeof name === 'string'));
|
|
634
|
+
}
|
|
586
635
|
async getType() {
|
|
587
636
|
if (this.existing)
|
|
588
637
|
return this.existing;
|
|
638
|
+
// Consume the import filter and reset it so it can't leak into a later call.
|
|
639
|
+
const enrichmentFilter = this.enabledClientsEnrichmentFilter;
|
|
640
|
+
this.enabledClientsEnrichmentFilter = null;
|
|
589
641
|
const [connections, directoryProvisioningConfigs] = await Promise.all([
|
|
590
642
|
(0, client_1.paginate)(this.client.connections.list, {
|
|
591
643
|
checkpoint: true,
|
|
@@ -602,7 +654,11 @@ class ConnectionsHandler extends default_1.default {
|
|
|
602
654
|
this.existing = filteredConnections;
|
|
603
655
|
if (this.existing === null)
|
|
604
656
|
return [];
|
|
605
|
-
|
|
657
|
+
// Import: enrich only local-config connections. Export (null): enrich all.
|
|
658
|
+
const shouldEnrich = (con) => enrichmentFilter === null || (con.name != null && enrichmentFilter.has(con.name));
|
|
659
|
+
const connectionTasks = filteredConnections
|
|
660
|
+
.map((con, index) => ({ con, index }))
|
|
661
|
+
.filter(({ con }) => shouldEnrich(con));
|
|
606
662
|
const connectionsWithEnabledClients = await this.client.pool
|
|
607
663
|
.addEachTask({
|
|
608
664
|
data: connectionTasks,
|
|
@@ -638,9 +694,9 @@ class ConnectionsHandler extends default_1.default {
|
|
|
638
694
|
},
|
|
639
695
|
})
|
|
640
696
|
.promise();
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
697
|
+
// Merge enriched connections back by index; skipped ones pass through.
|
|
698
|
+
const enrichedByIndex = new Map(connectionsWithEnabledClients.map(({ index, connection }) => [index, connection]));
|
|
699
|
+
this.existing = filteredConnections.map((con, index) => enrichedByIndex.get(index) ?? con);
|
|
644
700
|
// Apply `scim_configuration` to all the relevant `SCIM` connections. This method mutates `this.existing`.
|
|
645
701
|
await this.scimHandler.applyScimConfiguration(this.existing);
|
|
646
702
|
return this.existing;
|
|
@@ -655,6 +711,8 @@ class ConnectionsHandler extends default_1.default {
|
|
|
655
711
|
update: [],
|
|
656
712
|
conflicts: [],
|
|
657
713
|
};
|
|
714
|
+
// Scope getType() enrichment to the local config (see getType()).
|
|
715
|
+
this.setEnabledClientsEnrichmentFilter(connections);
|
|
658
716
|
// Convert enabled_clients by name to the id
|
|
659
717
|
const clients = await (0, client_1.paginate)(this.client.clients.list, {
|
|
660
718
|
paginate: true,
|
|
@@ -692,6 +750,8 @@ class ConnectionsHandler extends default_1.default {
|
|
|
692
750
|
conflicts: [],
|
|
693
751
|
};
|
|
694
752
|
}
|
|
753
|
+
// Scope getType() enrichment to the local config (see getType()).
|
|
754
|
+
this.setEnabledClientsEnrichmentFilter(connections);
|
|
695
755
|
const clients = await (0, client_1.paginate)(this.client.clients.list, {
|
|
696
756
|
paginate: true,
|
|
697
757
|
include_totals: true,
|
|
@@ -709,7 +769,11 @@ class ConnectionsHandler extends default_1.default {
|
|
|
709
769
|
...(enabledClients !== undefined && { enabled_clients: enabledClients }),
|
|
710
770
|
};
|
|
711
771
|
});
|
|
712
|
-
|
|
772
|
+
let proposedChanges = await super.dryRunChanges({ ...assets, connections: formatted });
|
|
773
|
+
const includedConnections = (assets.include && assets.include.connections) || [];
|
|
774
|
+
const excludedConnections = (assets.exclude && assets.exclude.connections) || [];
|
|
775
|
+
proposedChanges = (0, utils_1.filterExcluded)(proposedChanges, excludedConnections);
|
|
776
|
+
proposedChanges = (0, utils_1.filterIncluded)(proposedChanges, includedConnections);
|
|
713
777
|
return (0, exports.addExcludedConnectionPropertiesToChanges)({
|
|
714
778
|
proposedChanges,
|
|
715
779
|
existingConnections,
|
|
@@ -195,6 +195,33 @@ export declare const schema: {
|
|
|
195
195
|
};
|
|
196
196
|
};
|
|
197
197
|
};
|
|
198
|
+
otp_settings: {
|
|
199
|
+
type: string;
|
|
200
|
+
properties: {
|
|
201
|
+
email: {
|
|
202
|
+
type: string;
|
|
203
|
+
properties: {
|
|
204
|
+
otp_length: {
|
|
205
|
+
type: string;
|
|
206
|
+
};
|
|
207
|
+
otp_expiry: {
|
|
208
|
+
type: string;
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
phone: {
|
|
213
|
+
type: string;
|
|
214
|
+
properties: {
|
|
215
|
+
otp_length: {
|
|
216
|
+
type: string;
|
|
217
|
+
};
|
|
218
|
+
otp_expiry: {
|
|
219
|
+
type: string;
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
};
|
|
198
225
|
password_options: {
|
|
199
226
|
type: string;
|
|
200
227
|
properties: {
|
|
@@ -295,6 +322,7 @@ export default class DatabaseHandler extends DefaultAPIHandler {
|
|
|
295
322
|
private validatePasswordlessSettings;
|
|
296
323
|
private validateEmailUniqueConstraints;
|
|
297
324
|
getClientFN(fn: 'create' | 'delete' | 'getAll' | 'update'): Function;
|
|
325
|
+
private enrichConnectionsWithEnabledClients;
|
|
298
326
|
getType(): Promise<Connection[]>;
|
|
299
327
|
calcChanges(assets: Assets): Promise<CalculatedChanges>;
|
|
300
328
|
dryRunChanges(assets: Assets): Promise<CalculatedChanges>;
|