@rockcarver/frodo-cli 0.10.4 → 0.11.1-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +3 -3
  3. package/package.json +17 -15
  4. package/src/app.js +7 -6
  5. package/src/cli/_template/cmd-delete.js +9 -8
  6. package/src/cli/_template/cmd-describe.js +9 -8
  7. package/src/cli/_template/cmd-export.js +9 -8
  8. package/src/cli/_template/cmd-import.js +9 -8
  9. package/src/cli/_template/cmd-list.js +9 -8
  10. package/src/cli/_template/cmd-sub1-delete.js +9 -8
  11. package/src/cli/_template/cmd-sub1-describe.js +9 -8
  12. package/src/cli/_template/cmd-sub1-export.js +9 -8
  13. package/src/cli/_template/cmd-sub1-import.js +9 -8
  14. package/src/cli/_template/cmd-sub1-list.js +9 -8
  15. package/src/cli/_template/cmd-sub2-delete.js +9 -8
  16. package/src/cli/_template/cmd-sub2-describe.js +9 -8
  17. package/src/cli/_template/cmd-sub2-export.js +9 -8
  18. package/src/cli/_template/cmd-sub2-import.js +9 -8
  19. package/src/cli/_template/cmd-sub2-list.js +9 -8
  20. package/src/cli/admin/admin-add-autoid-static-user-mapping.js +12 -12
  21. package/src/cli/admin/admin-create-oauth2-client-with-admin-privileges.js +15 -18
  22. package/src/cli/admin/admin-get-access-token.js +12 -12
  23. package/src/cli/admin/admin-grant-oauth2-client-admin-privileges.js +13 -13
  24. package/src/cli/admin/admin-hide-generic-extension-attributes.js +13 -13
  25. package/src/cli/admin/admin-list-oauth2-clients-with-admin-privileges.js +13 -13
  26. package/src/cli/admin/admin-list-oauth2-clients-with-custom-privileges.js +14 -13
  27. package/src/cli/admin/admin-list-static-user-mappings.js +12 -12
  28. package/src/cli/admin/admin-remove-static-user-mapping.js +12 -12
  29. package/src/cli/admin/admin-repair-org-model.js +13 -13
  30. package/src/cli/admin/admin-revoke-oauth2-client-admin-privileges.js +13 -13
  31. package/src/cli/admin/admin-show-generic-extension-attributes.js +13 -13
  32. package/src/cli/app/app-delete.js +9 -8
  33. package/src/cli/app/app-describe.js +9 -8
  34. package/src/cli/app/app-export.js +15 -15
  35. package/src/cli/app/app-import.js +11 -11
  36. package/src/cli/app/app-list.js +11 -12
  37. package/src/cli/conn/conn-add.js +11 -11
  38. package/src/cli/conn/conn-delete.js +3 -1
  39. package/src/cli/conn/conn-describe.js +3 -1
  40. package/src/cli/conn/conn-list.js +3 -4
  41. package/src/cli/email/email-template-export.js +16 -16
  42. package/src/cli/email/email-template-import.js +16 -16
  43. package/src/cli/email/email-template-list.js +11 -11
  44. package/src/cli/esv/esv-apply.js +12 -12
  45. package/src/cli/esv/esv-secret-create.js +11 -11
  46. package/src/cli/esv/esv-secret-delete.js +13 -13
  47. package/src/cli/esv/esv-secret-describe.js +11 -11
  48. package/src/cli/esv/esv-secret-export.js +9 -8
  49. package/src/cli/esv/esv-secret-import.js +9 -8
  50. package/src/cli/esv/esv-secret-list.js +11 -11
  51. package/src/cli/esv/esv-secret-set.js +11 -11
  52. package/src/cli/esv/esv-secret-version-activate.js +12 -12
  53. package/src/cli/esv/esv-secret-version-create.js +11 -11
  54. package/src/cli/esv/esv-secret-version-deactivate.js +12 -12
  55. package/src/cli/esv/esv-secret-version-delete.js +13 -13
  56. package/src/cli/esv/esv-secret-version-list.js +11 -11
  57. package/src/cli/esv/esv-variable-create.js +11 -11
  58. package/src/cli/esv/esv-variable-delete.js +13 -16
  59. package/src/cli/esv/esv-variable-describe.js +11 -11
  60. package/src/cli/esv/esv-variable-export.js +9 -8
  61. package/src/cli/esv/esv-variable-import.js +9 -8
  62. package/src/cli/esv/esv-variable-list.js +11 -11
  63. package/src/cli/esv/esv-variable-set.js +13 -16
  64. package/src/cli/idm/idm-count.js +11 -11
  65. package/src/cli/idm/idm-export.js +16 -16
  66. package/src/cli/idm/idm-list.js +11 -11
  67. package/src/cli/idp/idp-export.js +15 -19
  68. package/src/cli/idp/idp-import.js +18 -18
  69. package/src/cli/idp/idp-list.js +12 -12
  70. package/src/cli/info/info.js +23 -19
  71. package/src/cli/journey/journey-delete.js +14 -14
  72. package/src/cli/journey/journey-describe.js +26 -35
  73. package/src/cli/journey/journey-export.js +18 -21
  74. package/src/cli/journey/journey-import.js +17 -17
  75. package/src/cli/journey/journey-list.js +12 -12
  76. package/src/cli/journey/journey-prune.js +12 -12
  77. package/src/cli/logging/logs-list.js +33 -28
  78. package/src/cli/logging/logs-tail.js +26 -22
  79. package/src/cli/realm/realm-add-custom-domain.js +13 -13
  80. package/src/cli/realm/realm-describe.js +14 -14
  81. package/src/cli/realm/realm-list.js +11 -11
  82. package/src/cli/realm/realm-remove-custom-domain.js +16 -13
  83. package/src/cli/saml/saml-cot-export.js +16 -16
  84. package/src/cli/saml/saml-cot-import.js +18 -18
  85. package/src/cli/saml/saml-cot-list.js +12 -12
  86. package/src/cli/saml/saml-describe.js +12 -12
  87. package/src/cli/saml/saml-export.js +16 -19
  88. package/src/cli/saml/saml-import.js +19 -18
  89. package/src/cli/saml/saml-list.js +12 -12
  90. package/src/cli/saml/saml-metadata-export.js +15 -19
  91. package/src/cli/script/script-delete.js +9 -8
  92. package/src/cli/script/script-describe.js +9 -8
  93. package/src/cli/script/script-export.js +18 -20
  94. package/src/cli/script/script-import.js +13 -12
  95. package/src/cli/script/script-list.js +12 -12
  96. package/src/cli/theme/theme-delete.js +17 -21
  97. package/src/cli/theme/theme-export.js +19 -18
  98. package/src/cli/theme/theme-import.js +21 -20
  99. package/src/cli/theme/theme-list.js +12 -12
  100. package/.eslintrc +0 -29
  101. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -30
  102. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  103. package/.github/README.md +0 -273
  104. package/.github/workflows/pipeline.yml +0 -487
  105. package/.prettierrc +0 -6
  106. package/CODE_OF_CONDUCT.md +0 -128
  107. package/docs/BINARIES.md +0 -22
  108. package/docs/CONTRIBUTE.md +0 -96
  109. package/docs/PIPELINE.md +0 -169
  110. package/docs/images/macos_warn1.png +0 -0
  111. package/docs/images/macos_warn2.png +0 -0
  112. package/docs/images/macos_warn3.png +0 -0
  113. package/docs/images/npm_versioning_guidelines.png +0 -0
  114. package/docs/images/release_pipeline.png +0 -0
  115. package/gulpfile.js +0 -49
  116. package/jsconfig.json +0 -6
  117. package/resources/sampleEntitiesFile.json +0 -8
  118. package/resources/sampleEnvFile.env +0 -2
  119. package/src/api/AuthenticateApi.js +0 -33
  120. package/src/api/BaseApi.js +0 -242
  121. package/src/api/CirclesOfTrustApi.js +0 -87
  122. package/src/api/EmailTemplateApi.js +0 -37
  123. package/src/api/IdmConfigApi.js +0 -88
  124. package/src/api/LogApi.js +0 -45
  125. package/src/api/ManagedObjectApi.js +0 -62
  126. package/src/api/OAuth2ClientApi.js +0 -69
  127. package/src/api/OAuth2OIDCApi.js +0 -73
  128. package/src/api/OAuth2ProviderApi.js +0 -32
  129. package/src/api/RealmApi.js +0 -99
  130. package/src/api/Saml2Api.js +0 -176
  131. package/src/api/ScriptApi.js +0 -84
  132. package/src/api/SecretsApi.js +0 -151
  133. package/src/api/ServerInfoApi.js +0 -41
  134. package/src/api/SocialIdentityProvidersApi.js +0 -114
  135. package/src/api/StartupApi.js +0 -45
  136. package/src/api/ThemeApi.js +0 -181
  137. package/src/api/TreeApi.js +0 -207
  138. package/src/api/VariablesApi.js +0 -104
  139. package/src/api/utils/ApiUtils.js +0 -77
  140. package/src/api/utils/Base64.js +0 -62
  141. package/src/cli/journey/journey-delete.e2e.test.js +0 -380
  142. package/src/cli/journey/journey-list.e2e.test.js +0 -141
  143. package/src/cli/theme/theme-delete.e2e.test.js +0 -178
  144. package/src/cli/theme/theme-list.e2e.test.js +0 -119
  145. package/src/ops/AdminOps.js +0 -901
  146. package/src/ops/AuthenticateOps.js +0 -342
  147. package/src/ops/CirclesOfTrustOps.js +0 -350
  148. package/src/ops/ConnectionProfileOps.js +0 -254
  149. package/src/ops/EmailTemplateOps.js +0 -326
  150. package/src/ops/IdmOps.js +0 -227
  151. package/src/ops/IdpOps.js +0 -342
  152. package/src/ops/JourneyOps.js +0 -2026
  153. package/src/ops/LogOps.js +0 -357
  154. package/src/ops/ManagedObjectOps.js +0 -34
  155. package/src/ops/OAuth2ClientOps.js +0 -151
  156. package/src/ops/OrganizationOps.js +0 -85
  157. package/src/ops/RealmOps.js +0 -139
  158. package/src/ops/SamlOps.js +0 -541
  159. package/src/ops/ScriptOps.js +0 -211
  160. package/src/ops/SecretsOps.js +0 -288
  161. package/src/ops/StartupOps.js +0 -114
  162. package/src/ops/ThemeOps.js +0 -379
  163. package/src/ops/VariablesOps.js +0 -185
  164. package/src/ops/templates/OAuth2ClientTemplate.json +0 -270
  165. package/src/ops/templates/OrgModelUserAttributesTemplate.json +0 -149
  166. package/src/ops/templates/cloud/GenericExtensionAttributesTemplate.json +0 -392
  167. package/src/ops/templates/cloud/managed.json +0 -4119
  168. package/src/ops/utils/Console.js +0 -434
  169. package/src/ops/utils/DataProtection.js +0 -92
  170. package/src/ops/utils/ExportImportUtils.js +0 -146
  171. package/src/ops/utils/OpsUtils.js +0 -76
  172. package/src/ops/utils/Wordwrap.js +0 -11
  173. package/src/storage/SessionStorage.js +0 -45
  174. package/test/client_cli/en/connections.test.js +0 -62
  175. package/test/client_cli/en/connections_add.test.js +0 -34
  176. package/test/client_cli/en/connections_delete.test.js +0 -34
  177. package/test/client_cli/en/connections_list.test.js +0 -34
  178. package/test/client_cli/en/email_templates.test.js +0 -77
  179. package/test/client_cli/en/email_templates_export.test.js +0 -196
  180. package/test/client_cli/en/email_templates_import.test.js +0 -145
  181. package/test/client_cli/en/email_templates_list.test.js +0 -130
  182. package/test/client_cli/en/idm.test.js +0 -111
  183. package/test/client_cli/en/idm_count.test.js +0 -121
  184. package/test/client_cli/en/idm_export.test.js +0 -136
  185. package/test/client_cli/en/idm_exportAll.test.js +0 -156
  186. package/test/client_cli/en/idm_exportAllRaw.test.js +0 -120
  187. package/test/client_cli/en/idm_import.test_.js +0 -103
  188. package/test/client_cli/en/idm_importAll.test_.js +0 -103
  189. package/test/client_cli/en/idm_list.test.js +0 -103
  190. package/test/client_cli/en/info.test.js +0 -125
  191. package/test/client_cli/en/journey.test.js +0 -127
  192. package/test/client_cli/en/journey_describe.test.js +0 -196
  193. package/test/client_cli/en/journey_export.test.js +0 -213
  194. package/test/client_cli/en/journey_import.test.js +0 -195
  195. package/test/client_cli/en/journey_importAll.test.js +0 -180
  196. package/test/client_cli/en/journey_list.test.js +0 -162
  197. package/test/client_cli/en/journey_prune.test.js +0 -148
  198. package/test/client_cli/en/logs.test.js +0 -79
  199. package/test/client_cli/en/logs_list.test.js +0 -83
  200. package/test/client_cli/en/logs_tail.test.js +0 -118
  201. package/test/client_cli/en/root.test.js +0 -91
  202. package/test/client_cli/en/script.test.js +0 -77
  203. package/test/client_cli/en/script_export.test.js +0 -213
  204. package/test/client_cli/en/script_import.test.js +0 -163
  205. package/test/client_cli/en/script_list.test.js +0 -148
  206. package/test/client_cli/utils/utils.js +0 -32
  207. package/test/e2e/journey/baseline/ForgottenUsername.journey.json +0 -216
  208. package/test/e2e/journey/baseline/Login.journey.json +0 -205
  209. package/test/e2e/journey/baseline/PasswordGrant.journey.json +0 -139
  210. package/test/e2e/journey/baseline/ProgressiveProfile.journey.json +0 -198
  211. package/test/e2e/journey/baseline/Registration.journey.json +0 -249
  212. package/test/e2e/journey/baseline/ResetPassword.journey.json +0 -268
  213. package/test/e2e/journey/baseline/UpdatePassword.journey.json +0 -323
  214. package/test/e2e/journey/baseline/allAlphaJourneys.journeys.json +0 -1520
  215. package/test/e2e/journey/delete/ForgottenUsername.journey.json +0 -216
  216. package/test/e2e/journey/delete/Login.journey.json +0 -205
  217. package/test/e2e/journey/delete/PasswordGrant.journey.json +0 -139
  218. package/test/e2e/journey/delete/ProgressiveProfile.journey.json +0 -198
  219. package/test/e2e/journey/delete/Registration.journey.json +0 -249
  220. package/test/e2e/journey/delete/ResetPassword.journey.json +0 -268
  221. package/test/e2e/journey/delete/UpdatePassword.journey.json +0 -323
  222. package/test/e2e/journey/delete/deleteMe.journey.json +0 -230
  223. package/test/e2e/journey/list/Disabled.journey.json +0 -43
  224. package/test/e2e/journey/list/ForgottenUsername.journey.json +0 -216
  225. package/test/e2e/journey/list/Login.journey.json +0 -205
  226. package/test/e2e/journey/list/PasswordGrant.journey.json +0 -139
  227. package/test/e2e/journey/list/ProgressiveProfile.journey.json +0 -198
  228. package/test/e2e/journey/list/Registration.journey.json +0 -249
  229. package/test/e2e/journey/list/ResetPassword.journey.json +0 -268
  230. package/test/e2e/journey/list/UpdatePassword.journey.json +0 -323
  231. package/test/e2e/setup.js +0 -98
  232. package/test/e2e/theme/baseline/Contrast.theme.json +0 -95
  233. package/test/e2e/theme/baseline/Highlander.theme.json +0 -95
  234. package/test/e2e/theme/baseline/Robroy.theme.json +0 -95
  235. package/test/e2e/theme/baseline/Starter-Theme.theme.json +0 -94
  236. package/test/e2e/theme/baseline/Zardoz.theme.json +0 -95
  237. package/test/e2e/theme/import/Contrast.theme.json +0 -95
  238. package/test/e2e/theme/import/Highlander.theme.json +0 -95
  239. package/test/e2e/theme/import/Robroy.theme.json +0 -95
  240. package/test/e2e/theme/import/Starter-Theme.theme.json +0 -94
  241. package/test/e2e/theme/import/Zardoz.default.theme.json +0 -95
  242. package/test/fs_tmp/.gitkeep +0 -2
  243. package/test/global/setup.js +0 -65
  244. package/test/lib_api/unit_tests/ApiUtils.test.js +0 -186
  245. package/test/lib_api/unit_tests/Base64URL.test.js +0 -22
  246. package/test/lib_api/unit_tests/DataProtection.test.js +0 -25
  247. package/test/lib_api/unit_tests/ExportImportUtils.test.js +0 -121
