auth0-deploy-cli 7.5.2 → 7.7.1
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/.eslintrc +7 -41
- package/.husky/pre-commit +4 -0
- package/.husky/pre-push +3 -1
- package/.prettierignore +10 -0
- package/.prettierrc.json +4 -0
- package/CHANGELOG.md +219 -7
- package/CONTRIBUTING.md +2 -2
- package/README.md +3 -0
- package/lib/args.js +16 -17
- package/lib/commands/export.js +3 -3
- package/lib/commands/import.js +7 -6
- package/lib/commands/index.js +1 -1
- package/lib/configFactory.js +5 -1
- package/lib/context/defaults.js +4 -3
- package/lib/context/directory/handlers/actions.js +6 -5
- package/lib/context/directory/handlers/attackProtection.js +10 -9
- package/lib/context/directory/handlers/branding.js +60 -0
- package/lib/context/directory/handlers/clientGrants.js +6 -4
- package/lib/context/directory/handlers/clients.js +4 -3
- package/lib/context/directory/handlers/connections.js +7 -4
- package/lib/context/directory/handlers/databases.js +30 -22
- package/lib/context/directory/handlers/emailProvider.js +6 -4
- package/lib/context/directory/handlers/emailTemplates.js +13 -11
- package/lib/context/directory/handlers/guardianFactorProviders.js +6 -4
- package/lib/context/directory/handlers/guardianFactorTemplates.js +6 -4
- package/lib/context/directory/handlers/guardianFactors.js +6 -4
- package/lib/context/directory/handlers/guardianPhoneFactorMessageTypes.js +4 -3
- package/lib/context/directory/handlers/guardianPhoneFactorSelectedProvider.js +4 -3
- package/lib/context/directory/handlers/guardianPolicies.js +4 -3
- package/lib/context/directory/handlers/hooks.js +5 -4
- package/lib/context/directory/handlers/index.js +5 -2
- package/lib/context/directory/handlers/migrations.js +8 -8
- package/lib/context/directory/handlers/organizations.js +4 -3
- package/lib/context/directory/handlers/pages.js +20 -20
- package/lib/context/directory/handlers/resourceServers.js +6 -4
- package/lib/context/directory/handlers/roles.js +4 -3
- package/lib/context/directory/handlers/rules.js +5 -4
- package/lib/context/directory/handlers/rulesConfigs.js +7 -5
- package/lib/context/directory/handlers/tenant.js +7 -4
- package/lib/context/directory/handlers/triggers.js +3 -2
- package/lib/context/directory/index.js +23 -22
- package/lib/context/index.js +83 -61
- package/lib/context/yaml/handlers/actions.js +12 -8
- package/lib/context/yaml/handlers/attackProtection.js +6 -12
- package/lib/context/yaml/handlers/branding.js +66 -0
- package/lib/context/yaml/handlers/clientGrants.js +5 -4
- package/lib/context/yaml/handlers/clients.js +9 -6
- package/lib/context/yaml/handlers/connections.js +10 -7
- package/lib/context/yaml/handlers/databases.js +15 -10
- package/lib/context/yaml/handlers/emailProvider.js +7 -5
- package/lib/context/yaml/handlers/emailTemplates.js +6 -5
- package/lib/context/yaml/handlers/guardianFactorProviders.js +6 -13
- package/lib/context/yaml/handlers/guardianFactorTemplates.js +6 -13
- package/lib/context/yaml/handlers/guardianFactors.js +6 -13
- package/lib/context/yaml/handlers/guardianPhoneFactorMessageTypes.js +6 -13
- package/lib/context/yaml/handlers/guardianPhoneFactorSelectedProvider.js +6 -13
- package/lib/context/yaml/handlers/guardianPolicies.js +6 -13
- package/lib/context/yaml/handlers/hooks.js +7 -5
- package/lib/context/yaml/handlers/index.js +5 -2
- package/lib/context/yaml/handlers/migrations.js +3 -2
- package/lib/context/yaml/handlers/organizations.js +6 -5
- package/lib/context/yaml/handlers/pages.js +6 -5
- package/lib/context/yaml/handlers/resourceServers.js +5 -4
- package/lib/context/yaml/handlers/roles.js +6 -5
- package/lib/context/yaml/handlers/rules.js +6 -5
- package/lib/context/yaml/handlers/rulesConfigs.js +6 -5
- package/lib/context/yaml/handlers/tenant.js +7 -5
- package/lib/context/yaml/handlers/triggers.js +5 -4
- package/lib/context/yaml/index.js +33 -24
- package/lib/index.js +20 -15
- package/lib/logger.js +4 -3
- package/lib/readonly.js +11 -16
- package/lib/sessionDurationsToMinutes.js +15 -0
- package/lib/tools/auth0/client.js +12 -12
- package/lib/tools/auth0/handlers/actions.js +21 -23
- package/lib/tools/auth0/handlers/attackProtection.js +14 -17
- package/lib/tools/auth0/handlers/branding.js +71 -13
- package/lib/tools/auth0/handlers/clientGrants.js +17 -10
- package/lib/tools/auth0/handlers/clients.js +15 -8
- package/lib/tools/auth0/handlers/connections.js +30 -10
- package/lib/tools/auth0/handlers/databases.js +25 -13
- package/lib/tools/auth0/handlers/default.js +46 -28
- package/lib/tools/auth0/handlers/emailTemplates.js +8 -10
- package/lib/tools/auth0/handlers/guardianFactorProviders.js +3 -3
- package/lib/tools/auth0/handlers/guardianFactorTemplates.js +3 -3
- package/lib/tools/auth0/handlers/guardianFactors.js +3 -3
- package/lib/tools/auth0/handlers/guardianPhoneFactorMessageTypes.js +11 -10
- package/lib/tools/auth0/handlers/guardianPhoneFactorSelectedProvider.js +10 -9
- package/lib/tools/auth0/handlers/guardianPolicies.js +5 -4
- package/lib/tools/auth0/handlers/hooks.js +34 -21
- package/lib/tools/auth0/handlers/index.js +31 -27
- package/lib/tools/auth0/handlers/migrations.js +2 -1
- package/lib/tools/auth0/handlers/organizations.js +67 -32
- package/lib/tools/auth0/handlers/pages.js +20 -14
- package/lib/tools/auth0/handlers/prompts.js +1 -0
- package/lib/tools/auth0/handlers/resourceServers.js +28 -15
- package/lib/tools/auth0/handlers/roles.js +61 -32
- package/lib/tools/auth0/handlers/rules.js +58 -35
- package/lib/tools/auth0/handlers/rulesConfigs.js +12 -6
- package/lib/tools/auth0/handlers/tenant.js +8 -4
- package/lib/tools/auth0/handlers/triggers.js +11 -12
- package/lib/tools/auth0/index.js +15 -31
- package/lib/tools/auth0/schema.js +7 -27
- package/lib/tools/calculateChanges.js +149 -0
- package/lib/tools/constants.js +162 -154
- package/lib/tools/deploy.js +1 -1
- package/lib/tools/index.js +1 -1
- package/lib/tools/logger.js +14 -8
- package/lib/tools/utils.js +34 -150
- package/lib/tools/{ValidationError.js → validationError.js} +3 -1
- package/lib/types.js +2 -0
- package/lib/utils.js +18 -25
- package/package.json +11 -2
- package/tsconfig.json +2 -3
- package/typescript-migration-progress.sh +1 -1
|
@@ -13,13 +13,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.schema = exports.excludeSchema = void 0;
|
|
16
|
-
const
|
|
16
|
+
const validationError_1 = __importDefault(require("../../validationError"));
|
|
17
17
|
const utils_1 = require("../../utils");
|
|
18
18
|
const default_1 = __importDefault(require("./default"));
|
|
19
19
|
const logger_1 = __importDefault(require("../../logger"));
|
|
20
|
+
const calculateChanges_1 = require("../../calculateChanges");
|
|
20
21
|
exports.excludeSchema = {
|
|
21
22
|
type: 'array',
|
|
22
|
-
items: { type: 'string' }
|
|
23
|
+
items: { type: 'string' },
|
|
23
24
|
};
|
|
24
25
|
exports.schema = {
|
|
25
26
|
type: 'array',
|
|
@@ -29,38 +30,37 @@ exports.schema = {
|
|
|
29
30
|
properties: {
|
|
30
31
|
script: {
|
|
31
32
|
type: 'string',
|
|
32
|
-
description:
|
|
33
|
-
default: ''
|
|
33
|
+
description: "A script that contains the rule's code",
|
|
34
|
+
default: '',
|
|
34
35
|
},
|
|
35
36
|
name: {
|
|
36
37
|
type: 'string',
|
|
37
|
-
description:
|
|
38
|
-
pattern: '^[^-\\s][a-zA-Z0-9-\\s]+[^-\\s]$'
|
|
38
|
+
description: "The name of the rule. Can only contain alphanumeric characters, spaces and '-'. Can neither start nor end with '-' or spaces",
|
|
39
|
+
pattern: '^[^-\\s][a-zA-Z0-9-\\s]+[^-\\s]$',
|
|
39
40
|
},
|
|
40
41
|
order: {
|
|
41
42
|
type: ['number', 'null'],
|
|
42
|
-
description:
|
|
43
|
-
default: null
|
|
43
|
+
description: "The rule's order in relation to other rules. A rule with a lower order than another rule executes first.",
|
|
44
|
+
default: null,
|
|
44
45
|
},
|
|
45
46
|
enabled: {
|
|
46
47
|
type: 'boolean',
|
|
47
48
|
description: 'true if the rule is enabled, false otherwise',
|
|
48
|
-
default: true
|
|
49
|
+
default: true,
|
|
49
50
|
},
|
|
50
51
|
stage: {
|
|
51
52
|
type: 'string',
|
|
52
|
-
description:
|
|
53
|
+
description: "The rule's execution stage",
|
|
53
54
|
default: 'login_success',
|
|
54
|
-
enum: ['login_success', 'login_failure', 'pre_authorize']
|
|
55
|
-
}
|
|
55
|
+
enum: ['login_success', 'login_failure', 'pre_authorize'],
|
|
56
|
+
},
|
|
56
57
|
},
|
|
57
|
-
required: ['name']
|
|
58
|
-
}
|
|
58
|
+
required: ['name'],
|
|
59
|
+
},
|
|
59
60
|
};
|
|
60
61
|
class RulesHandler extends default_1.default {
|
|
61
62
|
constructor(options) {
|
|
62
|
-
super(Object.assign(Object.assign({}, options), { type: 'rules', stripUpdateFields: ['stage']
|
|
63
|
-
}));
|
|
63
|
+
super(Object.assign(Object.assign({}, options), { type: 'rules', stripUpdateFields: ['stage'] }));
|
|
64
64
|
}
|
|
65
65
|
getType() {
|
|
66
66
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -84,17 +84,27 @@ class RulesHandler extends default_1.default {
|
|
|
84
84
|
existing = existing.filter((r) => !excludedRules.includes(r.name));
|
|
85
85
|
}
|
|
86
86
|
// Figure out what needs to be updated vs created
|
|
87
|
-
const { del, update, create, conflicts } = (0,
|
|
87
|
+
const { del, update, create, conflicts } = (0, calculateChanges_1.calculateChanges)({
|
|
88
|
+
handler: this,
|
|
89
|
+
assets: rules,
|
|
90
|
+
existing,
|
|
91
|
+
identifiers: ['id', 'name'],
|
|
92
|
+
allowDelete: false, //TODO: actually pass in correct allowDelete value
|
|
93
|
+
});
|
|
88
94
|
// Figure out the rules that need to be re-ordered
|
|
89
95
|
const futureRules = [...create, ...update];
|
|
90
96
|
const futureMaxOrder = Math.max(...futureRules.map((r) => r.order));
|
|
91
97
|
const existingMaxOrder = Math.max(...existing.map((r) => r.order));
|
|
92
98
|
let nextOrderNo = Math.max(futureMaxOrder, existingMaxOrder);
|
|
99
|
+
//@ts-ignore because we know reOrder is Asset[]
|
|
93
100
|
const reOrder = futureRules.reduce((accum, r) => {
|
|
94
101
|
const conflict = existing.find((f) => r.order === f.order && r.name !== f.name);
|
|
95
|
-
if (conflict) {
|
|
102
|
+
if (conflict !== undefined) {
|
|
96
103
|
nextOrderNo += 1;
|
|
97
|
-
|
|
104
|
+
return [
|
|
105
|
+
...accum,
|
|
106
|
+
Object.assign(Object.assign({}, conflict), { order: nextOrderNo }),
|
|
107
|
+
];
|
|
98
108
|
}
|
|
99
109
|
return accum;
|
|
100
110
|
}, []);
|
|
@@ -103,7 +113,7 @@ class RulesHandler extends default_1.default {
|
|
|
103
113
|
update,
|
|
104
114
|
create,
|
|
105
115
|
reOrder,
|
|
106
|
-
conflicts
|
|
116
|
+
conflicts,
|
|
107
117
|
};
|
|
108
118
|
});
|
|
109
119
|
}
|
|
@@ -121,24 +131,30 @@ class RulesHandler extends default_1.default {
|
|
|
121
131
|
const { update, create, del } = yield this.calcChanges(assets, true);
|
|
122
132
|
// Include del rules which are actually not going to be deleted but are excluded
|
|
123
133
|
// they can still muck up the ordering so we must take it into consideration.
|
|
124
|
-
const futureRules = [
|
|
134
|
+
const futureRules = [
|
|
135
|
+
...create,
|
|
136
|
+
...update,
|
|
137
|
+
...del.filter((r) => excludedRules.includes(r.name)),
|
|
138
|
+
];
|
|
125
139
|
// Detect rules with the same order
|
|
126
140
|
const rulesSameOrder = (0, utils_1.duplicateItems)(futureRules, 'order');
|
|
127
141
|
if (rulesSameOrder.length > 0) {
|
|
128
142
|
const formatted = rulesSameOrder.map((dups) => dups.map((d) => `${d.name}`));
|
|
129
|
-
throw new
|
|
130
|
-
${(0, utils_1.
|
|
143
|
+
throw new validationError_1.default(`There are multiple rules for the following stage-order combinations
|
|
144
|
+
${(0, utils_1.convertJsonToString)(formatted)}.
|
|
131
145
|
Only one rule must be defined for the same order number in a stage.`);
|
|
132
146
|
}
|
|
133
147
|
// Detect Rules that are changing stage as it's not allowed.
|
|
134
148
|
const existing = yield this.getType();
|
|
135
|
-
const stateChanged = futureRules
|
|
149
|
+
const stateChanged = futureRules
|
|
150
|
+
.reduce((changed, rule) => [
|
|
136
151
|
...changed,
|
|
137
|
-
...existing.filter((r) => rule.name.toLowerCase() === r.name.toLowerCase() && r.stage !== rule.stage)
|
|
138
|
-
]
|
|
152
|
+
...existing.filter((r) => rule.name.toLowerCase() === r.name.toLowerCase() && r.stage !== rule.stage),
|
|
153
|
+
], [])
|
|
154
|
+
.map((r) => r.name);
|
|
139
155
|
if (stateChanged.length > 0) {
|
|
140
|
-
throw new
|
|
141
|
-
${(0, utils_1.
|
|
156
|
+
throw new validationError_1.default(`The following rules changed stage which is not allowed:
|
|
157
|
+
${(0, utils_1.convertJsonToString)(stateChanged)}.
|
|
142
158
|
Rename the rules to recreate them and avoid this error.`);
|
|
143
159
|
}
|
|
144
160
|
yield _super.validate.call(this, assets);
|
|
@@ -156,20 +172,27 @@ class RulesHandler extends default_1.default {
|
|
|
156
172
|
// Figure out what needs to be updated vs created
|
|
157
173
|
const changes = yield this.calcChanges(assets);
|
|
158
174
|
// Temporally re-order rules with conflicting ordering
|
|
159
|
-
yield this.client.pool
|
|
175
|
+
yield this.client.pool
|
|
176
|
+
.addEachTask({
|
|
160
177
|
data: changes.reOrder,
|
|
161
|
-
generator: (rule) => this.client
|
|
178
|
+
generator: (rule) => this.client
|
|
179
|
+
.updateRule({ id: rule.id }, (0, utils_1.stripFields)(rule, this.stripUpdateFields))
|
|
180
|
+
.then(() => {
|
|
162
181
|
const updated = {
|
|
163
|
-
name: rule.name,
|
|
182
|
+
name: rule.name,
|
|
183
|
+
stage: rule.stage,
|
|
184
|
+
order: rule.order,
|
|
185
|
+
id: rule.id,
|
|
164
186
|
};
|
|
165
|
-
logger_1.default.info(`Temporally re-order Rule ${(0, utils_1.
|
|
166
|
-
})
|
|
167
|
-
})
|
|
187
|
+
logger_1.default.info(`Temporally re-order Rule ${(0, utils_1.convertJsonToString)(updated)}`);
|
|
188
|
+
}),
|
|
189
|
+
})
|
|
190
|
+
.promise();
|
|
168
191
|
yield _super.processChanges.call(this, assets, {
|
|
169
192
|
del: changes.del,
|
|
170
193
|
create: changes.create,
|
|
171
194
|
update: changes.update,
|
|
172
|
-
conflicts: changes.conflicts
|
|
195
|
+
conflicts: changes.conflicts,
|
|
173
196
|
});
|
|
174
197
|
});
|
|
175
198
|
}
|
|
@@ -20,16 +20,16 @@ exports.schema = {
|
|
|
20
20
|
type: 'object',
|
|
21
21
|
properties: {
|
|
22
22
|
key: { type: 'string', pattern: '^[A-Za-z0-9_-]*$' },
|
|
23
|
-
value: { type: 'string' }
|
|
23
|
+
value: { type: 'string' },
|
|
24
24
|
},
|
|
25
|
-
required: ['key', 'value']
|
|
25
|
+
required: ['key', 'value'],
|
|
26
26
|
},
|
|
27
|
-
additionalProperties: false
|
|
27
|
+
additionalProperties: false,
|
|
28
28
|
};
|
|
29
29
|
class RulesConfigsHandler extends default_1.default {
|
|
30
30
|
constructor(options) {
|
|
31
31
|
super(Object.assign(Object.assign({}, options), { type: 'rulesConfigs', id: 'key', functions: {
|
|
32
|
-
update: 'set' // Update or Creation of a ruleConfig is via set not update
|
|
32
|
+
update: 'set', // Update or Creation of a ruleConfig is via set not update
|
|
33
33
|
} }));
|
|
34
34
|
}
|
|
35
35
|
getType() {
|
|
@@ -45,12 +45,18 @@ class RulesConfigsHandler extends default_1.default {
|
|
|
45
45
|
const { rulesConfigs } = assets;
|
|
46
46
|
// Do nothing if not set
|
|
47
47
|
if (!rulesConfigs || !rulesConfigs.length)
|
|
48
|
-
return {
|
|
48
|
+
return {
|
|
49
|
+
del: [],
|
|
50
|
+
update: [],
|
|
51
|
+
create: [],
|
|
52
|
+
conflicts: [],
|
|
53
|
+
};
|
|
49
54
|
// Intention is to not delete/cleanup old configRules, that needs to be handled manually.
|
|
50
55
|
return {
|
|
51
56
|
del: [],
|
|
52
57
|
update: rulesConfigs,
|
|
53
|
-
create: []
|
|
58
|
+
create: [],
|
|
59
|
+
conflicts: [],
|
|
54
60
|
};
|
|
55
61
|
});
|
|
56
62
|
}
|
|
@@ -42,14 +42,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
42
42
|
};
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
44
|
exports.schema = void 0;
|
|
45
|
-
const
|
|
45
|
+
const validationError_1 = __importDefault(require("../../validationError"));
|
|
46
46
|
const default_1 = __importStar(require("./default"));
|
|
47
47
|
const pages_1 = require("./pages");
|
|
48
48
|
const utils_1 = require("../../utils");
|
|
49
49
|
exports.schema = {
|
|
50
|
-
type: 'object'
|
|
50
|
+
type: 'object',
|
|
51
51
|
};
|
|
52
|
-
const blockPageKeys = [
|
|
52
|
+
const blockPageKeys = [
|
|
53
|
+
...Object.keys(pages_1.pageNameMap),
|
|
54
|
+
...Object.values(pages_1.pageNameMap),
|
|
55
|
+
...pages_1.supportedPages,
|
|
56
|
+
];
|
|
53
57
|
class TenantHandler extends default_1.default {
|
|
54
58
|
constructor(options) {
|
|
55
59
|
super(Object.assign(Object.assign({}, options), { type: 'tenant' }));
|
|
@@ -72,7 +76,7 @@ class TenantHandler extends default_1.default {
|
|
|
72
76
|
return;
|
|
73
77
|
const pageKeys = Object.keys(tenant).filter((k) => blockPageKeys.includes(k));
|
|
74
78
|
if (pageKeys.length > 0) {
|
|
75
|
-
throw new
|
|
79
|
+
throw new validationError_1.default(`The following pages ${(0, utils_1.convertJsonToString)(pageKeys)} were found in tenant settings. Pages should be set separately. Please refer to the documentation.`);
|
|
76
80
|
}
|
|
77
81
|
});
|
|
78
82
|
}
|
|
@@ -56,15 +56,15 @@ exports.schema = {
|
|
|
56
56
|
type: 'object',
|
|
57
57
|
properties: {
|
|
58
58
|
action_name: { type: 'string', enum: constants_1.default.ACTIONS_TRIGGERS },
|
|
59
|
-
display_name: { type: 'string', default: '' }
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
59
|
+
display_name: { type: 'string', default: '' },
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
64
|
};
|
|
65
65
|
function isActionsDisabled(err) {
|
|
66
66
|
const errorBody = lodash_1.default.get(err, 'originalError.response.body') || {};
|
|
67
|
-
return
|
|
67
|
+
return err.statusCode === 403 && errorBody.errorCode === 'feature_not_enabled';
|
|
68
68
|
}
|
|
69
69
|
class TriggersHandler extends default_1.default {
|
|
70
70
|
constructor(options) {
|
|
@@ -76,8 +76,7 @@ class TriggersHandler extends default_1.default {
|
|
|
76
76
|
return this.existing;
|
|
77
77
|
}
|
|
78
78
|
// in case client version does not support actions
|
|
79
|
-
if (!this.client.actions
|
|
80
|
-
|| typeof this.client.actions.getAllTriggers !== 'function') {
|
|
79
|
+
if (!this.client.actions || typeof this.client.actions.getAllTriggers !== 'function') {
|
|
81
80
|
return [];
|
|
82
81
|
}
|
|
83
82
|
const triggerBindings = {};
|
|
@@ -87,12 +86,12 @@ class TriggersHandler extends default_1.default {
|
|
|
87
86
|
for (let i = 0; i < triggers.length; i++) {
|
|
88
87
|
const triggerId = triggers[i];
|
|
89
88
|
const { bindings } = yield this.client.actions.getTriggerBindings({
|
|
90
|
-
trigger_id: triggerId
|
|
89
|
+
trigger_id: triggerId,
|
|
91
90
|
});
|
|
92
91
|
if (bindings.length > 0) {
|
|
93
92
|
triggerBindings[triggerId] = bindings.map((binding) => ({
|
|
94
93
|
action_name: binding.action.name,
|
|
95
|
-
display_name: binding.display_name
|
|
94
|
+
display_name: binding.display_name,
|
|
96
95
|
}));
|
|
97
96
|
}
|
|
98
97
|
}
|
|
@@ -123,9 +122,9 @@ class TriggersHandler extends default_1.default {
|
|
|
123
122
|
const bindings = data.map((binding) => ({
|
|
124
123
|
ref: {
|
|
125
124
|
type: 'action_name',
|
|
126
|
-
value: binding.action_name
|
|
125
|
+
value: binding.action_name,
|
|
127
126
|
},
|
|
128
|
-
display_name: binding.display_name
|
|
127
|
+
display_name: binding.display_name,
|
|
129
128
|
}));
|
|
130
129
|
yield this.client.actions.updateTriggerBindings({ trigger_id: name }, { bindings });
|
|
131
130
|
this.didUpdate({ trigger_id: name });
|
package/lib/tools/auth0/index.js
CHANGED
|
@@ -1,27 +1,4 @@
|
|
|
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 __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -38,12 +15,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
38
15
|
const ajv_1 = __importDefault(require("ajv/lib/ajv"));
|
|
39
16
|
const client_1 = __importDefault(require("./client"));
|
|
40
17
|
const schema_1 = __importDefault(require("./schema"));
|
|
41
|
-
const
|
|
42
|
-
const defaultOrder = 50;
|
|
18
|
+
const handlers_1 = __importDefault(require("./handlers"));
|
|
43
19
|
function sortByOrder(toSort, stage) {
|
|
20
|
+
const defaultOrder = 50;
|
|
44
21
|
const sorted = [...toSort];
|
|
45
22
|
sorted.sort((a, b) => {
|
|
23
|
+
//@ts-ignore because this doesn't actually work. TODO: apply stage order
|
|
46
24
|
const aOrder = a[stage].order || defaultOrder;
|
|
25
|
+
//@ts-ignore because this doesn't actually work. TODO: apply stage order
|
|
47
26
|
const bOrder = b[stage].order || defaultOrder;
|
|
48
27
|
return aOrder - bOrder;
|
|
49
28
|
});
|
|
@@ -54,19 +33,24 @@ class Auth0 {
|
|
|
54
33
|
this.client = (0, client_1.default)(client);
|
|
55
34
|
this.config = config;
|
|
56
35
|
this.assets = assets;
|
|
57
|
-
this.handlers =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.
|
|
36
|
+
this.handlers = Object.values(handlers_1.default)
|
|
37
|
+
.map((handler) => {
|
|
38
|
+
//@ts-ignore because class expects `type` property but gets directly injected into class constructors
|
|
39
|
+
return new handler.default({ client: this.client, config: this.config });
|
|
40
|
+
})
|
|
41
|
+
.filter((handler) => {
|
|
42
|
+
const excludedAssetTypes = config('AUTH0_EXCLUDED') || [];
|
|
43
|
+
return !excludedAssetTypes.includes(handler.type);
|
|
61
44
|
});
|
|
62
45
|
}
|
|
63
46
|
runStage(stage) {
|
|
64
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
65
48
|
// Sort by priority
|
|
66
|
-
for (const handler of sortByOrder(this.handlers, stage)) {
|
|
49
|
+
for (const handler of sortByOrder(this.handlers, stage)) {
|
|
50
|
+
// eslint-disable-line
|
|
67
51
|
try {
|
|
68
52
|
const stageFn = Object.getPrototypeOf(handler)[stage];
|
|
69
|
-
this.assets = Object.assign(Object.assign({}, this.assets), (yield stageFn.apply(handler, [this.assets])) || {});
|
|
53
|
+
this.assets = Object.assign(Object.assign({}, this.assets), ((yield stageFn.apply(handler, [this.assets])) || {}));
|
|
70
54
|
}
|
|
71
55
|
catch (err) {
|
|
72
56
|
err.type = handler.type;
|
|
@@ -1,34 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
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 __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
4
|
};
|
|
25
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
const
|
|
27
|
-
const typesSchema = Object.entries(
|
|
6
|
+
const handlers_1 = __importDefault(require("./handlers"));
|
|
7
|
+
const typesSchema = Object.entries(handlers_1.default).reduce((map, [name, obj]) => {
|
|
28
8
|
map[name] = obj.schema; //eslint-disable-line
|
|
29
9
|
return map;
|
|
30
10
|
}, {});
|
|
31
|
-
const excludeSchema = Object.entries(
|
|
11
|
+
const excludeSchema = Object.entries(handlers_1.default).reduce((map, [name, obj]) => {
|
|
32
12
|
if (obj.excludeSchema) {
|
|
33
13
|
map[name] = obj.excludeSchema;
|
|
34
14
|
}
|
|
@@ -40,7 +20,7 @@ exports.default = {
|
|
|
40
20
|
properties: Object.assign(Object.assign({}, typesSchema), { exclude: {
|
|
41
21
|
type: 'object',
|
|
42
22
|
properties: Object.assign({}, excludeSchema),
|
|
43
|
-
default: {}
|
|
23
|
+
default: {},
|
|
44
24
|
} }),
|
|
45
|
-
additionalProperties: false
|
|
25
|
+
additionalProperties: false,
|
|
46
26
|
};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.calculateChanges = exports.processChangedObjectFields = void 0;
|
|
7
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
8
|
+
/**
|
|
9
|
+
* @template T
|
|
10
|
+
* @param {typeof import('./auth0/handlers/default').default} handler
|
|
11
|
+
* @param {T} desiredAssetState
|
|
12
|
+
* @param {T} currentAssetState
|
|
13
|
+
* @param {string[]} [objectFields=[]]
|
|
14
|
+
* @param {boolean} [allowDelete=false]
|
|
15
|
+
* @returns T
|
|
16
|
+
*/
|
|
17
|
+
function processChangedObjectFields({ handler, desiredAssetState, currentAssetState, allowDelete = false, }) {
|
|
18
|
+
const desiredAssetStateWithChanges = Object.assign({}, desiredAssetState);
|
|
19
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
20
|
+
for (const fieldName of handler.objectFields) {
|
|
21
|
+
const areDesiredStateAndCurrentStateEmpty = Object.keys(desiredAssetState[fieldName] || {}).length === 0 &&
|
|
22
|
+
Object.keys(currentAssetState[fieldName] || {}).length === 0;
|
|
23
|
+
if (areDesiredStateAndCurrentStateEmpty) {
|
|
24
|
+
// If both the desired state and current state for a given object is empty, it is a no-op and can skip
|
|
25
|
+
// eslint-disable-next-line no-continue
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
// A desired state that omits the objectField OR that has it as an empty object should
|
|
29
|
+
// signal that all fields should be removed (subject to ALLOW_DELETE).
|
|
30
|
+
if (desiredAssetState[fieldName] && Object.keys(desiredAssetState[fieldName]).length) {
|
|
31
|
+
// Both the current and desired state have the object field. Here's where we need to map
|
|
32
|
+
// to the APIv2 protocol of setting `null` values for deleted fields.
|
|
33
|
+
// For new and modified properties of the object field, we can just pass them through to
|
|
34
|
+
// APIv2.
|
|
35
|
+
if (currentAssetState[fieldName]) {
|
|
36
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
37
|
+
for (const currentObjectFieldPropertyName of Object.keys(currentAssetState[fieldName])) {
|
|
38
|
+
// Loop through each object property that exists currently
|
|
39
|
+
if (desiredAssetState[fieldName][currentObjectFieldPropertyName] === undefined) {
|
|
40
|
+
// If the object has a property that exists now but doesn't exist in the proposed state
|
|
41
|
+
if (allowDelete) {
|
|
42
|
+
desiredAssetStateWithChanges[fieldName][currentObjectFieldPropertyName] = null;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// If deletes aren't allowed, do outright delete the property within the object
|
|
46
|
+
logger_1.default.warn(`Detected that the ${fieldName} of the following ${handler.name || handler.id || ''} should be deleted. Doing so may be destructive.\nYou can enable deletes by setting 'AUTH0_ALLOW_DELETE' to true in the config\n${handler.objString(currentAssetState)}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (allowDelete) {
|
|
53
|
+
// If the desired state does not have the object field and the current state does, we
|
|
54
|
+
// should mark *all* properties for deletion by specifying an empty object.
|
|
55
|
+
//
|
|
56
|
+
// See: https://auth0.com/docs/users/metadata/manage-metadata-api#delete-user-metadata
|
|
57
|
+
desiredAssetStateWithChanges[fieldName] = {};
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
delete desiredAssetStateWithChanges[fieldName];
|
|
61
|
+
logger_1.default.warn(`Detected that the ${fieldName} of the following ${handler.name || handler.id || ''} should be emptied. Doing so may be destructive.\nYou can enable deletes by setting 'AUTH0_ALLOW_DELETE' to true in the config\n${handler.objString(currentAssetState)}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return desiredAssetStateWithChanges;
|
|
65
|
+
}
|
|
66
|
+
exports.processChangedObjectFields = processChangedObjectFields;
|
|
67
|
+
function calculateChanges({ handler, assets, existing, identifiers = ['id', 'name'], allowDelete, }) {
|
|
68
|
+
// Calculate the changes required between two sets of assets.
|
|
69
|
+
const update = [];
|
|
70
|
+
let del = [...existing];
|
|
71
|
+
let create = [...assets];
|
|
72
|
+
const conflicts = [];
|
|
73
|
+
const findByKeyValue = (key, value, arr) => arr.find((e) => {
|
|
74
|
+
if (Array.isArray(key)) {
|
|
75
|
+
const values = key.map((k) => e[k]);
|
|
76
|
+
if (values.every((v) => v)) {
|
|
77
|
+
return value === values.join('-');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return e[key] === value;
|
|
81
|
+
});
|
|
82
|
+
const processAssets = (id, arr) => {
|
|
83
|
+
arr.forEach((asset) => {
|
|
84
|
+
const assetIdValue = (() => {
|
|
85
|
+
if (Array.isArray(id)) {
|
|
86
|
+
const values = id.map((i) => asset[i]);
|
|
87
|
+
if (values.every((v) => v)) {
|
|
88
|
+
return values.join('-');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return asset[id];
|
|
92
|
+
})();
|
|
93
|
+
if (assetIdValue !== undefined) {
|
|
94
|
+
const found = findByKeyValue(id, assetIdValue, del);
|
|
95
|
+
if (found !== undefined) {
|
|
96
|
+
// Delete from existing
|
|
97
|
+
del = del.filter((e) => e !== found);
|
|
98
|
+
// Delete from create as it's an update
|
|
99
|
+
create = create.filter((e) => e !== asset);
|
|
100
|
+
// Append identifiers to asset
|
|
101
|
+
update.push(Object.assign(Object.assign({}, identifiers.reduce((obj, i) => {
|
|
102
|
+
if (found[i])
|
|
103
|
+
obj[i] = found[i];
|
|
104
|
+
return obj;
|
|
105
|
+
}, {})), (handler.objectFields.length
|
|
106
|
+
? processChangedObjectFields({
|
|
107
|
+
handler,
|
|
108
|
+
desiredAssetState: asset,
|
|
109
|
+
currentAssetState: found,
|
|
110
|
+
allowDelete,
|
|
111
|
+
})
|
|
112
|
+
: asset)));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
// Loop through identifiers (in order) to try match assets to existing
|
|
118
|
+
// If existing then update if not create
|
|
119
|
+
// The remainder will be deleted
|
|
120
|
+
for (const id of identifiers) {
|
|
121
|
+
// eslint-disable-line
|
|
122
|
+
processAssets(id, [...create]);
|
|
123
|
+
}
|
|
124
|
+
// Check if there are assets with names that will conflict with existing names during the update process
|
|
125
|
+
// This will rename those assets to a temp random name first
|
|
126
|
+
// This assumes the first identifiers is the unique identifier
|
|
127
|
+
if (identifiers.includes('name')) {
|
|
128
|
+
const uniqueID = identifiers[0];
|
|
129
|
+
const futureAssets = [...create, ...update];
|
|
130
|
+
futureAssets.forEach((a) => {
|
|
131
|
+
// If the conflicting item is going to be deleted then skip
|
|
132
|
+
const inDeleted = del.filter((e) => e.name === a.name && e[uniqueID] !== a[uniqueID])[0];
|
|
133
|
+
if (!inDeleted) {
|
|
134
|
+
const conflict = existing.filter((e) => e.name === a.name && e[uniqueID] !== a[uniqueID])[0];
|
|
135
|
+
if (conflict) {
|
|
136
|
+
const temp = Math.random().toString(36).substr(2, 5);
|
|
137
|
+
conflicts.push(Object.assign(Object.assign({}, conflict), { name: `${conflict.name}-${temp}` }));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
del,
|
|
144
|
+
update,
|
|
145
|
+
conflicts,
|
|
146
|
+
create,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
exports.calculateChanges = calculateChanges;
|