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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Common Pitfalls — auth0-deploy-cli
|
|
2
|
+
|
|
3
|
+
## 1. Dry-run must never mutate
|
|
4
|
+
|
|
5
|
+
`processChanges()` is called in both live and dry-run mode. The dry-run guard lives higher up the call stack — any code path that bypasses it (e.g. a direct API call outside `processChanges`) silently mutates tenant state. Always verify the full call graph, not just the handler method.
|
|
6
|
+
|
|
7
|
+
## 2. Both YAML and directory formats must work
|
|
8
|
+
|
|
9
|
+
New fields, handlers, and schema changes must work in both context formats. The YAML context uses a single `tenant.yaml`; the directory context uses nested JSON files. Test with both. Failing one format is a silent breakage users hit in production.
|
|
10
|
+
|
|
11
|
+
## 3. @@KEY@@ vs ##KEY## — use the right pattern
|
|
12
|
+
|
|
13
|
+
- `@@KEY@@` — JSON-stringified. Use for arrays, objects, booleans, numbers. If the replacement is a JSON array, `@@KEY@@` produces valid YAML/JSON inline.
|
|
14
|
+
- `##KEY##` — literal string substitution. Use only for plain string values.
|
|
15
|
+
|
|
16
|
+
Mixing them up causes silent corruption: a `##KEY##` wrapping a JSON array produces invalid YAML.
|
|
17
|
+
|
|
18
|
+
## 4. "Code path confirmed correct" ≠ "tested end-to-end"
|
|
19
|
+
|
|
20
|
+
For EA / entitlement-gated features, code review cannot substitute for a real API call. The API may return fields the code doesn't expect, or omit fields the code reads from `this.existing`. Always document what you could not test and create a follow-up ticket.
|
|
21
|
+
|
|
22
|
+
## 5. additionalProperties: false on EA objects
|
|
23
|
+
|
|
24
|
+
If a schema uses `additionalProperties: false` and the API later returns a new field on that object, every deploy will fail schema validation. Only use `additionalProperties: false` after confirming the exact API response shape from a real tenant response — not API docs alone.
|
|
25
|
+
|
|
26
|
+
## 6. identifiers must include name
|
|
27
|
+
|
|
28
|
+
`identifiers = ['id']` uses the auto-generated API ID for cross-tenant matching. This breaks portability — the ID is tenant-specific. Always include `name` (or a stable name-like field) as the primary matching key.
|
|
29
|
+
|
|
30
|
+
## 7. Export → re-deploy roundtrip must be idempotent
|
|
31
|
+
|
|
32
|
+
After an export, re-deploying the same config with no manual changes must produce zero diffs. Any field that gets transformed on export and then looks different on the next import/export cycle is a bug. Test this explicitly for new fields.
|
|
33
|
+
|
|
34
|
+
## 8. @order() placement
|
|
35
|
+
|
|
36
|
+
Handlers run in dependency order defined by `@order()`. A handler that creates resources another depends on (e.g. Connections before Clients) must have a lower order number. Wrong order → 404s or constraint errors during deploy.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Debugging
|
|
41
|
+
|
|
42
|
+
### Enable verbose logging
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
AUTH0_DEBUG=true node lib/index.js import -c config.json -i ./local/tenant.json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Common issues
|
|
49
|
+
|
|
50
|
+
| Symptom | Likely cause | Fix |
|
|
51
|
+
| ---------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------------- |
|
|
52
|
+
| Build errors / import not found | `tsconfig.json` path mismatch | Check `tsconfig.json` and ensure all imports resolve |
|
|
53
|
+
| "Handler not found" / resource skipped silently | Resource type not registered | Verify it's added to `src/tools/constants.ts` |
|
|
54
|
+
| Schema validation fails on deploy | Schema too strict or missing fields | Check schema definition in the handler file; confirm against a real API response |
|
|
55
|
+
| Keyword replacement produces raw `@@KEY@@` in output | Mapping missing or wrong pattern | Verify `AUTH0_KEYWORD_REPLACE_MAPPINGS` config and confirm `@@KEY@@` vs `##KEY##` |
|
|
56
|
+
| E2E fails with auth errors | Missing or wrong credentials | Check `AUTH0_DOMAIN`, `AUTH0_CLIENT_ID`, `AUTH0_CLIENT_SECRET` |
|
|
57
|
+
|
|
58
|
+
### Key files for debugging
|
|
59
|
+
|
|
60
|
+
- `src/tools/deploy.ts` — deployment orchestration; check here first if a resource is silently skipped
|
|
61
|
+
- `src/tools/calculateChanges.ts` — change detection; check here for unexpected create/update/delete
|
|
62
|
+
- `test/utils.js` — `mockPagedData()` and other test helpers
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Testing Reference — auth0-deploy-cli
|
|
2
|
+
|
|
3
|
+
## Framework and Tools
|
|
4
|
+
|
|
5
|
+
- **Test runner**: Mocha 10.x (`ts-mocha` for TypeScript)
|
|
6
|
+
- **Stubs / spies**: sinon
|
|
7
|
+
- **Coverage**: nyc (Istanbul)
|
|
8
|
+
- **Test location**: `test/` (mirrors `src/` structure)
|
|
9
|
+
- **File pattern**: `test/**/*.test*` (excludes `test/e2e/`)
|
|
10
|
+
- **Timeout**: 20 000 ms per test
|
|
11
|
+
|
|
12
|
+
## Running Tests
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# All unit tests (safe — no credentials)
|
|
16
|
+
npm test
|
|
17
|
+
|
|
18
|
+
# Single file
|
|
19
|
+
npx ts-mocha -p tsconfig.json test/tools/auth0/handlers/clients.test.js
|
|
20
|
+
|
|
21
|
+
# Pattern match
|
|
22
|
+
npm test -- --grep "should create client"
|
|
23
|
+
|
|
24
|
+
# With coverage report
|
|
25
|
+
npm run test:coverage
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Handler Test Scaffolding
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
const mockClient = {
|
|
32
|
+
clients: {
|
|
33
|
+
getAll: sinon.stub().returns(
|
|
34
|
+
mockPagedData([
|
|
35
|
+
/* existing resources */
|
|
36
|
+
])
|
|
37
|
+
),
|
|
38
|
+
create: sinon.stub().resolves({ client_id: 'abc', name: 'my-app' }),
|
|
39
|
+
update: sinon.stub().resolves({}),
|
|
40
|
+
delete: sinon.stub().resolves({}),
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const mockConfig = (key) => {
|
|
45
|
+
const config = {
|
|
46
|
+
AUTH0_ALLOW_DELETE: false,
|
|
47
|
+
AUTH0_EXCLUDED_CLIENTS: [],
|
|
48
|
+
};
|
|
49
|
+
return config[key];
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Test Naming Convention
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
describe('ClientsHandler', () => {
|
|
57
|
+
it('should create a client when it does not exist', async () => { ... });
|
|
58
|
+
it('should update a client when it already exists', async () => { ... });
|
|
59
|
+
it('should not delete when AUTH0_ALLOW_DELETE is false', async () => { ... });
|
|
60
|
+
it('should delete when AUTH0_ALLOW_DELETE is true', async () => { ... });
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Key Test Utilities
|
|
65
|
+
|
|
66
|
+
- `test/utils.js` — `mockPagedData()`, `buildStateObject()`, and other shared helpers
|
|
67
|
+
- `sinon.stub().resolves(value)` — async stubs
|
|
68
|
+
- `sinon.stub().returns(value)` — synchronous stubs (e.g. paged data iterators)
|
|
69
|
+
|
|
70
|
+
## What to Cover in Every Handler Test
|
|
71
|
+
|
|
72
|
+
- **Happy path**: normal create, update, delete with `AUTH0_ALLOW_DELETE=true`
|
|
73
|
+
- **No-delete guard**: `AUTH0_ALLOW_DELETE=false` produces zero deletes
|
|
74
|
+
- **Empty input**: empty asset arrays produce zero API calls
|
|
75
|
+
- **Idempotency**: deploy with unchanged config produces zero create/update/delete calls
|
|
76
|
+
- **Error path**: API call failure is surfaced (not swallowed)
|
|
77
|
+
- **Regression**: if fixing a bug, a test that would have caught the original bug
|
|
78
|
+
|
|
79
|
+
## Verifying Mocks
|
|
80
|
+
|
|
81
|
+
Always confirm the stub shape matches what the real API returns. A test named "should not delete" can pass silently for the wrong reason if the mock is wrong — verify the `sinon.stub()` is actually being called (or not called) via `sinon.assert`.
|
|
82
|
+
|
|
83
|
+
## E2E Test Requirements
|
|
84
|
+
|
|
85
|
+
> ⚠️ Ask before running — these mutate real tenant state.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Node module E2E (uses HTTP recordings)
|
|
89
|
+
AUTH0_HTTP_RECORDINGS=lockdown npm run test:e2e:node-module
|
|
90
|
+
|
|
91
|
+
# CLI E2E (requires real tenant)
|
|
92
|
+
AUTH0_DOMAIN=<tenant> AUTH0_CLIENT_ID=<id> AUTH0_CLIENT_SECRET=<secret> npm run test:e2e:cli
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use a dedicated development tenant. Never run E2E against a production tenant.
|
|
96
|
+
|
|
97
|
+
## Configuration Testing
|
|
98
|
+
|
|
99
|
+
When testing resource exclusion and property filtering:
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
const mockConfig = (key) => {
|
|
103
|
+
const config = {
|
|
104
|
+
AUTH0_ALLOW_DELETE: false,
|
|
105
|
+
AUTH0_EXCLUDED: [], // resource types excluded entirely
|
|
106
|
+
AUTH0_EXCLUDED_CLIENTS: ['my-app'], // named exclusion per resource type
|
|
107
|
+
EXCLUDED_PROPS: { clients: ['description'] }, // properties excluded from comparison
|
|
108
|
+
INCLUDED_PROPS: { clients: ['name', 'app_type'] }, // properties included in comparison
|
|
109
|
+
};
|
|
110
|
+
return config[key];
|
|
111
|
+
};
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- `AUTH0_EXCLUDED` — array of resource type strings to skip entirely
|
|
115
|
+
- `AUTH0_EXCLUDED_<TYPE>` — array of resource names to skip within a type
|
|
116
|
+
- `EXCLUDED_PROPS` — per-type list of properties to ignore during diff
|
|
117
|
+
- `INCLUDED_PROPS` — per-type allowlist; when set, only listed properties are compared
|
|
118
|
+
- Test keyword replacement by passing `AUTH0_KEYWORD_REPLACE_MAPPINGS` with a sample mapping and verifying the resolved value in the exported/imported asset
|