@rockcarver/frodo-lib 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +32 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +30 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/README.md +121 -0
- package/.github/workflows/pipeline.yml +287 -0
- package/.prettierrc +6 -0
- package/CHANGELOG.md +512 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/LICENSE +21 -0
- package/README.md +8 -0
- package/docs/CONTRIBUTE.md +96 -0
- package/docs/PIPELINE.md +169 -0
- package/docs/images/npm_versioning_guidelines.png +0 -0
- package/docs/images/release_pipeline.png +0 -0
- package/jsconfig.json +6 -0
- package/package.json +95 -0
- package/resources/sampleEntitiesFile.json +8 -0
- package/resources/sampleEnvFile.env +2 -0
- package/src/api/AuthenticateApi.js +33 -0
- package/src/api/BaseApi.js +242 -0
- package/src/api/CirclesOfTrustApi.js +87 -0
- package/src/api/EmailTemplateApi.js +37 -0
- package/src/api/IdmConfigApi.js +88 -0
- package/src/api/LogApi.js +45 -0
- package/src/api/ManagedObjectApi.js +62 -0
- package/src/api/OAuth2ClientApi.js +69 -0
- package/src/api/OAuth2OIDCApi.js +73 -0
- package/src/api/OAuth2ProviderApi.js +32 -0
- package/src/api/RealmApi.js +99 -0
- package/src/api/Saml2Api.js +176 -0
- package/src/api/ScriptApi.js +84 -0
- package/src/api/SecretsApi.js +151 -0
- package/src/api/ServerInfoApi.js +41 -0
- package/src/api/SocialIdentityProvidersApi.js +114 -0
- package/src/api/StartupApi.js +45 -0
- package/src/api/ThemeApi.js +181 -0
- package/src/api/TreeApi.js +207 -0
- package/src/api/VariablesApi.js +104 -0
- package/src/api/utils/ApiUtils.js +77 -0
- package/src/api/utils/ApiUtils.test.js +96 -0
- package/src/api/utils/Base64.js +62 -0
- package/src/index.js +32 -0
- package/src/index.test.js +13 -0
- package/src/ops/AdminOps.js +901 -0
- package/src/ops/AuthenticateOps.js +342 -0
- package/src/ops/CirclesOfTrustOps.js +350 -0
- package/src/ops/ConnectionProfileOps.js +254 -0
- package/src/ops/EmailTemplateOps.js +326 -0
- package/src/ops/IdmOps.js +227 -0
- package/src/ops/IdpOps.js +342 -0
- package/src/ops/JourneyOps.js +2026 -0
- package/src/ops/LogOps.js +357 -0
- package/src/ops/ManagedObjectOps.js +34 -0
- package/src/ops/OAuth2ClientOps.js +151 -0
- package/src/ops/OrganizationOps.js +85 -0
- package/src/ops/RealmOps.js +139 -0
- package/src/ops/SamlOps.js +541 -0
- package/src/ops/ScriptOps.js +211 -0
- package/src/ops/SecretsOps.js +288 -0
- package/src/ops/StartupOps.js +114 -0
- package/src/ops/ThemeOps.js +379 -0
- package/src/ops/VariablesOps.js +185 -0
- package/src/ops/templates/OAuth2ClientTemplate.json +270 -0
- package/src/ops/templates/OrgModelUserAttributesTemplate.json +149 -0
- package/src/ops/templates/cloud/GenericExtensionAttributesTemplate.json +392 -0
- package/src/ops/templates/cloud/managed.json +4119 -0
- package/src/ops/utils/Console.js +434 -0
- package/src/ops/utils/DataProtection.js +92 -0
- package/src/ops/utils/DataProtection.test.js +28 -0
- package/src/ops/utils/ExportImportUtils.js +146 -0
- package/src/ops/utils/ExportImportUtils.test.js +119 -0
- package/src/ops/utils/OpsUtils.js +76 -0
- package/src/ops/utils/Wordwrap.js +11 -0
- package/src/storage/SessionStorage.js +45 -0
- package/src/storage/StaticStorage.js +15 -0
- package/test/e2e/journey/baseline/ForgottenUsername.journey.json +216 -0
- package/test/e2e/journey/baseline/Login.journey.json +205 -0
- package/test/e2e/journey/baseline/PasswordGrant.journey.json +139 -0
- package/test/e2e/journey/baseline/ProgressiveProfile.journey.json +198 -0
- package/test/e2e/journey/baseline/Registration.journey.json +249 -0
- package/test/e2e/journey/baseline/ResetPassword.journey.json +268 -0
- package/test/e2e/journey/baseline/UpdatePassword.journey.json +323 -0
- package/test/e2e/journey/baseline/allAlphaJourneys.journeys.json +1520 -0
- package/test/e2e/journey/delete/ForgottenUsername.journey.json +216 -0
- package/test/e2e/journey/delete/Login.journey.json +205 -0
- package/test/e2e/journey/delete/PasswordGrant.journey.json +139 -0
- package/test/e2e/journey/delete/ProgressiveProfile.journey.json +198 -0
- package/test/e2e/journey/delete/Registration.journey.json +249 -0
- package/test/e2e/journey/delete/ResetPassword.journey.json +268 -0
- package/test/e2e/journey/delete/UpdatePassword.journey.json +323 -0
- package/test/e2e/journey/delete/deleteMe.journey.json +230 -0
- package/test/e2e/journey/list/Disabled.journey.json +43 -0
- package/test/e2e/journey/list/ForgottenUsername.journey.json +216 -0
- package/test/e2e/journey/list/Login.journey.json +205 -0
- package/test/e2e/journey/list/PasswordGrant.journey.json +139 -0
- package/test/e2e/journey/list/ProgressiveProfile.journey.json +198 -0
- package/test/e2e/journey/list/Registration.journey.json +249 -0
- package/test/e2e/journey/list/ResetPassword.journey.json +268 -0
- package/test/e2e/journey/list/UpdatePassword.journey.json +323 -0
- package/test/e2e/setup.js +107 -0
- package/test/e2e/theme/baseline/Contrast.theme.json +95 -0
- package/test/e2e/theme/baseline/Highlander.theme.json +95 -0
- package/test/e2e/theme/baseline/Robroy.theme.json +95 -0
- package/test/e2e/theme/baseline/Starter-Theme.theme.json +94 -0
- package/test/e2e/theme/baseline/Zardoz.theme.json +95 -0
- package/test/e2e/theme/import/Contrast.theme.json +95 -0
- package/test/e2e/theme/import/Highlander.theme.json +95 -0
- package/test/e2e/theme/import/Robroy.theme.json +95 -0
- package/test/e2e/theme/import/Starter-Theme.theme.json +94 -0
- package/test/e2e/theme/import/Zardoz.default.theme.json +95 -0
- package/test/fs_tmp/.gitkeep +2 -0
- package/test/global/setup.js +65 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { printMessage } from './utils/Console.js';
|
|
2
|
+
import { getCurrentTimestamp } from './utils/ExportImportUtils.js';
|
|
3
|
+
import {
|
|
4
|
+
createAPIKeyAndSecret,
|
|
5
|
+
getAPIKeys,
|
|
6
|
+
getSources,
|
|
7
|
+
} from '../api/LogApi.js';
|
|
8
|
+
|
|
9
|
+
import storage from '../storage/SessionStorage.js';
|
|
10
|
+
|
|
11
|
+
import * as LogApi from '../api/LogApi.js';
|
|
12
|
+
|
|
13
|
+
const unfilterableNoise = [
|
|
14
|
+
'text/plain' // Unfortunately, it is impossible to filter out those without excluding IDM script logging as well
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
const miscNoise = [
|
|
18
|
+
'com.iplanet.dpro.session.operations.ServerSessionOperationStrategy',
|
|
19
|
+
'com.iplanet.dpro.session.SessionIDFactory',
|
|
20
|
+
'com.iplanet.dpro.session.share.SessionEncodeURL',
|
|
21
|
+
'com.iplanet.services.naming.WebtopNaming',
|
|
22
|
+
'com.iplanet.sso.providers.dpro.SSOProviderImpl',
|
|
23
|
+
'com.sun.identity.authentication.AuthContext',
|
|
24
|
+
'com.sun.identity.authentication.client.AuthClientUtils',
|
|
25
|
+
'com.sun.identity.authentication.config.AMAuthConfigType',
|
|
26
|
+
'com.sun.identity.authentication.config.AMAuthenticationManager',
|
|
27
|
+
'com.sun.identity.authentication.config.AMAuthLevelManager',
|
|
28
|
+
'com.sun.identity.authentication.config.AMConfiguration',
|
|
29
|
+
'com.sun.identity.authentication.jaas.LoginContext',
|
|
30
|
+
'com.sun.identity.authentication.modules.application.Application',
|
|
31
|
+
'com.sun.identity.authentication.server.AuthContextLocal',
|
|
32
|
+
'com.sun.identity.authentication.service.AMLoginContext',
|
|
33
|
+
'com.sun.identity.authentication.service.AuthContextLookup',
|
|
34
|
+
'com.sun.identity.authentication.service.AuthD',
|
|
35
|
+
'com.sun.identity.authentication.service.AuthUtils',
|
|
36
|
+
'com.sun.identity.authentication.service.DSAMECallbackHandler',
|
|
37
|
+
'com.sun.identity.authentication.service.LoginState',
|
|
38
|
+
'com.sun.identity.authentication.spi.AMLoginModule',
|
|
39
|
+
'com.sun.identity.delegation.DelegationEvaluatorImpl',
|
|
40
|
+
'com.sun.identity.idm.plugins.internal.AgentsRepo',
|
|
41
|
+
'com.sun.identity.idm.server.IdCachedServicesImpl',
|
|
42
|
+
'com.sun.identity.idm.server.IdRepoPluginsCache',
|
|
43
|
+
'com.sun.identity.idm.server.IdServicesImpl',
|
|
44
|
+
'com.sun.identity.log.spi.ISDebug',
|
|
45
|
+
'com.sun.identity.shared.encode.CookieUtils',
|
|
46
|
+
'com.sun.identity.sm.ldap.SMSLdapObject',
|
|
47
|
+
'com.sun.identity.sm.CachedSMSEntry',
|
|
48
|
+
'com.sun.identity.sm.CachedSubEntries',
|
|
49
|
+
'com.sun.identity.sm.DNMapper',
|
|
50
|
+
'com.sun.identity.sm.ServiceConfigImpl',
|
|
51
|
+
'com.sun.identity.sm.ServiceConfigManagerImpl',
|
|
52
|
+
'com.sun.identity.sm.SMSEntry',
|
|
53
|
+
'com.sun.identity.sm.SMSUtils',
|
|
54
|
+
'com.sun.identity.sm.SmsWrapperObject',
|
|
55
|
+
'oauth2',
|
|
56
|
+
'org.apache.http.client.protocol.RequestAuthCache',
|
|
57
|
+
'org.apache.http.impl.conn.PoolingHttpClientConnectionManager',
|
|
58
|
+
'org.apache.http.impl.nio.client.InternalHttpAsyncClient',
|
|
59
|
+
'org.apache.http.impl.nio.client.InternalIODispatch',
|
|
60
|
+
'org.apache.http.impl.nio.client.MainClientExec',
|
|
61
|
+
'org.apache.http.impl.nio.conn.ManagedNHttpClientConnectionImpl',
|
|
62
|
+
'org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager',
|
|
63
|
+
'org.forgerock.audit.AuditServiceImpl',
|
|
64
|
+
'org.forgerock.oauth2.core.RealmOAuth2ProviderSettings',
|
|
65
|
+
'org.forgerock.openam.authentication.service.JAASModuleDetector',
|
|
66
|
+
'org.forgerock.openam.authentication.service.LoginContextFactory',
|
|
67
|
+
'org.forgerock.openam.blacklist.BloomFilterBlacklist',
|
|
68
|
+
'org.forgerock.openam.blacklist.CTSBlacklist',
|
|
69
|
+
'org.forgerock.openam.core.realms.impl.CachingRealmLookup',
|
|
70
|
+
'org.forgerock.openam.core.rest.authn.RestAuthCallbackHandlerManager',
|
|
71
|
+
'org.forgerock.openam.core.rest.authn.trees.AuthTrees',
|
|
72
|
+
'org.forgerock.openam.cors.CorsFilter',
|
|
73
|
+
'org.forgerock.openam.cts.CTSPersistentStoreImpl',
|
|
74
|
+
'org.forgerock.openam.cts.impl.CoreTokenAdapter',
|
|
75
|
+
'org.forgerock.openam.cts.impl.queue.AsyncResultHandler',
|
|
76
|
+
'org.forgerock.openam.cts.reaper.ReaperDeleteOnQueryResultHandler',
|
|
77
|
+
'org.forgerock.openam.headers.DisableSameSiteCookiesFilter',
|
|
78
|
+
'org.forgerock.openam.idrepo.ldap.DJLDAPv3Repo',
|
|
79
|
+
'org.forgerock.openam.rest.CsrfFilter',
|
|
80
|
+
'org.forgerock.openam.rest.restAuthenticationFilter',
|
|
81
|
+
'org.forgerock.openam.rest.fluent.CrestLoggingFilter',
|
|
82
|
+
'org.forgerock.openam.session.cts.CtsOperations',
|
|
83
|
+
'org.forgerock.openam.session.stateless.StatelessSessionManager',
|
|
84
|
+
'org.forgerock.openam.sm.datalayer.impl.ldap.ExternalLdapConfig',
|
|
85
|
+
'org.forgerock.openam.sm.datalayer.impl.ldap.LdapQueryBuilder',
|
|
86
|
+
'org.forgerock.openam.sm.datalayer.impl.SeriesTaskExecutor',
|
|
87
|
+
'org.forgerock.openam.sm.datalayer.impl.SeriesTaskExecutorThread',
|
|
88
|
+
'org.forgerock.openam.sm.datalayer.providers.LdapConnectionFactoryProvider',
|
|
89
|
+
'org.forgerock.openam.sm.file.ConfigFileSystemHandler',
|
|
90
|
+
'org.forgerock.openam.social.idp.SocialIdentityProviders',
|
|
91
|
+
'org.forgerock.openam.utils.ClientUtils',
|
|
92
|
+
'org.forgerock.opendj.ldap.CachedConnectionPool',
|
|
93
|
+
'org.forgerock.opendj.ldap.LoadBalancer',
|
|
94
|
+
'org.forgerock.secrets.keystore.KeyStoreSecretStore',
|
|
95
|
+
'org.forgerock.secrets.propertyresolver.PropertyResolverSecretStore',
|
|
96
|
+
'org.forgerock.secrets.SecretsProvider',
|
|
97
|
+
];
|
|
98
|
+
|
|
99
|
+
const journeysNoise = [
|
|
100
|
+
'org.forgerock.openam.auth.trees.engine.AuthTreeExecutor',
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
// eslint-disable-next-line no-unused-vars
|
|
104
|
+
const journeys = [
|
|
105
|
+
'org.forgerock.openam.auth.nodes.SelectIdPNode',
|
|
106
|
+
'org.forgerock.openam.auth.nodes.ValidatedPasswordNode',
|
|
107
|
+
'org.forgerock.openam.auth.nodes.ValidatedUsernameNode',
|
|
108
|
+
'org.forgerock.openam.auth.trees.engine.AuthTreeExecutor',
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
const samlNoise = [
|
|
112
|
+
'com.sun.identity.cot.COTCache',
|
|
113
|
+
'com.sun.identity.plugin.configuration.impl.ConfigurationInstanceImpl',
|
|
114
|
+
'com.sun.identity.saml2.meta.SAML2MetaCache',
|
|
115
|
+
'com.sun.identity.saml2.profile.CacheCleanUpRunnable',
|
|
116
|
+
'org.apache.xml.security.keys.KeyInfo',
|
|
117
|
+
'org.apache.xml.security.signature.XMLSignature',
|
|
118
|
+
'org.apache.xml.security.utils.SignerOutputStream',
|
|
119
|
+
'org.apache.xml.security.utils.resolver.ResourceResolver',
|
|
120
|
+
'org.apache.xml.security.utils.resolver.implementations.ResolverFragment',
|
|
121
|
+
'org.apache.xml.security.algorithms.JCEMapper',
|
|
122
|
+
'org.apache.xml.security.algorithms.implementations.SignatureBaseRSA',
|
|
123
|
+
'org.apache.xml.security.algorithms.SignatureAlgorithm',
|
|
124
|
+
'org.apache.xml.security.utils.ElementProxy',
|
|
125
|
+
'org.apache.xml.security.transforms.Transforms',
|
|
126
|
+
'org.apache.xml.security.utils.DigesterOutputStream',
|
|
127
|
+
'org.apache.xml.security.signature.Reference',
|
|
128
|
+
'org.apache.xml.security.signature.Manifest',
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
// eslint-disable-next-line no-unused-vars
|
|
132
|
+
const saml = [
|
|
133
|
+
'jsp.saml2.spAssertionConsumer',
|
|
134
|
+
'com.sun.identity.saml.common.SAMLUtils',
|
|
135
|
+
'com.sun.identity.saml2.common.SAML2Utils',
|
|
136
|
+
'com.sun.identity.saml2.meta.SAML2MetaManager',
|
|
137
|
+
'com.sun.identity.saml2.xmlsig.FMSigProvider',
|
|
138
|
+
];
|
|
139
|
+
|
|
140
|
+
const noise = miscNoise.concat(samlNoise).concat(journeysNoise);
|
|
141
|
+
|
|
142
|
+
const numLogLevelMap = {
|
|
143
|
+
0: ['SEVERE', 'ERROR', 'FATAL'],
|
|
144
|
+
1: ['WARNING', 'WARN', 'CONFIG'],
|
|
145
|
+
2: ['INFO', 'INFORMATION'],
|
|
146
|
+
3: ['DEBUG', 'FINE', 'FINER', 'FINEST'],
|
|
147
|
+
4: ['ALL'],
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const logLevelMap = {
|
|
151
|
+
SEVERE: ['SEVERE', 'ERROR', 'FATAL'],
|
|
152
|
+
ERROR: ['SEVERE', 'ERROR', 'FATAL'],
|
|
153
|
+
FATAL: ['SEVERE', 'ERROR', 'FATAL'],
|
|
154
|
+
WARN: ['SEVERE', 'ERROR', 'FATAL', 'WARNING', 'WARN', 'CONFIG'],
|
|
155
|
+
WARNING: ['SEVERE', 'ERROR', 'FATAL', 'WARNING', 'WARN', 'CONFIG'],
|
|
156
|
+
CONFIG: ['SEVERE', 'ERROR', 'FATAL', 'WARNING', 'WARN', 'CONFIG'],
|
|
157
|
+
INFO: [
|
|
158
|
+
'SEVERE',
|
|
159
|
+
'ERROR',
|
|
160
|
+
'FATAL',
|
|
161
|
+
'WARNING',
|
|
162
|
+
'WARN',
|
|
163
|
+
'CONFIG',
|
|
164
|
+
'INFO',
|
|
165
|
+
'INFORMATION',
|
|
166
|
+
],
|
|
167
|
+
INFORMATION: [
|
|
168
|
+
'SEVERE',
|
|
169
|
+
'ERROR',
|
|
170
|
+
'FATAL',
|
|
171
|
+
'WARNING',
|
|
172
|
+
'WARN',
|
|
173
|
+
'CONFIG',
|
|
174
|
+
'INFO',
|
|
175
|
+
'INFORMATION',
|
|
176
|
+
],
|
|
177
|
+
DEBUG: [
|
|
178
|
+
'SEVERE',
|
|
179
|
+
'ERROR',
|
|
180
|
+
'FATAL',
|
|
181
|
+
'WARNING',
|
|
182
|
+
'WARN',
|
|
183
|
+
'CONFIG',
|
|
184
|
+
'INFO',
|
|
185
|
+
'INFORMATION',
|
|
186
|
+
'DEBUG',
|
|
187
|
+
'FINE',
|
|
188
|
+
'FINER',
|
|
189
|
+
'FINEST',
|
|
190
|
+
],
|
|
191
|
+
FINE: [
|
|
192
|
+
'SEVERE',
|
|
193
|
+
'ERROR',
|
|
194
|
+
'FATAL',
|
|
195
|
+
'WARNING',
|
|
196
|
+
'WARN',
|
|
197
|
+
'CONFIG',
|
|
198
|
+
'INFO',
|
|
199
|
+
'INFORMATION',
|
|
200
|
+
'DEBUG',
|
|
201
|
+
'FINE',
|
|
202
|
+
'FINER',
|
|
203
|
+
'FINEST',
|
|
204
|
+
],
|
|
205
|
+
FINER: [
|
|
206
|
+
'SEVERE',
|
|
207
|
+
'ERROR',
|
|
208
|
+
'FATAL',
|
|
209
|
+
'WARNING',
|
|
210
|
+
'WARN',
|
|
211
|
+
'CONFIG',
|
|
212
|
+
'INFO',
|
|
213
|
+
'INFORMATION',
|
|
214
|
+
'DEBUG',
|
|
215
|
+
'FINE',
|
|
216
|
+
'FINER',
|
|
217
|
+
'FINEST',
|
|
218
|
+
],
|
|
219
|
+
FINEST: [
|
|
220
|
+
'SEVERE',
|
|
221
|
+
'ERROR',
|
|
222
|
+
'FATAL',
|
|
223
|
+
'WARNING',
|
|
224
|
+
'WARN',
|
|
225
|
+
'CONFIG',
|
|
226
|
+
'INFO',
|
|
227
|
+
'INFORMATION',
|
|
228
|
+
'DEBUG',
|
|
229
|
+
'FINE',
|
|
230
|
+
'FINER',
|
|
231
|
+
'FINEST',
|
|
232
|
+
],
|
|
233
|
+
ALL: ['ALL'],
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
export function resolveLevel(level) {
|
|
237
|
+
// const levels = ['FATAL', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL'];
|
|
238
|
+
// levels.splice(levels.indexOf(levelName) + 1, levels.length);
|
|
239
|
+
if (Number.isNaN(parseInt(level, 10))) {
|
|
240
|
+
return logLevelMap[level];
|
|
241
|
+
}
|
|
242
|
+
return logLevelMap[numLogLevelMap[level][0]];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// It seems that the undesirable 'text/plain' logs start with a date, not a LEVEL
|
|
246
|
+
// Therefore, for those, this function returns null, and thus filters out the undesirable
|
|
247
|
+
export function resolvePayloadLevel(log) {
|
|
248
|
+
try {
|
|
249
|
+
return log.type !== 'text/plain' ? log.payload.level : log.payload.match(/^([^:]*):/)[1];
|
|
250
|
+
} catch (e) { // Fail-safe for no group match
|
|
251
|
+
return null
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export async function getLogSources() {
|
|
256
|
+
const sources = [];
|
|
257
|
+
await getSources()
|
|
258
|
+
.then((response) => {
|
|
259
|
+
response.data.result.forEach((item) => {
|
|
260
|
+
sources.push(item);
|
|
261
|
+
});
|
|
262
|
+
})
|
|
263
|
+
.catch((error) => {
|
|
264
|
+
printMessage(
|
|
265
|
+
`getSources ERROR: get log sources call returned ${error}}`,
|
|
266
|
+
'error'
|
|
267
|
+
);
|
|
268
|
+
return [];
|
|
269
|
+
});
|
|
270
|
+
return sources;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export async function tailLogs(source, levels, txid, cookie) {
|
|
274
|
+
try {
|
|
275
|
+
const response = await LogApi.tail(source, cookie);
|
|
276
|
+
if (response.status < 200 || response.status > 399) {
|
|
277
|
+
printMessage(
|
|
278
|
+
`tail ERROR: tail call returned ${response.status}`,
|
|
279
|
+
'error'
|
|
280
|
+
);
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
// if (!cookie) {
|
|
284
|
+
// await saveConnection();
|
|
285
|
+
// }
|
|
286
|
+
const logsObject = response.data;
|
|
287
|
+
let filteredLogs = [];
|
|
288
|
+
if (Array.isArray(logsObject.result)) {
|
|
289
|
+
filteredLogs = logsObject.result.filter(
|
|
290
|
+
(el) =>
|
|
291
|
+
!noise.includes(el.payload.logger) &&
|
|
292
|
+
!noise.includes(el.type) &&
|
|
293
|
+
(levels[0] === 'ALL' || levels.includes(resolvePayloadLevel(el))) &&
|
|
294
|
+
(typeof txid === 'undefined' ||
|
|
295
|
+
txid === null ||
|
|
296
|
+
el.payload.transactionId.includes(txid))
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
filteredLogs.forEach((e) => {
|
|
301
|
+
printMessage(JSON.stringify(e.payload), 'data');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
setTimeout(() => {
|
|
305
|
+
tailLogs(source, levels, txid, logsObject.result.pagedResultsCookie);
|
|
306
|
+
}, 5000);
|
|
307
|
+
return null;
|
|
308
|
+
} catch (e) {
|
|
309
|
+
printMessage(`tail ERROR: tail data error - ${e}`, 'error');
|
|
310
|
+
return `tail ERROR: tail data error - ${e}`;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export async function provisionCreds() {
|
|
315
|
+
try {
|
|
316
|
+
let keyName = `frodo-${storage.session.getUsername()}`;
|
|
317
|
+
return getAPIKeys()
|
|
318
|
+
.then((response) => {
|
|
319
|
+
response.data.result.forEach((k) => {
|
|
320
|
+
if (k.name === keyName) {
|
|
321
|
+
// append current timestamp to name if the named key already exists
|
|
322
|
+
keyName = `${keyName}-${getCurrentTimestamp()}`;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
return createAPIKeyAndSecret(keyName)
|
|
326
|
+
.then((resp) => {
|
|
327
|
+
if (resp.data.name !== keyName) {
|
|
328
|
+
printMessage(
|
|
329
|
+
`create keys ERROR: could not create log API key ${keyName}`,
|
|
330
|
+
'error'
|
|
331
|
+
);
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
printMessage(
|
|
335
|
+
`Created a new log API key [${keyName}] in ${storage.session.getTenant()}`
|
|
336
|
+
);
|
|
337
|
+
return resp.data;
|
|
338
|
+
})
|
|
339
|
+
.catch((error) => {
|
|
340
|
+
printMessage(
|
|
341
|
+
`create keys ERROR: create keys call returned ${error}`,
|
|
342
|
+
'error'
|
|
343
|
+
);
|
|
344
|
+
return null;
|
|
345
|
+
});
|
|
346
|
+
})
|
|
347
|
+
.catch((error) => {
|
|
348
|
+
printMessage(
|
|
349
|
+
`get keys ERROR: get keys call returned ${error}`,
|
|
350
|
+
'error'
|
|
351
|
+
);
|
|
352
|
+
});
|
|
353
|
+
} catch (e) {
|
|
354
|
+
printMessage(`create keys ERROR: create keys data error - ${e}`, 'error');
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getManagedObject } from '../api/ManagedObjectApi.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a managed object's uuid to a human readable username
|
|
5
|
+
* @param {String} type managed object type, e.g. teammember or alpha_user
|
|
6
|
+
* @param {String} id managed object _id
|
|
7
|
+
* @returns {String} resolved username or uuid if any error occurs during reslution
|
|
8
|
+
*/
|
|
9
|
+
export async function resolveUserName(type, id) {
|
|
10
|
+
try {
|
|
11
|
+
return (await getManagedObject(type, id, ['userName'])).data.userName;
|
|
12
|
+
} catch (error) {
|
|
13
|
+
// eslint-disable-next-line no-empty
|
|
14
|
+
}
|
|
15
|
+
return id;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a managed object's uuid to a human readable full name
|
|
20
|
+
* @param {String} type managed object type, e.g. teammember or alpha_user
|
|
21
|
+
* @param {String} id managed object _id
|
|
22
|
+
* @returns {String} resolved full name or uuid if any error occurs during reslution
|
|
23
|
+
*/
|
|
24
|
+
export async function resolveFullName(type, id) {
|
|
25
|
+
try {
|
|
26
|
+
const managedObject = (
|
|
27
|
+
await getManagedObject(type, id, ['givenName', 'sn'])
|
|
28
|
+
).data;
|
|
29
|
+
return `${managedObject.givenName} ${managedObject.sn}`;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
// eslint-disable-next-line no-empty
|
|
32
|
+
}
|
|
33
|
+
return id;
|
|
34
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { createTable, printMessage } from './utils/Console.js';
|
|
3
|
+
import {
|
|
4
|
+
getTypedFilename,
|
|
5
|
+
saveToFile,
|
|
6
|
+
titleCase,
|
|
7
|
+
validateImport,
|
|
8
|
+
} from './utils/ExportImportUtils.js';
|
|
9
|
+
import storage from '../storage/SessionStorage.js';
|
|
10
|
+
import {
|
|
11
|
+
getOAuth2Client,
|
|
12
|
+
getOAuth2Clients,
|
|
13
|
+
putOAuth2Client,
|
|
14
|
+
} from '../api/OAuth2ClientApi.js';
|
|
15
|
+
import { getOAuth2Provider } from '../api/OAuth2ProviderApi.js';
|
|
16
|
+
import { getRealmName } from '../api/utils/ApiUtils.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* List OAuth2 clients
|
|
20
|
+
*/
|
|
21
|
+
export async function listOAuth2Clients(long = false) {
|
|
22
|
+
try {
|
|
23
|
+
const clients = (await getOAuth2Clients()).data.result;
|
|
24
|
+
clients.sort((a, b) => a._id.localeCompare(b._id));
|
|
25
|
+
if (long) {
|
|
26
|
+
const table = createTable([
|
|
27
|
+
'Client Id',
|
|
28
|
+
'Status',
|
|
29
|
+
'Client Type',
|
|
30
|
+
'Grant Types',
|
|
31
|
+
'Scopes',
|
|
32
|
+
'Redirect URIs',
|
|
33
|
+
// 'Description',
|
|
34
|
+
]);
|
|
35
|
+
const grantTypesMap = {
|
|
36
|
+
authorization_code: 'Authz Code',
|
|
37
|
+
client_credentials: 'Client Creds',
|
|
38
|
+
refresh_token: 'Refresh Token',
|
|
39
|
+
password: 'ROPC',
|
|
40
|
+
'urn:ietf:params:oauth:grant-type:uma-ticket': 'UMA',
|
|
41
|
+
implicit: 'Implicit',
|
|
42
|
+
'urn:ietf:params:oauth:grant-type:device_code': 'Device Code',
|
|
43
|
+
'urn:ietf:params:oauth:grant-type:saml2-bearer': 'SAML2 Bearer',
|
|
44
|
+
'urn:openid:params:grant-type:ciba': 'CIBA',
|
|
45
|
+
'urn:ietf:params:oauth:grant-type:token-exchange': 'Token Exchange',
|
|
46
|
+
'urn:ietf:params:oauth:grant-type:jwt-bearer': 'JWT Bearer',
|
|
47
|
+
};
|
|
48
|
+
clients.forEach((client) => {
|
|
49
|
+
table.push([
|
|
50
|
+
client._id,
|
|
51
|
+
client.coreOAuth2ClientConfig.status === 'Active'
|
|
52
|
+
? 'Active'.brightGreen
|
|
53
|
+
: client.coreOAuth2ClientConfig.status.brightRed,
|
|
54
|
+
client.coreOAuth2ClientConfig.clientType,
|
|
55
|
+
client.advancedOAuth2ClientConfig.grantTypes
|
|
56
|
+
.map((type) => grantTypesMap[type])
|
|
57
|
+
.join('\n'),
|
|
58
|
+
client.coreOAuth2ClientConfig.scopes.join('\n'),
|
|
59
|
+
client.coreOAuth2ClientConfig.redirectionUris.join('\n'),
|
|
60
|
+
// wordwrap(client.description, 30),
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
printMessage(table.toString(), 'data');
|
|
64
|
+
} else {
|
|
65
|
+
clients.forEach((client) => {
|
|
66
|
+
printMessage(`${client._id}`, 'data');
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
printMessage(`Error listing scripts - ${error}`, 'error');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Export OAuth2 client to file
|
|
76
|
+
* @param {String} id client id
|
|
77
|
+
* @param {String} file file name
|
|
78
|
+
*/
|
|
79
|
+
export async function exportOAuth2ClientToFile(id, file) {
|
|
80
|
+
let fileName = getTypedFilename(id, 'oauth2.app');
|
|
81
|
+
if (file) {
|
|
82
|
+
fileName = file;
|
|
83
|
+
}
|
|
84
|
+
const oauth2Service = (await getOAuth2Provider()).data;
|
|
85
|
+
const client = (await getOAuth2Client(id)).data;
|
|
86
|
+
client._provider = oauth2Service;
|
|
87
|
+
saveToFile('application', [client], '_id', fileName);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Export all OAuth2 clients to file
|
|
92
|
+
* @param {String} file file name
|
|
93
|
+
*/
|
|
94
|
+
export async function exportOAuth2ClientsToFile(file) {
|
|
95
|
+
let fileName = getTypedFilename(
|
|
96
|
+
`all${titleCase(getRealmName(storage.session.getRealm()))}Applications`,
|
|
97
|
+
'oauth2.app'
|
|
98
|
+
);
|
|
99
|
+
if (file) {
|
|
100
|
+
fileName = file;
|
|
101
|
+
}
|
|
102
|
+
const oauth2Service = (await getOAuth2Provider()).data;
|
|
103
|
+
const clients = (await getOAuth2Clients()).data.result;
|
|
104
|
+
const exportData = [];
|
|
105
|
+
for (const client of clients) {
|
|
106
|
+
client._provider = oauth2Service;
|
|
107
|
+
exportData.push(client);
|
|
108
|
+
}
|
|
109
|
+
saveToFile('application', exportData, '_id', fileName);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Export all OAuth2 clients to separate files
|
|
114
|
+
*/
|
|
115
|
+
export async function exportOAuth2ClientsToFiles() {
|
|
116
|
+
const oauth2Service = (await getOAuth2Provider()).data;
|
|
117
|
+
const clients = (await getOAuth2Clients()).data.result;
|
|
118
|
+
for (const client of clients) {
|
|
119
|
+
client._provider = oauth2Service;
|
|
120
|
+
const fileName = getTypedFilename(client._id, 'oauth2.app');
|
|
121
|
+
saveToFile('application', [client], '_id', fileName);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Import OAuth2 clients from file
|
|
127
|
+
* @param {String} file file name
|
|
128
|
+
*/
|
|
129
|
+
export async function importOAuth2ClientsFromFile(file) {
|
|
130
|
+
fs.readFile(file, 'utf8', (err, data) => {
|
|
131
|
+
if (err) throw err;
|
|
132
|
+
const applicationData = JSON.parse(data);
|
|
133
|
+
if (validateImport(applicationData.meta)) {
|
|
134
|
+
for (const id in applicationData.application) {
|
|
135
|
+
if (
|
|
136
|
+
Object.prototype.hasOwnProperty.call(applicationData.application, id)
|
|
137
|
+
) {
|
|
138
|
+
delete applicationData.application[id]._provider;
|
|
139
|
+
delete applicationData.application[id]._rev;
|
|
140
|
+
putOAuth2Client(id, applicationData.application[id]).then(
|
|
141
|
+
(result) => {
|
|
142
|
+
if (!result == null) printMessage(`Imported ${id}`);
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
printMessage('Import validation failed...', 'error');
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { queryAllManagedObjectsByType } from '../api/IdmConfigApi.js';
|
|
2
|
+
import storage from '../storage/SessionStorage.js';
|
|
3
|
+
import { printMessage } from './utils/Console.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get organization managed object type
|
|
7
|
+
* @returns {String} organization managed object type in this realm
|
|
8
|
+
*/
|
|
9
|
+
export function getRealmManagedOrganization() {
|
|
10
|
+
let realmManagedOrg = 'organization';
|
|
11
|
+
if (
|
|
12
|
+
storage.session.getDeploymentType() === global.CLOUD_DEPLOYMENT_TYPE_KEY
|
|
13
|
+
) {
|
|
14
|
+
realmManagedOrg = `${storage.session.getRealm()}_organization`;
|
|
15
|
+
}
|
|
16
|
+
return realmManagedOrg;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get organizations
|
|
21
|
+
* @returns {Promise} promise resolving to an object containing an array of organization objects
|
|
22
|
+
*/
|
|
23
|
+
export async function getOrganizations() {
|
|
24
|
+
const orgs = [];
|
|
25
|
+
let result = {
|
|
26
|
+
result: [],
|
|
27
|
+
resultCount: 0,
|
|
28
|
+
pagedResultsCookie: null,
|
|
29
|
+
totalPagedResultsPolicy: 'NONE',
|
|
30
|
+
totalPagedResults: -1,
|
|
31
|
+
remainingPagedResults: -1,
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
do {
|
|
35
|
+
// eslint-disable-next-line no-await-in-loop
|
|
36
|
+
result = await queryAllManagedObjectsByType(
|
|
37
|
+
getRealmManagedOrganization(),
|
|
38
|
+
['name', 'parent/*/name', 'children/*/name'],
|
|
39
|
+
result.pagedResultsCookie
|
|
40
|
+
).catch((queryAllManagedObjectsByTypeError) => {
|
|
41
|
+
printMessage(queryAllManagedObjectsByTypeError, 'error');
|
|
42
|
+
printMessage(
|
|
43
|
+
`Error querying ${getRealmManagedOrganization()} objects: ${queryAllManagedObjectsByTypeError}`,
|
|
44
|
+
'error'
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
orgs.concat(result.result);
|
|
48
|
+
printMessage('.', 'text', false);
|
|
49
|
+
} while (result.pagedResultsCookie);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
printMessage(error.response.data, 'error');
|
|
52
|
+
printMessage(`Error retrieving all organizations: ${error}`, 'error');
|
|
53
|
+
}
|
|
54
|
+
return orgs;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// unfinished work
|
|
58
|
+
export async function listOrganizationsTopDown() {
|
|
59
|
+
const orgs = [];
|
|
60
|
+
let result = {
|
|
61
|
+
result: [],
|
|
62
|
+
resultCount: 0,
|
|
63
|
+
pagedResultsCookie: null,
|
|
64
|
+
totalPagedResultsPolicy: 'NONE',
|
|
65
|
+
totalPagedResults: -1,
|
|
66
|
+
remainingPagedResults: -1,
|
|
67
|
+
};
|
|
68
|
+
do {
|
|
69
|
+
// eslint-disable-next-line no-await-in-loop
|
|
70
|
+
result = await queryAllManagedObjectsByType(
|
|
71
|
+
getRealmManagedOrganization(),
|
|
72
|
+
['name', 'parent/*/name', 'children/*/name'],
|
|
73
|
+
result.pagedResultsCookie
|
|
74
|
+
).catch((queryAllManagedObjectsByTypeError) => {
|
|
75
|
+
printMessage(queryAllManagedObjectsByTypeError, 'error');
|
|
76
|
+
printMessage(
|
|
77
|
+
`Error querying ${getRealmManagedOrganization()} objects: ${queryAllManagedObjectsByTypeError}`,
|
|
78
|
+
'error'
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
orgs.concat(result.result);
|
|
82
|
+
printMessage('.', 'text', false);
|
|
83
|
+
} while (result.pagedResultsCookie);
|
|
84
|
+
return orgs;
|
|
85
|
+
}
|