@rockcarver/frodo-lib 0.12.3 → 0.12.5-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/CHANGELOG.md +55 -1
- package/cjs/api/AuthenticateApi.js +2 -3
- package/cjs/api/AuthenticateApi.js.map +1 -1
- package/cjs/api/BaseApi.js +2 -2
- package/cjs/api/BaseApi.js.map +1 -1
- package/cjs/ops/AuthenticateOps.js +17 -4
- package/cjs/ops/AuthenticateOps.js.map +1 -1
- package/cjs/ops/ConnectionProfileOps.js +20 -5
- package/cjs/ops/ConnectionProfileOps.js.map +1 -1
- package/cjs/ops/JourneyOps.js +167 -146
- package/cjs/ops/JourneyOps.js.map +1 -1
- package/cjs/ops/NodeOps.js +343 -0
- package/cjs/ops/NodeOps.js.map +1 -0
- package/cjs/storage/SessionStorage.js +7 -1
- package/cjs/storage/SessionStorage.js.map +1 -1
- package/esm/api/AuthenticateApi.mjs +2 -1
- package/esm/api/BaseApi.mjs +6 -2
- package/esm/ops/AuthenticateOps.mjs +15 -4
- package/esm/ops/ConnectionProfileOps.mjs +20 -5
- package/esm/ops/JourneyOps.mjs +144 -124
- package/esm/ops/NodeOps.mjs +294 -0
- package/esm/storage/SessionStorage.mjs +7 -1
- package/package.json +1 -1
- package/types/api/AuthenticateApi.d.ts.map +1 -1
- package/types/api/BaseApi.d.ts.map +1 -1
- package/types/ops/AuthenticateOps.d.ts.map +1 -1
- package/types/ops/ConnectionProfileOps.d.ts +4 -0
- package/types/ops/ConnectionProfileOps.d.ts.map +1 -1
- package/types/ops/JourneyOps.d.ts +26 -6
- package/types/ops/JourneyOps.d.ts.map +1 -1
- package/types/ops/NodeOps.d.ts +29 -0
- package/types/ops/NodeOps.d.ts.map +1 -0
- package/types/storage/SessionStorage.d.ts +7 -1
- package/types/storage/SessionStorage.d.ts.map +1 -1
package/esm/ops/JourneyOps.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { convertBase64TextToArray, getTypedFilename, saveJsonToFile, getRealmStr
|
|
|
5
5
|
import { getRealmManagedUser, replaceAll } from './utils/OpsUtils';
|
|
6
6
|
import storage from '../storage/SessionStorage';
|
|
7
7
|
import { getNode, putNode, deleteNode, getNodeTypes, getNodesByType } from '../api/NodeApi';
|
|
8
|
+
import { isCloudOnlyNode, isCustomNode, isPremiumNode } from './NodeOps';
|
|
8
9
|
import { getTrees, getTree, putTree, deleteTree } from '../api/TreeApi';
|
|
9
10
|
import { getEmailTemplate, putEmailTemplate } from '../api/EmailTemplateApi';
|
|
10
11
|
import { getScript } from '../api/ScriptApi';
|
|
@@ -1128,19 +1129,16 @@ export async function importJourneysFromFiles(options) {
|
|
|
1128
1129
|
importAllJourneys(allJourneysData.trees, options);
|
|
1129
1130
|
}
|
|
1130
1131
|
/**
|
|
1131
|
-
* Describe a
|
|
1132
|
-
* @param {
|
|
1133
|
-
* @returns {Object} an object describing the tree
|
|
1132
|
+
* Describe a journey
|
|
1133
|
+
* @param {SingleJourneyExportTemplate} journeyData journey export object
|
|
1134
1134
|
*/
|
|
1135
1135
|
|
|
1136
1136
|
export function describeJourney(journeyData) {
|
|
1137
|
-
|
|
1137
|
+
var _journeyData$themes;
|
|
1138
|
+
|
|
1138
1139
|
const nodeTypeMap = {};
|
|
1139
|
-
const scriptsMap = {};
|
|
1140
|
-
const emailTemplatesMap = {};
|
|
1141
|
-
treeMap['treeName'] = journeyData.tree._id;
|
|
1142
1140
|
|
|
1143
|
-
for (const
|
|
1141
|
+
for (const nodeData of Object.values(journeyData.nodes)) {
|
|
1144
1142
|
if (nodeTypeMap[nodeData['_type']['_id']]) {
|
|
1145
1143
|
nodeTypeMap[nodeData['_type']['_id']] += 1;
|
|
1146
1144
|
} else {
|
|
@@ -1148,7 +1146,7 @@ export function describeJourney(journeyData) {
|
|
|
1148
1146
|
}
|
|
1149
1147
|
}
|
|
1150
1148
|
|
|
1151
|
-
for (const
|
|
1149
|
+
for (const nodeData of Object.values(journeyData.innerNodes)) {
|
|
1152
1150
|
if (nodeTypeMap[nodeData['_type']['_id']]) {
|
|
1153
1151
|
nodeTypeMap[nodeData['_type']['_id']] += 1;
|
|
1154
1152
|
} else {
|
|
@@ -1156,44 +1154,69 @@ export function describeJourney(journeyData) {
|
|
|
1156
1154
|
}
|
|
1157
1155
|
}
|
|
1158
1156
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1157
|
+
printMessage(`\n${journeyData.tree._id}`, 'data');
|
|
1158
|
+
const line = Array(journeyData.tree._id['length']).fill('=').join('');
|
|
1159
|
+
printMessage(line);
|
|
1162
1160
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1161
|
+
if (journeyData.tree.description) {
|
|
1162
|
+
printMessage(`\n${journeyData.tree.description}\n`, 'data');
|
|
1165
1163
|
}
|
|
1166
1164
|
|
|
1167
|
-
treeMap['nodeTypes'] = nodeTypeMap;
|
|
1168
|
-
treeMap['scripts'] = scriptsMap;
|
|
1169
|
-
treeMap['emailTemplates'] = emailTemplatesMap;
|
|
1170
|
-
printMessage(`\nJourney: ${treeMap['treeName']}`, 'data');
|
|
1171
|
-
printMessage('========');
|
|
1172
1165
|
printMessage('\nNodes:', 'data');
|
|
1173
1166
|
|
|
1174
|
-
if (Object.entries(
|
|
1175
|
-
for (const [name, count] of Object.entries(
|
|
1176
|
-
printMessage(`- ${
|
|
1167
|
+
if (Object.entries(nodeTypeMap).length) {
|
|
1168
|
+
for (const [name, count] of Object.entries(nodeTypeMap)) {
|
|
1169
|
+
printMessage(`- [${String(count)['brightCyan']}] ${name}`, 'data');
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
if ((_journeyData$themes = journeyData.themes) !== null && _journeyData$themes !== void 0 && _journeyData$themes.length) {
|
|
1174
|
+
printMessage('\nThemes:', 'data');
|
|
1175
|
+
|
|
1176
|
+
for (const themeData of journeyData.themes) {
|
|
1177
|
+
printMessage(`- [${themeData['_id']['brightCyan']}] ${themeData['name']}`, 'data');
|
|
1177
1178
|
}
|
|
1178
1179
|
}
|
|
1179
1180
|
|
|
1180
|
-
if (Object.entries(
|
|
1181
|
+
if (Object.entries(journeyData.scripts).length) {
|
|
1181
1182
|
printMessage('\nScripts:', 'data');
|
|
1182
1183
|
|
|
1183
|
-
for (const
|
|
1184
|
-
printMessage(`- ${
|
|
1184
|
+
for (const scriptData of Object.values(journeyData.scripts)) {
|
|
1185
|
+
printMessage(`- [${scriptData['_id'].brightCyan}] ${scriptData['name']}`, 'data');
|
|
1185
1186
|
}
|
|
1186
1187
|
}
|
|
1187
1188
|
|
|
1188
|
-
if (Object.entries(
|
|
1189
|
+
if (Object.entries(journeyData.emailTemplates).length) {
|
|
1189
1190
|
printMessage('\nEmail Templates:', 'data');
|
|
1190
1191
|
|
|
1191
|
-
for (const
|
|
1192
|
-
printMessage(`- ${
|
|
1192
|
+
for (const templateData of Object.values(journeyData.emailTemplates)) {
|
|
1193
|
+
printMessage(`- ${templateData['_id'].split('/')[1]}`, 'data');
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
if (Object.entries(journeyData.socialIdentityProviders).length) {
|
|
1198
|
+
printMessage('\nSocial Identity Providers:', 'data');
|
|
1199
|
+
|
|
1200
|
+
for (const socialIdpData of Object.values(journeyData.socialIdentityProviders)) {
|
|
1201
|
+
printMessage(`- ${socialIdpData['_id']} [${socialIdpData['_type']['_id'].brightCyan}]`, 'data');
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
if (Object.entries(journeyData.saml2Entities).length) {
|
|
1206
|
+
printMessage('\nSAML2 Entity Providers:', 'data');
|
|
1207
|
+
|
|
1208
|
+
for (const entityProviderData of Object.values(journeyData.saml2Entities)) {
|
|
1209
|
+
printMessage(`- ${entityProviderData['entityId']}`, 'data');
|
|
1193
1210
|
}
|
|
1194
1211
|
}
|
|
1195
1212
|
|
|
1196
|
-
|
|
1213
|
+
if (Object.entries(journeyData.circlesOfTrust).length) {
|
|
1214
|
+
printMessage('\nSAML2 Circles Of Trust:', 'data');
|
|
1215
|
+
|
|
1216
|
+
for (const cotData of Object.values(journeyData.circlesOfTrust)) {
|
|
1217
|
+
printMessage(`- ${cotData['_id']}`, 'data');
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1197
1220
|
}
|
|
1198
1221
|
/**
|
|
1199
1222
|
* Find all node configuration objects that are no longer referenced by any tree
|
|
@@ -1297,93 +1320,82 @@ export async function removeOrphanedNodes(orphanedNodes) {
|
|
|
1297
1320
|
stopProgressIndicator(`Removed ${orphanedNodes.length} orphaned nodes.`);
|
|
1298
1321
|
return errorNodes;
|
|
1299
1322
|
}
|
|
1300
|
-
const OOTB_NODE_TYPES_7 = ['AcceptTermsAndConditionsNode', 'AccountActiveDecisionNode', 'AccountLockoutNode', 'AgentDataStoreDecisionNode', 'AnonymousSessionUpgradeNode', 'AnonymousUserNode', 'AttributeCollectorNode', 'AttributePresentDecisionNode', 'AttributeValueDecisionNode', 'AuthLevelDecisionNode', 'ChoiceCollectorNode', 'ConsentNode', 'CookiePresenceDecisionNode', 'CreateObjectNode', 'CreatePasswordNode', 'DataStoreDecisionNode', 'DeviceGeoFencingNode', 'DeviceLocationMatchNode', 'DeviceMatchNode', 'DeviceProfileCollectorNode', 'DeviceSaveNode', 'DeviceTamperingVerificationNode', 'DisplayUserNameNode', 'EmailSuspendNode', 'EmailTemplateNode', 'IdentifyExistingUserNode', 'IncrementLoginCountNode', 'InnerTreeEvaluatorNode', 'IotAuthenticationNode', 'IotRegistrationNode', 'KbaCreateNode', 'KbaDecisionNode', 'KbaVerifyNode', 'LdapDecisionNode', 'LoginCountDecisionNode', 'MessageNode', 'MetadataNode', 'MeterNode', 'ModifyAuthLevelNode', 'OneTimePasswordCollectorDecisionNode', 'OneTimePasswordGeneratorNode', 'OneTimePasswordSmsSenderNode', 'OneTimePasswordSmtpSenderNode', 'PageNode', 'PasswordCollectorNode', 'PatchObjectNode', 'PersistentCookieDecisionNode', 'PollingWaitNode', 'ProfileCompletenessDecisionNode', 'ProvisionDynamicAccountNode', 'ProvisionIdmAccountNode', 'PushAuthenticationSenderNode', 'PushResultVerifierNode', 'QueryFilterDecisionNode', 'RecoveryCodeCollectorDecisionNode', 'RecoveryCodeDisplayNode', 'RegisterLogoutWebhookNode', 'RemoveSessionPropertiesNode', 'RequiredAttributesDecisionNode', 'RetryLimitDecisionNode', 'ScriptedDecisionNode', 'SelectIdPNode', 'SessionDataNode', 'SetFailureUrlNode', 'SetPersistentCookieNode', 'SetSessionPropertiesNode', 'SetSuccessUrlNode', 'SocialFacebookNode', 'SocialGoogleNode', 'SocialNode', 'SocialOAuthIgnoreProfileNode', 'SocialOpenIdConnectNode', 'SocialProviderHandlerNode', 'TermsAndConditionsDecisionNode', 'TimeSinceDecisionNode', 'TimerStartNode', 'TimerStopNode', 'UsernameCollectorNode', 'ValidatedPasswordNode', 'ValidatedUsernameNode', 'WebAuthnAuthenticationNode', 'WebAuthnDeviceStorageNode', 'WebAuthnRegistrationNode', 'ZeroPageLoginNode', 'product-CertificateCollectorNode', 'product-CertificateUserExtractorNode', 'product-CertificateValidationNode', 'product-KerberosNode', 'product-ReCaptchaNode', 'product-Saml2Node', 'product-WriteFederationInformationNode'];
|
|
1301
|
-
const OOTB_NODE_TYPES_7_1 = ['PushRegistrationNode', 'GetAuthenticatorAppNode', 'MultiFactorRegistrationOptionsNode', 'OptOutMultiFactorAuthenticationNode'].concat(OOTB_NODE_TYPES_7);
|
|
1302
|
-
const OOTB_NODE_TYPES_7_2 = ['OathRegistrationNode', 'OathTokenVerifierNode', 'PassthroughAuthenticationNode', 'ConfigProviderNode', 'DebugNode'].concat(OOTB_NODE_TYPES_7_1);
|
|
1303
|
-
const OOTB_NODE_TYPES_6_5 = ['AbstractSocialAuthLoginNode', 'AccountLockoutNode', 'AgentDataStoreDecisionNode', 'AnonymousUserNode', 'AuthLevelDecisionNode', 'ChoiceCollectorNode', 'CookiePresenceDecisionNode', 'CreatePasswordNode', 'DataStoreDecisionNode', 'InnerTreeEvaluatorNode', 'LdapDecisionNode', 'MessageNode', 'MetadataNode', 'MeterNode', 'ModifyAuthLevelNode', 'OneTimePasswordCollectorDecisionNode', 'OneTimePasswordGeneratorNode', 'OneTimePasswordSmsSenderNode', 'OneTimePasswordSmtpSenderNode', 'PageNode', 'PasswordCollectorNode', 'PersistentCookieDecisionNode', 'PollingWaitNode', 'ProvisionDynamicAccountNode', 'ProvisionIdmAccountNode', 'PushAuthenticationSenderNode', 'PushResultVerifierNode', 'RecoveryCodeCollectorDecisionNode', 'RecoveryCodeDisplayNode', 'RegisterLogoutWebhookNode', 'RemoveSessionPropertiesNode', 'RetryLimitDecisionNode', 'ScriptedDecisionNode', 'SessionDataNode', 'SetFailureUrlNode', 'SetPersistentCookieNode', 'SetSessionPropertiesNode', 'SetSuccessUrlNode', 'SocialFacebookNode', 'SocialGoogleNode', 'SocialNode', 'SocialOAuthIgnoreProfileNode', 'SocialOpenIdConnectNode', 'TimerStartNode', 'TimerStopNode', 'UsernameCollectorNode', 'WebAuthnAuthenticationNode', 'WebAuthnRegistrationNode', 'ZeroPageLoginNode'];
|
|
1304
|
-
const OOTB_NODE_TYPES_6 = ['AbstractSocialAuthLoginNode', 'AccountLockoutNode', 'AgentDataStoreDecisionNode', 'AnonymousUserNode', 'AuthLevelDecisionNode', 'ChoiceCollectorNode', 'CookiePresenceDecisionNode', 'CreatePasswordNode', 'DataStoreDecisionNode', 'InnerTreeEvaluatorNode', 'LdapDecisionNode', 'MessageNode', 'MetadataNode', 'MeterNode', 'ModifyAuthLevelNode', 'OneTimePasswordCollectorDecisionNode', 'OneTimePasswordGeneratorNode', 'OneTimePasswordSmsSenderNode', 'OneTimePasswordSmtpSenderNode', 'PageNode', 'PasswordCollectorNode', 'PersistentCookieDecisionNode', 'PollingWaitNode', 'ProvisionDynamicAccountNode', 'ProvisionIdmAccountNode', 'PushAuthenticationSenderNode', 'PushResultVerifierNode', 'RecoveryCodeCollectorDecisionNode', 'RecoveryCodeDisplayNode', 'RegisterLogoutWebhookNode', 'RemoveSessionPropertiesNode', 'RetryLimitDecisionNode', 'ScriptedDecisionNode', 'SessionDataNode', 'SetFailureUrlNode', 'SetPersistentCookieNode', 'SetSessionPropertiesNode', 'SetSuccessUrlNode', 'SocialFacebookNode', 'SocialGoogleNode', 'SocialNode', 'SocialOAuthIgnoreProfileNode', 'SocialOpenIdConnectNode', 'TimerStartNode', 'TimerStopNode', 'UsernameCollectorNode', 'WebAuthnAuthenticationNode', 'WebAuthnRegistrationNode', 'ZeroPageLoginNode'];
|
|
1305
1323
|
/**
|
|
1306
1324
|
* Analyze if a journey contains any custom nodes considering the detected or the overridden version.
|
|
1307
|
-
* @param {
|
|
1325
|
+
* @param {SingleJourneyExportTemplate} journey Journey/tree configuration object
|
|
1308
1326
|
* @returns {boolean} True if the journey/tree contains any custom nodes, false otherwise.
|
|
1309
1327
|
*/
|
|
1310
1328
|
|
|
1311
|
-
export
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
case '7.1.0':
|
|
1317
|
-
ootbNodeTypes = OOTB_NODE_TYPES_7_1.slice(0);
|
|
1318
|
-
break;
|
|
1319
|
-
|
|
1320
|
-
case '7.2.0':
|
|
1321
|
-
ootbNodeTypes = OOTB_NODE_TYPES_7_2.slice(0);
|
|
1322
|
-
break;
|
|
1323
|
-
|
|
1324
|
-
case '7.0.0':
|
|
1325
|
-
case '7.0.1':
|
|
1326
|
-
case '7.0.2':
|
|
1327
|
-
ootbNodeTypes = OOTB_NODE_TYPES_7.slice(0);
|
|
1328
|
-
break;
|
|
1329
|
-
|
|
1330
|
-
case '6.5.3':
|
|
1331
|
-
case '6.5.2.3':
|
|
1332
|
-
case '6.5.2.2':
|
|
1333
|
-
case '6.5.2.1':
|
|
1334
|
-
case '6.5.2':
|
|
1335
|
-
case '6.5.1':
|
|
1336
|
-
case '6.5.0.2':
|
|
1337
|
-
case '6.5.0.1':
|
|
1338
|
-
ootbNodeTypes = OOTB_NODE_TYPES_6_5.slice(0);
|
|
1339
|
-
break;
|
|
1340
|
-
|
|
1341
|
-
case '6.0.0.7':
|
|
1342
|
-
case '6.0.0.6':
|
|
1343
|
-
case '6.0.0.5':
|
|
1344
|
-
case '6.0.0.4':
|
|
1345
|
-
case '6.0.0.3':
|
|
1346
|
-
case '6.0.0.2':
|
|
1347
|
-
case '6.0.0.1':
|
|
1348
|
-
case '6.0.0':
|
|
1349
|
-
ootbNodeTypes = OOTB_NODE_TYPES_6.slice(0);
|
|
1350
|
-
break;
|
|
1351
|
-
|
|
1352
|
-
default:
|
|
1329
|
+
export function isCustomJourney(journey) {
|
|
1330
|
+
const nodeList = Object.values(journey.nodes).concat(Object.values(journey.innerNodes));
|
|
1331
|
+
|
|
1332
|
+
for (const node of nodeList) {
|
|
1333
|
+
if (isCustomNode(node['_type']['_id'])) {
|
|
1353
1334
|
return true;
|
|
1335
|
+
}
|
|
1354
1336
|
}
|
|
1355
1337
|
|
|
1356
|
-
|
|
1338
|
+
return false;
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Analyze if a journey contains any premium nodes considering the detected or the overridden version.
|
|
1342
|
+
* @param {SingleJourneyExportTemplate} journey Journey/tree configuration object
|
|
1343
|
+
* @returns {boolean} True if the journey/tree contains any custom nodes, false otherwise.
|
|
1344
|
+
*/
|
|
1357
1345
|
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
if (!ootbNodeTypes.includes(nodeList[node].nodeType)) {
|
|
1361
|
-
return true;
|
|
1362
|
-
}
|
|
1346
|
+
export function isPremiumJourney(journey) {
|
|
1347
|
+
const nodeList = Object.values(journey.nodes).concat(Object.values(journey.innerNodes));
|
|
1363
1348
|
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1349
|
+
for (const node of nodeList) {
|
|
1350
|
+
if (isPremiumNode(node['_type']['_id'])) {
|
|
1351
|
+
return true;
|
|
1367
1352
|
}
|
|
1368
1353
|
}
|
|
1369
1354
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1355
|
+
return false;
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Analyze if a journey contains any cloud-only nodes considering the detected or the overridden version.
|
|
1359
|
+
* @param {SingleJourneyExportTemplate} journey Journey/tree configuration object
|
|
1360
|
+
* @returns {boolean} True if the journey/tree contains any cloud-only nodes, false otherwise.
|
|
1361
|
+
*/
|
|
1372
1362
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
}
|
|
1380
|
-
} else {
|
|
1381
|
-
printMessage(`isCustom ERROR: can't get ${nodeList[pageNode].nodeType} with id ${pageNode} in ${journey._id}`, 'error');
|
|
1382
|
-
custom = false;
|
|
1363
|
+
export function isCloudOnlyJourney(journey) {
|
|
1364
|
+
const nodeList = Object.values(journey.nodes).concat(Object.values(journey.innerNodes));
|
|
1365
|
+
|
|
1366
|
+
for (const node of nodeList) {
|
|
1367
|
+
if (isCloudOnlyNode(node['_type']['_id'])) {
|
|
1368
|
+
return true;
|
|
1383
1369
|
}
|
|
1384
1370
|
}
|
|
1385
1371
|
|
|
1386
|
-
return
|
|
1372
|
+
return false;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* Get a journey's classifications, which can be one or multiple of:
|
|
1376
|
+
* - standard: can run on any instance of a ForgeRock platform
|
|
1377
|
+
* - cloud: utilize nodes, which are exclusively available in the ForgeRock Identity Cloud
|
|
1378
|
+
* - premium: utilizes nodes, which come at a premium
|
|
1379
|
+
* @param {SingleJourneyExportTemplate} journey journey export data
|
|
1380
|
+
* @returns {string[]} an array of one or multiple classifications
|
|
1381
|
+
*/
|
|
1382
|
+
|
|
1383
|
+
export function getJourneyClassification(journey) {
|
|
1384
|
+
const classifications = [];
|
|
1385
|
+
const premium = isPremiumJourney(journey);
|
|
1386
|
+
const custom = isCustomJourney(journey);
|
|
1387
|
+
const cloud = isCloudOnlyJourney(journey);
|
|
1388
|
+
|
|
1389
|
+
if (custom) {
|
|
1390
|
+
classifications.push('custom');
|
|
1391
|
+
} else if (cloud) {
|
|
1392
|
+
classifications.push('cloud');
|
|
1393
|
+
} else {
|
|
1394
|
+
classifications.push('standard');
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
if (premium) classifications.push('premium');
|
|
1398
|
+
return classifications;
|
|
1387
1399
|
}
|
|
1388
1400
|
/**
|
|
1389
1401
|
* List all the journeys/trees
|
|
@@ -1394,39 +1406,47 @@ export async function isCustom(journey) {
|
|
|
1394
1406
|
|
|
1395
1407
|
export async function listJourneys(long = false, analyze = false) {
|
|
1396
1408
|
let journeys = [];
|
|
1409
|
+
journeys = await getJourneys();
|
|
1397
1410
|
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1411
|
+
if (!long && !analyze) {
|
|
1412
|
+
for (const journeyStub of journeys) {
|
|
1413
|
+
printMessage(`${journeyStub['_id']}`, 'data');
|
|
1414
|
+
}
|
|
1415
|
+
} else {
|
|
1416
|
+
if (!analyze) {
|
|
1417
|
+
const table = createTable(['Name', 'Status', 'Tags']);
|
|
1404
1418
|
|
|
1405
|
-
|
|
1406
|
-
|
|
1419
|
+
for (const journeyStub of journeys) {
|
|
1420
|
+
var _journeyStub$uiConfig;
|
|
1407
1421
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1422
|
+
table.push([`${journeyStub._id}`, journeyStub.enabled === false ? 'disabled'['brightRed'] : 'enabled'['brightGreen'], (_journeyStub$uiConfig = journeyStub.uiConfig) !== null && _journeyStub$uiConfig !== void 0 && _journeyStub$uiConfig.categories ? wordwrap(JSON.parse(journeyStub.uiConfig.categories).join(', '), 60) : '']);
|
|
1423
|
+
}
|
|
1410
1424
|
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1425
|
+
printMessage(table.toString(), 'data');
|
|
1426
|
+
} else {
|
|
1427
|
+
createProgressIndicator(0, 'Retrieving details of all journeys...', 'indeterminate');
|
|
1428
|
+
const exportPromises = [];
|
|
1429
|
+
|
|
1430
|
+
for (const journeyStub of journeys) {
|
|
1431
|
+
exportPromises.push(exportJourney(journeyStub['_id'], {
|
|
1432
|
+
useStringArrays: false,
|
|
1433
|
+
deps: false,
|
|
1434
|
+
verbose: false
|
|
1435
|
+
}));
|
|
1436
|
+
}
|
|
1414
1437
|
|
|
1415
|
-
|
|
1416
|
-
|
|
1438
|
+
const journeyExports = await Promise.all(exportPromises);
|
|
1439
|
+
stopProgressIndicator('Retrieved details of all journeys.', 'success');
|
|
1440
|
+
const table = createTable(['Name', 'Status', 'Classification', 'Tags']);
|
|
1417
1441
|
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
printMessage(`${customTrees[i] ? '*' : ''}${journey._id}`, 'data');
|
|
1421
|
-
}
|
|
1422
|
-
} else {
|
|
1423
|
-
const table = createTable(['Name'['brightCyan'], 'Status'['brightCyan'], 'Tags'['brightCyan']]);
|
|
1442
|
+
for (const journeyExport of journeyExports) {
|
|
1443
|
+
var _journeyExport$tree$u;
|
|
1424
1444
|
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
}
|
|
1445
|
+
table.push([`${journeyExport.tree._id}`, journeyExport.tree.enabled === false ? 'disabled'['brightRed'] : 'enabled'['brightGreen'], getJourneyClassification(journeyExport).join(', '), (_journeyExport$tree$u = journeyExport.tree.uiConfig) !== null && _journeyExport$tree$u !== void 0 && _journeyExport$tree$u.categories ? wordwrap(JSON.parse(journeyExport.tree.uiConfig.categories).join(', '), 60) : '']);
|
|
1446
|
+
}
|
|
1428
1447
|
|
|
1429
|
-
|
|
1448
|
+
printMessage(table.toString(), 'data');
|
|
1449
|
+
}
|
|
1430
1450
|
}
|
|
1431
1451
|
|
|
1432
1452
|
return journeys;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import storage from '../storage/SessionStorage';
|
|
3
|
+
import { getNode, deleteNode, getNodeTypes, getNodesByType } from '../api/NodeApi';
|
|
4
|
+
import { getTrees } from '../api/TreeApi';
|
|
5
|
+
import { printMessage, createProgressIndicator, updateProgressIndicator, stopProgressIndicator } from './utils/Console';
|
|
6
|
+
import { getProviderByLocationAndId, getProviderMetadata } from '../api/Saml2Api';
|
|
7
|
+
import { encodeBase64Url } from '../api/utils/Base64';
|
|
8
|
+
const containerNodes = ['PageNode', 'CustomPageNode'];
|
|
9
|
+
const scriptedNodes = ['ConfigProviderNode', 'ScriptedDecisionNode', 'ClientScriptNode', 'SocialProviderHandlerNode', 'CustomScriptNode'];
|
|
10
|
+
const emailTemplateNodes = ['EmailSuspendNode', 'EmailTemplateNode'];
|
|
11
|
+
const emptyScriptPlaceholder = '[Empty]';
|
|
12
|
+
/**
|
|
13
|
+
* Helper to get all SAML2 dependencies for a given node object
|
|
14
|
+
* @param {Object} nodeObject node object
|
|
15
|
+
* @param {[Object]} allProviders array of all saml2 providers objects
|
|
16
|
+
* @param {[Object]} allCirclesOfTrust array of all circle of trust objects
|
|
17
|
+
* @returns {Promise} a promise that resolves to an object containing a saml2 dependencies
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
async function getSaml2NodeDependencies(nodeObject, allProviders, allCirclesOfTrust) {
|
|
21
|
+
const samlProperties = ['metaAlias', 'idpEntityId'];
|
|
22
|
+
const saml2EntityPromises = [];
|
|
23
|
+
|
|
24
|
+
for (const samlProperty of samlProperties) {
|
|
25
|
+
// In the following line nodeObject[samlProperty] will look like '/alpha/iSPAzure'.
|
|
26
|
+
const entityId = samlProperty === 'metaAlias' ? _.last(nodeObject[samlProperty].split('/')) : nodeObject[samlProperty];
|
|
27
|
+
|
|
28
|
+
const entity = _.find(allProviders, {
|
|
29
|
+
entityId
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (entity) {
|
|
33
|
+
try {
|
|
34
|
+
const providerResponse = await getProviderByLocationAndId(entity.location, entity._id);
|
|
35
|
+
/**
|
|
36
|
+
* Adding entityLocation here to the entityResponse because the import tool
|
|
37
|
+
* needs to know whether the saml2 entity is remote or not (this will be removed
|
|
38
|
+
* from the config before importing see updateSaml2Entity and createSaml2Entity functions).
|
|
39
|
+
* Importing a remote saml2 entity is a slightly different request (see createSaml2Entity).
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
providerResponse.entityLocation = entity.location;
|
|
43
|
+
|
|
44
|
+
if (entity.location === 'remote') {
|
|
45
|
+
// get the xml representation of this entity and add it to the entityResponse;
|
|
46
|
+
const metaDataResponse = await getProviderMetadata(providerResponse.entityId);
|
|
47
|
+
providerResponse.base64EntityXML = encodeBase64Url(metaDataResponse);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
saml2EntityPromises.push(providerResponse);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
printMessage(error.message, 'error');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const saml2EntitiesPromisesResults = await Promise.all(saml2EntityPromises);
|
|
59
|
+
const saml2Entities = [];
|
|
60
|
+
|
|
61
|
+
for (const saml2Entity of saml2EntitiesPromisesResults) {
|
|
62
|
+
if (saml2Entity) {
|
|
63
|
+
saml2Entities.push(saml2Entity);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const samlEntityIds = _.map(saml2Entities, saml2EntityConfig => `${saml2EntityConfig.entityId}|saml2`);
|
|
68
|
+
|
|
69
|
+
const circlesOfTrust = _.filter(allCirclesOfTrust, circleOfTrust => {
|
|
70
|
+
let hasEntityId = false;
|
|
71
|
+
|
|
72
|
+
for (const trustedProvider of circleOfTrust.trustedProviders) {
|
|
73
|
+
if (!hasEntityId && samlEntityIds.includes(trustedProvider)) {
|
|
74
|
+
hasEntityId = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return hasEntityId;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const saml2NodeDependencies = {
|
|
82
|
+
saml2Entities,
|
|
83
|
+
circlesOfTrust
|
|
84
|
+
};
|
|
85
|
+
return saml2NodeDependencies;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
printMessage(error.message, 'error');
|
|
88
|
+
const saml2NodeDependencies = {
|
|
89
|
+
saml2Entities: [],
|
|
90
|
+
circlesOfTrust: []
|
|
91
|
+
};
|
|
92
|
+
return saml2NodeDependencies;
|
|
93
|
+
}
|
|
94
|
+
} // export async function getTreeNodes(treeObject) {
|
|
95
|
+
// const nodeList = Object.entries(treeObject.nodes);
|
|
96
|
+
// const results = await Promise.allSettled(
|
|
97
|
+
// nodeList.map(
|
|
98
|
+
// async ([nodeId, nodeInfo]) => await getNode(nodeId, nodeInfo['nodeType'])
|
|
99
|
+
// )
|
|
100
|
+
// );
|
|
101
|
+
// const nodes = results.filter((r) => r.status === 'fulfilled');
|
|
102
|
+
// nodes.map((f) => {
|
|
103
|
+
// return f.status;
|
|
104
|
+
// });
|
|
105
|
+
// const failedList = results.filter((r) => r.status === 'rejected');
|
|
106
|
+
// return nodes;
|
|
107
|
+
// }
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Find all node configuration objects that are no longer referenced by any tree
|
|
111
|
+
* @returns {Promise<unknown[]>} a promise that resolves to an array of orphaned nodes
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
export async function findOrphanedNodes() {
|
|
116
|
+
const allNodes = [];
|
|
117
|
+
const orphanedNodes = [];
|
|
118
|
+
let types = [];
|
|
119
|
+
const allJourneys = (await getTrees()).result;
|
|
120
|
+
let errorMessage = '';
|
|
121
|
+
const errorTypes = [];
|
|
122
|
+
createProgressIndicator(undefined, `Counting total nodes...`, 'indeterminate');
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
types = (await getNodeTypes()).result;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
printMessage('Error retrieving all available node types:', 'error');
|
|
128
|
+
printMessage(error.response.data, 'error');
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
for (const type of types) {
|
|
133
|
+
try {
|
|
134
|
+
// eslint-disable-next-line no-await-in-loop, no-loop-func
|
|
135
|
+
const nodes = (await getNodesByType(type._id)).result;
|
|
136
|
+
|
|
137
|
+
for (const node of nodes) {
|
|
138
|
+
allNodes.push(node);
|
|
139
|
+
updateProgressIndicator(`${allNodes.length} total nodes${errorMessage}`);
|
|
140
|
+
}
|
|
141
|
+
} catch (error) {
|
|
142
|
+
errorTypes.push(type._id);
|
|
143
|
+
errorMessage = ` (Skipped type(s): ${errorTypes})`['yellow'];
|
|
144
|
+
updateProgressIndicator(`${allNodes.length} total nodes${errorMessage}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (errorTypes.length > 0) {
|
|
149
|
+
stopProgressIndicator(`${allNodes.length} total nodes${errorMessage}`, 'warn');
|
|
150
|
+
} else {
|
|
151
|
+
stopProgressIndicator(`${allNodes.length} total nodes`, 'success');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
createProgressIndicator(undefined, 'Counting active nodes...', 'indeterminate');
|
|
155
|
+
const activeNodes = [];
|
|
156
|
+
|
|
157
|
+
for (const journey of allJourneys) {
|
|
158
|
+
for (const nodeId in journey.nodes) {
|
|
159
|
+
if ({}.hasOwnProperty.call(journey.nodes, nodeId)) {
|
|
160
|
+
activeNodes.push(nodeId);
|
|
161
|
+
updateProgressIndicator(`${activeNodes.length} active nodes`);
|
|
162
|
+
const node = journey.nodes[nodeId];
|
|
163
|
+
|
|
164
|
+
if (containerNodes.includes(node.nodeType)) {
|
|
165
|
+
const containerNode = await getNode(nodeId, node.nodeType);
|
|
166
|
+
|
|
167
|
+
for (const innerNode of containerNode.nodes) {
|
|
168
|
+
activeNodes.push(innerNode._id);
|
|
169
|
+
updateProgressIndicator(`${activeNodes.length} active nodes`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
stopProgressIndicator(`${activeNodes.length} active nodes`, 'success');
|
|
177
|
+
createProgressIndicator(undefined, 'Calculating orphaned nodes...', 'indeterminate');
|
|
178
|
+
const diff = allNodes.filter(x => !activeNodes.includes(x._id));
|
|
179
|
+
|
|
180
|
+
for (const orphanedNode of diff) {
|
|
181
|
+
orphanedNodes.push(orphanedNode);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
stopProgressIndicator(`${orphanedNodes.length} orphaned nodes`, 'success');
|
|
185
|
+
return orphanedNodes;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Remove orphaned nodes
|
|
189
|
+
* @param {[Object]} orphanedNodes Pass in an array of orphaned node configuration objects to remove
|
|
190
|
+
* @returns {Promise<unknown[]>} a promise that resolves to an array nodes that encountered errors deleting
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
export async function removeOrphanedNodes(orphanedNodes) {
|
|
194
|
+
const errorNodes = [];
|
|
195
|
+
createProgressIndicator(orphanedNodes.length, 'Removing orphaned nodes...');
|
|
196
|
+
|
|
197
|
+
for (const node of orphanedNodes) {
|
|
198
|
+
updateProgressIndicator(`Removing ${node['_id']}...`);
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
// eslint-disable-next-line no-await-in-loop
|
|
202
|
+
await deleteNode(node['_id'], node['_type']['_id']);
|
|
203
|
+
} catch (deleteError) {
|
|
204
|
+
errorNodes.push(node);
|
|
205
|
+
printMessage(` ${deleteError}`, 'error');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
stopProgressIndicator(`Removed ${orphanedNodes.length} orphaned nodes.`);
|
|
210
|
+
return errorNodes;
|
|
211
|
+
}
|
|
212
|
+
const OOTB_NODE_TYPES_7 = ['AcceptTermsAndConditionsNode', 'AccountActiveDecisionNode', 'AccountLockoutNode', 'AgentDataStoreDecisionNode', 'AnonymousSessionUpgradeNode', 'AnonymousUserNode', 'AttributeCollectorNode', 'AttributePresentDecisionNode', 'AttributeValueDecisionNode', 'AuthLevelDecisionNode', 'ChoiceCollectorNode', 'ConsentNode', 'CookiePresenceDecisionNode', 'CreateObjectNode', 'CreatePasswordNode', 'DataStoreDecisionNode', 'DeviceGeoFencingNode', 'DeviceLocationMatchNode', 'DeviceMatchNode', 'DeviceProfileCollectorNode', 'DeviceSaveNode', 'DeviceTamperingVerificationNode', 'DisplayUserNameNode', 'EmailSuspendNode', 'EmailTemplateNode', 'IdentifyExistingUserNode', 'IncrementLoginCountNode', 'InnerTreeEvaluatorNode', 'IotAuthenticationNode', 'IotRegistrationNode', 'KbaCreateNode', 'KbaDecisionNode', 'KbaVerifyNode', 'LdapDecisionNode', 'LoginCountDecisionNode', 'MessageNode', 'MetadataNode', 'MeterNode', 'ModifyAuthLevelNode', 'OneTimePasswordCollectorDecisionNode', 'OneTimePasswordGeneratorNode', 'OneTimePasswordSmsSenderNode', 'OneTimePasswordSmtpSenderNode', 'PageNode', 'PasswordCollectorNode', 'PatchObjectNode', 'PersistentCookieDecisionNode', 'PollingWaitNode', 'ProfileCompletenessDecisionNode', 'ProvisionDynamicAccountNode', 'ProvisionIdmAccountNode', 'PushAuthenticationSenderNode', 'PushResultVerifierNode', 'QueryFilterDecisionNode', 'RecoveryCodeCollectorDecisionNode', 'RecoveryCodeDisplayNode', 'RegisterLogoutWebhookNode', 'RemoveSessionPropertiesNode', 'RequiredAttributesDecisionNode', 'RetryLimitDecisionNode', 'ScriptedDecisionNode', 'SelectIdPNode', 'SessionDataNode', 'SetFailureUrlNode', 'SetPersistentCookieNode', 'SetSessionPropertiesNode', 'SetSuccessUrlNode', 'SocialFacebookNode', 'SocialGoogleNode', 'SocialNode', 'SocialOAuthIgnoreProfileNode', 'SocialOpenIdConnectNode', 'SocialProviderHandlerNode', 'TermsAndConditionsDecisionNode', 'TimeSinceDecisionNode', 'TimerStartNode', 'TimerStopNode', 'UsernameCollectorNode', 'ValidatedPasswordNode', 'ValidatedUsernameNode', 'WebAuthnAuthenticationNode', 'WebAuthnDeviceStorageNode', 'WebAuthnRegistrationNode', 'ZeroPageLoginNode', 'product-CertificateCollectorNode', 'product-CertificateUserExtractorNode', 'product-CertificateValidationNode', 'product-KerberosNode', 'product-ReCaptchaNode', 'product-Saml2Node', 'product-WriteFederationInformationNode'];
|
|
213
|
+
const OOTB_NODE_TYPES_7_1 = ['PushRegistrationNode', 'GetAuthenticatorAppNode', 'MultiFactorRegistrationOptionsNode', 'OptOutMultiFactorAuthenticationNode'].concat(OOTB_NODE_TYPES_7);
|
|
214
|
+
const OOTB_NODE_TYPES_7_2 = ['OathRegistrationNode', 'OathTokenVerifierNode', 'PassthroughAuthenticationNode', 'ConfigProviderNode', 'DebugNode'].concat(OOTB_NODE_TYPES_7_1);
|
|
215
|
+
const OOTB_NODE_TYPES_7_3 = [].concat(OOTB_NODE_TYPES_7_2);
|
|
216
|
+
const OOTB_NODE_TYPES_6_5 = ['AbstractSocialAuthLoginNode', 'AccountLockoutNode', 'AgentDataStoreDecisionNode', 'AnonymousUserNode', 'AuthLevelDecisionNode', 'ChoiceCollectorNode', 'CookiePresenceDecisionNode', 'CreatePasswordNode', 'DataStoreDecisionNode', 'InnerTreeEvaluatorNode', 'LdapDecisionNode', 'MessageNode', 'MetadataNode', 'MeterNode', 'ModifyAuthLevelNode', 'OneTimePasswordCollectorDecisionNode', 'OneTimePasswordGeneratorNode', 'OneTimePasswordSmsSenderNode', 'OneTimePasswordSmtpSenderNode', 'PageNode', 'PasswordCollectorNode', 'PersistentCookieDecisionNode', 'PollingWaitNode', 'ProvisionDynamicAccountNode', 'ProvisionIdmAccountNode', 'PushAuthenticationSenderNode', 'PushResultVerifierNode', 'RecoveryCodeCollectorDecisionNode', 'RecoveryCodeDisplayNode', 'RegisterLogoutWebhookNode', 'RemoveSessionPropertiesNode', 'RetryLimitDecisionNode', 'ScriptedDecisionNode', 'SessionDataNode', 'SetFailureUrlNode', 'SetPersistentCookieNode', 'SetSessionPropertiesNode', 'SetSuccessUrlNode', 'SocialFacebookNode', 'SocialGoogleNode', 'SocialNode', 'SocialOAuthIgnoreProfileNode', 'SocialOpenIdConnectNode', 'TimerStartNode', 'TimerStopNode', 'UsernameCollectorNode', 'WebAuthnAuthenticationNode', 'WebAuthnRegistrationNode', 'ZeroPageLoginNode'];
|
|
217
|
+
const OOTB_NODE_TYPES_6 = ['AbstractSocialAuthLoginNode', 'AccountLockoutNode', 'AgentDataStoreDecisionNode', 'AnonymousUserNode', 'AuthLevelDecisionNode', 'ChoiceCollectorNode', 'CookiePresenceDecisionNode', 'CreatePasswordNode', 'DataStoreDecisionNode', 'InnerTreeEvaluatorNode', 'LdapDecisionNode', 'MessageNode', 'MetadataNode', 'MeterNode', 'ModifyAuthLevelNode', 'OneTimePasswordCollectorDecisionNode', 'OneTimePasswordGeneratorNode', 'OneTimePasswordSmsSenderNode', 'OneTimePasswordSmtpSenderNode', 'PageNode', 'PasswordCollectorNode', 'PersistentCookieDecisionNode', 'PollingWaitNode', 'ProvisionDynamicAccountNode', 'ProvisionIdmAccountNode', 'PushAuthenticationSenderNode', 'PushResultVerifierNode', 'RecoveryCodeCollectorDecisionNode', 'RecoveryCodeDisplayNode', 'RegisterLogoutWebhookNode', 'RemoveSessionPropertiesNode', 'RetryLimitDecisionNode', 'ScriptedDecisionNode', 'SessionDataNode', 'SetFailureUrlNode', 'SetPersistentCookieNode', 'SetSessionPropertiesNode', 'SetSuccessUrlNode', 'SocialFacebookNode', 'SocialGoogleNode', 'SocialNode', 'SocialOAuthIgnoreProfileNode', 'SocialOpenIdConnectNode', 'TimerStartNode', 'TimerStopNode', 'UsernameCollectorNode', 'WebAuthnAuthenticationNode', 'WebAuthnRegistrationNode', 'ZeroPageLoginNode'];
|
|
218
|
+
const CLOUD_ONLY_NODE_TYPES = ['IdentityStoreDecisionNode'];
|
|
219
|
+
const PREMIUM_NODE_TYPES = ['AutonomousAccessSignalNode', 'AutonomousAccessDecisionNode', 'AutonomousAccessResultNode'];
|
|
220
|
+
/**
|
|
221
|
+
* Analyze if a node is a premium node.
|
|
222
|
+
* @param {string} nodeType Node type
|
|
223
|
+
* @returns {boolean} True if the node type is premium, false otherwise.
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
export function isPremiumNode(nodeType) {
|
|
227
|
+
return PREMIUM_NODE_TYPES.includes(nodeType);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Analyze if a node is a cloud-only node.
|
|
231
|
+
* @param {string} nodeType Node type
|
|
232
|
+
* @returns {boolean} True if the node type is cloud-only, false otherwise.
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
export function isCloudOnlyNode(nodeType) {
|
|
236
|
+
return CLOUD_ONLY_NODE_TYPES.includes(nodeType);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Analyze if a node is custom.
|
|
240
|
+
* @param {string} nodeType Node type
|
|
241
|
+
* @returns {boolean} True if the node type is custom, false otherwise.
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
export function isCustomNode(nodeType) {
|
|
245
|
+
let ootbNodeTypes = [];
|
|
246
|
+
|
|
247
|
+
switch (storage.session.getAmVersion()) {
|
|
248
|
+
case '7.1.0':
|
|
249
|
+
ootbNodeTypes = OOTB_NODE_TYPES_7_1.slice(0);
|
|
250
|
+
break;
|
|
251
|
+
|
|
252
|
+
case '7.2.0':
|
|
253
|
+
ootbNodeTypes = OOTB_NODE_TYPES_7_2.slice(0);
|
|
254
|
+
break;
|
|
255
|
+
|
|
256
|
+
case '7.3.0':
|
|
257
|
+
ootbNodeTypes = OOTB_NODE_TYPES_7_3.slice(0);
|
|
258
|
+
break;
|
|
259
|
+
|
|
260
|
+
case '7.0.0':
|
|
261
|
+
case '7.0.1':
|
|
262
|
+
case '7.0.2':
|
|
263
|
+
ootbNodeTypes = OOTB_NODE_TYPES_7.slice(0);
|
|
264
|
+
break;
|
|
265
|
+
|
|
266
|
+
case '6.5.3':
|
|
267
|
+
case '6.5.2.3':
|
|
268
|
+
case '6.5.2.2':
|
|
269
|
+
case '6.5.2.1':
|
|
270
|
+
case '6.5.2':
|
|
271
|
+
case '6.5.1':
|
|
272
|
+
case '6.5.0.2':
|
|
273
|
+
case '6.5.0.1':
|
|
274
|
+
ootbNodeTypes = OOTB_NODE_TYPES_6_5.slice(0);
|
|
275
|
+
break;
|
|
276
|
+
|
|
277
|
+
case '6.0.0.7':
|
|
278
|
+
case '6.0.0.6':
|
|
279
|
+
case '6.0.0.5':
|
|
280
|
+
case '6.0.0.4':
|
|
281
|
+
case '6.0.0.3':
|
|
282
|
+
case '6.0.0.2':
|
|
283
|
+
case '6.0.0.1':
|
|
284
|
+
case '6.0.0':
|
|
285
|
+
ootbNodeTypes = OOTB_NODE_TYPES_6.slice(0);
|
|
286
|
+
break;
|
|
287
|
+
|
|
288
|
+
default:
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return !ootbNodeTypes.includes(nodeType) && !isPremiumNode(nodeType) && !isCloudOnlyNode(nodeType);
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=NodeOps.js.map
|