auth0-deploy-cli 8.29.2 → 8.30.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/.circleci/config.yml +0 -81
- package/.github/workflows/npm-publish.yml +52 -0
- package/CHANGELOG.md +28 -1
- package/lib/context/directory/handlers/clientGrants.js +9 -1
- package/lib/context/directory/handlers/clients.js +6 -1
- package/lib/context/directory/handlers/connections.js +7 -1
- package/lib/context/directory/handlers/databases.js +6 -1
- package/lib/context/directory/handlers/resourceServers.js +6 -1
- package/lib/context/directory/handlers/rules.js +6 -1
- package/lib/context/yaml/handlers/clientGrants.js +9 -1
- package/lib/context/yaml/handlers/clients.js +5 -0
- package/lib/context/yaml/handlers/connections.js +7 -1
- package/lib/context/yaml/handlers/databases.js +7 -1
- package/lib/context/yaml/handlers/resourceServers.js +30 -3
- package/lib/context/yaml/handlers/rules.js +5 -0
- package/lib/tools/auth0/handlers/actions.js +13 -15
- package/lib/tools/auth0/handlers/connections.d.ts +6 -0
- package/lib/tools/auth0/handlers/connections.js +47 -22
- package/lib/tools/auth0/handlers/prompts.js +61 -1
- package/package.json +3 -3
package/.circleci/config.yml
CHANGED
|
@@ -48,42 +48,6 @@ jobs:
|
|
|
48
48
|
paths: .
|
|
49
49
|
- codecov/upload
|
|
50
50
|
|
|
51
|
-
deploy:
|
|
52
|
-
parameters:
|
|
53
|
-
v:
|
|
54
|
-
type: string
|
|
55
|
-
default: "lts"
|
|
56
|
-
docker:
|
|
57
|
-
- image: cimg/node:<< parameters.v >>
|
|
58
|
-
working_directory: ~/repo
|
|
59
|
-
steps:
|
|
60
|
-
- attach_workspace:
|
|
61
|
-
at: ~/repo
|
|
62
|
-
- run:
|
|
63
|
-
name: Authenticate with registry
|
|
64
|
-
command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc
|
|
65
|
-
- run:
|
|
66
|
-
name: Publish package
|
|
67
|
-
command: npm publish
|
|
68
|
-
|
|
69
|
-
deploy_beta:
|
|
70
|
-
parameters:
|
|
71
|
-
v:
|
|
72
|
-
type: string
|
|
73
|
-
default: "lts"
|
|
74
|
-
docker:
|
|
75
|
-
- image: cimg/node:<< parameters.v >>
|
|
76
|
-
working_directory: ~/repo
|
|
77
|
-
steps:
|
|
78
|
-
- attach_workspace:
|
|
79
|
-
at: ~/repo
|
|
80
|
-
- run:
|
|
81
|
-
name: Authenticate with registry
|
|
82
|
-
command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/repo/.npmrc
|
|
83
|
-
- run:
|
|
84
|
-
name: Publish beta package
|
|
85
|
-
command: npm publish --tag beta
|
|
86
|
-
|
|
87
51
|
does_typescript_compile:
|
|
88
52
|
docker:
|
|
89
53
|
- image: cimg/node:22.12.0
|
|
@@ -128,48 +92,3 @@ workflows:
|
|
|
128
92
|
name: Unit tests with Node current
|
|
129
93
|
v: "22.12.0"
|
|
130
94
|
|
|
131
|
-
test_and_deploy:
|
|
132
|
-
jobs:
|
|
133
|
-
- unit_test:
|
|
134
|
-
name: Unit tests with Node LTS
|
|
135
|
-
v: "lts"
|
|
136
|
-
filters:
|
|
137
|
-
branches:
|
|
138
|
-
only: master
|
|
139
|
-
tags:
|
|
140
|
-
only: /^v.*/
|
|
141
|
-
- deploy:
|
|
142
|
-
name: Publish to NPM
|
|
143
|
-
v: "lts"
|
|
144
|
-
requires:
|
|
145
|
-
- Unit tests with Node LTS
|
|
146
|
-
filters:
|
|
147
|
-
branches:
|
|
148
|
-
ignore: /.*/
|
|
149
|
-
tags:
|
|
150
|
-
only: /^v[0-9]+\.[0-9]+\.[0-9]+$/
|
|
151
|
-
context:
|
|
152
|
-
- publish-npm
|
|
153
|
-
|
|
154
|
-
test_and_deploy_beta:
|
|
155
|
-
jobs:
|
|
156
|
-
- unit_test:
|
|
157
|
-
name: Unit tests with Node LTS (Beta)
|
|
158
|
-
v: "lts"
|
|
159
|
-
filters:
|
|
160
|
-
branches:
|
|
161
|
-
only: beta
|
|
162
|
-
tags:
|
|
163
|
-
only: /^v[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+$/
|
|
164
|
-
- deploy_beta:
|
|
165
|
-
name: Publish Beta to NPM
|
|
166
|
-
v: "lts"
|
|
167
|
-
requires:
|
|
168
|
-
- Unit tests with Node LTS (Beta)
|
|
169
|
-
filters:
|
|
170
|
-
branches:
|
|
171
|
-
ignore: /.*/
|
|
172
|
-
tags:
|
|
173
|
-
only: /^v[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+$/
|
|
174
|
-
context:
|
|
175
|
-
- publish-npm
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Publish package to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-node@v6
|
|
20
|
+
with:
|
|
21
|
+
node-version: 22.14.0
|
|
22
|
+
registry-url: https://registry.npmjs.org
|
|
23
|
+
package-manager-cache: false
|
|
24
|
+
|
|
25
|
+
- name: Update npm for trusted publishing
|
|
26
|
+
run: npm install --global npm@11
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm install
|
|
30
|
+
|
|
31
|
+
- name: Build package
|
|
32
|
+
run: npm run build
|
|
33
|
+
|
|
34
|
+
- name: Determine npm dist-tag
|
|
35
|
+
id: npm_dist_tag
|
|
36
|
+
shell: bash
|
|
37
|
+
run: |
|
|
38
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
39
|
+
|
|
40
|
+
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-beta\.[0-9]+)?$ ]]; then
|
|
41
|
+
echo "Unsupported release tag: ${GITHUB_REF_NAME}" >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [[ "$VERSION" == *"-beta."* ]]; then
|
|
46
|
+
echo "value=beta" >> "$GITHUB_OUTPUT"
|
|
47
|
+
else
|
|
48
|
+
echo "value=latest" >> "$GITHUB_OUTPUT"
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
- name: Publish package
|
|
52
|
+
run: npm publish --tag "${{ steps.npm_dist_tag.outputs.value }}"
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [8.30.0] - 2026-04-02
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add support for passkey enrollment in `prompts` partials. [#1328]
|
|
15
|
+
- Add support for `dpop_signing_alg` validation in OIDC and Okta `connections`. [#1343]
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fix action module fetching logic to resolve correct module IDs. [#1340]
|
|
20
|
+
- Fix `AUTH0_EXCLUDED_*` options not respected during export. [#1342]
|
|
21
|
+
|
|
22
|
+
## [8.29.3] - 2026-03-25
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Fix Universal Login Authentication Profile reverting to Identifier+Password after import when branding is included. [#1333]
|
|
27
|
+
- Fix efficiency and reliability of fetching `enabled_clients` for `connections`. [#1334]
|
|
28
|
+
|
|
10
29
|
## [8.29.2] - 2026-03-17
|
|
11
30
|
|
|
12
31
|
### Fixed
|
|
@@ -1685,7 +1704,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
1685
1704
|
[#1320]: https://github.com/auth0/auth0-deploy-cli/issues/1320
|
|
1686
1705
|
[#1321]: https://github.com/auth0/auth0-deploy-cli/issues/1321
|
|
1687
1706
|
[#1322]: https://github.com/auth0/auth0-deploy-cli/issues/1322
|
|
1688
|
-
[
|
|
1707
|
+
[#1328]: https://github.com/auth0/auth0-deploy-cli/issues/1328
|
|
1708
|
+
[#1333]: https://github.com/auth0/auth0-deploy-cli/issues/1333
|
|
1709
|
+
[#1334]: https://github.com/auth0/auth0-deploy-cli/issues/1334
|
|
1710
|
+
[#1340]: https://github.com/auth0/auth0-deploy-cli/issues/1340
|
|
1711
|
+
[#1342]: https://github.com/auth0/auth0-deploy-cli/issues/1342
|
|
1712
|
+
[#1343]: https://github.com/auth0/auth0-deploy-cli/issues/1343
|
|
1713
|
+
[Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.30.0...HEAD
|
|
1714
|
+
[8.30.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.29.3...v8.30.0
|
|
1715
|
+
[8.29.3]: https://github.com/auth0/auth0-deploy-cli/compare/v8.29.2...v8.29.3
|
|
1689
1716
|
[8.29.2]: https://github.com/auth0/auth0-deploy-cli/compare/v8.29.1...v8.29.2
|
|
1690
1717
|
[8.29.1]: https://github.com/auth0/auth0-deploy-cli/compare/v8.29.0...v8.29.1
|
|
1691
1718
|
[8.29.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.28.0...v8.29.0
|
|
@@ -25,13 +25,14 @@ function parse(context) {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
async function dump(context) {
|
|
28
|
-
|
|
28
|
+
let { clientGrants } = context.assets;
|
|
29
29
|
if (!clientGrants)
|
|
30
30
|
return; // Skip, nothing to dump
|
|
31
31
|
const grantsFolder = path_1.default.join(context.filePath, tools_1.constants.CLIENTS_GRANTS_DIRECTORY);
|
|
32
32
|
fs_extra_1.default.ensureDirSync(grantsFolder);
|
|
33
33
|
if (clientGrants.length === 0)
|
|
34
34
|
return;
|
|
35
|
+
const excludedClientsByNames = (context.assets.exclude && context.assets.exclude.clients) || [];
|
|
35
36
|
const allResourceServers = await (0, client_1.paginate)(context.mgmtClient.resourceServers.list, {
|
|
36
37
|
paginate: true,
|
|
37
38
|
include_totals: true,
|
|
@@ -40,6 +41,13 @@ async function dump(context) {
|
|
|
40
41
|
paginate: true,
|
|
41
42
|
include_totals: true,
|
|
42
43
|
});
|
|
44
|
+
// Filter out grants for excluded clients
|
|
45
|
+
if (excludedClientsByNames.length) {
|
|
46
|
+
const excludedClientIds = new Set(allClients
|
|
47
|
+
.filter((c) => c.name !== undefined && excludedClientsByNames.includes(c.name))
|
|
48
|
+
.map((c) => c.client_id));
|
|
49
|
+
clientGrants = clientGrants.filter((grant) => !excludedClientIds.has(grant.client_id));
|
|
50
|
+
}
|
|
43
51
|
// Convert client_id to the client name for readability
|
|
44
52
|
clientGrants.forEach((grant) => {
|
|
45
53
|
const dumpGrant = { ...grant };
|
|
@@ -36,10 +36,15 @@ function parse(context) {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
async function dump(context) {
|
|
39
|
-
|
|
39
|
+
let { clients } = context.assets;
|
|
40
40
|
const { userAttributeProfiles, connectionProfiles } = context.assets;
|
|
41
41
|
if (!clients)
|
|
42
42
|
return; // Skip, nothing to dump
|
|
43
|
+
// Filter excluded clients
|
|
44
|
+
const excludedClients = (context.assets.exclude && context.assets.exclude.clients) || [];
|
|
45
|
+
if (excludedClients.length) {
|
|
46
|
+
clients = clients.filter((client) => !excludedClients.includes(client.name ?? ''));
|
|
47
|
+
}
|
|
43
48
|
const clientsFolder = path_1.default.join(context.filePath, tools_1.constants.CLIENTS_DIRECTORY);
|
|
44
49
|
fs_extra_1.default.ensureDirSync(clientsFolder);
|
|
45
50
|
clients.forEach((client) => {
|
|
@@ -40,9 +40,15 @@ function parse(context) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
async function dump(context) {
|
|
43
|
-
|
|
43
|
+
let { connections } = context.assets;
|
|
44
|
+
const { clientsOrig } = context.assets;
|
|
44
45
|
if (!connections)
|
|
45
46
|
return; // Skip, nothing to dump
|
|
47
|
+
// Filter excluded connections
|
|
48
|
+
const excludedConnections = (context.assets.exclude && context.assets.exclude.connections) || [];
|
|
49
|
+
if (excludedConnections.length) {
|
|
50
|
+
connections = connections.filter((connection) => !excludedConnections.includes(connection.name));
|
|
51
|
+
}
|
|
46
52
|
const connectionsFolder = path_1.default.join(context.filePath, tools_1.constants.CONNECTIONS_DIRECTORY);
|
|
47
53
|
fs_extra_1.default.ensureDirSync(connectionsFolder);
|
|
48
54
|
// Convert enabled_clients from id to name
|
|
@@ -65,9 +65,14 @@ function parse(context) {
|
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
67
|
async function dump(context) {
|
|
68
|
-
|
|
68
|
+
let { databases } = context.assets;
|
|
69
69
|
if (!databases)
|
|
70
70
|
return; // Skip, nothing to dump
|
|
71
|
+
// Filter excluded databases
|
|
72
|
+
const excludedDatabases = (context.assets.exclude && context.assets.exclude.databases) || [];
|
|
73
|
+
if (excludedDatabases.length) {
|
|
74
|
+
databases = databases.filter((database) => !excludedDatabases.includes(database.name));
|
|
75
|
+
}
|
|
71
76
|
const databasesFolder = path_1.default.join(context.filePath, tools_1.constants.DATABASE_CONNECTIONS_DIRECTORY);
|
|
72
77
|
fs_extra_1.default.ensureDirSync(databasesFolder);
|
|
73
78
|
databases.forEach((database) => {
|
|
@@ -24,10 +24,15 @@ function parse(context) {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
async function dump(context) {
|
|
27
|
-
|
|
27
|
+
let { resourceServers } = context.assets;
|
|
28
28
|
let { clients } = context.assets;
|
|
29
29
|
if (!resourceServers)
|
|
30
30
|
return; // Skip, nothing to dump
|
|
31
|
+
// Filter excluded resource servers
|
|
32
|
+
const excludedResourceServers = (context.assets.exclude && context.assets.exclude.resourceServers) || [];
|
|
33
|
+
if (excludedResourceServers.length) {
|
|
34
|
+
resourceServers = resourceServers.filter((resourceServer) => !excludedResourceServers.includes(resourceServer.name ?? ''));
|
|
35
|
+
}
|
|
31
36
|
const resourceServersFolder = path_1.default.join(context.filePath, tools_1.constants.RESOURCE_SERVERS_DIRECTORY);
|
|
32
37
|
fs_extra_1.default.ensureDirSync(resourceServersFolder);
|
|
33
38
|
if (clients === undefined) {
|
|
@@ -30,9 +30,14 @@ function parse(context) {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
async function dump(context) {
|
|
33
|
-
|
|
33
|
+
let { rules } = context.assets;
|
|
34
34
|
if (!rules)
|
|
35
35
|
return; // Skip, nothing to dump
|
|
36
|
+
// Filter excluded rules
|
|
37
|
+
const excludedRules = (context.assets.exclude && context.assets.exclude.rules) || [];
|
|
38
|
+
if (excludedRules.length) {
|
|
39
|
+
rules = rules.filter((rule) => !excludedRules.includes(rule.name));
|
|
40
|
+
}
|
|
36
41
|
// Create Rules folder
|
|
37
42
|
const rulesFolder = path_1.default.join(context.filePath, tools_1.constants.RULES_DIRECTORY);
|
|
38
43
|
fs_extra_1.default.ensureDirSync(rulesFolder);
|
|
@@ -12,7 +12,7 @@ async function parse(context) {
|
|
|
12
12
|
}
|
|
13
13
|
async function dump(context) {
|
|
14
14
|
let { clients } = context.assets;
|
|
15
|
-
|
|
15
|
+
let { clientGrants } = context.assets;
|
|
16
16
|
if (!clientGrants)
|
|
17
17
|
return { clientGrants: null };
|
|
18
18
|
if (clients === undefined) {
|
|
@@ -21,6 +21,14 @@ async function dump(context) {
|
|
|
21
21
|
include_totals: true,
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
+
// Filter out grants for excluded clients
|
|
25
|
+
const excludedClientsByNames = (context.assets.exclude && context.assets.exclude.clients) || [];
|
|
26
|
+
if (excludedClientsByNames.length) {
|
|
27
|
+
const excludedClientIds = new Set((clients || [])
|
|
28
|
+
.filter((c) => c.name !== undefined && excludedClientsByNames.includes(c.name))
|
|
29
|
+
.map((c) => c.client_id));
|
|
30
|
+
clientGrants = clientGrants.filter((grant) => !excludedClientIds.has(grant.client_id));
|
|
31
|
+
}
|
|
24
32
|
// Convert client_id to the client name for readability
|
|
25
33
|
return {
|
|
26
34
|
clientGrants: clientGrants.map((grant) => {
|
|
@@ -36,6 +36,11 @@ async function dump(context) {
|
|
|
36
36
|
const { userAttributeProfiles, connectionProfiles } = context.assets;
|
|
37
37
|
if (!clients)
|
|
38
38
|
return { clients: null };
|
|
39
|
+
// Filter excluded clients
|
|
40
|
+
const excludedClients = (context.assets.exclude && context.assets.exclude.clients) || [];
|
|
41
|
+
if (excludedClients.length) {
|
|
42
|
+
clients = clients.filter((client) => !excludedClients.includes(client.name ?? ''));
|
|
43
|
+
}
|
|
39
44
|
// map ids to names for user attribute profiles and connection profiles
|
|
40
45
|
clients = clients.map((client) => {
|
|
41
46
|
const userAttributeProfileId = client?.express_configuration?.user_attribute_profile_id;
|
|
@@ -50,9 +50,15 @@ const getFormattedOptions = (connection, clients) => {
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
async function dump(context) {
|
|
53
|
-
|
|
53
|
+
let { connections } = context.assets;
|
|
54
|
+
const { clients } = context.assets;
|
|
54
55
|
if (!connections)
|
|
55
56
|
return { connections: null };
|
|
57
|
+
// Filter excluded connections
|
|
58
|
+
const excludedConnections = (context.assets.exclude && context.assets.exclude.connections) || [];
|
|
59
|
+
if (excludedConnections.length) {
|
|
60
|
+
connections = connections.filter((connection) => !excludedConnections.includes(connection.name));
|
|
61
|
+
}
|
|
56
62
|
return {
|
|
57
63
|
connections: connections.map((connection) => {
|
|
58
64
|
let dumpedConnection = {
|
|
@@ -31,9 +31,15 @@ async function parse(context) {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
async function dump(context) {
|
|
34
|
-
|
|
34
|
+
let { databases } = context.assets;
|
|
35
|
+
const { clients } = context.assets;
|
|
35
36
|
if (!databases)
|
|
36
37
|
return { databases: null };
|
|
38
|
+
// Filter excluded databases
|
|
39
|
+
const excludedDatabases = (context.assets.exclude && context.assets.exclude.databases) || [];
|
|
40
|
+
if (excludedDatabases.length) {
|
|
41
|
+
databases = databases.filter((database) => !excludedDatabases.includes(database.name));
|
|
42
|
+
}
|
|
37
43
|
const sortCustomScripts = ([name1], [name2]) => {
|
|
38
44
|
if (name1 === name2)
|
|
39
45
|
return 0;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const client_1 = require("../../../tools/auth0/client");
|
|
4
4
|
const utils_1 = require("../../../utils");
|
|
5
|
-
async function
|
|
5
|
+
async function parse(context) {
|
|
6
6
|
const { resourceServers } = context.assets;
|
|
7
7
|
let { clients } = context.assets;
|
|
8
8
|
if (!resourceServers) {
|
|
@@ -24,8 +24,35 @@ async function dumpAndParse(context) {
|
|
|
24
24
|
}),
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
async function dump(context) {
|
|
28
|
+
let { resourceServers } = context.assets;
|
|
29
|
+
let { clients } = context.assets;
|
|
30
|
+
if (!resourceServers) {
|
|
31
|
+
return { resourceServers: null };
|
|
32
|
+
}
|
|
33
|
+
// Filter excluded resource servers
|
|
34
|
+
const excludedResourceServers = (context.assets.exclude && context.assets.exclude.resourceServers) || [];
|
|
35
|
+
if (excludedResourceServers.length) {
|
|
36
|
+
resourceServers = resourceServers.filter((rs) => !excludedResourceServers.includes(rs.name ?? ''));
|
|
37
|
+
}
|
|
38
|
+
if (clients === undefined) {
|
|
39
|
+
clients = await (0, client_1.paginate)(context.mgmtClient.clients.list, {
|
|
40
|
+
paginate: true,
|
|
41
|
+
include_totals: true,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
resourceServers: resourceServers.map((rs) => {
|
|
46
|
+
const dumpResourceServer = { ...rs };
|
|
47
|
+
if (dumpResourceServer.client_id) {
|
|
48
|
+
dumpResourceServer.client_id = (0, utils_1.convertClientIdToName)(dumpResourceServer.client_id, clients || []);
|
|
49
|
+
}
|
|
50
|
+
return dumpResourceServer;
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
27
54
|
const resourceServersHandler = {
|
|
28
|
-
parse
|
|
29
|
-
dump
|
|
55
|
+
parse,
|
|
56
|
+
dump,
|
|
30
57
|
};
|
|
31
58
|
exports.default = resourceServersHandler;
|
|
@@ -25,6 +25,11 @@ async function dump(context) {
|
|
|
25
25
|
if (!rules) {
|
|
26
26
|
return { rules: null };
|
|
27
27
|
}
|
|
28
|
+
// Filter excluded rules
|
|
29
|
+
const excludedRules = (context.assets.exclude && context.assets.exclude.rules) || [];
|
|
30
|
+
if (excludedRules.length) {
|
|
31
|
+
rules = rules.filter((rule) => !excludedRules.includes(rule.name));
|
|
32
|
+
}
|
|
28
33
|
// Create Rules folder
|
|
29
34
|
const rulesFolder = path_1.default.join(context.basePath, 'rules');
|
|
30
35
|
fs_extra_1.default.ensureDirSync(rulesFolder);
|
|
@@ -249,7 +249,7 @@ class ActionHandler extends default_1.default {
|
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
async calcChanges(assets) {
|
|
252
|
-
let { actions
|
|
252
|
+
let { actions } = assets;
|
|
253
253
|
// Do nothing if not set
|
|
254
254
|
if (!actions)
|
|
255
255
|
return {
|
|
@@ -259,19 +259,14 @@ class ActionHandler extends default_1.default {
|
|
|
259
259
|
conflicts: [],
|
|
260
260
|
};
|
|
261
261
|
let modules = null;
|
|
262
|
-
|
|
263
|
-
modules =
|
|
262
|
+
try {
|
|
263
|
+
modules = await (0, client_1.paginate)(this.client.actions.modules.list, {
|
|
264
|
+
paginate: true,
|
|
265
|
+
});
|
|
264
266
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
paginate: true,
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
catch {
|
|
272
|
-
logger_1.default.debug('Skipping actions modules enrichment because action modules could not be retrieved.');
|
|
273
|
-
modules = null;
|
|
274
|
-
}
|
|
267
|
+
catch {
|
|
268
|
+
logger_1.default.debug('Skipping actions modules enrichment because action modules could not be retrieved.');
|
|
269
|
+
modules = null;
|
|
275
270
|
}
|
|
276
271
|
if (modules != null) {
|
|
277
272
|
// Use task queue to process actions in parallel
|
|
@@ -305,12 +300,15 @@ class ActionHandler extends default_1.default {
|
|
|
305
300
|
moduleVersions = await moduleVersions.getNextPage();
|
|
306
301
|
allModuleVersions.push(...moduleVersions.data);
|
|
307
302
|
}
|
|
303
|
+
const moduleVersionId = allModuleVersions?.find((v) => v.version_number === module.module_version_number)?.id;
|
|
304
|
+
if (!moduleVersionId) {
|
|
305
|
+
throw new Error(`Could not find action module version id for module '${module.module_name}' version '${module.module_version_number}'`);
|
|
306
|
+
}
|
|
308
307
|
return {
|
|
309
308
|
module_name: module.module_name,
|
|
310
309
|
module_id: foundModule.id,
|
|
311
310
|
module_version_number: module.module_version_number,
|
|
312
|
-
module_version_id:
|
|
313
|
-
?.id || '',
|
|
311
|
+
module_version_id: moduleVersionId,
|
|
314
312
|
};
|
|
315
313
|
}
|
|
316
314
|
return module;
|
|
@@ -51,6 +51,15 @@ const utils_1 = require("../../utils");
|
|
|
51
51
|
const client_1 = require("../client");
|
|
52
52
|
const scimHandler_1 = __importDefault(require("./scimHandler"));
|
|
53
53
|
const logger_1 = __importDefault(require("../../../logger"));
|
|
54
|
+
const connectionOptionsSchema = {
|
|
55
|
+
type: 'object',
|
|
56
|
+
properties: {
|
|
57
|
+
dpop_signing_alg: {
|
|
58
|
+
type: 'string',
|
|
59
|
+
enum: Object.values(auth0_1.Management.ConnectionDpopSigningAlgEnum),
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
};
|
|
54
63
|
exports.schema = {
|
|
55
64
|
type: 'array',
|
|
56
65
|
items: {
|
|
@@ -58,7 +67,7 @@ exports.schema = {
|
|
|
58
67
|
properties: {
|
|
59
68
|
name: { type: 'string' },
|
|
60
69
|
strategy: { type: 'string' },
|
|
61
|
-
options:
|
|
70
|
+
options: connectionOptionsSchema,
|
|
62
71
|
enabled_clients: { type: 'array', items: { type: 'string' } },
|
|
63
72
|
realms: { type: 'array', items: { type: 'string' } },
|
|
64
73
|
metadata: { type: 'object' },
|
|
@@ -166,10 +175,18 @@ const getConnectionEnabledClients = async (auth0Client, connectionId) => {
|
|
|
166
175
|
if (!connectionId)
|
|
167
176
|
return null;
|
|
168
177
|
try {
|
|
169
|
-
|
|
178
|
+
logger_1.default.debug(`Getting enabled clients for connection ${connectionId}`);
|
|
179
|
+
const enabledClients = [];
|
|
180
|
+
let page = await auth0Client.connections.clients.get(connectionId, { take: 100 });
|
|
181
|
+
enabledClients.push(...(page.data || []));
|
|
182
|
+
while (page.hasNextPage && page.hasNextPage()) {
|
|
183
|
+
page = await page.getNextPage();
|
|
184
|
+
enabledClients.push(...(page.data || []));
|
|
185
|
+
}
|
|
170
186
|
return enabledClients.filter((client) => !!client?.client_id).map((client) => client.client_id);
|
|
171
187
|
}
|
|
172
188
|
catch (error) {
|
|
189
|
+
logger_1.default.warn(`Unable to retrieve enabled clients for connection ${connectionId}: ${error?.message}`);
|
|
173
190
|
return null;
|
|
174
191
|
}
|
|
175
192
|
};
|
|
@@ -473,27 +490,35 @@ class ConnectionsHandler extends default_1.default {
|
|
|
473
490
|
this.existing = filteredConnections;
|
|
474
491
|
if (this.existing === null)
|
|
475
492
|
return [];
|
|
476
|
-
const
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
connection.enabled_clients = enabledClients;
|
|
484
|
-
}
|
|
485
|
-
if (connection.strategy === 'google-apps' && directoryProvisioningConfigs) {
|
|
486
|
-
const dirProvConfig = directoryProvisioningConfigs.find((congigCon) => congigCon.connection_id === con.id);
|
|
487
|
-
if (dirProvConfig) {
|
|
488
|
-
connection.directory_provisioning_configuration = {
|
|
489
|
-
mapping: dirProvConfig.mapping,
|
|
490
|
-
synchronize_automatically: dirProvConfig.synchronize_automatically,
|
|
491
|
-
};
|
|
493
|
+
const connectionTasks = filteredConnections.map((con, index) => ({ con, index }));
|
|
494
|
+
const connectionsWithEnabledClients = await this.client.pool
|
|
495
|
+
.addEachTask({
|
|
496
|
+
data: connectionTasks,
|
|
497
|
+
generator: async ({ con, index }) => {
|
|
498
|
+
if (!con?.id) {
|
|
499
|
+
return { index, connection: con };
|
|
492
500
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
501
|
+
const enabledClients = await (0, exports.getConnectionEnabledClients)(this.client, con.id);
|
|
502
|
+
let connection = { ...con };
|
|
503
|
+
if (enabledClients?.length) {
|
|
504
|
+
connection.enabled_clients = enabledClients;
|
|
505
|
+
}
|
|
506
|
+
if (connection.strategy === 'google-apps' && directoryProvisioningConfigs) {
|
|
507
|
+
const dirProvConfig = directoryProvisioningConfigs.find((configCon) => configCon.connection_id === con.id);
|
|
508
|
+
if (dirProvConfig) {
|
|
509
|
+
connection.directory_provisioning_configuration = {
|
|
510
|
+
mapping: dirProvConfig.mapping,
|
|
511
|
+
synchronize_automatically: dirProvConfig.synchronize_automatically,
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return { index, connection };
|
|
516
|
+
},
|
|
517
|
+
})
|
|
518
|
+
.promise();
|
|
519
|
+
this.existing = connectionsWithEnabledClients
|
|
520
|
+
.sort((a, b) => a.index - b.index)
|
|
521
|
+
.map(({ connection }) => connection);
|
|
497
522
|
// Apply `scim_configuration` to all the relevant `SCIM` connections. This method mutates `this.existing`.
|
|
498
523
|
await this.scimHandler.applyScimConfiguration(this.existing);
|
|
499
524
|
return this.existing;
|
|
@@ -1,4 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
2
41
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
42
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
43
|
};
|
|
@@ -6,7 +45,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
45
|
exports.schema = void 0;
|
|
7
46
|
const lodash_1 = require("lodash");
|
|
8
47
|
const auth0_1 = require("auth0");
|
|
9
|
-
const default_1 =
|
|
48
|
+
const default_1 = __importStar(require("./default"));
|
|
10
49
|
const types_1 = require("../../../types");
|
|
11
50
|
const logger_1 = __importDefault(require("../../../logger"));
|
|
12
51
|
const client_1 = require("../client");
|
|
@@ -122,7 +161,10 @@ const customPartialsPromptTypes = [
|
|
|
122
161
|
'signup',
|
|
123
162
|
'signup-id',
|
|
124
163
|
'signup-password',
|
|
164
|
+
'passkeys',
|
|
125
165
|
];
|
|
166
|
+
// Prompts that may not be available on all tenants (early access features)
|
|
167
|
+
const optionalPartialsPromptTypes = ['passkeys'];
|
|
126
168
|
const customPartialsScreenTypes = [
|
|
127
169
|
'login',
|
|
128
170
|
'login-id',
|
|
@@ -132,6 +174,8 @@ const customPartialsScreenTypes = [
|
|
|
132
174
|
'signup-password',
|
|
133
175
|
'login-passwordless-sms-otp',
|
|
134
176
|
'login-passwordless-email-code',
|
|
177
|
+
'passkeys-enrollment',
|
|
178
|
+
'passkeys-enrollment-local',
|
|
135
179
|
];
|
|
136
180
|
const customPartialsInsertionPoints = [
|
|
137
181
|
'form-content-start',
|
|
@@ -319,6 +363,19 @@ class PromptsHandler extends default_1.default {
|
|
|
319
363
|
this.IsFeatureSupported = false;
|
|
320
364
|
return null;
|
|
321
365
|
}
|
|
366
|
+
// Handle 400 errors for prompt types not available on all tenants (early access features)
|
|
367
|
+
// Error format: "Path validation error: 'Invalid value \"passkeys\"' on property prompt (Name of the prompt)."
|
|
368
|
+
if (error &&
|
|
369
|
+
error?.statusCode === 400 &&
|
|
370
|
+
error.message?.includes('Path validation error') &&
|
|
371
|
+
error.message?.includes('on property prompt')) {
|
|
372
|
+
// Check if the error message contains any of the optional prompt types
|
|
373
|
+
const unavailablePrompt = optionalPartialsPromptTypes.find((promptType) => error.message?.includes(promptType));
|
|
374
|
+
if (unavailablePrompt) {
|
|
375
|
+
logger_1.default.warn(`Skipping partials for prompt type '${unavailablePrompt}' because it is not available on this tenant.`);
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
322
379
|
if (error && error.statusCode === 429) {
|
|
323
380
|
logger_1.default.error(`The global rate limit has been exceeded, resulting in a ${error.statusCode} error. ${error.message}. Although this is an error, it is not blocking the pipeline.`);
|
|
324
381
|
return null;
|
|
@@ -459,3 +516,6 @@ class PromptsHandler extends default_1.default {
|
|
|
459
516
|
}
|
|
460
517
|
}
|
|
461
518
|
exports.default = PromptsHandler;
|
|
519
|
+
__decorate([
|
|
520
|
+
(0, default_1.order)('80')
|
|
521
|
+
], PromptsHandler.prototype, "processChanges", null);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auth0-deploy-cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.30.0",
|
|
4
4
|
"description": "A command line tool for deploying updates to your Auth0 tenant",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"lint": "eslint . && kacl lint",
|
|
12
12
|
"format": "npx prettier --write .",
|
|
13
13
|
"test": "ts-mocha -p tsconfig.json --recursive 'test/**/*.test*' --exclude 'test/e2e/*' --timeout 20000",
|
|
14
|
-
"test:e2e:node-module": "ts-mocha -p tsconfig.json --recursive 'test/e2e/*.test*' --timeout
|
|
14
|
+
"test:e2e:node-module": "ts-mocha -p tsconfig.json --recursive 'test/e2e/*.test*' --timeout 150000",
|
|
15
15
|
"test:e2e:cli": "sh ./test/e2e/e2e-cli.sh",
|
|
16
16
|
"test:coverage": "nyc npm run test && nyc report --reporter=lcov",
|
|
17
17
|
"build": "rimraf ./lib && npx tsc",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"homepage": "https://github.com/auth0/auth0-deploy-cli#readme",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"ajv": "^6.12.6",
|
|
36
|
-
"auth0": "^5.
|
|
36
|
+
"auth0": "^5.5.0",
|
|
37
37
|
"dot-prop": "^5.3.0",
|
|
38
38
|
"fs-extra": "^10.1.0",
|
|
39
39
|
"js-yaml": "^4.1.1",
|