auth0-deploy-cli
Advanced tools
Comparing version
@@ -10,2 +10,17 @@ # Changelog | ||
## [8.8.2] - 2025-05-08 | ||
### Added | ||
- Add support for refresh token policies configuration for `clients` - EA [#1085] | ||
### Changed | ||
- Remove `AUTH0_EXPERIMENTAL_EA` flag check for screens rendering `prompt` screen's settings `import` command [#1084] | ||
### Fixed | ||
- Fix tenant network ACL management not enabled [#1079] | ||
- Fix error handling `guardianFactorProviders`, `guardianFactorTemplates`, `guardianFactors`, `guardianPhoneFactorMessageTypes`, `guardianPhoneFactorSelectedProvider` for forbidden depreated feature [#1086] | ||
## [8.8.1] - 2025-04-28 | ||
@@ -1307,3 +1322,8 @@ | ||
[#1072]: https://github.com/auth0/auth0-deploy-cli/issues/1072 | ||
[Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.8.1...HEAD | ||
[#1079]: https://github.com/auth0/auth0-deploy-cli/issues/1079 | ||
[#1084]: https://github.com/auth0/auth0-deploy-cli/issues/1084 | ||
[#1085]: https://github.com/auth0/auth0-deploy-cli/issues/1085 | ||
[#1086]: https://github.com/auth0/auth0-deploy-cli/issues/1086 | ||
[Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.8.2...HEAD | ||
[8.8.2]: https://github.com/auth0/auth0-deploy-cli/compare/v8.8.1...v8.8.2 | ||
[8.8.1]: https://github.com/auth0/auth0-deploy-cli/compare/v8.8.0...v8.8.1 | ||
@@ -1310,0 +1330,0 @@ [8.8.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.7.1...v8.8.0 |
@@ -72,2 +72,28 @@ import { Assets } from '../../../types'; | ||
}; | ||
refresh_token: { | ||
type: string[]; | ||
description: string; | ||
properties: { | ||
policies: { | ||
type: string[]; | ||
description: string; | ||
items: { | ||
type: string; | ||
properties: { | ||
audience: { | ||
type: string; | ||
}; | ||
scope: { | ||
type: string; | ||
items: { | ||
type: string; | ||
}; | ||
uniqueItems: boolean; | ||
}; | ||
}; | ||
required: string[]; | ||
}; | ||
}; | ||
}; | ||
}; | ||
}; | ||
@@ -74,0 +100,0 @@ required: string[]; |
@@ -18,2 +18,22 @@ "use strict"; | ||
const default_1 = __importDefault(require("./default")); | ||
const multiResourceRefreshTokenPolicies = { | ||
type: ['array', 'null'], | ||
description: 'A collection of policies governing multi-resource refresh token exchange (MRRT), defining how refresh tokens can be used across different resource servers', | ||
items: { | ||
type: 'object', | ||
properties: { | ||
audience: { | ||
type: 'string', | ||
}, | ||
scope: { | ||
type: 'array', | ||
items: { | ||
type: 'string', | ||
}, | ||
uniqueItems: true, | ||
}, | ||
}, | ||
required: ['audience', 'scope'], | ||
}, | ||
}; | ||
exports.schema = { | ||
@@ -70,2 +90,9 @@ type: 'array', | ||
}, | ||
refresh_token: { | ||
type: ['object', 'null'], | ||
description: 'Refresh token configuration', | ||
properties: { | ||
policies: multiResourceRefreshTokenPolicies, | ||
}, | ||
}, | ||
}, | ||
@@ -72,0 +99,0 @@ required: ['name'], |
@@ -23,4 +23,4 @@ import DefaultHandler from './default'; | ||
constructor(options: DefaultHandler); | ||
getType(): Promise<Asset[]>; | ||
getType(): Promise<Asset[] | null>; | ||
processChanges(assets: Assets): Promise<void>; | ||
} |
@@ -29,2 +29,3 @@ "use strict"; | ||
const constants_1 = __importDefault(require("../../constants")); | ||
const utils_1 = require("../../utils"); | ||
const mappings = Object.entries(constants_1.default.GUARDIAN_FACTOR_PROVIDERS).reduce((accum, [name, providers]) => { | ||
@@ -55,21 +56,32 @@ providers.forEach((p) => { | ||
return this.existing; | ||
const data = yield Promise.all(mappings.map((m) => __awaiter(this, void 0, void 0, function* () { | ||
let provider; | ||
// TODO: This is quite a change, needs to be validated for sure. | ||
if (m.name === 'phone' && m.provider === 'twilio') { | ||
provider = yield this.client.guardian.getPhoneFactorProviderTwilio(); | ||
try { | ||
const data = yield Promise.all(mappings.map((m) => __awaiter(this, void 0, void 0, function* () { | ||
let provider; | ||
// TODO: This is quite a change, needs to be validated for sure. | ||
if (m.name === 'phone' && m.provider === 'twilio') { | ||
provider = yield this.client.guardian.getPhoneFactorProviderTwilio(); | ||
} | ||
else if (m.name === 'sms' && m.provider === 'twilio') { | ||
provider = yield this.client.guardian.getSmsFactorProviderTwilio(); | ||
} | ||
else if (m.name === 'push-notification' && m.provider === 'apns') { | ||
provider = yield this.client.guardian.getPushNotificationProviderAPNS(); | ||
} | ||
else if (m.name === 'push-notification' && m.provider === 'sns') { | ||
provider = yield this.client.guardian.getPushNotificationProviderSNS(); | ||
} | ||
return Object.assign(Object.assign({}, m), provider.data); | ||
}))); | ||
// Filter out empty, should have more then 2 keys (name, provider) | ||
return data.filter((d) => Object.keys(d).length > 2); | ||
} | ||
catch (err) { | ||
if (err.statusCode === 404 || err.statusCode === 501) { | ||
return null; | ||
} | ||
else if (m.name === 'sms' && m.provider === 'twilio') { | ||
provider = yield this.client.guardian.getSmsFactorProviderTwilio(); | ||
if ((0, utils_1.isForbiddenFeatureError)(err, this.type)) { | ||
return null; | ||
} | ||
else if (m.name === 'push-notification' && m.provider === 'apns') { | ||
provider = yield this.client.guardian.getPushNotificationProviderAPNS(); | ||
} | ||
else if (m.name === 'push-notification' && m.provider === 'sns') { | ||
provider = yield this.client.guardian.getPushNotificationProviderSNS(); | ||
} | ||
return Object.assign(Object.assign({}, m), provider.data); | ||
}))); | ||
// Filter out empty, should have more then 2 keys (name, provider) | ||
return data.filter((d) => Object.keys(d).length > 2); | ||
throw err; | ||
} | ||
}); | ||
@@ -76,0 +88,0 @@ } |
@@ -19,4 +19,4 @@ import DefaultHandler from './default'; | ||
constructor(options: DefaultHandler); | ||
getType(): Promise<Asset[]>; | ||
getType(): Promise<Asset[] | null>; | ||
processChanges(assets: Assets): Promise<void>; | ||
} |
@@ -18,2 +18,3 @@ "use strict"; | ||
const constants_1 = __importDefault(require("../../constants")); | ||
const utils_1 = require("../../utils"); | ||
exports.schema = { | ||
@@ -37,5 +38,16 @@ type: 'array', | ||
return this.existing; | ||
const { data } = yield this.client.guardian.getFactors(); | ||
this.existing = data; | ||
return this.existing; | ||
try { | ||
const { data } = yield this.client.guardian.getFactors(); | ||
this.existing = data; | ||
return this.existing; | ||
} | ||
catch (err) { | ||
if (err.statusCode === 404 || err.statusCode === 501) { | ||
return null; | ||
} | ||
if ((0, utils_1.isForbiddenFeatureError)(err, this.type)) { | ||
return null; | ||
} | ||
throw err; | ||
} | ||
}); | ||
@@ -42,0 +54,0 @@ } |
@@ -19,4 +19,4 @@ import DefaultHandler from './default'; | ||
constructor(options: any); | ||
getType(): Promise<Asset[]>; | ||
getType(): Promise<Asset[] | null>; | ||
processChanges(assets: Assets): Promise<void>; | ||
} |
@@ -29,2 +29,3 @@ "use strict"; | ||
const constants_1 = __importDefault(require("../../constants")); | ||
const utils_1 = require("../../utils"); | ||
exports.schema = { | ||
@@ -48,16 +49,23 @@ type: 'array', | ||
return this.existing; | ||
const data = yield Promise.all(constants_1.default.GUARDIAN_FACTOR_TEMPLATES.map((name) => __awaiter(this, void 0, void 0, function* () { | ||
// TODO: This is quite a change, needs to be validated for sure. | ||
if (name === 'sms') { | ||
const { data: templates } = yield this.client.guardian.getSmsFactorTemplates(); | ||
return Object.assign({ name }, templates); | ||
// TODO: GUARDIAN_FACTOR_TEMPLATES only contains 'sms'. Is that expected? We also have 'phone'. | ||
} | ||
else { | ||
try { | ||
const data = yield Promise.all(constants_1.default.GUARDIAN_FACTOR_TEMPLATES.map((name) => __awaiter(this, void 0, void 0, function* () { | ||
if (name === 'sms') { | ||
const { data: templates } = yield this.client.guardian.getSmsFactorTemplates(); | ||
return Object.assign({ name }, templates); | ||
} | ||
const { data: templates } = yield this.client.guardian.getPhoneFactorTemplates(); | ||
return Object.assign({ name }, templates); | ||
}))); | ||
// Filter out empty, should have more then 1 keys (name) | ||
return data.filter((d) => Object.keys(d).length > 1); | ||
} | ||
catch (err) { | ||
if (err.statusCode === 404 || err.statusCode === 501) { | ||
return null; | ||
} | ||
}))); | ||
// Filter out empty, should have more then 1 keys (name) | ||
return data.filter((d) => Object.keys(d).length > 1); | ||
if ((0, utils_1.isForbiddenFeatureError)(err, this.type)) { | ||
return null; | ||
} | ||
throw err; | ||
} | ||
}); | ||
@@ -64,0 +72,0 @@ } |
@@ -19,4 +19,4 @@ import DefaultHandler from './default'; | ||
constructor(options: DefaultHandler); | ||
getType(): Promise<Asset[] | {}>; | ||
getType(): Promise<Asset | null>; | ||
processChanges(assets: Assets): Promise<void>; | ||
} |
@@ -18,2 +18,3 @@ "use strict"; | ||
const constants_1 = __importDefault(require("../../constants")); | ||
const utils_1 = require("../../utils"); | ||
exports.schema = { | ||
@@ -56,3 +57,3 @@ type: 'object', | ||
typeof this.client.guardian.getPhoneFactorMessageTypes !== 'function') { | ||
return {}; | ||
return null; | ||
} | ||
@@ -65,8 +66,11 @@ if (this.existing) | ||
} | ||
catch (e) { | ||
if (isFeatureUnavailableError(e)) { | ||
catch (err) { | ||
if (isFeatureUnavailableError(err)) { | ||
// Gracefully skip processing this configuration value. | ||
return {}; | ||
return null; | ||
} | ||
throw e; | ||
if ((0, utils_1.isForbiddenFeatureError)(err, this.type)) { | ||
return null; | ||
} | ||
throw err; | ||
} | ||
@@ -73,0 +77,0 @@ return this.existing; |
@@ -16,4 +16,4 @@ import DefaultHandler from './default'; | ||
constructor(options: any); | ||
getType(): Promise<Asset>; | ||
getType(): Promise<Asset | null>; | ||
processChanges(assets: Assets): Promise<void>; | ||
} |
@@ -18,2 +18,3 @@ "use strict"; | ||
const constants_1 = __importDefault(require("../../constants")); | ||
const utils_1 = require("../../utils"); | ||
exports.schema = { | ||
@@ -53,3 +54,3 @@ type: 'object', | ||
typeof this.client.guardian.getPhoneFactorSelectedProvider !== 'function') { | ||
return {}; | ||
return null; | ||
} | ||
@@ -62,8 +63,11 @@ if (this.existing) | ||
} | ||
catch (e) { | ||
if (isFeatureUnavailableError(e)) { | ||
catch (err) { | ||
if (isFeatureUnavailableError(err)) { | ||
// Gracefully skip processing this configuration value. | ||
return {}; | ||
return null; | ||
} | ||
throw e; | ||
if ((0, utils_1.isForbiddenFeatureError)(err, this.type)) { | ||
return null; | ||
} | ||
throw err; | ||
} | ||
@@ -70,0 +74,0 @@ return this.existing; |
@@ -241,2 +241,6 @@ "use strict"; | ||
} | ||
if (err.statusCode === 403) { | ||
logger_1.default.debug('Tenant ACL Management is not enabled for this tenant. Please verify `scope` or contact Auth0 support to enable this feature.'); | ||
return null; | ||
} | ||
throw err; | ||
@@ -243,0 +247,0 @@ } |
@@ -389,7 +389,4 @@ "use strict"; | ||
yield this.updateCustomPromptsPartials(partials); | ||
const includeExperimentalEA = this.config('AUTH0_EXPERIMENTAL_EA') || false; | ||
if (includeExperimentalEA) { | ||
// Update screen renderers | ||
yield this.updateScreenRenderers(screenRenderers); | ||
} | ||
// Update screen renderers | ||
yield this.updateScreenRenderers(screenRenderers); | ||
this.updated += 1; | ||
@@ -396,0 +393,0 @@ this.didUpdate(prompts); |
@@ -39,1 +39,2 @@ import { Asset, Assets, CalculatedChanges, KeywordMappings } from '../types'; | ||
}) => boolean; | ||
export declare const isForbiddenFeatureError: (err: any, type: any) => boolean; |
@@ -48,3 +48,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isDeprecatedError = exports.detectInsufficientScopeError = exports.stripObfuscatedFieldsFromPayload = exports.obfuscateSensitiveValues = exports.keywordReplaceStringRegExp = exports.keywordReplaceArrayRegExp = void 0; | ||
exports.isForbiddenFeatureError = exports.isDeprecatedError = exports.detectInsufficientScopeError = exports.stripObfuscatedFieldsFromPayload = exports.obfuscateSensitiveValues = exports.keywordReplaceStringRegExp = exports.keywordReplaceArrayRegExp = void 0; | ||
exports.keywordArrayReplace = keywordArrayReplace; | ||
@@ -288,2 +288,11 @@ exports.keywordStringReplace = keywordStringReplace; | ||
exports.isDeprecatedError = isDeprecatedError; | ||
const isForbiddenFeatureError = (err, type) => { | ||
var _a; | ||
if (err.statusCode === 403) { | ||
logger_1.default.warn(`${err.message};${(_a = err.errorCode) !== null && _a !== void 0 ? _a : ''} - Skipping ${type}`); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
exports.isForbiddenFeatureError = isForbiddenFeatureError; | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "auth0-deploy-cli", | ||
"version": "8.8.1", | ||
"version": "8.8.2", | ||
"description": "A command line tool for deploying updates to your Auth0 tenant", | ||
@@ -36,3 +36,3 @@ "main": "lib/index.js", | ||
"ajv": "^6.12.6", | ||
"auth0": "^4.21.0", | ||
"auth0": "^4.23.0", | ||
"dot-prop": "^5.3.0", | ||
@@ -43,6 +43,6 @@ "fs-extra": "^10.1.0", | ||
"mkdirp": "^1.0.4", | ||
"nconf": "^0.12.1", | ||
"nconf": "^0.13.0", | ||
"promise-pool-executor": "^1.1.1", | ||
"sanitize-filename": "^1.6.3", | ||
"undici": "^7.7.0", | ||
"undici": "^7.8.0", | ||
"winston": "^3.17.0", | ||
@@ -76,3 +76,3 @@ "yargs": "^15.4.1" | ||
"ts-mocha": "^10.1.0", | ||
"typescript": "^5.8.2", | ||
"typescript": "^5.8.3", | ||
"zlib": "^1.0.5" | ||
@@ -79,0 +79,0 @@ }, |
@@ -8,28 +8,5 @@  | ||
--- | ||
## Help Us Improve Auth0 Deploy CLI – Take Our Survey! | ||
👋 Hello developers! We're on a mission to make Auth0 Deploy CLI the best it can be, and we need YOUR help. We've put together a brief survey to understand how you use Deploy CLI, what you love about it, and where you think we can do better. | ||
### Why Should You Take the Survey? | ||
- **Direct Impact:** Your feedback will directly influence the future of Deploy CLI. Ever wished for a feature or fix? Here's your chance to let us know. | ||
- **It's Quick:** The survey takes less than 10 minutes to complete. | ||
### Privacy | ||
We care about your privacy. All data collected is anonymous and will only be used for improving Auth0 Deploy CLI. | ||
### Ready to Make a Difference? | ||
[Click here to take the survey](https://www.surveymonkey.com/r/LZKMPFN) | ||
Thank you for helping us make Auth0 Deploy CLI better for everyone! | ||
--- | ||
The Auth0 Deploy CLI is a tool that helps you manage your Auth0 tenant configuration. It integrates into your development workflows as a standalone CLI or as a node module. | ||
**Supported resource types:** actions, branding, client grants, clients (applications), connections, custom domains, email templates, emails, grants, guardian, hook secrets, log streams, migrations, organizations, pages, prompts, resource servers (APIs), roles, tenant settings, themes. | ||
**Supported resource types:** actions, branding, client grants, clients (applications), connections, custom domains, email templates, emails, grants, guardian, hook secrets, log streams, migrations, organizations, pages, prompts, resource servers (APIs), roles, tenant settings, themes, forms, flows, self-service profiles, network ACLs. | ||
@@ -36,0 +13,0 @@ 🎢 [Highlights](#highlights) • 📚 [Documentation](#documentation) • 🚀 [Getting Started](#getting-started) • 💬 [Feedback](#feedback) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
1234265
0.47%17851
0.59%142
-13.94%+ Added
- Removed
Updated
Updated
Updated