From fb408bb0bd9192e7bfe05cc949696fd242a66e25 Mon Sep 17 00:00:00 2001 From: Preston Hales Date: Thu, 18 Dec 2025 12:05:17 -0700 Subject: [PATCH] Add library API and Ops functions for doing custom node exports, imports, deletes, etc. --- package-lock.json | 58 +- src/api/NodeApi.test.ts | 394 +- src/api/NodeApi.ts | 184 + src/ops/ConfigOps.ts | 50 +- src/ops/JourneyOps.test.ts | 181 +- src/ops/JourneyOps.ts | 83 +- src/ops/NodeOps.test.ts | 389 +- src/ops/NodeOps.ts | 632 +- .../recording.har | 136 + .../recording.har | 136 + .../recording.har | 136 + .../recording.har | 136 + .../recording.har | 148 + .../recording.har | 148 + .../recording.har | 148 + .../recording.har | 148 + .../recording.har | 2418 +++++ .../recording.har | 2730 ++++++ .../recording.har | 178 + .../recording.har | 178 + .../recording.har | 161 + .../recording.har | 161 + .../recording.har | 166 + .../recording.har | 165 + .../recording.har | 161 + .../recording.har | 162 + .../recording.har | 178 + .../recording.har | 54 +- .../recording.har | 44 +- .../recording.har | 472 + .../recording.har | 334 + .../recording.har | 480 + .../recording.har | 490 + .../recording.har | 325 + .../recording.har | 161 + .../recording.har | 465 + .../recording.har | 165 + .../recording.har | 161 + .../recording.har | 165 + .../recording.har | 161 + .../recording.har | 162 + .../recording.har | 162 + .../recording.har | 166 + .../2-Import-by-ID_3996169380/recording.har | 178 + .../3-Import-by-Name_237557869/recording.har | 334 + .../4-Import-all_2873519115/recording.har | 974 ++ .../recording.har | 165 + .../recording.har | 161 + .../recording.har | 162 + .../recording.har | 162 + .../recording.har | 165 + .../recording.har | 161 + .../recording.har | 489 + .../recording.har | 321 + .../recording.har | 329 + .../recording.har | 329 + src/test/mocks/ForgeRockApiMockEngine.ts | 3 +- .../FrodoTestJourney12.journey.json | 488 + .../FrodoTestJourney3.journey.json | 21 + src/test/setup/JourneySetup.ts | 87 + src/test/setup/NodeSetup.ts | 303 + src/test/snapshots/api/NodeApi.test.js.snap | 1429 ++- src/test/snapshots/ops/ConfigOps.test.js.snap | 8020 +++++++++++++++++ .../snapshots/ops/JourneyOps.test.js.snap | 1024 +++ src/test/snapshots/ops/NodeOps.test.js.snap | 3208 +++++++ src/utils/PollyUtils.ts | 5 +- 66 files changed, 31785 insertions(+), 465 deletions(-) create mode 100644 src/test/mock-recordings/JourneyOps_2291468013/exportJourney_2045999962/4-Export-journey-FrodoTestJourney12-w_3945220971/custom-node-dependencies_2882997917/recording.har create mode 100644 src/test/mock-recordings/JourneyOps_2291468013/importJourney_541402267/3-Import-journey-FrodoTestJourney12-w_2042673225/custom-node-dependencies_2882997917/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/createCustomNode_2029579653/1-Create-custom-node_3964295767/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/createNode_3265123738/1-Create-new-node-5227de7a-02db-4f25-858e-c8d4f0e0b600-SetStateNode_2109339458/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/1-Delete-existing-custom-node-a15e2efb3deb4d4ea338c74a6440b69f-1_577392640/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node-11111111111111111111111111111111-1_3308823964/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/1-Get-existing-custom-node-a605506774a848f7877b4d17a453bd39-1_1914184324/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/2-Get-non-existing-custom-node-11111111111111111111111111111111-1_1204087401/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/getCustomNodes_3622984558/1-Get-all-custom-nodes_3599720857/recording.har create mode 100644 src/test/mock-recordings/NodeApi_1241226927/putCustomNode_1758137090/1-Update-existing-custom-node-aaaa3fb2f5dc42dd9772bedc93898bd8-1_446967736/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/1-Create-new-node-with-id_2113523129/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/2-Create-new-node-without-id_3214205544/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/3-Create-existing-node-by-id_1394702125/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/4-Create-existing-node-without-id_833852283/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/1-Delete-existing-custom-node-by-id_580138965/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node_3331521686/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/3-Delete-existing-custom-node-by-name_491988969/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/1-Delete-existing-node_273846342/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/2-Delete-non-existing-node_1726654525/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/1-Export-existing-custom-node-by-ID_4135699686/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/2-Export-non-existing-custom-node_4081094025/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/3-Export-existing-custom-node-by-name_3299881190/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/exportCustomNodes_1729513026/1-Export-custom-nodes_1354206594/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/2-Import-by-ID_3996169380/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/3-Import-by-Name_237557869/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/4-Import-all_2873519115/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/1-Read-existing-custom-node-by-ID_573989968/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/2-Read-non-existing-custom-node_1881359087/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/3-Read-existing-custom-node-by-name_1309848192/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/readCustomNodes_561531088/1-Read-custom-nodes_2112965120/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/1-Read-existing-node_2978326169/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/2-Read-non-existing-node_2851841034/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/1-Update-existing-custom-node_2742140269/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/2-Update-non-existing-custom-node_3002975744/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/1-Update-existing-node_144302408/recording.har create mode 100644 src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/2-Update-non-existing-node_2780671391/recording.har create mode 100644 src/test/mocks/JourneyOps/importJourney/FrodoTestJourney12.journey.json create mode 100644 src/test/setup/JourneySetup.ts create mode 100644 src/test/setup/NodeSetup.ts diff --git a/package-lock.json b/package-lock.json index 89e93c2fe..25cbfc08a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -97,6 +97,7 @@ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -1353,9 +1354,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -1911,6 +1912,7 @@ "integrity": "sha512-1ZZcmojW8iSFmvHGeLlvuudM3WiDV842FsVvtPAo3HoAYE6jCNveLHJ+X4qvonL4enj1SyTF3hXA107UkQFQrA==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@pollyjs/utils": "^6.0.6", "@sindresorhus/fnv1a": "^2.0.1", @@ -2626,6 +2628,7 @@ "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "7.18.0", @@ -2660,6 +2663,7 @@ "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", @@ -2840,6 +2844,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3171,6 +3176,7 @@ "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -3523,6 +3529,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", @@ -4599,6 +4606,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -4693,6 +4701,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4749,6 +4758,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -6877,6 +6887,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -7585,9 +7596,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -8234,9 +8245,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", + "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", "dev": true, "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { @@ -8928,6 +8939,7 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -9395,15 +9407,15 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", - "minimatch": "^10.0.3", + "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" @@ -9419,11 +9431,11 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/brace-expansion": "^5.0.0" }, @@ -10204,9 +10216,9 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { @@ -10474,6 +10486,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -10871,6 +10884,7 @@ "integrity": "sha512-/z585740YHURLl9DN2jCWe6OW7zKYm6VoQ93H0sxZ1cwHQEQrUn5BJrEnkWhfzUdyO+BLGjnKUZ9iz9hKloFDw==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@gerrit0/mini-shiki": "^1.24.0", "lunr": "^2.3.9", @@ -10904,6 +10918,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11373,6 +11388,7 @@ "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", + "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/src/api/NodeApi.test.ts b/src/api/NodeApi.test.ts index edb7d04d6..6ad1fba70 100644 --- a/src/api/NodeApi.test.ts +++ b/src/api/NodeApi.test.ts @@ -34,248 +34,14 @@ import { state } from '../index'; import { autoSetupPolly } from '../utils/AutoSetupPolly'; import { filterRecording } from '../utils/PollyUtils'; +import * as TestData from '../test/setup/NodeSetup'; + const ctx = autoSetupPolly(); describe('NodeApi', () => { - const node1 = { - type: 'ValidatedUsernameNode', - node: { - _id: '67693475-3a58-4e38-bcc6-037b3fe46a58', - usernameAttribute: 'userName', - validateInput: false, - _type: { - _id: 'ValidatedUsernameNode', - name: 'Platform Username', - collection: true, - }, - _outcomes: [ - { - id: 'outcome', - displayName: 'Outcome', - }, - ], - }, - }; - const node2 = { - id: '18ffdd4b-41b7-41b3-8248-f4fdfd68423f', - type: 'ValidatedPasswordNode', - node: { - validateInput: false, - passwordAttribute: 'password', - _type: { - _id: 'ValidatedPasswordNode', - name: 'Platform Password', - collection: true, - }, - _outcomes: [ - { - id: 'outcome', - displayName: 'Outcome', - }, - ], - }, - }; - const node3 = { - id: 'b726262c-641e-4fa5-b276-98e129b44cd9', - type: 'PatchObjectNode', - node: { - identityResource: 'managed/user', - patchAsObject: false, - ignoredFields: [], - identityAttribute: 'userName', - _type: { - _id: 'PatchObjectNode', - name: 'Patch Object', - collection: true, - }, - _outcomes: [ - { - id: 'PATCHED', - displayName: 'Patched', - }, - { - id: 'FAILURE', - displayName: 'Failed', - }, - ], - }, - }; - const node4 = { - type: 'CreateObjectNode', - node: { - _id: '23bab9d4-1663-450f-8a4b-680f44f54fd6', - identityResource: 'managed/user', - _type: { - _id: 'CreateObjectNode', - name: 'Create Object', - collection: true, - }, - _outcomes: [ - { - id: 'CREATED', - displayName: 'Created', - }, - { - id: 'FAILURE', - displayName: 'Failed', - }, - ], - }, - }; - // in recording mode, setup test data before recording - beforeAll(async () => { - if (process.env.FRODO_POLLY_MODE === 'record') { - // setup node1 - delete if exists, then create - try { - await NodeApi.getNode({ - nodeId: node1.node._id, - nodeType: node1.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node1.node._id, - nodeType: node1.type, - state, - }); - } catch (error) { - // ignore - } finally { - await NodeApi.putNode({ - nodeId: node1.node._id, - nodeType: node1.type, - nodeData: node1.node, - state, - }); - } - // setup node2 - delete if exists - try { - await NodeApi.getNode({ - nodeId: node2.id, - nodeType: node2.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node2.id, - nodeType: node2.type, - state, - }); - } catch (error) { - // ignore - } finally { - await NodeApi.putNode({ - nodeId: node2.id, - nodeType: node2.type, - nodeData: node2.node, - state, - }); - } - // setup node3 - delete if exists, then create - try { - await NodeApi.getNode({ - nodeId: node3.id, - nodeType: node3.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node3.id, - nodeType: node3.type, - state, - }); - } catch (error) { - // ignore - } finally { - await NodeApi.putNode({ - nodeId: node3.id, - nodeType: node3.type, - nodeData: node3.node, - state, - }); - } - // setup node4 - delete if exists, then create - try { - await NodeApi.getNode({ - nodeId: node4.node._id, - nodeType: node4.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node4.node._id, - nodeType: node4.type, - state, - }); - } catch (error) { - // ignore - } finally { - await NodeApi.putNode({ - nodeId: node4.node._id, - nodeType: node4.type, - nodeData: node4.node, - state, - }); - } - } - }); - // in recording mode, remove test data after recording - afterAll(async () => { - if (process.env.FRODO_POLLY_MODE === 'record') { - try { - await NodeApi.getNode({ - nodeId: node1.node._id, - nodeType: node1.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node1.node._id, - nodeType: node1.type, - state, - }); - } catch (error) { - // ignore - } - try { - await NodeApi.getNode({ - nodeId: node2.id, - nodeType: node2.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node2.id, - nodeType: node2.type, - state, - }); - } catch (error) { - // ignore - } - try { - await NodeApi.getNode({ - nodeId: node3.id, - nodeType: node3.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node3.id, - nodeType: node3.type, - state, - }); - } catch (error) { - // ignore - } - try { - await NodeApi.getNode({ - nodeId: node4.node._id, - nodeType: node4.type, - state, - }); - await NodeApi.deleteNode({ - nodeId: node4.node._id, - nodeType: node4.type, - state, - }); - } catch (error) { - // ignore - } - } - }); + + TestData.setup(); + beforeEach(async () => { if (process.env.FRODO_POLLY_MODE === 'record') { ctx.polly.server.any().on('beforePersist', (_req, recording) => { @@ -325,10 +91,10 @@ describe('NodeApi', () => { expect(NodeApi.getNode).toBeDefined(); }); - test(`1: Get existing node [${node1.node._id} - ${node1.type}]`, async () => { + test(`1: Get existing node [${TestData.node1._id} - ${TestData.node1._type._id}]`, async () => { const response = await NodeApi.getNode({ - nodeId: node1.node._id, - nodeType: node1.type, + nodeId: TestData.node1._id, + nodeType: TestData.node1._type._id, state, }); expect(response).toMatchSnapshot(); @@ -348,26 +114,42 @@ describe('NodeApi', () => { }); }); + describe ('createNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeApi.createNode).toBeDefined(); + }); + + test(`1: Create new node [${TestData.node5._id} - ${TestData.node5._type._id}]`, async () => { + const response = await NodeApi.putNode({ + nodeId: TestData.node5._id, + nodeType: TestData.node5._type._id, + nodeData: TestData.node5, + state, + }); + expect(response).toMatchSnapshot(); + }); + }) + describe('putNode()', () => { test('0: Method is implemented', async () => { expect(NodeApi.putNode).toBeDefined(); }); - test(`1: Create new node [${node2.id} - ${node2.type}]`, async () => { + test(`1: Create new node [${TestData.node2._id} - ${TestData.node2._type._id}]`, async () => { const response = await NodeApi.putNode({ - nodeId: node2.id, - nodeType: node2.type, - nodeData: node2.node, + nodeId: TestData.node2._id, + nodeType: TestData.node2._type._id, + nodeData: TestData.node2, state, }); expect(response).toMatchSnapshot(); }); - test(`2: Update existing node [${node3.id} - ${node3.type}]`, async () => { + test(`2: Update existing node [${TestData.node3._id} - ${TestData.node3._type._id}]`, async () => { const node = await NodeApi.putNode({ - nodeId: node3.id, - nodeType: node3.type, - nodeData: node3.node, + nodeId: TestData.node3._id, + nodeType: TestData.node3._type._id, + nodeData: TestData.node3, state, }); expect(node).toMatchSnapshot(); @@ -379,10 +161,10 @@ describe('NodeApi', () => { expect(NodeApi.deleteNode).toBeDefined(); }); - test(`1: Delete existing node [${node4.node._id} - ${node4.type}]`, async () => { + test(`1: Delete existing node [${TestData.node4._id} - ${TestData.node4._type._id}]`, async () => { const node = await NodeApi.deleteNode({ - nodeId: node4.node._id, - nodeType: node4.type, + nodeId: TestData.node4._id, + nodeType: TestData.node4._type._id, state, }); expect(node).toMatchSnapshot(); @@ -401,4 +183,110 @@ describe('NodeApi', () => { } }); }); + + describe('createCustomNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeApi.createCustomNode).toBeDefined(); + }); + + test('1: Create custom node', async () => { + const response = await NodeApi.createCustomNode({ + nodeData: TestData.customNode3, + state, + }); + expect(response).toMatchSnapshot(); + }); + }); + + describe('getCustomNodes()', () => { + test('0: Method is implemented', async () => { + expect(NodeApi.getCustomNodes).toBeDefined(); + }); + + test('1: Get all custom nodes', async () => { + const response = await NodeApi.getCustomNodes({ state }); + expect(response).toMatchSnapshot(); + }); + }); + + describe('getCustomNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeApi.getCustomNode).toBeDefined(); + }); + + test(`1: Get existing custom node [${TestData.customNode1._id}]`, async () => { + const response = await NodeApi.getCustomNode({ + nodeId: TestData.customNode1._id, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test('2: Get non-existing custom node [11111111111111111111111111111111-1]', async () => { + expect.assertions(1); + try { + await NodeApi.getCustomNode({ + nodeId: '11111111111111111111111111111111-1', + state, + }); + } catch (error) { + expect(error.response.data).toMatchSnapshot(); + } + }); + }); + + describe('putCustomNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeApi.putCustomNode).toBeDefined(); + }); + + test(`1: Update existing custom node [${TestData.customNode2._id}]`, async () => { + const response = await NodeApi.putCustomNode({ + nodeId: TestData.customNode2._id, + nodeData: TestData.customNode2, + state, + }); + expect(response).toMatchSnapshot(); + }); + }); + + describe('deleteCustomNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeApi.deleteCustomNode).toBeDefined(); + }); + + test(`1: Delete existing custom node [${TestData.customNode4._id}]`, async () => { + const node = await NodeApi.deleteCustomNode({ + nodeId: TestData.customNode4._id, + state, + }); + expect(node).toMatchSnapshot(); + }); + + test('2: Delete non-existing custom node [11111111111111111111111111111111-1]', async () => { + expect.assertions(1); + try { + await NodeApi.deleteCustomNode({ + nodeId: '11111111111111111111111111111111-1', + state, + }); + } catch (error) { + expect(error.response.data).toMatchSnapshot(); + } + }); + }); + + describe('getCustomNodeUsage()', () => { + test('0: Method is implemented', async () => { + expect(NodeApi.getCustomNodeUsage).toBeDefined(); + }); + + test(`1: Get custom node usage [${TestData.customNode1._id}]`, async () => { + const response = await NodeApi.getCustomNodeUsage({ + nodeId: TestData.customNode1._id, + state, + }); + expect(response).toMatchSnapshot(); + }); + }); }); diff --git a/src/api/NodeApi.ts b/src/api/NodeApi.ts index b05cbb0e2..ee90ca0ad 100644 --- a/src/api/NodeApi.ts +++ b/src/api/NodeApi.ts @@ -22,6 +22,12 @@ const nodeURLTemplate = '%s/json%s/realm-config/authentication/authenticationtrees/nodes/%s/%s'; const createNodeURLTemplate = '%s/json%s/realm-config/authentication/authenticationtrees/nodes/%s?_action=create'; +const customNodeTypeURLTemplate = '%s/json/node-designer/node-type'; +const queryAllCustomNodesURLTemplate = + customNodeTypeURLTemplate + '?_queryFilter=true'; +const customNodeURLTemplate = customNodeTypeURLTemplate + '/%s'; +const journeyUsageCustomNodesURLTemplate = + customNodeURLTemplate + '?_action=journeys'; const apiVersion = 'protocol=2.1,resource=1.0'; const getNodeApiConfig = () => { @@ -49,6 +55,35 @@ export interface InnerNodeRefSkeletonInterface { nodeType: string; } +export type CustomNodeProperty = { + title: string; + description: string; + type: 'NUMBER' | 'STRING' | 'OBJECT' | 'BOOLEAN'; + required: boolean; + defaultValue?: + | string + | number + | boolean + | Record + | string[] + | number[]; + multivalued: boolean; + options?: Record; +}; + +export type CustomNodeSkeleton = IdObjectSkeletonInterface & { + serviceName: string; + displayName: string; + description: string; + outcomes: string[]; + outputs: string[]; + inputs: string[]; + script: string | string[]; + errorOutcome: boolean; + tags: string[]; + properties: Record; +}; + export type NodeSkeleton = AmConfigEntityInterface & { nodes?: InnerNodeRefSkeletonInterface[]; tree?: string; @@ -71,6 +106,11 @@ export type NodeTypeSkeleton = IdObjectSkeletonInterface & { help: string; }; +/** + * Object that is layed out as follows: . = array of nodes where custom node type is used in the journey in the specified realm + */ +export type CustomNodeUsage = Record>; + /** * Get all node types * @returns {Promise>} a promise that resolves to an array of node type objects @@ -283,3 +323,147 @@ export async function deleteNode({ }); return data; } + +/** + * Create custom node + * @param {CustomNodeSkeleton} nodeData custom node object + * @returns {Promise} a promise that resolves to an object containing a custom node object + */ +export async function createCustomNode({ + nodeData, + state, +}: { + nodeData: CustomNodeSkeleton; + state: State; +}): Promise { + const urlString = util.format(customNodeTypeURLTemplate, state.getHost()); + const { data } = await generateAmApi({ + resource: getNodeApiConfig(), + state, + }).post(urlString, nodeData, { + withCredentials: true, + }); + return data; +} + +/** + * Get all custom nodes + * @returns {Promise} a promise that resolves to an object containing an array of custom node objects + */ +export async function getCustomNodes({ + state, +}: { + state: State; +}): Promise> { + const urlString = util.format( + queryAllCustomNodesURLTemplate, + state.getHost() + ); + const { data } = await generateAmApi({ + resource: getNodeApiConfig(), + state, + }).get(urlString, { + withCredentials: true, + }); + return data; +} + +/** + * Get custom node by uuid + * @param {string} nodeId custom node uuid + * @returns {Promise} a promise that resolves to a custom node object + */ +export async function getCustomNode({ + nodeId, + state, +}: { + nodeId: string; + state: State; +}): Promise { + const urlString = util.format(customNodeURLTemplate, state.getHost(), nodeId); + const { data } = await generateAmApi({ + resource: getNodeApiConfig(), + state, + }).get(urlString, { + withCredentials: true, + }); + return data; +} + +/** + * Put custom node by uuid. + * NOTE: due to a bug in the current version of AIC (19646.0), you cannot create a custom node using PUT unless you don't include the if-match header, + * which header is required to make updates to an existing custom node. Use createCustomNode if you want to create a new custom node. + * @param {string} nodeId custom node uuid + * @param {CustomNodeSkeleton} nodeData custom node object + * @returns {Promise} a promise that resolves to an object containing a custom node object + */ +export async function putCustomNode({ + nodeId, + nodeData, + state, +}: { + nodeId: string; + nodeData: CustomNodeSkeleton; + state: State; +}): Promise { + const urlString = util.format(customNodeURLTemplate, state.getHost(), nodeId); + const { data } = await generateAmApi({ + resource: getNodeApiConfig(), + state, + }).put(urlString, nodeData, { + withCredentials: true, + headers: { + 'If-Match': '*', + }, + }); + return data; +} + +/** + * Delete custom node by uuid + * @param {String} nodeId custom node uuid + * @returns {Promise} a promise that resolves to an object containing a custom node object + */ +export async function deleteCustomNode({ + nodeId, + state, +}: { + nodeId: string; + state: State; +}): Promise { + const urlString = util.format(customNodeURLTemplate, state.getHost(), nodeId); + const { data } = await generateAmApi({ + resource: getNodeApiConfig(), + state, + }).delete(urlString, { + withCredentials: true, + }); + return data; +} + +/** + * Get custom node usage by uuid + * @param {String} nodeId custom node uuid + * @returns {Promise} a promise that resolves to an object containing a custom node usage object + */ +export async function getCustomNodeUsage({ + nodeId, + state, +}: { + nodeId: string; + state: State; +}): Promise { + const urlString = util.format( + journeyUsageCustomNodesURLTemplate, + state.getHost(), + nodeId + ); + const { data } = await generateAmApi({ + resource: getNodeApiConfig(), + state, + }).post(urlString, undefined, { + withCredentials: true, + }); + return data; +} diff --git a/src/ops/ConfigOps.ts b/src/ops/ConfigOps.ts index 4a6df1c00..d3e8f1c1d 100644 --- a/src/ops/ConfigOps.ts +++ b/src/ops/ConfigOps.ts @@ -6,6 +6,7 @@ import { CircleOfTrustSkeleton } from '../api/CirclesOfTrustApi'; import { SiteSkeleton } from '../api/classic/SiteApi'; import { SecretSkeleton } from '../api/cloud/SecretsApi'; import { VariableSkeleton } from '../api/cloud/VariablesApi'; +import { CustomNodeSkeleton } from '../api/NodeApi'; import { OAuth2ClientSkeleton } from '../api/OAuth2ClientApi'; import { OAuth2TrustedJwtIssuerSkeleton } from '../api/OAuth2TrustedJwtIssuerApi'; import { PolicySkeleton } from '../api/PoliciesApi'; @@ -93,6 +94,7 @@ import { MappingSkeleton, SyncSkeleton, } from './MappingOps'; +import { exportCustomNodes, importCustomNodes } from './NodeOps'; import { exportOAuth2Clients, importOAuth2Clients } from './OAuth2ClientOps'; import { exportOAuth2TrustedJwtIssuers, @@ -160,6 +162,7 @@ export default (state: State): Config => { options: FullImportOptions = { reUuidJourneys: false, reUuidScripts: false, + reUuidCustomNodes: false, cleanServices: false, includeDefault: false, includeActiveValues: true, @@ -230,6 +233,10 @@ export interface FullImportOptions { * Generate new UUIDs for all scripts during import. */ reUuidScripts: boolean; + /** + * Generate new UUIDs and service names for all custom nodes during import. + */ + reUuidCustomNodes: boolean; /** * Indicates whether to remove previously existing services of the same id before importing */ @@ -261,6 +268,7 @@ export interface FullGlobalExportInterface extends AmConfigEntitiesInterface { idm: Record | undefined; internalRole: Record; mapping: Record | undefined; + nodeTypes: Record | undefined; realm: Record | undefined; scripttype: Record | undefined; secret: Record | undefined; @@ -445,6 +453,19 @@ export async function exportFullConfiguration({ ) )?.internalRole, mapping: mappings?.mapping, + nodeTypes: ( + await exportWithErrorHandling( + exportCustomNodes, + { + options: { + useStringArrays, + }, + state, + }, + 'Custom Nodes', + resultCallback + ) + )?.nodeTypes, realm: ( await exportWithErrorHandling( exportRealms, @@ -611,7 +632,11 @@ export async function exportFullConfiguration({ await exportWithErrorHandling( exportJourneys, { - options: { deps: false, useStringArrays, coords }, + options: { + deps: false, + useStringArrays, + coords, + }, resultCallback: errorCallback, state, }, @@ -751,6 +776,7 @@ export async function importFullConfiguration({ options = { reUuidJourneys: false, reUuidScripts: false, + reUuidCustomNodes: false, cleanServices: false, includeDefault: false, includeActiveValues: true, @@ -775,6 +801,7 @@ export async function importFullConfiguration({ const { reUuidJourneys, reUuidScripts, + reUuidCustomNodes, cleanServices, includeDefault, includeActiveValues, @@ -783,7 +810,7 @@ export async function importFullConfiguration({ const errorCallback = getErrorCallback(resultCallback); // Import to global let indicatorId = createProgressIndicator({ - total: 14, + total: 15, message: `Importing everything for global...`, state, }); @@ -835,6 +862,25 @@ export async function importFullConfiguration({ isClassicDeployment && !!importData.global.realm ) ); + response.push( + await importWithErrorHandling( + importCustomNodes, + { + nodeId: '', + nodeName: '', + importData: importData.global, + options: { + reUuid: reUuidCustomNodes, + }, + resultCallback: errorCallback, + state, + }, + indicatorId, + 'Custom Nodes', + resultCallback, + !!importData.global.nodeTypes + ) + ); response.push( await importWithErrorHandling( importScriptTypes, diff --git a/src/ops/JourneyOps.test.ts b/src/ops/JourneyOps.test.ts index 72342eb63..cc497542c 100644 --- a/src/ops/JourneyOps.test.ts +++ b/src/ops/JourneyOps.test.ts @@ -48,116 +48,20 @@ */ import { state } from '../index'; import * as JourneyOps from './JourneyOps'; -import { getJourney } from '../test/mocks/ForgeRockApiMockEngine'; import { autoSetupPolly } from '../utils/AutoSetupPolly'; import { filterRecording } from '../utils/PollyUtils'; import Constants from '../shared/Constants'; + +import * as TestData from '../test/setup/JourneySetup'; import { snapshotResultCallback } from '../test/utils/TestUtils'; const ctx = autoSetupPolly(); state.setDeploymentType(Constants.CLOUD_DEPLOYMENT_TYPE_KEY); -async function stageJourney(journey: { id: string }, create = true) { - // delete if exists, then create - try { - await JourneyOps.readJourney({ journeyId: journey.id, state }); - await JourneyOps.deleteJourney({ - journeyId: journey.id, - options: { - deep: true, - verbose: false, - progress: false, - }, - state, - }); - } catch (error) { - // ignore - } finally { - if (create) { - await JourneyOps.importJourney({ - importData: getJourney(journey.id), - options: { - reUuid: false, - deps: true, - }, - state, - }); - } - } -} - describe('JourneyOps', () => { - const journey1 = { - id: 'FrodoTestJourney1', - }; - const journey2 = { - id: 'FrodoTestJourney2', - }; - const journey3 = { - id: 'FrodoTestJourney3', - }; - const journey4 = { - id: 'FrodoTestJourney4', - }; - const journey5 = { - id: 'FrodoTestJourney5', - }; - const journey6 = { - id: 'FrodoTestJourney6', - }; - const journey7 = { - id: 'FrodoTestJourney7', - }; - const journey8 = { - id: 'FrodoTestJourney8', - }; - const journey9 = { - id: 'FrodoTestJourney9', - }; - const journey10 = { - id: 'FrodoTestJourney10', - }; - const journey10NoCoords = { - id: 'FrodoTestJourney10NoCoords' - }; - const journey11 = { - id: 'FrodoTestJourney11', - } - // in recording mode, setup test data before recording - beforeAll(async () => { - if (process.env.FRODO_POLLY_MODE === 'record') { - await stageJourney(journey1); - await stageJourney(journey2); - await stageJourney(journey3); - await stageJourney(journey4, false); - await stageJourney(journey5, false); - await stageJourney(journey6); - await stageJourney(journey7); - await stageJourney(journey8); - await stageJourney(journey9); - await stageJourney(journey10); - await stageJourney(journey10NoCoords, false); - await stageJourney(journey11, false); - } - }); - // in recording mode, remove test data after recording - afterAll(async () => { - if (process.env.FRODO_POLLY_MODE === 'record') { - await stageJourney(journey1, false); - await stageJourney(journey2, false); - await stageJourney(journey3, false); - await stageJourney(journey4, false); - await stageJourney(journey5, false); - await stageJourney(journey6, false); - await stageJourney(journey7, false); - await stageJourney(journey8, false); - await stageJourney(journey9, false); - await stageJourney(journey10, false); - await stageJourney(journey10NoCoords, false); - await stageJourney(journey11, false); - } - }); + TestData.setup(); + beforeEach(async () => { if (process.env.FRODO_POLLY_MODE === 'record') { ctx.polly.server.any().on('beforePersist', (_req, recording) => { @@ -182,7 +86,7 @@ describe('JourneyOps', () => { }); test('1: Nothing changes when coordinates exist', async () => { - const journey = getJourney(journey10.id); + const journey = TestData.journey10; const tree = JSON.parse(JSON.stringify(journey.tree)); expect(await JourneyOps.updateCoordinates({ tree: tree, @@ -194,7 +98,7 @@ describe('JourneyOps', () => { }); test('2: Update coordinates with server coordinates when server tree exists', async () => { - const journey = getJourney(journey10.id); + const journey = TestData.journey10; const tree = JSON.parse(JSON.stringify(journey.tree)); delete tree.nodes[node1].x; delete tree.nodes[node2].y; @@ -211,7 +115,7 @@ describe('JourneyOps', () => { }); test('3: Updates coordinates to 0 if serverTree does not exist', async () => { - const journey = getJourney(journey11.id); + const journey = TestData.journey11; const expectedTree = JSON.parse(JSON.stringify(journey.tree)); expectedTree.nodes[node5].x = 0; expectedTree.nodes[node5].y = 0; @@ -228,7 +132,7 @@ describe('JourneyOps', () => { }); test('4: Updates coordinates to 0 if serverTree nodes do not exist', async () => { - const journey = getJourney(journey10NoCoords.id); + const journey = TestData.journey10NoCoords; const expectedTree = JSON.parse(JSON.stringify(journey.tree)); expectedTree.nodes[node1].x = 0; expectedTree.nodes[node1].y = 0; @@ -247,8 +151,8 @@ describe('JourneyOps', () => { }); test('5: Updates coordinates in various cases', async () => { - const journey = getJourney(journey10.id); - const journeyNoCoords = getJourney(journey10NoCoords.id); + const journey = TestData.journey10; + const journeyNoCoords = TestData.journey10NoCoords; const expectedTree = JSON.parse(JSON.stringify(journey.tree)); expectedTree.nodes[node1].x = 0; expectedTree.nodes[node2].y = 0; @@ -296,9 +200,9 @@ describe('JourneyOps', () => { expect(JourneyOps.exportJourney).toBeDefined(); }); - test(`1: Export journey '${journey3.id}' w/o dependencies`, async () => { + test(`1: Export journey '${TestData.journey3.tree._id}' w/o dependencies`, async () => { const response = await JourneyOps.exportJourney({ - journeyId: journey3.id, + journeyId: TestData.journey3.tree._id, options: { useStringArrays: false, deps: false, @@ -311,9 +215,9 @@ describe('JourneyOps', () => { }); }); - test(`2: Export journey '${journey3.id}' w/ dependencies`, async () => { + test(`2: Export journey '${TestData.journey3.tree._id}' w/ dependencies`, async () => { const response = await JourneyOps.exportJourney({ - journeyId: journey3.id, + journeyId: TestData.journey3.tree._id, options: { useStringArrays: false, deps: true, @@ -326,9 +230,9 @@ describe('JourneyOps', () => { }); }); - test(`3: Export journey '${journey3.id}' w/ dependencies and w/o coordinates`, async () => { + test(`3: Export journey '${TestData.journey3.tree._id}' w/ dependencies and w/o coordinates`, async () => { const response = await JourneyOps.exportJourney({ - journeyId: journey3.id, + journeyId: TestData.journey3.tree._id, options: { useStringArrays: false, deps: true, @@ -340,6 +244,21 @@ describe('JourneyOps', () => { meta: expect.any(Object), }); }); + + test(`4: Export journey '${TestData.journey12.tree._id}' w/ custom node dependencies`, async () => { + const response = await JourneyOps.exportJourney({ + journeyId: TestData.journey12.tree._id, + options: { + useStringArrays: true, + deps: true, + coords: true, + }, + state, + }); + expect(response).toMatchSnapshot({ + meta: expect.any(Object), + }); + }); }); describe('exportJourneys()', () => { @@ -374,8 +293,8 @@ describe('JourneyOps', () => { expect(JourneyOps.importJourney).toBeDefined(); }); - test(`1: Import journey '${journey4.id}' w/o dependencies`, async () => { - const journeyExport = getJourney(journey4.id); + test(`1: Import journey '${TestData.journey4.tree._id}' w/o dependencies`, async () => { + const journeyExport = TestData.journey4; expect.assertions(1); const response = await JourneyOps.importJourney({ importData: journeyExport, @@ -388,8 +307,22 @@ describe('JourneyOps', () => { expect(response).toBeTruthy(); }); - test(`2: Import journey '${journey5.id}' w/ dependencies`, async () => { - const journeyExport = getJourney(journey5.id); + test(`2: Import journey '${TestData.journey5.tree._id}' w/ dependencies`, async () => { + const journeyExport = TestData.journey5; + expect.assertions(1); + const response = await JourneyOps.importJourney({ + importData: journeyExport, + options: { + reUuid: false, + deps: true, + }, + state, + }); + expect(response).toBeTruthy(); + }); + + test(`3: Import journey '${TestData.journey12.tree._id}' w/ custom node dependencies`, async () => { + const journeyExport = TestData.journey12; expect.assertions(1); const response = await JourneyOps.importJourney({ importData: journeyExport, @@ -408,19 +341,19 @@ describe('JourneyOps', () => { expect(JourneyOps.enableJourney).toBeDefined(); }); - test(`1: Enable disabled journey '${journey6.id}'`, async () => { + test(`1: Enable disabled journey '${TestData.journey6.tree._id}'`, async () => { expect.assertions(1); const result = await JourneyOps.enableJourney({ - journeyId: journey6.id, + journeyId: TestData.journey6.tree._id, state, }); expect(result).toBeTruthy(); }); - test(`2: Enable already enabled journey '${journey7.id}'`, async () => { + test(`2: Enable already enabled journey '${TestData.journey7.tree._id}'`, async () => { expect.assertions(1); const result = await JourneyOps.enableJourney({ - journeyId: journey7.id, + journeyId: TestData.journey7.tree._id, state, }); expect(result).toBeTruthy(); @@ -432,19 +365,19 @@ describe('JourneyOps', () => { expect(JourneyOps.disableJourney).toBeDefined(); }); - test(`1: Disable enabled journey '${journey8.id}'`, async () => { + test(`1: Disable enabled journey '${TestData.journey8.tree._id}'`, async () => { expect.assertions(1); const result = await JourneyOps.disableJourney({ - journeyId: journey8.id, + journeyId: TestData.journey8.tree._id, state, }); expect(result).toBeTruthy(); }); - test(`2: Disable already disabled journey '${journey9.id}'`, async () => { + test(`2: Disable already disabled journey '${TestData.journey9.tree._id}'`, async () => { expect.assertions(1); const result = await JourneyOps.disableJourney({ - journeyId: journey9.id, + journeyId: TestData.journey9.tree._id, state, }); expect(result).toBeTruthy(); diff --git a/src/ops/JourneyOps.ts b/src/ops/JourneyOps.ts index 8c602ea65..3539248dd 100644 --- a/src/ops/JourneyOps.ts +++ b/src/ops/JourneyOps.ts @@ -9,6 +9,7 @@ import { } from '../api/CirclesOfTrustApi'; import { VariableSkeleton } from '../api/cloud/VariablesApi'; import { + CustomNodeSkeleton, deleteNode, getNode, type InnerNodeRefSkeletonInterface, @@ -76,10 +77,13 @@ import { readSocialIdentityProviders, } from './IdpOps'; import { + CustomNodeExportInterface, findOrphanedNodes as _findOrphanedNodes, + importCustomNodes, isCloudOnlyNode, isCustomNode, isPremiumNode, + readCustomNode, removeOrphanedNodes as _removeOrphanedNodes, } from './NodeOps'; import { type ExportMetaData, ResultCallback } from './OpsTypes'; @@ -530,7 +534,7 @@ export interface TreeExportOptions { */ useStringArrays: boolean; /** - * Include any dependencies (scripts, email templates, SAML entity providers and circles of trust, social identity providers, themes). + * Include any dependencies specific to AIC (scripts, email templates, SAML entity providers and circles of trust, social identity providers, themes). */ deps: boolean; /** @@ -548,7 +552,7 @@ export interface TreeImportOptions { */ reUuid: boolean; /** - * Include any dependencies (scripts, email templates, SAML entity providers and circles of trust, social identity providers, themes). + * Include any dependencies specific to AIC or Frodo (scripts, email templates, SAML entity providers and circles of trust, social identity providers, themes, custom nodes). */ deps: boolean; } @@ -557,6 +561,7 @@ export interface SingleTreeExportInterface { meta?: ExportMetaData; innerNodes?: Record; innernodes?: Record; + nodeTypes?: Record; nodes: Record; scripts: Record; emailTemplates: Record; @@ -905,6 +910,7 @@ export async function exportJourney({ const variables: Record = {}; const nodePromises = []; const scriptPromises = []; + const customNodePromises = []; const emailTemplatePromises = []; const innerNodePromises = []; const saml2ConfigPromises = []; @@ -964,6 +970,20 @@ export async function exportJourney({ scriptPromises.push(readScript({ scriptId: nodeObject.script, state })); } + // handle custom node types + if ( + deps && + nodeObject._type?._id && + nodeObject._type._id.startsWith('designer-') + ) { + customNodePromises.push( + readCustomNode({ + nodeId: nodeObject._type._id.substring(9) + '-1', + state, + }) + ); + } + // frodo supports email templates in platform deployments if (deps && isPlatformDeployment) { if (emailTemplateNodes.includes(nodeType)) { @@ -1095,6 +1115,20 @@ export async function exportJourney({ ); } + // handle custom node types + if ( + deps && + innerNodeObject._type?._id && + innerNodeObject._type._id.startsWith('designer-') + ) { + customNodePromises.push( + readCustomNode({ + nodeId: innerNodeObject._type._id.substring(9) + '-1', + state, + }) + ); + } + // frodo supports email templates in platform deployments if (deps && isPlatformDeployment) { if (emailTemplateNodes.includes(innerNodeType)) { @@ -1367,6 +1401,31 @@ export async function exportJourney({ ); } + // Process custom nodes + if (verbose && customNodePromises.length > 0) + printMessage({ message: '\n - Custom Nodes:', newline: false, state }); + try { + const customNodeObjects = await Promise.all(customNodePromises); + for (const customNodeObject of customNodeObjects) { + if (!customNodeObject) continue; + if (verbose) + printMessage({ + message: `\n - ${customNodeObject._id} (${customNodeObject.displayName})`, + type: 'info', + newline: false, + state, + }); + if (useStringArrays) + customNodeObject.script = (customNodeObject.script as string).split( + '\n' + ); + if (!exportData.nodeTypes) exportData.nodeTypes = {}; + exportData.nodeTypes[customNodeObject._id] = customNodeObject; + } + } catch (error) { + errors.push(new FrodoError(`Error reading custom nodes`, error)); + } + // Process themes if (themePromise) { if (verbose) @@ -1696,6 +1755,26 @@ export async function importJourney({ } } + // Process custom nodes + if ( + deps && + importData.nodeTypes && + Object.entries(importData.nodeTypes).length > 0 + ) { + if (verbose) + printMessage({ message: ' - Custom Nodes:', newline: false, state }); + await importCustomNodes({ + importData: importData as CustomNodeExportInterface, + options: { + reUuid: false, + }, + resultCallback: (err) => { + if (err) errors.push(err); + }, + state, + }); + } + // Process email templates if ( deps && diff --git a/src/ops/NodeOps.test.ts b/src/ops/NodeOps.test.ts index 8e74273a3..ff7b65adf 100644 --- a/src/ops/NodeOps.test.ts +++ b/src/ops/NodeOps.test.ts @@ -52,6 +52,9 @@ import { autoSetupPolly } from '../utils/AutoSetupPolly'; import { filterRecording } from '../utils/PollyUtils'; import Constants from '../shared/Constants'; +import * as TestData from '../test/setup/NodeSetup'; +import { snapshotResultCallback } from '../test/utils/TestUtils'; + const ctx = autoSetupPolly(); const stateCloud750 = frodo.createInstance({ amVersion: '7.5.0', @@ -67,12 +70,14 @@ describe('NodeOps', () => { // stage test data } }); + // in recording mode, remove test data after recording afterAll(async () => { if (process.env.FRODO_POLLY_MODE === 'record') { // clean-up test data } }); + beforeEach(async () => { if (process.env.FRODO_POLLY_MODE === 'record') { ctx.polly.server.any().on('beforePersist', (_req, recording) => { @@ -80,6 +85,7 @@ describe('NodeOps', () => { }); } }); + // Phase 1 if ( !process.env.FRODO_POLLY_MODE || @@ -87,6 +93,8 @@ describe('NodeOps', () => { process.env.FRODO_RECORD_PHASE === '1') ) { + TestData.setup(); + describe('createNodeExportTemplate()', () => { test('0: Method is implemented', async () => { expect(NodeOps.createNodeExportTemplate).toBeDefined(); @@ -100,6 +108,19 @@ describe('NodeOps', () => { }); }); + describe('createCustomNodeExportTemplate()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.createCustomNodeExportTemplate).toBeDefined(); + }); + + test('1: Create Custom Node Export Template', async () => { + const response = NodeOps.createCustomNodeExportTemplate({ state }); + expect(response).toMatchSnapshot({ + meta: expect.any(Object), + }); + }); + }); + describe('readNodeTypes()', () => { test('0: Method is implemented', async () => { expect(NodeOps.readNodeTypes).toBeDefined(); @@ -137,7 +158,28 @@ describe('NodeOps', () => { test('0: Method is implemented', async () => { expect(NodeOps.readNode).toBeDefined(); }); - //TODO: Create tests + + test(`1: Read existing node`, async () => { + const response = await NodeOps.readNode({ + nodeId: TestData.node1._id, + nodeType: TestData.node1._type._id, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test('2: Read non-existing node', async () => { + expect.assertions(1); + try { + await NodeOps.readNode({ + nodeId: '00000000-0000-0000-0000-000000000000', + nodeType: 'PageNode', + state, + }); + } catch (error) { + expect(error.response.data).toMatchSnapshot(); + } + }); }); describe('exportNodes()', () => { @@ -157,25 +199,323 @@ describe('NodeOps', () => { test('0: Method is implemented', async () => { expect(NodeOps.createNode).toBeDefined(); }); - //TODO: Create tests + + test(`1: Create new node with id`, async () => { + await TestData.stageNode(TestData.node5); + const response = await NodeOps.createNode({ + nodeId: TestData.node5._id, + nodeType: TestData.node5._type._id, + nodeData: TestData.node5, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test(`2: Create new node without id`, async() => { + await TestData.stageNode(TestData.node5); + const response = await NodeOps.createNode({ + nodeType: TestData.node5._type._id, + nodeData: TestData.node5, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test(`3: Create existing node by id`, async() => { + await TestData.stageNode(TestData.node5, true); + await expect(NodeOps.createNode({ + nodeId: TestData.node5._id, + nodeType: TestData.node5._type._id, + nodeData: TestData.node5, + state, + })).rejects.toThrow('Error creating SetStateNode node ' + TestData.node5._id); + }); + + test(`4: Create existing node without id`, async() => { + await TestData.stageNode(TestData.node5, true); + await expect(NodeOps.createNode({ + nodeType: TestData.node5._type._id, + nodeData: TestData.node5, + state, + })).rejects.toThrow('Request failed with status code 409'); + }); }); describe('updateNode()', () => { test('0: Method is implemented', async () => { expect(NodeOps.updateNode).toBeDefined(); }); - //TODO: Create tests + + test(`1: Update existing node`, async () => { + await TestData.stageNode(TestData.node3, true); + const node = await NodeOps.updateNode({ + nodeId: TestData.node3._id, + nodeType: TestData.node3._type._id, + nodeData: TestData.node3, + state, + }); + expect(node).toMatchSnapshot(); + }); + + test(`2: Update non-existing node`, async () => { + await TestData.stageNode(TestData.node3); + const node = await NodeOps.updateNode({ + nodeId: TestData.node3._id, + nodeType: TestData.node3._type._id, + nodeData: TestData.node3, + state, + }); + expect(node).toMatchSnapshot(); + }); }); describe('deleteNode()', () => { test('0: Method is implemented', async () => { expect(NodeOps.deleteNode).toBeDefined(); }); + + test(`1: Delete existing node`, async () => { + const node = await NodeOps.deleteNode({ + nodeId: TestData.node4._id, + nodeType: TestData.node4._type._id, + state, + }); + expect(node).toMatchSnapshot(); + }); + + test('2: Delete non-existing node', async () => { + await expect(NodeOps.deleteNode({ + nodeId: '00000000-0000-0000-0000-000000000000', + nodeType: 'PageNode', + state, + })).rejects.toThrow('Request failed with status code 404'); + }); }); - describe('removeOrphanedNodes()', () => { + describe('readCustomNode()', () => { test('0: Method is implemented', async () => { - expect(NodeOps.removeOrphanedNodes).toBeDefined(); + expect(NodeOps.readCustomNode).toBeDefined(); + }); + + test(`1: Read existing custom node by ID`, async () => { + const response = await NodeOps.readCustomNode({ + nodeId: TestData.customNode1.serviceName, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test('2: Read non-existing custom node', async () => { + await expect(NodeOps.readCustomNode({ + nodeId: '11111111111111111111111111111111-1', + state, + })).rejects.toThrow('Error reading custom node 11111111111111111111111111111111-1'); + }); + + test(`3: Read existing custom node by name`, async () => { + const response = await NodeOps.readCustomNode({ + nodeName: TestData.customNode1.displayName, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test(`4: Read without name or id`, async () => { + await expect(NodeOps.readCustomNode({ + state, + })).rejects.toThrow('No custom node ID or display name provided.'); + }); + }); + + describe('readCustomNodes()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.readCustomNodes).toBeDefined(); + }); + + test('1: Read custom nodes', async () => { + const response = await NodeOps.readCustomNodes({ state }); + expect(response).toMatchSnapshot(); + }); + }); + + describe('exportCustomNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.exportCustomNode).toBeDefined(); + }); + + test(`1: Export existing custom node by ID`, async () => { + const response = await NodeOps.exportCustomNode({ + nodeId: TestData.customNode1.serviceName, + state, + }); + expect(response).toMatchSnapshot({ + meta: expect.any(Object), + }); + }); + + test('2: Export non-existing custom node', async () => { + await expect(NodeOps.exportCustomNode({ + nodeId: '11111111111111111111111111111111-1', + state, + })).rejects.toThrow('Error exporting custom node 11111111111111111111111111111111-1'); + }); + + test(`3: Export existing custom node by name`, async () => { + const response = await NodeOps.exportCustomNode({ + nodeName: TestData.customNode1.displayName, + state, + }); + expect(response).toMatchSnapshot({ + meta: expect.any(Object), + }); + }); + + test(`4: Export without name or id`, async () => { + await expect(NodeOps.exportCustomNode({ + state, + })).rejects.toThrow('No custom node ID or display name provided.'); + }); + }); + + describe('exportCustomNodes()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.exportCustomNodes).toBeDefined(); + }); + + test('1: Export custom nodes', async () => { + const response = await NodeOps.exportCustomNodes({ state }); + expect(response).toMatchSnapshot({ + meta: expect.any(Object), + }); + }); + }); + + describe('updateCustomNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.updateCustomNode).toBeDefined(); + }); + + test(`1: Update existing custom node`, async () => { + await TestData.stageCustomNode(TestData.customNode2, true); + const response = await NodeOps.updateCustomNode({ + nodeId: TestData.customNode2.serviceName, + nodeData: TestData.customNode2, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test(`2: Update non-existing custom node`, async () => { + await TestData.stageCustomNode(TestData.customNode2); + await expect(NodeOps.updateCustomNode({ + nodeId: TestData.customNode2._id, + nodeData: TestData.customNode2, + state, + })).rejects.toThrow('Error updating custom node'); + }); + }); + + describe('importCustomNodes()', () => { + + const importData = NodeOps.createCustomNodeExportTemplate({ state }); + importData.nodeTypes = { + [TestData.customNode2._id]: TestData.customNode2, + // We want to also test importing with array scripts, so make this script an array + [TestData.customNode3._id]: {...TestData.customNode3, script: (TestData.customNode3.script as string).split('\n')}, + [TestData.customNode4._id]: TestData.customNode4, + } + + test('0: Method is implemented', async () => { + expect(NodeOps.importCustomNodes).toBeDefined(); + }); + + test('1: Import None', async () => { + const response = await NodeOps.importCustomNodes({ + importData: NodeOps.createCustomNodeExportTemplate({ state }), + options: { + reUuid: false + }, + resultCallback: snapshotResultCallback, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test('2: Import by ID', async () => { + const response = await NodeOps.importCustomNodes({ + nodeId: TestData.customNode3.serviceName, + importData, + options: { + reUuid: false + }, + resultCallback: snapshotResultCallback, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test('3: Import by Name', async () => { + const response = await NodeOps.importCustomNodes({ + nodeName: TestData.customNode3.displayName, + importData, + options: { + reUuid: false + }, + resultCallback: snapshotResultCallback, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test('4: Import all', async () => { + const response = await NodeOps.importCustomNodes({ + importData, + options: { + reUuid: false + }, + resultCallback: snapshotResultCallback, + state, + }); + expect(response).toMatchSnapshot(); + }); + + test.todo('5: Import re-uuid'); + }); + + describe('deleteCustomNode()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.deleteCustomNode).toBeDefined(); + }); + + test(`1: Delete existing custom node by id`, async () => { + await TestData.stageCustomNode(TestData.customNode4, true); + const node = await NodeOps.deleteCustomNode({ + nodeId: TestData.customNode4.serviceName, + state, + }); + expect(node).toMatchSnapshot(); + }); + + test('2: Delete non-existing custom node', async () => { + await expect(NodeOps.deleteCustomNode({ + nodeId: '11111111111111111111111111111111-1', + state, + })).rejects.toThrow('Error deleting custom node 11111111111111111111111111111111-1'); + }); + + test(`3: Delete existing custom node by name`, async () => { + await TestData.stageCustomNode(TestData.customNode4, true); + const node = await NodeOps.deleteCustomNode({ + nodeName: TestData.customNode4.displayName, + state, + }); + expect(node).toMatchSnapshot(); + }); + + test('4: Delete without name or id', async () => { + await expect(NodeOps.deleteCustomNode({ + state, + })).rejects.toThrow('No custom node ID or display name provided.'); }); }); @@ -525,6 +865,37 @@ describe('NodeOps', () => { expect(classification).toMatchSnapshot(); }); }); + + describe('getCustomNodeUsage()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.getCustomNodeUsage).toBeDefined(); + }); + + test(`1: Get custom node usage [${TestData.customNode1._id}]`, async () => { + const response = await NodeOps.getCustomNodeUsage({ + nodeId: TestData.customNode1.serviceName, + state, + }); + expect(response).toMatchSnapshot(); + }); + }); + + describe('getCustomNodeId()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.getCustomNodeId).toBeDefined(); + }); + + test(`1: Get custom node id of service name]`, async () => { + expect(NodeOps.getCustomNodeId(TestData.customNode1.serviceName)).toBe(TestData.customNode1._id); + }); + + test(`2: Return input when falsey or in format]`, async () => { + expect(NodeOps.getCustomNodeId(undefined)).toBeUndefined(); + expect(NodeOps.getCustomNodeId(null)).toBeNull(); + expect(NodeOps.getCustomNodeId('')).toBe(''); + expect(NodeOps.getCustomNodeId(TestData.customNode1._id)).toBe(TestData.customNode1._id); + }); + }); } // Phase 2 if ( @@ -532,11 +903,17 @@ describe('NodeOps', () => { (process.env.FRODO_POLLY_MODE === 'record' && process.env.FRODO_RECORD_PHASE === '2') ) { - describe('deleteNode()', () => { + describe('deleteCustomNodes()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.deleteCustomNodes).toBeDefined(); + }); //TODO: Create tests }); describe('removeOrphanedNodes()', () => { + test('0: Method is implemented', async () => { + expect(NodeOps.removeOrphanedNodes).toBeDefined(); + }); //TODO: Create tests }); } diff --git a/src/ops/NodeOps.ts b/src/ops/NodeOps.ts index 11362c9ab..2201252cf 100644 --- a/src/ops/NodeOps.ts +++ b/src/ops/NodeOps.ts @@ -1,12 +1,22 @@ +import { v4 as uuidv4 } from 'uuid'; + import { + createCustomNode, createNode as _createNode, + CustomNodeSkeleton, + CustomNodeUsage, + deleteCustomNode as _deleteCustomNode, deleteNode as _deleteNode, + getCustomNode, + getCustomNodes, + getCustomNodeUsage as _getCustomNodeUsage, getNode as _getNode, getNodes as _getNodes, getNodesByType as _getNodesByType, getNodeTypes as _getNodeTypes, type NodeSkeleton, type NodeTypeSkeleton, + putCustomNode, putNode as _putNode, } from '../api/NodeApi'; import { getTrees } from '../api/TreeApi'; @@ -18,10 +28,12 @@ import { printError, stopProgressIndicator, updateProgressIndicator, + verboseMessage, } from '../utils/Console'; -import { getMetadata } from '../utils/ExportImportUtils'; +import { getMetadata, getResult } from '../utils/ExportImportUtils'; +import { applyNameCollisionPolicy } from '../utils/ForgeRockUtils'; import { FrodoError } from './FrodoError'; -import { ExportMetaData } from './OpsTypes'; +import { ExportMetaData, ResultCallback } from './OpsTypes'; export type Node = { /** @@ -78,6 +90,85 @@ export type Node = { * @returns {Promise} a promise that resolves to an object containing a node object */ deleteNode(nodeId: string, nodeType: string): Promise; + /** + * Read custom node. Either ID or name must be provided. + * @param {string} nodeId ID or service name of custom node. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. + * @returns {Promise} a promise that resolves to a custom node object + */ + readCustomNode( + nodeId?: string, + nodeName?: string + ): Promise; + /** + * Read all custom nodes + * @returns {Promise} a promise that resolves to an array of custom nodes objects + */ + readCustomNodes(): Promise; + /** + * Export custom node. Either ID or name must be provided. + * @param {string} nodeId ID or service name of custom node. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. + * @param {CustomNodeExportOptions} options Custom node export options + * @returns {Promise} a promise that resolves to a custom node export object + */ + exportCustomNode( + nodeId?: string, + nodeName?: string, + options?: CustomNodeExportOptions + ): Promise; + /** + * Export all custom nodes + * @param {CustomNodeExportOptions} options Custom node export options + * @returns {Promise} a promise that resolves to a custom node export object + */ + exportCustomNodes( + options?: CustomNodeExportOptions + ): Promise; + /** + * Update custom node by ID + * @param {string} nodeId ID or service name of custom node. + * @param {CustomNodeSkeleton} nodeData node object + * @returns {Promise} a promise that resolves to a custom node object + */ + updateCustomNode( + nodeId: string, + nodeData: CustomNodeSkeleton + ): Promise; + /** + * Import custom nodes + * @param {string} nodeId ID or service name of custom node. If supplied, only the custom node of that id is imported. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. If supplied, only the custom node of that name is imported + * @param {CustomNodeExportInterface} importData Custom node import data + * @param {CustomNodeImportOptions} options Custom node import options + * @param {ResultCallback} resultCallback Optional callback to process individual results + * @returns {Promise} the imported custom nodes + */ + importCustomNodes( + nodeId: string, + nodeName: string, + importData: CustomNodeExportInterface, + options?: CustomNodeImportOptions, + resultCallback?: ResultCallback + ): Promise; + /** + * Delete custom node. Either ID or name must be provided. + * @param {string} nodeId ID or service name of custom node. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. + * @returns {Promise} promise that resolves to a custom node object + */ + deleteCustomNode( + nodeId?: string, + nodeName?: string + ): Promise; + /** + * Delete custom nodes + * @param {ResultCallback} resultCallback Optional callback to process individual results + * @returns {Promise} promise that resolves to an array of custom node objects + */ + deleteCustomNodes( + resultCallback?: ResultCallback + ): Promise; /** * Find all node configuration objects that are no longer referenced by any tree * @returns {Promise} a promise that resolves to an array of orphaned nodes @@ -128,6 +219,12 @@ export type Node = { * @returns {NodeClassificationType[]} an array of one or multiple classifications */ getNodeClassification(nodeType: string): NodeClassificationType[]; + /** + * Get custom node usage by ID + * @param {String} nodeId ID or service name of the custom node + * @returns {Promise} a promise that resolves to an object containing a custom node usage object + */ + getCustomNodeUsage(nodeId: string): Promise; }; export default (state: State): Node => { @@ -163,6 +260,91 @@ export default (state: State): Node => { async deleteNode(nodeId: string, nodeType: string): Promise { return deleteNode({ nodeId, nodeType, state }); }, + readCustomNode( + nodeId?: string, + nodeName?: string + ): Promise { + return readCustomNode({ + nodeId, + nodeName, + state, + }); + }, + readCustomNodes(): Promise { + return readCustomNodes({ + state, + }); + }, + exportCustomNode( + nodeId?: string, + nodeName?: string, + options: CustomNodeExportOptions = { + useStringArrays: true, + } + ): Promise { + return exportCustomNode({ + nodeId, + nodeName, + options, + state, + }); + }, + exportCustomNodes( + options: CustomNodeExportOptions = { + useStringArrays: true, + } + ): Promise { + return exportCustomNodes({ + options, + state, + }); + }, + updateCustomNode( + nodeId: string, + nodeData: CustomNodeSkeleton + ): Promise { + return updateCustomNode({ + nodeId, + nodeData, + state, + }); + }, + importCustomNodes( + nodeId: string, + nodeName: string, + importData: CustomNodeExportInterface, + options: CustomNodeImportOptions = { + reUuid: false, + }, + resultCallback?: ResultCallback + ): Promise { + return importCustomNodes({ + nodeId, + nodeName, + importData, + options, + resultCallback, + state, + }); + }, + deleteCustomNode( + nodeId?: string, + nodeName?: string + ): Promise { + return deleteCustomNode({ + nodeId, + nodeName, + state, + }); + }, + deleteCustomNodes( + resultCallback?: ResultCallback + ): Promise { + return deleteCustomNodes({ + resultCallback, + state, + }); + }, async findOrphanedNodes(): Promise { return findOrphanedNodes({ state }); }, @@ -189,6 +371,12 @@ export default (state: State): Node => { getNodeClassification(nodeType: string): NodeClassificationType[] { return getNodeClassification({ nodeType, state }); }, + getCustomNodeUsage(nodeId: string): Promise { + return getCustomNodeUsage({ + nodeId, + state, + }); + }, }; }; @@ -197,19 +385,30 @@ export interface NodeExportInterface { node: Record; } +export interface CustomNodeExportInterface { + meta?: ExportMetaData; + // Use nodeTypes since this is how AIC exports them + nodeTypes: Record; +} + /** - * Create an empty node export template - * @returns {NodeExportInterface} an empty node export template + * Custom node import options */ -export function createNodeExportTemplate({ - state, -}: { - state: State; -}): NodeExportInterface { - return { - meta: getMetadata({ state }), - node: {}, - }; +export interface CustomNodeImportOptions { + /** + * Generate new UUIDs and service names for all custom nodes during import. + */ + reUuid: boolean; +} + +/** + * Custom node export options + */ +export interface CustomNodeExportOptions { + /** + * Use string arrays to store script code + */ + useStringArrays: boolean; } export type NodeClassificationType = @@ -231,6 +430,36 @@ export enum NodeClassification { const containerNodes = ['PageNode', 'CustomPageNode']; +/** + * Create an empty node export template + * @returns {NodeExportInterface} an empty node export template + */ +export function createNodeExportTemplate({ + state, +}: { + state: State; +}): NodeExportInterface { + return { + meta: getMetadata({ state }), + node: {}, + }; +} + +/** + * Create an empty custom node export template + * @returns {CustomNodeExportInterface} an empty custom node export template + */ +export function createCustomNodeExportTemplate({ + state, +}: { + state: State; +}): CustomNodeExportInterface { + return { + meta: getMetadata({ state }), + nodeTypes: {}, + }; +} + /** * Read all node types * @returns {Promise} a promise that resolves to an array of node type objects @@ -433,6 +662,352 @@ export async function deleteNode({ } } +/** + * Read custom node. Either ID or name must be provided. + * @param {string} nodeId ID or service name of custom node. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. + * @returns {Promise} a promise that resolves to a custom node object + */ +export async function readCustomNode({ + nodeId, + nodeName, + state, +}: { + nodeId?: string; + nodeName?: string; + state: State; +}): Promise { + nodeId = getCustomNodeId(nodeId); + if (!nodeId && !nodeName) { + throw new FrodoError(`No custom node ID or display name provided.`); + } + try { + if (nodeId) { + return await getCustomNode({ nodeId, state }); + } + const nodes = await readCustomNodes({ state }); + for (const node of nodes) { + if (node.displayName === nodeName) { + return node; + } + } + throw new FrodoError(`Custom node '${nodeName}' not found`); + } catch (error) { + throw new FrodoError( + `Error reading custom node ${nodeName || nodeId}`, + error + ); + } +} + +/** + * Read all custom nodes + * @returns {Promise} a promise that resolves to an array of custom nodes objects + */ +export async function readCustomNodes({ + state, +}: { + state: State; +}): Promise { + try { + const { result } = await getCustomNodes({ state }); + return result; + } catch (error) { + throw new FrodoError(`Error reading custom nodes`, error); + } +} + +/** + * Export custom node. Either ID or name must be provided. + * @param {string} nodeId ID or service name of custom node. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. + * @param {CustomNodeExportOptions} options Custom node export options + * @returns {Promise} a promise that resolves to a custom node export object + */ +export async function exportCustomNode({ + nodeId, + nodeName, + options = { + useStringArrays: true, + }, + state, +}: { + nodeId?: string; + nodeName?: string; + options?: CustomNodeExportOptions; + state: State; +}): Promise { + nodeId = getCustomNodeId(nodeId); + if (!nodeId && !nodeName) { + throw new FrodoError(`No custom node ID or display name provided.`); + } + try { + debugMessage({ message: `NodeOps.exportCustomNode: start`, state }); + const exportData = createCustomNodeExportTemplate({ state }); + const node = await readCustomNode({ nodeId, nodeName, state }); + if (options.useStringArrays) { + node.script = (node.script as string).split('\n'); + } + exportData.nodeTypes[node._id] = node; + debugMessage({ message: `NodeOps.exportCustomNode: end`, state }); + return exportData; + } catch (error) { + throw new FrodoError( + `Error exporting custom node ${nodeName || nodeId}`, + error + ); + } +} + +/** + * Export all custom nodes + * @param {CustomNodeExportOptions} options Custom node export options + * @returns {Promise} a promise that resolves to a custom node export object + */ +export async function exportCustomNodes({ + options = { + useStringArrays: true, + }, + state, +}: { + options?: CustomNodeExportOptions; + state: State; +}): Promise { + let indicatorId: string; + try { + debugMessage({ message: `NodeOps.exportCustomNodes: start`, state }); + const exportData = createCustomNodeExportTemplate({ state }); + const nodes = await readCustomNodes({ state }); + indicatorId = createProgressIndicator({ + total: nodes.length, + message: 'Exporting custom nodes...', + state, + }); + for (const node of nodes) { + updateProgressIndicator({ + id: indicatorId, + message: `Exporting custom node ${node.displayName}`, + state, + }); + if (options.useStringArrays) { + node.script = (node.script as string).split('\n'); + } + exportData.nodeTypes[node._id] = node; + } + stopProgressIndicator({ + id: indicatorId, + message: `Exported ${nodes.length} custom nodes.`, + state, + }); + debugMessage({ message: `NodeOps.exportCustomNodes: end`, state }); + return exportData; + } catch (error) { + stopProgressIndicator({ + id: indicatorId, + message: `Error exporting custom nodes.`, + status: 'fail', + state, + }); + throw new FrodoError(`Error exporting custom nodes`, error); + } +} + +/** + * Update custom node by ID + * @param {string} nodeId ID or service name of custom node. + * @param {CustomNodeSkeleton} nodeData node object + * @returns {Promise} a promise that resolves to a custom node object + */ +export async function updateCustomNode({ + nodeId, + nodeData, + state, +}: { + nodeId: string; + nodeData: CustomNodeSkeleton; + state: State; +}): Promise { + nodeId = getCustomNodeId(nodeId); + let result = null; + try { + if (Array.isArray(nodeData.script)) { + nodeData.script = nodeData.script.join('\n'); + } + result = await putCustomNode({ nodeId, nodeData, state }); + } catch (error) { + if ( + error.response?.status === 409 && + error.response?.data.message.startsWith('Node Type with display name') && + error.response?.data.message.endsWith('already exists') + ) { + verboseMessage({ + message: `updateCustomNode WARNING: custom node with display name ${nodeData.displayName} already exists, using renaming policy... => `, + state, + }); + const newName = applyNameCollisionPolicy(nodeData.displayName); + nodeData.displayName = newName; + result = await updateCustomNode({ nodeId, nodeData, state }); + verboseMessage({ + message: `Saved custom node as ${newName}`, + state, + }); + } else { + throw new FrodoError(`Error updating custom node`, error); + } + } + return result; +} + +/** + * Import custom nodes + * @param {string} nodeId ID or service name of custom node. If supplied, only the custom node of that id is imported. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. If supplied, only the custom node of that name is imported + * @param {CustomNodeExportInterface} importData Custom node import data + * @param {CustomNodeImportOptions} options Custom node import options + * @param {ResultCallback} resultCallback Optional callback to process individual results + * @returns {Promise} the imported custom nodes + */ +export async function importCustomNodes({ + nodeId, + nodeName, + importData, + options = { + reUuid: false, + }, + resultCallback, + state, +}: { + nodeId?: string; + nodeName?: string; + importData: CustomNodeExportInterface; + options: CustomNodeImportOptions; + resultCallback?: ResultCallback; + state: State; +}): Promise { + nodeId = getCustomNodeId(nodeId); + debugMessage({ message: `NodeOps.importCustomNodes: start`, state }); + const response = []; + for (const existingId of Object.keys(importData.nodeTypes)) { + try { + const nodeData = importData.nodeTypes[existingId]; + const shouldNotImportCustomNode = + (nodeId && nodeId !== nodeData._id) || + (!nodeId && nodeName && nodeName !== nodeData.displayName); + if (shouldNotImportCustomNode) continue; + debugMessage({ + message: `NodeOps.importCustomNodes: Importing custom node ${nodeData.displayName} (${existingId})`, + state, + }); + let newId = existingId; + if (options.reUuid) { + newId = uuidv4().replaceAll('-', ''); + debugMessage({ + message: `NodeOps.importCustomNodes: Re-uuid-ing custom node ${nodeData.displayName} ${existingId} => ${newId}-1...`, + state, + }); + nodeData._id = newId + '-1'; + nodeData.serviceName = newId; + } + if (Array.isArray(nodeData.script)) + nodeData.script = nodeData.script.join('\n'); + // First attempt to create the node. If it fails, try updating it + let result; + try { + result = await createCustomNode({ nodeData, state }); + } catch (error) { + if (error.response?.status === 409) { + result = await updateCustomNode({ + nodeId: newId, + nodeData, + state, + }); + } else throw error; + } + if (resultCallback) { + resultCallback(undefined, result); + } + response.push(result); + } catch (e) { + if (resultCallback) { + resultCallback(e, undefined); + } else { + throw new FrodoError( + `Error importing custom node '${importData.nodeTypes[existingId].displayName}'`, + e + ); + } + } + } + debugMessage({ message: `NodeOps.importCustomNodes: end`, state }); + return response; +} + +/** + * Delete custom node. Either ID or name must be provided. + * @param {string} nodeId ID or service name of custom node. Takes priority over node display name if both are provided. + * @param {string} nodeName Display name of custom node. + * @returns {Promise} promise that resolves to a custom node object + */ +export async function deleteCustomNode({ + nodeId, + nodeName, + state, +}: { + nodeId?: string; + nodeName?: string; + state: State; +}): Promise { + nodeId = getCustomNodeId(nodeId); + if (!nodeId && !nodeName) { + throw new FrodoError(`No custom node ID or display name provided.`); + } + try { + let id = nodeId; + if (!id) { + const node = await readCustomNode({ nodeId, nodeName, state }); + id = node._id; + } + return await _deleteCustomNode({ nodeId: id, state }); + } catch (error) { + throw new FrodoError( + `Error deleting custom node ${nodeName || nodeId}`, + error + ); + } +} + +/** + * Delete custom nodes + * @param {ResultCallback} resultCallback Optional callback to process individual results + * @returns {Promise} promise that resolves to an array of custom node objects + */ +export async function deleteCustomNodes({ + resultCallback, + state, +}: { + resultCallback: ResultCallback; + state: State; +}): Promise { + const nodes = await readCustomNodes({ state }); + const deletedNodes = []; + for (const node of nodes) { + const result: CustomNodeSkeleton = await getResult( + resultCallback, + `Error deleting custom node ${node.displayName}`, + deleteCustomNode, + { + nodeId: node._id, + nodeName: node.displayName, + state, + } + ); + if (result) { + deletedNodes.push(result); + } + } + return deletedNodes; +} + /** * Find all node configuration objects that are no longer referenced by any tree * @returns {Promise} a promise that resolves to an array of orphaned nodes @@ -1068,3 +1643,34 @@ export function getNodeClassification({ if (deprecated) classifications.push(NodeClassification.DEPRECATED); return classifications; } + +/** + * Get custom node usage by ID + * @param {String} nodeId ID or service name of the custom node + * @returns {Promise} a promise that resolves to an object containing a custom node usage object + */ +export async function getCustomNodeUsage({ + nodeId, + state, +}: { + nodeId: string; + state: State; +}): Promise { + try { + return await _getCustomNodeUsage({ + nodeId: getCustomNodeId(nodeId), + state, + }); + } catch (error) { + throw new FrodoError(`Error getting custom node usage`, error); + } +} + +/** + * Helper that normalized a service name to custom node id if needed + * @param nodeId The custom node id or service name + * @returns nodeId if falsey or in id format, otherwise returns nodeId in id format + */ +export function getCustomNodeId(nodeId?: string): string | undefined | null { + return !nodeId || nodeId.endsWith('-1') ? nodeId : nodeId + '-1'; +} diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/10-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_490542302/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/10-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_490542302/recording.har index bf7f4378c..6b08b8180 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/10-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_490542302/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/10-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_490542302/recording.har @@ -7,6 +7,142 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "703e628077d09ac9e51694a7730d95f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-5dfc921d-a89d-4d72-a1ad-1a9fd7abf0b5" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "cookie", + "value": "iPlanetDirectoryPro=" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.classic.com:8080" + } + ], + "headersSize": 568, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "http://openam-frodo-dev.classic.com:8080/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33585, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33585, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"296916566\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"764229896\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1484382943\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"419010643\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"745481489\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"390387834\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"733279755\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 18:53:42 GMT" + }, + { + "name": "keep-alive", + "value": "timeout=20" + }, + { + "name": "connection", + "value": "keep-alive" + } + ], + "headersSize": 499, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T18:53:42.981Z", + "time": 7, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 7 + } + }, { "_id": "eb697468085abfef6b608e5d514d9750", "_order": 0, diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/6-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-an_163529349/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/6-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-an_163529349/recording.har index f71dcc083..d78c24062 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/6-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-an_163529349/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/6-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-an_163529349/recording.har @@ -7,6 +7,142 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "703e628077d09ac9e51694a7730d95f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-5dfc921d-a89d-4d72-a1ad-1a9fd7abf0b5" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "cookie", + "value": "iPlanetDirectoryPro=" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.classic.com:8080" + } + ], + "headersSize": 568, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "http://openam-frodo-dev.classic.com:8080/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33585, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33585, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"296916566\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"764229896\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1484382943\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"419010643\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"745481489\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"390387834\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"733279755\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 18:53:42 GMT" + }, + { + "name": "keep-alive", + "value": "timeout=20" + }, + { + "name": "connection", + "value": "keep-alive" + } + ], + "headersSize": 499, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T18:53:42.981Z", + "time": 7, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 7 + } + }, { "_id": "eb697468085abfef6b608e5d514d9750", "_order": 0, diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/7-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3985776396/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/7-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3985776396/recording.har index 055631f4d..4d6ccea11 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/7-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3985776396/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/7-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3985776396/recording.har @@ -7,6 +7,142 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "703e628077d09ac9e51694a7730d95f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-5dfc921d-a89d-4d72-a1ad-1a9fd7abf0b5" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "cookie", + "value": "iPlanetDirectoryPro=" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.classic.com:8080" + } + ], + "headersSize": 568, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "http://openam-frodo-dev.classic.com:8080/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33585, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33585, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"296916566\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"764229896\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1484382943\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"419010643\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"745481489\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"390387834\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"733279755\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 18:53:42 GMT" + }, + { + "name": "keep-alive", + "value": "timeout=20" + }, + { + "name": "connection", + "value": "keep-alive" + } + ], + "headersSize": 499, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T18:53:42.981Z", + "time": 7, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 7 + } + }, { "_id": "eb697468085abfef6b608e5d514d9750", "_order": 0, diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/8-Export-only-importable-with-string-arrays-decoding-variables-including-journey-coordina_1978519911/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/8-Export-only-importable-with-string-arrays-decoding-variables-including-journey-coordina_1978519911/recording.har index b0333faed..6ff4547d1 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/8-Export-only-importable-with-string-arrays-decoding-variables-including-journey-coordina_1978519911/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Classic-Tests_743483830/exportFullConfiguration_221463303/8-Export-only-importable-with-string-arrays-decoding-variables-including-journey-coordina_1978519911/recording.har @@ -7,6 +7,142 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "703e628077d09ac9e51694a7730d95f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-5dfc921d-a89d-4d72-a1ad-1a9fd7abf0b5" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "cookie", + "value": "iPlanetDirectoryPro=" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.classic.com:8080" + } + ], + "headersSize": 568, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "http://openam-frodo-dev.classic.com:8080/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33585, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33585, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"296916566\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"764229896\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1484382943\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"419010643\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"745481489\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"390387834\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"733279755\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "transfer-encoding", + "value": "chunked" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 18:53:42 GMT" + }, + { + "name": "keep-alive", + "value": "timeout=20" + }, + { + "name": "connection", + "value": "keep-alive" + } + ], + "headersSize": 499, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T18:53:42.981Z", + "time": 7, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 7 + } + }, { "_id": "eb697468085abfef6b608e5d514d9750", "_order": 0, diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/1-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-a_2200088734/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/1-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-a_2200088734/recording.har index ce6d1f04a..7b530e91c 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/1-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-a_2200088734/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/1-Export-everything-with-string-arrays-decoding-variables-including-journey-coordinates-a_2200088734/recording.har @@ -7,6 +7,154 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33589, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33589, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"855360523\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"-2070743967\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1859562163\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"309311416\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"705045404\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"-1749152606\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"957146401\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 19:01:08 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T19:01:08.716Z", + "time": 91, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 91 + } + }, { "_id": "fc71be44855f4e764537c68893e9a626", "_order": 0, diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/2-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3883162875/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/2-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3883162875/recording.har index f32264cb1..7f9f4ecf7 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/2-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3883162875/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/2-Export-everything-without-string-arrays-decoding-variables-excluding-journey-coordinate_3883162875/recording.har @@ -7,6 +7,154 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33589, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33589, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"855360523\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"-2070743967\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1859562163\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"309311416\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"705045404\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"-1749152606\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"957146401\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 19:01:08 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T19:01:08.716Z", + "time": 91, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 91 + } + }, { "_id": "fc71be44855f4e764537c68893e9a626", "_order": 0, diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/3-Export-only-importable-config-with-string-arrays-decoding-variables-including-journey-c_2747516410/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/3-Export-only-importable-config-with-string-arrays-decoding-variables-including-journey-c_2747516410/recording.har index f4174f16a..cb766f52a 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/3-Export-only-importable-config-with-string-arrays-decoding-variables-including-journey-c_2747516410/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/3-Export-only-importable-config-with-string-arrays-decoding-variables-including-journey-c_2747516410/recording.har @@ -7,6 +7,154 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33589, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33589, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"855360523\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"-2070743967\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1859562163\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"309311416\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"705045404\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"-1749152606\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"957146401\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 19:01:08 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T19:01:08.716Z", + "time": 91, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 91 + } + }, { "_id": "fc71be44855f4e764537c68893e9a626", "_order": 0, diff --git a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/5-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_3002604266/recording.har b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/5-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_3002604266/recording.har index 0babc7ecd..c93a7ae63 100644 --- a/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/5-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_3002604266/recording.har +++ b/src/test/mock-recordings/ConfigOps_2138586609/Cloud-Tests_2178067211/exportFullConfiguration_221463303/5-Export-only-global-config-with-string-arrays-decoding-variables-including-journey-coord_3002604266/recording.har @@ -7,6 +7,154 @@ "version": "6.0.6" }, "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 33589, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 33589, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"855360523\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"-2070743967\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\\n\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"1859562163\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"309311416\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"session-1\",\"_rev\":\"705045404\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"-1749152606\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"957146401\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}],\"resultCount\":7,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":7,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 19:01:08 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-187b32ff-6faf-4b8f-bdd3-d691defc688e" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T19:01:08.716Z", + "time": 91, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 91 + } + }, { "_id": "fc71be44855f4e764537c68893e9a626", "_order": 0, diff --git a/src/test/mock-recordings/JourneyOps_2291468013/exportJourney_2045999962/4-Export-journey-FrodoTestJourney12-w_3945220971/custom-node-dependencies_2882997917/recording.har b/src/test/mock-recordings/JourneyOps_2291468013/exportJourney_2045999962/4-Export-journey-FrodoTestJourney12-w_3945220971/custom-node-dependencies_2882997917/recording.har new file mode 100644 index 000000000..1d80a3f91 --- /dev/null +++ b/src/test/mock-recordings/JourneyOps_2291468013/exportJourney_2045999962/4-Export-journey-FrodoTestJourney12-w_3945220971/custom-node-dependencies_2882997917/recording.har @@ -0,0 +1,2418 @@ +{ + "log": { + "_recordingName": "JourneyOps/exportJourney()/4: Export journey 'FrodoTestJourney12' w/ custom node dependencies", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "56e928cb309b791301a1454f7c6de722", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2005, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/FrodoTestJourney12" + }, + "response": { + "bodySize": 1172, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1172, + "text": "{\"_id\":\"FrodoTestJourney12\",\"_rev\":\"-268378089\",\"identityResource\":\"managed/alpha_user\",\"entryNodeId\":\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\",\"innerTreeOnly\":false,\"description\":\"Test journey for custom nodes\",\"noSession\":false,\"mustRun\":false,\"enabled\":true,\"transactionalOnly\":false,\"uiConfig\":{\"categories\":\"[]\",\"annotations\":\"{\\\"forNodes\\\":{},\\\"structural\\\":[]}\"},\"nodes\":{\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\":{\"x\":463,\"y\":80,\"connections\":{\"outcome\":\"461a364c-5884-44f6-87d9-ae749cc08f24\"},\"nodeType\":\"PageNode\",\"displayName\":\"Login Page\"},\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\":{\"x\":210,\"y\":161,\"connections\":{\"True\":\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\",\"False\":\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\"},\"nodeType\":\"designer-session\",\"displayName\":\"Has Session AM\"},\"461a364c-5884-44f6-87d9-ae749cc08f24\":{\"x\":734,\"y\":161,\"connections\":{\"true\":\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\",\"false\":\"e301438c-0bd0-429c-ab0c-66126501069a\"},\"nodeType\":\"DataStoreDecisionNode\",\"displayName\":\"Data Store Decision\"}},\"staticNodes\":{\"startNode\":{\"x\":70,\"y\":188},\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\":{\"x\":1014,\"y\":102},\"e301438c-0bd0-429c-ab0c-66126501069a\":{\"x\":1014,\"y\":241}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-268378089\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1172" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 752, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:25.984Z", + "time": 109, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 109 + } + }, + { + "_id": "8491b762ea9e0d6de34b91e8d5d97a4d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1881, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/openidm/config/ui/themerealm" + }, + "response": { + "bodySize": 84421, + "content": { + "mimeType": "application/json;charset=utf-8", + "size": 84421, + "text": "{\"_id\":\"ui/themerealm\",\"realm\":{\"alpha\":[{\"_id\":\"abb4efed-ae70-4064-91a7-936be552d6fc\",\"accountFooter\":\"\",\"accountFooterEnabled\":false,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#000000\",\"buttonRounded\":\"0\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\",\"journeyFooterEnabled\":false,\"journeyHeader\":\"
Header Content
\",\"journeyHeaderEnabled\":false,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":false,\"journeyLayout\":\"card\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#000000\",\"linkColor\":\"#000000\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/contrast/logo-contrast.svg\",\"logoAltText\":\"Contrast\",\"logoEnabled\":true,\"logoHeight\":\"72\",\"logoProfile\":\"data:image/svg+xml,%0A%3Csvg width='46' height='46' viewBox='0 0 46 46' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M24.3477 13.5664H43.9438C43.5192 12.6317 43.0319 11.734 42.4905 10.8711H24.3477V13.5664Z' fill='black'/%3E%3Cpath d='M24.3477 8.17578H40.5261C39.6996 7.2052 38.7974 6.30182 37.8224 5.48047H24.3477V8.17578Z' fill='black'/%3E%3Cpath d='M24.3477 40.5195H37.8224C38.7975 39.6982 39.6996 38.7948 40.5261 37.8242H24.3477V40.5195Z' fill='black'/%3E%3Cpath d='M24.3477 2.78516H33.8482C31.0136 1.27039 27.7313 0.198195 24.3477 0V2.78516Z' fill='black'/%3E%3Cpath d='M24.3477 18.957H45.6208C45.4566 18.0405 45.2557 17.1372 44.9856 16.2617H24.3477V18.957Z' fill='black'/%3E%3Cpath d='M24.3477 21.6523V24.3477H45.9317C45.958 23.8992 46 23.4549 46 23C46 22.5451 45.958 22.1008 45.9317 21.6523H24.3477Z' fill='black'/%3E%3Cpath d='M0 23C0 35.1781 9.64778 45.2964 21.6523 46V0C9.64778 0.703566 0 10.8219 0 23Z' fill='black'/%3E%3Cpath d='M24.3477 46C27.7313 45.8018 31.0136 44.7296 33.8482 43.2148H24.3477V46Z' fill='black'/%3E%3Cpath d='M45.6208 27.043H24.3477V29.7383H44.9857C45.2557 28.8628 45.4566 27.9595 45.6208 27.043V27.043Z' fill='black'/%3E%3Cpath d='M24.3477 35.1289H42.4905C43.0319 34.266 43.5192 33.3683 43.9438 32.4336H24.3477V35.1289Z' fill='black'/%3E%3C/svg%3E%0A\",\"logoProfileAltText\":\"Contrast\",\"logoProfileCollapsed\":\"data:image/svg+xml,%0A%3Csvg width='46' height='46' viewBox='0 0 46 46' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M24.3477 13.5664H43.9438C43.5192 12.6317 43.0319 11.734 42.4905 10.8711H24.3477V13.5664Z' fill='black'/%3E%3Cpath d='M24.3477 8.17578H40.5261C39.6996 7.2052 38.7974 6.30182 37.8224 5.48047H24.3477V8.17578Z' fill='black'/%3E%3Cpath d='M24.3477 40.5195H37.8224C38.7975 39.6982 39.6996 38.7948 40.5261 37.8242H24.3477V40.5195Z' fill='black'/%3E%3Cpath d='M24.3477 2.78516H33.8482C31.0136 1.27039 27.7313 0.198195 24.3477 0V2.78516Z' fill='black'/%3E%3Cpath d='M24.3477 18.957H45.6208C45.4566 18.0405 45.2557 17.1372 44.9856 16.2617H24.3477V18.957Z' fill='black'/%3E%3Cpath d='M24.3477 21.6523V24.3477H45.9317C45.958 23.8992 46 23.4549 46 23C46 22.5451 45.958 22.1008 45.9317 21.6523H24.3477Z' fill='black'/%3E%3Cpath d='M0 23C0 35.1781 9.64778 45.2964 21.6523 46V0C9.64778 0.703566 0 10.8219 0 23Z' fill='black'/%3E%3Cpath d='M24.3477 46C27.7313 45.8018 31.0136 44.7296 33.8482 43.2148H24.3477V46Z' fill='black'/%3E%3Cpath d='M45.6208 27.043H24.3477V29.7383H44.9857C45.2557 28.8628 45.4566 27.9595 45.6208 27.043V27.043Z' fill='black'/%3E%3Cpath d='M24.3477 35.1289H42.4905C43.0319 34.266 43.5192 33.3683 43.9438 32.4336H24.3477V35.1289Z' fill='black'/%3E%3C/svg%3E%0A\",\"logoProfileCollapsedAltText\":\"\",\"logoProfileCollapsedHeight\":\"22\",\"logoProfileHeight\":\"22\",\"name\":\"Contrast\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#000000\",\"primaryOffColor\":\"#000000\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#000000\",\"profileMenuTextHighlightColor\":\"#455469\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"72ef4fcb-aae2-4c78-a050-d0e373c6a175\",\"accountFooter\":\"\\n\",\"accountFooterEnabled\":true,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#5E6D82\",\"buttonRounded\":\"50\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\\n\\n\",\"journeyFooterEnabled\":true,\"journeyHeader\":\"
\\n \\n \\n \\n \\n \\n
    \\n
  • \\n Link\\n
  • \\n
  • \\n Disabled\\n
  • \\n
\\n
    \\n
  • \\n Link\\n
  • \\n
\\n \\n \\n
\\n\",\"journeyHeaderEnabled\":true,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":false,\"journeyLayout\":\"card\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#C60819\",\"linkColor\":\"#EB0A1E\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-icon.svg\",\"logoAltText\":\"\",\"logoEnabled\":true,\"logoHeight\":\"40\",\"logoProfile\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-full.svg\",\"logoProfileAltText\":\"Highlander\",\"logoProfileCollapsed\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-icon.svg\",\"logoProfileCollapsedAltText\":\"Highlander\",\"logoProfileCollapsedHeight\":\"28\",\"logoProfileHeight\":\"28\",\"name\":\"Highlander\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#EB0A1E\",\"primaryOffColor\":\"#C60819\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#455469\",\"profileMenuTextHighlightColor\":\"#EB0A1E\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"8e756273-9dbb-42dd-babe-52912336ea3d\",\"accountFooter\":\"\\n\",\"accountFooterEnabled\":true,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#5E6D82\",\"buttonRounded\":\"50\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\\n\",\"journeyFooterEnabled\":true,\"journeyHeader\":\"
\\n \\n \\n \\n \\n \\n
    \\n
  • \\n Link\\n
  • \\n
  • \\n Disabled\\n
  • \\n
\\n
    \\n
  • \\n Link\\n
  • \\n
\\n \\n \\n
\\n\",\"journeyHeaderEnabled\":true,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":true,\"journeyLayout\":\"justified-right\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#49871E\",\"linkColor\":\"#5AA625\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/robroy/logo-robroy-icon.svg\",\"logoAltText\":\"\",\"logoEnabled\":true,\"logoHeight\":\"40\",\"logoProfile\":\"data:image/svg+xml,%0A%3Csvg width='156' height='34' viewBox='0 0 156 34' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cpath d='M32.5539 32.5538C32.5539 32.5538 17.0796 35.6024 7.23861 25.7614C-2.60242 15.9204 0.446148 0.446137 0.446148 0.446137C0.446148 0.446137 15.9204 -2.60243 25.7614 7.23866C35.6024 17.0797 32.5539 32.5538 32.5539 32.5538Z' fill='%23C3EA21'/%3E%3Cpath d='M32.5537 32.554C32.5537 32.554 17.0795 35.6026 7.23845 25.7615C-2.60257 15.9205 0.445995 0.446289 0.445995 0.446289L32.5537 32.554Z' fill='%238ADB53'/%3E%3C/g%3E%3Cpath d='M51.053 25.38L53.186 25.11V8.964L51.161 8.586V6.939H55.076C55.418 6.939 55.796 6.93 56.21 6.912C56.624 6.894 56.939 6.876 57.155 6.858C58.091 6.786 58.865 6.75 59.477 6.75C61.331 6.75 62.816 6.939 63.932 7.317C65.048 7.695 65.858 8.271 66.362 9.045C66.866 9.819 67.118 10.836 67.118 12.096C67.118 13.338 66.785 14.49 66.119 15.552C65.453 16.614 64.49 17.343 63.23 17.739C63.95 18.045 64.589 18.603 65.147 19.413C65.705 20.223 66.299 21.276 66.929 22.572C67.379 23.454 67.721 24.093 67.955 24.489C68.207 24.867 68.45 25.083 68.684 25.137L69.575 25.407V27H64.985C64.697 27 64.391 26.712 64.067 26.136C63.761 25.542 63.356 24.615 62.852 23.355C62.258 21.879 61.745 20.727 61.313 19.899C60.881 19.071 60.422 18.558 59.936 18.36H57.155V25.11L59.639 25.38V27H51.053V25.38ZM59.639 16.713C60.665 16.713 61.466 16.344 62.042 15.606C62.618 14.868 62.906 13.761 62.906 12.285C62.906 10.971 62.618 9.999 62.042 9.369C61.484 8.739 60.512 8.424 59.126 8.424C58.622 8.424 58.19 8.451 57.83 8.505C57.488 8.541 57.263 8.559 57.155 8.559V16.659C57.371 16.695 57.893 16.713 58.721 16.713H59.639ZM70.674 19.521C70.674 17.829 71.007 16.389 71.673 15.201C72.357 14.013 73.266 13.122 74.4 12.528C75.534 11.916 76.767 11.61 78.099 11.61C80.367 11.61 82.113 12.312 83.337 13.716C84.579 15.102 85.2 16.992 85.2 19.386C85.2 21.096 84.858 22.554 84.174 23.76C83.508 24.948 82.608 25.839 81.474 26.433C80.358 27.009 79.125 27.297 77.775 27.297C75.525 27.297 73.779 26.604 72.537 25.218C71.295 23.814 70.674 21.915 70.674 19.521ZM77.991 25.542C80.025 25.542 81.042 23.58 81.042 19.656C81.042 17.604 80.799 16.047 80.313 14.985C79.827 13.905 79.035 13.365 77.937 13.365C75.849 13.365 74.805 15.327 74.805 19.251C74.805 21.303 75.057 22.869 75.561 23.949C76.083 25.011 76.893 25.542 77.991 25.542ZM86.4395 5.454L91.3805 4.86H91.4345L92.1905 5.373V13.338C92.6765 12.852 93.2705 12.447 93.9725 12.123C94.6925 11.781 95.4665 11.61 96.2945 11.61C98.0225 11.61 99.4265 12.222 100.506 13.446C101.604 14.652 102.153 16.506 102.153 19.008C102.153 20.556 101.829 21.96 101.181 23.22C100.533 24.48 99.5975 25.479 98.3735 26.217C97.1675 26.937 95.7635 27.297 94.1615 27.297C92.7395 27.297 91.5065 27.18 90.4625 26.946C89.4185 26.694 88.7525 26.469 88.4645 26.271V7.182L86.4395 6.858V5.454ZM94.8635 13.986C94.3235 13.986 93.8105 14.112 93.3245 14.364C92.8565 14.598 92.4785 14.868 92.1905 15.174V25.029C92.2985 25.227 92.5505 25.389 92.9465 25.515C93.3425 25.641 93.7925 25.704 94.2965 25.704C95.4485 25.704 96.3665 25.173 97.0505 24.111C97.7525 23.031 98.1035 21.438 98.1035 19.332C98.1035 17.514 97.8065 16.173 97.2125 15.309C96.6185 14.427 95.8355 13.986 94.8635 13.986Z' fill='black'/%3E%3Cpath d='M104.183 25.38L106.316 25.11V8.964L104.291 8.586V6.939H108.206C108.548 6.939 108.926 6.93 109.34 6.912C109.754 6.894 110.069 6.876 110.285 6.858C111.221 6.786 111.995 6.75 112.607 6.75C114.461 6.75 115.946 6.939 117.062 7.317C118.178 7.695 118.988 8.271 119.492 9.045C119.996 9.819 120.248 10.836 120.248 12.096C120.248 13.338 119.915 14.49 119.249 15.552C118.583 16.614 117.62 17.343 116.36 17.739C117.08 18.045 117.719 18.603 118.277 19.413C118.835 20.223 119.429 21.276 120.059 22.572C120.509 23.454 120.851 24.093 121.085 24.489C121.337 24.867 121.58 25.083 121.814 25.137L122.705 25.407V27H118.115C117.827 27 117.521 26.712 117.197 26.136C116.891 25.542 116.486 24.615 115.982 23.355C115.388 21.879 114.875 20.727 114.443 19.899C114.011 19.071 113.552 18.558 113.066 18.36H110.285V25.11L112.769 25.38V27H104.183V25.38ZM112.769 16.713C113.795 16.713 114.596 16.344 115.172 15.606C115.748 14.868 116.036 13.761 116.036 12.285C116.036 10.971 115.748 9.999 115.172 9.369C114.614 8.739 113.642 8.424 112.256 8.424C111.752 8.424 111.32 8.451 110.96 8.505C110.618 8.541 110.393 8.559 110.285 8.559V16.659C110.501 16.695 111.023 16.713 111.851 16.713H112.769ZM123.804 19.521C123.804 17.829 124.137 16.389 124.803 15.201C125.487 14.013 126.396 13.122 127.53 12.528C128.664 11.916 129.897 11.61 131.229 11.61C133.497 11.61 135.243 12.312 136.467 13.716C137.709 15.102 138.33 16.992 138.33 19.386C138.33 21.096 137.988 22.554 137.304 23.76C136.638 24.948 135.738 25.839 134.604 26.433C133.488 27.009 132.255 27.297 130.905 27.297C128.655 27.297 126.909 26.604 125.667 25.218C124.425 23.814 123.804 21.915 123.804 19.521ZM131.121 25.542C133.155 25.542 134.172 23.58 134.172 19.656C134.172 17.604 133.929 16.047 133.443 14.985C132.957 13.905 132.165 13.365 131.067 13.365C128.979 13.365 127.935 15.327 127.935 19.251C127.935 21.303 128.187 22.869 128.691 23.949C129.213 25.011 130.023 25.542 131.121 25.542ZM143.187 33.723C142.863 33.723 142.512 33.696 142.134 33.642C141.774 33.588 141.513 33.525 141.351 33.453V30.564C141.477 30.636 141.729 30.708 142.107 30.78C142.485 30.852 142.827 30.888 143.133 30.888C144.033 30.888 144.771 30.591 145.347 29.997C145.941 29.403 146.49 28.404 146.994 27H145.536L140.46 13.905L139.245 13.554V11.988H146.67V13.554L144.699 13.878L147.102 21.357L148.074 24.543L148.911 21.357L151.125 13.878L149.424 13.554V11.988H155.283V13.554L153.96 13.878C152.97 16.902 151.989 19.818 151.017 22.626C150.045 25.434 149.478 27.009 149.316 27.351C148.74 28.863 148.191 30.069 147.669 30.969C147.147 31.869 146.526 32.553 145.806 33.021C145.086 33.489 144.213 33.723 143.187 33.723Z' fill='%236CBE34'/%3E%3Cdefs%3E%3CclipPath id='clip0'%3E%3Crect width='33' height='33' fill='white' transform='matrix(-1 0 0 1 33 0)'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A\",\"logoProfileAltText\":\"RobRoy\",\"logoProfileCollapsed\":\"data:image/svg+xml,%0A%3Csvg width='33' height='33' viewBox='0 0 33 33' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cpath d='M32.5539 32.5538C32.5539 32.5538 17.0796 35.6024 7.23861 25.7614C-2.60242 15.9204 0.446148 0.446137 0.446148 0.446137C0.446148 0.446137 15.9204 -2.60243 25.7614 7.23866C35.6024 17.0797 32.5539 32.5538 32.5539 32.5538Z' fill='%23C3EA21'/%3E%3Cpath d='M32.5537 32.554C32.5537 32.554 17.0795 35.6026 7.23845 25.7615C-2.60257 15.9205 0.445996 0.446289 0.445996 0.446289L32.5537 32.554Z' fill='%238ADB53'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0'%3E%3Crect width='33' height='33' fill='white' transform='matrix(-1 0 0 1 33 0)'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A\",\"logoProfileCollapsedAltText\":\"RobRoy\",\"logoProfileCollapsedHeight\":\"28\",\"logoProfileHeight\":\"28\",\"name\":\"Robroy\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#5AA625\",\"primaryOffColor\":\"#49871E\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#455469\",\"profileMenuTextHighlightColor\":\"#5AA625\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"33b89c09-2a29-4e9b-9e2b-12fd7e1c7466\",\"accountFooter\":\"\",\"accountFooterEnabled\":false,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#324054\",\"backgroundImage\":\"\",\"bodyText\":\"#23282e\",\"buttonRounded\":5,\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":true,\"journeyFooter\":\"\",\"journeyFooterEnabled\":false,\"journeyHeader\":\"
Header Content
\",\"journeyHeaderEnabled\":false,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":false,\"journeyLayout\":\"card\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#0c85cf\",\"linkColor\":\"#109cf1\",\"linkedTrees\":[],\"logo\":\"\",\"logoAltText\":\"\",\"logoHeight\":\"40\",\"logoProfile\":\"\",\"logoProfileAltText\":\"\",\"logoProfileCollapsed\":\"\",\"logoProfileCollapsedAltText\":\"\",\"logoProfileCollapsedHeight\":\"40\",\"logoProfileHeight\":\"40\",\"name\":\"Starter Theme\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#324054\",\"primaryOffColor\":\"#242E3C\",\"profileBackgroundColor\":\"#f6f8fa\",\"profileMenuHighlightColor\":\"#f3f5f8\",\"profileMenuHoverColor\":\"#324054\",\"profileMenuHoverTextColor\":\"#ffffff\",\"profileMenuTextHighlightColor\":\"#455469\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"8ee2e08a-db04-4a16-b3d9-6f52c9aee5cb\",\"accountFooter\":\"\\n\",\"accountFooterEnabled\":true,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#5E6D82\",\"buttonRounded\":\"50\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\\n\",\"journeyFooterEnabled\":true,\"journeyHeader\":\"
Header Content
\",\"journeyHeaderEnabled\":false,\"journeyJustifiedContent\":\"
\\n

Uptime & Performance Benchmarking Made Easy

\\n
\\n\\n\",\"journeyJustifiedContentEnabled\":true,\"journeyLayout\":\"justified-right\",\"journeyTheaterMode\":true,\"linkActiveColor\":\"#007661\",\"linkColor\":\"#009C80\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/zardoz/logo-zardoz.svg\",\"logoAltText\":\"Zardoz Logo\",\"logoEnabled\":true,\"logoHeight\":\"47\",\"logoProfile\":\"https://cdn.forgerock.com/platform/themes/zardoz/logo-zardoz.svg\",\"logoProfileAltText\":\"Zardaz Logo\",\"logoProfileCollapsed\":\"https://cdn.forgerock.com/platform/themes/zardoz/logo-zardoz.svg\",\"logoProfileCollapsedAltText\":\"Zardaz Logo\",\"logoProfileCollapsedHeight\":\"28\",\"logoProfileHeight\":\"40\",\"name\":\"Zardoz\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#009C80\",\"primaryOffColor\":\"#007661\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#455469\",\"profileMenuTextHighlightColor\":\"#009C80\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"00203891-dde0-4114-b27a-219ae0b43a61\",\"accountFooter\":\"\\n\",\"accountFooterEnabled\":true,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#5E6D82\",\"buttonRounded\":\"50\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\\n\\n\",\"journeyFooterEnabled\":true,\"journeyHeader\":\"
\\n \\n \\n \\n \\n \\n
    \\n
  • \\n Link\\n
  • \\n
  • \\n Disabled\\n
  • \\n
\\n
    \\n
  • \\n Link\\n
  • \\n
\\n \\n \\n
\\n\",\"journeyHeaderEnabled\":true,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":false,\"journeyLayout\":\"card\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#C60819\",\"linkColor\":\"#EB0A1E\",\"linkedTrees\":[],\"logo\":\"\",\"logoAltText\":\"\",\"logoEnabled\":true,\"logoHeight\":\"40\",\"logoProfile\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-full.svg\",\"logoProfileAltText\":\"Highlander\",\"logoProfileCollapsed\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-icon.svg\",\"logoProfileCollapsedAltText\":\"Highlander\",\"logoProfileCollapsedHeight\":\"28\",\"logoProfileHeight\":\"28\",\"name\":\"Highlander\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#EB0A1E\",\"primaryOffColor\":\"#C60819\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#455469\",\"profileMenuTextHighlightColor\":\"#EB0A1E\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"}],\"bravo\":[{\"_id\":\"bf4828bd-6e24-41ba-8773-0a4a349399d3\",\"accountFooter\":\"\",\"accountFooterEnabled\":false,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#000000\",\"buttonRounded\":\"0\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\",\"journeyFooterEnabled\":false,\"journeyHeader\":\"
Header Content
\",\"journeyHeaderEnabled\":false,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":false,\"journeyLayout\":\"card\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#000000\",\"linkColor\":\"#000000\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/contrast/logo-contrast.svg\",\"logoAltText\":\"Contrast\",\"logoEnabled\":true,\"logoHeight\":\"72\",\"logoProfile\":\"data:image/svg+xml,%0A%3Csvg width='46' height='46' viewBox='0 0 46 46' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M24.3477 13.5664H43.9438C43.5192 12.6317 43.0319 11.734 42.4905 10.8711H24.3477V13.5664Z' fill='black'/%3E%3Cpath d='M24.3477 8.17578H40.5261C39.6996 7.2052 38.7974 6.30182 37.8224 5.48047H24.3477V8.17578Z' fill='black'/%3E%3Cpath d='M24.3477 40.5195H37.8224C38.7975 39.6982 39.6996 38.7948 40.5261 37.8242H24.3477V40.5195Z' fill='black'/%3E%3Cpath d='M24.3477 2.78516H33.8482C31.0136 1.27039 27.7313 0.198195 24.3477 0V2.78516Z' fill='black'/%3E%3Cpath d='M24.3477 18.957H45.6208C45.4566 18.0405 45.2557 17.1372 44.9856 16.2617H24.3477V18.957Z' fill='black'/%3E%3Cpath d='M24.3477 21.6523V24.3477H45.9317C45.958 23.8992 46 23.4549 46 23C46 22.5451 45.958 22.1008 45.9317 21.6523H24.3477Z' fill='black'/%3E%3Cpath d='M0 23C0 35.1781 9.64778 45.2964 21.6523 46V0C9.64778 0.703566 0 10.8219 0 23Z' fill='black'/%3E%3Cpath d='M24.3477 46C27.7313 45.8018 31.0136 44.7296 33.8482 43.2148H24.3477V46Z' fill='black'/%3E%3Cpath d='M45.6208 27.043H24.3477V29.7383H44.9857C45.2557 28.8628 45.4566 27.9595 45.6208 27.043V27.043Z' fill='black'/%3E%3Cpath d='M24.3477 35.1289H42.4905C43.0319 34.266 43.5192 33.3683 43.9438 32.4336H24.3477V35.1289Z' fill='black'/%3E%3C/svg%3E%0A\",\"logoProfileAltText\":\"Contrast\",\"logoProfileCollapsed\":\"data:image/svg+xml,%0A%3Csvg width='46' height='46' viewBox='0 0 46 46' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M24.3477 13.5664H43.9438C43.5192 12.6317 43.0319 11.734 42.4905 10.8711H24.3477V13.5664Z' fill='black'/%3E%3Cpath d='M24.3477 8.17578H40.5261C39.6996 7.2052 38.7974 6.30182 37.8224 5.48047H24.3477V8.17578Z' fill='black'/%3E%3Cpath d='M24.3477 40.5195H37.8224C38.7975 39.6982 39.6996 38.7948 40.5261 37.8242H24.3477V40.5195Z' fill='black'/%3E%3Cpath d='M24.3477 2.78516H33.8482C31.0136 1.27039 27.7313 0.198195 24.3477 0V2.78516Z' fill='black'/%3E%3Cpath d='M24.3477 18.957H45.6208C45.4566 18.0405 45.2557 17.1372 44.9856 16.2617H24.3477V18.957Z' fill='black'/%3E%3Cpath d='M24.3477 21.6523V24.3477H45.9317C45.958 23.8992 46 23.4549 46 23C46 22.5451 45.958 22.1008 45.9317 21.6523H24.3477Z' fill='black'/%3E%3Cpath d='M0 23C0 35.1781 9.64778 45.2964 21.6523 46V0C9.64778 0.703566 0 10.8219 0 23Z' fill='black'/%3E%3Cpath d='M24.3477 46C27.7313 45.8018 31.0136 44.7296 33.8482 43.2148H24.3477V46Z' fill='black'/%3E%3Cpath d='M45.6208 27.043H24.3477V29.7383H44.9857C45.2557 28.8628 45.4566 27.9595 45.6208 27.043V27.043Z' fill='black'/%3E%3Cpath d='M24.3477 35.1289H42.4905C43.0319 34.266 43.5192 33.3683 43.9438 32.4336H24.3477V35.1289Z' fill='black'/%3E%3C/svg%3E%0A\",\"logoProfileCollapsedAltText\":\"\",\"logoProfileCollapsedHeight\":\"22\",\"logoProfileHeight\":\"22\",\"name\":\"Contrast\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#000000\",\"primaryOffColor\":\"#000000\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#000000\",\"profileMenuTextHighlightColor\":\"#455469\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"f2bdd040-2e46-4602-a0ab-24ed52103cdc\",\"accountFooter\":\"\\n\",\"accountFooterEnabled\":true,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#5E6D82\",\"buttonRounded\":\"50\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\\n\\n\",\"journeyFooterEnabled\":true,\"journeyHeader\":\"
\\n \\n \\n \\n \\n \\n
    \\n
  • \\n Link\\n
  • \\n
  • \\n Disabled\\n
  • \\n
\\n
    \\n
  • \\n Link\\n
  • \\n
\\n \\n \\n
\\n\",\"journeyHeaderEnabled\":true,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":false,\"journeyLayout\":\"card\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#C60819\",\"linkColor\":\"#EB0A1E\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-icon.svg\",\"logoAltText\":\"\",\"logoEnabled\":true,\"logoHeight\":\"40\",\"logoProfile\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-full.svg\",\"logoProfileAltText\":\"Highlander\",\"logoProfileCollapsed\":\"https://cdn.forgerock.com/platform/themes/highlander/logo-highlander-icon.svg\",\"logoProfileCollapsedAltText\":\"Highlander\",\"logoProfileCollapsedHeight\":\"28\",\"logoProfileHeight\":\"28\",\"name\":\"Highlander\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#EB0A1E\",\"primaryOffColor\":\"#C60819\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#455469\",\"profileMenuTextHighlightColor\":\"#EB0A1E\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"62ac2a64-9db9-4f0a-a7e4-74f3d662bc42\",\"accountFooter\":\"\\n\",\"accountFooterEnabled\":true,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#5E6D82\",\"buttonRounded\":\"50\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\\n\",\"journeyFooterEnabled\":true,\"journeyHeader\":\"
\\n \\n \\n \\n \\n \\n
    \\n
  • \\n Link\\n
  • \\n
  • \\n Disabled\\n
  • \\n
\\n
    \\n
  • \\n Link\\n
  • \\n
\\n \\n \\n
\\n\",\"journeyHeaderEnabled\":true,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":true,\"journeyLayout\":\"justified-right\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#49871E\",\"linkColor\":\"#5AA625\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/robroy/logo-robroy-icon.svg\",\"logoAltText\":\"\",\"logoEnabled\":true,\"logoHeight\":\"40\",\"logoProfile\":\"data:image/svg+xml,%0A%3Csvg width='156' height='34' viewBox='0 0 156 34' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cpath d='M32.5539 32.5538C32.5539 32.5538 17.0796 35.6024 7.23861 25.7614C-2.60242 15.9204 0.446148 0.446137 0.446148 0.446137C0.446148 0.446137 15.9204 -2.60243 25.7614 7.23866C35.6024 17.0797 32.5539 32.5538 32.5539 32.5538Z' fill='%23C3EA21'/%3E%3Cpath d='M32.5537 32.554C32.5537 32.554 17.0795 35.6026 7.23845 25.7615C-2.60257 15.9205 0.445995 0.446289 0.445995 0.446289L32.5537 32.554Z' fill='%238ADB53'/%3E%3C/g%3E%3Cpath d='M51.053 25.38L53.186 25.11V8.964L51.161 8.586V6.939H55.076C55.418 6.939 55.796 6.93 56.21 6.912C56.624 6.894 56.939 6.876 57.155 6.858C58.091 6.786 58.865 6.75 59.477 6.75C61.331 6.75 62.816 6.939 63.932 7.317C65.048 7.695 65.858 8.271 66.362 9.045C66.866 9.819 67.118 10.836 67.118 12.096C67.118 13.338 66.785 14.49 66.119 15.552C65.453 16.614 64.49 17.343 63.23 17.739C63.95 18.045 64.589 18.603 65.147 19.413C65.705 20.223 66.299 21.276 66.929 22.572C67.379 23.454 67.721 24.093 67.955 24.489C68.207 24.867 68.45 25.083 68.684 25.137L69.575 25.407V27H64.985C64.697 27 64.391 26.712 64.067 26.136C63.761 25.542 63.356 24.615 62.852 23.355C62.258 21.879 61.745 20.727 61.313 19.899C60.881 19.071 60.422 18.558 59.936 18.36H57.155V25.11L59.639 25.38V27H51.053V25.38ZM59.639 16.713C60.665 16.713 61.466 16.344 62.042 15.606C62.618 14.868 62.906 13.761 62.906 12.285C62.906 10.971 62.618 9.999 62.042 9.369C61.484 8.739 60.512 8.424 59.126 8.424C58.622 8.424 58.19 8.451 57.83 8.505C57.488 8.541 57.263 8.559 57.155 8.559V16.659C57.371 16.695 57.893 16.713 58.721 16.713H59.639ZM70.674 19.521C70.674 17.829 71.007 16.389 71.673 15.201C72.357 14.013 73.266 13.122 74.4 12.528C75.534 11.916 76.767 11.61 78.099 11.61C80.367 11.61 82.113 12.312 83.337 13.716C84.579 15.102 85.2 16.992 85.2 19.386C85.2 21.096 84.858 22.554 84.174 23.76C83.508 24.948 82.608 25.839 81.474 26.433C80.358 27.009 79.125 27.297 77.775 27.297C75.525 27.297 73.779 26.604 72.537 25.218C71.295 23.814 70.674 21.915 70.674 19.521ZM77.991 25.542C80.025 25.542 81.042 23.58 81.042 19.656C81.042 17.604 80.799 16.047 80.313 14.985C79.827 13.905 79.035 13.365 77.937 13.365C75.849 13.365 74.805 15.327 74.805 19.251C74.805 21.303 75.057 22.869 75.561 23.949C76.083 25.011 76.893 25.542 77.991 25.542ZM86.4395 5.454L91.3805 4.86H91.4345L92.1905 5.373V13.338C92.6765 12.852 93.2705 12.447 93.9725 12.123C94.6925 11.781 95.4665 11.61 96.2945 11.61C98.0225 11.61 99.4265 12.222 100.506 13.446C101.604 14.652 102.153 16.506 102.153 19.008C102.153 20.556 101.829 21.96 101.181 23.22C100.533 24.48 99.5975 25.479 98.3735 26.217C97.1675 26.937 95.7635 27.297 94.1615 27.297C92.7395 27.297 91.5065 27.18 90.4625 26.946C89.4185 26.694 88.7525 26.469 88.4645 26.271V7.182L86.4395 6.858V5.454ZM94.8635 13.986C94.3235 13.986 93.8105 14.112 93.3245 14.364C92.8565 14.598 92.4785 14.868 92.1905 15.174V25.029C92.2985 25.227 92.5505 25.389 92.9465 25.515C93.3425 25.641 93.7925 25.704 94.2965 25.704C95.4485 25.704 96.3665 25.173 97.0505 24.111C97.7525 23.031 98.1035 21.438 98.1035 19.332C98.1035 17.514 97.8065 16.173 97.2125 15.309C96.6185 14.427 95.8355 13.986 94.8635 13.986Z' fill='black'/%3E%3Cpath d='M104.183 25.38L106.316 25.11V8.964L104.291 8.586V6.939H108.206C108.548 6.939 108.926 6.93 109.34 6.912C109.754 6.894 110.069 6.876 110.285 6.858C111.221 6.786 111.995 6.75 112.607 6.75C114.461 6.75 115.946 6.939 117.062 7.317C118.178 7.695 118.988 8.271 119.492 9.045C119.996 9.819 120.248 10.836 120.248 12.096C120.248 13.338 119.915 14.49 119.249 15.552C118.583 16.614 117.62 17.343 116.36 17.739C117.08 18.045 117.719 18.603 118.277 19.413C118.835 20.223 119.429 21.276 120.059 22.572C120.509 23.454 120.851 24.093 121.085 24.489C121.337 24.867 121.58 25.083 121.814 25.137L122.705 25.407V27H118.115C117.827 27 117.521 26.712 117.197 26.136C116.891 25.542 116.486 24.615 115.982 23.355C115.388 21.879 114.875 20.727 114.443 19.899C114.011 19.071 113.552 18.558 113.066 18.36H110.285V25.11L112.769 25.38V27H104.183V25.38ZM112.769 16.713C113.795 16.713 114.596 16.344 115.172 15.606C115.748 14.868 116.036 13.761 116.036 12.285C116.036 10.971 115.748 9.999 115.172 9.369C114.614 8.739 113.642 8.424 112.256 8.424C111.752 8.424 111.32 8.451 110.96 8.505C110.618 8.541 110.393 8.559 110.285 8.559V16.659C110.501 16.695 111.023 16.713 111.851 16.713H112.769ZM123.804 19.521C123.804 17.829 124.137 16.389 124.803 15.201C125.487 14.013 126.396 13.122 127.53 12.528C128.664 11.916 129.897 11.61 131.229 11.61C133.497 11.61 135.243 12.312 136.467 13.716C137.709 15.102 138.33 16.992 138.33 19.386C138.33 21.096 137.988 22.554 137.304 23.76C136.638 24.948 135.738 25.839 134.604 26.433C133.488 27.009 132.255 27.297 130.905 27.297C128.655 27.297 126.909 26.604 125.667 25.218C124.425 23.814 123.804 21.915 123.804 19.521ZM131.121 25.542C133.155 25.542 134.172 23.58 134.172 19.656C134.172 17.604 133.929 16.047 133.443 14.985C132.957 13.905 132.165 13.365 131.067 13.365C128.979 13.365 127.935 15.327 127.935 19.251C127.935 21.303 128.187 22.869 128.691 23.949C129.213 25.011 130.023 25.542 131.121 25.542ZM143.187 33.723C142.863 33.723 142.512 33.696 142.134 33.642C141.774 33.588 141.513 33.525 141.351 33.453V30.564C141.477 30.636 141.729 30.708 142.107 30.78C142.485 30.852 142.827 30.888 143.133 30.888C144.033 30.888 144.771 30.591 145.347 29.997C145.941 29.403 146.49 28.404 146.994 27H145.536L140.46 13.905L139.245 13.554V11.988H146.67V13.554L144.699 13.878L147.102 21.357L148.074 24.543L148.911 21.357L151.125 13.878L149.424 13.554V11.988H155.283V13.554L153.96 13.878C152.97 16.902 151.989 19.818 151.017 22.626C150.045 25.434 149.478 27.009 149.316 27.351C148.74 28.863 148.191 30.069 147.669 30.969C147.147 31.869 146.526 32.553 145.806 33.021C145.086 33.489 144.213 33.723 143.187 33.723Z' fill='%236CBE34'/%3E%3Cdefs%3E%3CclipPath id='clip0'%3E%3Crect width='33' height='33' fill='white' transform='matrix(-1 0 0 1 33 0)'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A\",\"logoProfileAltText\":\"RobRoy\",\"logoProfileCollapsed\":\"data:image/svg+xml,%0A%3Csvg width='33' height='33' viewBox='0 0 33 33' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0)'%3E%3Cpath d='M32.5539 32.5538C32.5539 32.5538 17.0796 35.6024 7.23861 25.7614C-2.60242 15.9204 0.446148 0.446137 0.446148 0.446137C0.446148 0.446137 15.9204 -2.60243 25.7614 7.23866C35.6024 17.0797 32.5539 32.5538 32.5539 32.5538Z' fill='%23C3EA21'/%3E%3Cpath d='M32.5537 32.554C32.5537 32.554 17.0795 35.6026 7.23845 25.7615C-2.60257 15.9205 0.445996 0.446289 0.445996 0.446289L32.5537 32.554Z' fill='%238ADB53'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0'%3E%3Crect width='33' height='33' fill='white' transform='matrix(-1 0 0 1 33 0)'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A\",\"logoProfileCollapsedAltText\":\"RobRoy\",\"logoProfileCollapsedHeight\":\"28\",\"logoProfileHeight\":\"28\",\"name\":\"Robroy\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#5AA625\",\"primaryOffColor\":\"#49871E\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#455469\",\"profileMenuTextHighlightColor\":\"#5AA625\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"b7d8de5a-f788-4ac8-b80a-3220a5f977ec\",\"accountFooter\":\"\",\"accountFooterEnabled\":false,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#324054\",\"backgroundImage\":\"\",\"bodyText\":\"#23282e\",\"buttonRounded\":5,\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":true,\"journeyFooter\":\"\",\"journeyFooterEnabled\":false,\"journeyHeader\":\"
Header Content
\",\"journeyHeaderEnabled\":false,\"journeyJustifiedContent\":\"\",\"journeyJustifiedContentEnabled\":false,\"journeyLayout\":\"card\",\"journeyTheaterMode\":false,\"linkActiveColor\":\"#0c85cf\",\"linkColor\":\"#109cf1\",\"linkedTrees\":[],\"logo\":\"\",\"logoAltText\":\"\",\"logoHeight\":\"40\",\"logoProfile\":\"\",\"logoProfileAltText\":\"\",\"logoProfileCollapsed\":\"\",\"logoProfileCollapsedAltText\":\"\",\"logoProfileCollapsedHeight\":\"40\",\"logoProfileHeight\":\"40\",\"name\":\"Starter Theme\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#324054\",\"primaryOffColor\":\"#242E3C\",\"profileBackgroundColor\":\"#f6f8fa\",\"profileMenuHighlightColor\":\"#f3f5f8\",\"profileMenuHoverColor\":\"#324054\",\"profileMenuHoverTextColor\":\"#ffffff\",\"profileMenuTextHighlightColor\":\"#455469\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"},{\"_id\":\"8dfd6c93-972a-4786-950d-79904f66af4b\",\"accountFooter\":\"\\n\",\"accountFooterEnabled\":true,\"accountPageSections\":{\"accountControls\":{\"enabled\":false},\"accountSecurity\":{\"enabled\":true,\"subsections\":{\"password\":{\"enabled\":true},\"securityQuestions\":{\"enabled\":false},\"twoStepVerification\":{\"enabled\":true},\"username\":{\"enabled\":true}}},\"consent\":{\"enabled\":false},\"oauthApplications\":{\"enabled\":false},\"personalInformation\":{\"enabled\":true},\"preferences\":{\"enabled\":false},\"social\":{\"enabled\":false},\"trustedDevices\":{\"enabled\":true}},\"backgroundColor\":\"#FFFFFF\",\"backgroundImage\":\"\",\"bodyText\":\"#5E6D82\",\"buttonRounded\":\"50\",\"dangerColor\":\"#f7685b\",\"favicon\":\"\",\"isDefault\":false,\"journeyFooter\":\"\\n\",\"journeyFooterEnabled\":true,\"journeyHeader\":\"
Header Content
\",\"journeyHeaderEnabled\":false,\"journeyJustifiedContent\":\"
\\n

Uptime & Performance Benchmarking Made Easy

\\n
\\n\\n\",\"journeyJustifiedContentEnabled\":true,\"journeyLayout\":\"justified-right\",\"journeyTheaterMode\":true,\"linkActiveColor\":\"#007661\",\"linkColor\":\"#009C80\",\"linkedTrees\":[],\"logo\":\"https://cdn.forgerock.com/platform/themes/zardoz/logo-zardoz.svg\",\"logoAltText\":\"Zardoz Logo\",\"logoEnabled\":true,\"logoHeight\":\"47\",\"logoProfile\":\"https://cdn.forgerock.com/platform/themes/zardoz/logo-zardoz.svg\",\"logoProfileAltText\":\"Zardaz Logo\",\"logoProfileCollapsed\":\"https://cdn.forgerock.com/platform/themes/zardoz/logo-zardoz.svg\",\"logoProfileCollapsedAltText\":\"Zardaz Logo\",\"logoProfileCollapsedHeight\":\"28\",\"logoProfileHeight\":\"40\",\"name\":\"Zardoz\",\"pageTitle\":\"#23282e\",\"primaryColor\":\"#009C80\",\"primaryOffColor\":\"#007661\",\"profileBackgroundColor\":\"#FFFFFF\",\"profileMenuHighlightColor\":\"#FFFFFF\",\"profileMenuHoverColor\":\"#FFFFFF\",\"profileMenuHoverTextColor\":\"#455469\",\"profileMenuTextHighlightColor\":\"#009C80\",\"secondaryColor\":\"#69788b\",\"textColor\":\"#ffffff\"}]}}" + }, + "cookies": [], + "headers": [ + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "vary", + "value": "Origin" + }, + { + "name": "cache-control", + "value": "no-store" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "content-type", + "value": "application/json;charset=utf-8" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "x-frame-options", + "value": "DENY" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 685, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.106Z", + "time": 81, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 81 + } + }, + { + "_id": "3df89b4193dadb41052109b11ec2b6dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2032, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PageNode/0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97" + }, + "response": { + "bodySize": 1373, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1373, + "text": "{\"_id\":\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\",\"_rev\":\"2033345625\",\"nodes\":[{\"_id\":\"03416cc6-588b-409a-919f-038bb8194c81\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Welcome\"},{\"_id\":\"1a002d5d-5ad5-4d0e-965f-a0f26278d08d\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Username\"},{\"_id\":\"65c2a8cd-e623-4c5d-b420-e55fc5105f43\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Password\"},{\"_id\":\"ee549716-666c-4b9d-baab-defe1a93eb6c\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Email\"},{\"_id\":\"eaf91b8a-bb71-4037-97ec-cd2e54885668\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Age\"},{\"_id\":\"d8bd62e2-a4e7-4e08-bb28-10570aa31fcf\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Is old\"},{\"_id\":\"18edd91b-5e15-49df-b3c3-764114a8ebb3\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Hidden\"},{\"_id\":\"0a3d5de0-9426-4a9a-aae0-163eda075d43\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Script\"},{\"_id\":\"f9155861-f7c8-4022-9bed-e4ef5b238824\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Terms\"}],\"pageDescription\":{},\"pageHeader\":{},\"_type\":{\"_id\":\"PageNode\",\"name\":\"Page Node\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"2033345625\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1373" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.111Z", + "time": 68, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 68 + } + }, + { + "_id": "50ca980b3c27eedf064debd9ada9dafa", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2040, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-session/8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb" + }, + "response": { + "bodySize": 246, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 246, + "text": "{\"_id\":\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\",\"_rev\":\"-1617974950\",\"_type\":{\"_id\":\"designer-session\",\"name\":\"Has Session AM\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"True\",\"displayName\":\"True\"},{\"id\":\"False\",\"displayName\":\"False\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1617974950\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "246" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.115Z", + "time": 140, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 140 + } + }, + { + "_id": "af2c27598754f39fee4fb3bc53e1912a", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2045, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/DataStoreDecisionNode/461a364c-5884-44f6-87d9-ae749cc08f24" + }, + "response": { + "bodySize": 255, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 255, + "text": "{\"_id\":\"461a364c-5884-44f6-87d9-ae749cc08f24\",\"_rev\":\"2126257365\",\"_type\":{\"_id\":\"DataStoreDecisionNode\",\"name\":\"Data Store Decision\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"true\",\"displayName\":\"True\"},{\"id\":\"false\",\"displayName\":\"False\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"2126257365\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "255" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.123Z", + "time": 140, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 140 + } + }, + { + "_id": "7927ae1bb6d94805bb158175efbf8b8a", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/03416cc6-588b-409a-919f-038bb8194c81" + }, + "response": { + "bodySize": 381, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 381, + "text": "{\"_id\":\"03416cc6-588b-409a-919f-038bb8194c81\",\"_rev\":\"-191831406\",\"callback\":\"TEXT_OUTPUT_CALLBACK\",\"options\":{\"messageType\":\"1\",\"message\":\"WARNING: You must enter your username and password to continue!\"},\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-191831406\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "381" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.275Z", + "time": 77, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 77 + } + }, + { + "_id": "7ed1d76ff2fbc200d9b5827d136ff66d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/1a002d5d-5ad5-4d0e-965f-a0f26278d08d" + }, + "response": { + "bodySize": 373, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 373, + "text": "{\"_id\":\"1a002d5d-5ad5-4d0e-965f-a0f26278d08d\",\"_rev\":\"-605795289\",\"callback\":\"NAME_CALLBACK\",\"objectSharedProperty\":\"userName\",\"options\":{\"prompt\":\"Enter Your Username\"},\"sharedProperty\":\"username\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-605795289\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "373" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.279Z", + "time": 74, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 74 + } + }, + { + "_id": "5a803a88cfa4050c398fce06b28f1dde", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/65c2a8cd-e623-4c5d-b420-e55fc5105f43" + }, + "response": { + "bodySize": 384, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 384, + "text": "{\"_id\":\"65c2a8cd-e623-4c5d-b420-e55fc5105f43\",\"_rev\":\"-1753807887\",\"callback\":\"PASSWORD_CALLBACK\",\"objectTransientProperty\":\"password\",\"transientProperty\":\"password\",\"options\":{\"prompt\":\"Enter Your Password\"},\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1753807887\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "384" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.283Z", + "time": 73, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 73 + } + }, + { + "_id": "736144c4b6cc1b7b0048454cc4ab94dc", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/ee549716-666c-4b9d-baab-defe1a93eb6c" + }, + "response": { + "bodySize": 412, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 412, + "text": "{\"_id\":\"ee549716-666c-4b9d-baab-defe1a93eb6c\",\"_rev\":\"146018854\",\"callback\":\"STRING_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"mail\",\"options\":{\"name\":\"mail\",\"prompt\":\"Enter Your Email\",\"required\":\"true\"},\"sharedProperty\":\"email\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"146018854\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "412" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 785, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.287Z", + "time": 72, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 72 + } + }, + { + "_id": "227b425a71b596778ee82aa96e485897", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/eaf91b8a-bb71-4037-97ec-cd2e54885668" + }, + "response": { + "bodySize": 439, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 439, + "text": "{\"_id\":\"eaf91b8a-bb71-4037-97ec-cd2e54885668\",\"_rev\":\"2022883295\",\"callback\":\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"frUnindexedInteger1\",\"options\":{\"name\":\"frUnindexedInteger1\",\"prompt\":\"Enter Your Age\",\"required\":\"true\"},\"sharedProperty\":\"age\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"2022883295\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "439" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.291Z", + "time": 144, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 144 + } + }, + { + "_id": "3e43574c2a282990a5cf3e0032fcdcf5", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/d8bd62e2-a4e7-4e08-bb28-10570aa31fcf" + }, + "response": { + "bodySize": 439, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 439, + "text": "{\"_id\":\"d8bd62e2-a4e7-4e08-bb28-10570aa31fcf\",\"_rev\":\"-1308099819\",\"callback\":\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"frUnindexedString1\",\"options\":{\"name\":\"frUnindexedString1\",\"prompt\":\"Are you old?\",\"required\":\"true\"},\"sharedProperty\":\"isOld\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1308099819\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "439" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.296Z", + "time": 135, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 135 + } + }, + { + "_id": "52d0fd04a41e9d394cfeb2abf7215bc0", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/18edd91b-5e15-49df-b3c3-764114a8ebb3" + }, + "response": { + "bodySize": 347, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 347, + "text": "{\"_id\":\"18edd91b-5e15-49df-b3c3-764114a8ebb3\",\"_rev\":\"975185327\",\"callback\":\"HIDDEN_VALUE_CALLBACK\",\"options\":{\"id\":\"myId\",\"value\":\"I am hidden\"},\"sharedProperty\":\"hidden\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"975185327\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "347" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 785, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.300Z", + "time": 133, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 133 + } + }, + { + "_id": "2742752f69dcd6cb1d9bf680350b394d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/0a3d5de0-9426-4a9a-aae0-163eda075d43" + }, + "response": { + "bodySize": 359, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 359, + "text": "{\"_id\":\"0a3d5de0-9426-4a9a-aae0-163eda075d43\",\"_rev\":\"4824664\",\"callback\":\"SCRIPT_TEXT_OUTPUT_CALLBACK\",\"options\":{\"message\":\"console.log(\\\"hello console!\\\");\"},\"sharedProperty\":\"out\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"4824664\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "359" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 783, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.306Z", + "time": 126, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 126 + } + }, + { + "_id": "325cd55ae1cda1ea9a35b23cbec693d7", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2065, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/f9155861-f7c8-4022-9bed-e4ef5b238824" + }, + "response": { + "bodySize": 407, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 407, + "text": "{\"_id\":\"f9155861-f7c8-4022-9bed-e4ef5b238824\",\"_rev\":\"-1687279556\",\"callback\":\"TERMS_AND_CONDITIONS_CALLBACK\",\"options\":{\"version\":\"6.7\",\"terms\":\"This is the way\",\"createDate\":\"2025-11-12T22:30:59.417Z\"},\"sharedProperty\":\"accepted\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1687279556\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "407" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.314Z", + "time": 120, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 120 + } + }, + { + "_id": "13c0beaaa7896a3f78c4319177709633", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1941, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/session-1" + }, + "response": { + "bodySize": 484, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 484, + "text": "{\"_id\":\"session-1\",\"_rev\":\"1175982017\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1175982017\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "484" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.319Z", + "time": 119, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 119 + } + }, + { + "_id": "755d8aba5152b9197bf328bdc35a9311", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1966, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/ef81b1a52c914710b3388caebfe7233a-1" + }, + "response": { + "bodySize": 24911, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 24911, + "text": "{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-1739635001\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks).\\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1739635001\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 794, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:26.457Z", + "time": 82, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 82 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/JourneyOps_2291468013/importJourney_541402267/3-Import-journey-FrodoTestJourney12-w_2042673225/custom-node-dependencies_2882997917/recording.har b/src/test/mock-recordings/JourneyOps_2291468013/importJourney_541402267/3-Import-journey-FrodoTestJourney12-w_2042673225/custom-node-dependencies_2882997917/recording.har new file mode 100644 index 000000000..625fddf64 --- /dev/null +++ b/src/test/mock-recordings/JourneyOps_2291468013/importJourney_541402267/3-Import-journey-FrodoTestJourney12-w_2042673225/custom-node-dependencies_2882997917/recording.har @@ -0,0 +1,2730 @@ +{ + "log": { + "_recordingName": "JourneyOps/importJourney()/3: Import journey 'FrodoTestJourney12' w/ custom node dependencies", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "97313394769cea5447766b0e629f3572", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 446, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "446" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1953, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 94, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 94, + "text": "{\"code\":409,\"reason\":\"Conflict\",\"message\":\"Node Type with resource id session already exists\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "94" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 409, + "statusText": "Conflict" + }, + "startedDateTime": "2025-11-13T16:56:30.998Z", + "time": 70, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 70 + } + }, + { + "_id": "66e8c9f881687a104ecb4a111b1fcaa5", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 446, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "446" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1975, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/session-1" + }, + "response": { + "bodySize": 485, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 485, + "text": "{\"_id\":\"session-1\",\"_rev\":\"-1029167343\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1029167343\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "485" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.073Z", + "time": 84, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 84 + } + }, + { + "_id": "1f023d7ecc6567db671f8c7e3287e3e5", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 24847, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "24847" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1955, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks).\\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 119, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 119, + "text": "{\"code\":409,\"reason\":\"Conflict\",\"message\":\"Node Type with resource id ef81b1a52c914710b3388caebfe7233a already exists\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "119" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 409, + "statusText": "Conflict" + }, + "startedDateTime": "2025-11-13T16:56:31.168Z", + "time": 68, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 68 + } + }, + { + "_id": "4577c52acdf445f9cecce14f9d6b4fd7", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 24847, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "24847" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2002, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks).\\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/ef81b1a52c914710b3388caebfe7233a-1" + }, + "response": { + "bodySize": 24910, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 24910, + "text": "{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-754144533\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks).\\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-754144533\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 793, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.247Z", + "time": 94, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 94 + } + }, + { + "_id": "37ed11f81fb7b49eb8990e7b85105ce4", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 361, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "361" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"03416cc6-588b-409a-919f-038bb8194c81\",\"callback\":\"TEXT_OUTPUT_CALLBACK\",\"options\":{\"messageType\":\"1\",\"message\":\"WARNING: You must enter your username and password to continue!\"},\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/03416cc6-588b-409a-919f-038bb8194c81" + }, + "response": { + "bodySize": 381, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 381, + "text": "{\"_id\":\"03416cc6-588b-409a-919f-038bb8194c81\",\"_rev\":\"-191831406\",\"callback\":\"TEXT_OUTPUT_CALLBACK\",\"options\":{\"messageType\":\"1\",\"message\":\"WARNING: You must enter your username and password to continue!\"},\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-191831406\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "381" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.347Z", + "time": 94, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 94 + } + }, + { + "_id": "9d1c89c50f4580dab1f325365d911ca5", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 353, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "353" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"1a002d5d-5ad5-4d0e-965f-a0f26278d08d\",\"callback\":\"NAME_CALLBACK\",\"objectSharedProperty\":\"userName\",\"options\":{\"prompt\":\"Enter Your Username\"},\"sharedProperty\":\"username\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/1a002d5d-5ad5-4d0e-965f-a0f26278d08d" + }, + "response": { + "bodySize": 373, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 373, + "text": "{\"_id\":\"1a002d5d-5ad5-4d0e-965f-a0f26278d08d\",\"_rev\":\"-605795289\",\"callback\":\"NAME_CALLBACK\",\"objectSharedProperty\":\"userName\",\"options\":{\"prompt\":\"Enter Your Username\"},\"sharedProperty\":\"username\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-605795289\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "373" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.447Z", + "time": 81, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 81 + } + }, + { + "_id": "6e74b88f1677046ace1f6dd9fb4a67a4", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 363, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "363" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"65c2a8cd-e623-4c5d-b420-e55fc5105f43\",\"callback\":\"PASSWORD_CALLBACK\",\"objectTransientProperty\":\"password\",\"transientProperty\":\"password\",\"options\":{\"prompt\":\"Enter Your Password\"},\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/65c2a8cd-e623-4c5d-b420-e55fc5105f43" + }, + "response": { + "bodySize": 384, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 384, + "text": "{\"_id\":\"65c2a8cd-e623-4c5d-b420-e55fc5105f43\",\"_rev\":\"-1753807887\",\"callback\":\"PASSWORD_CALLBACK\",\"objectTransientProperty\":\"password\",\"transientProperty\":\"password\",\"options\":{\"prompt\":\"Enter Your Password\"},\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1753807887\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "384" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.533Z", + "time": 78, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 78 + } + }, + { + "_id": "2ffbc260a630ee47e44b2d9e8409367d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 393, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "393" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"ee549716-666c-4b9d-baab-defe1a93eb6c\",\"callback\":\"STRING_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"mail\",\"options\":{\"name\":\"mail\",\"prompt\":\"Enter Your Email\",\"required\":\"true\"},\"sharedProperty\":\"email\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/ee549716-666c-4b9d-baab-defe1a93eb6c" + }, + "response": { + "bodySize": 412, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 412, + "text": "{\"_id\":\"ee549716-666c-4b9d-baab-defe1a93eb6c\",\"_rev\":\"146018854\",\"callback\":\"STRING_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"mail\",\"options\":{\"name\":\"mail\",\"prompt\":\"Enter Your Email\",\"required\":\"true\"},\"sharedProperty\":\"email\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"146018854\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "412" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 785, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.616Z", + "time": 70, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 70 + } + }, + { + "_id": "1092fb06411d09f444fc2fa569ebcb2d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 419, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "419" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"eaf91b8a-bb71-4037-97ec-cd2e54885668\",\"callback\":\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"frUnindexedInteger1\",\"options\":{\"name\":\"frUnindexedInteger1\",\"prompt\":\"Enter Your Age\",\"required\":\"true\"},\"sharedProperty\":\"age\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/eaf91b8a-bb71-4037-97ec-cd2e54885668" + }, + "response": { + "bodySize": 439, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 439, + "text": "{\"_id\":\"eaf91b8a-bb71-4037-97ec-cd2e54885668\",\"_rev\":\"2022883295\",\"callback\":\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"frUnindexedInteger1\",\"options\":{\"name\":\"frUnindexedInteger1\",\"prompt\":\"Enter Your Age\",\"required\":\"true\"},\"sharedProperty\":\"age\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"2022883295\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "439" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.693Z", + "time": 72, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 72 + } + }, + { + "_id": "139d7b927a7e8203577c37422b36b8dc", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 418, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "418" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"d8bd62e2-a4e7-4e08-bb28-10570aa31fcf\",\"callback\":\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"frUnindexedString1\",\"options\":{\"name\":\"frUnindexedString1\",\"prompt\":\"Are you old?\",\"required\":\"true\"},\"sharedProperty\":\"isOld\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/d8bd62e2-a4e7-4e08-bb28-10570aa31fcf" + }, + "response": { + "bodySize": 439, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 439, + "text": "{\"_id\":\"d8bd62e2-a4e7-4e08-bb28-10570aa31fcf\",\"_rev\":\"-1308099819\",\"callback\":\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\",\"objectSharedProperty\":\"frUnindexedString1\",\"options\":{\"name\":\"frUnindexedString1\",\"prompt\":\"Are you old?\",\"required\":\"true\"},\"sharedProperty\":\"isOld\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1308099819\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "439" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.771Z", + "time": 71, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 71 + } + }, + { + "_id": "33e3c4359283ffdb05c07e94b067f176", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 328, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "328" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"18edd91b-5e15-49df-b3c3-764114a8ebb3\",\"callback\":\"HIDDEN_VALUE_CALLBACK\",\"options\":{\"id\":\"myId\",\"value\":\"I am hidden\"},\"sharedProperty\":\"hidden\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/18edd91b-5e15-49df-b3c3-764114a8ebb3" + }, + "response": { + "bodySize": 347, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 347, + "text": "{\"_id\":\"18edd91b-5e15-49df-b3c3-764114a8ebb3\",\"_rev\":\"975185327\",\"callback\":\"HIDDEN_VALUE_CALLBACK\",\"options\":{\"id\":\"myId\",\"value\":\"I am hidden\"},\"sharedProperty\":\"hidden\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"975185327\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "347" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 785, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.847Z", + "time": 71, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 71 + } + }, + { + "_id": "147af0714e78eb89fa372b0c4bcaea25", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 342, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "342" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"0a3d5de0-9426-4a9a-aae0-163eda075d43\",\"callback\":\"SCRIPT_TEXT_OUTPUT_CALLBACK\",\"options\":{\"message\":\"console.log(\\\"hello console!\\\");\"},\"sharedProperty\":\"out\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/0a3d5de0-9426-4a9a-aae0-163eda075d43" + }, + "response": { + "bodySize": 359, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 359, + "text": "{\"_id\":\"0a3d5de0-9426-4a9a-aae0-163eda075d43\",\"_rev\":\"4824664\",\"callback\":\"SCRIPT_TEXT_OUTPUT_CALLBACK\",\"options\":{\"message\":\"console.log(\\\"hello console!\\\");\"},\"sharedProperty\":\"out\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"4824664\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "359" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:31 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 783, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:31.922Z", + "time": 73, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 73 + } + }, + { + "_id": "6d3daed40bc95a53d82662c5500d18b6", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 386, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "386" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2086, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"f9155861-f7c8-4022-9bed-e4ef5b238824\",\"callback\":\"TERMS_AND_CONDITIONS_CALLBACK\",\"options\":{\"version\":\"6.7\",\"terms\":\"This is the way\",\"createDate\":\"2025-11-12T22:30:59.417Z\"},\"sharedProperty\":\"accepted\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-ef81b1a52c914710b3388caebfe7233a/f9155861-f7c8-4022-9bed-e4ef5b238824" + }, + "response": { + "bodySize": 407, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 407, + "text": "{\"_id\":\"f9155861-f7c8-4022-9bed-e4ef5b238824\",\"_rev\":\"-1687279556\",\"callback\":\"TERMS_AND_CONDITIONS_CALLBACK\",\"options\":{\"version\":\"6.7\",\"terms\":\"This is the way\",\"createDate\":\"2025-11-12T22:30:59.417Z\"},\"sharedProperty\":\"accepted\",\"_type\":{\"_id\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"name\":\"Display Callback\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1687279556\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "407" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:32 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:32.001Z", + "time": 71, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 71 + } + }, + { + "_id": "acc7ad09133c375dcbafbc729ac8222f", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1353, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1353" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2054, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\",\"nodes\":[{\"_id\":\"03416cc6-588b-409a-919f-038bb8194c81\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Welcome\"},{\"_id\":\"1a002d5d-5ad5-4d0e-965f-a0f26278d08d\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Username\"},{\"_id\":\"65c2a8cd-e623-4c5d-b420-e55fc5105f43\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Password\"},{\"_id\":\"ee549716-666c-4b9d-baab-defe1a93eb6c\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Email\"},{\"_id\":\"eaf91b8a-bb71-4037-97ec-cd2e54885668\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Age\"},{\"_id\":\"d8bd62e2-a4e7-4e08-bb28-10570aa31fcf\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Is old\"},{\"_id\":\"18edd91b-5e15-49df-b3c3-764114a8ebb3\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Hidden\"},{\"_id\":\"0a3d5de0-9426-4a9a-aae0-163eda075d43\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Script\"},{\"_id\":\"f9155861-f7c8-4022-9bed-e4ef5b238824\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Terms\"}],\"pageDescription\":{},\"pageHeader\":{},\"_type\":{\"_id\":\"PageNode\",\"name\":\"Page Node\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PageNode/0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97" + }, + "response": { + "bodySize": 1373, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1373, + "text": "{\"_id\":\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\",\"_rev\":\"2033345625\",\"nodes\":[{\"_id\":\"03416cc6-588b-409a-919f-038bb8194c81\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Welcome\"},{\"_id\":\"1a002d5d-5ad5-4d0e-965f-a0f26278d08d\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Username\"},{\"_id\":\"65c2a8cd-e623-4c5d-b420-e55fc5105f43\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Password\"},{\"_id\":\"ee549716-666c-4b9d-baab-defe1a93eb6c\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Email\"},{\"_id\":\"eaf91b8a-bb71-4037-97ec-cd2e54885668\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Age\"},{\"_id\":\"d8bd62e2-a4e7-4e08-bb28-10570aa31fcf\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Is old\"},{\"_id\":\"18edd91b-5e15-49df-b3c3-764114a8ebb3\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Hidden\"},{\"_id\":\"0a3d5de0-9426-4a9a-aae0-163eda075d43\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Script\"},{\"_id\":\"f9155861-f7c8-4022-9bed-e4ef5b238824\",\"nodeType\":\"designer-ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Terms\"}],\"pageDescription\":{},\"pageHeader\":{},\"_type\":{\"_id\":\"PageNode\",\"name\":\"Page Node\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"2033345625\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1373" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:32 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:32.077Z", + "time": 181, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 181 + } + }, + { + "_id": "dd5d546e8526693ffdbb7e7248de936a", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 225, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "225" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2061, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\",\"_type\":{\"_id\":\"designer-session\",\"name\":\"Has Session AM\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"True\",\"displayName\":\"True\"},{\"id\":\"False\",\"displayName\":\"False\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/designer-session/8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb" + }, + "response": { + "bodySize": 246, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 246, + "text": "{\"_id\":\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\",\"_rev\":\"-1617974950\",\"_type\":{\"_id\":\"designer-session\",\"name\":\"Has Session AM\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"True\",\"displayName\":\"True\"},{\"id\":\"False\",\"displayName\":\"False\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1617974950\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "246" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:32 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:32.263Z", + "time": 78, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 78 + } + }, + { + "_id": "0de829d83a6e3098bfffb524d0d765b5", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 235, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "235" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2066, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"461a364c-5884-44f6-87d9-ae749cc08f24\",\"_type\":{\"_id\":\"DataStoreDecisionNode\",\"name\":\"Data Store Decision\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"true\",\"displayName\":\"True\"},{\"id\":\"false\",\"displayName\":\"False\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/DataStoreDecisionNode/461a364c-5884-44f6-87d9-ae749cc08f24" + }, + "response": { + "bodySize": 255, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 255, + "text": "{\"_id\":\"461a364c-5884-44f6-87d9-ae749cc08f24\",\"_rev\":\"2126257365\",\"_type\":{\"_id\":\"DataStoreDecisionNode\",\"name\":\"Data Store Decision\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"true\",\"displayName\":\"True\"},{\"id\":\"false\",\"displayName\":\"False\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"2126257365\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "255" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:32 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:32.345Z", + "time": 92, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 92 + } + }, + { + "_id": "a2a002a6997aa65a77fc50e45ffd85ad", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1152, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1152" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2027, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"FrodoTestJourney12\",\"identityResource\":\"managed/alpha_user\",\"entryNodeId\":\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\",\"innerTreeOnly\":false,\"description\":\"Test journey for custom nodes\",\"noSession\":false,\"mustRun\":false,\"enabled\":true,\"transactionalOnly\":false,\"uiConfig\":{\"categories\":\"[]\",\"annotations\":\"{\\\"forNodes\\\":{},\\\"structural\\\":[]}\"},\"nodes\":{\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\":{\"x\":463,\"y\":80,\"connections\":{\"outcome\":\"461a364c-5884-44f6-87d9-ae749cc08f24\"},\"nodeType\":\"PageNode\",\"displayName\":\"Login Page\"},\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\":{\"x\":210,\"y\":161,\"connections\":{\"True\":\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\",\"False\":\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\"},\"nodeType\":\"designer-session\",\"displayName\":\"Has Session AM\"},\"461a364c-5884-44f6-87d9-ae749cc08f24\":{\"x\":734,\"y\":161,\"connections\":{\"true\":\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\",\"false\":\"e301438c-0bd0-429c-ab0c-66126501069a\"},\"nodeType\":\"DataStoreDecisionNode\",\"displayName\":\"Data Store Decision\"}},\"staticNodes\":{\"startNode\":{\"x\":70,\"y\":188},\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\":{\"x\":1014,\"y\":102},\"e301438c-0bd0-429c-ab0c-66126501069a\":{\"x\":1014,\"y\":241}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/FrodoTestJourney12" + }, + "response": { + "bodySize": 1172, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1172, + "text": "{\"_id\":\"FrodoTestJourney12\",\"_rev\":\"-268378089\",\"identityResource\":\"managed/alpha_user\",\"entryNodeId\":\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\",\"innerTreeOnly\":false,\"description\":\"Test journey for custom nodes\",\"noSession\":false,\"mustRun\":false,\"enabled\":true,\"transactionalOnly\":false,\"uiConfig\":{\"categories\":\"[]\",\"annotations\":\"{\\\"forNodes\\\":{},\\\"structural\\\":[]}\"},\"nodes\":{\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\":{\"x\":463,\"y\":80,\"connections\":{\"outcome\":\"461a364c-5884-44f6-87d9-ae749cc08f24\"},\"nodeType\":\"PageNode\",\"displayName\":\"Login Page\"},\"8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb\":{\"x\":210,\"y\":161,\"connections\":{\"True\":\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\",\"False\":\"0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97\"},\"nodeType\":\"designer-session\",\"displayName\":\"Has Session AM\"},\"461a364c-5884-44f6-87d9-ae749cc08f24\":{\"x\":734,\"y\":161,\"connections\":{\"true\":\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\",\"false\":\"e301438c-0bd0-429c-ab0c-66126501069a\"},\"nodeType\":\"DataStoreDecisionNode\",\"displayName\":\"Data Store Decision\"}},\"staticNodes\":{\"startNode\":{\"x\":70,\"y\":188},\"70e691a5-1e33-4ac3-a356-e7b6d60d92e0\":{\"x\":1014,\"y\":102},\"e301438c-0bd0-429c-ab0c-66126501069a\":{\"x\":1014,\"y\":241}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-268378089\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1172" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 16:56:32 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-76de093e-042b-41eb-b05f-99d10e83f337" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 752, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T16:56:32.443Z", + "time": 139, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 139 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/createCustomNode_2029579653/1-Create-custom-node_3964295767/recording.har b/src/test/mock-recordings/NodeApi_1241226927/createCustomNode_2029579653/1-Create-custom-node_3964295767/recording.har new file mode 100644 index 000000000..6446a6496 --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/createCustomNode_2029579653/1-Create-custom-node_3964295767/recording.har @@ -0,0 +1,178 @@ +{ + "log": { + "_recordingName": "NodeApi/createCustomNode()/1: Create custom node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "6779d5a8def50c2a744c600e057a7b6c", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1550, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1550" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 1569, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1569, + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"249944700\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"249944700\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a6063fb2f5dc42dd9772bedc93898bd8-1" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1569" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 20:56:52 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 905, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a6063fb2f5dc42dd9772bedc93898bd8-1", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-10T20:56:52.798Z", + "time": 146, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 146 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/createNode_3265123738/1-Create-new-node-5227de7a-02db-4f25-858e-c8d4f0e0b600-SetStateNode_2109339458/recording.har b/src/test/mock-recordings/NodeApi_1241226927/createNode_3265123738/1-Create-new-node-5227de7a-02db-4f25-858e-c8d4f0e0b600-SetStateNode_2109339458/recording.har new file mode 100644 index 000000000..1eaaa4f93 --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/createNode_3265123738/1-Create-new-node-5227de7a-02db-4f25-858e-c8d4f0e0b600-SetStateNode_2109339458/recording.har @@ -0,0 +1,178 @@ +{ + "log": { + "_recordingName": "NodeApi/createNode()/1: Create new node [5227de7a-02db-4f25-858e-c8d4f0e0b600 - SetStateNode]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "3e88a143b767283bbb5c95c9cd1aa0f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 240, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-9a4836d5-7283-4c03-9157-d00933eee209" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "240" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2057, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 23:26:44 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-9a4836d5-7283-4c03-9157-d00933eee209" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 975, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-10T23:26:43.849Z", + "time": 182, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 182 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/1-Delete-existing-custom-node-a15e2efb3deb4d4ea338c74a6440b69f-1_577392640/recording.har b/src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/1-Delete-existing-custom-node-a15e2efb3deb4d4ea338c74a6440b69f-1_577392640/recording.har new file mode 100644 index 000000000..08f7d1ac8 --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/1-Delete-existing-custom-node-a15e2efb3deb4d4ea338c74a6440b69f-1_577392640/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeApi/deleteCustomNode()/1: Delete existing custom node [a15e2efb3deb4d4ea338c74a6440b69f-1]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "b4eb15d9815c3a216d47fbd8587b6983", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1969, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1" + }, + "response": { + "bodySize": 44, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 44, + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "44" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 20:56:53 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-10T20:56:53.330Z", + "time": 350, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 350 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node-11111111111111111111111111111111-1_3308823964/recording.har b/src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node-11111111111111111111111111111111-1_3308823964/recording.har new file mode 100644 index 000000000..b1aafc8a5 --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node-11111111111111111111111111111111-1_3308823964/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeApi/deleteCustomNode()/2: Delete non-existing custom node [11111111111111111111111111111111-1]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "a22ce1c31cda3365994ce70dc28d29cc", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1969, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/11111111111111111111111111111111-1" + }, + "response": { + "bodySize": 122, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 122, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Node Type with resource ID 11111111111111111111111111111111-1 does not exist\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "122" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 20:56:53 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-10T20:56:53.687Z", + "time": 88, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 88 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har b/src/test/mock-recordings/NodeApi_1241226927/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har new file mode 100644 index 000000000..641a2c6e2 --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har @@ -0,0 +1,166 @@ +{ + "log": { + "_recordingName": "NodeApi/getCustomNodeUsage()/1: Get custom node usage [a605506774a848f7877b4d17a453bd39-1]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "355f16fd5fbfbb12e2d7c2d676811949", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-a23abc05-645c-475d-8cec-2448c0d8ff84" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1984, + "httpVersion": "HTTP/1.1", + "method": "POST", + "queryString": [ + { + "name": "_action", + "value": "journeys" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a605506774a848f7877b4d17a453bd39-1?_action=journeys" + }, + "response": { + "bodySize": 2, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 2, + "text": "{}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "2" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 00:33:08 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-a23abc05-645c-475d-8cec-2448c0d8ff84" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 764, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T00:33:08.899Z", + "time": 93, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 93 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/1-Get-existing-custom-node-a605506774a848f7877b4d17a453bd39-1_1914184324/recording.har b/src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/1-Get-existing-custom-node-a605506774a848f7877b4d17a453bd39-1_1914184324/recording.har new file mode 100644 index 000000000..edbe0812c --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/1-Get-existing-custom-node-a605506774a848f7877b4d17a453bd39-1_1914184324/recording.har @@ -0,0 +1,165 @@ +{ + "log": { + "_recordingName": "NodeApi/getCustomNode()/1: Get existing custom node [a605506774a848f7877b4d17a453bd39-1]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "0fd5b8444ee4325c096dbe851da4a968", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1966, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a605506774a848f7877b4d17a453bd39-1" + }, + "response": { + "bodySize": 538, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 538, + "text": "{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"1177267832\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1177267832\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "538" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 20:56:53 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-10T20:56:53.044Z", + "time": 70, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 70 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/2-Get-non-existing-custom-node-11111111111111111111111111111111-1_1204087401/recording.har b/src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/2-Get-non-existing-custom-node-11111111111111111111111111111111-1_1204087401/recording.har new file mode 100644 index 000000000..0141e41c6 --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/getCustomNode_1016170563/2-Get-non-existing-custom-node-11111111111111111111111111111111-1_1204087401/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeApi/getCustomNode()/2: Get non-existing custom node [11111111111111111111111111111111-1]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "f3d0ad4d6248ae44e695553bb05bac8d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1966, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/11111111111111111111111111111111-1" + }, + "response": { + "bodySize": 122, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 122, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Node Type with resource ID 11111111111111111111111111111111-1 does not exist\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "122" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 20:56:53 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-10T20:56:53.125Z", + "time": 69, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 69 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/getCustomNodes_3622984558/1-Get-all-custom-nodes_3599720857/recording.har b/src/test/mock-recordings/NodeApi_1241226927/getCustomNodes_3622984558/1-Get-all-custom-nodes_3599720857/recording.har new file mode 100644 index 000000000..f84f2aadc --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/getCustomNodes_3622984558/1-Get-all-custom-nodes_3599720857/recording.har @@ -0,0 +1,162 @@ +{ + "log": { + "_recordingName": "NodeApi/getCustomNodes()/1: Get all custom nodes", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-5ffe757d-7e28-48b3-b768-562663c3c9bf" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 38330, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 38330, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"594973911\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"1736156056\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"2075177108\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-628951673\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"1253294564\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"session-1\",\"_rev\":\"490056204\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"1113564678\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"-1941250080\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"2077288621\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"1554001423\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}}],\"resultCount\":10,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":10,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:35:23 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-5ffe757d-7e28-48b3-b768-562663c3c9bf" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T16:35:23.624Z", + "time": 111, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 111 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/putCustomNode_1758137090/1-Update-existing-custom-node-aaaa3fb2f5dc42dd9772bedc93898bd8-1_446967736/recording.har b/src/test/mock-recordings/NodeApi_1241226927/putCustomNode_1758137090/1-Update-existing-custom-node-aaaa3fb2f5dc42dd9772bedc93898bd8-1_446967736/recording.har new file mode 100644 index 000000000..c5a0186bc --- /dev/null +++ b/src/test/mock-recordings/NodeApi_1241226927/putCustomNode_1758137090/1-Update-existing-custom-node-aaaa3fb2f5dc42dd9772bedc93898bd8-1_446967736/recording.har @@ -0,0 +1,178 @@ +{ + "log": { + "_recordingName": "NodeApi/putCustomNode()/1: Update existing custom node [aaaa3fb2f5dc42dd9772bedc93898bd8-1]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "01301945c173e73f762aebd7509b339b", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1832, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "1832" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2001, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 1852, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1852, + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"1871053300\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1871053300\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1852" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 20:56:53 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-21a47d0e-f8d4-4542-978c-06e67383be15" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-10T20:56:53.209Z", + "time": 110, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 110 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/1-Create-new-node-18ffdd4b-41b7-41b3-8248-f4fdfd68423f-ValidatedPasswordNode_2011968362/recording.har b/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/1-Create-new-node-18ffdd4b-41b7-41b3-8248-f4fdfd68423f-ValidatedPasswordNode_2011968362/recording.har index ce077f48b..af399913d 100644 --- a/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/1-Create-new-node-18ffdd4b-41b7-41b3-8248-f4fdfd68423f-ValidatedPasswordNode_2011968362/recording.har +++ b/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/1-Create-new-node-18ffdd4b-41b7-41b3-8248-f4fdfd68423f-ValidatedPasswordNode_2011968362/recording.har @@ -8,11 +8,11 @@ }, "entries": [ { - "_id": "2a1e8c93a7b3ec83607ce2c34b5142ea", + "_id": "4fc07fd7506192c91217ef29f3193589", "_order": 0, "cache": {}, "request": { - "bodySize": 194, + "bodySize": 239, "cookies": [], "headers": [ { @@ -25,11 +25,11 @@ }, { "name": "user-agent", - "value": "@rockcarver/frodo-lib/2.0.0-32" + "value": "@rockcarver/frodo-lib/3.3.3" }, { "name": "x-forgerock-transactionid", - "value": "frodo-a17956a8-ed35-4434-90a1-a8d44298b7b0" + "value": "frodo-9a4836d5-7283-4c03-9157-d00933eee209" }, { "name": "accept-api-version", @@ -41,30 +41,34 @@ }, { "name": "content-length", - "value": 194 + "value": "239" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" }, { "name": "host", "value": "openam-frodo-dev.forgeblocks.com" } ], - "headersSize": 1703, + "headersSize": 2066, "httpVersion": "HTTP/1.1", "method": "PUT", "postData": { "mimeType": "application/json", "params": [], - "text": "{\"validateInput\":false,\"passwordAttribute\":\"password\",\"_type\":{\"_id\":\"ValidatedPasswordNode\",\"name\":\"Platform Password\",\"collection\":true},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + "text": "{\"_id\":\"18ffdd4b-41b7-41b3-8248-f4fdfd68423f\",\"validateInput\":false,\"passwordAttribute\":\"password\",\"_type\":{\"_id\":\"ValidatedPasswordNode\",\"name\":\"Platform Password\",\"collection\":true},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" }, "queryString": [], "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/ValidatedPasswordNode/18ffdd4b-41b7-41b3-8248-f4fdfd68423f" }, "response": { - "bodySize": 260, + "bodySize": 276, "content": { "mimeType": "application/json;charset=UTF-8", - "size": 260, - "text": "{\"_id\":\"18ffdd4b-41b7-41b3-8248-f4fdfd68423f\",\"_rev\":\"-1456614726\",\"validateInput\":false,\"passwordAttribute\":\"password\",\"_type\":{\"_id\":\"ValidatedPasswordNode\",\"name\":\"Platform Password\",\"collection\":true},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + "size": 276, + "text": "{\"_id\":\"18ffdd4b-41b7-41b3-8248-f4fdfd68423f\",\"_rev\":\"-1272777657\",\"validateInput\":false,\"passwordAttribute\":\"password\",\"_type\":{\"_id\":\"ValidatedPasswordNode\",\"name\":\"Platform Password\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" }, "cookies": [], "headers": [ @@ -102,12 +106,16 @@ }, { "name": "etag", - "value": "\"-1456614726\"" + "value": "\"-1272777657\"" }, { "name": "expires", "value": "0" }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/ValidatedPasswordNode/18ffdd4b-41b7-41b3-8248-f4fdfd68423f" + }, { "name": "pragma", "value": "no-cache" @@ -118,20 +126,24 @@ }, { "name": "content-length", - "value": "260" + "value": "276" }, { "name": "date", - "value": "Sat, 30 Sep 2023 19:49:03 GMT" + "value": "Mon, 10 Nov 2025 23:26:44 GMT" }, { "name": "x-forgerock-transactionid", - "value": "frodo-a17956a8-ed35-4434-90a1-a8d44298b7b0" + "value": "frodo-9a4836d5-7283-4c03-9157-d00933eee209" }, { "name": "strict-transport-security", "value": "max-age=31536000; includeSubDomains; preload;" }, + { + "name": "x-robots-tag", + "value": "none" + }, { "name": "via", "value": "1.1 google" @@ -141,14 +153,14 @@ "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" } ], - "headersSize": 767, + "headersSize": 985, "httpVersion": "HTTP/1.1", - "redirectURL": "", - "status": 200, - "statusText": "OK" + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/ValidatedPasswordNode/18ffdd4b-41b7-41b3-8248-f4fdfd68423f", + "status": 201, + "statusText": "Created" }, - "startedDateTime": "2023-09-30T19:49:04.084Z", - "time": 79, + "startedDateTime": "2025-11-10T23:26:44.045Z", + "time": 192, "timings": { "blocked": -1, "connect": -1, @@ -156,7 +168,7 @@ "receive": 0, "send": 0, "ssl": -1, - "wait": 79 + "wait": 192 } } ], diff --git a/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/2-Update-existing-node-b726262c-641e-4fa5-b276-98e129b44cd9-PatchObjectNode_3788241750/recording.har b/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/2-Update-existing-node-b726262c-641e-4fa5-b276-98e129b44cd9-PatchObjectNode_3788241750/recording.har index 3955e00e9..79c7fd356 100644 --- a/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/2-Update-existing-node-b726262c-641e-4fa5-b276-98e129b44cd9-PatchObjectNode_3788241750/recording.har +++ b/src/test/mock-recordings/NodeApi_1241226927/putNode_2023210989/2-Update-existing-node-b726262c-641e-4fa5-b276-98e129b44cd9-PatchObjectNode_3788241750/recording.har @@ -8,11 +8,11 @@ }, "entries": [ { - "_id": "567225d05c540e8cea67eaa8f35ee6de", + "_id": "e6cf499c0a4cedf40859b63ecb0f3b82", "_order": 0, "cache": {}, "request": { - "bodySize": 276, + "bodySize": 321, "cookies": [], "headers": [ { @@ -25,11 +25,11 @@ }, { "name": "user-agent", - "value": "@rockcarver/frodo-lib/2.0.0-32" + "value": "@rockcarver/frodo-lib/3.3.3" }, { "name": "x-forgerock-transactionid", - "value": "frodo-a17956a8-ed35-4434-90a1-a8d44298b7b0" + "value": "frodo-9a4836d5-7283-4c03-9157-d00933eee209" }, { "name": "accept-api-version", @@ -41,30 +41,34 @@ }, { "name": "content-length", - "value": 276 + "value": "321" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" }, { "name": "host", "value": "openam-frodo-dev.forgeblocks.com" } ], - "headersSize": 1697, + "headersSize": 2060, "httpVersion": "HTTP/1.1", "method": "PUT", "postData": { "mimeType": "application/json", "params": [], - "text": "{\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" }, "queryString": [], "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9" }, "response": { - "bodySize": 342, + "bodySize": 358, "content": { "mimeType": "application/json;charset=UTF-8", - "size": 342, - "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"_rev\":\"-2080259640\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + "size": 358, + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"_rev\":\"-1625726187\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" }, "cookies": [], "headers": [ @@ -102,7 +106,7 @@ }, { "name": "etag", - "value": "\"-2080259640\"" + "value": "\"-1625726187\"" }, { "name": "expires", @@ -118,20 +122,24 @@ }, { "name": "content-length", - "value": "342" + "value": "358" }, { "name": "date", - "value": "Sat, 30 Sep 2023 19:49:03 GMT" + "value": "Mon, 10 Nov 2025 23:26:44 GMT" }, { "name": "x-forgerock-transactionid", - "value": "frodo-a17956a8-ed35-4434-90a1-a8d44298b7b0" + "value": "frodo-9a4836d5-7283-4c03-9157-d00933eee209" }, { "name": "strict-transport-security", "value": "max-age=31536000; includeSubDomains; preload;" }, + { + "name": "x-robots-tag", + "value": "none" + }, { "name": "via", "value": "1.1 google" @@ -141,14 +149,14 @@ "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" } ], - "headersSize": 767, + "headersSize": 787, "httpVersion": "HTTP/1.1", "redirectURL": "", "status": 200, "statusText": "OK" }, - "startedDateTime": "2023-09-30T19:49:04.173Z", - "time": 85, + "startedDateTime": "2025-11-10T23:26:44.248Z", + "time": 98, "timings": { "blocked": -1, "connect": -1, @@ -156,7 +164,7 @@ "receive": 0, "send": 0, "ssl": -1, - "wait": 85 + "wait": 98 } } ], diff --git a/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/1-Create-new-node-with-id_2113523129/recording.har b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/1-Create-new-node-with-id_2113523129/recording.har new file mode 100644 index 000000000..38d66d70b --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/1-Create-new-node-with-id_2113523129/recording.har @@ -0,0 +1,472 @@ +{ + "log": { + "_recordingName": "NodeOps/createNode()/1: Create new node with id", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "0c23ba5766dbcd6dd561c65f46a01508", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2039, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 55, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 55, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Not Found\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "55" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:09 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-11T00:18:09.145Z", + "time": 68, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 68 + } + }, + { + "_id": "ed254f287d8b017d49e56318547b172a", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2036, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 55, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 55, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Not Found\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "55" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:09 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-11T00:18:09.220Z", + "time": 66, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 66 + } + }, + { + "_id": "3e88a143b767283bbb5c95c9cd1aa0f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 240, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "240" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2057, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:09 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 975, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:18:09.298Z", + "time": 238, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 238 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/2-Create-new-node-without-id_3214205544/recording.har b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/2-Create-new-node-without-id_3214205544/recording.har new file mode 100644 index 000000000..c2216634c --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/2-Create-new-node-without-id_3214205544/recording.har @@ -0,0 +1,334 @@ +{ + "log": { + "_recordingName": "NodeOps/createNode()/2: Create new node without id", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "0c23ba5766dbcd6dd561c65f46a01508", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2039, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:09 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:18:09.549Z", + "time": 211, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 211 + } + }, + { + "_id": "3be4c47172df4f49d4afe7d2a9a3e639", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 240, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, deflate, br" + }, + { + "name": "content-length", + "value": "240" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2026, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [ + { + "name": "_action", + "value": "create" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode?_action=create" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:09 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 975, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:18:09.767Z", + "time": 187, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 187 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/3-Create-existing-node-by-id_1394702125/recording.har b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/3-Create-existing-node-by-id_1394702125/recording.har new file mode 100644 index 000000000..ee7ee5b99 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/3-Create-existing-node-by-id_1394702125/recording.har @@ -0,0 +1,480 @@ +{ + "log": { + "_recordingName": "NodeOps/createNode()/3: Create existing node by id", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "0c23ba5766dbcd6dd561c65f46a01508", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2039, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:10 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:18:09.969Z", + "time": 268, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 268 + } + }, + { + "_id": "3e88a143b767283bbb5c95c9cd1aa0f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 240, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "240" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2057, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:10 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 975, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:18:10.244Z", + "time": 205, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 205 + } + }, + { + "_id": "ed254f287d8b017d49e56318547b172a", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2036, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:10 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:18:10.456Z", + "time": 109, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 109 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/4-Create-existing-node-without-id_833852283/recording.har b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/4-Create-existing-node-without-id_833852283/recording.har new file mode 100644 index 000000000..46cad8d20 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/createNode_3265123738/4-Create-existing-node-without-id_833852283/recording.har @@ -0,0 +1,490 @@ +{ + "log": { + "_recordingName": "NodeOps/createNode()/4: Create existing node without id", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "0c23ba5766dbcd6dd561c65f46a01508", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2039, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:10 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:18:10.574Z", + "time": 238, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 238 + } + }, + { + "_id": "3e88a143b767283bbb5c95c9cd1aa0f1", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 240, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "240" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2057, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + "response": { + "bodySize": 260, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 260, + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"_rev\":\"1797046015\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1797046015\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "260" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:11 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 975, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode/5227de7a-02db-4f25-858e-c8d4f0e0b600", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:18:10.863Z", + "time": 179, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 179 + } + }, + { + "_id": "3be4c47172df4f49d4afe7d2a9a3e639", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 240, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, deflate, br" + }, + { + "name": "content-length", + "value": "240" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2026, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"5227de7a-02db-4f25-858e-c8d4f0e0b600\",\"attributes\":{\"errorMessage\":\"An error has occurred!\"},\"_type\":{\"_id\":\"SetStateNode\",\"name\":\"Set State\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"outcome\"}]}" + }, + "queryString": [ + { + "name": "_action", + "value": "create" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/SetStateNode?_action=create" + }, + "response": { + "bodySize": 90, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 90, + "text": "{\"code\":409,\"reason\":\"Conflict\",\"message\":\"Unable to save config: Service already exists\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "90" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:18:11 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8bc9a033-edfe-4476-8732-bbff992f5a99" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 409, + "statusText": "Conflict" + }, + "startedDateTime": "2025-11-11T00:18:11.049Z", + "time": 85, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 85 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/1-Delete-existing-custom-node-by-id_580138965/recording.har b/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/1-Delete-existing-custom-node-by-id_580138965/recording.har new file mode 100644 index 000000000..35109974c --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/1-Delete-existing-custom-node-by-id_580138965/recording.har @@ -0,0 +1,325 @@ +{ + "log": { + "_recordingName": "NodeOps/deleteCustomNode()/1: Delete existing custom node by id", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "b4eb15d9815c3a216d47fbd8587b6983", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-f7c830d7-65d6-4b23-aca6-4a266f40b15a" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1969, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1" + }, + "response": { + "bodySize": 44, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 44, + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "44" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 01:00:34 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-f7c830d7-65d6-4b23-aca6-4a266f40b15a" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T01:00:34.543Z", + "time": 228, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 228 + } + }, + { + "_id": "12a30e40d7dd11aaef5372e6333869c2", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 2327, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-f7c830d7-65d6-4b23-aca6-4a266f40b15a" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "2327" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 2347, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 2347, + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-681298522\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-681298522\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "2347" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 01:00:34 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-f7c830d7-65d6-4b23-aca6-4a266f40b15a" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 906, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T01:00:34.776Z", + "time": 136, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 136 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node_3331521686/recording.har b/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node_3331521686/recording.har new file mode 100644 index 000000000..e00f4acad --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/2-Delete-non-existing-custom-node_3331521686/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeOps/deleteCustomNode()/2: Delete non-existing custom node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "a22ce1c31cda3365994ce70dc28d29cc", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-9f4c1ba1-ea93-49c1-a730-f2b266d48770" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1969, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/11111111111111111111111111111111-1" + }, + "response": { + "bodySize": 122, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 122, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Node Type with resource ID 11111111111111111111111111111111-1 does not exist\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "122" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:45:26 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-9f4c1ba1-ea93-49c1-a730-f2b266d48770" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-11T00:45:26.809Z", + "time": 63, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 63 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/3-Delete-existing-custom-node-by-name_491988969/recording.har b/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/3-Delete-existing-custom-node-by-name_491988969/recording.har new file mode 100644 index 000000000..bbdda1fe6 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/deleteCustomNode_2631021918/3-Delete-existing-custom-node-by-name_491988969/recording.har @@ -0,0 +1,465 @@ +{ + "log": { + "_recordingName": "NodeOps/deleteCustomNode()/3: Delete existing custom node by name", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "b4eb15d9815c3a216d47fbd8587b6983", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-46b82293-193d-4f98-b84b-23c047eedd2a" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1969, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1" + }, + "response": { + "bodySize": 44, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 44, + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "44" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:29:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-46b82293-193d-4f98-b84b-23c047eedd2a" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 655, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T16:29:39.864Z", + "time": 220, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 220 + } + }, + { + "_id": "12a30e40d7dd11aaef5372e6333869c2", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 2327, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-46b82293-193d-4f98-b84b-23c047eedd2a" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "2327" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 2347, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 2347, + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-951348208\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-951348208\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "2347" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:29:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-46b82293-193d-4f98-b84b-23c047eedd2a" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 796, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-12-18T16:29:40.091Z", + "time": 222, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 222 + } + }, + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-46b82293-193d-4f98-b84b-23c047eedd2a" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 38329, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 38329, + "text": "{\"result\":[{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"172104099\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"594973911\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"1578984014\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-628951673\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"1253294564\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"1113564678\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"session-1\",\"_rev\":\"490056204\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"-1941250080\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-951348208\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"1554001423\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}}],\"resultCount\":10,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":10,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:29:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-46b82293-193d-4f98-b84b-23c047eedd2a" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T16:29:40.321Z", + "time": 103, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 103 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/1-Delete-existing-node_273846342/recording.har b/src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/1-Delete-existing-node_273846342/recording.har new file mode 100644 index 000000000..1150dcd64 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/1-Delete-existing-node_273846342/recording.har @@ -0,0 +1,165 @@ +{ + "log": { + "_recordingName": "NodeOps/deleteNode()/1: Delete existing node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "aa47aa205e6d9b3428a8e78ad7060f34", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-bb4fc560-36fa-4d91-83d3-9ab2daaebd2d" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2043, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/CreateObjectNode/23bab9d4-1663-450f-8a4b-680f44f54fd6" + }, + "response": { + "bodySize": 287, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 287, + "text": "{\"_id\":\"23bab9d4-1663-450f-8a4b-680f44f54fd6\",\"_rev\":\"1983463508\",\"identityResource\":\"managed/user\",\"_type\":{\"_id\":\"CreateObjectNode\",\"name\":\"Create Object\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"CREATED\",\"displayName\":\"Created\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1983463508\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "287" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:29:15 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-bb4fc560-36fa-4d91-83d3-9ab2daaebd2d" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:29:15.727Z", + "time": 184, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 184 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/2-Delete-non-existing-node_1726654525/recording.har b/src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/2-Delete-non-existing-node_1726654525/recording.har new file mode 100644 index 000000000..2792b7c20 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/deleteNode_2473664889/2-Delete-non-existing-node_1726654525/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeOps/deleteNode()/2: Delete non-existing node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "81bdb374a328436152a96f112b66101e", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-bb4fc560-36fa-4d91-83d3-9ab2daaebd2d" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2035, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PageNode/00000000-0000-0000-0000-000000000000" + }, + "response": { + "bodySize": 55, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 55, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Not Found\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "55" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:29:16 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-bb4fc560-36fa-4d91-83d3-9ab2daaebd2d" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-11T00:29:15.925Z", + "time": 92, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 92 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/1-Export-existing-custom-node-by-ID_4135699686/recording.har b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/1-Export-existing-custom-node-by-ID_4135699686/recording.har new file mode 100644 index 000000000..f2e0b8434 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/1-Export-existing-custom-node-by-ID_4135699686/recording.har @@ -0,0 +1,165 @@ +{ + "log": { + "_recordingName": "NodeOps/exportCustomNode()/1: Export existing custom node by ID", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "0fd5b8444ee4325c096dbe851da4a968", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-93254ccf-7611-47d8-80be-c5cc23a2a645" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1966, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a605506774a848f7877b4d17a453bd39-1" + }, + "response": { + "bodySize": 538, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 538, + "text": "{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"1089949934\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1089949934\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "538" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:38:33 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-93254ccf-7611-47d8-80be-c5cc23a2a645" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:38:33.713Z", + "time": 63, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 63 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/2-Export-non-existing-custom-node_4081094025/recording.har b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/2-Export-non-existing-custom-node_4081094025/recording.har new file mode 100644 index 000000000..930a9e102 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/2-Export-non-existing-custom-node_4081094025/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeOps/exportCustomNode()/2: Export non-existing custom node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "f3d0ad4d6248ae44e695553bb05bac8d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-93254ccf-7611-47d8-80be-c5cc23a2a645" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1966, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/11111111111111111111111111111111-1" + }, + "response": { + "bodySize": 122, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 122, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Node Type with resource ID 11111111111111111111111111111111-1 does not exist\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "122" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:38:33 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-93254ccf-7611-47d8-80be-c5cc23a2a645" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-11T00:38:33.791Z", + "time": 57, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 57 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/3-Export-existing-custom-node-by-name_3299881190/recording.har b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/3-Export-existing-custom-node-by-name_3299881190/recording.har new file mode 100644 index 000000000..95e95b045 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNode_1320797343/3-Export-existing-custom-node-by-name_3299881190/recording.har @@ -0,0 +1,162 @@ +{ + "log": { + "_recordingName": "NodeOps/exportCustomNode()/3: Export existing custom node by name", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 38331, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 38331, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"594973911\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"1177790320\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-628951673\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"1253294564\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"1113564678\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"session-1\",\"_rev\":\"490056204\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"-1941250080\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-1807621590\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"1086162449\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"1554001423\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}}],\"resultCount\":10,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":10,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:25:02 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T16:25:02.054Z", + "time": 103, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 103 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/exportCustomNodes_1729513026/1-Export-custom-nodes_1354206594/recording.har b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNodes_1729513026/1-Export-custom-nodes_1354206594/recording.har new file mode 100644 index 000000000..898ddec19 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/exportCustomNodes_1729513026/1-Export-custom-nodes_1354206594/recording.har @@ -0,0 +1,162 @@ +{ + "log": { + "_recordingName": "NodeOps/exportCustomNodes()/1: Export custom nodes", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 38331, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 38331, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"594973911\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"1177790320\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-628951673\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"1253294564\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"1113564678\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"session-1\",\"_rev\":\"490056204\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"-1941250080\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-1807621590\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"1086162449\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"1554001423\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}}],\"resultCount\":10,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":10,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:25:02 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T16:25:02.170Z", + "time": 75, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 75 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har b/src/test/mock-recordings/NodeOps_3921382371/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har new file mode 100644 index 000000000..f545c2802 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/getCustomNodeUsage_2935368156/1-Get-custom-node-usage-a605506774a848f7877b4d17a453bd39-1_1039697978/recording.har @@ -0,0 +1,166 @@ +{ + "log": { + "_recordingName": "NodeOps/getCustomNodeUsage()/1: Get custom node usage [a605506774a848f7877b4d17a453bd39-1]", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "355f16fd5fbfbb12e2d7c2d676811949", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-9dc38eb8-ba4d-4ff2-9a7f-97753cc51a0a" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1984, + "httpVersion": "HTTP/1.1", + "method": "POST", + "queryString": [ + { + "name": "_action", + "value": "journeys" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a605506774a848f7877b4d17a453bd39-1?_action=journeys" + }, + "response": { + "bodySize": 2, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 2, + "text": "{}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "2" + }, + { + "name": "date", + "value": "Thu, 13 Nov 2025 00:43:46 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-9dc38eb8-ba4d-4ff2-9a7f-97753cc51a0a" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 764, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-13T00:43:46.671Z", + "time": 112, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 112 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/2-Import-by-ID_3996169380/recording.har b/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/2-Import-by-ID_3996169380/recording.har new file mode 100644 index 000000000..c1809cf00 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/2-Import-by-ID_3996169380/recording.har @@ -0,0 +1,178 @@ +{ + "log": { + "_recordingName": "NodeOps/importCustomNodes()/2: Import by ID", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "6779d5a8def50c2a744c600e057a7b6c", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1550, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1550" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 1570, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1570, + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"-121767584\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-121767584\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a6063fb2f5dc42dd9772bedc93898bd8-1" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1570" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:03 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 906, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a6063fb2f5dc42dd9772bedc93898bd8-1", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:58:03.108Z", + "time": 141, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 141 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/3-Import-by-Name_237557869/recording.har b/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/3-Import-by-Name_237557869/recording.har new file mode 100644 index 000000000..3e6e1077b --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/3-Import-by-Name_237557869/recording.har @@ -0,0 +1,334 @@ +{ + "log": { + "_recordingName": "NodeOps/importCustomNodes()/3: Import by Name", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "6779d5a8def50c2a744c600e057a7b6c", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1550, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1550" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 119, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 119, + "text": "{\"code\":409,\"reason\":\"Conflict\",\"message\":\"Node Type with resource id a6063fb2f5dc42dd9772bedc93898bd8 already exists\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "119" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:03 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 409, + "statusText": "Conflict" + }, + "startedDateTime": "2025-11-11T00:58:03.261Z", + "time": 63, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 63 + } + }, + { + "_id": "f6a362f7ece65aebae5e20b942646342", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1550, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "1550" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2001, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a6063fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 1570, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1570, + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"-756969277\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-756969277\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1570" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:03 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:58:03.339Z", + "time": 193, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 193 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/4-Import-all_2873519115/recording.har b/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/4-Import-all_2873519115/recording.har new file mode 100644 index 000000000..c7af67967 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/importCustomNodes_3278097671/4-Import-all_2873519115/recording.har @@ -0,0 +1,974 @@ +{ + "log": { + "_recordingName": "NodeOps/importCustomNodes()/4: Import all", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "7c2add208843d7267e919d70cf79b9fe", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1832, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1832" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 119, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 119, + "text": "{\"code\":409,\"reason\":\"Conflict\",\"message\":\"Node Type with resource id aaaa3fb2f5dc42dd9772bedc93898bd8 already exists\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "119" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:03 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 409, + "statusText": "Conflict" + }, + "startedDateTime": "2025-11-11T00:58:03.541Z", + "time": 69, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 69 + } + }, + { + "_id": "01301945c173e73f762aebd7509b339b", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1832, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "1832" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2001, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 1851, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1851, + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"984835321\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"984835321\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1851" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:03 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:58:03.616Z", + "time": 153, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 153 + } + }, + { + "_id": "6779d5a8def50c2a744c600e057a7b6c", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1550, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1550" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 119, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 119, + "text": "{\"code\":409,\"reason\":\"Conflict\",\"message\":\"Node Type with resource id a6063fb2f5dc42dd9772bedc93898bd8 already exists\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "119" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:03 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 409, + "statusText": "Conflict" + }, + "startedDateTime": "2025-11-11T00:58:03.775Z", + "time": 70, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 70 + } + }, + { + "_id": "f6a362f7ece65aebae5e20b942646342", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1550, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "1550" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2001, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a6063fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 1571, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1571, + "text": "{\"_id\":\"a6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"-1723210064\",\"serviceName\":\"a6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU - TEST\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1723210064\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1571" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:04 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 788, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:58:03.852Z", + "time": 161, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 161 + } + }, + { + "_id": "12a30e40d7dd11aaef5372e6333869c2", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 2327, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "2327" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 119, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 119, + "text": "{\"code\":409,\"reason\":\"Conflict\",\"message\":\"Node Type with resource id a15e2efb3deb4d4ea338c74a6440b69f already exists\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "119" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:04 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 409, + "statusText": "Conflict" + }, + "startedDateTime": "2025-11-11T00:58:04.018Z", + "time": 66, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 66 + } + }, + { + "_id": "026db9b7db021857171e5c71d9dad792", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 2327, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "2327" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2001, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a15e2efb3deb4d4ea338c74a6440b69f-1" + }, + "response": { + "bodySize": 2347, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 2347, + "text": "{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-623333120\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-623333120\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "2347" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:58:04 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-16ccbf75-d4f9-4e35-b121-899d67ff4721" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:58:04.090Z", + "time": 85, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 85 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/1-Read-existing-custom-node-by-ID_573989968/recording.har b/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/1-Read-existing-custom-node-by-ID_573989968/recording.har new file mode 100644 index 000000000..7c92d4382 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/1-Read-existing-custom-node-by-ID_573989968/recording.har @@ -0,0 +1,165 @@ +{ + "log": { + "_recordingName": "NodeOps/readCustomNode()/1: Read existing custom node by ID", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "0fd5b8444ee4325c096dbe851da4a968", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-156004d5-8488-4b82-9d2e-a98d0e880f45" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1966, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/a605506774a848f7877b4d17a453bd39-1" + }, + "response": { + "bodySize": 538, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 538, + "text": "{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"1354478386\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1354478386\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "538" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:33:43 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-156004d5-8488-4b82-9d2e-a98d0e880f45" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:33:43.113Z", + "time": 63, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 63 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/2-Read-non-existing-custom-node_1881359087/recording.har b/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/2-Read-non-existing-custom-node_1881359087/recording.har new file mode 100644 index 000000000..1f63a61df --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/2-Read-non-existing-custom-node_1881359087/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeOps/readCustomNode()/2: Read non-existing custom node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "f3d0ad4d6248ae44e695553bb05bac8d", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-156004d5-8488-4b82-9d2e-a98d0e880f45" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1966, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/11111111111111111111111111111111-1" + }, + "response": { + "bodySize": 122, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 122, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Node Type with resource ID 11111111111111111111111111111111-1 does not exist\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "122" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:33:43 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-156004d5-8488-4b82-9d2e-a98d0e880f45" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-11T00:33:43.189Z", + "time": 125, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 125 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/3-Read-existing-custom-node-by-name_1309848192/recording.har b/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/3-Read-existing-custom-node-by-name_1309848192/recording.har new file mode 100644 index 000000000..2b679fd93 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/readCustomNode_1281539917/3-Read-existing-custom-node-by-name_1309848192/recording.har @@ -0,0 +1,162 @@ +{ + "log": { + "_recordingName": "NodeOps/readCustomNode()/3: Read existing custom node by name", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 38331, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 38331, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"594973911\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"1177790320\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-628951673\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"1253294564\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"1113564678\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"session-1\",\"_rev\":\"490056204\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"-1941250080\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-1807621590\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"1086162449\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"1554001423\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}}],\"resultCount\":10,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":10,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:25:01 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T16:25:01.689Z", + "time": 85, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 85 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/readCustomNodes_561531088/1-Read-custom-nodes_2112965120/recording.har b/src/test/mock-recordings/NodeOps_3921382371/readCustomNodes_561531088/1-Read-custom-nodes_2112965120/recording.har new file mode 100644 index 000000000..66bbfe258 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/readCustomNodes_561531088/1-Read-custom-nodes_2112965120/recording.har @@ -0,0 +1,162 @@ +{ + "log": { + "_recordingName": "NodeOps/readCustomNodes()/1: Read custom nodes", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "cee51132a7193d5394b226be6da617dd", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1949, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [ + { + "name": "_queryFilter", + "value": "true" + } + ], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type?_queryFilter=true" + }, + "response": { + "bodySize": 38331, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 38331, + "text": "{\"result\":[{\"_id\":\"c6063fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"594973911\",\"serviceName\":\"c6063fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"ALU\",\"description\":\"Simple ALU that performs basic binary math operations. Expects an \\\"x\\\" and \\\"y\\\" value on the shared state, and will produce a new \\\"z\\\" value on the shared state as output.\",\"outcomes\":[\"Success\"],\"outputs\":[\"z\"],\"inputs\":[\"x\",\"y\"],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n MULTIPLY: \\\"MULTIPLY\\\",\\n DIVIDE: \\\"DIVIDE\\\"\\n}\\n\\nfunction main() {\\n var a = Number(properties.a);\\n var b = Number(properties.b);\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"z\\\", a + b);\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"z\\\", a - b);\\n break;\\n case OPERATORS.MULTIPLY:\\n nodeState.putShared(\\\"z\\\", a * b);\\n break;\\n case OPERATORS.DIVIDE:\\n if (b == 0) throw new Error(\\\"Cannot divide by 0\\\");\\n nodeState.putShared(\\\"z\\\", a / b);\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"utilities\"],\"properties\":{\"operator\":{\"title\":\"Operator\",\"description\":\"The operation to perform.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"ADD\",\"options\":{\"ADD\":\"+\",\"MULTIPLY\":\"*\",\"SUBTRACT\":\"-\",\"DIVIDE\":\"/\"},\"multivalued\":false}}},{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"1177790320\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"ef81b1a52c914710b3388caebfe7233a-1\",\"_rev\":\"-628951673\",\"serviceName\":\"ef81b1a52c914710b3388caebfe7233a\",\"displayName\":\"Display Callback\",\"description\":\"Displays custom callback to the page\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: 'outcome'\\n};\\n\\nvar CALLBACKS = {\\n\\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \\\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tCHOICE_CALLBACK: \\\"CHOICE_CALLBACK\\\",\\n\\tCONFIRMATION_CALLBACK: \\\"CONFIRMATION_CALLBACK\\\",\\n\\tCONSENT_MAPPING_CALLBACK: \\\"CONSENT_MAPPING_CALLBACK\\\",\\n\\tDEVICE_PROFILE_CALLBACK: \\\"DEVICE_PROFILE_CALLBACK\\\",\\n\\tHIDDEN_VALUE_CALLBACK: \\\"HIDDEN_VALUE_CALLBACK\\\",\\n\\tHTTP_CALLBACK: \\\"HTTP_CALLBACK\\\",\\n\\tIDP_CALLBACK: \\\"IDP_CALLBACK\\\",\\n\\tKBA_CREATE_CALLBACK: \\\"KBA_CREATE_CALLBACK\\\",\\n\\tLANGUAGE_CALLBACK: \\\"LANGUAGE_CALLBACK\\\",\\n\\tMETADATA_CALLBACK: \\\"METADATA_CALLBACK\\\",\\n\\tNAME_CALLBACK: \\\"NAME_CALLBACK\\\",\\n\\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \\\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tPASSWORD_CALLBACK: \\\"PASSWORD_CALLBACK\\\",\\n\\tPOLLING_WAIT_CALLBACK: \\\"POLLING_WAIT_CALLBACK\\\",\\n REDIRECT_CALLBACK: \\\"REDIRECT_CALLBACK\\\",\\n\\tSCRIPT_TEXT_OUTPUT_CALLBACK: \\\"SCRIPT_TEXT_OUTPUT_CALLBACK\\\",\\n\\tSELECT_IDP_CALLBACK: \\\"SELECT_IDP_CALLBACK\\\",\\n\\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \\\"STRING_ATTRIBUTE_INPUT_CALLBACK\\\",\\n\\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \\\"SUSPENDED_TEXT_OUTPUT_CALLBACK\\\",\\n\\tTERMS_AND_CONDITIONS_CALLBACK: \\\"TERMS_AND_CONDITIONS_CALLBACK\\\",\\n\\tTEXT_INPUT_CALLBACK: \\\"TEXT_INPUT_CALLBACK\\\",\\n\\tTEXT_OUTPUT_CALLBACK: \\\"TEXT_OUTPUT_CALLBACK\\\",\\n\\tVALIDATED_PASSWORD_CALLBACK: \\\"VALIDATED_PASSWORD_CALLBACK\\\",\\n\\tVALIDATED_USERNAME_CALLBACK: \\\"VALIDATED_USERNAME_CALLBACK\\\",\\n\\tX509_CERTIFICATE_CALLBACK: \\\"X509_CERTIFICATE_CALLBACK\\\"\\n}\\n\\nfunction isStringPresent(value) {\\n return value;\\n}\\n\\nfunction getString(value) {\\n return value || '';\\n}\\n\\nfunction isArrayPresent(value) {\\n return value;\\n}\\n\\nfunction getArray(value) {\\n return value ? JSON.parse(value) : [];\\n}\\n\\nfunction isObjectPresent(value) {\\n return value;\\n}\\n\\nfunction getObject(value) {\\n return value ? JSON.parse(value) : {};\\n}\\n\\nfunction isIntPresent(value) {\\n return value;\\n}\\n\\nfunction getInt(value) {\\n return value ? parseInt(value) : 0;\\n}\\n\\nfunction isDoublePresent(value) {\\n return value;\\n}\\n\\nfunction getDouble(value) {\\n return value ? parseFloat(value) : 0.0;\\n}\\n\\nfunction isBooleanPresent(value) {\\n return value;\\n}\\n\\nfunction getBoolean(value) {\\n return value ? value.toLowerCase() === 'true' : false;\\n}\\n\\nfunction setProperty(value) {\\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\\n if (properties.objectSharedProperty) {\\n var attributes = {};\\n attributes[properties.objectSharedProperty] = value;\\n nodeState.mergeShared({\\n objectAttributes: attributes\\n });\\n }\\n if (properties.objectTransientProperty) {\\n var attributes = {};\\n attributes[properties.objectTransientProperty] = value;\\n nodeState.mergeTransient({\\n objectAttributes: attributes\\n });\\n }\\n}\\n\\nfunction booleanAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getBoolean(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction choiceCallback() {\\n var prompt = getString(properties.options.prompt);\\n var choices = getArray(properties.options.choices);\\n var defaultChoice = getInt(properties.options.defaultChoice);\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\\n}\\n\\nfunction confirmationCallback() {\\n var prompt = getString(properties.options.prompt);\\n var messageType = getInt(properties.options.messageType);\\n var options = getArray(properties.options.options);\\n var optionType = getInt(properties.options.optionType);\\n var defaultOption = getInt(properties.options.defaultOption);\\n if (isStringPresent(properties.options.prompt)) {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\\n }\\n } else {\\n if (isIntPresent(properties.options.optionType)) {\\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\\n } else {\\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\\n }\\n }\\n}\\n\\nfunction consentMappingCallback() {\\n var config = getObject(properties.options.config);\\n var message = getString(properties.options.message);\\n var isRequired = getBoolean(properties.options.isRequired);\\n var name = getString(properties.options.name);\\n var displayName = getString(properties.options.displayName);\\n var icon = getString(properties.options.icon);\\n var accessLevel = getString(properties.options.accessLevel);\\n var titles = getArray(properties.options.titles);\\n if (isObjectPresent(properties.options.prompt)) {\\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\\n } else {\\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\\n }\\n}\\n\\nfunction deviceProfileCallback() {\\n var metadata = getBoolean(properties.options.metadata);\\n var location = getBoolean(properties.options.location);\\n var message = getString(properties.options.message);\\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\\n}\\n\\nfunction hiddenValueCallback() {\\n var id = getString(properties.options.id);\\n var value = getString(properties.options.value);\\n callbacksBuilder.hiddenValueCallback(id, value);\\n}\\n\\nfunction httpCallback() {\\n var authorizationHeader = getString(properties.options.authorizationHeader);\\n var negotiationHeader = getString(properties.options.negotiationHeader);\\n var authRHeader = getString(properties.options.authRHeader);\\n var negoName = getString(properties.options.negoName);\\n var negoValue = getString(properties.options.negoValue);\\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\\n var errorCode = getString(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\\n } else {\\n var errorCode = getInt(properties.options.errorCode);\\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\\n }\\n}\\n\\nfunction idPCallback() {\\n var provider = getString(properties.options.provider);\\n var clientId = getString(properties.options.clientId);\\n var redirectUri = getString(properties.options.redirectUri);\\n var scope = getArray(properties.options.scope);\\n var nonce = getString(properties.options.nonce);\\n var request = getString(properties.options.request);\\n var requestUri = getString(properties.options.requestUri);\\n var acrValues = getArray(properties.options.acrValues);\\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\\n var token = getString(properties.options.token);\\n var tokenType = getString(properties.options.tokenType);\\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\\n } else {\\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\\n }\\n}\\n\\nfunction kbaCreateCallback() {\\n var prompt = getString(properties.options.prompt);\\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\\n}\\n\\nfunction languageCallback() {\\n var language = getString(properties.options.language);\\n var country = getString(properties.options.country);\\n callbacksBuilder.languageCallback(language, country);\\n}\\n\\nfunction metadataCallback() {\\n var outputValue = getObject(properties.options.outputValue);\\n callbacksBuilder.metadataCallback(outputValue);\\n}\\n\\nfunction nameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultName = getString(properties.options.defaultName);\\n if (isStringPresent(properties.options.defaultName)) {\\n callbacksBuilder.nameCallback(prompt, defaultName);\\n } else {\\n callbacksBuilder.nameCallback(prompt);\\n }\\n}\\n\\nfunction numberAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getDouble(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction passwordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n callbacksBuilder.passwordCallback(prompt, echoOn);\\n}\\n\\nfunction pollingWaitCallback() {\\n var waitTime = getString(properties.options.waitTime);\\n var message = getString(properties.options.message);\\n callbacksBuilder.pollingWaitCallback(waitTime, message);\\n}\\n\\nfunction redirectCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction scriptTextOutputCallback() {\\n var message = getString(properties.options.message);\\n callbacksBuilder.scriptTextOutputCallback(message);\\n}\\n\\nfunction selectIdPCallback() {\\n var providers = getObject(properties.options.providers);\\n callbacksBuilder.selectIdPCallback(providers);\\n}\\n\\nfunction stringAttributeInputCallback() {\\n var name = getString(properties.options.name);\\n var prompt = getString(properties.options.prompt);\\n var value = getString(properties.options.value);\\n var required = getBoolean(properties.options.required);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\\n if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\\n }\\n } else if (isArrayPresent(failedPolicies)) {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\\n } else {\\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\\n }\\n}\\n\\nfunction suspendedTextOutputCallback() {\\n var messageType = getInt(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\\n}\\n\\nfunction termsAndConditionsCallback() {\\n var version = getString(properties.options.version);\\n var terms = getString(properties.options.terms);\\n var createDate = getString(properties.options.createDate);\\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\\n}\\n\\nfunction textInputCallback() {\\n var prompt = getString(properties.options.prompt);\\n var defaultText = getString(properties.options.defaultText);\\n if (isStringPresent(properties.options.defaultText)) {\\n callbacksBuilder.textInputCallback(prompt, defaultText);\\n } else {\\n callbacksBuilder.textInputCallback(prompt);\\n }\\n}\\n\\nfunction textOutputCallback() {\\n var messageType = getString(properties.options.messageType);\\n var message = getString(properties.options.message);\\n callbacksBuilder.textOutputCallback(messageType, message);\\n}\\n\\nfunction validatedPasswordCallback() {\\n var prompt = getString(properties.options.prompt);\\n var echoOn = getBoolean(properties.options.echoOn);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\\n }\\n}\\n\\nfunction validatedUsernameCallback() {\\n var prompt = getString(properties.options.prompt);\\n var policies = getObject(properties.options.policies);\\n var validateOnly = getBoolean(properties.options.validateOnly);\\n var failedPolicies = getArray(properties.options.failedPolicies);\\n if (isArrayPresent(properties.options.failedPolicies)) {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\\n } else {\\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\\n }\\n}\\n\\nfunction x509CertificateCallback() {\\n throw new Error('Not Implemented');\\n}\\n\\nfunction getBooleanAttributeInputCallback() {\\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getChoiceCallback() {\\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\\n var selections = callbacks.getChoiceCallbacks().get(0);\\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\\n}\\n\\nfunction getConfirmationCallback() {\\n setProperty(callbacks.getConfirmationCallbacks().get(0));\\n}\\n\\nfunction getConsentMappingCallback() {\\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\\n}\\n\\nfunction getDeviceProfileCallback() {\\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\\n}\\n\\nfunction getHiddenValueCallback() {\\n var id = getString(properties.options.id);\\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\\n}\\n\\nfunction getHttpCallback() {\\n setProperty(callbacks.getHttpCallbacks().get(0));\\n}\\n\\nfunction getIdPCallback() {\\n setProperty(callbacks.getIdpCallbacks().get(0));\\n}\\n\\nfunction getKbaCreateCallback() {\\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\\n}\\n\\nfunction getLanguageCallback() {\\n setProperty(callbacks.getLanguageCallbacks().get(0));\\n}\\n\\nfunction getNameCallback() {\\n setProperty(callbacks.getNameCallbacks().get(0));\\n}\\n\\nfunction getNumberAttributeInputCallback() {\\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getPasswordCallback() {\\n setProperty(callbacks.getPasswordCallbacks().get(0));\\n}\\n\\nfunction getSelectIdPCallback() {\\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\\n}\\n\\nfunction getStringAttributeInputCallback() {\\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\\n}\\n\\nfunction getTermsAndConditionsCallback() {\\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\\n}\\n\\nfunction getTextInputCallback() {\\n setProperty(callbacks.getTextInputCallbacks().get(0));\\n}\\n\\nfunction getValidatedPasswordCallback() {\\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\\n}\\n\\nfunction getValidatedUsernameCallback() {\\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\\n}\\n\\nfunction getX509CertificateCallback() {\\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\\n}\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\\n default: break;\\n }\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n\\n switch (properties.callback) {\\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\\n default: throw new Error('Unknown Callback'); // Should never reach this case\\n }\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"callback\",\"utilities\"],\"properties\":{\"callback\":{\"title\":\"Callback\",\"description\":\"The callback to display\",\"type\":\"STRING\",\"required\":true,\"options\":{\"METADATA_CALLBACK\":\"metadataCallback\",\"TERMS_AND_CONDITIONS_CALLBACK\":\"termsAndConditionsCallback\",\"NUMBER_ATTRIBUTE_INPUT_CALLBACK\":\"numberAttributeInputCallback\",\"TEXT_OUTPUT_CALLBACK\":\"textOutputCallback\",\"SCRIPT_TEXT_OUTPUT_CALLBACK\":\"scriptTextOutputCallback\",\"CONSENT_MAPPING_CALLBACK\":\"consentMappingCallback\",\"STRING_ATTRIBUTE_INPUT_CALLBACK\":\"stringAttributeInputCallback\",\"IDP_CALLBACK\":\"idPCallback\",\"VALIDATED_PASSWORD_CALLBACK\":\"validatedPasswordCallback\",\"SELECT_IDP_CALLBACK\":\"selectIdPCallback\",\"POLLING_WAIT_CALLBACK\":\"pollingWaitCallback\",\"NAME_CALLBACK\":\"nameCallback\",\"SUSPENDED_TEXT_OUTPUT_CALLBACK\":\"suspendedTextOutputCallback\",\"REDIRECT_CALLBACK\":\"redirectCallback\",\"X509_CERTIFICATE_CALLBACK\":\"x509CertificateCallback\",\"PASSWORD_CALLBACK\":\"passwordCallback\",\"TEXT_INPUT_CALLBACK\":\"textInputCallback\",\"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\":\"booleanAttributeInputCallback\",\"CONFIRMATION_CALLBACK\":\"confirmationCallback\",\"CHOICE_CALLBACK\":\"choiceCallback\",\"DEVICE_PROFILE_CALLBACK\":\"deviceProfileCallback\",\"HIDDEN_VALUE_CALLBACK\":\"hiddenValueCallback\",\"HTTP_CALLBACK\":\"httpCallback\",\"VALIDATED_USERNAME_CALLBACK\":\"validatedUsernameCallback\",\"KBA_CREATE_CALLBACK\":\"kbaCreateCallback\",\"LANGUAGE_CALLBACK\":\"languageCallback\"},\"multivalued\":false},\"objectSharedProperty\":{\"title\":\"Object Attributes Shared Property\",\"description\":\"The objectAttributes property on the shared state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"objectTransientProperty\":{\"title\":\"Object Attributes Transient Property\",\"description\":\"The objectAttributes property on the transient state to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"options\":{\"title\":\"Options\",\"description\":\"The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). \\n\\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \\\"Hello World!\\\" }. \\n\\nNote that for required parameters that are not specified in the options will use default values based on the type of the parameter (\\\"\\\" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).\",\"type\":\"OBJECT\",\"required\":true,\"multivalued\":false},\"sharedProperty\":{\"title\":\"Shared State Property\",\"description\":\"The shared state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false},\"transientProperty\":{\"title\":\"Transient State Property\",\"description\":\"The transient state property to put the callback input into (if applicable)\",\"type\":\"STRING\",\"required\":false,\"multivalued\":false}}},{\"_id\":\"8ab9f1aad4b4460a9c45d15fb148e221-1\",\"_rev\":\"1253294564\",\"serviceName\":\"8ab9f1aad4b4460a9c45d15fb148e221\",\"displayName\":\"Display State\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}},{\"_id\":\"c15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"1113564678\",\"serviceName\":\"c15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"session-1\",\"_rev\":\"490056204\",\"serviceName\":\"session\",\"displayName\":\"Has Session AM\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"c605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"-1941250080\",\"serviceName\":\"c605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"a15e2efb3deb4d4ea338c74a6440b69f-1\",\"_rev\":\"-1807621590\",\"serviceName\":\"a15e2efb3deb4d4ea338c74a6440b69f\",\"displayName\":\"Vector ALU - TEST\",\"description\":\"Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key \\\"c\\\".\",\"outcomes\":[\"Success\"],\"outputs\":[\"c\"],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n SUCCESS: 'Success'\\n};\\n\\nvar OPERATORS = {\\n ADD: \\\"ADD\\\",\\n SUBTRACT: \\\"SUBTRACT\\\",\\n DOT: \\\"DOT\\\",\\n CROSS: \\\"CROSS\\\"\\n}\\n\\nfunction add(a, b) {\\n return a.map((v, i) => v + b[i]);\\n}\\n\\nfunction subtract(a, b) {\\n return a.map((v, i) => v - b[i]);\\n}\\n\\nfunction dot(a, b) {\\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\\n}\\n\\nfunction cross(a, b) {\\n return [\\n a[1] * b[2] - a[2] * b[1],\\n a[2] * b[0] - a[0] * b[2],\\n a[0] * b[1] - a[1] * b[0]\\n ];\\n}\\n\\nfunction main() {\\n if (properties.a.length !== properties.b.length) throw new Error(\\\"Vectors not the same dimension.\\\");\\n switch (properties.operator) {\\n case OPERATORS.ADD:\\n nodeState.putShared(\\\"c\\\", add(properties.a, properties.b));\\n break;\\n case OPERATORS.SUBTRACT:\\n nodeState.putShared(\\\"c\\\", subtract(properties.a, properties.b));\\n break;\\n case OPERATORS.DOT:\\n nodeState.putShared(\\\"c\\\", dot(properties.a, properties.b));\\n break;\\n case OPERATORS.CROSS:\\n if (properties.a.length !== 3) throw new Error(\\\"Vectors not dimension 3 for cross product\\\");\\n nodeState.putShared(\\\"c\\\", cross(properties.a, properties.b));\\n break;\\n default: throw new Error(\\\"Unknown operator.\\\");\\n }\\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\\n}\\n\\nmain();\\n\",\"errorOutcome\":true,\"tags\":[\"math\",\"vector\",\"utilities\"],\"properties\":{\"a\":{\"title\":\"A\",\"description\":\"Left vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[1,2,3],\"multivalued\":true},\"b\":{\"title\":\"B\",\"description\":\"Right vector operand\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":[4,5,6],\"multivalued\":true},\"operator\":{\"title\":\"Operator\",\"description\":\"The binary operation to perform on the vectors.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"DOT\",\"options\":{\"ADD\":\"+\",\"CROSS\":\"X\",\"DOT\":\".\",\"SUBTRACT\":\"-\"},\"multivalued\":false}}},{\"_id\":\"a605506774a848f7877b4d17a453bd39-1\",\"_rev\":\"1086162449\",\"serviceName\":\"a605506774a848f7877b4d17a453bd39\",\"displayName\":\"Has Session - TEST\",\"description\":\"Checks if the user has a current session.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n TRUE: 'True',\\n FALSE: 'False'\\n}\\n\\nfunction main() {\\n action.goTo(typeof existingSession === \\\"undefined\\\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"utilities\"],\"properties\":{}},{\"_id\":\"e5ad0110c8ee4dafaae983003cd05d4a-1\",\"_rev\":\"1554001423\",\"serviceName\":\"e5ad0110c8ee4dafaae983003cd05d4a\",\"displayName\":\"Generate JWT\",\"description\":\"Generate a signed JWT using the HMAC SHA-256 algorithm.\",\"outcomes\":[\"True\",\"False\"],\"outputs\":[],\"inputs\":[],\"script\":\"var aud = properties.audience;\\nvar iss = properties.issuer;\\nvar validity = properties.validity;\\nvar esv = properties.signingkey;\\n\\nvar signingkey = systemEnv.getProperty(esv);\\n\\nvar username = nodeState.get(\\\"username\\\");\\n\\nvar data = {\\n jwtType:\\\"SIGNED\\\",\\n jwsAlgorithm: \\\"HS256\\\",\\n issuer: iss,\\n subject: username,\\n audience: aud,\\n type: \\\"JWT\\\",\\n validityMinutes: validity,\\n signingKey: signingkey\\n};\\n\\nvar jwt = jwtAssertion.generateJwt(data);\\n\\nif (jwt !== null && jwt.length > 0) {\\n nodeState.putShared(\\\"assertionJwt\\\" , jwt);\\n action.goTo(\\\"True\\\");\\n} else {\\n action.goTo(\\\"False\\\");\\n}\",\"errorOutcome\":true,\"tags\":[\"Utilities\",\"utilities\"],\"properties\":{\"audience\":{\"title\":\"Audience\",\"description\":\"The audience (aud) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"issuer\":{\"title\":\"Issuer\",\"description\":\"The issuer (iss) claim\",\"type\":\"STRING\",\"required\":true,\"multivalued\":false},\"signingkey\":{\"title\":\"HMAC Signing Key\",\"description\":\"The secret label for the HMAC signing key\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"esv.signing.key\",\"multivalued\":false},\"validity\":{\"title\":\"Validity (minutes)\",\"description\":\"\",\"type\":\"NUMBER\",\"required\":true,\"defaultValue\":5,\"multivalued\":false}}}],\"resultCount\":10,\"pagedResultsCookie\":null,\"totalPagedResultsPolicy\":\"EXACT\",\"totalPagedResults\":10,\"remainingPagedResults\":-1}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "protocol=2.1,resource=1.0, resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "date", + "value": "Thu, 18 Dec 2025 16:25:01 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-7df92e81-4a4f-45fd-9aa6-1810434eb485" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + }, + { + "name": "transfer-encoding", + "value": "chunked" + } + ], + "headersSize": 690, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-12-18T16:25:01.791Z", + "time": 99, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 99 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/1-Read-existing-node_2978326169/recording.har b/src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/1-Read-existing-node_2978326169/recording.har new file mode 100644 index 000000000..aef2f3c6d --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/1-Read-existing-node_2978326169/recording.har @@ -0,0 +1,165 @@ +{ + "log": { + "_recordingName": "NodeOps/readNode()/1: Read existing node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "7a249b03c479f8c8057e50c533791298", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-193adbdf-127c-407a-9b61-70370c08ee40" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2045, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/ValidatedUsernameNode/67693475-3a58-4e38-bcc6-037b3fe46a58" + }, + "response": { + "bodySize": 275, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 275, + "text": "{\"_id\":\"67693475-3a58-4e38-bcc6-037b3fe46a58\",\"_rev\":\"1964272313\",\"usernameAttribute\":\"userName\",\"validateInput\":false,\"_type\":{\"_id\":\"ValidatedUsernameNode\",\"name\":\"Platform Username\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"outcome\",\"displayName\":\"Outcome\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"1964272313\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "275" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 23:50:16 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-193adbdf-127c-407a-9b61-70370c08ee40" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 786, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-10T23:50:15.959Z", + "time": 58, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 58 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/2-Read-non-existing-node_2851841034/recording.har b/src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/2-Read-non-existing-node_2851841034/recording.har new file mode 100644 index 000000000..d97574c59 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/readNode_3063847234/2-Read-non-existing-node_2851841034/recording.har @@ -0,0 +1,161 @@ +{ + "log": { + "_recordingName": "NodeOps/readNode()/2: Read non-existing node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "374bc95de6930a2363fd9b8a41af25f9", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-193adbdf-127c-407a-9b61-70370c08ee40" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2032, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PageNode/00000000-0000-0000-0000-000000000000" + }, + "response": { + "bodySize": 55, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 55, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Not Found\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "55" + }, + { + "name": "date", + "value": "Mon, 10 Nov 2025 23:50:16 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-193adbdf-127c-407a-9b61-70370c08ee40" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-10T23:50:16.029Z", + "time": 77, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 77 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/1-Update-existing-custom-node_2742140269/recording.har b/src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/1-Update-existing-custom-node_2742140269/recording.har new file mode 100644 index 000000000..f7c34627c --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/1-Update-existing-custom-node_2742140269/recording.har @@ -0,0 +1,489 @@ +{ + "log": { + "_recordingName": "NodeOps/updateCustomNode()/1: Update existing custom node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "31359fe225030056cfe3def3f0978822", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1969, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 44, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 44, + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "44" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:49:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:49:40.036Z", + "time": 301, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 301 + } + }, + { + "_id": "7c2add208843d7267e919d70cf79b9fe", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1832, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "1832" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1954, + "httpVersion": "HTTP/1.1", + "method": "POST", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type" + }, + "response": { + "bodySize": 1851, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1851, + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"690035393\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"690035393\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1851" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:49:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 905, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:49:40.345Z", + "time": 152, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 152 + } + }, + { + "_id": "01301945c173e73f762aebd7509b339b", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1832, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "1832" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2001, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 1852, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 1852, + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"_rev\":\"-993019861\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-993019861\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "1852" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:49:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:49:40.504Z", + "time": 87, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 87 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/2-Update-non-existing-custom-node_3002975744/recording.har b/src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/2-Update-non-existing-custom-node_3002975744/recording.har new file mode 100644 index 000000000..53aaebc1d --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/updateCustomNode_2439955524/2-Update-non-existing-custom-node_3002975744/recording.har @@ -0,0 +1,321 @@ +{ + "log": { + "_recordingName": "NodeOps/updateCustomNode()/2: Update non-existing custom node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "31359fe225030056cfe3def3f0978822", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 1969, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 44, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 44, + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "44" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:49:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 765, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:49:40.603Z", + "time": 237, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 237 + } + }, + { + "_id": "01301945c173e73f762aebd7509b339b", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 1832, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "if-match", + "value": "*" + }, + { + "name": "content-length", + "value": "1832" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2001, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"aaaa3fb2f5dc42dd9772bedc93898bd8-1\",\"serviceName\":\"aaaa3fb2f5dc42dd9772bedc93898bd8\",\"displayName\":\"Display State - TEST\",\"description\":\"Debug node that displays the shared and transient state of the journey for debugging purposes.\",\"outcomes\":[\"outcome\"],\"outputs\":[],\"inputs\":[],\"script\":\"var SCRIPT_OUTCOMES = {\\n OUTCOME: \\\"outcome\\\"\\n};\\n\\nfunction main() {\\n if (!callbacks.isEmpty()) {\\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\\n return;\\n }\\n var keySet = nodeState.keys(); // Java Set\\n var keys = Array.from(keySet); // Make it into JavaScript array\\n debugState = {};\\n for (var i in keys) {\\n var k = new String(keys[i]);\\n var item = nodeState.get(k);\\n if (typeof item === \\\"object\\\") {\\n debugState[k] = nodeState.getObject(k);\\n } else {\\n debugState[k] = nodeState.get(k);\\n }\\n }\\n if (properties.displayFormat === \\\"JSON\\\") {\\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\\n return;\\n }\\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\\n}\\n\\nmain();\\n\",\"errorOutcome\":false,\"tags\":[\"debug\",\"testing\"],\"properties\":{\"displayFormat\":{\"title\":\"Display Format\",\"description\":\"The format in which to display the states.\",\"type\":\"STRING\",\"required\":true,\"defaultValue\":\"TABLE\",\"options\":{\"TABLE\":\"HTML Table\",\"JSON\":\"Raw JSON\"},\"multivalued\":false}}}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/node-designer/node-type/aaaa3fb2f5dc42dd9772bedc93898bd8-1" + }, + "response": { + "bodySize": 122, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 122, + "text": "{\"code\":404,\"reason\":\"Not Found\",\"message\":\"Node Type with resource ID aaaa3fb2f5dc42dd9772bedc93898bd8-1 does not exist\"}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "122" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:49:40 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-1f69a393-c1b1-4836-90db-d632bcd2bdbe" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 766, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 404, + "statusText": "Not Found" + }, + "startedDateTime": "2025-11-11T00:49:40.847Z", + "time": 58, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 58 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/1-Update-existing-node_144302408/recording.har b/src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/1-Update-existing-node_144302408/recording.har new file mode 100644 index 000000000..9137df837 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/1-Update-existing-node_144302408/recording.har @@ -0,0 +1,329 @@ +{ + "log": { + "_recordingName": "NodeOps/updateNode()/1: Update existing node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "be006ccbd48e6af8d995fa70d4784e4a", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2042, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9" + }, + "response": { + "bodySize": 358, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 358, + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"_rev\":\"-1625726187\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1625726187\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "358" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:24:58 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:24:58.612Z", + "time": 179, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 179 + } + }, + { + "_id": "e6cf499c0a4cedf40859b63ecb0f3b82", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 321, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "321" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2060, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9" + }, + "response": { + "bodySize": 358, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 358, + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"_rev\":\"-1625726187\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1625726187\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "358" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:24:58 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 979, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:24:58.800Z", + "time": 159, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 159 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/2-Update-non-existing-node_2780671391/recording.har b/src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/2-Update-non-existing-node_2780671391/recording.har new file mode 100644 index 000000000..c16063f60 --- /dev/null +++ b/src/test/mock-recordings/NodeOps_3921382371/updateNode_1043886451/2-Update-non-existing-node_2780671391/recording.har @@ -0,0 +1,329 @@ +{ + "log": { + "_recordingName": "NodeOps/updateNode()/2: Update non-existing node", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "6.0.6" + }, + "entries": [ + { + "_id": "be006ccbd48e6af8d995fa70d4784e4a", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2042, + "httpVersion": "HTTP/1.1", + "method": "DELETE", + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9" + }, + "response": { + "bodySize": 358, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 358, + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"_rev\":\"-1625726187\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1625726187\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "358" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:24:59 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 787, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-11-11T00:24:59.044Z", + "time": 195, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 195 + } + }, + { + "_id": "e6cf499c0a4cedf40859b63ecb0f3b82", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 321, + "cookies": [], + "headers": [ + { + "name": "accept", + "value": "application/json, text/plain, */*" + }, + { + "name": "content-type", + "value": "application/json" + }, + { + "name": "user-agent", + "value": "@rockcarver/frodo-lib/3.3.3" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "accept-api-version", + "value": "protocol=2.1,resource=1.0" + }, + { + "name": "authorization", + "value": "Bearer " + }, + { + "name": "content-length", + "value": "321" + }, + { + "name": "accept-encoding", + "value": "gzip, compress, deflate, br" + }, + { + "name": "host", + "value": "openam-frodo-dev.forgeblocks.com" + } + ], + "headersSize": 2060, + "httpVersion": "HTTP/1.1", + "method": "PUT", + "postData": { + "mimeType": "application/json", + "params": [], + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + }, + "queryString": [], + "url": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9" + }, + "response": { + "bodySize": 358, + "content": { + "mimeType": "application/json;charset=UTF-8", + "size": 358, + "text": "{\"_id\":\"b726262c-641e-4fa5-b276-98e129b44cd9\",\"_rev\":\"-1625726187\",\"identityResource\":\"managed/user\",\"patchAsObject\":false,\"ignoredFields\":[],\"identityAttribute\":\"userName\",\"_type\":{\"_id\":\"PatchObjectNode\",\"name\":\"Patch Object\",\"collection\":true,\"version\":\"1.0\"},\"_outcomes\":[{\"id\":\"PATCHED\",\"displayName\":\"Patched\"},{\"id\":\"FAILURE\",\"displayName\":\"Failed\"}]}" + }, + "cookies": [], + "headers": [ + { + "name": "x-frame-options", + "value": "SAMEORIGIN" + }, + { + "name": "content-security-policy-report-only", + "value": "frame-ancestors 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "cache-control", + "value": "private" + }, + { + "name": "content-api-version", + "value": "resource=1.0" + }, + { + "name": "content-security-policy", + "value": "default-src 'none';frame-ancestors 'none';sandbox" + }, + { + "name": "cross-origin-opener-policy", + "value": "same-origin" + }, + { + "name": "cross-origin-resource-policy", + "value": "same-origin" + }, + { + "name": "etag", + "value": "\"-1625726187\"" + }, + { + "name": "expires", + "value": "0" + }, + { + "name": "location", + "value": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9" + }, + { + "name": "pragma", + "value": "no-cache" + }, + { + "name": "content-type", + "value": "application/json;charset=UTF-8" + }, + { + "name": "content-length", + "value": "358" + }, + { + "name": "date", + "value": "Tue, 11 Nov 2025 00:24:59 GMT" + }, + { + "name": "x-forgerock-transactionid", + "value": "frodo-8c610ffc-e07f-4b81-bdf3-5d05317d5ded" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubDomains; preload;" + }, + { + "name": "x-robots-tag", + "value": "none" + }, + { + "name": "via", + "value": "1.1 google" + }, + { + "name": "alt-svc", + "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000" + } + ], + "headersSize": 979, + "httpVersion": "HTTP/1.1", + "redirectURL": "https://openam-frodo-dev.forgeblocks.com/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PatchObjectNode/b726262c-641e-4fa5-b276-98e129b44cd9", + "status": 201, + "statusText": "Created" + }, + "startedDateTime": "2025-11-11T00:24:59.246Z", + "time": 174, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 174 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/src/test/mocks/ForgeRockApiMockEngine.ts b/src/test/mocks/ForgeRockApiMockEngine.ts index 505cc6bec..e9a372d92 100644 --- a/src/test/mocks/ForgeRockApiMockEngine.ts +++ b/src/test/mocks/ForgeRockApiMockEngine.ts @@ -3,6 +3,7 @@ import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; +import { SingleTreeExportInterface } from '../../ops/JourneyOps'; import { getTypedFilename } from '../../utils/ExportImportUtils'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -77,7 +78,7 @@ export function mockAccessToken(mock: MockAdapter) { * Tree Mock Data */ -export function getJourney(journeyId: string) { +export function getJourney(journeyId: string): SingleTreeExportInterface { const treeObject = JSON.parse( fs.readFileSync( path.resolve( diff --git a/src/test/mocks/JourneyOps/importJourney/FrodoTestJourney12.journey.json b/src/test/mocks/JourneyOps/importJourney/FrodoTestJourney12.journey.json new file mode 100644 index 000000000..94ca6f6f3 --- /dev/null +++ b/src/test/mocks/JourneyOps/importJourney/FrodoTestJourney12.journey.json @@ -0,0 +1,488 @@ +{ + "tree": { + "_id": "FrodoTestJourney12", + "_rev": "-1089656935", + "identityResource": "managed/alpha_user", + "entryNodeId": "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb", + "innerTreeOnly": false, + "description": "Test journey for custom nodes", + "noSession": false, + "mustRun": false, + "enabled": true, + "transactionalOnly": false, + "uiConfig": { + "categories": "[]", + "annotations": "{\"forNodes\":{},\"structural\":[]}" + }, + "nodes": { + "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97": { + "x": 463, + "y": 80, + "connections": { + "outcome": "461a364c-5884-44f6-87d9-ae749cc08f24" + }, + "nodeType": "PageNode", + "displayName": "Login Page" + }, + "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb": { + "x": 210, + "y": 161, + "connections": { + "True": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0", + "False": "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97" + }, + "nodeType": "designer-session", + "displayName": "Has Session AM" + }, + "461a364c-5884-44f6-87d9-ae749cc08f24": { + "x": 734, + "y": 161, + "connections": { + "true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0", + "false": "e301438c-0bd0-429c-ab0c-66126501069a" + }, + "nodeType": "DataStoreDecisionNode", + "displayName": "Data Store Decision" + } + }, + "staticNodes": { + "startNode": { + "x": 70, + "y": 188 + }, + "70e691a5-1e33-4ac3-a356-e7b6d60d92e0": { + "x": 1014, + "y": 102 + }, + "e301438c-0bd0-429c-ab0c-66126501069a": { + "x": 1014, + "y": 241 + } + } + }, + "nodes": { + "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97": { + "_id": "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97", + "_rev": "2033345625", + "nodes": [ + { + "_id": "03416cc6-588b-409a-919f-038bb8194c81", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Welcome" + }, + { + "_id": "1a002d5d-5ad5-4d0e-965f-a0f26278d08d", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Username" + }, + { + "_id": "65c2a8cd-e623-4c5d-b420-e55fc5105f43", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Password" + }, + { + "_id": "ee549716-666c-4b9d-baab-defe1a93eb6c", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Email" + }, + { + "_id": "eaf91b8a-bb71-4037-97ec-cd2e54885668", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Age" + }, + { + "_id": "d8bd62e2-a4e7-4e08-bb28-10570aa31fcf", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Is old" + }, + { + "_id": "18edd91b-5e15-49df-b3c3-764114a8ebb3", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Hidden" + }, + { + "_id": "0a3d5de0-9426-4a9a-aae0-163eda075d43", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Script" + }, + { + "_id": "f9155861-f7c8-4022-9bed-e4ef5b238824", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + "displayName": "Terms" + } + ], + "pageDescription": {}, + "pageHeader": {}, + "_type": { + "_id": "PageNode", + "name": "Page Node", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb": { + "_id": "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb", + "_rev": "-1617974950", + "_type": { + "_id": "designer-session", + "name": "Has Session AM", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "True", + "displayName": "True" + }, + { + "id": "False", + "displayName": "False" + } + ] + }, + "461a364c-5884-44f6-87d9-ae749cc08f24": { + "_id": "461a364c-5884-44f6-87d9-ae749cc08f24", + "_rev": "2126257365", + "_type": { + "_id": "DataStoreDecisionNode", + "name": "Data Store Decision", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "true", + "displayName": "True" + }, + { + "id": "false", + "displayName": "False" + } + ] + } + }, + "innerNodes": { + "03416cc6-588b-409a-919f-038bb8194c81": { + "_id": "03416cc6-588b-409a-919f-038bb8194c81", + "_rev": "-191831406", + "callback": "TEXT_OUTPUT_CALLBACK", + "options": { + "messageType": "1", + "message": "WARNING: You must enter your username and password to continue!" + }, + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "1a002d5d-5ad5-4d0e-965f-a0f26278d08d": { + "_id": "1a002d5d-5ad5-4d0e-965f-a0f26278d08d", + "_rev": "-605795289", + "callback": "NAME_CALLBACK", + "objectSharedProperty": "userName", + "options": { + "prompt": "Enter Your Username" + }, + "sharedProperty": "username", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "65c2a8cd-e623-4c5d-b420-e55fc5105f43": { + "_id": "65c2a8cd-e623-4c5d-b420-e55fc5105f43", + "_rev": "-1753807887", + "callback": "PASSWORD_CALLBACK", + "objectTransientProperty": "password", + "transientProperty": "password", + "options": { + "prompt": "Enter Your Password" + }, + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "ee549716-666c-4b9d-baab-defe1a93eb6c": { + "_id": "ee549716-666c-4b9d-baab-defe1a93eb6c", + "_rev": "146018854", + "callback": "STRING_ATTRIBUTE_INPUT_CALLBACK", + "objectSharedProperty": "mail", + "options": { + "name": "mail", + "prompt": "Enter Your Email", + "required": "true" + }, + "sharedProperty": "email", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "eaf91b8a-bb71-4037-97ec-cd2e54885668": { + "_id": "eaf91b8a-bb71-4037-97ec-cd2e54885668", + "_rev": "2022883295", + "callback": "NUMBER_ATTRIBUTE_INPUT_CALLBACK", + "objectSharedProperty": "frUnindexedInteger1", + "options": { + "name": "frUnindexedInteger1", + "prompt": "Enter Your Age", + "required": "true" + }, + "sharedProperty": "age", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "d8bd62e2-a4e7-4e08-bb28-10570aa31fcf": { + "_id": "d8bd62e2-a4e7-4e08-bb28-10570aa31fcf", + "_rev": "-1308099819", + "callback": "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK", + "objectSharedProperty": "frUnindexedString1", + "options": { + "name": "frUnindexedString1", + "prompt": "Are you old?", + "required": "true" + }, + "sharedProperty": "isOld", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "18edd91b-5e15-49df-b3c3-764114a8ebb3": { + "_id": "18edd91b-5e15-49df-b3c3-764114a8ebb3", + "_rev": "975185327", + "callback": "HIDDEN_VALUE_CALLBACK", + "options": { + "id": "myId", + "value": "I am hidden" + }, + "sharedProperty": "hidden", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "0a3d5de0-9426-4a9a-aae0-163eda075d43": { + "_id": "0a3d5de0-9426-4a9a-aae0-163eda075d43", + "_rev": "4824664", + "callback": "SCRIPT_TEXT_OUTPUT_CALLBACK", + "options": { + "message": "console.log(\"hello console!\");" + }, + "sharedProperty": "out", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + }, + "f9155861-f7c8-4022-9bed-e4ef5b238824": { + "_id": "f9155861-f7c8-4022-9bed-e4ef5b238824", + "_rev": "-1687279556", + "callback": "TERMS_AND_CONDITIONS_CALLBACK", + "options": { + "version": "6.7", + "terms": "This is the way", + "createDate": "2025-11-12T22:30:59.417Z" + }, + "sharedProperty": "accepted", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "name": "Display Callback", + "collection": true, + "version": "1.0" + }, + "_outcomes": [ + { + "id": "outcome", + "displayName": "outcome" + } + ] + } + }, + "nodeTypes": { + "session-1": { + "serviceName": "session", + "displayName": "Has Session AM", + "description": "Checks if the user has a current session.", + "outcomes": [ + "True", + "False" + ], + "outputs": [], + "inputs": [], + "script": "var SCRIPT_OUTCOMES = {\n TRUE: 'True',\n FALSE: 'False'\n}\n\nfunction main() {\n action.goTo(typeof existingSession === \"undefined\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\n}\n\nmain();\n", + "errorOutcome": false, + "tags": [ + "utilities" + ], + "properties": {} + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "displayName": "Display Callback", + "description": "Displays custom callback to the page", + "outcomes": [ + "outcome" + ], + "outputs": [], + "inputs": [], + "script": "var SCRIPT_OUTCOMES = {\n OUTCOME: 'outcome'\n};\n\nvar CALLBACKS = {\n\tBOOLEAN_ATTRIBUTE_INPUT_CALLBACK: \"BOOLEAN_ATTRIBUTE_INPUT_CALLBACK\",\n\tCHOICE_CALLBACK: \"CHOICE_CALLBACK\",\n\tCONFIRMATION_CALLBACK: \"CONFIRMATION_CALLBACK\",\n\tCONSENT_MAPPING_CALLBACK: \"CONSENT_MAPPING_CALLBACK\",\n\tDEVICE_PROFILE_CALLBACK: \"DEVICE_PROFILE_CALLBACK\",\n\tHIDDEN_VALUE_CALLBACK: \"HIDDEN_VALUE_CALLBACK\",\n\tHTTP_CALLBACK: \"HTTP_CALLBACK\",\n\tIDP_CALLBACK: \"IDP_CALLBACK\",\n\tKBA_CREATE_CALLBACK: \"KBA_CREATE_CALLBACK\",\n\tLANGUAGE_CALLBACK: \"LANGUAGE_CALLBACK\",\n\tMETADATA_CALLBACK: \"METADATA_CALLBACK\",\n\tNAME_CALLBACK: \"NAME_CALLBACK\",\n\tNUMBER_ATTRIBUTE_INPUT_CALLBACK: \"NUMBER_ATTRIBUTE_INPUT_CALLBACK\",\n\tPASSWORD_CALLBACK: \"PASSWORD_CALLBACK\",\n\tPOLLING_WAIT_CALLBACK: \"POLLING_WAIT_CALLBACK\",\n REDIRECT_CALLBACK: \"REDIRECT_CALLBACK\",\n\tSCRIPT_TEXT_OUTPUT_CALLBACK: \"SCRIPT_TEXT_OUTPUT_CALLBACK\",\n\tSELECT_IDP_CALLBACK: \"SELECT_IDP_CALLBACK\",\n\tSTRING_ATTRIBUTE_INPUT_CALLBACK: \"STRING_ATTRIBUTE_INPUT_CALLBACK\",\n\tSUSPENDED_TEXT_OUTPUT_CALLBACK: \"SUSPENDED_TEXT_OUTPUT_CALLBACK\",\n\tTERMS_AND_CONDITIONS_CALLBACK: \"TERMS_AND_CONDITIONS_CALLBACK\",\n\tTEXT_INPUT_CALLBACK: \"TEXT_INPUT_CALLBACK\",\n\tTEXT_OUTPUT_CALLBACK: \"TEXT_OUTPUT_CALLBACK\",\n\tVALIDATED_PASSWORD_CALLBACK: \"VALIDATED_PASSWORD_CALLBACK\",\n\tVALIDATED_USERNAME_CALLBACK: \"VALIDATED_USERNAME_CALLBACK\",\n\tX509_CERTIFICATE_CALLBACK: \"X509_CERTIFICATE_CALLBACK\"\n}\n\nfunction isStringPresent(value) {\n return value;\n}\n\nfunction getString(value) {\n return value || '';\n}\n\nfunction isArrayPresent(value) {\n return value;\n}\n\nfunction getArray(value) {\n return value ? JSON.parse(value) : [];\n}\n\nfunction isObjectPresent(value) {\n return value;\n}\n\nfunction getObject(value) {\n return value ? JSON.parse(value) : {};\n}\n\nfunction isIntPresent(value) {\n return value;\n}\n\nfunction getInt(value) {\n return value ? parseInt(value) : 0;\n}\n\nfunction isDoublePresent(value) {\n return value;\n}\n\nfunction getDouble(value) {\n return value ? parseFloat(value) : 0.0;\n}\n\nfunction isBooleanPresent(value) {\n return value;\n}\n\nfunction getBoolean(value) {\n return value ? value.toLowerCase() === 'true' : false;\n}\n\nfunction setProperty(value) {\n if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);\n if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);\n if (properties.objectSharedProperty) {\n var attributes = {};\n attributes[properties.objectSharedProperty] = value;\n nodeState.mergeShared({\n objectAttributes: attributes\n });\n }\n if (properties.objectTransientProperty) {\n var attributes = {};\n attributes[properties.objectTransientProperty] = value;\n nodeState.mergeTransient({\n objectAttributes: attributes\n });\n }\n}\n\nfunction booleanAttributeInputCallback() {\n var name = getString(properties.options.name);\n var prompt = getString(properties.options.prompt);\n var value = getBoolean(properties.options.value);\n var required = getBoolean(properties.options.required);\n var policies = getObject(properties.options.policies);\n var validateOnly = getBoolean(properties.options.validateOnly);\n var failedPolicies = getArray(properties.options.failedPolicies);\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\n if (isArrayPresent(failedPolicies)) {\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\n } else {\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\n }\n } else if (isArrayPresent(failedPolicies)) {\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);\n } else {\n callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);\n }\n}\n\nfunction choiceCallback() {\n var prompt = getString(properties.options.prompt);\n var choices = getArray(properties.options.choices);\n var defaultChoice = getInt(properties.options.defaultChoice);\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\n callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);\n}\n\nfunction confirmationCallback() {\n var prompt = getString(properties.options.prompt);\n var messageType = getInt(properties.options.messageType);\n var options = getArray(properties.options.options);\n var optionType = getInt(properties.options.optionType);\n var defaultOption = getInt(properties.options.defaultOption);\n if (isStringPresent(properties.options.prompt)) {\n if (isIntPresent(properties.options.optionType)) {\n callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);\n } else {\n callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);\n }\n } else {\n if (isIntPresent(properties.options.optionType)) {\n callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);\n } else {\n callbacksBuilder.confirmationCallback(messageType, options, defaultOption);\n }\n }\n}\n\nfunction consentMappingCallback() {\n var config = getObject(properties.options.config);\n var message = getString(properties.options.message);\n var isRequired = getBoolean(properties.options.isRequired);\n var name = getString(properties.options.name);\n var displayName = getString(properties.options.displayName);\n var icon = getString(properties.options.icon);\n var accessLevel = getString(properties.options.accessLevel);\n var titles = getArray(properties.options.titles);\n if (isObjectPresent(properties.options.prompt)) {\n callbacksBuilder.consentMappingCallback(config, message, isRequired);\n } else {\n callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);\n }\n}\n\nfunction deviceProfileCallback() {\n var metadata = getBoolean(properties.options.metadata);\n var location = getBoolean(properties.options.location);\n var message = getString(properties.options.message);\n callbacksBuilder.deviceProfileCallback(metadata, location, message);\n}\n\nfunction hiddenValueCallback() {\n var id = getString(properties.options.id);\n var value = getString(properties.options.value);\n callbacksBuilder.hiddenValueCallback(id, value);\n}\n\nfunction httpCallback() {\n var authorizationHeader = getString(properties.options.authorizationHeader);\n var negotiationHeader = getString(properties.options.negotiationHeader);\n var authRHeader = getString(properties.options.authRHeader);\n var negoName = getString(properties.options.negoName);\n var negoValue = getString(properties.options.negoValue);\n if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {\n var errorCode = getString(properties.options.errorCode);\n callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);\n } else {\n var errorCode = getInt(properties.options.errorCode);\n callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);\n }\n}\n\nfunction idPCallback() {\n var provider = getString(properties.options.provider);\n var clientId = getString(properties.options.clientId);\n var redirectUri = getString(properties.options.redirectUri);\n var scope = getArray(properties.options.scope);\n var nonce = getString(properties.options.nonce);\n var request = getString(properties.options.request);\n var requestUri = getString(properties.options.requestUri);\n var acrValues = getArray(properties.options.acrValues);\n var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);\n var token = getString(properties.options.token);\n var tokenType = getString(properties.options.tokenType);\n if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);\n } else {\n callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);\n }\n}\n\nfunction kbaCreateCallback() {\n var prompt = getString(properties.options.prompt);\n var predefinedQuestions = getArray(properties.options.predefinedQuestions);\n var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);\n callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);\n}\n\nfunction languageCallback() {\n var language = getString(properties.options.language);\n var country = getString(properties.options.country);\n callbacksBuilder.languageCallback(language, country);\n}\n\nfunction metadataCallback() {\n var outputValue = getObject(properties.options.outputValue);\n callbacksBuilder.metadataCallback(outputValue);\n}\n\nfunction nameCallback() {\n var prompt = getString(properties.options.prompt);\n var defaultName = getString(properties.options.defaultName);\n if (isStringPresent(properties.options.defaultName)) {\n callbacksBuilder.nameCallback(prompt, defaultName);\n } else {\n callbacksBuilder.nameCallback(prompt);\n }\n}\n\nfunction numberAttributeInputCallback() {\n var name = getString(properties.options.name);\n var prompt = getString(properties.options.prompt);\n var value = getDouble(properties.options.value);\n var required = getBoolean(properties.options.required);\n var policies = getObject(properties.options.policies);\n var validateOnly = getBoolean(properties.options.validateOnly);\n var failedPolicies = getArray(properties.options.failedPolicies);\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\n if (isArrayPresent(failedPolicies)) {\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\n } else {\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\n }\n } else if (isArrayPresent(failedPolicies)) {\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);\n } else {\n callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);\n }\n}\n\nfunction passwordCallback() {\n var prompt = getString(properties.options.prompt);\n var echoOn = getBoolean(properties.options.echoOn);\n callbacksBuilder.passwordCallback(prompt, echoOn);\n}\n\nfunction pollingWaitCallback() {\n var waitTime = getString(properties.options.waitTime);\n var message = getString(properties.options.message);\n callbacksBuilder.pollingWaitCallback(waitTime, message);\n}\n\nfunction redirectCallback() {\n throw new Error('Not Implemented');\n}\n\nfunction scriptTextOutputCallback() {\n var message = getString(properties.options.message);\n callbacksBuilder.scriptTextOutputCallback(message);\n}\n\nfunction selectIdPCallback() {\n var providers = getObject(properties.options.providers);\n callbacksBuilder.selectIdPCallback(providers);\n}\n\nfunction stringAttributeInputCallback() {\n var name = getString(properties.options.name);\n var prompt = getString(properties.options.prompt);\n var value = getString(properties.options.value);\n var required = getBoolean(properties.options.required);\n var policies = getObject(properties.options.policies);\n var validateOnly = getBoolean(properties.options.validateOnly);\n var failedPolicies = getArray(properties.options.failedPolicies);\n if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {\n if (isArrayPresent(failedPolicies)) {\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);\n } else {\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);\n }\n } else if (isArrayPresent(failedPolicies)) {\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);\n } else {\n callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);\n }\n}\n\nfunction suspendedTextOutputCallback() {\n var messageType = getInt(properties.options.messageType);\n var message = getString(properties.options.message);\n callbacksBuilder.suspendedTextOutputCallback(messageType, message);\n}\n\nfunction termsAndConditionsCallback() {\n var version = getString(properties.options.version);\n var terms = getString(properties.options.terms);\n var createDate = getString(properties.options.createDate);\n callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);\n}\n\nfunction textInputCallback() {\n var prompt = getString(properties.options.prompt);\n var defaultText = getString(properties.options.defaultText);\n if (isStringPresent(properties.options.defaultText)) {\n callbacksBuilder.textInputCallback(prompt, defaultText);\n } else {\n callbacksBuilder.textInputCallback(prompt);\n }\n}\n\nfunction textOutputCallback() {\n var messageType = getString(properties.options.messageType);\n var message = getString(properties.options.message);\n callbacksBuilder.textOutputCallback(messageType, message);\n}\n\nfunction validatedPasswordCallback() {\n var prompt = getString(properties.options.prompt);\n var echoOn = getBoolean(properties.options.echoOn);\n var policies = getObject(properties.options.policies);\n var validateOnly = getBoolean(properties.options.validateOnly);\n var failedPolicies = getArray(properties.options.failedPolicies);\n if (isArrayPresent(properties.options.failedPolicies)) {\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);\n } else {\n callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);\n }\n}\n\nfunction validatedUsernameCallback() {\n var prompt = getString(properties.options.prompt);\n var policies = getObject(properties.options.policies);\n var validateOnly = getBoolean(properties.options.validateOnly);\n var failedPolicies = getArray(properties.options.failedPolicies);\n if (isArrayPresent(properties.options.failedPolicies)) {\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);\n } else {\n callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);\n }\n}\n\nfunction x509CertificateCallback() {\n throw new Error('Not Implemented');\n}\n\nfunction getBooleanAttributeInputCallback() {\n setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));\n}\n\nfunction getChoiceCallback() {\n var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);\n var selections = callbacks.getChoiceCallbacks().get(0);\n setProperty(multipleSelectionsAllowed ? selections : selections[0]);\n}\n\nfunction getConfirmationCallback() {\n setProperty(callbacks.getConfirmationCallbacks().get(0));\n}\n\nfunction getConsentMappingCallback() {\n setProperty(callbacks.getConsentMappingCallbacks().get(0));\n}\n\nfunction getDeviceProfileCallback() {\n setProperty(callbacks.getDeviceProfileCallbacks().get(0));\n}\n\nfunction getHiddenValueCallback() {\n var id = getString(properties.options.id);\n setProperty(callbacks.getHiddenValueCallbacks().get(id));\n}\n\nfunction getHttpCallback() {\n setProperty(callbacks.getHttpCallbacks().get(0));\n}\n\nfunction getIdPCallback() {\n setProperty(callbacks.getIdpCallbacks().get(0));\n}\n\nfunction getKbaCreateCallback() {\n setProperty(callbacks.getKbaCreateCallbacks().get(0));\n}\n\nfunction getLanguageCallback() {\n setProperty(callbacks.getLanguageCallbacks().get(0));\n}\n\nfunction getNameCallback() {\n setProperty(callbacks.getNameCallbacks().get(0));\n}\n\nfunction getNumberAttributeInputCallback() {\n setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));\n}\n\nfunction getPasswordCallback() {\n setProperty(callbacks.getPasswordCallbacks().get(0));\n}\n\nfunction getSelectIdPCallback() {\n setProperty(callbacks.getSelectIdPCallbacks().get(0));\n}\n\nfunction getStringAttributeInputCallback() {\n setProperty(callbacks.getStringAttributeInputCallbacks().get(0));\n}\n\nfunction getTermsAndConditionsCallback() {\n setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));\n}\n\nfunction getTextInputCallback() {\n setProperty(callbacks.getTextInputCallbacks().get(0));\n}\n\nfunction getValidatedPasswordCallback() {\n setProperty(callbacks.getValidatedPasswordCallbacks().get(0));\n}\n\nfunction getValidatedUsernameCallback() {\n setProperty(callbacks.getValidatedUsernameCallbacks().get(0));\n}\n\nfunction getX509CertificateCallback() {\n setProperty(callbacks.getX509CertificateCallbacks().get(0));\n}\n\nfunction main() {\n if (!callbacks.isEmpty()) {\n switch (properties.callback) {\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;\n case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;\n case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;\n case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;\n case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;\n case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;\n case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;\n case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;\n case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;\n case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;\n case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;\n default: break;\n }\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\n return;\n }\n\n switch (properties.callback) {\n case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;\n case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;\n case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;\n case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;\n case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;\n case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;\n case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;\n case CALLBACKS.IDP_CALLBACK: idPCallback(); break;\n case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;\n case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;\n case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;\n case CALLBACKS.NAME_CALLBACK: nameCallback(); break;\n case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;\n case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;\n case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;\n case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;\n case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;\n case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;\n case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;\n case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;\n case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;\n case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;\n case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;\n case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;\n case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;\n case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;\n default: throw new Error('Unknown Callback'); // Should never reach this case\n }\n}\n\nmain();\n", + "errorOutcome": false, + "tags": [ + "callback", + "utilities" + ], + "properties": { + "callback": { + "title": "Callback", + "description": "The callback to display", + "type": "STRING", + "required": true, + "options": { + "METADATA_CALLBACK": "metadataCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "IDP_CALLBACK": "idPCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "NAME_CALLBACK": "nameCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CHOICE_CALLBACK": "choiceCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback" + }, + "multivalued": false + }, + "objectSharedProperty": { + "title": "Object Attributes Shared Property", + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "type": "STRING", + "required": false, + "multivalued": false + }, + "objectTransientProperty": { + "title": "Object Attributes Transient Property", + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "type": "STRING", + "required": false, + "multivalued": false + }, + "options": { + "title": "Options", + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks).\n\nFor example, for textOutputCallback, the options could be: { messageType: 0, message: \"Hello World!\" }", + "type": "OBJECT", + "required": true, + "multivalued": false + }, + "sharedProperty": { + "title": "Shared State Property", + "description": "The shared state property to put the callback input into (if applicable)", + "type": "STRING", + "required": false, + "multivalued": false + }, + "transientProperty": { + "title": "Transient State Property", + "description": "The transient state property to put the callback input into (if applicable)", + "type": "STRING", + "required": false, + "multivalued": false + } + } + } + }, + "scripts": {}, + "emailTemplates": {}, + "socialIdentityProviders": {}, + "themes": [], + "saml2Entities": {}, + "circlesOfTrust": {} +} \ No newline at end of file diff --git a/src/test/mocks/JourneyOps/importJourney/FrodoTestJourney3.journey.json b/src/test/mocks/JourneyOps/importJourney/FrodoTestJourney3.journey.json index f654efe79..da19ae43f 100644 --- a/src/test/mocks/JourneyOps/importJourney/FrodoTestJourney3.journey.json +++ b/src/test/mocks/JourneyOps/importJourney/FrodoTestJourney3.journey.json @@ -680,6 +680,27 @@ "name": "GitHub Profile Normalization (VS)", "script": "\"/*\\n * Copyright 2020 ForgeRock AS. All Rights Reserved\\n *\\n * Use of this code requires a commercial software license with ForgeRock AS.\\n * or with one of its affiliates. All use shall be exclusively subject\\n * to such license between the licensee and ForgeRock AS.\\n */\\n\\nimport static org.forgerock.json.JsonValue.field\\nimport static org.forgerock.json.JsonValue.json\\nimport static org.forgerock.json.JsonValue.object\\n\\nlogger.warning(\\\"GitHub rawProfile: \\\"+rawProfile)\\n\\nreturn json(object(\\n field(\\\"id\\\", rawProfile.id),\\n field(\\\"displayName\\\", rawProfile.name),\\n field(\\\"givenName\\\", rawProfile.first_name),\\n field(\\\"familyName\\\", rawProfile.last_name),\\n field(\\\"photoUrl\\\", rawProfile.picture.data.url),\\n field(\\\"email\\\", rawProfile.email),\\n field(\\\"username\\\", rawProfile.email)))\"" }, + "3bd13a46-61c4-4974-8efb-1700c80c64e3": { + "_id": "3bd13a46-61c4-4974-8efb-1700c80c64e3", + "context": "AUTHENTICATION_TREE_DECISION_NODE", + "createdBy": "null", + "creationDate": 0, + "default": false, + "description": "Inactive Device Match Script", + "evaluatorVersion": "1.0", + "language": "JAVASCRIPT", + "lastModifiedBy": "null", + "lastModifiedDate": 0, + "name": "Inactive Device Match Script", + "script": [ + "/*", + " * Inactive Device Match Script", + " */", + "", + "outcome = \"true\";", + "" + ] + }, "58c824ae-84ed-4724-82cd-db128fc3f6c": { "_id": "58c824ae-84ed-4724-82cd-db128fc3f6c", "context": "SOCIAL_IDP_PROFILE_TRANSFORMATION", diff --git a/src/test/setup/JourneySetup.ts b/src/test/setup/JourneySetup.ts new file mode 100644 index 000000000..9841e7f12 --- /dev/null +++ b/src/test/setup/JourneySetup.ts @@ -0,0 +1,87 @@ +import { state } from '../../index'; +import * as JourneyOps from '../../ops/JourneyOps'; +import { getJourney } from '../mocks/ForgeRockApiMockEngine'; + +export const journey1 = getJourney('FrodoTestJourney1'); +export const journey2 = getJourney('FrodoTestJourney2'); +export const journey3 = getJourney('FrodoTestJourney3'); +export const journey4 = getJourney('FrodoTestJourney4'); +export const journey5 = getJourney('FrodoTestJourney5'); +export const journey6 = getJourney('FrodoTestJourney6'); +export const journey7 = getJourney('FrodoTestJourney7'); +export const journey8 = getJourney('FrodoTestJourney8'); +export const journey9 = getJourney('FrodoTestJourney9'); +export const journey10 = getJourney('FrodoTestJourney10'); +export const journey10NoCoords = getJourney('FrodoTestJourney10NoCoords'); +export const journey11 = getJourney('FrodoTestJourney11'); +export const journey12 = getJourney('FrodoTestJourney12'); + +export async function stageJourney( + journey: JourneyOps.SingleTreeExportInterface, + create = true +) { + // delete if exists, then create + try { + await JourneyOps.deleteJourney({ + journeyId: journey.tree._id, + options: { + deep: true, + verbose: false, + progress: false, + }, + state, + }); + } catch (error) { + // ignore + } finally { + if (create) { + await JourneyOps.importJourney({ + importData: getJourney(journey.tree._id), + options: { + reUuid: false, + deps: true, + }, + state, + }); + } + } +} + +export function setup() { + // in recording mode, setup test data before recording + beforeAll(async () => { + if (process.env.FRODO_POLLY_MODE === 'record') { + await stageJourney(journey1); + await stageJourney(journey2); + await stageJourney(journey3); + await stageJourney(journey4, false); + await stageJourney(journey5, false); + await stageJourney(journey6); + await stageJourney(journey7); + await stageJourney(journey8); + await stageJourney(journey9); + await stageJourney(journey10); + await stageJourney(journey10NoCoords, false); + await stageJourney(journey11, false); + await stageJourney(journey12); + } + }); + // in recording mode, remove test data after recording + afterAll(async () => { + if (process.env.FRODO_POLLY_MODE === 'record') { + await stageJourney(journey1, false); + await stageJourney(journey2, false); + await stageJourney(journey3, false); + await stageJourney(journey4, false); + await stageJourney(journey5, false); + await stageJourney(journey6, false); + await stageJourney(journey7, false); + await stageJourney(journey8, false); + await stageJourney(journey9, false); + await stageJourney(journey10, false); + await stageJourney(journey10NoCoords, false); + await stageJourney(journey11, false); + await stageJourney(journey12, false); + } + }); +} diff --git a/src/test/setup/NodeSetup.ts b/src/test/setup/NodeSetup.ts new file mode 100644 index 000000000..9734d7e28 --- /dev/null +++ b/src/test/setup/NodeSetup.ts @@ -0,0 +1,303 @@ +import * as NodeApi from '../../api/NodeApi'; +import { state } from '../../index'; + +export const node1: NodeApi.NodeSkeleton = { + _id: '67693475-3a58-4e38-bcc6-037b3fe46a58', + usernameAttribute: 'userName', + validateInput: false, + _type: { + _id: 'ValidatedUsernameNode', + name: 'Platform Username', + collection: true, + }, + _outcomes: [ + { + id: 'outcome', + displayName: 'Outcome', + }, + ], +}; + +export const node2: NodeApi.NodeSkeleton = { + _id: '18ffdd4b-41b7-41b3-8248-f4fdfd68423f', + validateInput: false, + passwordAttribute: 'password', + _type: { + _id: 'ValidatedPasswordNode', + name: 'Platform Password', + collection: true, + }, + _outcomes: [ + { + id: 'outcome', + displayName: 'Outcome', + }, + ], +}; + +export const node3: NodeApi.NodeSkeleton = { + _id: 'b726262c-641e-4fa5-b276-98e129b44cd9', + identityResource: 'managed/user', + patchAsObject: false, + ignoredFields: [], + identityAttribute: 'userName', + _type: { + _id: 'PatchObjectNode', + name: 'Patch Object', + collection: true, + }, + _outcomes: [ + { + id: 'PATCHED', + displayName: 'Patched', + }, + { + id: 'FAILURE', + displayName: 'Failed', + }, + ], +}; + +export const node4: NodeApi.NodeSkeleton = { + _id: '23bab9d4-1663-450f-8a4b-680f44f54fd6', + identityResource: 'managed/user', + _type: { + _id: 'CreateObjectNode', + name: 'Create Object', + collection: true, + }, + _outcomes: [ + { + id: 'CREATED', + displayName: 'Created', + }, + { + id: 'FAILURE', + displayName: 'Failed', + }, + ], +}; + +export const node5: NodeApi.NodeSkeleton = { + _id: '5227de7a-02db-4f25-858e-c8d4f0e0b600', + attributes: { + errorMessage: 'An error has occurred!', + }, + _type: { + _id: 'SetStateNode', + name: 'Set State', + collection: true, + version: '1.0', + }, + _outcomes: [ + { + id: 'outcome', + displayName: 'outcome', + }, + ], +}; + +export const customNode1: NodeApi.CustomNodeSkeleton = { + _id: 'a605506774a848f7877b4d17a453bd39-1', + serviceName: 'a605506774a848f7877b4d17a453bd39', + displayName: 'Has Session - TEST', + description: 'Checks if the user has a current session.', + outcomes: ['True', 'False'], + outputs: [], + inputs: [], + script: + "var SCRIPT_OUTCOMES = {\n TRUE: 'True',\n FALSE: 'False'\n}\n\nfunction main() {\n action.goTo(typeof existingSession === \"undefined\" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);\n}\n\nmain();\n", + errorOutcome: false, + tags: ['utilities'], + properties: {}, +}; + +export const customNode2: NodeApi.CustomNodeSkeleton = { + _id: 'aaaa3fb2f5dc42dd9772bedc93898bd8-1', + serviceName: 'aaaa3fb2f5dc42dd9772bedc93898bd8', + displayName: 'Display State - TEST', + description: + 'Debug node that displays the shared and transient state of the journey for debugging purposes.', + outcomes: ['outcome'], + outputs: [], + inputs: [], + script: + 'var SCRIPT_OUTCOMES = {\n OUTCOME: "outcome"\n};\n\nfunction main() {\n if (!callbacks.isEmpty()) {\n action.goTo(SCRIPT_OUTCOMES.OUTCOME);\n return;\n }\n var keySet = nodeState.keys(); // Java Set\n var keys = Array.from(keySet); // Make it into JavaScript array\n debugState = {};\n for (var i in keys) {\n var k = new String(keys[i]);\n var item = nodeState.get(k);\n if (typeof item === "object") {\n debugState[k] = nodeState.getObject(k);\n } else {\n debugState[k] = nodeState.get(k);\n }\n }\n if (properties.displayFormat === "JSON") {\n callbacksBuilder.textOutputCallback(0, `
${JSON.stringify(debugState, null, 2)}
`);\n return;\n }\n callbacksBuilder.textOutputCallback(0, `${Array.from(Object.keys(debugState).map(k => ``))}
KeyValue
${k}
${debugState[k]}
`);\n}\n\nmain();\n', + errorOutcome: false, + tags: ['debug', 'testing'], + properties: { + displayFormat: { + title: 'Display Format', + description: 'The format in which to display the states.', + type: 'STRING', + required: true, + defaultValue: 'TABLE', + options: { + TABLE: 'HTML Table', + JSON: 'Raw JSON', + }, + multivalued: false, + }, + }, +}; + +export const customNode3: NodeApi.CustomNodeSkeleton = { + _id: 'a6063fb2f5dc42dd9772bedc93898bd8-1', + serviceName: 'a6063fb2f5dc42dd9772bedc93898bd8', + displayName: 'ALU - TEST', + description: + 'Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.', + outcomes: ['Success'], + outputs: ['z'], + inputs: ['x', 'y'], + script: + 'var SCRIPT_OUTCOMES = {\n SUCCESS: \'Success\'\n};\n\nvar OPERATORS = {\n ADD: "ADD",\n SUBTRACT: "SUBTRACT",\n MULTIPLY: "MULTIPLY",\n DIVIDE: "DIVIDE"\n}\n\nfunction main() {\n var a = Number(properties.a);\n var b = Number(properties.b);\n switch (properties.operator) {\n case OPERATORS.ADD:\n nodeState.putShared("z", a + b);\n break;\n case OPERATORS.SUBTRACT:\n nodeState.putShared("z", a - b);\n break;\n case OPERATORS.MULTIPLY:\n nodeState.putShared("z", a * b);\n break;\n case OPERATORS.DIVIDE:\n if (b == 0) throw new Error("Cannot divide by 0");\n nodeState.putShared("z", a / b);\n break;\n default: throw new Error("Unknown operator.");\n }\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\n}\n\nmain();\n', + errorOutcome: true, + tags: ['math', 'utilities'], + properties: { + operator: { + title: 'Operator', + description: 'The operation to perform.', + type: 'STRING', + required: true, + defaultValue: 'ADD', + options: { + ADD: '+', + MULTIPLY: '*', + SUBTRACT: '-', + DIVIDE: '/', + }, + multivalued: false, + }, + }, +}; + +export const customNode4: NodeApi.CustomNodeSkeleton = { + _id: 'a15e2efb3deb4d4ea338c74a6440b69f-1', + serviceName: 'a15e2efb3deb4d4ea338c74a6440b69f', + displayName: 'Vector ALU - TEST', + description: + 'Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".', + outcomes: ['Success'], + outputs: ['c'], + inputs: [], + script: + 'var SCRIPT_OUTCOMES = {\n SUCCESS: \'Success\'\n};\n\nvar OPERATORS = {\n ADD: "ADD",\n SUBTRACT: "SUBTRACT",\n DOT: "DOT",\n CROSS: "CROSS"\n}\n\nfunction add(a, b) {\n return a.map((v, i) => v + b[i]);\n}\n\nfunction subtract(a, b) {\n return a.map((v, i) => v - b[i]);\n}\n\nfunction dot(a, b) {\n return a.reduce((sum, v, i) => sum + v * b[i], 0);\n}\n\nfunction cross(a, b) {\n return [\n a[1] * b[2] - a[2] * b[1],\n a[2] * b[0] - a[0] * b[2],\n a[0] * b[1] - a[1] * b[0]\n ];\n}\n\nfunction main() {\n if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");\n switch (properties.operator) {\n case OPERATORS.ADD:\n nodeState.putShared("c", add(properties.a, properties.b));\n break;\n case OPERATORS.SUBTRACT:\n nodeState.putShared("c", subtract(properties.a, properties.b));\n break;\n case OPERATORS.DOT:\n nodeState.putShared("c", dot(properties.a, properties.b));\n break;\n case OPERATORS.CROSS:\n if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");\n nodeState.putShared("c", cross(properties.a, properties.b));\n break;\n default: throw new Error("Unknown operator.");\n }\n action.goTo(SCRIPT_OUTCOMES.SUCCESS);\n}\n\nmain();\n', + errorOutcome: true, + tags: ['math', 'vector', 'utilities'], + properties: { + a: { + title: 'A', + description: 'Left vector operand', + type: 'NUMBER', + required: true, + defaultValue: [1, 2, 3], + multivalued: true, + }, + b: { + title: 'B', + description: 'Right vector operand', + type: 'NUMBER', + required: true, + defaultValue: [4, 5, 6], + multivalued: true, + }, + operator: { + title: 'Operator', + description: 'The binary operation to perform on the vectors.', + type: 'STRING', + required: true, + defaultValue: 'DOT', + options: { + ADD: '+', + CROSS: 'X', + DOT: '.', + SUBTRACT: '-', + }, + multivalued: false, + }, + }, +}; + +export async function stageNode(node: NodeApi.NodeSkeleton, createNew = false) { + try { + await NodeApi.deleteNode({ + nodeId: node._id, + nodeType: node._type._id, + state, + }); + } catch (error) { + // ignore + } finally { + if (createNew) { + await NodeApi.putNode({ + nodeId: node._id, + nodeType: node._type._id, + nodeData: node, + state, + }); + } + } +} + +export async function stageCustomNode( + customNode: NodeApi.CustomNodeSkeleton, + createNew = false +) { + try { + await NodeApi.deleteCustomNode({ + nodeId: customNode._id, + state, + }); + } catch (error) { + // ignore + } finally { + if (createNew) { + await NodeApi.createCustomNode({ + nodeData: customNode, + state, + }); + } + } +} + +export function setup() { + // in recording mode, setup test data before recording + beforeAll(async () => { + if (process.env.FRODO_POLLY_MODE === 'record') { + // setup node1 - delete if exists, then create + await stageNode(node1, true); + // setup node2 - delete if exists + await stageNode(node2); + // setup node3 - delete if exists, then create + await stageNode(node3, true); + // setup node4 - delete if exists, then create + await stageNode(node4, true); + // setup node5 - delete if exists + await stageNode(node5); + // setup customNode1 - delete if exists, then create + await stageCustomNode(customNode1, true); + // setup customNode2 - delete if exists, then create + await stageCustomNode(customNode2, true); + // setup customNode3 - delete if exists + await stageCustomNode(customNode3); + // setup customNode4 - delete if exists, then create + await stageCustomNode(customNode4, true); + } + }); + + // in recording mode, remove test data after recording + afterAll(async () => { + if (process.env.FRODO_POLLY_MODE === 'record') { + await stageNode(node1); + await stageNode(node2); + await stageNode(node3); + await stageNode(node4); + await stageNode(node5); + await stageCustomNode(customNode1); + await stageCustomNode(customNode2); + await stageCustomNode(customNode3); + await stageCustomNode(customNode4); + } + }); +} diff --git a/src/test/snapshots/api/NodeApi.test.js.snap b/src/test/snapshots/api/NodeApi.test.js.snap index 41d0efe99..795188bf4 100644 --- a/src/test/snapshots/api/NodeApi.test.js.snap +++ b/src/test/snapshots/api/NodeApi.test.js.snap @@ -1,5 +1,117 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`NodeApi createCustomNode() 1: Create custom node 1`] = ` +{ + "_id": "a6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "249944700", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU - TEST", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "a6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], +} +`; + +exports[`NodeApi createNode() 1: Create new node [5227de7a-02db-4f25-858e-c8d4f0e0b600 - SetStateNode] 1`] = ` +{ + "_id": "5227de7a-02db-4f25-858e-c8d4f0e0b600", + "_outcomes": [ + { + "displayName": "Outcome", + "id": "outcome", + }, + ], + "_rev": "1797046015", + "_type": { + "_id": "SetStateNode", + "collection": true, + "name": "Set State", + "version": "1.0", + }, + "attributes": { + "errorMessage": "An error has occurred!", + }, +} +`; + +exports[`NodeApi deleteCustomNode() 1: Delete existing custom node [a15e2efb3deb4d4ea338c74a6440b69f-1] 1`] = ` +{ + "_id": "a15e2efb3deb4d4ea338c74a6440b69f-1", +} +`; + +exports[`NodeApi deleteCustomNode() 2: Delete non-existing custom node [11111111111111111111111111111111-1] 1`] = ` +{ + "code": 404, + "message": "Node Type with resource ID 11111111111111111111111111111111-1 does not exist", + "reason": "Not Found", +} +`; + exports[`NodeApi deleteNode() 1: Delete existing node [23bab9d4-1663-450f-8a4b-680f44f54fd6 - CreateObjectNode] 1`] = ` { "_id": "23bab9d4-1663-450f-8a4b-680f44f54fd6", @@ -31,6 +143,1253 @@ exports[`NodeApi deleteNode() 2: Delete non-existing node [00000000-0000-0000-00 } `; +exports[`NodeApi getCustomNode() 1: Get existing custom node [a605506774a848f7877b4d17a453bd39-1] 1`] = ` +{ + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "1177267832", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], +} +`; + +exports[`NodeApi getCustomNode() 2: Get non-existing custom node [11111111111111111111111111111111-1] 1`] = ` +{ + "code": 404, + "message": "Node Type with resource ID 11111111111111111111111111111111-1 does not exist", + "reason": "Not Found", +} +`; + +exports[`NodeApi getCustomNodeUsage() 1: Get custom node usage [a605506774a848f7877b4d17a453bd39-1] 1`] = `{}`; + +exports[`NodeApi getCustomNodes() 1: Get all custom nodes 1`] = ` +{ + "pagedResultsCookie": null, + "remainingPagedResults": -1, + "result": [ + { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "594973911", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + { + "_id": "a15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "1736156056", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU - TEST", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + DOT: "DOT", + CROSS: "CROSS" +} + +function add(a, b) { + return a.map((v, i) => v + b[i]); +} + +function subtract(a, b) { + return a.map((v, i) => v - b[i]); +} + +function dot(a, b) { + return a.reduce((sum, v, i) => sum + v * b[i], 0); +} + +function cross(a, b) { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ]; +} + +function main() { + if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension."); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("c", add(properties.a, properties.b)); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("c", subtract(properties.a, properties.b)); + break; + case OPERATORS.DOT: + nodeState.putShared("c", dot(properties.a, properties.b)); + break; + case OPERATORS.CROSS: + if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product"); + nodeState.putShared("c", cross(properties.a, properties.b)); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "a15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + { + "_id": "aaaa3fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "2075177108", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "aaaa3fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "debug", + "testing", + ], + }, + { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "-628951673", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: 'outcome' +}; + +var CALLBACKS = { + BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK", + CHOICE_CALLBACK: "CHOICE_CALLBACK", + CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK", + CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK", + DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK", + HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK", + HTTP_CALLBACK: "HTTP_CALLBACK", + IDP_CALLBACK: "IDP_CALLBACK", + KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK", + LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK", + METADATA_CALLBACK: "METADATA_CALLBACK", + NAME_CALLBACK: "NAME_CALLBACK", + NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK", + PASSWORD_CALLBACK: "PASSWORD_CALLBACK", + POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK", + REDIRECT_CALLBACK: "REDIRECT_CALLBACK", + SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK", + SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK", + STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK", + SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK", + TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK", + TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK", + TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK", + VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK", + VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK", + X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK" +} + +function isStringPresent(value) { + return value; +} + +function getString(value) { + return value || ''; +} + +function isArrayPresent(value) { + return value; +} + +function getArray(value) { + return value ? JSON.parse(value) : []; +} + +function isObjectPresent(value) { + return value; +} + +function getObject(value) { + return value ? JSON.parse(value) : {}; +} + +function isIntPresent(value) { + return value; +} + +function getInt(value) { + return value ? parseInt(value) : 0; +} + +function isDoublePresent(value) { + return value; +} + +function getDouble(value) { + return value ? parseFloat(value) : 0.0; +} + +function isBooleanPresent(value) { + return value; +} + +function getBoolean(value) { + return value ? value.toLowerCase() === 'true' : false; +} + +function setProperty(value) { + if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value); + if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value); + if (properties.objectSharedProperty) { + var attributes = {}; + attributes[properties.objectSharedProperty] = value; + nodeState.mergeShared({ + objectAttributes: attributes + }); + } + if (properties.objectTransientProperty) { + var attributes = {}; + attributes[properties.objectTransientProperty] = value; + nodeState.mergeTransient({ + objectAttributes: attributes + }); + } +} + +function booleanAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getBoolean(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required); + } +} + +function choiceCallback() { + var prompt = getString(properties.options.prompt); + var choices = getArray(properties.options.choices); + var defaultChoice = getInt(properties.options.defaultChoice); + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed); +} + +function confirmationCallback() { + var prompt = getString(properties.options.prompt); + var messageType = getInt(properties.options.messageType); + var options = getArray(properties.options.options); + var optionType = getInt(properties.options.optionType); + var defaultOption = getInt(properties.options.defaultOption); + if (isStringPresent(properties.options.prompt)) { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption); + } + } else { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(messageType, options, defaultOption); + } + } +} + +function consentMappingCallback() { + var config = getObject(properties.options.config); + var message = getString(properties.options.message); + var isRequired = getBoolean(properties.options.isRequired); + var name = getString(properties.options.name); + var displayName = getString(properties.options.displayName); + var icon = getString(properties.options.icon); + var accessLevel = getString(properties.options.accessLevel); + var titles = getArray(properties.options.titles); + if (isObjectPresent(properties.options.prompt)) { + callbacksBuilder.consentMappingCallback(config, message, isRequired); + } else { + callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired); + } +} + +function deviceProfileCallback() { + var metadata = getBoolean(properties.options.metadata); + var location = getBoolean(properties.options.location); + var message = getString(properties.options.message); + callbacksBuilder.deviceProfileCallback(metadata, location, message); +} + +function hiddenValueCallback() { + var id = getString(properties.options.id); + var value = getString(properties.options.value); + callbacksBuilder.hiddenValueCallback(id, value); +} + +function httpCallback() { + var authorizationHeader = getString(properties.options.authorizationHeader); + var negotiationHeader = getString(properties.options.negotiationHeader); + var authRHeader = getString(properties.options.authRHeader); + var negoName = getString(properties.options.negoName); + var negoValue = getString(properties.options.negoValue); + if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) { + var errorCode = getString(properties.options.errorCode); + callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode); + } else { + var errorCode = getInt(properties.options.errorCode); + callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode); + } +} + +function idPCallback() { + var provider = getString(properties.options.provider); + var clientId = getString(properties.options.clientId); + var redirectUri = getString(properties.options.redirectUri); + var scope = getArray(properties.options.scope); + var nonce = getString(properties.options.nonce); + var request = getString(properties.options.request); + var requestUri = getString(properties.options.requestUri); + var acrValues = getArray(properties.options.acrValues); + var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo); + var token = getString(properties.options.token); + var tokenType = getString(properties.options.tokenType); + if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType); + } else { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo); + } +} + +function kbaCreateCallback() { + var prompt = getString(properties.options.prompt); + var predefinedQuestions = getArray(properties.options.predefinedQuestions); + var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions); + callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions); +} + +function languageCallback() { + var language = getString(properties.options.language); + var country = getString(properties.options.country); + callbacksBuilder.languageCallback(language, country); +} + +function metadataCallback() { + var outputValue = getObject(properties.options.outputValue); + callbacksBuilder.metadataCallback(outputValue); +} + +function nameCallback() { + var prompt = getString(properties.options.prompt); + var defaultName = getString(properties.options.defaultName); + if (isStringPresent(properties.options.defaultName)) { + callbacksBuilder.nameCallback(prompt, defaultName); + } else { + callbacksBuilder.nameCallback(prompt); + } +} + +function numberAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getDouble(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required); + } +} + +function passwordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + callbacksBuilder.passwordCallback(prompt, echoOn); +} + +function pollingWaitCallback() { + var waitTime = getString(properties.options.waitTime); + var message = getString(properties.options.message); + callbacksBuilder.pollingWaitCallback(waitTime, message); +} + +function redirectCallback() { + throw new Error('Not Implemented'); +} + +function scriptTextOutputCallback() { + var message = getString(properties.options.message); + callbacksBuilder.scriptTextOutputCallback(message); +} + +function selectIdPCallback() { + var providers = getObject(properties.options.providers); + callbacksBuilder.selectIdPCallback(providers); +} + +function stringAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getString(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required); + } +} + +function suspendedTextOutputCallback() { + var messageType = getInt(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.suspendedTextOutputCallback(messageType, message); +} + +function termsAndConditionsCallback() { + var version = getString(properties.options.version); + var terms = getString(properties.options.terms); + var createDate = getString(properties.options.createDate); + callbacksBuilder.termsAndConditionsCallback(version, terms, createDate); +} + +function textInputCallback() { + var prompt = getString(properties.options.prompt); + var defaultText = getString(properties.options.defaultText); + if (isStringPresent(properties.options.defaultText)) { + callbacksBuilder.textInputCallback(prompt, defaultText); + } else { + callbacksBuilder.textInputCallback(prompt); + } +} + +function textOutputCallback() { + var messageType = getString(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.textOutputCallback(messageType, message); +} + +function validatedPasswordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly); + } +} + +function validatedUsernameCallback() { + var prompt = getString(properties.options.prompt); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly); + } +} + +function x509CertificateCallback() { + throw new Error('Not Implemented'); +} + +function getBooleanAttributeInputCallback() { + setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0)); +} + +function getChoiceCallback() { + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + var selections = callbacks.getChoiceCallbacks().get(0); + setProperty(multipleSelectionsAllowed ? selections : selections[0]); +} + +function getConfirmationCallback() { + setProperty(callbacks.getConfirmationCallbacks().get(0)); +} + +function getConsentMappingCallback() { + setProperty(callbacks.getConsentMappingCallbacks().get(0)); +} + +function getDeviceProfileCallback() { + setProperty(callbacks.getDeviceProfileCallbacks().get(0)); +} + +function getHiddenValueCallback() { + var id = getString(properties.options.id); + setProperty(callbacks.getHiddenValueCallbacks().get(id)); +} + +function getHttpCallback() { + setProperty(callbacks.getHttpCallbacks().get(0)); +} + +function getIdPCallback() { + setProperty(callbacks.getIdpCallbacks().get(0)); +} + +function getKbaCreateCallback() { + setProperty(callbacks.getKbaCreateCallbacks().get(0)); +} + +function getLanguageCallback() { + setProperty(callbacks.getLanguageCallbacks().get(0)); +} + +function getNameCallback() { + setProperty(callbacks.getNameCallbacks().get(0)); +} + +function getNumberAttributeInputCallback() { + setProperty(callbacks.getNumberAttributeInputCallbacks().get(0)); +} + +function getPasswordCallback() { + setProperty(callbacks.getPasswordCallbacks().get(0)); +} + +function getSelectIdPCallback() { + setProperty(callbacks.getSelectIdPCallbacks().get(0)); +} + +function getStringAttributeInputCallback() { + setProperty(callbacks.getStringAttributeInputCallbacks().get(0)); +} + +function getTermsAndConditionsCallback() { + setProperty(callbacks.getTermsAndConditionsCallbacks().get(0)); +} + +function getTextInputCallback() { + setProperty(callbacks.getTextInputCallbacks().get(0)); +} + +function getValidatedPasswordCallback() { + setProperty(callbacks.getValidatedPasswordCallbacks().get(0)); +} + +function getValidatedUsernameCallback() { + setProperty(callbacks.getValidatedUsernameCallbacks().get(0)); +} + +function getX509CertificateCallback() { + setProperty(callbacks.getX509CertificateCallbacks().get(0)); +} + +function main() { + if (!callbacks.isEmpty()) { + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break; + case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break; + case CALLBACKS.NAME_CALLBACK: getNameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break; + default: break; + } + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: httpCallback(); break; + case CALLBACKS.IDP_CALLBACK: idPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break; + case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break; + case CALLBACKS.NAME_CALLBACK: nameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break; + case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break; + case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break; + case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break; + case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break; + case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break; + default: throw new Error('Unknown Callback'); // Should never reach this case + } +} + +main(); +", + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "1253294564", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + { + "_id": "session-1", + "_rev": "490056204", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "1113564678", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + DOT: "DOT", + CROSS: "CROSS" +} + +function add(a, b) { + return a.map((v, i) => v + b[i]); +} + +function subtract(a, b) { + return a.map((v, i) => v - b[i]); +} + +function dot(a, b) { + return a.reduce((sum, v, i) => sum + v * b[i], 0); +} + +function cross(a, b) { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ]; +} + +function main() { + if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension."); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("c", add(properties.a, properties.b)); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("c", subtract(properties.a, properties.b)); + break; + case OPERATORS.DOT: + nodeState.putShared("c", dot(properties.a, properties.b)); + break; + case OPERATORS.CROSS: + if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product"); + nodeState.putShared("c", cross(properties.a, properties.b)); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "-1941250080", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + { + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "2077288621", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "1554001423", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": "var aud = properties.audience; +var iss = properties.issuer; +var validity = properties.validity; +var esv = properties.signingkey; + +var signingkey = systemEnv.getProperty(esv); + +var username = nodeState.get("username"); + +var data = { + jwtType:"SIGNED", + jwsAlgorithm: "HS256", + issuer: iss, + subject: username, + audience: aud, + type: "JWT", + validityMinutes: validity, + signingKey: signingkey +}; + +var jwt = jwtAssertion.generateJwt(data); + +if (jwt !== null && jwt.length > 0) { + nodeState.putShared("assertionJwt" , jwt); + action.goTo("True"); +} else { + action.goTo("False"); +}", + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + ], + "resultCount": 10, + "totalPagedResults": 10, + "totalPagedResultsPolicy": "EXACT", +} +`; + exports[`NodeApi getNode() 1: Get existing node [67693475-3a58-4e38-bcc6-037b3fe46a58 - ValidatedUsernameNode] 1`] = ` { "_id": "67693475-3a58-4e38-bcc6-037b3fe46a58", @@ -12904,6 +14263,70 @@ exports[`NodeApi getNodesByType() 1: Get all page nodes 1`] = ` } `; +exports[`NodeApi putCustomNode() 1: Update existing custom node [aaaa3fb2f5dc42dd9772bedc93898bd8-1] 1`] = ` +{ + "_id": "aaaa3fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "1871053300", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "aaaa3fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "debug", + "testing", + ], +} +`; + exports[`NodeApi putNode() 1: Create new node [18ffdd4b-41b7-41b3-8248-f4fdfd68423f - ValidatedPasswordNode] 1`] = ` { "_id": "18ffdd4b-41b7-41b3-8248-f4fdfd68423f", @@ -12913,11 +14336,12 @@ exports[`NodeApi putNode() 1: Create new node [18ffdd4b-41b7-41b3-8248-f4fdfd684 "id": "outcome", }, ], - "_rev": "-1456614726", + "_rev": "-1272777657", "_type": { "_id": "ValidatedPasswordNode", "collection": true, "name": "Platform Password", + "version": "1.0", }, "passwordAttribute": "password", "validateInput": false, @@ -12937,11 +14361,12 @@ exports[`NodeApi putNode() 2: Update existing node [b726262c-641e-4fa5-b276-98e1 "id": "FAILURE", }, ], - "_rev": "-2080259640", + "_rev": "-1625726187", "_type": { "_id": "PatchObjectNode", "collection": true, "name": "Patch Object", + "version": "1.0", }, "identityAttribute": "userName", "identityResource": "managed/user", diff --git a/src/test/snapshots/ops/ConfigOps.test.js.snap b/src/test/snapshots/ops/ConfigOps.test.js.snap index be97433d0..b91da8f4b 100644 --- a/src/test/snapshots/ops/ConfigOps.test.js.snap +++ b/src/test/snapshots/ops/ConfigOps.test.js.snap @@ -1095,6 +1095,1012 @@ exports[`ConfigOps Classic Tests exportFullConfiguration() 6: Export everything "idm": undefined, "internalRole": undefined, "mapping": undefined, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "390387834", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "733279755", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "419010643", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "296916566", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " MULTIPLY: "MULTIPLY",", + " DIVIDE: "DIVIDE"", + "}", + "", + "function main() {", + " var a = Number(properties.a);", + " var b = Number(properties.b);", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("z", a + b);", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("z", a - b);", + " break;", + " case OPERATORS.MULTIPLY:", + " nodeState.putShared("z", a * b);", + " break;", + " case OPERATORS.DIVIDE:", + " if (b == 0) throw new Error("Cannot divide by 0");", + " nodeState.putShared("z", a / b);", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "764229896", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": [ + "var aud = properties.audience;", + "var iss = properties.issuer;", + "var validity = properties.validity;", + "var esv = properties.signingkey;", + "", + "var signingkey = systemEnv.getProperty(esv);", + "", + "var username = nodeState.get("username");", + "", + "var data = {", + " jwtType:"SIGNED",", + " jwsAlgorithm: "HS256",", + " issuer: iss,", + " subject: username,", + " audience: aud,", + " type: "JWT",", + " validityMinutes: validity,", + " signingKey: signingkey", + "};", + "", + "var jwt = jwtAssertion.generateJwt(data);", + "", + "if (jwt !== null && jwt.length > 0) {", + " nodeState.putShared("assertionJwt" , jwt);", + " action.goTo("True");", + "} else {", + " action.goTo("False");", + "}", + "", + ], + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1484382943", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "745481489", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": { "L2ZpcnN0": { "_id": "L2ZpcnN0", @@ -38716,6 +39722,998 @@ exports[`ConfigOps Classic Tests exportFullConfiguration() 7: Export everything "idm": undefined, "internalRole": undefined, "mapping": undefined, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "390387834", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "733279755", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + DOT: "DOT", + CROSS: "CROSS" +} + +function add(a, b) { + return a.map((v, i) => v + b[i]); +} + +function subtract(a, b) { + return a.map((v, i) => v - b[i]); +} + +function dot(a, b) { + return a.reduce((sum, v, i) => sum + v * b[i], 0); +} + +function cross(a, b) { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ]; +} + +function main() { + if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension."); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("c", add(properties.a, properties.b)); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("c", subtract(properties.a, properties.b)); + break; + case OPERATORS.DOT: + nodeState.putShared("c", dot(properties.a, properties.b)); + break; + case OPERATORS.CROSS: + if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product"); + nodeState.putShared("c", cross(properties.a, properties.b)); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "419010643", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "296916566", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "764229896", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": "var aud = properties.audience; +var iss = properties.issuer; +var validity = properties.validity; +var esv = properties.signingkey; + +var signingkey = systemEnv.getProperty(esv); + +var username = nodeState.get("username"); + +var data = { + jwtType:"SIGNED", + jwsAlgorithm: "HS256", + issuer: iss, + subject: username, + audience: aud, + type: "JWT", + validityMinutes: validity, + signingKey: signingkey +}; + +var jwt = jwtAssertion.generateJwt(data); + +if (jwt !== null && jwt.length > 0) { + nodeState.putShared("assertionJwt" , jwt); + action.goTo("True"); +} else { + action.goTo("False"); +} +", + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1484382943", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: 'outcome' +}; + +var CALLBACKS = { + BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK", + CHOICE_CALLBACK: "CHOICE_CALLBACK", + CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK", + CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK", + DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK", + HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK", + HTTP_CALLBACK: "HTTP_CALLBACK", + IDP_CALLBACK: "IDP_CALLBACK", + KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK", + LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK", + METADATA_CALLBACK: "METADATA_CALLBACK", + NAME_CALLBACK: "NAME_CALLBACK", + NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK", + PASSWORD_CALLBACK: "PASSWORD_CALLBACK", + POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK", + REDIRECT_CALLBACK: "REDIRECT_CALLBACK", + SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK", + SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK", + STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK", + SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK", + TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK", + TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK", + TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK", + VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK", + VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK", + X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK" +} + +function isStringPresent(value) { + return value; +} + +function getString(value) { + return value || ''; +} + +function isArrayPresent(value) { + return value; +} + +function getArray(value) { + return value ? JSON.parse(value) : []; +} + +function isObjectPresent(value) { + return value; +} + +function getObject(value) { + return value ? JSON.parse(value) : {}; +} + +function isIntPresent(value) { + return value; +} + +function getInt(value) { + return value ? parseInt(value) : 0; +} + +function isDoublePresent(value) { + return value; +} + +function getDouble(value) { + return value ? parseFloat(value) : 0.0; +} + +function isBooleanPresent(value) { + return value; +} + +function getBoolean(value) { + return value ? value.toLowerCase() === 'true' : false; +} + +function setProperty(value) { + if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value); + if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value); + if (properties.objectSharedProperty) { + var attributes = {}; + attributes[properties.objectSharedProperty] = value; + nodeState.mergeShared({ + objectAttributes: attributes + }); + } + if (properties.objectTransientProperty) { + var attributes = {}; + attributes[properties.objectTransientProperty] = value; + nodeState.mergeTransient({ + objectAttributes: attributes + }); + } +} + +function booleanAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getBoolean(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required); + } +} + +function choiceCallback() { + var prompt = getString(properties.options.prompt); + var choices = getArray(properties.options.choices); + var defaultChoice = getInt(properties.options.defaultChoice); + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed); +} + +function confirmationCallback() { + var prompt = getString(properties.options.prompt); + var messageType = getInt(properties.options.messageType); + var options = getArray(properties.options.options); + var optionType = getInt(properties.options.optionType); + var defaultOption = getInt(properties.options.defaultOption); + if (isStringPresent(properties.options.prompt)) { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption); + } + } else { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(messageType, options, defaultOption); + } + } +} + +function consentMappingCallback() { + var config = getObject(properties.options.config); + var message = getString(properties.options.message); + var isRequired = getBoolean(properties.options.isRequired); + var name = getString(properties.options.name); + var displayName = getString(properties.options.displayName); + var icon = getString(properties.options.icon); + var accessLevel = getString(properties.options.accessLevel); + var titles = getArray(properties.options.titles); + if (isObjectPresent(properties.options.prompt)) { + callbacksBuilder.consentMappingCallback(config, message, isRequired); + } else { + callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired); + } +} + +function deviceProfileCallback() { + var metadata = getBoolean(properties.options.metadata); + var location = getBoolean(properties.options.location); + var message = getString(properties.options.message); + callbacksBuilder.deviceProfileCallback(metadata, location, message); +} + +function hiddenValueCallback() { + var id = getString(properties.options.id); + var value = getString(properties.options.value); + callbacksBuilder.hiddenValueCallback(id, value); +} + +function httpCallback() { + var authorizationHeader = getString(properties.options.authorizationHeader); + var negotiationHeader = getString(properties.options.negotiationHeader); + var authRHeader = getString(properties.options.authRHeader); + var negoName = getString(properties.options.negoName); + var negoValue = getString(properties.options.negoValue); + if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) { + var errorCode = getString(properties.options.errorCode); + callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode); + } else { + var errorCode = getInt(properties.options.errorCode); + callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode); + } +} + +function idPCallback() { + var provider = getString(properties.options.provider); + var clientId = getString(properties.options.clientId); + var redirectUri = getString(properties.options.redirectUri); + var scope = getArray(properties.options.scope); + var nonce = getString(properties.options.nonce); + var request = getString(properties.options.request); + var requestUri = getString(properties.options.requestUri); + var acrValues = getArray(properties.options.acrValues); + var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo); + var token = getString(properties.options.token); + var tokenType = getString(properties.options.tokenType); + if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType); + } else { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo); + } +} + +function kbaCreateCallback() { + var prompt = getString(properties.options.prompt); + var predefinedQuestions = getArray(properties.options.predefinedQuestions); + var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions); + callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions); +} + +function languageCallback() { + var language = getString(properties.options.language); + var country = getString(properties.options.country); + callbacksBuilder.languageCallback(language, country); +} + +function metadataCallback() { + var outputValue = getObject(properties.options.outputValue); + callbacksBuilder.metadataCallback(outputValue); +} + +function nameCallback() { + var prompt = getString(properties.options.prompt); + var defaultName = getString(properties.options.defaultName); + if (isStringPresent(properties.options.defaultName)) { + callbacksBuilder.nameCallback(prompt, defaultName); + } else { + callbacksBuilder.nameCallback(prompt); + } +} + +function numberAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getDouble(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required); + } +} + +function passwordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + callbacksBuilder.passwordCallback(prompt, echoOn); +} + +function pollingWaitCallback() { + var waitTime = getString(properties.options.waitTime); + var message = getString(properties.options.message); + callbacksBuilder.pollingWaitCallback(waitTime, message); +} + +function redirectCallback() { + throw new Error('Not Implemented'); +} + +function scriptTextOutputCallback() { + var message = getString(properties.options.message); + callbacksBuilder.scriptTextOutputCallback(message); +} + +function selectIdPCallback() { + var providers = getObject(properties.options.providers); + callbacksBuilder.selectIdPCallback(providers); +} + +function stringAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getString(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required); + } +} + +function suspendedTextOutputCallback() { + var messageType = getInt(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.suspendedTextOutputCallback(messageType, message); +} + +function termsAndConditionsCallback() { + var version = getString(properties.options.version); + var terms = getString(properties.options.terms); + var createDate = getString(properties.options.createDate); + callbacksBuilder.termsAndConditionsCallback(version, terms, createDate); +} + +function textInputCallback() { + var prompt = getString(properties.options.prompt); + var defaultText = getString(properties.options.defaultText); + if (isStringPresent(properties.options.defaultText)) { + callbacksBuilder.textInputCallback(prompt, defaultText); + } else { + callbacksBuilder.textInputCallback(prompt); + } +} + +function textOutputCallback() { + var messageType = getString(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.textOutputCallback(messageType, message); +} + +function validatedPasswordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly); + } +} + +function validatedUsernameCallback() { + var prompt = getString(properties.options.prompt); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly); + } +} + +function x509CertificateCallback() { + throw new Error('Not Implemented'); +} + +function getBooleanAttributeInputCallback() { + setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0)); +} + +function getChoiceCallback() { + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + var selections = callbacks.getChoiceCallbacks().get(0); + setProperty(multipleSelectionsAllowed ? selections : selections[0]); +} + +function getConfirmationCallback() { + setProperty(callbacks.getConfirmationCallbacks().get(0)); +} + +function getConsentMappingCallback() { + setProperty(callbacks.getConsentMappingCallbacks().get(0)); +} + +function getDeviceProfileCallback() { + setProperty(callbacks.getDeviceProfileCallbacks().get(0)); +} + +function getHiddenValueCallback() { + var id = getString(properties.options.id); + setProperty(callbacks.getHiddenValueCallbacks().get(id)); +} + +function getHttpCallback() { + setProperty(callbacks.getHttpCallbacks().get(0)); +} + +function getIdPCallback() { + setProperty(callbacks.getIdpCallbacks().get(0)); +} + +function getKbaCreateCallback() { + setProperty(callbacks.getKbaCreateCallbacks().get(0)); +} + +function getLanguageCallback() { + setProperty(callbacks.getLanguageCallbacks().get(0)); +} + +function getNameCallback() { + setProperty(callbacks.getNameCallbacks().get(0)); +} + +function getNumberAttributeInputCallback() { + setProperty(callbacks.getNumberAttributeInputCallbacks().get(0)); +} + +function getPasswordCallback() { + setProperty(callbacks.getPasswordCallbacks().get(0)); +} + +function getSelectIdPCallback() { + setProperty(callbacks.getSelectIdPCallbacks().get(0)); +} + +function getStringAttributeInputCallback() { + setProperty(callbacks.getStringAttributeInputCallbacks().get(0)); +} + +function getTermsAndConditionsCallback() { + setProperty(callbacks.getTermsAndConditionsCallbacks().get(0)); +} + +function getTextInputCallback() { + setProperty(callbacks.getTextInputCallbacks().get(0)); +} + +function getValidatedPasswordCallback() { + setProperty(callbacks.getValidatedPasswordCallbacks().get(0)); +} + +function getValidatedUsernameCallback() { + setProperty(callbacks.getValidatedUsernameCallbacks().get(0)); +} + +function getX509CertificateCallback() { + setProperty(callbacks.getX509CertificateCallbacks().get(0)); +} + +function main() { + if (!callbacks.isEmpty()) { + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break; + case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break; + case CALLBACKS.NAME_CALLBACK: getNameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break; + default: break; + } + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: httpCallback(); break; + case CALLBACKS.IDP_CALLBACK: idPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break; + case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break; + case CALLBACKS.NAME_CALLBACK: nameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break; + case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break; + case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break; + case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break; + case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break; + case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break; + default: throw new Error('Unknown Callback'); // Should never reach this case + } +} + +main(); +", + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "745481489", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": { "L2ZpcnN0": { "_id": "L2ZpcnN0", @@ -63624,6 +65622,1012 @@ exports[`ConfigOps Classic Tests exportFullConfiguration() 8: Export only import "idm": undefined, "internalRole": undefined, "mapping": undefined, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "390387834", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "733279755", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "419010643", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "296916566", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " MULTIPLY: "MULTIPLY",", + " DIVIDE: "DIVIDE"", + "}", + "", + "function main() {", + " var a = Number(properties.a);", + " var b = Number(properties.b);", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("z", a + b);", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("z", a - b);", + " break;", + " case OPERATORS.MULTIPLY:", + " nodeState.putShared("z", a * b);", + " break;", + " case OPERATORS.DIVIDE:", + " if (b == 0) throw new Error("Cannot divide by 0");", + " nodeState.putShared("z", a / b);", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "764229896", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": [ + "var aud = properties.audience;", + "var iss = properties.issuer;", + "var validity = properties.validity;", + "var esv = properties.signingkey;", + "", + "var signingkey = systemEnv.getProperty(esv);", + "", + "var username = nodeState.get("username");", + "", + "var data = {", + " jwtType:"SIGNED",", + " jwsAlgorithm: "HS256",", + " issuer: iss,", + " subject: username,", + " audience: aud,", + " type: "JWT",", + " validityMinutes: validity,", + " signingKey: signingkey", + "};", + "", + "var jwt = jwtAssertion.generateJwt(data);", + "", + "if (jwt !== null && jwt.length > 0) {", + " nodeState.putShared("assertionJwt" , jwt);", + " action.goTo("True");", + "} else {", + " action.goTo("False");", + "}", + "", + ], + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1484382943", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "745481489", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": { "L2ZpcnN0": { "_id": "L2ZpcnN0", @@ -113395,6 +116399,1012 @@ exports[`ConfigOps Classic Tests exportFullConfiguration() 10: Export only globa "idm": undefined, "internalRole": undefined, "mapping": undefined, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "390387834", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "733279755", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "419010643", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "296916566", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " MULTIPLY: "MULTIPLY",", + " DIVIDE: "DIVIDE"", + "}", + "", + "function main() {", + " var a = Number(properties.a);", + " var b = Number(properties.b);", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("z", a + b);", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("z", a - b);", + " break;", + " case OPERATORS.MULTIPLY:", + " nodeState.putShared("z", a * b);", + " break;", + " case OPERATORS.DIVIDE:", + " if (b == 0) throw new Error("Cannot divide by 0");", + " nodeState.putShared("z", a / b);", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "764229896", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": [ + "var aud = properties.audience;", + "var iss = properties.issuer;", + "var validity = properties.validity;", + "var esv = properties.signingkey;", + "", + "var signingkey = systemEnv.getProperty(esv);", + "", + "var username = nodeState.get("username");", + "", + "var data = {", + " jwtType:"SIGNED",", + " jwsAlgorithm: "HS256",", + " issuer: iss,", + " subject: username,", + " audience: aud,", + " type: "JWT",", + " validityMinutes: validity,", + " signingKey: signingkey", + "};", + "", + "var jwt = jwtAssertion.generateJwt(data);", + "", + "if (jwt !== null && jwt.length > 0) {", + " nodeState.putShared("assertionJwt" , jwt);", + " action.goTo("True");", + "} else {", + " action.goTo("False");", + "}", + "", + ], + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1484382943", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "745481489", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": { "L2ZpcnN0": { "_id": "L2ZpcnN0", @@ -136176,6 +140186,1012 @@ a { }, }, }, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "-1749152606", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "957146401", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "309311416", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "855360523", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " MULTIPLY: "MULTIPLY",", + " DIVIDE: "DIVIDE"", + "}", + "", + "function main() {", + " var a = Number(properties.a);", + " var b = Number(properties.b);", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("z", a + b);", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("z", a - b);", + " break;", + " case OPERATORS.MULTIPLY:", + " nodeState.putShared("z", a * b);", + " break;", + " case OPERATORS.DIVIDE:", + " if (b == 0) throw new Error("Cannot divide by 0");", + " nodeState.putShared("z", a / b);", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "-2070743967", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": [ + "var aud = properties.audience;", + "var iss = properties.issuer;", + "var validity = properties.validity;", + "var esv = properties.signingkey;", + "", + "var signingkey = systemEnv.getProperty(esv);", + "", + "var username = nodeState.get("username");", + "", + "var data = {", + " jwtType:"SIGNED",", + " jwsAlgorithm: "HS256",", + " issuer: iss,", + " subject: username,", + " audience: aud,", + " type: "JWT",", + " validityMinutes: validity,", + " signingKey: signingkey", + "};", + "", + "var jwt = jwtAssertion.generateJwt(data);", + "", + "if (jwt !== null && jwt.length > 0) {", + " nodeState.putShared("assertionJwt" , jwt);", + " action.goTo("True");", + "} else {", + " action.goTo("False");", + "}", + "", + ], + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1859562163", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "705045404", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": { "L2FscGhh": { "_id": "L2FscGhh", @@ -211569,6 +216585,998 @@ a { }, }, }, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "-1749152606", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "957146401", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + DOT: "DOT", + CROSS: "CROSS" +} + +function add(a, b) { + return a.map((v, i) => v + b[i]); +} + +function subtract(a, b) { + return a.map((v, i) => v - b[i]); +} + +function dot(a, b) { + return a.reduce((sum, v, i) => sum + v * b[i], 0); +} + +function cross(a, b) { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ]; +} + +function main() { + if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension."); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("c", add(properties.a, properties.b)); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("c", subtract(properties.a, properties.b)); + break; + case OPERATORS.DOT: + nodeState.putShared("c", dot(properties.a, properties.b)); + break; + case OPERATORS.CROSS: + if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product"); + nodeState.putShared("c", cross(properties.a, properties.b)); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "309311416", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "855360523", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "-2070743967", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": "var aud = properties.audience; +var iss = properties.issuer; +var validity = properties.validity; +var esv = properties.signingkey; + +var signingkey = systemEnv.getProperty(esv); + +var username = nodeState.get("username"); + +var data = { + jwtType:"SIGNED", + jwsAlgorithm: "HS256", + issuer: iss, + subject: username, + audience: aud, + type: "JWT", + validityMinutes: validity, + signingKey: signingkey +}; + +var jwt = jwtAssertion.generateJwt(data); + +if (jwt !== null && jwt.length > 0) { + nodeState.putShared("assertionJwt" , jwt); + action.goTo("True"); +} else { + action.goTo("False"); +} +", + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1859562163", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: 'outcome' +}; + +var CALLBACKS = { + BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK", + CHOICE_CALLBACK: "CHOICE_CALLBACK", + CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK", + CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK", + DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK", + HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK", + HTTP_CALLBACK: "HTTP_CALLBACK", + IDP_CALLBACK: "IDP_CALLBACK", + KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK", + LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK", + METADATA_CALLBACK: "METADATA_CALLBACK", + NAME_CALLBACK: "NAME_CALLBACK", + NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK", + PASSWORD_CALLBACK: "PASSWORD_CALLBACK", + POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK", + REDIRECT_CALLBACK: "REDIRECT_CALLBACK", + SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK", + SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK", + STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK", + SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK", + TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK", + TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK", + TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK", + VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK", + VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK", + X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK" +} + +function isStringPresent(value) { + return value; +} + +function getString(value) { + return value || ''; +} + +function isArrayPresent(value) { + return value; +} + +function getArray(value) { + return value ? JSON.parse(value) : []; +} + +function isObjectPresent(value) { + return value; +} + +function getObject(value) { + return value ? JSON.parse(value) : {}; +} + +function isIntPresent(value) { + return value; +} + +function getInt(value) { + return value ? parseInt(value) : 0; +} + +function isDoublePresent(value) { + return value; +} + +function getDouble(value) { + return value ? parseFloat(value) : 0.0; +} + +function isBooleanPresent(value) { + return value; +} + +function getBoolean(value) { + return value ? value.toLowerCase() === 'true' : false; +} + +function setProperty(value) { + if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value); + if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value); + if (properties.objectSharedProperty) { + var attributes = {}; + attributes[properties.objectSharedProperty] = value; + nodeState.mergeShared({ + objectAttributes: attributes + }); + } + if (properties.objectTransientProperty) { + var attributes = {}; + attributes[properties.objectTransientProperty] = value; + nodeState.mergeTransient({ + objectAttributes: attributes + }); + } +} + +function booleanAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getBoolean(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required); + } +} + +function choiceCallback() { + var prompt = getString(properties.options.prompt); + var choices = getArray(properties.options.choices); + var defaultChoice = getInt(properties.options.defaultChoice); + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed); +} + +function confirmationCallback() { + var prompt = getString(properties.options.prompt); + var messageType = getInt(properties.options.messageType); + var options = getArray(properties.options.options); + var optionType = getInt(properties.options.optionType); + var defaultOption = getInt(properties.options.defaultOption); + if (isStringPresent(properties.options.prompt)) { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption); + } + } else { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(messageType, options, defaultOption); + } + } +} + +function consentMappingCallback() { + var config = getObject(properties.options.config); + var message = getString(properties.options.message); + var isRequired = getBoolean(properties.options.isRequired); + var name = getString(properties.options.name); + var displayName = getString(properties.options.displayName); + var icon = getString(properties.options.icon); + var accessLevel = getString(properties.options.accessLevel); + var titles = getArray(properties.options.titles); + if (isObjectPresent(properties.options.prompt)) { + callbacksBuilder.consentMappingCallback(config, message, isRequired); + } else { + callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired); + } +} + +function deviceProfileCallback() { + var metadata = getBoolean(properties.options.metadata); + var location = getBoolean(properties.options.location); + var message = getString(properties.options.message); + callbacksBuilder.deviceProfileCallback(metadata, location, message); +} + +function hiddenValueCallback() { + var id = getString(properties.options.id); + var value = getString(properties.options.value); + callbacksBuilder.hiddenValueCallback(id, value); +} + +function httpCallback() { + var authorizationHeader = getString(properties.options.authorizationHeader); + var negotiationHeader = getString(properties.options.negotiationHeader); + var authRHeader = getString(properties.options.authRHeader); + var negoName = getString(properties.options.negoName); + var negoValue = getString(properties.options.negoValue); + if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) { + var errorCode = getString(properties.options.errorCode); + callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode); + } else { + var errorCode = getInt(properties.options.errorCode); + callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode); + } +} + +function idPCallback() { + var provider = getString(properties.options.provider); + var clientId = getString(properties.options.clientId); + var redirectUri = getString(properties.options.redirectUri); + var scope = getArray(properties.options.scope); + var nonce = getString(properties.options.nonce); + var request = getString(properties.options.request); + var requestUri = getString(properties.options.requestUri); + var acrValues = getArray(properties.options.acrValues); + var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo); + var token = getString(properties.options.token); + var tokenType = getString(properties.options.tokenType); + if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType); + } else { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo); + } +} + +function kbaCreateCallback() { + var prompt = getString(properties.options.prompt); + var predefinedQuestions = getArray(properties.options.predefinedQuestions); + var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions); + callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions); +} + +function languageCallback() { + var language = getString(properties.options.language); + var country = getString(properties.options.country); + callbacksBuilder.languageCallback(language, country); +} + +function metadataCallback() { + var outputValue = getObject(properties.options.outputValue); + callbacksBuilder.metadataCallback(outputValue); +} + +function nameCallback() { + var prompt = getString(properties.options.prompt); + var defaultName = getString(properties.options.defaultName); + if (isStringPresent(properties.options.defaultName)) { + callbacksBuilder.nameCallback(prompt, defaultName); + } else { + callbacksBuilder.nameCallback(prompt); + } +} + +function numberAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getDouble(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required); + } +} + +function passwordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + callbacksBuilder.passwordCallback(prompt, echoOn); +} + +function pollingWaitCallback() { + var waitTime = getString(properties.options.waitTime); + var message = getString(properties.options.message); + callbacksBuilder.pollingWaitCallback(waitTime, message); +} + +function redirectCallback() { + throw new Error('Not Implemented'); +} + +function scriptTextOutputCallback() { + var message = getString(properties.options.message); + callbacksBuilder.scriptTextOutputCallback(message); +} + +function selectIdPCallback() { + var providers = getObject(properties.options.providers); + callbacksBuilder.selectIdPCallback(providers); +} + +function stringAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getString(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required); + } +} + +function suspendedTextOutputCallback() { + var messageType = getInt(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.suspendedTextOutputCallback(messageType, message); +} + +function termsAndConditionsCallback() { + var version = getString(properties.options.version); + var terms = getString(properties.options.terms); + var createDate = getString(properties.options.createDate); + callbacksBuilder.termsAndConditionsCallback(version, terms, createDate); +} + +function textInputCallback() { + var prompt = getString(properties.options.prompt); + var defaultText = getString(properties.options.defaultText); + if (isStringPresent(properties.options.defaultText)) { + callbacksBuilder.textInputCallback(prompt, defaultText); + } else { + callbacksBuilder.textInputCallback(prompt); + } +} + +function textOutputCallback() { + var messageType = getString(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.textOutputCallback(messageType, message); +} + +function validatedPasswordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly); + } +} + +function validatedUsernameCallback() { + var prompt = getString(properties.options.prompt); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly); + } +} + +function x509CertificateCallback() { + throw new Error('Not Implemented'); +} + +function getBooleanAttributeInputCallback() { + setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0)); +} + +function getChoiceCallback() { + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + var selections = callbacks.getChoiceCallbacks().get(0); + setProperty(multipleSelectionsAllowed ? selections : selections[0]); +} + +function getConfirmationCallback() { + setProperty(callbacks.getConfirmationCallbacks().get(0)); +} + +function getConsentMappingCallback() { + setProperty(callbacks.getConsentMappingCallbacks().get(0)); +} + +function getDeviceProfileCallback() { + setProperty(callbacks.getDeviceProfileCallbacks().get(0)); +} + +function getHiddenValueCallback() { + var id = getString(properties.options.id); + setProperty(callbacks.getHiddenValueCallbacks().get(id)); +} + +function getHttpCallback() { + setProperty(callbacks.getHttpCallbacks().get(0)); +} + +function getIdPCallback() { + setProperty(callbacks.getIdpCallbacks().get(0)); +} + +function getKbaCreateCallback() { + setProperty(callbacks.getKbaCreateCallbacks().get(0)); +} + +function getLanguageCallback() { + setProperty(callbacks.getLanguageCallbacks().get(0)); +} + +function getNameCallback() { + setProperty(callbacks.getNameCallbacks().get(0)); +} + +function getNumberAttributeInputCallback() { + setProperty(callbacks.getNumberAttributeInputCallbacks().get(0)); +} + +function getPasswordCallback() { + setProperty(callbacks.getPasswordCallbacks().get(0)); +} + +function getSelectIdPCallback() { + setProperty(callbacks.getSelectIdPCallbacks().get(0)); +} + +function getStringAttributeInputCallback() { + setProperty(callbacks.getStringAttributeInputCallbacks().get(0)); +} + +function getTermsAndConditionsCallback() { + setProperty(callbacks.getTermsAndConditionsCallbacks().get(0)); +} + +function getTextInputCallback() { + setProperty(callbacks.getTextInputCallbacks().get(0)); +} + +function getValidatedPasswordCallback() { + setProperty(callbacks.getValidatedPasswordCallbacks().get(0)); +} + +function getValidatedUsernameCallback() { + setProperty(callbacks.getValidatedUsernameCallbacks().get(0)); +} + +function getX509CertificateCallback() { + setProperty(callbacks.getX509CertificateCallbacks().get(0)); +} + +function main() { + if (!callbacks.isEmpty()) { + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break; + case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break; + case CALLBACKS.NAME_CALLBACK: getNameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break; + default: break; + } + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: httpCallback(); break; + case CALLBACKS.IDP_CALLBACK: idPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break; + case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break; + case CALLBACKS.NAME_CALLBACK: nameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break; + case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break; + case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break; + case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break; + case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break; + case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break; + default: throw new Error('Unknown Callback'); // Should never reach this case + } +} + +main(); +", + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "705045404", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": { "L2FscGhh": { "_id": "L2FscGhh", @@ -276422,6 +282430,1012 @@ a { }, }, }, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "-1749152606", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "957146401", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "309311416", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "855360523", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " MULTIPLY: "MULTIPLY",", + " DIVIDE: "DIVIDE"", + "}", + "", + "function main() {", + " var a = Number(properties.a);", + " var b = Number(properties.b);", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("z", a + b);", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("z", a - b);", + " break;", + " case OPERATORS.MULTIPLY:", + " nodeState.putShared("z", a * b);", + " break;", + " case OPERATORS.DIVIDE:", + " if (b == 0) throw new Error("Cannot divide by 0");", + " nodeState.putShared("z", a / b);", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "-2070743967", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": [ + "var aud = properties.audience;", + "var iss = properties.issuer;", + "var validity = properties.validity;", + "var esv = properties.signingkey;", + "", + "var signingkey = systemEnv.getProperty(esv);", + "", + "var username = nodeState.get("username");", + "", + "var data = {", + " jwtType:"SIGNED",", + " jwsAlgorithm: "HS256",", + " issuer: iss,", + " subject: username,", + " audience: aud,", + " type: "JWT",", + " validityMinutes: validity,", + " signingKey: signingkey", + "};", + "", + "var jwt = jwtAssertion.generateJwt(data);", + "", + "if (jwt !== null && jwt.length > 0) {", + " nodeState.putShared("assertionJwt" , jwt);", + " action.goTo("True");", + "} else {", + " action.goTo("False");", + "}", + "", + ], + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1859562163", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "705045404", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": undefined, "scripttype": undefined, "secret": { @@ -361955,6 +368969,1012 @@ a { }, }, }, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "-1749152606", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "957146401", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "309311416", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "855360523", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " MULTIPLY: "MULTIPLY",", + " DIVIDE: "DIVIDE"", + "}", + "", + "function main() {", + " var a = Number(properties.a);", + " var b = Number(properties.b);", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("z", a + b);", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("z", a - b);", + " break;", + " case OPERATORS.MULTIPLY:", + " nodeState.putShared("z", a * b);", + " break;", + " case OPERATORS.DIVIDE:", + " if (b == 0) throw new Error("Cannot divide by 0");", + " nodeState.putShared("z", a / b);", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "-2070743967", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": [ + "var aud = properties.audience;", + "var iss = properties.issuer;", + "var validity = properties.validity;", + "var esv = properties.signingkey;", + "", + "var signingkey = systemEnv.getProperty(esv);", + "", + "var username = nodeState.get("username");", + "", + "var data = {", + " jwtType:"SIGNED",", + " jwsAlgorithm: "HS256",", + " issuer: iss,", + " subject: username,", + " audience: aud,", + " type: "JWT",", + " validityMinutes: validity,", + " signingKey: signingkey", + "};", + "", + "var jwt = jwtAssertion.generateJwt(data);", + "", + "if (jwt !== null && jwt.length > 0) {", + " nodeState.putShared("assertionJwt" , jwt);", + " action.goTo("True");", + "} else {", + " action.goTo("False");", + "}", + "", + ], + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "1859562163", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "705045404", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, "realm": { "L2FscGhh": { "_id": "L2FscGhh", diff --git a/src/test/snapshots/ops/JourneyOps.test.js.snap b/src/test/snapshots/ops/JourneyOps.test.js.snap index 0532be6dc..0e70a98e6 100644 --- a/src/test/snapshots/ops/JourneyOps.test.js.snap +++ b/src/test/snapshots/ops/JourneyOps.test.js.snap @@ -2979,6 +2979,1030 @@ a{ } `; +exports[`JourneyOps exportJourney() 4: Export journey 'FrodoTestJourney12' w/ custom node dependencies 1`] = ` +{ + "circlesOfTrust": {}, + "emailTemplates": {}, + "innerNodes": { + "03416cc6-588b-409a-919f-038bb8194c81": { + "_id": "03416cc6-588b-409a-919f-038bb8194c81", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "-191831406", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "TEXT_OUTPUT_CALLBACK", + "options": { + "message": "WARNING: You must enter your username and password to continue!", + "messageType": "1", + }, + }, + "0a3d5de0-9426-4a9a-aae0-163eda075d43": { + "_id": "0a3d5de0-9426-4a9a-aae0-163eda075d43", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "4824664", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "SCRIPT_TEXT_OUTPUT_CALLBACK", + "options": { + "message": "console.log("hello console!");", + }, + "sharedProperty": "out", + }, + "18edd91b-5e15-49df-b3c3-764114a8ebb3": { + "_id": "18edd91b-5e15-49df-b3c3-764114a8ebb3", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "975185327", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "HIDDEN_VALUE_CALLBACK", + "options": { + "id": "myId", + "value": "I am hidden", + }, + "sharedProperty": "hidden", + }, + "1a002d5d-5ad5-4d0e-965f-a0f26278d08d": { + "_id": "1a002d5d-5ad5-4d0e-965f-a0f26278d08d", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "-605795289", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "NAME_CALLBACK", + "objectSharedProperty": "userName", + "options": { + "prompt": "Enter Your Username", + }, + "sharedProperty": "username", + }, + "65c2a8cd-e623-4c5d-b420-e55fc5105f43": { + "_id": "65c2a8cd-e623-4c5d-b420-e55fc5105f43", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "-1753807887", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "PASSWORD_CALLBACK", + "objectTransientProperty": "password", + "options": { + "prompt": "Enter Your Password", + }, + "transientProperty": "password", + }, + "d8bd62e2-a4e7-4e08-bb28-10570aa31fcf": { + "_id": "d8bd62e2-a4e7-4e08-bb28-10570aa31fcf", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "-1308099819", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK", + "objectSharedProperty": "frUnindexedString1", + "options": { + "name": "frUnindexedString1", + "prompt": "Are you old?", + "required": "true", + }, + "sharedProperty": "isOld", + }, + "eaf91b8a-bb71-4037-97ec-cd2e54885668": { + "_id": "eaf91b8a-bb71-4037-97ec-cd2e54885668", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "2022883295", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "NUMBER_ATTRIBUTE_INPUT_CALLBACK", + "objectSharedProperty": "frUnindexedInteger1", + "options": { + "name": "frUnindexedInteger1", + "prompt": "Enter Your Age", + "required": "true", + }, + "sharedProperty": "age", + }, + "ee549716-666c-4b9d-baab-defe1a93eb6c": { + "_id": "ee549716-666c-4b9d-baab-defe1a93eb6c", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "146018854", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "STRING_ATTRIBUTE_INPUT_CALLBACK", + "objectSharedProperty": "mail", + "options": { + "name": "mail", + "prompt": "Enter Your Email", + "required": "true", + }, + "sharedProperty": "email", + }, + "f9155861-f7c8-4022-9bed-e4ef5b238824": { + "_id": "f9155861-f7c8-4022-9bed-e4ef5b238824", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "-1687279556", + "_type": { + "_id": "designer-ef81b1a52c914710b3388caebfe7233a", + "collection": true, + "name": "Display Callback", + "version": "1.0", + }, + "callback": "TERMS_AND_CONDITIONS_CALLBACK", + "options": { + "createDate": "2025-11-12T22:30:59.417Z", + "terms": "This is the way", + "version": "6.7", + }, + "sharedProperty": "accepted", + }, + }, + "meta": Any, + "nodeTypes": { + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "-1739635001", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "1175982017", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, + "nodes": { + "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97": { + "_id": "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97", + "_outcomes": [ + { + "displayName": "outcome", + "id": "outcome", + }, + ], + "_rev": "2033345625", + "_type": { + "_id": "PageNode", + "collection": true, + "name": "Page Node", + "version": "1.0", + }, + "nodes": [ + { + "_id": "03416cc6-588b-409a-919f-038bb8194c81", + "displayName": "Welcome", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "1a002d5d-5ad5-4d0e-965f-a0f26278d08d", + "displayName": "Username", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "65c2a8cd-e623-4c5d-b420-e55fc5105f43", + "displayName": "Password", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "ee549716-666c-4b9d-baab-defe1a93eb6c", + "displayName": "Email", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "eaf91b8a-bb71-4037-97ec-cd2e54885668", + "displayName": "Age", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "d8bd62e2-a4e7-4e08-bb28-10570aa31fcf", + "displayName": "Is old", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "18edd91b-5e15-49df-b3c3-764114a8ebb3", + "displayName": "Hidden", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "0a3d5de0-9426-4a9a-aae0-163eda075d43", + "displayName": "Script", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + { + "_id": "f9155861-f7c8-4022-9bed-e4ef5b238824", + "displayName": "Terms", + "nodeType": "designer-ef81b1a52c914710b3388caebfe7233a", + }, + ], + "pageDescription": {}, + "pageHeader": {}, + }, + "461a364c-5884-44f6-87d9-ae749cc08f24": { + "_id": "461a364c-5884-44f6-87d9-ae749cc08f24", + "_outcomes": [ + { + "displayName": "True", + "id": "true", + }, + { + "displayName": "False", + "id": "false", + }, + ], + "_rev": "2126257365", + "_type": { + "_id": "DataStoreDecisionNode", + "collection": true, + "name": "Data Store Decision", + "version": "1.0", + }, + }, + "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb": { + "_id": "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb", + "_outcomes": [ + { + "displayName": "True", + "id": "True", + }, + { + "displayName": "False", + "id": "False", + }, + ], + "_rev": "-1617974950", + "_type": { + "_id": "designer-session", + "collection": true, + "name": "Has Session AM", + "version": "1.0", + }, + }, + }, + "saml2Entities": {}, + "scripts": {}, + "socialIdentityProviders": {}, + "themes": [], + "tree": { + "_id": "FrodoTestJourney12", + "_rev": "-268378089", + "description": "Test journey for custom nodes", + "enabled": true, + "entryNodeId": "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb", + "identityResource": "managed/alpha_user", + "innerTreeOnly": false, + "mustRun": false, + "noSession": false, + "nodes": { + "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97": { + "connections": { + "outcome": "461a364c-5884-44f6-87d9-ae749cc08f24", + }, + "displayName": "Login Page", + "nodeType": "PageNode", + "x": 463, + "y": 80, + }, + "461a364c-5884-44f6-87d9-ae749cc08f24": { + "connections": { + "false": "e301438c-0bd0-429c-ab0c-66126501069a", + "true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0", + }, + "displayName": "Data Store Decision", + "nodeType": "DataStoreDecisionNode", + "x": 734, + "y": 161, + }, + "8c4f5d43-d7f8-4ac2-8aae-d38f8f5cb9cb": { + "connections": { + "False": "0fc7e34a-e3b5-4f5d-baea-ffde4ee63a97", + "True": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0", + }, + "displayName": "Has Session AM", + "nodeType": "designer-session", + "x": 210, + "y": 161, + }, + }, + "staticNodes": { + "70e691a5-1e33-4ac3-a356-e7b6d60d92e0": { + "x": 1014, + "y": 102, + }, + "e301438c-0bd0-429c-ab0c-66126501069a": { + "x": 1014, + "y": 241, + }, + "startNode": { + "x": 70, + "y": 188, + }, + }, + "transactionalOnly": false, + "uiConfig": { + "annotations": "{"forNodes":{},"structural":[]}", + "categories": "[]", + }, + }, + "variable": {}, +} +`; + exports[`JourneyOps exportJourneys() 1: Export journeys w/o dependencies 1`] = ` { "meta": Any, diff --git a/src/test/snapshots/ops/NodeOps.test.js.snap b/src/test/snapshots/ops/NodeOps.test.js.snap index 7efcef8a1..dfb2e735a 100644 --- a/src/test/snapshots/ops/NodeOps.test.js.snap +++ b/src/test/snapshots/ops/NodeOps.test.js.snap @@ -1,5 +1,56 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`NodeOps createCustomNodeExportTemplate() 1: Create Custom Node Export Template 1`] = ` +{ + "meta": Any, + "nodeTypes": {}, +} +`; + +exports[`NodeOps createNode() 1: Create new node with id 1`] = ` +{ + "_id": "5227de7a-02db-4f25-858e-c8d4f0e0b600", + "_outcomes": [ + { + "displayName": "Outcome", + "id": "outcome", + }, + ], + "_rev": "1797046015", + "_type": { + "_id": "SetStateNode", + "collection": true, + "name": "Set State", + "version": "1.0", + }, + "attributes": { + "errorMessage": "An error has occurred!", + }, +} +`; + +exports[`NodeOps createNode() 2: Create new node without id 1`] = ` +{ + "_id": "5227de7a-02db-4f25-858e-c8d4f0e0b600", + "_outcomes": [ + { + "displayName": "Outcome", + "id": "outcome", + }, + ], + "_rev": "1797046015", + "_type": { + "_id": "SetStateNode", + "collection": true, + "name": "Set State", + "version": "1.0", + }, + "attributes": { + "errorMessage": "An error has occurred!", + }, +} +`; + exports[`NodeOps createNodeExportTemplate() 1: Create Node Export Template 1`] = ` { "meta": Any, @@ -7,6 +58,1341 @@ exports[`NodeOps createNodeExportTemplate() 1: Create Node Export Template 1`] = } `; +exports[`NodeOps deleteCustomNode() 1: Delete existing custom node by id 1`] = ` +{ + "_id": "a15e2efb3deb4d4ea338c74a6440b69f-1", +} +`; + +exports[`NodeOps deleteCustomNode() 3: Delete existing custom node by name 1`] = ` +{ + "_id": "a15e2efb3deb4d4ea338c74a6440b69f-1", +} +`; + +exports[`NodeOps deleteNode() 1: Delete existing node 1`] = ` +{ + "_id": "23bab9d4-1663-450f-8a4b-680f44f54fd6", + "_outcomes": [ + { + "displayName": "Created", + "id": "CREATED", + }, + { + "displayName": "Failed", + "id": "FAILURE", + }, + ], + "_rev": "1983463508", + "_type": { + "_id": "CreateObjectNode", + "collection": true, + "name": "Create Object", + "version": "1.0", + }, + "identityResource": "managed/user", +} +`; + +exports[`NodeOps exportCustomNode() 1: Export existing custom node by ID 1`] = ` +{ + "meta": Any, + "nodeTypes": { + "a605506774a848f7877b4d17a453bd39-1": { + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "1089949934", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + }, +} +`; + +exports[`NodeOps exportCustomNode() 3: Export existing custom node by name 1`] = ` +{ + "meta": Any, + "nodeTypes": { + "a605506774a848f7877b4d17a453bd39-1": { + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "1086162449", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + }, +} +`; + +exports[`NodeOps exportCustomNodes() 1: Export custom nodes 1`] = ` +{ + "meta": Any, + "nodeTypes": { + "8ab9f1aad4b4460a9c45d15fb148e221-1": { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "1253294564", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + "a15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "a15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "-1807621590", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU - TEST", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "a15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "a605506774a848f7877b4d17a453bd39-1": { + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "1086162449", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "aaaa3fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "aaaa3fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "1177790320", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: "outcome"", + "};", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + " var keySet = nodeState.keys(); // Java Set", + " var keys = Array.from(keySet); // Make it into JavaScript array", + " debugState = {};", + " for (var i in keys) {", + " var k = new String(keys[i]);", + " var item = nodeState.get(k);", + " if (typeof item === "object") {", + " debugState[k] = nodeState.getObject(k);", + " } else {", + " debugState[k] = nodeState.get(k);", + " }", + " }", + " if (properties.displayFormat === "JSON") {", + " callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`);", + " return;", + " }", + " callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`);", + "}", + "", + "main();", + "", + ], + "serviceName": "aaaa3fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "debug", + "testing", + ], + }, + "c15e2efb3deb4d4ea338c74a6440b69f-1": { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "1113564678", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " DOT: "DOT",", + " CROSS: "CROSS"", + "}", + "", + "function add(a, b) {", + " return a.map((v, i) => v + b[i]);", + "}", + "", + "function subtract(a, b) {", + " return a.map((v, i) => v - b[i]);", + "}", + "", + "function dot(a, b) {", + " return a.reduce((sum, v, i) => sum + v * b[i], 0);", + "}", + "", + "function cross(a, b) {", + " return [", + " a[1] * b[2] - a[2] * b[1],", + " a[2] * b[0] - a[0] * b[2],", + " a[0] * b[1] - a[1] * b[0]", + " ];", + "}", + "", + "function main() {", + " if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension.");", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("c", add(properties.a, properties.b));", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("c", subtract(properties.a, properties.b));", + " break;", + " case OPERATORS.DOT:", + " nodeState.putShared("c", dot(properties.a, properties.b));", + " break;", + " case OPERATORS.CROSS:", + " if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product");", + " nodeState.putShared("c", cross(properties.a, properties.b));", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + "c605506774a848f7877b4d17a453bd39-1": { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "-1941250080", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + "c6063fb2f5dc42dd9772bedc93898bd8-1": { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "594973911", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " SUCCESS: 'Success'", + "};", + "", + "var OPERATORS = {", + " ADD: "ADD",", + " SUBTRACT: "SUBTRACT",", + " MULTIPLY: "MULTIPLY",", + " DIVIDE: "DIVIDE"", + "}", + "", + "function main() {", + " var a = Number(properties.a);", + " var b = Number(properties.b);", + " switch (properties.operator) {", + " case OPERATORS.ADD:", + " nodeState.putShared("z", a + b);", + " break;", + " case OPERATORS.SUBTRACT:", + " nodeState.putShared("z", a - b);", + " break;", + " case OPERATORS.MULTIPLY:", + " nodeState.putShared("z", a * b);", + " break;", + " case OPERATORS.DIVIDE:", + " if (b == 0) throw new Error("Cannot divide by 0");", + " nodeState.putShared("z", a / b);", + " break;", + " default: throw new Error("Unknown operator.");", + " }", + " action.goTo(SCRIPT_OUTCOMES.SUCCESS);", + "}", + "", + "main();", + "", + ], + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + "e5ad0110c8ee4dafaae983003cd05d4a-1": { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "1554001423", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": [ + "var aud = properties.audience;", + "var iss = properties.issuer;", + "var validity = properties.validity;", + "var esv = properties.signingkey;", + "", + "var signingkey = systemEnv.getProperty(esv);", + "", + "var username = nodeState.get("username");", + "", + "var data = {", + " jwtType:"SIGNED",", + " jwsAlgorithm: "HS256",", + " issuer: iss,", + " subject: username,", + " audience: aud,", + " type: "JWT",", + " validityMinutes: validity,", + " signingKey: signingkey", + "};", + "", + "var jwt = jwtAssertion.generateJwt(data);", + "", + "if (jwt !== null && jwt.length > 0) {", + " nodeState.putShared("assertionJwt" , jwt);", + " action.goTo("True");", + "} else {", + " action.goTo("False");", + "}", + ], + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, + "ef81b1a52c914710b3388caebfe7233a-1": { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "-628951673", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": [ + "var SCRIPT_OUTCOMES = {", + " OUTCOME: 'outcome'", + "};", + "", + "var CALLBACKS = {", + " BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK",", + " CHOICE_CALLBACK: "CHOICE_CALLBACK",", + " CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK",", + " CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK",", + " DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK",", + " HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK",", + " HTTP_CALLBACK: "HTTP_CALLBACK",", + " IDP_CALLBACK: "IDP_CALLBACK",", + " KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK",", + " LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK",", + " METADATA_CALLBACK: "METADATA_CALLBACK",", + " NAME_CALLBACK: "NAME_CALLBACK",", + " NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK",", + " PASSWORD_CALLBACK: "PASSWORD_CALLBACK",", + " POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK",", + " REDIRECT_CALLBACK: "REDIRECT_CALLBACK",", + " SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK",", + " SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK",", + " STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK",", + " SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK",", + " TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK",", + " TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK",", + " TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK",", + " VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK",", + " VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK",", + " X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK"", + "}", + "", + "function isStringPresent(value) {", + " return value;", + "}", + "", + "function getString(value) {", + " return value || '';", + "}", + "", + "function isArrayPresent(value) {", + " return value;", + "}", + "", + "function getArray(value) {", + " return value ? JSON.parse(value) : [];", + "}", + "", + "function isObjectPresent(value) {", + " return value;", + "}", + "", + "function getObject(value) {", + " return value ? JSON.parse(value) : {};", + "}", + "", + "function isIntPresent(value) {", + " return value;", + "}", + "", + "function getInt(value) {", + " return value ? parseInt(value) : 0;", + "}", + "", + "function isDoublePresent(value) {", + " return value;", + "}", + "", + "function getDouble(value) {", + " return value ? parseFloat(value) : 0.0;", + "}", + "", + "function isBooleanPresent(value) {", + " return value;", + "}", + "", + "function getBoolean(value) {", + " return value ? value.toLowerCase() === 'true' : false;", + "}", + "", + "function setProperty(value) {", + " if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value);", + " if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value);", + " if (properties.objectSharedProperty) {", + " var attributes = {};", + " attributes[properties.objectSharedProperty] = value;", + " nodeState.mergeShared({", + " objectAttributes: attributes", + " });", + " }", + " if (properties.objectTransientProperty) {", + " var attributes = {};", + " attributes[properties.objectTransientProperty] = value;", + " nodeState.mergeTransient({", + " objectAttributes: attributes", + " });", + " }", + "}", + "", + "function booleanAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getBoolean(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function choiceCallback() {", + " var prompt = getString(properties.options.prompt);", + " var choices = getArray(properties.options.choices);", + " var defaultChoice = getInt(properties.options.defaultChoice);", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed);", + "}", + "", + "function confirmationCallback() {", + " var prompt = getString(properties.options.prompt);", + " var messageType = getInt(properties.options.messageType);", + " var options = getArray(properties.options.options);", + " var optionType = getInt(properties.options.optionType);", + " var defaultOption = getInt(properties.options.defaultOption);", + " if (isStringPresent(properties.options.prompt)) {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption);", + " }", + " } else {", + " if (isIntPresent(properties.options.optionType)) {", + " callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption);", + " } else {", + " callbacksBuilder.confirmationCallback(messageType, options, defaultOption);", + " }", + " }", + "}", + "", + "function consentMappingCallback() {", + " var config = getObject(properties.options.config);", + " var message = getString(properties.options.message);", + " var isRequired = getBoolean(properties.options.isRequired);", + " var name = getString(properties.options.name);", + " var displayName = getString(properties.options.displayName);", + " var icon = getString(properties.options.icon);", + " var accessLevel = getString(properties.options.accessLevel);", + " var titles = getArray(properties.options.titles);", + " if (isObjectPresent(properties.options.prompt)) {", + " callbacksBuilder.consentMappingCallback(config, message, isRequired);", + " } else {", + " callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired);", + " }", + "}", + "", + "function deviceProfileCallback() {", + " var metadata = getBoolean(properties.options.metadata);", + " var location = getBoolean(properties.options.location);", + " var message = getString(properties.options.message);", + " callbacksBuilder.deviceProfileCallback(metadata, location, message);", + "}", + "", + "function hiddenValueCallback() {", + " var id = getString(properties.options.id);", + " var value = getString(properties.options.value);", + " callbacksBuilder.hiddenValueCallback(id, value);", + "}", + "", + "function httpCallback() {", + " var authorizationHeader = getString(properties.options.authorizationHeader);", + " var negotiationHeader = getString(properties.options.negotiationHeader);", + " var authRHeader = getString(properties.options.authRHeader);", + " var negoName = getString(properties.options.negoName);", + " var negoValue = getString(properties.options.negoValue);", + " if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) {", + " var errorCode = getString(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode);", + " } else {", + " var errorCode = getInt(properties.options.errorCode);", + " callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode);", + " }", + "}", + "", + "function idPCallback() {", + " var provider = getString(properties.options.provider);", + " var clientId = getString(properties.options.clientId);", + " var redirectUri = getString(properties.options.redirectUri);", + " var scope = getArray(properties.options.scope);", + " var nonce = getString(properties.options.nonce);", + " var request = getString(properties.options.request);", + " var requestUri = getString(properties.options.requestUri);", + " var acrValues = getArray(properties.options.acrValues);", + " var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo);", + " var token = getString(properties.options.token);", + " var tokenType = getString(properties.options.tokenType);", + " if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType);", + " } else {", + " callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo);", + " }", + "}", + "", + "function kbaCreateCallback() {", + " var prompt = getString(properties.options.prompt);", + " var predefinedQuestions = getArray(properties.options.predefinedQuestions);", + " var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions);", + " callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions);", + "}", + "", + "function languageCallback() {", + " var language = getString(properties.options.language);", + " var country = getString(properties.options.country);", + " callbacksBuilder.languageCallback(language, country);", + "}", + "", + "function metadataCallback() {", + " var outputValue = getObject(properties.options.outputValue);", + " callbacksBuilder.metadataCallback(outputValue);", + "}", + "", + "function nameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultName = getString(properties.options.defaultName);", + " if (isStringPresent(properties.options.defaultName)) {", + " callbacksBuilder.nameCallback(prompt, defaultName);", + " } else {", + " callbacksBuilder.nameCallback(prompt);", + " }", + "}", + "", + "function numberAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getDouble(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function passwordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " callbacksBuilder.passwordCallback(prompt, echoOn);", + "}", + "", + "function pollingWaitCallback() {", + " var waitTime = getString(properties.options.waitTime);", + " var message = getString(properties.options.message);", + " callbacksBuilder.pollingWaitCallback(waitTime, message);", + "}", + "", + "function redirectCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function scriptTextOutputCallback() {", + " var message = getString(properties.options.message);", + " callbacksBuilder.scriptTextOutputCallback(message);", + "}", + "", + "function selectIdPCallback() {", + " var providers = getObject(properties.options.providers);", + " callbacksBuilder.selectIdPCallback(providers);", + "}", + "", + "function stringAttributeInputCallback() {", + " var name = getString(properties.options.name);", + " var prompt = getString(properties.options.prompt);", + " var value = getString(properties.options.value);", + " var required = getBoolean(properties.options.required);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) {", + " if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly);", + " }", + " } else if (isArrayPresent(failedPolicies)) {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies);", + " } else {", + " callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required);", + " }", + "}", + "", + "function suspendedTextOutputCallback() {", + " var messageType = getInt(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.suspendedTextOutputCallback(messageType, message);", + "}", + "", + "function termsAndConditionsCallback() {", + " var version = getString(properties.options.version);", + " var terms = getString(properties.options.terms);", + " var createDate = getString(properties.options.createDate);", + " callbacksBuilder.termsAndConditionsCallback(version, terms, createDate);", + "}", + "", + "function textInputCallback() {", + " var prompt = getString(properties.options.prompt);", + " var defaultText = getString(properties.options.defaultText);", + " if (isStringPresent(properties.options.defaultText)) {", + " callbacksBuilder.textInputCallback(prompt, defaultText);", + " } else {", + " callbacksBuilder.textInputCallback(prompt);", + " }", + "}", + "", + "function textOutputCallback() {", + " var messageType = getString(properties.options.messageType);", + " var message = getString(properties.options.message);", + " callbacksBuilder.textOutputCallback(messageType, message);", + "}", + "", + "function validatedPasswordCallback() {", + " var prompt = getString(properties.options.prompt);", + " var echoOn = getBoolean(properties.options.echoOn);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly);", + " }", + "}", + "", + "function validatedUsernameCallback() {", + " var prompt = getString(properties.options.prompt);", + " var policies = getObject(properties.options.policies);", + " var validateOnly = getBoolean(properties.options.validateOnly);", + " var failedPolicies = getArray(properties.options.failedPolicies);", + " if (isArrayPresent(properties.options.failedPolicies)) {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies);", + " } else {", + " callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly);", + " }", + "}", + "", + "function x509CertificateCallback() {", + " throw new Error('Not Implemented');", + "}", + "", + "function getBooleanAttributeInputCallback() {", + " setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0));", + "}", + "", + "function getChoiceCallback() {", + " var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed);", + " var selections = callbacks.getChoiceCallbacks().get(0);", + " setProperty(multipleSelectionsAllowed ? selections : selections[0]);", + "}", + "", + "function getConfirmationCallback() {", + " setProperty(callbacks.getConfirmationCallbacks().get(0));", + "}", + "", + "function getConsentMappingCallback() {", + " setProperty(callbacks.getConsentMappingCallbacks().get(0));", + "}", + "", + "function getDeviceProfileCallback() {", + " setProperty(callbacks.getDeviceProfileCallbacks().get(0));", + "}", + "", + "function getHiddenValueCallback() {", + " var id = getString(properties.options.id);", + " setProperty(callbacks.getHiddenValueCallbacks().get(id));", + "}", + "", + "function getHttpCallback() {", + " setProperty(callbacks.getHttpCallbacks().get(0));", + "}", + "", + "function getIdPCallback() {", + " setProperty(callbacks.getIdpCallbacks().get(0));", + "}", + "", + "function getKbaCreateCallback() {", + " setProperty(callbacks.getKbaCreateCallbacks().get(0));", + "}", + "", + "function getLanguageCallback() {", + " setProperty(callbacks.getLanguageCallbacks().get(0));", + "}", + "", + "function getNameCallback() {", + " setProperty(callbacks.getNameCallbacks().get(0));", + "}", + "", + "function getNumberAttributeInputCallback() {", + " setProperty(callbacks.getNumberAttributeInputCallbacks().get(0));", + "}", + "", + "function getPasswordCallback() {", + " setProperty(callbacks.getPasswordCallbacks().get(0));", + "}", + "", + "function getSelectIdPCallback() {", + " setProperty(callbacks.getSelectIdPCallbacks().get(0));", + "}", + "", + "function getStringAttributeInputCallback() {", + " setProperty(callbacks.getStringAttributeInputCallbacks().get(0));", + "}", + "", + "function getTermsAndConditionsCallback() {", + " setProperty(callbacks.getTermsAndConditionsCallbacks().get(0));", + "}", + "", + "function getTextInputCallback() {", + " setProperty(callbacks.getTextInputCallbacks().get(0));", + "}", + "", + "function getValidatedPasswordCallback() {", + " setProperty(callbacks.getValidatedPasswordCallbacks().get(0));", + "}", + "", + "function getValidatedUsernameCallback() {", + " setProperty(callbacks.getValidatedUsernameCallbacks().get(0));", + "}", + "", + "function getX509CertificateCallback() {", + " setProperty(callbacks.getX509CertificateCallbacks().get(0));", + "}", + "", + "function main() {", + " if (!callbacks.isEmpty()) {", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: getNameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break;", + " default: break;", + " }", + " action.goTo(SCRIPT_OUTCOMES.OUTCOME);", + " return;", + " }", + "", + " switch (properties.callback) {", + " case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break;", + " case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break;", + " case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break;", + " case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break;", + " case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break;", + " case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break;", + " case CALLBACKS.HTTP_CALLBACK: httpCallback(); break;", + " case CALLBACKS.IDP_CALLBACK: idPCallback(); break;", + " case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break;", + " case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break;", + " case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break;", + " case CALLBACKS.NAME_CALLBACK: nameCallback(); break;", + " case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break;", + " case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break;", + " case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break;", + " case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break;", + " case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break;", + " case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break;", + " case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break;", + " case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break;", + " case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break;", + " case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break;", + " case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break;", + " case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break;", + " case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break;", + " case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break;", + " default: throw new Error('Unknown Callback'); // Should never reach this case", + " }", + "}", + "", + "main();", + "", + ], + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + "session-1": { + "_id": "session-1", + "_rev": "490056204", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": [ + "var SCRIPT_OUTCOMES = {", + " TRUE: 'True',", + " FALSE: 'False'", + "}", + "", + "function main() {", + " action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE);", + "}", + "", + "main();", + "", + ], + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + }, +} +`; + exports[`NodeOps exportNodes() 1: Export nodes 1`] = ` { "meta": Any, @@ -3059,6 +4445,8 @@ exports[`NodeOps exportNodes() 1: Export nodes 1`] = ` } `; +exports[`NodeOps getCustomNodeUsage() 1: Get custom node usage [a605506774a848f7877b4d17a453bd39-1] 1`] = `{}`; + exports[`NodeOps getNodeClassification() 1: Classification of "PageNode" is "standard" 1`] = ` [ "standard", @@ -3160,6 +4548,417 @@ exports[`NodeOps getNodeClassification() 16: Classification of "CustomNode" is " ] `; +exports[`NodeOps importCustomNodes() 1: Import None 1`] = `[]`; + +exports[`NodeOps importCustomNodes() 2: Import by ID 1`] = ` +[ + { + "_id": "a6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "-121767584", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU - TEST", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "a6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, +] +`; + +exports[`NodeOps importCustomNodes() 3: Import by Name 1`] = ` +[ + { + "_id": "a6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "-756969277", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU - TEST", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "a6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, +] +`; + +exports[`NodeOps importCustomNodes() 4: Import all 1`] = ` +[ + { + "_id": "aaaa3fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "984835321", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "aaaa3fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "debug", + "testing", + ], + }, + { + "_id": "a6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "-1723210064", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU - TEST", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "a6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + { + "_id": "a15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "-623333120", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU - TEST", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + DOT: "DOT", + CROSS: "CROSS" +} + +function add(a, b) { + return a.map((v, i) => v + b[i]); +} + +function subtract(a, b) { + return a.map((v, i) => v - b[i]); +} + +function dot(a, b) { + return a.reduce((sum, v, i) => sum + v * b[i], 0); +} + +function cross(a, b) { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ]; +} + +function main() { + if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension."); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("c", add(properties.a, properties.b)); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("c", subtract(properties.a, properties.b)); + break; + case OPERATORS.DOT: + nodeState.putShared("c", dot(properties.a, properties.b)); + break; + case OPERATORS.CROSS: + if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product"); + nodeState.putShared("c", cross(properties.a, properties.b)); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "a15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, +] +`; + exports[`NodeOps isCloudExcludedNode() 1: LdapDecisionNode is not a cloud-excluded node 1`] = `false`; exports[`NodeOps isCloudExcludedNode() 2: CreatePasswordNode is a cloud-excluded node 1`] = `true`; @@ -3206,6 +5005,1297 @@ exports[`NodeOps isPremiumNode() 3: AutonomousAccessResultNode is a premium node exports[`NodeOps isPremiumNode() 4: AutonomousAccessSignalNode is a premium node 1`] = `true`; +exports[`NodeOps readCustomNode() 1: Read existing custom node by ID 1`] = ` +{ + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "1354478386", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], +} +`; + +exports[`NodeOps readCustomNode() 3: Read existing custom node by name 1`] = ` +{ + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "1086162449", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], +} +`; + +exports[`NodeOps readCustomNodes() 1: Read custom nodes 1`] = ` +[ + { + "_id": "c6063fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "594973911", + "description": "Simple ALU that performs basic binary math operations. Expects an "x" and "y" value on the shared state, and will produce a new "z" value on the shared state as output.", + "displayName": "ALU", + "errorOutcome": true, + "inputs": [ + "x", + "y", + ], + "outcomes": [ + "Success", + ], + "outputs": [ + "z", + ], + "properties": { + "operator": { + "defaultValue": "ADD", + "description": "The operation to perform.", + "multivalued": false, + "options": { + "ADD": "+", + "DIVIDE": "/", + "MULTIPLY": "*", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + MULTIPLY: "MULTIPLY", + DIVIDE: "DIVIDE" +} + +function main() { + var a = Number(properties.a); + var b = Number(properties.b); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("z", a + b); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("z", a - b); + break; + case OPERATORS.MULTIPLY: + nodeState.putShared("z", a * b); + break; + case OPERATORS.DIVIDE: + if (b == 0) throw new Error("Cannot divide by 0"); + nodeState.putShared("z", a / b); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c6063fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "math", + "utilities", + ], + }, + { + "_id": "aaaa3fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "1177790320", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "aaaa3fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "debug", + "testing", + ], + }, + { + "_id": "ef81b1a52c914710b3388caebfe7233a-1", + "_rev": "-628951673", + "description": "Displays custom callback to the page", + "displayName": "Display Callback", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "callback": { + "description": "The callback to display", + "multivalued": false, + "options": { + "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK": "booleanAttributeInputCallback", + "CHOICE_CALLBACK": "choiceCallback", + "CONFIRMATION_CALLBACK": "confirmationCallback", + "CONSENT_MAPPING_CALLBACK": "consentMappingCallback", + "DEVICE_PROFILE_CALLBACK": "deviceProfileCallback", + "HIDDEN_VALUE_CALLBACK": "hiddenValueCallback", + "HTTP_CALLBACK": "httpCallback", + "IDP_CALLBACK": "idPCallback", + "KBA_CREATE_CALLBACK": "kbaCreateCallback", + "LANGUAGE_CALLBACK": "languageCallback", + "METADATA_CALLBACK": "metadataCallback", + "NAME_CALLBACK": "nameCallback", + "NUMBER_ATTRIBUTE_INPUT_CALLBACK": "numberAttributeInputCallback", + "PASSWORD_CALLBACK": "passwordCallback", + "POLLING_WAIT_CALLBACK": "pollingWaitCallback", + "REDIRECT_CALLBACK": "redirectCallback", + "SCRIPT_TEXT_OUTPUT_CALLBACK": "scriptTextOutputCallback", + "SELECT_IDP_CALLBACK": "selectIdPCallback", + "STRING_ATTRIBUTE_INPUT_CALLBACK": "stringAttributeInputCallback", + "SUSPENDED_TEXT_OUTPUT_CALLBACK": "suspendedTextOutputCallback", + "TERMS_AND_CONDITIONS_CALLBACK": "termsAndConditionsCallback", + "TEXT_INPUT_CALLBACK": "textInputCallback", + "TEXT_OUTPUT_CALLBACK": "textOutputCallback", + "VALIDATED_PASSWORD_CALLBACK": "validatedPasswordCallback", + "VALIDATED_USERNAME_CALLBACK": "validatedUsernameCallback", + "X509_CERTIFICATE_CALLBACK": "x509CertificateCallback", + }, + "required": true, + "title": "Callback", + "type": "STRING", + }, + "objectSharedProperty": { + "description": "The objectAttributes property on the shared state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Shared Property", + "type": "STRING", + }, + "objectTransientProperty": { + "description": "The objectAttributes property on the transient state to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Object Attributes Transient Property", + "type": "STRING", + }, + "options": { + "description": "The options containing the parameters for the callback (see documentation for possible parameters: https://docs.pingidentity.com/pingoneaic/latest/am-scripting/scripting-api-node.html#scripting-api-node-callbacks). + +For example, for textOutputCallback, the options could be: { messageType: 0, message: "Hello World!" }. + +Note that for required parameters that are not specified in the options will use default values based on the type of the parameter ("" for Strings, [] for Arrays, {} for Objects, 0 for Ints, 0.0 for Doubles, and false for Booleans).", + "multivalued": false, + "required": true, + "title": "Options", + "type": "OBJECT", + }, + "sharedProperty": { + "description": "The shared state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Shared State Property", + "type": "STRING", + }, + "transientProperty": { + "description": "The transient state property to put the callback input into (if applicable)", + "multivalued": false, + "required": false, + "title": "Transient State Property", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: 'outcome' +}; + +var CALLBACKS = { + BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: "BOOLEAN_ATTRIBUTE_INPUT_CALLBACK", + CHOICE_CALLBACK: "CHOICE_CALLBACK", + CONFIRMATION_CALLBACK: "CONFIRMATION_CALLBACK", + CONSENT_MAPPING_CALLBACK: "CONSENT_MAPPING_CALLBACK", + DEVICE_PROFILE_CALLBACK: "DEVICE_PROFILE_CALLBACK", + HIDDEN_VALUE_CALLBACK: "HIDDEN_VALUE_CALLBACK", + HTTP_CALLBACK: "HTTP_CALLBACK", + IDP_CALLBACK: "IDP_CALLBACK", + KBA_CREATE_CALLBACK: "KBA_CREATE_CALLBACK", + LANGUAGE_CALLBACK: "LANGUAGE_CALLBACK", + METADATA_CALLBACK: "METADATA_CALLBACK", + NAME_CALLBACK: "NAME_CALLBACK", + NUMBER_ATTRIBUTE_INPUT_CALLBACK: "NUMBER_ATTRIBUTE_INPUT_CALLBACK", + PASSWORD_CALLBACK: "PASSWORD_CALLBACK", + POLLING_WAIT_CALLBACK: "POLLING_WAIT_CALLBACK", + REDIRECT_CALLBACK: "REDIRECT_CALLBACK", + SCRIPT_TEXT_OUTPUT_CALLBACK: "SCRIPT_TEXT_OUTPUT_CALLBACK", + SELECT_IDP_CALLBACK: "SELECT_IDP_CALLBACK", + STRING_ATTRIBUTE_INPUT_CALLBACK: "STRING_ATTRIBUTE_INPUT_CALLBACK", + SUSPENDED_TEXT_OUTPUT_CALLBACK: "SUSPENDED_TEXT_OUTPUT_CALLBACK", + TERMS_AND_CONDITIONS_CALLBACK: "TERMS_AND_CONDITIONS_CALLBACK", + TEXT_INPUT_CALLBACK: "TEXT_INPUT_CALLBACK", + TEXT_OUTPUT_CALLBACK: "TEXT_OUTPUT_CALLBACK", + VALIDATED_PASSWORD_CALLBACK: "VALIDATED_PASSWORD_CALLBACK", + VALIDATED_USERNAME_CALLBACK: "VALIDATED_USERNAME_CALLBACK", + X509_CERTIFICATE_CALLBACK: "X509_CERTIFICATE_CALLBACK" +} + +function isStringPresent(value) { + return value; +} + +function getString(value) { + return value || ''; +} + +function isArrayPresent(value) { + return value; +} + +function getArray(value) { + return value ? JSON.parse(value) : []; +} + +function isObjectPresent(value) { + return value; +} + +function getObject(value) { + return value ? JSON.parse(value) : {}; +} + +function isIntPresent(value) { + return value; +} + +function getInt(value) { + return value ? parseInt(value) : 0; +} + +function isDoublePresent(value) { + return value; +} + +function getDouble(value) { + return value ? parseFloat(value) : 0.0; +} + +function isBooleanPresent(value) { + return value; +} + +function getBoolean(value) { + return value ? value.toLowerCase() === 'true' : false; +} + +function setProperty(value) { + if (properties.sharedProperty) nodeState.putShared(properties.sharedProperty, value); + if (properties.transientProperty) nodeState.putTransient(properties.transientProperty, value); + if (properties.objectSharedProperty) { + var attributes = {}; + attributes[properties.objectSharedProperty] = value; + nodeState.mergeShared({ + objectAttributes: attributes + }); + } + if (properties.objectTransientProperty) { + var attributes = {}; + attributes[properties.objectTransientProperty] = value; + nodeState.mergeTransient({ + objectAttributes: attributes + }); + } +} + +function booleanAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getBoolean(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.booleanAttributeInputCallback(name, prompt, value, required); + } +} + +function choiceCallback() { + var prompt = getString(properties.options.prompt); + var choices = getArray(properties.options.choices); + var defaultChoice = getInt(properties.options.defaultChoice); + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + callbacksBuilder.choiceCallback(prompt, choices, defaultChoice, multipleSelectionsAllowed); +} + +function confirmationCallback() { + var prompt = getString(properties.options.prompt); + var messageType = getInt(properties.options.messageType); + var options = getArray(properties.options.options); + var optionType = getInt(properties.options.optionType); + var defaultOption = getInt(properties.options.defaultOption); + if (isStringPresent(properties.options.prompt)) { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(prompt, messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(prompt, messageType, options, defaultOption); + } + } else { + if (isIntPresent(properties.options.optionType)) { + callbacksBuilder.confirmationCallback(messageType, optionType, defaultOption); + } else { + callbacksBuilder.confirmationCallback(messageType, options, defaultOption); + } + } +} + +function consentMappingCallback() { + var config = getObject(properties.options.config); + var message = getString(properties.options.message); + var isRequired = getBoolean(properties.options.isRequired); + var name = getString(properties.options.name); + var displayName = getString(properties.options.displayName); + var icon = getString(properties.options.icon); + var accessLevel = getString(properties.options.accessLevel); + var titles = getArray(properties.options.titles); + if (isObjectPresent(properties.options.prompt)) { + callbacksBuilder.consentMappingCallback(config, message, isRequired); + } else { + callbacksBuilder.consentMappingCallback(name, displayName, icon, accessLevel, titles, message, isRequired); + } +} + +function deviceProfileCallback() { + var metadata = getBoolean(properties.options.metadata); + var location = getBoolean(properties.options.location); + var message = getString(properties.options.message); + callbacksBuilder.deviceProfileCallback(metadata, location, message); +} + +function hiddenValueCallback() { + var id = getString(properties.options.id); + var value = getString(properties.options.value); + callbacksBuilder.hiddenValueCallback(id, value); +} + +function httpCallback() { + var authorizationHeader = getString(properties.options.authorizationHeader); + var negotiationHeader = getString(properties.options.negotiationHeader); + var authRHeader = getString(properties.options.authRHeader); + var negoName = getString(properties.options.negoName); + var negoValue = getString(properties.options.negoValue); + if (isStringPresent(properties.options.authorizationHeader) || isStringPresent(properties.options.negotiationHeader)) { + var errorCode = getString(properties.options.errorCode); + callbacksBuilder.httpCallback(authorizationHeader, negotiationHeader, errorCode); + } else { + var errorCode = getInt(properties.options.errorCode); + callbacksBuilder.httpCallback(authRHeader, negoName, negoValue, errorCode); + } +} + +function idPCallback() { + var provider = getString(properties.options.provider); + var clientId = getString(properties.options.clientId); + var redirectUri = getString(properties.options.redirectUri); + var scope = getArray(properties.options.scope); + var nonce = getString(properties.options.nonce); + var request = getString(properties.options.request); + var requestUri = getString(properties.options.requestUri); + var acrValues = getArray(properties.options.acrValues); + var requestNativeAppForUserInfo = getBoolean(properties.options.requestNativeAppForUserInfo); + var token = getString(properties.options.token); + var tokenType = getString(properties.options.tokenType); + if (isStringPresent(properties.options.token) || isStringPresent(properties.options.tokenType)) { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo, token, tokenType); + } else { + callbacksBuilder.idPCallback(provider, clientId, redirectUri, scope, nonce, request, requestUri, acrValues, requestNativeAppForUserInfo); + } +} + +function kbaCreateCallback() { + var prompt = getString(properties.options.prompt); + var predefinedQuestions = getArray(properties.options.predefinedQuestions); + var allowUserDefinedQuestions = getBoolean(properties.options.allowUserDefinedQuestions); + callbacksBuilder.kbaCreateCallback(prompt, predefinedQuestions, allowUserDefinedQuestions); +} + +function languageCallback() { + var language = getString(properties.options.language); + var country = getString(properties.options.country); + callbacksBuilder.languageCallback(language, country); +} + +function metadataCallback() { + var outputValue = getObject(properties.options.outputValue); + callbacksBuilder.metadataCallback(outputValue); +} + +function nameCallback() { + var prompt = getString(properties.options.prompt); + var defaultName = getString(properties.options.defaultName); + if (isStringPresent(properties.options.defaultName)) { + callbacksBuilder.nameCallback(prompt, defaultName); + } else { + callbacksBuilder.nameCallback(prompt); + } +} + +function numberAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getDouble(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.numberAttributeInputCallback(name, prompt, value, required); + } +} + +function passwordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + callbacksBuilder.passwordCallback(prompt, echoOn); +} + +function pollingWaitCallback() { + var waitTime = getString(properties.options.waitTime); + var message = getString(properties.options.message); + callbacksBuilder.pollingWaitCallback(waitTime, message); +} + +function redirectCallback() { + throw new Error('Not Implemented'); +} + +function scriptTextOutputCallback() { + var message = getString(properties.options.message); + callbacksBuilder.scriptTextOutputCallback(message); +} + +function selectIdPCallback() { + var providers = getObject(properties.options.providers); + callbacksBuilder.selectIdPCallback(providers); +} + +function stringAttributeInputCallback() { + var name = getString(properties.options.name); + var prompt = getString(properties.options.prompt); + var value = getString(properties.options.value); + var required = getBoolean(properties.options.required); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isBooleanPresent(properties.options.validateOnly) || isObjectPresent(properties.options.policies)) { + if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, policies, validateOnly); + } + } else if (isArrayPresent(failedPolicies)) { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required, failedPolicies); + } else { + callbacksBuilder.stringAttributeInputCallback(name, prompt, value, required); + } +} + +function suspendedTextOutputCallback() { + var messageType = getInt(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.suspendedTextOutputCallback(messageType, message); +} + +function termsAndConditionsCallback() { + var version = getString(properties.options.version); + var terms = getString(properties.options.terms); + var createDate = getString(properties.options.createDate); + callbacksBuilder.termsAndConditionsCallback(version, terms, createDate); +} + +function textInputCallback() { + var prompt = getString(properties.options.prompt); + var defaultText = getString(properties.options.defaultText); + if (isStringPresent(properties.options.defaultText)) { + callbacksBuilder.textInputCallback(prompt, defaultText); + } else { + callbacksBuilder.textInputCallback(prompt); + } +} + +function textOutputCallback() { + var messageType = getString(properties.options.messageType); + var message = getString(properties.options.message); + callbacksBuilder.textOutputCallback(messageType, message); +} + +function validatedPasswordCallback() { + var prompt = getString(properties.options.prompt); + var echoOn = getBoolean(properties.options.echoOn); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedPasswordCallback(prompt, echoOn, policies, validateOnly); + } +} + +function validatedUsernameCallback() { + var prompt = getString(properties.options.prompt); + var policies = getObject(properties.options.policies); + var validateOnly = getBoolean(properties.options.validateOnly); + var failedPolicies = getArray(properties.options.failedPolicies); + if (isArrayPresent(properties.options.failedPolicies)) { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly, failedPolicies); + } else { + callbacksBuilder.validatedUsernameCallback(prompt, policies, validateOnly); + } +} + +function x509CertificateCallback() { + throw new Error('Not Implemented'); +} + +function getBooleanAttributeInputCallback() { + setProperty(callbacks.getBooleanAttributeInputCallbacks().get(0)); +} + +function getChoiceCallback() { + var multipleSelectionsAllowed = getBoolean(properties.options.multipleSelectionsAllowed); + var selections = callbacks.getChoiceCallbacks().get(0); + setProperty(multipleSelectionsAllowed ? selections : selections[0]); +} + +function getConfirmationCallback() { + setProperty(callbacks.getConfirmationCallbacks().get(0)); +} + +function getConsentMappingCallback() { + setProperty(callbacks.getConsentMappingCallbacks().get(0)); +} + +function getDeviceProfileCallback() { + setProperty(callbacks.getDeviceProfileCallbacks().get(0)); +} + +function getHiddenValueCallback() { + var id = getString(properties.options.id); + setProperty(callbacks.getHiddenValueCallbacks().get(id)); +} + +function getHttpCallback() { + setProperty(callbacks.getHttpCallbacks().get(0)); +} + +function getIdPCallback() { + setProperty(callbacks.getIdpCallbacks().get(0)); +} + +function getKbaCreateCallback() { + setProperty(callbacks.getKbaCreateCallbacks().get(0)); +} + +function getLanguageCallback() { + setProperty(callbacks.getLanguageCallbacks().get(0)); +} + +function getNameCallback() { + setProperty(callbacks.getNameCallbacks().get(0)); +} + +function getNumberAttributeInputCallback() { + setProperty(callbacks.getNumberAttributeInputCallbacks().get(0)); +} + +function getPasswordCallback() { + setProperty(callbacks.getPasswordCallbacks().get(0)); +} + +function getSelectIdPCallback() { + setProperty(callbacks.getSelectIdPCallbacks().get(0)); +} + +function getStringAttributeInputCallback() { + setProperty(callbacks.getStringAttributeInputCallbacks().get(0)); +} + +function getTermsAndConditionsCallback() { + setProperty(callbacks.getTermsAndConditionsCallbacks().get(0)); +} + +function getTextInputCallback() { + setProperty(callbacks.getTextInputCallbacks().get(0)); +} + +function getValidatedPasswordCallback() { + setProperty(callbacks.getValidatedPasswordCallbacks().get(0)); +} + +function getValidatedUsernameCallback() { + setProperty(callbacks.getValidatedUsernameCallbacks().get(0)); +} + +function getX509CertificateCallback() { + setProperty(callbacks.getX509CertificateCallbacks().get(0)); +} + +function main() { + if (!callbacks.isEmpty()) { + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: getBooleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: getChoiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: getConfirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: getConsentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: getDeviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: getHiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: getHttpCallback(); break; + case CALLBACKS.IDP_CALLBACK: getIdPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: getKbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: getLanguageCallback(); break; + case CALLBACKS.NAME_CALLBACK: getNameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: getNumberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: getPasswordCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: getSelectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: getStringAttributeInputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: getTermsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: getTextInputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: getValidatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: getValidatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: getX509CertificateCallback(); break; + default: break; + } + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + + switch (properties.callback) { + case CALLBACKS.BOOLEAN_ATTRIBUTE_INPUT_CALLBACK: booleanAttributeInputCallback(); break; + case CALLBACKS.CHOICE_CALLBACK: choiceCallback(); break; + case CALLBACKS.CONFIRMATION_CALLBACK: confirmationCallback(); break; + case CALLBACKS.CONSENT_MAPPING_CALLBACK: consentMappingCallback(); break; + case CALLBACKS.DEVICE_PROFILE_CALLBACK: deviceProfileCallback(); break; + case CALLBACKS.HIDDEN_VALUE_CALLBACK: hiddenValueCallback(); break; + case CALLBACKS.HTTP_CALLBACK: httpCallback(); break; + case CALLBACKS.IDP_CALLBACK: idPCallback(); break; + case CALLBACKS.KBA_CREATE_CALLBACK: kbaCreateCallback(); break; + case CALLBACKS.LANGUAGE_CALLBACK: languageCallback(); break; + case CALLBACKS.METADATA_CALLBACK: metadataCallback(); break; + case CALLBACKS.NAME_CALLBACK: nameCallback(); break; + case CALLBACKS.NUMBER_ATTRIBUTE_INPUT_CALLBACK: numberAttributeInputCallback(); break; + case CALLBACKS.PASSWORD_CALLBACK: passwordCallback(); break; + case CALLBACKS.POLLING_WAIT_CALLBACK: pollingWaitCallback(); break; + case CALLBACKS.REDIRECT_CALLBACK: redirectCallback(); break; + case CALLBACKS.SCRIPT_TEXT_OUTPUT_CALLBACK: scriptTextOutputCallback(); break; + case CALLBACKS.SELECT_IDP_CALLBACK: selectIdPCallback(); break; + case CALLBACKS.STRING_ATTRIBUTE_INPUT_CALLBACK: stringAttributeInputCallback(); break; + case CALLBACKS.SUSPENDED_TEXT_OUTPUT_CALLBACK: suspendedTextOutputCallback(); break; + case CALLBACKS.TERMS_AND_CONDITIONS_CALLBACK: termsAndConditionsCallback(); break; + case CALLBACKS.TEXT_INPUT_CALLBACK: textInputCallback(); break; + case CALLBACKS.TEXT_OUTPUT_CALLBACK: textOutputCallback(); break; + case CALLBACKS.VALIDATED_PASSWORD_CALLBACK: validatedPasswordCallback(); break; + case CALLBACKS.VALIDATED_USERNAME_CALLBACK: validatedUsernameCallback(); break; + case CALLBACKS.X509_CERTIFICATE_CALLBACK: x509CertificateCallback(); break; + default: throw new Error('Unknown Callback'); // Should never reach this case + } +} + +main(); +", + "serviceName": "ef81b1a52c914710b3388caebfe7233a", + "tags": [ + "callback", + "utilities", + ], + }, + { + "_id": "8ab9f1aad4b4460a9c45d15fb148e221-1", + "_rev": "1253294564", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "8ab9f1aad4b4460a9c45d15fb148e221", + "tags": [ + "debug", + "testing", + ], + }, + { + "_id": "c15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "1113564678", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + DOT: "DOT", + CROSS: "CROSS" +} + +function add(a, b) { + return a.map((v, i) => v + b[i]); +} + +function subtract(a, b) { + return a.map((v, i) => v - b[i]); +} + +function dot(a, b) { + return a.reduce((sum, v, i) => sum + v * b[i], 0); +} + +function cross(a, b) { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ]; +} + +function main() { + if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension."); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("c", add(properties.a, properties.b)); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("c", subtract(properties.a, properties.b)); + break; + case OPERATORS.DOT: + nodeState.putShared("c", dot(properties.a, properties.b)); + break; + case OPERATORS.CROSS: + if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product"); + nodeState.putShared("c", cross(properties.a, properties.b)); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "c15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + { + "_id": "session-1", + "_rev": "490056204", + "description": "Checks if the user has a current session.", + "displayName": "Has Session AM", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "session", + "tags": [ + "utilities", + ], + }, + { + "_id": "c605506774a848f7877b4d17a453bd39-1", + "_rev": "-1941250080", + "description": "Checks if the user has a current session.", + "displayName": "Has Session", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "c605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + { + "_id": "a15e2efb3deb4d4ea338c74a6440b69f-1", + "_rev": "-1807621590", + "description": "Simple ALU that performs basic binary vector math operations. Outputs the result onto the shared state with key "c".", + "displayName": "Vector ALU - TEST", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "Success", + ], + "outputs": [ + "c", + ], + "properties": { + "a": { + "defaultValue": [ + 1, + 2, + 3, + ], + "description": "Left vector operand", + "multivalued": true, + "required": true, + "title": "A", + "type": "NUMBER", + }, + "b": { + "defaultValue": [ + 4, + 5, + 6, + ], + "description": "Right vector operand", + "multivalued": true, + "required": true, + "title": "B", + "type": "NUMBER", + }, + "operator": { + "defaultValue": "DOT", + "description": "The binary operation to perform on the vectors.", + "multivalued": false, + "options": { + "ADD": "+", + "CROSS": "X", + "DOT": ".", + "SUBTRACT": "-", + }, + "required": true, + "title": "Operator", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + SUCCESS: 'Success' +}; + +var OPERATORS = { + ADD: "ADD", + SUBTRACT: "SUBTRACT", + DOT: "DOT", + CROSS: "CROSS" +} + +function add(a, b) { + return a.map((v, i) => v + b[i]); +} + +function subtract(a, b) { + return a.map((v, i) => v - b[i]); +} + +function dot(a, b) { + return a.reduce((sum, v, i) => sum + v * b[i], 0); +} + +function cross(a, b) { + return [ + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0] + ]; +} + +function main() { + if (properties.a.length !== properties.b.length) throw new Error("Vectors not the same dimension."); + switch (properties.operator) { + case OPERATORS.ADD: + nodeState.putShared("c", add(properties.a, properties.b)); + break; + case OPERATORS.SUBTRACT: + nodeState.putShared("c", subtract(properties.a, properties.b)); + break; + case OPERATORS.DOT: + nodeState.putShared("c", dot(properties.a, properties.b)); + break; + case OPERATORS.CROSS: + if (properties.a.length !== 3) throw new Error("Vectors not dimension 3 for cross product"); + nodeState.putShared("c", cross(properties.a, properties.b)); + break; + default: throw new Error("Unknown operator."); + } + action.goTo(SCRIPT_OUTCOMES.SUCCESS); +} + +main(); +", + "serviceName": "a15e2efb3deb4d4ea338c74a6440b69f", + "tags": [ + "math", + "vector", + "utilities", + ], + }, + { + "_id": "a605506774a848f7877b4d17a453bd39-1", + "_rev": "1086162449", + "description": "Checks if the user has a current session.", + "displayName": "Has Session - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": {}, + "script": "var SCRIPT_OUTCOMES = { + TRUE: 'True', + FALSE: 'False' +} + +function main() { + action.goTo(typeof existingSession === "undefined" ? SCRIPT_OUTCOMES.FALSE : SCRIPT_OUTCOMES.TRUE); +} + +main(); +", + "serviceName": "a605506774a848f7877b4d17a453bd39", + "tags": [ + "utilities", + ], + }, + { + "_id": "e5ad0110c8ee4dafaae983003cd05d4a-1", + "_rev": "1554001423", + "description": "Generate a signed JWT using the HMAC SHA-256 algorithm.", + "displayName": "Generate JWT", + "errorOutcome": true, + "inputs": [], + "outcomes": [ + "True", + "False", + ], + "outputs": [], + "properties": { + "audience": { + "description": "The audience (aud) claim", + "multivalued": false, + "required": true, + "title": "Audience", + "type": "STRING", + }, + "issuer": { + "description": "The issuer (iss) claim", + "multivalued": false, + "required": true, + "title": "Issuer", + "type": "STRING", + }, + "signingkey": { + "defaultValue": "esv.signing.key", + "description": "The secret label for the HMAC signing key", + "multivalued": false, + "required": true, + "title": "HMAC Signing Key", + "type": "STRING", + }, + "validity": { + "defaultValue": 5, + "description": "", + "multivalued": false, + "required": true, + "title": "Validity (minutes)", + "type": "NUMBER", + }, + }, + "script": "var aud = properties.audience; +var iss = properties.issuer; +var validity = properties.validity; +var esv = properties.signingkey; + +var signingkey = systemEnv.getProperty(esv); + +var username = nodeState.get("username"); + +var data = { + jwtType:"SIGNED", + jwsAlgorithm: "HS256", + issuer: iss, + subject: username, + audience: aud, + type: "JWT", + validityMinutes: validity, + signingKey: signingkey +}; + +var jwt = jwtAssertion.generateJwt(data); + +if (jwt !== null && jwt.length > 0) { + nodeState.putShared("assertionJwt" , jwt); + action.goTo("True"); +} else { + action.goTo("False"); +}", + "serviceName": "e5ad0110c8ee4dafaae983003cd05d4a", + "tags": [ + "Utilities", + "utilities", + ], + }, +] +`; + +exports[`NodeOps readNode() 1: Read existing node 1`] = ` +{ + "_id": "67693475-3a58-4e38-bcc6-037b3fe46a58", + "_outcomes": [ + { + "displayName": "Outcome", + "id": "outcome", + }, + ], + "_rev": "1964272313", + "_type": { + "_id": "ValidatedUsernameNode", + "collection": true, + "name": "Platform Username", + "version": "1.0", + }, + "usernameAttribute": "userName", + "validateInput": false, +} +`; + +exports[`NodeOps readNode() 2: Read non-existing node 1`] = ` +{ + "code": 404, + "message": "Not Found", + "reason": "Not Found", +} +`; + exports[`NodeOps readNodeTypes() 1: Read node types 1`] = ` [ { @@ -9137,3 +12227,121 @@ exports[`NodeOps readNodesByType() 1: Read nodes of type SelectIdPNode 1`] = ` }, ] `; + +exports[`NodeOps updateCustomNode() 1: Update existing custom node 1`] = ` +{ + "_id": "aaaa3fb2f5dc42dd9772bedc93898bd8-1", + "_rev": "-993019861", + "description": "Debug node that displays the shared and transient state of the journey for debugging purposes.", + "displayName": "Display State - TEST", + "errorOutcome": false, + "inputs": [], + "outcomes": [ + "outcome", + ], + "outputs": [], + "properties": { + "displayFormat": { + "defaultValue": "TABLE", + "description": "The format in which to display the states.", + "multivalued": false, + "options": { + "JSON": "Raw JSON", + "TABLE": "HTML Table", + }, + "required": true, + "title": "Display Format", + "type": "STRING", + }, + }, + "script": "var SCRIPT_OUTCOMES = { + OUTCOME: "outcome" +}; + +function main() { + if (!callbacks.isEmpty()) { + action.goTo(SCRIPT_OUTCOMES.OUTCOME); + return; + } + var keySet = nodeState.keys(); // Java Set + var keys = Array.from(keySet); // Make it into JavaScript array + debugState = {}; + for (var i in keys) { + var k = new String(keys[i]); + var item = nodeState.get(k); + if (typeof item === "object") { + debugState[k] = nodeState.getObject(k); + } else { + debugState[k] = nodeState.get(k); + } + } + if (properties.displayFormat === "JSON") { + callbacksBuilder.textOutputCallback(0, \`
\${JSON.stringify(debugState, null, 2)}
\`); + return; + } + callbacksBuilder.textOutputCallback(0, \`\${Array.from(Object.keys(debugState).map(k => \`\`))}
KeyValue
\${k}
\${debugState[k]}
\`); +} + +main(); +", + "serviceName": "aaaa3fb2f5dc42dd9772bedc93898bd8", + "tags": [ + "debug", + "testing", + ], +} +`; + +exports[`NodeOps updateNode() 1: Update existing node 1`] = ` +{ + "_id": "b726262c-641e-4fa5-b276-98e129b44cd9", + "_outcomes": [ + { + "displayName": "Patched", + "id": "PATCHED", + }, + { + "displayName": "Failed", + "id": "FAILURE", + }, + ], + "_rev": "-1625726187", + "_type": { + "_id": "PatchObjectNode", + "collection": true, + "name": "Patch Object", + "version": "1.0", + }, + "identityAttribute": "userName", + "identityResource": "managed/user", + "ignoredFields": [], + "patchAsObject": false, +} +`; + +exports[`NodeOps updateNode() 2: Update non-existing node 1`] = ` +{ + "_id": "b726262c-641e-4fa5-b276-98e129b44cd9", + "_outcomes": [ + { + "displayName": "Patched", + "id": "PATCHED", + }, + { + "displayName": "Failed", + "id": "FAILURE", + }, + ], + "_rev": "-1625726187", + "_type": { + "_id": "PatchObjectNode", + "collection": true, + "name": "Patch Object", + "version": "1.0", + }, + "identityAttribute": "userName", + "identityResource": "managed/user", + "ignoredFields": [], + "patchAsObject": false, +} +`; diff --git a/src/utils/PollyUtils.ts b/src/utils/PollyUtils.ts index 61c0683c8..1b2a2b948 100644 --- a/src/utils/PollyUtils.ts +++ b/src/utils/PollyUtils.ts @@ -126,12 +126,13 @@ function obfuscateJsonString(json: string): string { // check for scripts if (obj.script) { try { - let script = decode(obj.script); + const isEncoded = isBase64Encoded(obj.script); + let script = isEncoded ? decode(obj.script) : obj.script; script = script.replace( /(var .*?(?:Sid|sid|Secret|secret|PhoneNumberFrom) = (?:"|'))(.*?)((?:"|'))/g, '$1$3' ); - obj.script = encode(script); + obj.script = isEncoded ? encode(script) : script; } catch (error) { // ignore }