@@ -1,139 +0,0 @@
1
- import {
2
- createKeyValueTable,
3
- createTable,
4
- printMessage,
5
- } from './utils/Console.js';
6
- import { getRealmByName, getRealms, putRealm } from '../api/RealmApi.js';
7
-
8
- /**
9
- * List realms
10
- * @param {boolean} long Long list format with details
11
- */
12
- export async function listRealms(long = false) {
13
- try {
14
- const realms = (await getRealms()).data.result;
15
- if (long) {
16
- const table = createTable([
17
- 'Name'.brightCyan,
18
- 'Status'.brightCyan,
19
- 'Custom Domains'.brightCyan,
20
- 'Parent'.brightCyan,
21
- ]);
22
- realms.forEach((realmConfig) => {
23
- table.push([
24
- realmConfig.name,
25
- realmConfig.active ? 'active'.brightGreen : 'inactive'.brightRed,
26
- realmConfig.aliases.join('\n'),
27
- realmConfig.parentPath,
28
- ]);
29
- });
30
- printMessage(table.toString());
31
- } else {
32
- realms.forEach((realmConfig) => {
33
- printMessage(realmConfig.name, 'info');
34
- });
35
- }
36
- } catch (error) {
37
- printMessage(`Error listing realms: ${error.rmessage}`, 'error');
38
- printMessage(error.response.data, 'error');
39
- }
40
- }
41
-
42
- /**
43
- * Describe realm
44
- * @param {String} realm realm name
45
- */
46
- export async function describe(realm) {
47
- try {
48
- const realmConfig = await getRealmByName(realm);
49
- const table = createKeyValueTable();
50
- table.push(['Name'.brightCyan, realmConfig.name]);
51
- table.push([
52
- 'Status'.brightCyan,
53
- realmConfig.active ? 'active'.brightGreen : 'inactive'.brightRed,
54
- ]);
55
- table.push(['Custom Domains'.brightCyan, realmConfig.aliases.join('\n')]);
56
- table.push(['Parent'.brightCyan, realmConfig.parentPath]);
57
- table.push(['Id'.brightCyan, realmConfig._id]);
58
- printMessage(table.toString());
59
- } catch (error) {
60
- printMessage(`Realm ${realm} not found!`, 'error');
61
- }
62
- }
63
-
64
- /**
65
- * Add custom DNS domain name (realm DNS alias)
66
- * @param {String} realm realm name
67
- * @param {String} domain domain name
68
- */
69
- export async function addCustomDomain(realm, domain) {
70
- try {
71
- let realmConfig = await getRealmByName(realm);
72
- let exists = false;
73
- realmConfig.aliases.forEach((alias) => {
74
- if (domain.toLowerCase() === alias.toLowerCase()) {
75
- exists = true;
76
- }
77
- });
78
- if (!exists) {
79
- try {
80
- realmConfig.aliases.push(domain.toLowerCase());
81
- realmConfig = (await putRealm(realmConfig._id, realmConfig)).data;
82
- const table = createKeyValueTable();
83
- table.push(['Name'.brightCyan, realmConfig.name]);
84
- table.push([
85
- 'Status'.brightCyan,
86
- realmConfig.active ? 'active'.brightGreen : 'inactive'.brightRed,
87
- ]);
88
- table.push([
89
- 'Custom Domains'.brightCyan,
90
- realmConfig.aliases.join('\n'),
91
- ]);
92
- table.push(['Parent'.brightCyan, realmConfig.parentPath]);
93
- table.push(['Id'.brightCyan, realmConfig._id]);
94
- printMessage(table.toString());
95
- } catch (error) {
96
- printMessage(`Error adding custom domain: ${error.message}`, 'error');
97
- }
98
- }
99
- } catch (error) {
100
- printMessage(`${error.message}`, 'error');
101
- }
102
- }
103
-
104
- /**
105
- * Remove custom DNS domain name (realm DNS alias)
106
- * @param {String} realm realm name
107
- * @param {String} domain domain name
108
- */
109
- export async function removeCustomDomain(realm, domain) {
110
- try {
111
- let realmConfig = await getRealmByName(realm);
112
- const aliases = realmConfig.aliases.filter(
113
- (alias) => domain.toLowerCase() !== alias.toLowerCase()
114
- );
115
- if (aliases.length < realmConfig.aliases.length) {
116
- try {
117
- realmConfig.aliases = aliases;
118
- realmConfig = (await putRealm(realmConfig._id, realmConfig)).data;
119
- const table = createKeyValueTable();
120
- table.push(['Name'.brightCyan, realmConfig.name]);
121
- table.push([
122
- 'Status'.brightCyan,
123
- realmConfig.active ? 'active'.brightGreen : 'inactive'.brightRed,
124
- ]);
125
- table.push([
126
- 'Custom Domains'.brightCyan,
127
- realmConfig.aliases.join('\n'),
128
- ]);
129
- table.push(['Parent'.brightCyan, realmConfig.parentPath]);
130
- table.push(['Id'.brightCyan, realmConfig._id]);
131
- printMessage(table.toString());
132
- } catch (error) {
133
- printMessage(`Error removing custom domain: ${error.message}`, 'error');
134
- }
135
- }
136
- } catch (error) {
137
- printMessage(`${error.message}`, 'error');
138
- }
139
- }
@@ -1,541 +0,0 @@
1
- import fs from 'fs';
2
- import _ from 'lodash';
3
- import { decode, encode, encodeBase64Url } from '../api/utils/Base64.js';
4
- import {
5
- createTable,
6
- printMessage,
7
- createProgressBar,
8
- updateProgressBar,
9
- stopProgressBar,
10
- createObjectTable,
11
- } from './utils/Console.js';
12
- import {
13
- getProviders,
14
- findProviders,
15
- getProviderByLocationAndId,
16
- getProviderMetadata,
17
- createProvider,
18
- getProviderMetadataUrl,
19
- } from '../api/Saml2Api.js';
20
- import { getScript } from '../api/ScriptApi.js';
21
- import {
22
- convertBase64TextToArray,
23
- convertBase64UrlTextToArray,
24
- convertTextArrayToBase64,
25
- convertTextArrayToBase64Url,
26
- getRealmString,
27
- getTypedFilename,
28
- saveJsonToFile,
29
- saveTextToFile,
30
- validateImport,
31
- } from './utils/ExportImportUtils.js';
32
- import { createOrUpdateScript } from './ScriptOps.js';
33
-
34
- const roleMap = {
35
- identityProvider: 'IDP',
36
- serviceProvider: 'SP',
37
- attributeQueryProvider: 'AttrQuery',
38
- xacmlPolicyEnforcementPoint: 'XACML PEP',
39
- };
40
-
41
- // use a function vs a template variable to avoid problems in loops
42
- function getFileDataTemplate() {
43
- return {
44
- meta: {},
45
- script: {},
46
- saml: {
47
- hosted: {},
48
- remote: {},
49
- metadata: {},
50
- },
51
- };
52
- }
53
-
54
- /**
55
- * List entity providers
56
- * @param {boolean} long Long list format with details
57
- */
58
- export async function listProviders(long = false) {
59
- const providerList = (await getProviders()).data.result;
60
- providerList.sort((a, b) => a._id.localeCompare(b._id));
61
- if (!long) {
62
- providerList.forEach((item) => {
63
- printMessage(`${item.entityId}`, 'data');
64
- });
65
- } else {
66
- const table = createTable([
67
- 'Entity Id'.brightCyan,
68
- 'Location'.brightCyan,
69
- 'Role(s)'.brightCyan,
70
- ]);
71
- providerList.forEach((provider) => {
72
- table.push([
73
- provider.entityId,
74
- provider.location,
75
- provider.roles.map((role) => roleMap[role]).join(', '),
76
- ]);
77
- });
78
- printMessage(table.toString());
79
- }
80
- }
81
-
82
- /**
83
- * Include dependencies in the export file
84
- * @param {Object} providerData Object representing a SAML entity provider
85
- * @param {Object} fileData File data object to add dependencies to
86
- */
87
- async function exportDependencies(providerData, fileData) {
88
- const attrMapperScriptId = _.get(providerData, [
89
- 'identityProvider',
90
- 'assertionProcessing',
91
- 'attributeMapper',
92
- 'attributeMapperScript',
93
- ]);
94
- if (attrMapperScriptId && attrMapperScriptId !== '[Empty]') {
95
- const scriptData = (await getScript(attrMapperScriptId)).data;
96
- scriptData.script = convertBase64TextToArray(scriptData.script);
97
- // eslint-disable-next-line no-param-reassign
98
- fileData.script[attrMapperScriptId] = scriptData;
99
- }
100
- const idpAdapterScriptId = _.get(providerData, [
101
- 'identityProvider',
102
- 'advanced',
103
- 'idpAdapter',
104
- 'idpAdapterScript',
105
- ]);
106
- if (idpAdapterScriptId && idpAdapterScriptId !== '[Empty]') {
107
- const scriptData = (await getScript(idpAdapterScriptId)).data;
108
- scriptData.script = convertBase64TextToArray(scriptData.script);
109
- // eslint-disable-next-line no-param-reassign
110
- fileData.script[idpAdapterScriptId] = scriptData;
111
- }
112
- const metaDataResponse = await getProviderMetadata(providerData.entityId);
113
- // eslint-disable-next-line no-param-reassign
114
- fileData.saml.metadata[providerData._id] = convertBase64UrlTextToArray(
115
- encodeBase64Url(metaDataResponse.data)
116
- );
117
- }
118
-
119
- /**
120
- * Export a single entity provider to file
121
- * @param {String} entityId Provider entity id
122
- * @param {String} file Optional filename
123
- */
124
- export async function exportProvider(entityId, file = null) {
125
- let fileName = file;
126
- if (!fileName) {
127
- fileName = getTypedFilename(entityId, 'saml');
128
- }
129
- createProgressBar(1, `Exporting provider ${entityId}`);
130
- const found = await findProviders(`entityId eq '${entityId}'`, 'location');
131
- switch (found.data.resultCount) {
132
- case 0:
133
- printMessage(`No provider with entity id '${entityId}' found`, 'error');
134
- break;
135
- case 1:
136
- {
137
- const { location } = found.data.result[0];
138
- const id = found.data.result[0]._id;
139
- getProviderByLocationAndId(location, id)
140
- .then(async (response) => {
141
- const providerData = response.data;
142
- updateProgressBar(`Writing file ${fileName}`);
143
- const fileData = getFileDataTemplate();
144
- fileData.saml[location][providerData._id] = providerData;
145
- await exportDependencies(providerData, fileData);
146
- saveJsonToFile(fileData, fileName);
147
- stopProgressBar(
148
- `Exported ${entityId.brightCyan} to ${fileName.brightCyan}.`
149
- );
150
- })
151
- .catch((err) => {
152
- stopProgressBar(`${err}`);
153
- printMessage(err, 'error');
154
- });
155
- }
156
- break;
157
- default:
158
- printMessage(
159
- `Multiple providers with entity id '${entityId}' found`,
160
- 'error'
161
- );
162
- }
163
- }
164
-
165
- /**
166
- * Export provider metadata to file
167
- * @param {String} entityId Provider entity id
168
- * @param {String} file Optional filename
169
- */
170
- export async function exportMetadata(entityId, file = null) {
171
- let fileName = file;
172
- if (!fileName) {
173
- fileName = getTypedFilename(entityId, 'metadata', 'xml');
174
- }
175
- createProgressBar(1, `Exporting metadata for: ${entityId}`);
176
- getProviderMetadata(entityId)
177
- .then(async (response) => {
178
- updateProgressBar(`Writing file ${fileName}`);
179
- // printMessage(response.data, 'error');
180
- const metaData = response.data;
181
- saveTextToFile(metaData, fileName);
182
- stopProgressBar(
183
- `Exported ${entityId.brightCyan} metadata to ${fileName.brightCyan}.`
184
- );
185
- })
186
- .catch((err) => {
187
- stopProgressBar(`${err}`);
188
- printMessage(err, 'error');
189
- });
190
- }
191
-
192
- /**
193
- * Describe an entity provider's configuration
194
- * @param {String} entityId Provider entity id
195
- */
196
- export async function describeProvider(entityId) {
197
- const found = await findProviders(
198
- `entityId eq '${entityId}'`,
199
- 'location,roles'
200
- );
201
- switch (found.data.resultCount) {
202
- case 0:
203
- printMessage(`No provider with entity id '${entityId}' found`, 'error');
204
- break;
205
- case 1:
206
- {
207
- const { location } = found.data.result[0];
208
- const id = found.data.result[0]._id;
209
- const roles = found.data.result[0].roles
210
- .map((role) => roleMap[role])
211
- .join(', ');
212
- getProviderByLocationAndId(location, id)
213
- .then(async (response) => {
214
- const rawProviderData = response.data;
215
- delete rawProviderData._id;
216
- delete rawProviderData._rev;
217
- rawProviderData.location = location;
218
- rawProviderData.roles = roles;
219
- rawProviderData.metadataUrl = getProviderMetadataUrl(entityId);
220
- // const fullProviderData = getFileDataTemplate();
221
- // fullProviderData.saml[location][rawProviderData._id] =
222
- // rawProviderData;
223
- // await exportDependencies(rawProviderData, fullProviderData);
224
- // describe the provider
225
- const table = createObjectTable(rawProviderData);
226
- printMessage(table.toString());
227
- })
228
- .catch((err) => {
229
- printMessage(err, 'error');
230
- });
231
- }
232
- break;
233
- default:
234
- printMessage(
235
- `Multiple providers with entity id '${entityId}' found`,
236
- 'error'
237
- );
238
- }
239
- }
240
-
241
- /**
242
- * Export all entity providers to one file
243
- * @param {String} file Optional filename
244
- */
245
- export async function exportProvidersToFile(file = null) {
246
- let fileName = file;
247
- if (!fileName) {
248
- fileName = getTypedFilename(`all${getRealmString()}Providers`, 'saml');
249
- }
250
- const fileData = getFileDataTemplate();
251
- const found = await getProviders();
252
- if (found.status < 200 || found.status > 399) {
253
- printMessage(found, 'data');
254
- printMessage(`exportProvidersToFile: ${found.status}`, 'error');
255
- } else if (found.data.resultCount > 0) {
256
- createProgressBar(found.data.resultCount, 'Exporting providers');
257
- for (const stubData of found.data.result) {
258
- updateProgressBar(`Exporting provider ${stubData.entityId}`);
259
- // eslint-disable-next-line no-await-in-loop
260
- const response = await getProviderByLocationAndId(
261
- stubData.location,
262
- stubData._id
263
- );
264
- const providerData = response.data;
265
- // eslint-disable-next-line no-await-in-loop
266
- await exportDependencies(providerData, fileData);
267
- fileData.saml[stubData.location][providerData._id] = providerData;
268
- }
269
- saveJsonToFile(fileData, fileName);
270
- stopProgressBar(
271
- `${found.data.resultCount} providers exported to ${fileName}.`
272
- );
273
- } else {
274
- printMessage('No entity providers found.', 'info');
275
- }
276
- }
277
-
278
- /**
279
- * Export all entity providers to individual files
280
- */
281
- export async function exportProvidersToFiles() {
282
- const found = await getProviders();
283
- if (found.data.resultCount > 0) {
284
- createProgressBar(found.data.resultCount, 'Exporting providers');
285
- for (const stubData of found.data.result) {
286
- updateProgressBar(`Exporting provider ${stubData.entityId}`);
287
- const fileName = getTypedFilename(stubData.entityId, 'saml');
288
- const fileData = getFileDataTemplate();
289
- // eslint-disable-next-line no-await-in-loop
290
- const response = await getProviderByLocationAndId(
291
- stubData.location,
292
- stubData._id
293
- );
294
- const providerData = response.data;
295
- // eslint-disable-next-line no-await-in-loop
296
- await exportDependencies(providerData, fileData);
297
- fileData.saml[stubData.location][providerData._id] = providerData;
298
- saveJsonToFile(fileData, fileName);
299
- }
300
- stopProgressBar(`${found.data.resultCount} providers exported.`);
301
- } else {
302
- printMessage('No entity providers found.', 'info');
303
- }
304
- }
305
-
306
- /**
307
- * Include dependencies from the import file
308
- * @param {Object} providerData Object representing a SAML entity provider
309
- * @param {Object} fileData File data object to read dependencies from
310
- */
311
- async function importDependencies(providerData, fileData) {
312
- const attrMapperScriptId = _.get(providerData, [
313
- 'identityProvider',
314
- 'assertionProcessing',
315
- 'attributeMapper',
316
- 'attributeMapperScript',
317
- ]);
318
- if (attrMapperScriptId && attrMapperScriptId !== '[Empty]') {
319
- const scriptData = _.get(fileData, ['script', attrMapperScriptId]);
320
- scriptData.script = convertTextArrayToBase64(scriptData.script);
321
- await createOrUpdateScript(attrMapperScriptId, scriptData);
322
- }
323
- const idpAdapterScriptId = _.get(providerData, [
324
- 'identityProvider',
325
- 'advanced',
326
- 'idpAdapter',
327
- 'idpAdapterScript',
328
- ]);
329
- if (idpAdapterScriptId && idpAdapterScriptId !== '[Empty]') {
330
- const scriptData = _.get(fileData, ['script', idpAdapterScriptId]);
331
- scriptData.script = convertTextArrayToBase64(scriptData.script);
332
- await createOrUpdateScript(attrMapperScriptId, scriptData);
333
- }
334
- }
335
-
336
- /**
337
- * Find provider in import file and return its location
338
- * @param {String} entityId64 Base64-encoded provider entity id
339
- * @param {Object} fileData Import file json data
340
- * @returns {String} 'hosted' or 'remote' if found, undefined otherwise
341
- */
342
- function getLocation(entityId64, fileData) {
343
- if (_.get(fileData, ['saml', 'hosted', entityId64])) {
344
- return 'hosted';
345
- }
346
- if (_.get(fileData, ['saml', 'remote', entityId64])) {
347
- return 'remote';
348
- }
349
- return undefined;
350
- }
351
-
352
- /**
353
- * Import a SAML entity provider by entity id from file
354
- * @param {String} entityId Provider entity id
355
- * @param {String} file Import file name
356
- */
357
- export async function importProvider(entityId, file) {
358
- const entityId64 = encode(entityId, false);
359
- fs.readFile(file, 'utf8', async (err, data) => {
360
- if (err) throw err;
361
- const fileData = JSON.parse(data);
362
- if (validateImport(fileData.meta)) {
363
- createProgressBar(1, 'Importing provider...');
364
- const location = getLocation(entityId64, fileData);
365
- if (location) {
366
- const providerData = _.get(fileData, ['saml', location, entityId64]);
367
- updateProgressBar(`Importing ${entityId}`);
368
- await importDependencies(providerData, fileData);
369
- let metaData = null;
370
- if (location === 'remote') {
371
- metaData = convertTextArrayToBase64Url(
372
- fileData.saml.metadata[entityId64]
373
- );
374
- }
375
- createProvider(location, providerData, metaData)
376
- .then(() => {
377
- stopProgressBar(`Successfully imported provider ${entityId}.`);
378
- })
379
- .catch((createProviderErr) => {
380
- printMessage(`\nError importing provider ${entityId}`, 'error');
381
- printMessage(createProviderErr.response, 'error');
382
- });
383
- } else {
384
- stopProgressBar(
385
- `Provider ${entityId.brightCyan} not found in ${file.brightCyan}!`
386
- );
387
- }
388
- } else {
389
- printMessage('Import validation failed...', 'error');
390
- }
391
- });
392
- }
393
-
394
- /**
395
- * Import first SAML entity provider from file
396
- * @param {String} file Import file name
397
- */
398
- export async function importFirstProvider(file) {
399
- fs.readFile(file, 'utf8', async (err, data) => {
400
- if (err) throw err;
401
- const fileData = JSON.parse(data);
402
- if (validateImport(fileData.meta)) {
403
- createProgressBar(1, 'Importing provider...');
404
- // find providers in hosted and if none exist in remote
405
- let location = 'hosted';
406
- let providerIds = _.keys(fileData.saml[location]);
407
- if (providerIds.length === 0) {
408
- location = 'remote';
409
- providerIds = _.keys(fileData.saml[location]);
410
- if (providerIds.length === 0) {
411
- location = null;
412
- }
413
- }
414
- if (location) {
415
- const entityId64 = providerIds[0];
416
- const entityId = decode(entityId64);
417
- const providerData = _.get(fileData, ['saml', location, entityId64]);
418
- updateProgressBar(`Importing ${entityId}`);
419
- await importDependencies(providerData, fileData);
420
- let metaData = null;
421
- if (location === 'remote') {
422
- metaData = convertTextArrayToBase64Url(
423
- fileData.saml.metadata[entityId64]
424
- );
425
- }
426
- createProvider(location, providerData, metaData)
427
- .then(() => {
428
- stopProgressBar(`Successfully imported provider ${entityId}.`);
429
- })
430
- .catch((createProviderErr) => {
431
- stopProgressBar(`Error importing provider ${entityId}`);
432
- printMessage(`\nError importing provider ${entityId}`, 'error');
433
- printMessage(createProviderErr.response.data, 'error');
434
- });
435
- } else {
436
- stopProgressBar(`No providers found in ${file.brightCyan}!`);
437
- }
438
- } else {
439
- printMessage('Import validation failed...', 'error');
440
- }
441
- });
442
- }
443
-
444
- /**
445
- * Import all SAML entity providers from file
446
- * @param {String} file Import file name
447
- */
448
- export async function importProvidersFromFile(file) {
449
- fs.readFile(file, 'utf8', async (err, data) => {
450
- if (err) throw err;
451
- const fileData = JSON.parse(data);
452
- if (validateImport(fileData.meta)) {
453
- // find providers in hosted and in remote and map locations
454
- const hostedIds = _.keys(fileData.saml.hosted);
455
- const remoteIds = _.keys(fileData.saml.remote);
456
- const providerIds = hostedIds.concat(remoteIds);
457
- createProgressBar(providerIds.length, 'Importing providers...');
458
- for (const entityId64 of providerIds) {
459
- const location = hostedIds.includes(entityId64) ? 'hosted' : 'remote';
460
- const entityId = decode(entityId64);
461
- const providerData = _.get(fileData, ['saml', location, entityId64]);
462
- // eslint-disable-next-line no-await-in-loop
463
- await importDependencies(providerData, fileData);
464
- let metaData = null;
465
- if (location === 'remote') {
466
- metaData = convertTextArrayToBase64Url(
467
- fileData.saml.metadata[entityId64]
468
- );
469
- }
470
- try {
471
- // eslint-disable-next-line no-await-in-loop
472
- await createProvider(location, providerData, metaData);
473
- updateProgressBar(`Imported ${entityId}`);
474
- } catch (createProviderErr) {
475
- printMessage(`\nError importing provider ${entityId}`, 'error');
476
- printMessage(createProviderErr.response.data, 'error');
477
- }
478
- }
479
- stopProgressBar(`Providers imported.`);
480
- } else {
481
- printMessage('Import validation failed...', 'error');
482
- }
483
- });
484
- }
485
-
486
- /**
487
- * Import all SAML entity providers from all *.saml.json files in the current directory
488
- */
489
- export async function importProvidersFromFiles() {
490
- const names = fs.readdirSync('.');
491
- const jsonFiles = names.filter((name) =>
492
- name.toLowerCase().endsWith('.saml.json')
493
- );
494
- createProgressBar(jsonFiles.length, 'Importing providers...');
495
- let total = 0;
496
- let totalErrors = 0;
497
- for (const file of jsonFiles) {
498
- const data = fs.readFileSync(file, 'utf8');
499
- const fileData = JSON.parse(data);
500
- if (validateImport(fileData.meta)) {
501
- // find providers in hosted and in remote and map locations
502
- const hostedIds = _.keys(fileData.saml.hosted);
503
- const remoteIds = _.keys(fileData.saml.remote);
504
- const providerIds = hostedIds.concat(remoteIds);
505
- total += providerIds.length;
506
- let errors = 0;
507
- for (const entityId64 of providerIds) {
508
- const location = hostedIds.includes(entityId64) ? 'hosted' : 'remote';
509
- const entityId = decode(entityId64);
510
- const providerData = _.get(fileData, ['saml', location, entityId64]);
511
- importDependencies(providerData, fileData);
512
- let metaData = null;
513
- if (location === 'remote') {
514
- metaData = convertTextArrayToBase64Url(
515
- fileData.saml.metadata[entityId64]
516
- );
517
- }
518
- try {
519
- // eslint-disable-next-line no-await-in-loop
520
- await createProvider(location, providerData, metaData);
521
- // updateProgressBar(`Imported ${entityId}`);
522
- } catch (createProviderErr) {
523
- errors += 1;
524
- printMessage(`\nError importing provider ${entityId}`, 'error');
525
- printMessage(createProviderErr.response.data, 'error');
526
- }
527
- }
528
- totalErrors += errors;
529
- updateProgressBar(
530
- `Imported ${providerIds.length - errors} provider(s) from ${file}`
531
- );
532
- } else {
533
- printMessage(`Validation of ${file} failed!`, 'error');
534
- }
535
- }
536
- stopProgressBar(
537
- `Imported ${total - totalErrors} of ${total} provider(s) from ${
538
- jsonFiles.length
539
- } file(s).`
540
- );
541
- }