@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,96 @@
|
|
|
1
|
+
# Contribute to frodo
|
|
2
|
+
Any direct commits to the repository are not allowed. Pull requests (PR) are most welcome. Please fork this repo and develop and test in that fork. Once you feel ready, please create a PR. For any major changes, please open an [issue](https://github.com/rockcarver/frodo/issues) first to discuss what and why you'd like to change.
|
|
3
|
+
|
|
4
|
+
## Developing
|
|
5
|
+
### Forking this repo
|
|
6
|
+
Please refer to these couple of excellent resources for getting started with forking the repo and contributing to github open source projects in general. These are great reads not only for someone new to this, even regular github contributors may find some great tidbits of information.
|
|
7
|
+
|
|
8
|
+
- [https://github.com/firstcontributions/first-contributions](https://github.com/firstcontributions/first-contributions)
|
|
9
|
+
Also take a look at [Additional material](https://github.com/firstcontributions/first-contributions/blob/master/additional-material/git_workflow_scenarios/additional-material.md) towards the end, as there are some good tips on that page.
|
|
10
|
+
|
|
11
|
+
OR
|
|
12
|
+
|
|
13
|
+
- [https://www.dataschool.io/how-to-contribute-on-github/](https://www.dataschool.io/how-to-contribute-on-github/)
|
|
14
|
+
|
|
15
|
+
### Prerequisites
|
|
16
|
+
- Node.js 18 (used by developers) or newer
|
|
17
|
+
- npm (included with Node.js)
|
|
18
|
+
- A GUI editor is highly recommended. The current developers use [VSCode](https://code.visualstudio.com/), but you are welcome to others, like [Atom](https://atom.io/) or [Sublime](https://www.sublimetext.com/) too. The repository contains configuration files for VSCode's [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and [prettier](https://prettier.io/) add-ons, which will automatically lint the code and apply coding styles when using VSCode. The same files may work for other editors with similar add-ons, but this has not been tested.
|
|
19
|
+
|
|
20
|
+
### Build
|
|
21
|
+
To build locally we need to do a couple of extra steps due to a limitation with the `pkg` module we're using to distribute binaries. `pkg` [doesn't support ES6](https://github.com/vercel/pkg/issues/1291) modules as of yet, so we have to transpile to commonJS then build.
|
|
22
|
+
|
|
23
|
+
There should be a `dist` folder when you cloned the repo from Github, the binaries will get pushed there. We're using a `gulp` script to transpile ES6 module to commonJS and then `pkg` can create the binary for the respective OS. For Mac OS you'll have to sign the binary
|
|
24
|
+
|
|
25
|
+
#### For windows and Linux
|
|
26
|
+
|
|
27
|
+
```console
|
|
28
|
+
cd $HOME/frodo
|
|
29
|
+
npm install
|
|
30
|
+
npm install -g pkg gulp
|
|
31
|
+
gulp
|
|
32
|
+
cd ./dist
|
|
33
|
+
npm i
|
|
34
|
+
#For Windows
|
|
35
|
+
pkg -C Gzip -t node16-win-x64 --out-path bin/win .
|
|
36
|
+
#For Linux
|
|
37
|
+
pkg -C Gzip -t node16-linux-x64 --out-path bin/linux .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### For MacOS
|
|
41
|
+
|
|
42
|
+
For MacOS we need to sign the binaries with an Apple Developer Cert.
|
|
43
|
+
|
|
44
|
+
```console
|
|
45
|
+
# create variables
|
|
46
|
+
CERTIFICATE_PATH=<YOUR_CERTIFICATE_PATH>
|
|
47
|
+
INTERMEDIATE_CERTIFICATE_PATH=<YOUR_INTERMEDIATE_CERTIFICATE_PATH>
|
|
48
|
+
KEYCHAIN_PATH=<YOUR_TEMP_KEYCHAIN_PATH>
|
|
49
|
+
KEYCHAIN_PASSWORD=<KEY_CHAIN_PASSWORD>
|
|
50
|
+
DEVELOPMENT_CERTIFICATE_PASSPHRASE=<YOUR_CERT_PASSPHRASE>
|
|
51
|
+
|
|
52
|
+
#create temp keychain
|
|
53
|
+
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
54
|
+
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
|
|
55
|
+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
56
|
+
|
|
57
|
+
#import certs to keychain
|
|
58
|
+
security import $CERTIFICATE_PATH -P "$DEVELOPMENT_CERTIFICATE_PASSPHRASE" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
|
|
59
|
+
security import $INTERMEDIATE_CERTIFICATE_PATH -P "$DEVELOPMENT_CERTIFICATE_PASSPHRASE" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
|
|
60
|
+
security list-keychain -d user -s $KEYCHAIN_PATH
|
|
61
|
+
|
|
62
|
+
# import certificate to keychain
|
|
63
|
+
security import $CERTIFICATE_PATH -P "$DEVELOPMENT_CERTIFICATE_PASSPHRASE" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
|
|
64
|
+
security import $INTERMEDIATE_CERTIFICATE_PATH -P "$DEVELOPMENT_CERTIFICATE_PASSPHRASE" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
|
|
65
|
+
security list-keychain -d user -s $KEYCHAIN_PATH
|
|
66
|
+
|
|
67
|
+
cd $HOME/frodo
|
|
68
|
+
npm install
|
|
69
|
+
npm install -g pkg gulp
|
|
70
|
+
gulp
|
|
71
|
+
|
|
72
|
+
cd ./dist
|
|
73
|
+
npm i
|
|
74
|
+
pkg -C Gzip -t node16-macos-x64 --out-path bin/macos .
|
|
75
|
+
|
|
76
|
+
cd ./dist/bin/macos
|
|
77
|
+
codesign -f -s 'DEV_ID' --timestamp --deep frodo
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This will build `frodo` in each local directory respective to the OS target you chose
|
|
81
|
+
|
|
82
|
+
```console
|
|
83
|
+
./dist/bin/linux/frodo
|
|
84
|
+
./dist/bin/macos/frodo
|
|
85
|
+
./dist/bin/win/frodo
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Run
|
|
89
|
+
|
|
90
|
+
`frodo` is self contained, statically linked, so no dependencies should be needed. It can be run as:
|
|
91
|
+
|
|
92
|
+
```console
|
|
93
|
+
$HOME/frodo/frodo # or the platform equivalent binary
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
We recommend sourcing, or adding it to the path if you're on windows, to make it easier to call from your terminal without switching directories
|
package/docs/PIPELINE.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Frodo Release Pipeline
|
|
2
|
+
|
|
3
|
+
The Frodo project uses a fully automated release [pipeline](../.github/workflows/pipeline.yml) based on GitHub workflows:
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Releasing Frodo
|
|
8
|
+
|
|
9
|
+
This information is only actionable if you are an active contributor or maintainer with appropriate access to the repository and need to understand how frodo releases work.
|
|
10
|
+
|
|
11
|
+
### Every Push Triggers A Release
|
|
12
|
+
|
|
13
|
+
Frodo adopted the principle of continuous integration. Therefore every push to the main branch in the [rockcarver/frodo] repository trigger the automated release pipeline.
|
|
14
|
+
|
|
15
|
+
The pipeline determines the type of release - `prerelease`, `patch`, `minor`, `major` - for the push:
|
|
16
|
+
|
|
17
|
+
- Scans the commit and PR comments for trigger phrases:
|
|
18
|
+
- `PATCH RELEASE` triggers a `patch` release
|
|
19
|
+
- `MINOR RELEASE` triggers a `minor` release
|
|
20
|
+
- `MAJOR RELEASE` triggers a `major` release
|
|
21
|
+
- Everything else triggers a `prerelease`
|
|
22
|
+
- Bumps the version accordingly:<br>
|
|
23
|
+
`<major>`.`<minor>`.`<patch>`-`<prerelease>`
|
|
24
|
+
- Updates the [changelog](../CHANGELOG.md) file in [keep a changelog](https://keepachangelog.com/en/1.0.0/) format:
|
|
25
|
+
- Creates a new release heading using the bumped version and a date stamp
|
|
26
|
+
- Moves the content of the `Unreleased` section into the new section
|
|
27
|
+
- Adds release details links
|
|
28
|
+
|
|
29
|
+
❗❗❗ IMPORTANT ❗❗❗<br>
|
|
30
|
+
Contributors are instructed to submit pull requests. Maintainers must make sure none of the commit comments nor the PR comment contain trigger phrases that would cause the pipeline to perform an undesired version bump and release.
|
|
31
|
+
|
|
32
|
+
### Automatic Pre-Releases During Iterative Development
|
|
33
|
+
|
|
34
|
+
The default release type (if no specific and exact trigger phrases are used) results in a pre-release. Pre-releases are flagged with the label `Pre-release` on the [release page](../releases) indicating to users that these releases are not considered final or complete.
|
|
35
|
+
|
|
36
|
+
Pre-releases are a great way to get the latest and greatest functionality but they are not fully polished, readme and changelog might not be updated and test coverage might not be complete.
|
|
37
|
+
|
|
38
|
+
### Triggering Patch, Minor, and Major Releases
|
|
39
|
+
|
|
40
|
+
Maintainers must validate PRs contain an updated `Unreleased` section in the[changelog](../CHANGELOG.md) before merging any PR. Changelog entries must adhere to the [keep a changelog](https://keepachangelog.com/en/1.0.0/) format.
|
|
41
|
+
|
|
42
|
+
Maintainers must use an appropriate trigger phrase (see: [Every Push Triggers A Release](#Every-Push-Triggers-A-Release)) in the PR title to trigger the appropriate automated version bump and release.
|
|
43
|
+
|
|
44
|
+
❗❗❗ IMPORTANT ❗❗❗<br>
|
|
45
|
+
Maintainers must adhere to the [guidelines set forth by the npm project](https://docs.npmjs.com/about-semantic-versioning#incrementing-semantic-versions-in-published-packages) to determine the appropriate release type:
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
Frodo is currently in a pre-1.0.0 phase. We are striving to release 1.0.0 very soon.
|
|
50
|
+
|
|
51
|
+
## Current Pipeline Explained
|
|
52
|
+
|
|
53
|
+
### Trigger Event
|
|
54
|
+
|
|
55
|
+
The trigger event is any `push` to the `main` branch in the repository.
|
|
56
|
+
|
|
57
|
+
### Smoke Tests
|
|
58
|
+
|
|
59
|
+
This step performs a quick smoke test of the vital functions like login with and without network proxy. All smoke tests must pass or pipeline execution terminates.
|
|
60
|
+
|
|
61
|
+
### Update Changelog
|
|
62
|
+
|
|
63
|
+
This step calculates the new version but doesn't modify `package.json` and `package-lock.json`. Based on that new version, it creates a new heading in the [CHANGELOG.md](../CHANGELOG.md) file and moves everything from the `Unreleased` section into the new version section. It also creates links to the release tags at the bottom of the [CHANGELOG.md](../CHANGELOG.md) file. Last but not least, it commits the updated [CHANGELOG.md](../CHANGELOG.md) file to the repository.
|
|
64
|
+
|
|
65
|
+
#### 3rd-Party Actions
|
|
66
|
+
|
|
67
|
+
- [gh-action-bump-version](https://github.com/phips28/gh-action-bump-version): phips28/gh-action-bump-version@master
|
|
68
|
+
- [keep-a-changelog-new-release](https://github.com/thomaseizinger/keep-a-changelog-new-release): thomaseizinger/keep-a-changelog-new-release@1.3.0
|
|
69
|
+
|
|
70
|
+
### Bump Version
|
|
71
|
+
|
|
72
|
+
This step calculates the new version and corresponding tag, updates both [package.json](../package.json) and [package-lock.json](../package-lock.json) and commits the changes to the `main` branch.
|
|
73
|
+
|
|
74
|
+
#### 3rd-Party Actions
|
|
75
|
+
|
|
76
|
+
- [gh-action-bump-version](https://github.com/phips28/gh-action-bump-version): phips28/gh-action-bump-version@master
|
|
77
|
+
|
|
78
|
+
### Release Notes
|
|
79
|
+
|
|
80
|
+
This step extracts the changes under the heading that matches the release version and uses it as the release notes. For pre-releases it also generates a section of changes based on commits that were part of the release.
|
|
81
|
+
|
|
82
|
+
Good release notes require the contributor and/or maintainer take the time and update the [CHANGELOG.md](../CHANGELOG.md) file. Auto-generated release notes based on commit comments are less than optimal but acceptable for pre-releases.
|
|
83
|
+
|
|
84
|
+
Patch, minor, and major releases require a carefully curated [CHANGELOG.md](../CHANGELOG.md) file.
|
|
85
|
+
|
|
86
|
+
#### 3rd-Party Actions
|
|
87
|
+
|
|
88
|
+
- [submark](https://github.com/dahlia/submark): dahlia/submark@main
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
### Release
|
|
92
|
+
|
|
93
|
+
This step creates a GitHub release based on the tag created in a previous step and posts a number of artifacts:
|
|
94
|
+
|
|
95
|
+
- [CHANGELOG.md](../CHANGELOG.md)
|
|
96
|
+
- [LICENSE](../LICENSE)
|
|
97
|
+
- `Release.txt` - Generated for each release containing the git sha of the release
|
|
98
|
+
- `<tag>.zip` - Generated for each release containing the full repository as a `.zip` archive
|
|
99
|
+
- `<tag>.tar.gz` - Generated for each release containing the full repository as a `.tar.gz` archive
|
|
100
|
+
|
|
101
|
+
_Note:_ this step does not include the frodo binaries!
|
|
102
|
+
|
|
103
|
+
#### 3rd-Party Actions
|
|
104
|
+
|
|
105
|
+
- [action-gh-release](https://github.com/softprops/action-gh-release): softprops/action-gh-release@v1
|
|
106
|
+
|
|
107
|
+
### Binary Releases
|
|
108
|
+
|
|
109
|
+
The binaries are built by GitHub runners of the same OS as the binary they are building. That allows the binaries to be executed (tested) as one of the steps in the build process.
|
|
110
|
+
|
|
111
|
+
The binary builds run in parallel while all the previous steps run in sequence and must complete before the binay builds even kick off.
|
|
112
|
+
|
|
113
|
+
#### Linux Binary Release
|
|
114
|
+
|
|
115
|
+
This step builds the Linux binary and adds it to the release created in an earlier step.
|
|
116
|
+
|
|
117
|
+
#### 3rd-Party Actions
|
|
118
|
+
|
|
119
|
+
- [action-gh-release](https://github.com/softprops/action-gh-release): softprops/action-gh-release@v1
|
|
120
|
+
|
|
121
|
+
#### Mac OS Binary Release
|
|
122
|
+
|
|
123
|
+
This step builds the Mac OS binary and adds it to the release created in an earlier step.
|
|
124
|
+
|
|
125
|
+
#### 3rd-Party Actions
|
|
126
|
+
|
|
127
|
+
- [action-gh-release](https://github.com/softprops/action-gh-release): softprops/action-gh-release@v1
|
|
128
|
+
|
|
129
|
+
#### Windows Binary Release
|
|
130
|
+
|
|
131
|
+
This step builds the Windows binary and adds it to the release created in an earlier step.
|
|
132
|
+
|
|
133
|
+
#### 3rd-Party Actions
|
|
134
|
+
|
|
135
|
+
- [action-gh-release](https://github.com/softprops/action-gh-release): softprops/action-gh-release@v1
|
|
136
|
+
|
|
137
|
+
## Pipeline Maintenance
|
|
138
|
+
|
|
139
|
+
Pipeline maintenance is a tricky business. Pipeline testing in forks is difficult because GitHub by default imposes a different behaviour for pipeline events than in the main repository. Some pipeline steps require branch names, which means the pipeline needs to be adopted to run in the fork and branch it is being tested in.
|
|
140
|
+
|
|
141
|
+
All of the above has lead the team to make and test pipeline changes in the main repository on the real pipeline.
|
|
142
|
+
|
|
143
|
+
### Recover From A Wrong Version Bump And Release
|
|
144
|
+
|
|
145
|
+
When testing the pipeline and especially when experimenting with the automated version bump logic, it is unavoidable that once in a while a version is released that really has to be removed. E.g. during the pipeline development and testing of the first full automation, a bump to version 1.0.0 was triggered unintentionally. While minor and patch version bumps can be dealt with, major version bumps should really not be taken lightly.
|
|
146
|
+
|
|
147
|
+
So to recover from that, the following needs to happen:
|
|
148
|
+
|
|
149
|
+
1. Manually delete the `faulty release` from the [release page](../releases)
|
|
150
|
+
1. Manually modify the following files in your fork:
|
|
151
|
+
- [CHANGELOG.md](../CHANGELOG.md)
|
|
152
|
+
1. Find the faulty release heading towards the top of the file
|
|
153
|
+
1. Move your changelog entries in the faulty release section back into the Unreleased section
|
|
154
|
+
1. Now remove the faulty release header
|
|
155
|
+
1. Find the link to the faulty release tag at the bottom of the file and remove it
|
|
156
|
+
- [package.json](../package.json)
|
|
157
|
+
- Fine the 1 occurance of the frodo version in package.json and reset it to the `previous version` from before the faulty version bump
|
|
158
|
+
- [package-lock.json](../package-lock.json)
|
|
159
|
+
- Find the 2 occurances of the faulty version in package-lock.json and reset them to the `previous version` from before the faulty version bump
|
|
160
|
+
1. Commit your changes and create a new pull request
|
|
161
|
+
1. In the frodo repository, merge the PR and provide the appropriate comment to trigger the intended version bump
|
|
162
|
+
1. Remove the faulty tag from the repository:<br>
|
|
163
|
+
This is important because you cannot update an existing tag and in order to eventually release the version in the future, you must delete it first. Beware the difference between version (e.g. `1.0.0`) and tag (e.g. `v1.0.0`). This step requires you to use the tag:
|
|
164
|
+
- From the command line, navigate to the directory where you cloned the frodo repository (_not your fork, the real one!_)
|
|
165
|
+
- Issue the following command:<br>
|
|
166
|
+
```
|
|
167
|
+
git push --delete origin v1.0.0
|
|
168
|
+
```
|
|
169
|
+
1. Validate the pipeline created the desired new version and release
|
|
Binary file
|
|
Binary file
|
package/jsconfig.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rockcarver/frodo-lib",
|
|
3
|
+
"version": "0.11.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "ForgeROck DO Library, frodo-lib, a library to manage ForgeRock platform deployments supporting Identity Cloud tenants, ForgeOps deployments, and classic deployments.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"forgerock",
|
|
8
|
+
"library",
|
|
9
|
+
"am",
|
|
10
|
+
"idm",
|
|
11
|
+
"forgeops",
|
|
12
|
+
"identity cloud",
|
|
13
|
+
"export",
|
|
14
|
+
"import",
|
|
15
|
+
"ci/cd",
|
|
16
|
+
"devops"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=14"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/rockcarver/frodo-lib.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/rockcarver/frodo-lib/issues"
|
|
27
|
+
},
|
|
28
|
+
"main": "src/index.js",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
31
|
+
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
|
|
32
|
+
"lint": "eslint --ext .js --ignore-path .gitignore ."
|
|
33
|
+
},
|
|
34
|
+
"jest": {
|
|
35
|
+
"globalSetup": "<rootDir>/test/global/setup.js"
|
|
36
|
+
},
|
|
37
|
+
"contributors": [
|
|
38
|
+
{
|
|
39
|
+
"name": "Sandeep Chaturvedi",
|
|
40
|
+
"email": "sandeep.chaturvedi@forgerock.com"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "Adam Crockett",
|
|
44
|
+
"email": "adam.crockett@forgerock.com"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "Ali Falahi",
|
|
48
|
+
"email": "ali@falahi.com"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "Joshua Sayers",
|
|
52
|
+
"email": "joshua.sayers@forgerock.com"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "Volker Scheuber",
|
|
56
|
+
"email": "volker.scheuber@forgerock.com"
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@colors/colors": "^1.5.0",
|
|
62
|
+
"axios": "^0.27.2",
|
|
63
|
+
"axios-retry": "^3.3.1",
|
|
64
|
+
"cli-progress": "^3.11.2",
|
|
65
|
+
"cli-table3": "^0.6.2",
|
|
66
|
+
"commander": "^9.4.0",
|
|
67
|
+
"fs-extra": "^10.0.0",
|
|
68
|
+
"https-proxy-agent": "^5.0.1",
|
|
69
|
+
"lodash": "^4.17.21",
|
|
70
|
+
"nanospinner": "^1.1.0",
|
|
71
|
+
"properties-reader": "^2.2.0",
|
|
72
|
+
"qs": "^6.10.3",
|
|
73
|
+
"readline-sync": "^1.4.10",
|
|
74
|
+
"replaceall": "^0.1.6",
|
|
75
|
+
"slugify": "^1.6.5",
|
|
76
|
+
"url": "^0.11.0",
|
|
77
|
+
"uuid": "^8.3.2",
|
|
78
|
+
"yesno": "^0.4.0"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@babel/eslint-parser": "^7.18.9",
|
|
82
|
+
"del": "^6.0.0",
|
|
83
|
+
"eslint": "^8.21.0",
|
|
84
|
+
"eslint-config-airbnb": "^19.0.4",
|
|
85
|
+
"eslint-config-prettier": "^8.4.0",
|
|
86
|
+
"eslint-plugin-import": "^2.25.4",
|
|
87
|
+
"eslint-plugin-jest": "^26.8.2",
|
|
88
|
+
"eslint-plugin-jsx-a11y": "^6.6.1",
|
|
89
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
90
|
+
"eslint-plugin-react": "^7.29.2",
|
|
91
|
+
"eslint-plugin-react-hooks": "^4.3.0",
|
|
92
|
+
"jest": "^28.1.3",
|
|
93
|
+
"map-stream": "^0.0.7"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import util from 'util';
|
|
2
|
+
import { generateAmApi } from './BaseApi.js';
|
|
3
|
+
import storage from '../storage/SessionStorage.js';
|
|
4
|
+
|
|
5
|
+
const authenticateUrlTemplate = '%s/json%s/authenticate';
|
|
6
|
+
|
|
7
|
+
const apiVersion = 'resource=2.0, protocol=1.0';
|
|
8
|
+
const getApiConfig = () => ({
|
|
9
|
+
apiVersion,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const realmPathTemplate = '/realms/%s';
|
|
13
|
+
|
|
14
|
+
export function getRealmUrl(realm) {
|
|
15
|
+
let localRealm = realm;
|
|
16
|
+
if (localRealm.startsWith('/') && localRealm.length > 1) {
|
|
17
|
+
localRealm = localRealm.substring(1);
|
|
18
|
+
}
|
|
19
|
+
let realmPath = util.format(realmPathTemplate, 'root');
|
|
20
|
+
if (localRealm !== '/') {
|
|
21
|
+
realmPath += util.format(realmPathTemplate, localRealm);
|
|
22
|
+
}
|
|
23
|
+
return realmPath;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function step(data = {}, config = {}) {
|
|
27
|
+
const urlString = util.format(
|
|
28
|
+
authenticateUrlTemplate,
|
|
29
|
+
storage.session.getTenant(),
|
|
30
|
+
getRealmUrl('/')
|
|
31
|
+
);
|
|
32
|
+
return generateAmApi(getApiConfig()).post(urlString, data, config);
|
|
33
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import axiosRetry from 'axios-retry';
|
|
3
|
+
import * as https from 'https';
|
|
4
|
+
import HttpsProxyAgent from 'https-proxy-agent';
|
|
5
|
+
import url from 'url';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import storage from '../storage/SessionStorage.js';
|
|
8
|
+
import { getTenantURL } from './utils/ApiUtils.js';
|
|
9
|
+
// import pkg from '../../package.json' assert { type: 'json' };
|
|
10
|
+
|
|
11
|
+
const pkg = JSON.parse(
|
|
12
|
+
fs.readFileSync(new URL('../../package.json', import.meta.url))
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
axiosRetry(axios, {
|
|
16
|
+
retries: 3,
|
|
17
|
+
shouldResetTimeout: true,
|
|
18
|
+
// eslint-disable-next-line no-unused-vars
|
|
19
|
+
retryCondition: (_error) => true, // retry no matter what
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const timeout = 30000;
|
|
23
|
+
const userAgent = `${pkg.name}/${pkg.version}`;
|
|
24
|
+
let httpsAgent;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Helper method to create properly configured httpsAgent
|
|
28
|
+
* @returns {any} appropriate httpsAgent
|
|
29
|
+
*/
|
|
30
|
+
function getHttpsAgent() {
|
|
31
|
+
if (httpsAgent) return httpsAgent;
|
|
32
|
+
const options = {
|
|
33
|
+
rejectUnauthorized: !storage.session.getAllowInsecureConnection(),
|
|
34
|
+
};
|
|
35
|
+
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
|
|
36
|
+
if (httpsProxy) {
|
|
37
|
+
// https://github.com/axios/axios/issues/3459
|
|
38
|
+
console.error(`Using proxy ${httpsProxy}`.yellow);
|
|
39
|
+
const parsed = url.parse(httpsProxy);
|
|
40
|
+
options.host = parsed.hostname;
|
|
41
|
+
options.port = parsed.port;
|
|
42
|
+
options.protocol = parsed.protocol;
|
|
43
|
+
options.rejectUnauthorized = !storage.session.getAllowInsecureConnection();
|
|
44
|
+
httpsAgent = new HttpsProxyAgent(options);
|
|
45
|
+
return httpsAgent;
|
|
46
|
+
}
|
|
47
|
+
httpsAgent = new https.Agent(options);
|
|
48
|
+
return httpsAgent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getProxy() {
|
|
52
|
+
if (process.env.HTTPS_PROXY || process.env.https_proxy) return false;
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generates an AM Axios API instance
|
|
58
|
+
* @param {object} resource Takes an object takes a resource object. example:
|
|
59
|
+
* @param {object} requestOverride Takes an object of AXIOS parameters that can be used to either
|
|
60
|
+
* add on extra information or override default properties https://github.com/axios/axios#request-config
|
|
61
|
+
*
|
|
62
|
+
* @returns {AxiosInstance}
|
|
63
|
+
*/
|
|
64
|
+
export function generateAmApi(resource, requestOverride = {}) {
|
|
65
|
+
let headers = {
|
|
66
|
+
'User-Agent': userAgent,
|
|
67
|
+
'Content-Type': 'application/json',
|
|
68
|
+
'Accept-API-Version': resource.apiVersion,
|
|
69
|
+
Cookie: `${storage.session.raw.cookieName}=${storage.session.raw.cookieValue}`,
|
|
70
|
+
};
|
|
71
|
+
if (requestOverride.headers) {
|
|
72
|
+
headers = {
|
|
73
|
+
...headers,
|
|
74
|
+
...requestOverride.headers,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const requestDetails = {
|
|
79
|
+
baseURL: `${storage.session.getTenant()}/json${resource.path}`,
|
|
80
|
+
timeout,
|
|
81
|
+
...requestOverride,
|
|
82
|
+
headers,
|
|
83
|
+
httpsAgent: getHttpsAgent(),
|
|
84
|
+
proxy: getProxy(),
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const request = axios.create(requestDetails);
|
|
88
|
+
|
|
89
|
+
return request;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Generates an OAuth2 Axios API instance
|
|
94
|
+
* @param {object} resource Takes an object takes a resource object. example:
|
|
95
|
+
* @param {object} requestOverride Takes an object of AXIOS parameters that can be used to either
|
|
96
|
+
* add on extra information or override default properties https://github.com/axios/axios#request-config
|
|
97
|
+
*
|
|
98
|
+
* @returns {AxiosInstance}
|
|
99
|
+
*/
|
|
100
|
+
export function generateOauth2Api(resource, requestOverride = {}) {
|
|
101
|
+
let headers = {
|
|
102
|
+
'User-Agent': userAgent,
|
|
103
|
+
'Accept-API-Version': resource.apiVersion,
|
|
104
|
+
Cookie: `${storage.session.raw.cookieName}=${storage.session.raw.cookieValue}`,
|
|
105
|
+
};
|
|
106
|
+
if (requestOverride.headers) {
|
|
107
|
+
headers = {
|
|
108
|
+
...headers,
|
|
109
|
+
...requestOverride.headers,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const requestDetails = {
|
|
114
|
+
baseURL: `${storage.session.getTenant()}/json${resource.path}`,
|
|
115
|
+
timeout,
|
|
116
|
+
...requestOverride,
|
|
117
|
+
headers,
|
|
118
|
+
httpsAgent: getHttpsAgent(),
|
|
119
|
+
proxy: getProxy(),
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const request = axios.create(requestDetails);
|
|
123
|
+
|
|
124
|
+
return request;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Generates an IDM Axios API instance
|
|
129
|
+
* @param {object} requestOverride Takes an object of AXIOS parameters that can be used to either add
|
|
130
|
+
* on extra information or override default properties https://github.com/axios/axios#request-config
|
|
131
|
+
*
|
|
132
|
+
* @returns {AxiosInstance}
|
|
133
|
+
*/
|
|
134
|
+
export function generateIdmApi(requestOverride = {}) {
|
|
135
|
+
const requestDetails = {
|
|
136
|
+
baseURL: getTenantURL(storage.session.getTenant()),
|
|
137
|
+
timeout,
|
|
138
|
+
headers: {
|
|
139
|
+
'User-Agent': userAgent,
|
|
140
|
+
'Content-Type': 'application/json',
|
|
141
|
+
},
|
|
142
|
+
...requestOverride,
|
|
143
|
+
httpsAgent: getHttpsAgent(),
|
|
144
|
+
proxy: getProxy(),
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
if (storage.session.getBearerToken()) {
|
|
148
|
+
requestDetails.headers.Authorization = `Bearer ${storage.session.getBearerToken()}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const request = axios.create(requestDetails);
|
|
152
|
+
|
|
153
|
+
return request;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Generates a LogKeys API Axios instance
|
|
158
|
+
* @param {object} requestOverride Takes an object of AXIOS parameters that can be used to either add
|
|
159
|
+
* on extra information or override default properties https://github.com/axios/axios#request-config
|
|
160
|
+
*
|
|
161
|
+
* @returns {AxiosInstance}
|
|
162
|
+
*/
|
|
163
|
+
export function generateLogKeysApi(requestOverride = {}) {
|
|
164
|
+
const headers = {
|
|
165
|
+
'User-Agent': userAgent,
|
|
166
|
+
'Content-Type': 'application/json',
|
|
167
|
+
};
|
|
168
|
+
const requestDetails = {
|
|
169
|
+
baseURL: getTenantURL(storage.session.getTenant()),
|
|
170
|
+
timeout,
|
|
171
|
+
headers,
|
|
172
|
+
...requestOverride,
|
|
173
|
+
httpsAgent: getHttpsAgent(),
|
|
174
|
+
proxy: getProxy(),
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
if (storage.session.getBearerToken()) {
|
|
178
|
+
requestDetails.headers.Authorization = `Bearer ${storage.session.getBearerToken()}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const request = axios.create(requestDetails);
|
|
182
|
+
|
|
183
|
+
return request;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Generates a Log API Axios instance
|
|
188
|
+
* @param {object} requestOverride Takes an object of AXIOS parameters that can be used to either add
|
|
189
|
+
* on extra information or override default properties https://github.com/axios/axios#request-config
|
|
190
|
+
*
|
|
191
|
+
* @returns {AxiosInstance}
|
|
192
|
+
*/
|
|
193
|
+
export function generateLogApi(requestOverride = {}) {
|
|
194
|
+
const headers = {
|
|
195
|
+
'User-Agent': userAgent,
|
|
196
|
+
'X-API-Key': storage.session.getLogApiKey(),
|
|
197
|
+
'X-API-Secret': storage.session.getLogApiSecret(),
|
|
198
|
+
};
|
|
199
|
+
const requestDetails = {
|
|
200
|
+
baseURL: getTenantURL(storage.session.getTenant()),
|
|
201
|
+
timeout,
|
|
202
|
+
headers,
|
|
203
|
+
...requestOverride,
|
|
204
|
+
httpsAgent: getHttpsAgent(),
|
|
205
|
+
proxy: getProxy(),
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const request = axios.create(requestDetails);
|
|
209
|
+
|
|
210
|
+
return request;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Generates an ESV Axios API instance for Environment Secrets and Variables
|
|
215
|
+
* @param {object} requestOverride Takes an object of AXIOS parameters that can be used to either add
|
|
216
|
+
* on extra information or override default properties https://github.com/axios/axios#request-config
|
|
217
|
+
*
|
|
218
|
+
* @returns {AxiosInstance}
|
|
219
|
+
*/
|
|
220
|
+
export function generateESVApi(resource, requestOverride = {}) {
|
|
221
|
+
const headers = {
|
|
222
|
+
'User-Agent': userAgent,
|
|
223
|
+
'Content-Type': 'application/json',
|
|
224
|
+
'Accept-API-Version': resource.apiVersion,
|
|
225
|
+
};
|
|
226
|
+
const requestDetails = {
|
|
227
|
+
baseURL: getTenantURL(storage.session.getTenant()),
|
|
228
|
+
timeout,
|
|
229
|
+
headers,
|
|
230
|
+
...requestOverride,
|
|
231
|
+
httpsAgent: getHttpsAgent(),
|
|
232
|
+
proxy: getProxy(),
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
if (storage.session.getBearerToken()) {
|
|
236
|
+
requestDetails.headers.Authorization = `Bearer ${storage.session.getBearerToken()}`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const request = axios.create(requestDetails);
|
|
240
|
+
|
|
241
|
+
return request;
|
|
242
|
+
}
|