diff --git a/.editorconfig b/.editorconfig index 0439866..c2fa6a2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,7 +16,7 @@ insert_final_newline = true indent_style = space indent_size = 4 -[*.{ts,tsx,js,jsx,json,css,scss,yml}] +[*.{ts,tsx,js,jsx,json,css,scss,yml,html,vue}] indent_size = 2 [*.md] diff --git a/.gitattributes b/.gitattributes index c013844..ca61722 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,6 +8,8 @@ # These files are text and should be normalized (Convert crlf => lf) *.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf *.coffee text *.css text *.cql text diff --git a/.gitignore b/.gitignore index 50d9fe1..2b19086 100644 --- a/.gitignore +++ b/.gitignore @@ -52,8 +52,9 @@ local.properties # STS-specific /.sts4-cache/* + ###################### -# Intellij +# IntelliJ ###################### .idea/ *.iml @@ -67,7 +68,12 @@ out/ ###################### # Visual Studio Code ###################### -.vscode/ +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace ###################### # Maven diff --git a/.huskyrc b/.huskyrc new file mode 100644 index 0000000..4d077c8 --- /dev/null +++ b/.huskyrc @@ -0,0 +1,5 @@ +{ + "hooks": { + "pre-commit": "lint-staged" + } +} diff --git a/.jhipster/AccessToken.json b/.jhipster/AccessToken.json index 954f6f2..d20813f 100644 --- a/.jhipster/AccessToken.json +++ b/.jhipster/AccessToken.json @@ -1,46 +1,53 @@ { - "fluentMethods": true, - "clientRootFolder": "caseManagement", - "relationships": [ - { - "relationshipType": "many-to-one", - "otherEntityName": "user", - "otherEntityRelationshipName": "accessToken", - "relationshipName": "user", - "otherEntityField": "id" - }, - { - "relationshipType": "many-to-one", - "otherEntityName": "ticketSystemInstance", - "otherEntityRelationshipName": "accessToken", - "relationshipName": "ticketInstance", - "otherEntityField": "id" - } - ], - "fields": [ - { - "fieldName": "token", - "fieldType": "String", - "fieldValidateRules": [ - "required" - ] - }, - { - "fieldName": "expirationDate", - "fieldType": "ZonedDateTime" - } - ], - "changelogDate": "20201108111723", - "dto": "no", - "searchEngine": false, - "service": "no", - "entityTableName": "access_token", - "databaseType": "sql", - "readOnly": false, - "jpaMetamodelFiltering": false, - "pagination": "infinite-scroll", - "microserviceName": "caseManagement", - "name": "AccessToken", - "applications": "*", - "skipClient": true -} \ No newline at end of file + "fluentMethods": true, + "clientRootFolder": "caseManagement", + "relationships": [ + { + "relationshipType": "many-to-one", + "otherEntityName": "user", + "otherEntityRelationshipName": "accessToken", + "relationshipName": "user", + "otherEntityField": "id" + }, + { + "relationshipType": "many-to-one", + "otherEntityName": "ticketSystemInstance", + "otherEntityRelationshipName": "accessToken", + "relationshipName": "ticketInstance", + "otherEntityField": "id" + } + ], + "fields": [ + { + "fieldName": "token", + "fieldType": "String", + "fieldValidateRules": ["required"] + }, + { + "fieldName": "expirationDate", + "fieldType": "ZonedDateTime" + }, + { + "fieldName": "salt", + "fieldType": "String", + "fieldValidateRules": ["required"] + }, + { + "fieldName": "refreshToken", + "fieldType": "String" + } + ], + "changelogDate": "20201108111723", + "dto": "no", + "searchEngine": false, + "service": "no", + "entityTableName": "access_token", + "databaseType": "sql", + "readOnly": false, + "jpaMetamodelFiltering": false, + "pagination": "infinite-scroll", + "microserviceName": "caseManagement", + "name": "AccessToken", + "applications": "*", + "skipClient": true +} diff --git a/.jhipster/TicketSystemInstance.json b/.jhipster/TicketSystemInstance.json index 006738e..c1fede3 100644 --- a/.jhipster/TicketSystemInstance.json +++ b/.jhipster/TicketSystemInstance.json @@ -1,43 +1,53 @@ { - "name": "TicketSystemInstance", - "fields": [ - { - "fieldName": "name", - "fieldType": "String" - }, - { - "fieldName": "type", - "fieldType": "TicketSystem", - "fieldValues": "JIRA", - "fieldValidateRules": [ - "required" - ] - }, - { - "fieldName": "url", - "fieldType": "String", - "fieldValidateRules": [ - "required" - ] - } - ], - "relationships": [ - { - "relationshipType": "one-to-many", - "otherEntityName": "accessToken", - "otherEntityRelationshipName": "ticketInstance", - "relationshipName": "accessToken" - } - ], - "changelogDate": "20201108112112", - "entityTableName": "ticket_system_instance", - "dto": "no", - "pagination": "infinite-scroll", - "service": "no", - "jpaMetamodelFiltering": false, - "fluentMethods": true, - "readOnly": false, - "clientRootFolder": "caseManagement", - "applications": "*", - "microserviceName": "caseManagement" -} \ No newline at end of file + "name": "TicketSystemInstance", + "fields": [ + { + "fieldName": "name", + "fieldType": "String" + }, + { + "fieldName": "type", + "fieldType": "TicketSystem", + "fieldValues": "JIRA", + "fieldValidateRules": ["required"] + }, + { + "fieldName": "url", + "fieldType": "String", + "fieldValidateRules": ["required"] + }, + { + "fieldName": "consumerKey", + "fieldType": "String" + }, + { + "fieldName": "clientId", + "fieldType": "String" + }, + { + "fieldName": "clientSecret", + "fieldType": "String" + } + ], + "relationships": [ + { + "relationshipType": "one-to-many", + "otherEntityName": "accessToken", + "otherEntityRelationshipName": "ticketInstance", + "relationshipName": "accessToken" + } + ], + "changelogDate": "20201108112112", + "entityTableName": "ticket_system_instance", + "dto": "yes", + "pagination": "infinite-scroll", + "service": "no", + "jpaMetamodelFiltering": false, + "fluentMethods": true, + "readOnly": false, + "clientRootFolder": "caseManagement", + "applications": "*", + "microserviceName": "caseManagement", + "searchEngine": false, + "databaseType": "sql" +} diff --git a/.lintstagedrc.js b/.lintstagedrc.js new file mode 100644 index 0000000..dad2893 --- /dev/null +++ b/.lintstagedrc.js @@ -0,0 +1,3 @@ +module.exports = { + '{,src/**/}*.{md,json,yml,html,java}': ['prettier --write'], +}; diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index c32394f..b901097 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -20,7 +20,7 @@ public class MavenWrapperDownloader { - private static final String WRAPPER_VERSION = "0.5.5"; + private static final String WRAPPER_VERSION = "0.5.6"; /** * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. */ diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index 0d5e649..2cc7d4a 100644 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 7d59a01..642d572 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/.prettierignore b/.prettierignore index 91b1ba3..ab0567f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,8 @@ node_modules target +build package-lock.json .git +.mvn +gradle +.gradle diff --git a/.prettierrc b/.prettierrc index b749286..f9b9911 100644 --- a/.prettierrc +++ b/.prettierrc @@ -10,3 +10,9 @@ arrowParens: avoid # jsx and tsx rules: jsxBracketSameLine: false + +# java rules: +overrides: + - files: "*.java" + options: + tabWidth: 4 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6eed822..0000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -os: -- linux -services: -- docker -language: node_js -node_js: -- 13.5.0 -jdk: -- openjdk8 -sudo: false -cache: - directories: - - node - - node_modules - - "$HOME/.m2" - - "$HOME/.yarn-cache" - - "$HOME/.sonar/cache" -addons: - sonarcloud: - organization: "securityrat" - token: - secure: iEsQimM9dEZJKOYRIhQxT3Y+bQ2LCGVUm0qtl6J1ki/eUO3RNArGFxVPEYXM0pX86fA5/FNlUY7Efy7WLSwW6nLMeMW4pd0s2Z7xx5xDOkgiuIXfx8klE/YW8AQHggl/qcYm0M2VyFUVnRzkGfIYgNxKykA0MKNFQ2pgXeMh3MmVAqZ9a3MGd6hVU7p+fr1qDpN0Wwss3dj35pO2k0Cskyq89klN1Gd9qfZvpYoelXdP7fTj87KrbQx5K976RxGSok77szcBNegS3pKblQFWPcV9iqwnNkZHoeDsbEa4TsOi/5CBb/lMhj+oc53KAoe9SMAC5irHTQBf2Huvvl5WfZbtqD17YqQ7jbsErG3GBDc5SsATwKhv2AiZIjKYfe9AfQICf2S87sFP2CyzYow1mf5Pm0DI8b6oN7aOLzSTvqQmd3/MVhB1BBGFuLz34/q+J2KAnOkfleQa6f2Onp7XK86xFStjJUSbParXg3xMPciEsvQxNwqGqnHB3ooVkKfOBccHRYHJKHyWfaYgd/KDIo9sqhIQz/XRb+RZJvSqNt8ahGXdtmg6GuWAm2N3Ic9GVSJu3PxzywYYBFfSp6vRg1zQ+DYM0io+JLuBHd4M0MgxcZ1scUPHQe+VrPnlANSI/gnWBBvCoSwEqggUIC/x3w0R7U0er+C/a8LVxXmb4aA= - branches: - - master -env: - global: - - REPOS_SCRIPTS=$TRAVIS_BUILD_DIR/travis/scripts - - SPRING_OUTPUT_ANSI_ENABLED=ALWAYS - - SPRING_JPA_SHOW_SQL=false - - DOCKER_REPO=securityrat/case-management - - secure: H1q/AM/ljDpTk3Z7l2/WPVFV4JeraiAqa7LvVV3GudGXN8B1CS8Bj3+TnQcmyFmXu1cWD5Hq2EfRIZqttTlpge28Id0Ad+iL6j1Sm/xBJy9ltFdP5xjsWuF+06YH/lAXwmaOGHoC4wHQ6sbI0wbUQ775ABIoz2/talLF4podxvAJOuZIMJjX4akDaAx+uac5Th8QFNlRpMgdST2aUUSocFavJBxsX4jjxT6XIiUuvtVZqJ3kt/+YUju1Saez/jLO9nL0uHwNiu8J2V2keEj0B/9hc2ZzEUXwZpKPtEMkOpDob4aDsb7ljClsqOURSkulmbRQ5KYqYEIfjLFuYXXfpbq7SnN1/5Qd1nlloMMBqiVTad1/w97j7m15XECZ+hctJO40XxJ4ec+34HfSi+Gm0zEHtg4hC/S05LRIPH+ky4MyzIluxm0DcLFKP9ajc8+vIZ2XZpJcfx6fhWP+iQJP6aKVtclmuPww8Ru/L18/2JhslDOVGTdxY/Lkuf7PBSlTKIDXKTepPyShCOFf4cZmYI+R9QlVSWyn221VRS7OQ6Ty6Bxmn4UwQc/aXYOXLD3rHuNR3CvpiJA/7AwbdcI18zN/zGRX5fGZPMzjIoUuuUMUNg0Rkw2N6jrYOWWUpkKhXavTAAfhkHm+HZTEWS1Ch/U2/R09MQ7RqQoLdSG151Y= - - secure: O1iKPJcS8SvHNjsC1KfASw42f1KPDVoa9ePheO/+UB20Mg2mnooIrZO+2ksTATGSTjG2pVHR2c7hM3WEkdPrt7MzV+g0pGw/THuyZU90p3JkccBFudR+d9z7MZnwXzdrV6EKmEalPmB/HlBxXugUj5hl0S9kvS31J1DNWthzZ6ZE2uvQPKSMW/Fp+5kg5cj0XVUIgPUgmUnTgUjvLF1nSdd2PNEJ3Bf2p6SQQQVx0KInR3+iZGS/h5SX5CWRuF02IARt0IemKGflkpihMw1mtAGH//CRnV02bzrplwfaioIhQqV4C2mwlGfF+irMOmZ2yAyyuEWdj2/35V7re8oDcdQtwrpY+Y7moDjFgS4iEQIqrOQgQpJAoyjuzKjgJ5QIPAhkzU8JMeqMnK5wfW6S4O/mA0QR5fVJMdQok6GjLmZWtRxzJQW4v+jcJ3pQBsyJCmMMVHDHwyVP4Ss71MqpI7nFTCNN+wFTMcsx1xr9E++rq+xcwdQvwQn5/Bp+DzgBezv2HQhrxKS8ozWpGMeUiDalR3N0WGZEmgtFoOy5nQ3PePPTb4JFqaOY+wD6MKsfvBUxnysmpEmpU93pVzUjFPvUmZPcE2JuFNB7KCKMjsCmGThPT7fnMuCWbuDPYeL0jCzn/LYtg+szamCz7KdXtTS0alCN0ZUKO4i+kzqGipU= -before_install: -- sudo /etc/init.d/mysql stop -- sudo /etc/init.d/postgresql stop -- curl -o- -L https://yarnpkg.com/install.sh | bash -- export PATH=$HOME/.yarn/bin:$PATH -install: -- yarn install -script: -- chmod +x mvnw -- "./mvnw clean org.jacoco:jacoco-maven-plugin:prepare-agent test sonar:sonar" -before_deploy: -- "./mvnw verify -Pprod -DskipTests -Ddocker.repository=$DOCKER_REPO" -deploy: - provider: script - script: bash $REPOS_SCRIPTS/docker_push - on: - branch: master - condition: "-n $TAG_NAME" -notifications: - email: - on_success: change - on_failure: always diff --git a/.yo-rc.json b/.yo-rc.json index bcced94..12a5d7b 100644 --- a/.yo-rc.json +++ b/.yo-rc.json @@ -3,7 +3,7 @@ "promptValues": { "packageName": "org.securityrat.casemanagement" }, - "jhipsterVersion": "6.6.0", + "jhipsterVersion": "7.0.0", "baseName": "caseManagement", "packageName": "org.securityrat.casemanagement", "packageFolder": "org/securityrat/casemanagement", @@ -34,6 +34,18 @@ "otherModules": [], "blueprints": [], "embeddableLaunchScript": false, - "creationTimestamp": 1577042681890 + "creationTimestamp": 1577042681890, + "skipServer": false, + "skipCheckLengthOfIdentifier": false, + "skipFakeData": false, + "pages": [], + "reactive": false, + "clientFramework": "angularX", + "clientTheme": "none", + "clientThemeVariant": "", + "withAdminUi": true, + "nativeLanguage": "en", + "languages": ["en", "fr"], + "entities": ["AccessToken", "TicketSystemInstance"] } } diff --git a/README.md b/README.md index 1145d54..4e472fa 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ # caseManagement -This application was generated using JHipster 6.6.0, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v6.6.0](https://www.jhipster.tech/documentation-archive/v6.6.0). +This application was generated using JHipster 7.0.0, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v7.0.0](https://www.jhipster.tech/documentation-archive/v7.0.0). This is a "microservice" application intended to be part of a microservice architecture, please refer to the [Doing microservices with JHipster][] page of the documentation for more information. - This application is configured for Service Discovery and Configuration with Consul. On launch, it will refuse to start if it is not able to connect to Consul at [http://localhost:8500](http://localhost:8500). For more information, read our documentation on [Service Discovery and Configuration with Consul][]. ## Development To start your application in the dev profile, run: - ./mvnw +``` +./mvnw +``` For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][]. @@ -20,11 +21,15 @@ For further instructions on how to develop with JHipster, have a look at [Using To build the final jar and optimize the caseManagement application for production, run: - ./mvnw -Pprod clean verify +``` +./mvnw -Pprod clean verify +``` To ensure everything worked, run: - java -jar target/*.jar +``` +java -jar target/*.jar +``` Refer to [Using JHipster in production][] for more details. @@ -32,13 +37,17 @@ Refer to [Using JHipster in production][] for more details. To package your application as a war in order to deploy it to an application server, run: - ./mvnw -Pprod,war clean verify +``` +./mvnw -Pprod,war clean verify +``` ## Testing To launch your application's tests, run: - ./mvnw verify +``` +./mvnw verify +``` For more information, refer to the [Running tests page][]. @@ -50,6 +59,8 @@ Sonar is used to analyse code quality. You can start a local Sonar server (acces docker-compose -f src/main/docker/sonar.yml up -d ``` +Note: we have turned off authentication in [src/main/docker/sonar.yml](src/main/docker/sonar.yml) for out of the box experience while trying out SonarQube, for real use cases turn it back on. + You can run a Sonar analysis with using the [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) or by using the maven plugin. Then, run a Sonar analysis: @@ -64,8 +75,6 @@ If you need to re-run the Sonar phase, please be sure to specify at least the `i ./mvnw initialize sonar:sonar ``` -or - For more information, refer to the [Code quality page][]. ## Using Docker to simplify development (optional) @@ -74,20 +83,28 @@ You can use Docker to improve your JHipster development experience. A number of For example, to start a mariadb database in a docker container, run: - docker-compose -f src/main/docker/mariadb.yml up -d +``` +docker-compose -f src/main/docker/mariadb.yml up -d +``` To stop it and remove the container, run: - docker-compose -f src/main/docker/mariadb.yml down +``` +docker-compose -f src/main/docker/mariadb.yml down +``` You can also fully dockerize your application and all the services that it depends on. To achieve this, first build a docker image of your app by running: - ./mvnw -Pprod verify jib:dockerBuild +``` +./mvnw -Pprod verify jib:dockerBuild +``` Then run: - docker-compose -f src/main/docker/app.yml up -d +``` +docker-compose -f src/main/docker/app.yml up -d +``` For more information refer to [Using Docker and Docker-Compose][], this page also contains information on the docker-compose sub-generator (`jhipster docker-compose`), which is able to generate docker configurations for one or several JHipster applications. @@ -96,12 +113,12 @@ For more information refer to [Using Docker and Docker-Compose][], this page als To configure CI for your project, run the ci-cd sub-generator (`jhipster ci-cd`), this will let you generate configuration files for a number of Continuous Integration systems. Consult the [Setting up Continuous Integration][] page for more information. [jhipster homepage and latest documentation]: https://www.jhipster.tech -[jhipster 6.6.0 archive]: https://www.jhipster.tech/documentation-archive/v6.6.0 -[doing microservices with jhipster]: https://www.jhipster.tech/documentation-archive/v6.6.0/microservices-architecture/ -[using jhipster in development]: https://www.jhipster.tech/documentation-archive/v6.6.0/development/ -[service discovery and configuration with consul]: https://www.jhipster.tech/documentation-archive/v6.6.0/microservices-architecture/#consul -[using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v6.6.0/docker-compose -[using jhipster in production]: https://www.jhipster.tech/documentation-archive/v6.6.0/production/ -[running tests page]: https://www.jhipster.tech/documentation-archive/v6.6.0/running-tests/ -[code quality page]: https://www.jhipster.tech/documentation-archive/v6.6.0/code-quality/ -[setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v6.6.0/setting-up-ci/ +[jhipster 7.0.0 archive]: https://www.jhipster.tech/documentation-archive/v7.0.0 +[doing microservices with jhipster]: https://www.jhipster.tech/documentation-archive/v7.0.0/microservices-architecture/ +[using jhipster in development]: https://www.jhipster.tech/documentation-archive/v7.0.0/development/ +[service discovery and configuration with consul]: https://www.jhipster.tech/documentation-archive/v7.0.0/microservices-architecture/#consul +[using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v7.0.0/docker-compose +[using jhipster in production]: https://www.jhipster.tech/documentation-archive/v7.0.0/production/ +[running tests page]: https://www.jhipster.tech/documentation-archive/v7.0.0/running-tests/ +[code quality page]: https://www.jhipster.tech/documentation-archive/v7.0.0/code-quality/ +[setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v7.0.0/setting-up-ci/ diff --git a/checkstyle.xml b/checkstyle.xml index 10a479f..5d5ae65 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -1,6 +1,6 @@ + "https://checkstyle.org/dtds/configuration_1_3.dtd"> @@ -9,8 +9,7 @@ - + - \ No newline at end of file + diff --git a/mvnw b/mvnw index d2f0ea3..41c0f0c 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Maven Start Up Batch script # # Required ENV vars: # ------------------ @@ -212,9 +212,9 @@ else echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." fi if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" fi while IFS="=" read key value; do case "$key" in (wrapperUrl) jarUrl="$value"; break ;; @@ -246,7 +246,7 @@ else else curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f fi - + else if [ "$MVNW_VERBOSE" = true ]; then echo "Falling back to using Java to download" diff --git a/mvnw.cmd b/mvnw.cmd index 1c0f07d..8611571 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,7 +18,7 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script +@REM Maven Start Up Batch script @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @@ -26,7 +26,7 @@ @REM Optional ENV vars @REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -43,7 +43,7 @@ title %0 @REM set %HOME% to equivalent of $HOME if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") -@REM Execute a appUser defined script before this one +@REM Execute a user defined script before this one if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre @REM check for pre script, once with legacy .bat ending and once with .cmd ending if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" @@ -120,7 +120,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B @@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... diff --git a/package.json b/package.json index 50e9c9d..d888e9b 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,59 @@ { "name": "case-management", "version": "0.0.0", - "description": "Description for caseManagement", "private": true, + "description": "Description for caseManagement", "license": "UNLICENSED", - "cacheDirectories": [ - "node_modules" - ], + "scripts": { + "prettier:check": "prettier --check \"{,src/**/}*.{md,json,yml,html,java}\"", + "prettier:format": "prettier --write \"{,src/**/}*.{md,json,yml,html,java}\"", + "docker:db:up": "docker-compose -f src/main/docker/mariadb.yml up -d", + "docker:db:down": "docker-compose -f src/main/docker/mariadb.yml down -v --remove-orphans", + "docker:consul:up": "docker-compose -f src/main/docker/consul.yml up -d", + "docker:consul:down": "docker-compose -f src/main/docker/consul.yml down -v --remove-orphans", + "docker:others:await": "", + "predocker:others:up": "", + "docker:others:up": "npm run docker:consul:up", + "docker:others:down": "npm run docker:consul:down", + "ci:e2e:prepare:docker": "npm run docker:db:up && npm run docker:others:up && docker ps -a", + "ci:e2e:prepare": "npm run ci:e2e:prepare:docker", + "ci:e2e:teardown:docker": "npm run docker:db:down --if-present && npm run docker:others:down && docker ps -a", + "ci:e2e:teardown": "npm run ci:e2e:teardown:docker", + "backend:info": "./mvnw -ntp enforcer:display-info --batch-mode", + "backend:doc:test": "./mvnw -ntp javadoc:javadoc --batch-mode", + "backend:nohttp:test": "./mvnw -ntp checkstyle:check --batch-mode", + "java:jar": "./mvnw -ntp verify -DskipTests --batch-mode", + "java:war": "./mvnw -ntp verify -DskipTests --batch-mode -Pwar", + "java:docker": "./mvnw -ntp verify -DskipTests jib:dockerBuild", + "backend:unit:test": "./mvnw -ntp -P-webapp verify --batch-mode -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.securityrat.casemanagement=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF", + "java:jar:dev": "npm run java:jar -- -Pdev,webapp", + "java:jar:prod": "npm run java:jar -- -Pprod", + "java:war:dev": "npm run java:war -- -Pdev,webapp", + "java:war:prod": "npm run java:war -- -Pprod", + "java:docker:dev": "npm run java:docker -- -Pdev,webapp", + "java:docker:prod": "npm run java:docker -- -Pprod", + "ci:backend:test": "npm run backend:info && npm run backend:doc:test && npm run backend:nohttp:test && npm run backend:unit:test", + "ci:server:package": "npm run java:$npm_package_config_packaging:$npm_package_config_default_environment", + "ci:e2e:package": "npm run java:$npm_package_config_packaging:$npm_package_config_default_environment -- -Pe2e -Denforcer.skip=true", + "preci:e2e:server:start": "npm run docker:db:await --if-present && npm run docker:others:await --if-present", + "ci:e2e:server:start": "java -jar target/e2e.$npm_package_config_packaging --spring.profiles.active=$npm_package_config_default_environment -Dlogging.level.ROOT=OFF -Dlogging.level.org.zalando=OFF -Dlogging.level.tech.jhipster=OFF -Dlogging.level.org.securityrat.casemanagement=OFF -Dlogging.level.org.springframework=OFF -Dlogging.level.org.springframework.web=OFF -Dlogging.level.org.springframework.security=OFF --logging.level.org.springframework.web=ERROR" + }, + "config": { + "backend_port": "8082", + "packaging": "jar" + }, "devDependencies": { - "generator-jhipster": "6.6.0", - "@openapitools/openapi-generator-cli": "0.0.14-4.0.2" + "generator-jhipster": "7.0.0", + "husky": "4.3.8", + "lint-staged": "10.5.4", + "prettier": "2.2.1", + "prettier-plugin-java": "1.0.2", + "prettier-plugin-packagejson": "2.2.10" }, "engines": { - "node": ">=8.9.0" - } + "node": ">=14.16.0" + }, + "cacheDirectories": [ + "node_modules" + ] } diff --git a/pom.xml b/pom.xml index 8f5b4d1..18114ca 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,8 @@ - + 4.0.0 org.securityrat.casemanagement @@ -22,80 +24,69 @@ 3.3.9 - 1.8 + 11 UTF-8 UTF-8 ${project.build.directory}/test-results yyyyMMddHHmmss ${java.version} ${java.version} + org.securityrat.casemanagement.CaseManagementApp -Djava.security.egd=file:/dev/./urandom -Xmx256m jdt_apt false - securityrat/case-management - + - 3.1.0 + 7.0.0 - 2.1.11.RELEASE - - 5.1.12.RELEASE + https://mvnrepository.com/artifact/tech.jhipster/jhipster-dependencies/${jhipster-dependencies.version} --> + 2.4.4 - 5.3.14.Final + 5.4.29.Final - 3.23.2-GA + 3.27.0-GA - 3.6.3 - 3.6 - - 5.3.8.Final + 4.3.1 + 4.3.1 1.4.200 2.0.1.Final - 2.3.2 - 0.12.0 - 1.3.1.Final + 2.3.3 + 0.17.0 + 1.4.2.Final 3.1.0 3.8.1 - 3.1.1 + 3.2.0 2.10 3.0.0-M3 - 3.0.0-M4 + 3.0.0-M5 2.2.1 - 3.1.0 - 3.0.0-M4 - 3.2.3 - 3.1.0 - 8.29 - 0.0.4.RELEASE - 4.0.0 - 0.8.5 - 1.8.0 + 3.2.0 + 3.0.0-M5 + 3.3.1 + 3.1.2 + 8.40 + 0.0.5.RELEASE + 4.0.3 + 0.8.6 + 2.8.0 1.0.0 1.0.0 - 3.7.0.1746 - ${project.build.directory}/jacoco/test - ${jacoco.utReportFolder}/test.exec - ${project.build.directory}/jacoco/integrationTest - ${jacoco.itReportFolder}/integrationTest.exec - ${project.testresult.directory}/test - ${project.testresult.directory}/integrationTest + 3.8.0.2131 - io.github.jhipster + tech.jhipster jhipster-dependencies ${jhipster-dependencies.version} pom @@ -107,10 +98,17 @@ - io.github.jhipster + tech.jhipster jhipster-framework - + + javax.annotation + javax.annotation-api + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + com.fasterxml.jackson.datatype jackson-datatype-hibernate5 @@ -123,20 +121,14 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 - - com.fasterxml.jackson.module - jackson-module-afterburner - com.h2database h2 test - com.jayway.jsonpath - json-path - test - + io.springfox + springfox-oas io.springfox @@ -150,27 +142,18 @@ com.zaxxer HikariCP - - commons-io - commons-io - org.apache.commons commons-lang3 - org.mariadb.jdbc - mariadb-java-client - - - org.junit.jupiter - junit-jupiter-engine + org.testcontainers + mariadb test - org.assertj - assertj-core - test + org.mariadb.jdbc + mariadb-java-client org.hibernate @@ -188,18 +171,18 @@ org.liquibase liquibase-core - - - net.logstash.logback - logstash-logback-encoder + + ${liquibase.version} org.mapstruct mapstruct + ${mapstruct.version} org.mapstruct mapstruct-processor + ${mapstruct.version} provided @@ -215,10 +198,6 @@ org.springframework.boot spring-boot-starter-actuator - - org.springframework.boot - spring-boot-starter-aop - org.springframework.boot spring-boot-starter-data-jpa @@ -245,8 +224,8 @@ test - junit - junit + org.junit.vintage + junit-vintage-engine @@ -287,23 +266,11 @@ org.springframework.boot spring-boot-starter-oauth2-resource-server - - org.springframework.security.oauth - spring-security-oauth2 - - - org.springframework.security - spring-security-jwt - org.springframework.cloud spring-cloud-starter - - org.springframework.cloud - spring-cloud-starter-netflix-ribbon - org.springframework.cloud spring-cloud-starter-netflix-hystrix @@ -312,6 +279,10 @@ org.springframework.retry spring-retry + + org.springframework.cloud + spring-cloud-starter-bootstrap + org.springframework.cloud spring-cloud-starter-consul-discovery @@ -324,10 +295,7 @@ org.springframework.cloud spring-cloud-starter-openfeign - - org.springframework.boot - spring-boot-starter-cloud-connectors - + org.springframework.security spring-security-data @@ -349,72 +317,14 @@ org.apache.maven.plugins maven-compiler-plugin - - ${java.version} - ${java.version} - - - org.springframework.boot - spring-boot-configuration-processor - ${spring-boot.version} - - - org.mapstruct - mapstruct-processor - ${mapstruct.version} - - - - org.hibernate - hibernate-jpamodelgen - ${hibernate.version} - - - org.glassfish.jaxb - jaxb-runtime - ${jaxb-runtime.version} - - - - org.apache.maven.plugins maven-checkstyle-plugin - ${maven-checkstyle.version} - - - com.puppycrawl.tools - checkstyle - ${checkstyle.version} - - - io.spring.nohttp - nohttp-checkstyle - ${spring-nohttp-checkstyle.version} - - - - checkstyle.xml - pom.xml,README.md - .git/**/*,target/**/*,node_modules/**/*,node/**/* - ./ - - - - - check - - - org.apache.maven.plugins maven-javadoc-plugin - ${maven-javadoc-plugin.version} - - ${maven.compiler.source} - org.apache.maven.plugins @@ -455,21 +365,6 @@ org.springframework.boot spring-boot-maven-plugin - - - - repackage - - - - - ${start-class} - true - - com.google.cloud.tools @@ -478,30 +373,119 @@ org.codehaus.mojo properties-maven-plugin - ${properties-maven-plugin.version} - - - initialize - - read-project-properties - - - - sonar-project.properties - - - - + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven-checkstyle.version} + + + com.puppycrawl.tools + checkstyle + ${checkstyle.version} + + + io.spring.nohttp + nohttp-checkstyle + ${spring-nohttp-checkstyle.version} + + + + checkstyle.xml + pom.xml,README.md + .git/**/*,target/**/*,node_modules/**/*,node/**/* + ./ + + + + + check + + + + org.apache.maven.plugins maven-compiler-plugin ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + org.springframework.boot + spring-boot-configuration-processor + ${spring-boot.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + org.hibernate + hibernate-jpamodelgen + ${hibernate.version} + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + ${maven.compiler.source} + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + + default-war + + war + + package + + + + WEB-INF/**,META-INF/** + false + + + + org.codehaus.mojo + properties-maven-plugin + ${properties-maven-plugin.version} + + + initialize + + read-project-properties + + + + sonar-project.properties + + + + + + pl.project13.maven git-commit-id-plugin @@ -534,10 +518,6 @@ prepare-agent - - - ${jacoco.utReportFile} - @@ -546,20 +526,12 @@ report - - ${jacoco.utReportFile} - ${jacoco.utReportFolder} - pre-integration-tests prepare-agent-integration - - - ${jacoco.itReportFile} - @@ -568,10 +540,6 @@ report-integration - - ${jacoco.itReportFile} - ${jacoco.itReportFolder} - @@ -590,7 +558,7 @@ bash - chmod +x /entrypoint.sh && sync && /entrypoint.sh + /entrypoint.sh 8082 @@ -600,7 +568,17 @@ 0 USE_CURRENT_TIMESTAMP + 1000 + + src/main/docker/jib + + + /entrypoint.sh + 755 + + + @@ -623,19 +601,9 @@ - io.github.jhipster - jhipster-framework - ${jhipster-dependencies.version} - - - org.hibernate - hibernate-core - ${hibernate-core.version} - - - org.javassist - javassist - ${javassist.version} + org.liquibase + liquibase-core + ${liquibase.version} org.liquibase.ext @@ -652,26 +620,16 @@ validation-api ${validation-api.version} + + org.javassist + javassist + ${javassist.version} + com.h2database h2 ${h2.version} - - org.springframework - spring-core - ${spring.version} - - - org.springframework - spring-context - ${spring.version} - - - org.springframework - spring-beans - ${spring.version} - @@ -718,8 +676,8 @@ [${maven.version},) - You are running an incompatible version of Java. JHipster supports JDK 8 to 13. - [1.8,14) + You are running an incompatible version of Java. JHipster supports JDK 8 to 15. + [1.8,16) @@ -776,7 +734,6 @@ alphabetical - ${junit.utReportFolder} **/*IT* **/*IntTest* @@ -793,7 +750,6 @@ ${project.build.outputDirectory} alphabetical - ${junit.itReportFolder} **/*IT* **/*IntTest* @@ -823,6 +779,22 @@ org.springframework.boot spring-boot-maven-plugin ${spring-boot.version} + + + + repackage + + + + + ${start-class} + true + + + @@ -836,9 +808,9 @@ - swagger + api-docs - ,swagger + ,api-docs @@ -895,9 +867,6 @@ org.springframework.boot spring-boot-maven-plugin - - ${start-class} - @@ -914,7 +883,7 @@ - prod${profile.swagger}${profile.no-liquibase} + prod${profile.api-docs}${profile.tls}${profile.no-liquibase} @@ -924,19 +893,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} - - - - war - - package - - - - WEB-INF/**,META-INF/** - false - @@ -964,6 +920,7 @@ org.mapstruct mapstruct-processor + ${mapstruct.version} org.hibernate diff --git a/sonar-project.properties b/sonar-project.properties index 4bf3ba5..fdcdfce 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,25 +1,25 @@ -sonar.projectKey=org.securityrat.casemanagement -sonar.projectName=case Management -sonar.projectVersion=0.0.1-SNAPSHOT +sonar.projectKey=caseManagement +sonar.projectName=caseManagement generated by jhipster +sonar.projectVersion=1.0 sonar.sources=src/main/ sonar.host.url=http://localhost:9001 sonar.tests=src/test/ -sonar.coverage.jacoco.xmlReportPaths=target/jacoco/test/jacoco.xml,target/jacoco/integrationTest/jacoco.xml +sonar.coverage.jacoco.xmlReportPaths=target/site/**/jacoco*.xml sonar.java.codeCoveragePlugin=jacoco -sonar.junit.reportPaths=target/test-results/test,target/test-results/integrationTest +sonar.junit.reportPaths=target/surefire-reports,target/failsafe-reports sonar.sourceEncoding=UTF-8 sonar.exclusions=src/main/webapp/content/**/*.*, src/main/webapp/i18n/*.js, target/classes/static/**/*.* sonar.issue.ignore.multicriteria=S3437,S4684,UndocumentedApi -# Rule https://sonarcloud.io/coding_rules?open=squid%3AS3437&rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient +# Rule https://rules.sonarsource.com/java/RSPEC-3437 is ignored, as a JPA-managed field cannot be transient sonar.issue.ignore.multicriteria.S3437.resourceKey=src/main/java/**/* sonar.issue.ignore.multicriteria.S3437.ruleKey=squid:S3437 -# Rule https://sonarcloud.io/coding_rules?open=squid%3AUndocumentedApi&rule_key=squid%3AUndocumentedApi is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names should be self-explanatory +# Rule https://rules.sonarsource.com/java/RSPEC-1176 is ignored, as we want to follow "clean code" guidelines and classes, methods and arguments names should be self-explanatory sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey=src/main/java/**/* sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey=squid:UndocumentedApi -# Rule https://sonarcloud.io/coding_rules?open=squid%3AS4684&rule_key=squid%3AS4684 +# Rule https://rules.sonarsource.com/java/RSPEC-4684 sonar.issue.ignore.multicriteria.S4684.resourceKey=src/main/java/**/* -sonar.issue.ignore.multicriteria.S4684.ruleKey=squid:S4684 +sonar.issue.ignore.multicriteria.S4684.ruleKey=java:S4684 diff --git a/src/main/docker/app.yml b/src/main/docker/app.yml index 9f766b3..eed6a30 100644 --- a/src/main/docker/app.yml +++ b/src/main/docker/app.yml @@ -1,28 +1,52 @@ -version: '2' +# This configuration is intended for development purpose, it's **your** responsibility to harden it for production +version: '3.8' services: casemanagement-app: image: casemanagement environment: - _JAVA_OPTIONS=-Xmx512m -Xms256m - - SPRING_PROFILES_ACTIVE=prod,swagger + - SPRING_PROFILES_ACTIVE=prod,api-docs - MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED=true - SPRING_CLOUD_CONSUL_HOST=consul - SPRING_CLOUD_CONSUL_PORT=8500 - - SPRING_DATASOURCE_URL=jdbc:mariadb://casemanagement-mariadb:3306/casemanagement + - SPRING_DATASOURCE_URL=jdbc:mariadb://casemanagement-mariadb:3306/casemanagement?useLegacyDatetimeCode=false&serverTimezone=UTC + - SPRING_LIQUIBASE_URL=jdbc:mariadb://casemanagement-mariadb:3306/casemanagement?useLegacyDatetimeCode=false&serverTimezone=UTC - SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI=http://keycloak:9080/auth/realms/jhipster - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID=internal - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET=internal - JHIPSTER_SLEEP=120 # gives time for mariadb server to start casemanagement-mariadb: - extends: - file: mariadb.yml - service: casemanagement-mariadb + image: mariadb:10.5.9 + # volumes: + # - ~/volumes/jhipster/caseManagement/mysql/:/var/lib/mysql/ + environment: + - MYSQL_USER=root + - MYSQL_ALLOW_EMPTY_PASSWORD=yes + - MYSQL_DATABASE=casemanagement + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix + ports: + - 127.0.0.1:3306:3306 + command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8mb4 --explicit_defaults_for_timestamp consul: - extends: - file: consul.yml - service: consul + image: consul:1.9.4 + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix + ports: + - 127.0.0.1:8300:8300 + - 127.0.0.1:8500:8500 + - 127.0.0.1:8600:8600 + command: consul agent -dev -ui -client 0.0.0.0 -log-level=INFO consul-config-loader: - extends: - file: consul.yml - service: consul-config-loader + image: jhipster/consul-config-loader:v0.4.1 + volumes: + - ./central-server-config:/config + environment: + - INIT_SLEEP_SECONDS=5 + - CONSUL_URL=consul + - CONSUL_PORT=8500 + # Uncomment to load configuration into Consul from a Git repository + # as configured in central-server-config/git2consul.json + # Also set SPRING_CLOUD_CONSUL_CONFIG_FORMAT=files on your apps + # - CONFIG_MODE=git diff --git a/src/main/docker/central-server-config/application.yml b/src/main/docker/central-server-config/application.yml index e2398f0..af04448 100644 --- a/src/main/docker/central-server-config/application.yml +++ b/src/main/docker/central-server-config/application.yml @@ -6,4 +6,5 @@ jhipster: security: authentication: jwt: - secret: my-secret-key-which-should-be-changed-in-production-and-be-base64-encoded + # secret key which should be base64 encoded and changed in production + base64-secret: ebcc96a1801b3e946498deeae1c992287d454acc diff --git a/src/main/docker/config/git2consul.json b/src/main/docker/config/git2consul.json index dcb9f6b..000854d 100644 --- a/src/main/docker/config/git2consul.json +++ b/src/main/docker/config/git2consul.json @@ -4,7 +4,7 @@ { "name": "config", "url": "https://github.com/jhipster/generator-jhipster.git", - "branches": ["master"], + "branches": ["main"], "include_branch_name": false, "source_root": "generators/server/src/main/docker/config/consul-config/", "hooks": [ diff --git a/src/main/docker/consul.yml b/src/main/docker/consul.yml index 2aa4598..546ac4b 100644 --- a/src/main/docker/consul.yml +++ b/src/main/docker/consul.yml @@ -1,15 +1,18 @@ -version: '2' +# This configuration is intended for development purpose, it's **your** responsibility to harden it for production +version: '3.8' services: consul: - image: consul:1.6.2 + image: consul:1.9.4 + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix ports: - - 8300:8300 - - 8500:8500 - - 8600:8600 - command: consul agent -dev -ui -client 0.0.0.0 + - 127.0.0.1:8300:8300 + - 127.0.0.1:8500:8500 + - 127.0.0.1:8600:8600 + command: consul agent -dev -ui -client 0.0.0.0 -log-level=INFO consul-config-loader: - image: jhipster/consul-config-loader:v0.3.0 + image: jhipster/consul-config-loader:v0.4.1 volumes: - ./central-server-config:/config environment: diff --git a/src/main/docker/jhipster-control-center.yml b/src/main/docker/jhipster-control-center.yml new file mode 100644 index 0000000..7d0d9a9 --- /dev/null +++ b/src/main/docker/jhipster-control-center.yml @@ -0,0 +1,54 @@ +## How to use JHCC docker compose +# To allow JHCC to reach JHipster application from a docker container note that we set the host as host.docker.internal +# To reach the application from a browser, you need to add '127.0.0.1 host.docker.internal' to your hosts file. +### Discovery mode +# JHCC support 3 kinds of discovery mode: Consul, Eureka and static +# In order to use one, please set SPRING_PROFILES_ACTIVE to one (and only one) of this values: consul,eureka,static +### Discovery properties +# According to the discovery mode choose as Spring profile, you have to set the right properties +# please note that current properties are set to run JHCC with default values, personalize them if needed +# and remove those from other modes. You can only have one mode active. +#### Eureka +# - EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://admin:admin@host.docker.internal:8761/eureka/ +#### Consul +# - SPRING_CLOUD_CONSUL_HOST=host.docker.internal +# - SPRING_CLOUD_CONSUL_PORT=8500 +#### Static +# Add instances to "MyApp" +# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYAPP_0_URI=http://host.docker.internal:8081 +# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYAPP_1_URI=http://host.docker.internal:8082 +# Or add a new application named MyNewApp +# - SPRING_CLOUD_DISCOVERY_CLIENT_SIMPLE_INSTANCES_MYNEWAPP_0_URI=http://host.docker.internal:8080 +# This configuration is intended for development purpose, it's **your** responsibility to harden it for production + +#### IMPORTANT +# If you choose Consul or Eureka mode: +# Do not forget to remove the prefix "127.0.0.1" in front of their port in order to expose them. +# This is required because JHCC need to communicate with Consul or Eureka. +# - In Consul mode, the ports are in the consul.yml file. +# - In Eureka mode, the ports are in the jhipster-registry.yml file. + +version: '3.8' +services: + jhipster-control-center: + image: 'jhipster/jhipster-control-center:v0.4.1' + command: + - /bin/sh + - -c + # Patch /etc/hosts to support resolving host.docker.internal to the internal IP address used by the host in all OSes + - echo "`ip route | grep default | cut -d ' ' -f3` host.docker.internal" | tee -a /etc/hosts > /dev/null && java -jar /jhipster-control-center.jar + environment: + - _JAVA_OPTIONS=-Xmx512m -Xms256m + - SPRING_PROFILES_ACTIVE=prod,api-docs,consul,oauth2 + - JHIPSTER_SLEEP=30 # gives time for other services to boot before the application + # For keycloak to work, you need to add '127.0.0.1 keycloak' to your hosts file + - SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_OIDC_ISSUER_URI=http://keycloak:9080/auth/realms/jhipster + - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_ID=jhipster-control-center + - SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_OIDC_CLIENT_SECRET=jhipster-control-center + - SPRING_CLOUD_CONSUL_HOST=host.docker.internal + - SPRING_CLOUD_CONSUL_PORT=8500 + - LOGGING_FILE_NAME=/tmp/jhipster-control-center.log + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix + ports: + - 127.0.0.1:7419:7419 diff --git a/src/main/jib/entrypoint.sh b/src/main/docker/jib/entrypoint.sh similarity index 100% rename from src/main/jib/entrypoint.sh rename to src/main/docker/jib/entrypoint.sh diff --git a/src/main/docker/mariadb.yml b/src/main/docker/mariadb.yml index ea2b077..9a96c98 100644 --- a/src/main/docker/mariadb.yml +++ b/src/main/docker/mariadb.yml @@ -1,13 +1,16 @@ -version: '2' +# This configuration is intended for development purpose, it's **your** responsibility to harden it for production +version: '3.8' services: casemanagement-mariadb: - image: mariadb:10.4.10 + image: mariadb:10.5.9 # volumes: - # - ~/volumes/jhipster/caseManagement/mysql/:/var/lib/mysql/ + # - ~/volumes/jhipster/caseManagement/mysql/:/var/lib/mysql/ environment: - MYSQL_USER=root - MYSQL_ALLOW_EMPTY_PASSWORD=yes - MYSQL_DATABASE=casemanagement + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix ports: - - 3306:3306 + - 127.0.0.1:3306:3306 command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8mb4 --explicit_defaults_for_timestamp diff --git a/src/main/docker/monitoring.yml b/src/main/docker/monitoring.yml index c1ac16e..1c7c1e2 100644 --- a/src/main/docker/monitoring.yml +++ b/src/main/docker/monitoring.yml @@ -1,26 +1,31 @@ -version: '2' +# This configuration is intended for development purpose, it's **your** responsibility to harden it for production +version: '3.8' services: casemanagement-prometheus: - image: prom/prometheus:v2.14.0 + image: prom/prometheus:v2.25.0 volumes: - ./prometheus/:/etc/prometheus/ command: - '--config.file=/etc/prometheus/prometheus.yml' + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix ports: - - 9090:9090 + - 127.0.0.1:9090:9090 # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and # grafana/provisioning/datasources/datasource.yml network_mode: 'host' # to test locally running service casemanagement-grafana: - image: grafana/grafana:6.5.1 + image: grafana/grafana:7.4.3 volumes: - ./grafana/provisioning/:/etc/grafana/provisioning/ environment: - GF_SECURITY_ADMIN_PASSWORD=admin - GF_USERS_ALLOW_SIGN_UP=false - GF_INSTALL_PLUGINS=grafana-piechart-panel + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix ports: - - 3000:3000 + - 127.0.0.1:3000:3000 # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and # grafana/provisioning/datasources/datasource.yml network_mode: 'host' # to test locally running service diff --git a/src/main/docker/sonar.yml b/src/main/docker/sonar.yml index 622d796..8104715 100644 --- a/src/main/docker/sonar.yml +++ b/src/main/docker/sonar.yml @@ -1,7 +1,13 @@ -version: '2' +# This configuration is intended for development purpose, it's **your** responsibility to harden it for production +version: '3.8' services: casemanagement-sonar: - image: sonarqube:7.9.1-community + image: sonarqube:8.7.0-community + # Authentication is turned off for out of the box experience while trying out SonarQube + # For real use cases delete sonar.forceAuthentication variable or set sonar.forceAuthentication=true + environment: + - sonar.forceAuthentication=false + # If you want to expose these ports outside your dev PC, + # remove the "127.0.0.1:" prefix ports: - - 9001:9000 - - 9092:9092 + - 127.0.0.1:9001:9000 diff --git a/src/main/java/org/securityrat/casemanagement/ApplicationWebXml.java b/src/main/java/org/securityrat/casemanagement/ApplicationWebXml.java index 2346a2a..a0a82fd 100644 --- a/src/main/java/org/securityrat/casemanagement/ApplicationWebXml.java +++ b/src/main/java/org/securityrat/casemanagement/ApplicationWebXml.java @@ -1,9 +1,8 @@ package org.securityrat.casemanagement; -import io.github.jhipster.config.DefaultProfileUtil; - import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import tech.jhipster.config.DefaultProfileUtil; /** * This is a helper Java class that provides an alternative to creating a {@code web.xml}. @@ -13,9 +12,7 @@ public class ApplicationWebXml extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - /** - * set a default to use when no profile is configured. - */ + // set a default to use when no profile is configured. DefaultProfileUtil.addDefaultProfile(application.application()); return application.sources(CaseManagementApp.class); } diff --git a/src/main/java/org/securityrat/casemanagement/CaseManagementApp.java b/src/main/java/org/securityrat/casemanagement/CaseManagementApp.java index 46f1405..60793e8 100644 --- a/src/main/java/org/securityrat/casemanagement/CaseManagementApp.java +++ b/src/main/java/org/securityrat/casemanagement/CaseManagementApp.java @@ -1,30 +1,26 @@ package org.securityrat.casemanagement; -import org.securityrat.casemanagement.config.ApplicationProperties; - -import io.github.jhipster.config.DefaultProfileUtil; -import io.github.jhipster.config.JHipsterConstants; - +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Optional; +import javax.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; +import org.securityrat.casemanagement.config.ApplicationProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.core.env.Environment; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Collection; +import tech.jhipster.config.DefaultProfileUtil; +import tech.jhipster.config.JHipsterConstants; @SpringBootApplication -@EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class}) -@EnableDiscoveryClient -public class CaseManagementApp implements InitializingBean { +@EnableConfigurationProperties({ LiquibaseProperties.class, ApplicationProperties.class }) +public class CaseManagementApp { private static final Logger log = LoggerFactory.getLogger(CaseManagementApp.class); @@ -41,16 +37,24 @@ public CaseManagementApp(Environment env) { *

* You can find more information on how profiles work with JHipster on https://www.jhipster.tech/profiles/. */ - @Override - public void afterPropertiesSet() throws Exception { + @PostConstruct + public void initApplication() { Collection activeProfiles = Arrays.asList(env.getActiveProfiles()); - if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) { - log.error("You have misconfigured your application! It should not run " + - "with both the 'dev' and 'prod' profiles at the same time."); + if ( + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION) + ) { + log.error( + "You have misconfigured your application! It should not run " + "with both the 'dev' and 'prod' profiles at the same time." + ); } - if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) { - log.error("You have misconfigured your application! It should not " + - "run with both the 'dev' and 'cloud' profiles at the same time."); + if ( + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && + activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD) + ) { + log.error( + "You have misconfigured your application! It should not " + "run with both the 'dev' and 'cloud' profiles at the same time." + ); } } @@ -67,26 +71,24 @@ public static void main(String[] args) { } private static void logApplicationStartup(Environment env) { - String protocol = "http"; - if (env.getProperty("server.ssl.key-store") != null) { - protocol = "https"; - } + String protocol = Optional.ofNullable(env.getProperty("server.ssl.key-store")).map(key -> "https").orElse("http"); String serverPort = env.getProperty("server.port"); - String contextPath = env.getProperty("server.servlet.context-path"); - if (StringUtils.isBlank(contextPath)) { - contextPath = "/"; - } + String contextPath = Optional + .ofNullable(env.getProperty("server.servlet.context-path")) + .filter(StringUtils::isNotBlank) + .orElse("/"); String hostAddress = "localhost"; try { hostAddress = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException e) { log.warn("The host name could not be determined, using `localhost` as fallback"); } - log.info("\n----------------------------------------------------------\n\t" + - "Application '{}' is running! Access URLs:\n\t" + - "Local: \t\t{}://localhost:{}{}\n\t" + - "External: \t{}://{}:{}{}\n\t" + - "Profile(s): \t{}\n----------------------------------------------------------", + log.info( + "\n----------------------------------------------------------\n\t" + + "Application '{}' is running! Access URLs:\n\t" + + "Local: \t\t{}://localhost:{}{}\n\t" + + "External: \t{}://{}:{}{}\n\t" + + "Profile(s): \t{}\n----------------------------------------------------------", env.getProperty("spring.application.name"), protocol, serverPort, @@ -95,13 +97,17 @@ private static void logApplicationStartup(Environment env) { hostAddress, serverPort, contextPath, - env.getActiveProfiles()); + env.getActiveProfiles() + ); String configServerStatus = env.getProperty("configserver.status"); if (configServerStatus == null) { configServerStatus = "Not found or not setup for this application"; } - log.info("\n----------------------------------------------------------\n\t" + - "Config Server: \t{}\n----------------------------------------------------------", configServerStatus); + log.info( + "\n----------------------------------------------------------\n\t" + + "Config Server: \t{}\n----------------------------------------------------------", + configServerStatus + ); } } diff --git a/src/main/java/org/securityrat/casemanagement/GeneratedByJHipster.java b/src/main/java/org/securityrat/casemanagement/GeneratedByJHipster.java new file mode 100644 index 0000000..2119628 --- /dev/null +++ b/src/main/java/org/securityrat/casemanagement/GeneratedByJHipster.java @@ -0,0 +1,13 @@ +package org.securityrat.casemanagement; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.annotation.Generated; + +@Generated(value = "JHipster", comments = "Generated by JHipster 7.0.0") +@Retention(RetentionPolicy.SOURCE) +@Target({ ElementType.TYPE }) +public @interface GeneratedByJHipster { +} diff --git a/src/main/java/org/securityrat/casemanagement/aop/logging/LoggingAspect.java b/src/main/java/org/securityrat/casemanagement/aop/logging/LoggingAspect.java index e065893..b73510b 100644 --- a/src/main/java/org/securityrat/casemanagement/aop/logging/LoggingAspect.java +++ b/src/main/java/org/securityrat/casemanagement/aop/logging/LoggingAspect.java @@ -1,7 +1,6 @@ package org.securityrat.casemanagement.aop.logging; -import io.github.jhipster.config.JHipsterConstants; - +import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; @@ -12,8 +11,7 @@ import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; - -import java.util.Arrays; +import tech.jhipster.config.JHipsterConstants; /** * Aspect for logging execution of service and repository Spring components. @@ -23,8 +21,6 @@ @Aspect public class LoggingAspect { - private final Logger log = LoggerFactory.getLogger(this.getClass()); - private final Environment env; public LoggingAspect(Environment env) { @@ -34,9 +30,11 @@ public LoggingAspect(Environment env) { /** * Pointcut that matches all repositories, services and Web REST endpoints. */ - @Pointcut("within(@org.springframework.stereotype.Repository *)" + + @Pointcut( + "within(@org.springframework.stereotype.Repository *)" + " || within(@org.springframework.stereotype.Service *)" + - " || within(@org.springframework.web.bind.annotation.RestController *)") + " || within(@org.springframework.web.bind.annotation.RestController *)" + ) public void springBeanPointcut() { // Method is empty as this is just a Pointcut, the implementations are in the advices. } @@ -44,13 +42,25 @@ public void springBeanPointcut() { /** * Pointcut that matches all Spring beans in the application's main packages. */ - @Pointcut("within(org.securityrat.casemanagement.repository..*)"+ - " || within(org.securityrat.casemanagement.service..*)"+ - " || within(org.securityrat.casemanagement.web.rest..*)") + @Pointcut( + "within(org.securityrat.casemanagement.repository..*)" + + " || within(org.securityrat.casemanagement.service..*)" + + " || within(org.securityrat.casemanagement.web.rest..*)" + ) public void applicationPackagePointcut() { // Method is empty as this is just a Pointcut, the implementations are in the advices. } + /** + * Retrieves the {@link Logger} associated to the given {@link JoinPoint}. + * + * @param joinPoint join point we want the logger for. + * @return {@link Logger} associated to the given {@link JoinPoint}. + */ + private Logger logger(JoinPoint joinPoint) { + return LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringTypeName()); + } + /** * Advice that logs methods throwing exceptions. * @@ -60,12 +70,21 @@ public void applicationPackagePointcut() { @AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e") public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) { - log.error("Exception in {}.{}() with cause = \'{}\' and exception = \'{}\'", joinPoint.getSignature().getDeclaringTypeName(), - joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL", e.getMessage(), e); - + logger(joinPoint) + .error( + "Exception in {}() with cause = \'{}\' and exception = \'{}\'", + joinPoint.getSignature().getName(), + e.getCause() != null ? e.getCause() : "NULL", + e.getMessage(), + e + ); } else { - log.error("Exception in {}.{}() with cause = {}", joinPoint.getSignature().getDeclaringTypeName(), - joinPoint.getSignature().getName(), e.getCause() != null? e.getCause() : "NULL"); + logger(joinPoint) + .error( + "Exception in {}() with cause = {}", + joinPoint.getSignature().getName(), + e.getCause() != null ? e.getCause() : "NULL" + ); } } @@ -78,21 +97,18 @@ public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { */ @Around("applicationPackagePointcut() && springBeanPointcut()") public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable { + Logger log = logger(joinPoint); if (log.isDebugEnabled()) { - log.debug("Enter: {}.{}() with argument[s] = {}", joinPoint.getSignature().getDeclaringTypeName(), - joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs())); + log.debug("Enter: {}() with argument[s] = {}", joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs())); } try { Object result = joinPoint.proceed(); if (log.isDebugEnabled()) { - log.debug("Exit: {}.{}() with result = {}", joinPoint.getSignature().getDeclaringTypeName(), - joinPoint.getSignature().getName(), result); + log.debug("Exit: {}() with result = {}", joinPoint.getSignature().getName(), result); } return result; } catch (IllegalArgumentException e) { - log.error("Illegal argument: {} in {}.{}()", Arrays.toString(joinPoint.getArgs()), - joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName()); - + log.error("Illegal argument: {} in {}()", Arrays.toString(joinPoint.getArgs()), joinPoint.getSignature().getName()); throw e; } } diff --git a/src/main/java/org/securityrat/casemanagement/client/AuthorizedFeignClient.java b/src/main/java/org/securityrat/casemanagement/client/AuthorizedFeignClient.java index d589ae4..31d75f1 100644 --- a/src/main/java/org/securityrat/casemanagement/client/AuthorizedFeignClient.java +++ b/src/main/java/org/securityrat/casemanagement/client/AuthorizedFeignClient.java @@ -1,17 +1,15 @@ package org.securityrat.casemanagement.client; +import java.lang.annotation.*; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClientsConfiguration; import org.springframework.core.annotation.AliasFor; -import java.lang.annotation.*; - @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @FeignClient public @interface AuthorizedFeignClient { - @AliasFor(annotation = FeignClient.class, attribute = "name") String name() default ""; @@ -48,7 +46,7 @@ Class fallback() default void.class; /** - * Path prefix to be used by all method-level mappings. Can be used with or without {@code @RibbonClient}. + * Path prefix to be used by all method-level mappings. * @return the path prefix to be used by all method-level mappings. */ String path() default ""; diff --git a/src/main/java/org/securityrat/casemanagement/client/OAuth2InterceptedFeignConfiguration.java b/src/main/java/org/securityrat/casemanagement/client/OAuth2InterceptedFeignConfiguration.java index 659d076..f304ec9 100644 --- a/src/main/java/org/securityrat/casemanagement/client/OAuth2InterceptedFeignConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/client/OAuth2InterceptedFeignConfiguration.java @@ -1,10 +1,8 @@ package org.securityrat.casemanagement.client; -import org.springframework.context.annotation.Bean; - import feign.RequestInterceptor; - import org.securityrat.casemanagement.security.oauth2.AuthorizationHeaderUtil; +import org.springframework.context.annotation.Bean; public class OAuth2InterceptedFeignConfiguration { diff --git a/src/main/java/org/securityrat/casemanagement/client/RequirementManagementServiceClient.java b/src/main/java/org/securityrat/casemanagement/client/RequirementManagementServiceClient.java deleted file mode 100644 index 0f988b1..0000000 --- a/src/main/java/org/securityrat/casemanagement/client/RequirementManagementServiceClient.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.securityrat.casemanagement.client; - -import java.util.List; - -import org.securityrat.casemanagement.service.dto.*; -import org.springframework.web.bind.annotation.*; - -@AuthorizedFeignClient(name = "requirementManagement") -public interface RequirementManagementServiceClient { - - /** - * Get a list of RequirementSets from requirement management. - * - * @param active - * Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * @return List of RequirementSets as returned by requirement management. - */ - @RequestMapping(value = "/api/requirement-sets") - List getRequirementSetsFromRequirementManagement( - @RequestParam(value = "active.equals") Boolean active); - - /** - * Get a list of Attributes from requirement management, filter by active. - * - * @param active - * Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * @return List of Attributes as returned by requirement management. - */ - @RequestMapping(value = "/api/attributes") - List getAttributesFromRequirementManagement(@RequestParam(value = "active.equals") Boolean active); - - /** - * Get a list of all Attributes from requirement management. - * - * @return List of Attributes as returned by requirement management. - */ - @RequestMapping(value = "/api/attributes") - List getAllAttributesFromRequirementManagement(); - - /** - * Get a list of all ExtensionKeys from requirement management. - * - * param active Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * - * @return List of ExtensionKeys as returned by requirement management. - */ - @RequestMapping(value = "/api/extension-keys") - List getAllExtensionKeysFromRequirementManagement( - @RequestParam(value = "active.equals") Boolean active); - - /** - * Get a list of all Skeletons from requirement management. - * - * param active Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * - * @return List of Skeletons as returned by requirement management. - */ - @RequestMapping(value = "/api/skeletons") - List getAllSkeletonsFromRequirementManagement(@RequestParam(value = "active.equals") Boolean active); - - /** - * Get a list of all Extensions from requirement management. - * - * param active Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * - * @return List of Extensions as returned by requirement management. - */ - @RequestMapping(value = "/api/extensions") - List getAllExtensionsFromRequirementManagement(@RequestParam(value = "active.equals") Boolean active); - - /** - * Get a list of all SkAtEx from requirement management. - * - * param active Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * - * @return List of SkAtEx as returned by requirement management. - */ - @RequestMapping(value = "/api/sk-at-exes") - List getAllSkAtExFromRequirementManagement(@RequestParam(value = "active.equals") Boolean active); - - /** - * Get a list of all AttributeKeys from requirement management. - * - * param active Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * - * @return List of AttributeKeys as returned by requirement management. - */ - @RequestMapping(value = "/api/attribute-keys") - List getAttributeKeysFromRequirementManagement( - @RequestParam(value = "active.equals") Boolean active); - - /** - * Get a list of all AttributeKeys from requirement management. - * - * @param active - * Add the given value of type Boolean as a filter for the field - * 'active' to the request to requirement management - * @param attributeKeyType - * type of the attribute Keys to be requested. - * - * @return List of AttributeKeys as returned by requirement management. - */ - @RequestMapping(value = "/api/attribute-keys") - List getAttributeKeysFromRequirementManagement( - @RequestParam(value = "active.equals") Boolean active, - @RequestParam(value = "type.equals") String attributeKeyType); - - @RequestMapping(value = "/api/sk-at-exes/{id}") - SkAtExDTO getSkAtExById(@RequestParam(value = "id") Integer id); - - @RequestMapping(value = "/api/attributes/{id}") - AttributeDTO getAttributeById(@RequestParam(value = "id") Integer id); - - @RequestMapping(value = "/api/skeletons/{id}") - SkeletonDTO getSkeletonById(@RequestParam(value = "id") Integer id); - - @RequestMapping(value = "/api/extension-keys/{id}") - ExtensionKeyDTO getExtensionKeyById(@RequestParam(value = "id") Integer id); - -} diff --git a/src/main/java/org/securityrat/casemanagement/client/TokenRelayRequestInterceptor.java b/src/main/java/org/securityrat/casemanagement/client/TokenRelayRequestInterceptor.java index 5104c0a..acff2ec 100644 --- a/src/main/java/org/securityrat/casemanagement/client/TokenRelayRequestInterceptor.java +++ b/src/main/java/org/securityrat/casemanagement/client/TokenRelayRequestInterceptor.java @@ -1,11 +1,9 @@ package org.securityrat.casemanagement.client; -import org.securityrat.casemanagement.security.oauth2.AuthorizationHeaderUtil; - import feign.RequestInterceptor; import feign.RequestTemplate; - import java.util.Optional; +import org.securityrat.casemanagement.security.oauth2.AuthorizationHeaderUtil; public class TokenRelayRequestInterceptor implements RequestInterceptor { diff --git a/src/main/java/org/securityrat/casemanagement/config/ApplicationProperties.java b/src/main/java/org/securityrat/casemanagement/config/ApplicationProperties.java index edac8d7..51dbea4 100644 --- a/src/main/java/org/securityrat/casemanagement/config/ApplicationProperties.java +++ b/src/main/java/org/securityrat/casemanagement/config/ApplicationProperties.java @@ -6,8 +6,7 @@ * Properties specific to Case Management. *

* Properties are configured in the {@code application.yml} file. - * See {@link io.github.jhipster.config.JHipsterProperties} for a good example. + * See {@link tech.jhipster.config.JHipsterProperties} for a good example. */ @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) -public class ApplicationProperties { -} +public class ApplicationProperties {} diff --git a/src/main/java/org/securityrat/casemanagement/config/AsyncConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/AsyncConfiguration.java index 30010be..119228b 100644 --- a/src/main/java/org/securityrat/casemanagement/config/AsyncConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/AsyncConfiguration.java @@ -1,6 +1,6 @@ package org.securityrat.casemanagement.config; -import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor; +import java.util.concurrent.Executor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; @@ -12,8 +12,7 @@ import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; - -import java.util.concurrent.Executor; +import tech.jhipster.async.ExceptionHandlingAsyncTaskExecutor; @Configuration @EnableAsync diff --git a/src/main/java/org/securityrat/casemanagement/config/CloudDatabaseConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/CloudDatabaseConfiguration.java deleted file mode 100644 index 61bb763..0000000 --- a/src/main/java/org/securityrat/casemanagement/config/CloudDatabaseConfiguration.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.securityrat.casemanagement.config; - -import io.github.jhipster.config.JHipsterConstants; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.cloud.config.java.AbstractCloudConfig; -import org.springframework.context.annotation.*; - -import javax.sql.DataSource; -import org.springframework.boot.context.properties.ConfigurationProperties; - - -@Configuration -@Profile(JHipsterConstants.SPRING_PROFILE_CLOUD) -public class CloudDatabaseConfiguration extends AbstractCloudConfig { - - private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class); - - private static final String CLOUD_CONFIGURATION_HIKARI_PREFIX = "spring.datasource.hikari"; - - @Bean - @ConfigurationProperties(CLOUD_CONFIGURATION_HIKARI_PREFIX) - public DataSource dataSource() { - log.info("Configuring JDBC datasource from a cloud provider"); - return connectionFactory().dataSource(); - } -} diff --git a/src/main/java/org/securityrat/casemanagement/config/Constants.java b/src/main/java/org/securityrat/casemanagement/config/Constants.java index 8559954..2213540 100644 --- a/src/main/java/org/securityrat/casemanagement/config/Constants.java +++ b/src/main/java/org/securityrat/casemanagement/config/Constants.java @@ -6,12 +6,10 @@ public final class Constants { // Regex for acceptable logins - public static final String LOGIN_REGEX = "^[_.@A-Za-z0-9-]*$"; - - public static final String SYSTEM_ACCOUNT = "system"; + public static final String LOGIN_REGEX = "^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$"; + + public static final String SYSTEM = "system"; public static final String DEFAULT_LANGUAGE = "en"; - public static final String ANONYMOUS_USER = "anonymoususer"; - private Constants() { - } + private Constants() {} } diff --git a/src/main/java/org/securityrat/casemanagement/config/DatabaseConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/DatabaseConfiguration.java index 78fa2d3..1f6c240 100644 --- a/src/main/java/org/securityrat/casemanagement/config/DatabaseConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/DatabaseConfiguration.java @@ -1,19 +1,17 @@ package org.securityrat.casemanagement.config; -import io.github.jhipster.config.JHipsterConstants; -import io.github.jhipster.config.h2.H2ConfigurationHelper; +import java.sql.SQLException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; - import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; - -import java.sql.SQLException; +import tech.jhipster.config.JHipsterConstants; +import tech.jhipster.config.h2.H2ConfigurationHelper; @Configuration @EnableJpaRepositories("org.securityrat.casemanagement.repository") diff --git a/src/main/java/org/securityrat/casemanagement/config/FeignConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/FeignConfiguration.java index 5dd7837..94cdd4d 100644 --- a/src/main/java/org/securityrat/casemanagement/config/FeignConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/FeignConfiguration.java @@ -18,5 +18,4 @@ public class FeignConfiguration { feign.Logger.Level feignLoggerLevel() { return feign.Logger.Level.BASIC; } - } diff --git a/src/main/java/org/securityrat/casemanagement/config/JacksonConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/JacksonConfiguration.java index a83db54..b11a73e 100644 --- a/src/main/java/org/securityrat/casemanagement/config/JacksonConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/JacksonConfiguration.java @@ -3,8 +3,6 @@ import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.module.afterburner.AfterburnerModule; - import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.zalando.problem.ProblemModule; @@ -35,19 +33,11 @@ public Hibernate5Module hibernate5Module() { return new Hibernate5Module(); } - /* - * Jackson Afterburner module to speed up serialization/deserialization. - */ - @Bean - public AfterburnerModule afterburnerModule() { - return new AfterburnerModule(); - } - /* * Module for serialization/deserialization of RFC7807 Problem. */ @Bean - ProblemModule problemModule() { + public ProblemModule problemModule() { return new ProblemModule(); } @@ -55,7 +45,7 @@ ProblemModule problemModule() { * Module for serialization/deserialization of ConstraintViolationProblem. */ @Bean - ConstraintViolationProblemModule constraintViolationProblemModule() { + public ConstraintViolationProblemModule constraintViolationProblemModule() { return new ConstraintViolationProblemModule(); } } diff --git a/src/main/java/org/securityrat/casemanagement/config/LiquibaseConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/LiquibaseConfiguration.java index 16d770f..ce7ce72 100644 --- a/src/main/java/org/securityrat/casemanagement/config/LiquibaseConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/LiquibaseConfiguration.java @@ -1,7 +1,7 @@ package org.securityrat.casemanagement.config; -import io.github.jhipster.config.JHipsterConstants; -import io.github.jhipster.config.liquibase.SpringLiquibaseUtil; +import java.util.concurrent.Executor; +import javax.sql.DataSource; import liquibase.integration.spring.SpringLiquibase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,9 +14,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; - -import javax.sql.DataSource; -import java.util.concurrent.Executor; +import tech.jhipster.config.JHipsterConstants; +import tech.jhipster.config.liquibase.SpringLiquibaseUtil; @Configuration public class LiquibaseConfiguration { @@ -30,13 +29,23 @@ public LiquibaseConfiguration(Environment env) { } @Bean - public SpringLiquibase liquibase(@Qualifier("taskExecutor") Executor executor, - @LiquibaseDataSource ObjectProvider liquibaseDataSource, LiquibaseProperties liquibaseProperties, - ObjectProvider dataSource, DataSourceProperties dataSourceProperties) { - + public SpringLiquibase liquibase( + @Qualifier("taskExecutor") Executor executor, + @LiquibaseDataSource ObjectProvider liquibaseDataSource, + LiquibaseProperties liquibaseProperties, + ObjectProvider dataSource, + DataSourceProperties dataSourceProperties + ) { // If you don't want Liquibase to start asynchronously, substitute by this: // SpringLiquibase liquibase = SpringLiquibaseUtil.createSpringLiquibase(liquibaseDataSource.getIfAvailable(), liquibaseProperties, dataSource.getIfUnique(), dataSourceProperties); - SpringLiquibase liquibase = SpringLiquibaseUtil.createAsyncSpringLiquibase(this.env, executor, liquibaseDataSource.getIfAvailable(), liquibaseProperties, dataSource.getIfUnique(), dataSourceProperties); + SpringLiquibase liquibase = SpringLiquibaseUtil.createAsyncSpringLiquibase( + this.env, + executor, + liquibaseDataSource.getIfAvailable(), + liquibaseProperties, + dataSource.getIfUnique(), + dataSourceProperties + ); liquibase.setChangeLog("classpath:config/liquibase/master.xml"); liquibase.setContexts(liquibaseProperties.getContexts()); liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema()); diff --git a/src/main/java/org/securityrat/casemanagement/config/LocaleConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/LocaleConfiguration.java index a29995e..bbac062 100644 --- a/src/main/java/org/securityrat/casemanagement/config/LocaleConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/LocaleConfiguration.java @@ -1,17 +1,16 @@ package org.securityrat.casemanagement.config; -import io.github.jhipster.config.locale.AngularCookieLocaleResolver; - import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.*; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import tech.jhipster.config.locale.AngularCookieLocaleResolver; @Configuration public class LocaleConfiguration implements WebMvcConfigurer { - @Bean(name = "localeResolver") + @Bean public LocaleResolver localeResolver() { AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver(); cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY"); diff --git a/src/main/java/org/securityrat/casemanagement/config/LoggingAspectConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/LoggingAspectConfiguration.java index 868191f..1d3b842 100644 --- a/src/main/java/org/securityrat/casemanagement/config/LoggingAspectConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/LoggingAspectConfiguration.java @@ -1,11 +1,9 @@ package org.securityrat.casemanagement.config; import org.securityrat.casemanagement.aop.logging.LoggingAspect; - -import io.github.jhipster.config.JHipsterConstants; - import org.springframework.context.annotation.*; import org.springframework.core.env.Environment; +import tech.jhipster.config.JHipsterConstants; @Configuration @EnableAspectJAutoProxy diff --git a/src/main/java/org/securityrat/casemanagement/config/LoggingConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/LoggingConfiguration.java index d315346..562ce6e 100644 --- a/src/main/java/org/securityrat/casemanagement/config/LoggingConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/LoggingConfiguration.java @@ -1,9 +1,12 @@ package org.securityrat.casemanagement.config; +import static tech.jhipster.config.logging.LoggingUtils.*; + import ch.qos.logback.classic.LoggerContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.github.jhipster.config.JHipsterProperties; +import java.util.HashMap; +import java.util.Map; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; @@ -11,11 +14,7 @@ import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.Configuration; - -import java.util.HashMap; -import java.util.Map; - -import static io.github.jhipster.config.logging.LoggingUtils.*; +import tech.jhipster.config.JHipsterProperties; /* * Configures the console and Logstash log appenders from the app properties @@ -24,13 +23,14 @@ @RefreshScope public class LoggingConfiguration { - public LoggingConfiguration(@Value("${spring.application.name}") String appName, - @Value("${server.port}") String serverPort, - JHipsterProperties jHipsterProperties, - ObjectProvider consulRegistration, - ObjectProvider buildProperties, - ObjectMapper mapper) throws JsonProcessingException { - + public LoggingConfiguration( + @Value("${spring.application.name}") String appName, + @Value("${server.port}") String serverPort, + JHipsterProperties jHipsterProperties, + ObjectProvider consulRegistration, + ObjectProvider buildProperties, + ObjectMapper mapper + ) throws JsonProcessingException { LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); Map map = new HashMap<>(); @@ -52,8 +52,5 @@ public LoggingConfiguration(@Value("${spring.application.name}") String appName, if (loggingProperties.isUseJsonFormat() || logstashProperties.isEnabled()) { addContextListener(context, customFields, loggingProperties); } - if (jHipsterProperties.getMetrics().getLogs().isEnabled()) { - setMetricsMarkerLogbackFilter(context, loggingProperties.isUseJsonFormat()); - } } } diff --git a/src/main/java/org/securityrat/casemanagement/config/MethodSecurityConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/MethodSecurityConfiguration.java deleted file mode 100644 index 088d156..0000000 --- a/src/main/java/org/securityrat/casemanagement/config/MethodSecurityConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.securityrat.casemanagement.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; -import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; - -@Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) -public class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { - @Override - protected MethodSecurityExpressionHandler createExpressionHandler() { - return new OAuth2MethodSecurityExpressionHandler(); - } -} diff --git a/src/main/java/org/securityrat/casemanagement/config/SecurityConfiguration.java b/src/main/java/org/securityrat/casemanagement/config/SecurityConfiguration.java index 64170e8..e1525b9 100644 --- a/src/main/java/org/securityrat/casemanagement/config/SecurityConfiguration.java +++ b/src/main/java/org/securityrat/casemanagement/config/SecurityConfiguration.java @@ -1,28 +1,32 @@ package org.securityrat.casemanagement.config; +import java.util.*; import org.securityrat.casemanagement.security.*; - -import io.github.jhipster.config.JHipsterProperties; +import org.securityrat.casemanagement.security.SecurityUtils; +import org.securityrat.casemanagement.security.oauth2.AudienceValidator; +import org.securityrat.casemanagement.security.oauth2.JwtGrantedAuthorityConverter; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; -import org.securityrat.casemanagement.security.oauth2.AudienceValidator; -import org.securityrat.casemanagement.security.SecurityUtils; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator; import org.springframework.security.oauth2.core.OAuth2TokenValidator; import org.springframework.security.oauth2.jwt.*; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.security.core.GrantedAuthority; -import java.util.*; -import org.securityrat.casemanagement.security.oauth2.JwtAuthorityExtractor; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter; import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport; +import tech.jhipster.config.JHipsterProperties; @EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @Import(SecurityProblemSupport.class) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @@ -30,18 +34,16 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private String issuerUri; private final JHipsterProperties jHipsterProperties; - private final JwtAuthorityExtractor jwtAuthorityExtractor; private final SecurityProblemSupport problemSupport; - public SecurityConfiguration(JwtAuthorityExtractor jwtAuthorityExtractor, JHipsterProperties jHipsterProperties, SecurityProblemSupport problemSupport) { + public SecurityConfiguration(JHipsterProperties jHipsterProperties, SecurityProblemSupport problemSupport) { this.problemSupport = problemSupport; - this.jwtAuthorityExtractor = jwtAuthorityExtractor; this.jHipsterProperties = jHipsterProperties; } + @Override public void configure(WebSecurity web) { - web.ignoring() - .antMatchers("/h2-console/**"); + web.ignoring().antMatchers("/h2-console/**"); } @Override @@ -59,7 +61,7 @@ public void configure(HttpSecurity http) throws Exception { .and() .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN) .and() - .featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'") + .featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'self'; payment 'none'") .and() .frameOptions() .deny() @@ -69,26 +71,32 @@ public void configure(HttpSecurity http) throws Exception { .and() .authorizeRequests() .antMatchers("/api/auth-info").permitAll() + .antMatchers("/api/admin/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/api/**").authenticated() .antMatchers("/management/health").permitAll() + .antMatchers("/management/health/**").permitAll() .antMatchers("/management/info").permitAll() .antMatchers("/management/prometheus").permitAll() .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN) .and() .oauth2ResourceServer() .jwt() - .jwtAuthenticationConverter(jwtAuthorityExtractor) + .jwtAuthenticationConverter(authenticationConverter()) .and() .and() .oauth2Client(); // @formatter:on } + Converter authenticationConverter() { + JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); + jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new JwtGrantedAuthorityConverter()); + return jwtAuthenticationConverter; + } @Bean JwtDecoder jwtDecoder() { - NimbusJwtDecoderJwkSupport jwtDecoder = (NimbusJwtDecoderJwkSupport) - JwtDecoders.fromOidcIssuerLocation(issuerUri); + NimbusJwtDecoder jwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(issuerUri); OAuth2TokenValidator audienceValidator = new AudienceValidator(jHipsterProperties.getSecurity().getOauth2().getAudience()); OAuth2TokenValidator withIssuer = JwtValidators.createDefaultWithIssuer(issuerUri); diff --git a/src/main/java/org/securityrat/casemanagement/config/WebConfigurer.java b/src/main/java/org/securityrat/casemanagement/config/WebConfigurer.java index 1abc415..3a652ec 100644 --- a/src/main/java/org/securityrat/casemanagement/config/WebConfigurer.java +++ b/src/main/java/org/securityrat/casemanagement/config/WebConfigurer.java @@ -1,8 +1,6 @@ package org.securityrat.casemanagement.config; -import io.github.jhipster.config.JHipsterConstants; -import io.github.jhipster.config.JHipsterProperties; -import io.github.jhipster.config.h2.H2ConfigurationHelper; +import javax.servlet.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.server.*; @@ -12,11 +10,13 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; +import org.springframework.util.CollectionUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; - -import javax.servlet.*; +import tech.jhipster.config.JHipsterConstants; +import tech.jhipster.config.JHipsterProperties; +import tech.jhipster.config.h2.H2ConfigurationHelper; /** * Configuration of web application with Servlet 3.0 APIs. @@ -40,6 +40,7 @@ public void onStartup(ServletContext servletContext) throws ServletException { if (env.getActiveProfiles().length != 0) { log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles()); } + if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) { initH2Console(servletContext); } @@ -50,11 +51,14 @@ public void onStartup(ServletContext servletContext) throws ServletException { public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = jHipsterProperties.getCors(); - if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) { + if (!CollectionUtils.isEmpty(config.getAllowedOrigins())) { log.debug("Registering CORS filter"); source.registerCorsConfiguration("/api/**", config); source.registerCorsConfiguration("/management/**", config); source.registerCorsConfiguration("/v2/api-docs", config); + source.registerCorsConfiguration("/v3/api-docs", config); + source.registerCorsConfiguration("/swagger-resources", config); + source.registerCorsConfiguration("/swagger-ui/**", config); } return new CorsFilter(source); } @@ -66,5 +70,4 @@ private void initH2Console(ServletContext servletContext) { log.debug("Initialize H2 console"); H2ConfigurationHelper.initH2Console(servletContext); } - } diff --git a/src/main/java/org/securityrat/casemanagement/config/audit/AuditEventConverter.java b/src/main/java/org/securityrat/casemanagement/config/audit/AuditEventConverter.java deleted file mode 100644 index a049c52..0000000 --- a/src/main/java/org/securityrat/casemanagement/config/audit/AuditEventConverter.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.securityrat.casemanagement.config.audit; - -import org.securityrat.casemanagement.domain.PersistentAuditEvent; - -import org.springframework.boot.actuate.audit.AuditEvent; -import org.springframework.security.web.authentication.WebAuthenticationDetails; -import org.springframework.stereotype.Component; - -import java.util.*; - -@Component -public class AuditEventConverter { - - /** - * Convert a list of {@link PersistentAuditEvent}s to a list of {@link AuditEvent}s. - * - * @param persistentAuditEvents the list to convert. - * @return the converted list. - */ - public List convertToAuditEvent(Iterable persistentAuditEvents) { - if (persistentAuditEvents == null) { - return Collections.emptyList(); - } - List auditEvents = new ArrayList<>(); - for (PersistentAuditEvent persistentAuditEvent : persistentAuditEvents) { - auditEvents.add(convertToAuditEvent(persistentAuditEvent)); - } - return auditEvents; - } - - /** - * Convert a {@link PersistentAuditEvent} to an {@link AuditEvent}. - * - * @param persistentAuditEvent the event to convert. - * @return the converted list. - */ - public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) { - if (persistentAuditEvent == null) { - return null; - } - return new AuditEvent(persistentAuditEvent.getAuditEventDate(), persistentAuditEvent.getPrincipal(), - persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData())); - } - - /** - * Internal conversion. This is needed to support the current SpringBoot actuator {@code AuditEventRepository} interface. - * - * @param data the data to convert. - * @return a map of {@link String}, {@link Object}. - */ - public Map convertDataToObjects(Map data) { - Map results = new HashMap<>(); - - if (data != null) { - for (Map.Entry entry : data.entrySet()) { - results.put(entry.getKey(), entry.getValue()); - } - } - return results; - } - - /** - * Internal conversion. This method will allow to save additional data. - * By default, it will save the object as string. - * - * @param data the data to convert. - * @return a map of {@link String}, {@link String}. - */ - public Map convertDataToStrings(Map data) { - Map results = new HashMap<>(); - - if (data != null) { - for (Map.Entry entry : data.entrySet()) { - // Extract the data that will be saved. - if (entry.getValue() instanceof WebAuthenticationDetails) { - WebAuthenticationDetails authenticationDetails = (WebAuthenticationDetails) entry.getValue(); - results.put("remoteAddress", authenticationDetails.getRemoteAddress()); - results.put("sessionId", authenticationDetails.getSessionId()); - } else { - results.put(entry.getKey(), Objects.toString(entry.getValue())); - } - } - } - return results; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/config/audit/package-info.java b/src/main/java/org/securityrat/casemanagement/config/audit/package-info.java deleted file mode 100644 index 033145f..0000000 --- a/src/main/java/org/securityrat/casemanagement/config/audit/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Audit specific code. - */ -package org.securityrat.casemanagement.config.audit; diff --git a/src/main/java/org/securityrat/casemanagement/domain/AbstractAuditingEntity.java b/src/main/java/org/securityrat/casemanagement/domain/AbstractAuditingEntity.java index 6a5e210..14f1725 100644 --- a/src/main/java/org/securityrat/casemanagement/domain/AbstractAuditingEntity.java +++ b/src/main/java/org/securityrat/casemanagement/domain/AbstractAuditingEntity.java @@ -1,21 +1,20 @@ package org.securityrat.casemanagement.domain; import com.fasterxml.jackson.annotation.JsonIgnore; -import org.springframework.data.annotation.CreatedBy; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedBy; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - import java.io.Serializable; import java.time.Instant; import javax.persistence.Column; import javax.persistence.EntityListeners; import javax.persistence.MappedSuperclass; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; /** - * Base abstract class for entities which will hold definitions for created, last modified by and created, - * last modified by date. + * Base abstract class for entities which will hold definitions for created, last modified, created by, + * last modified by attributes. */ @MappedSuperclass @EntityListeners(AuditingEntityListener.class) diff --git a/src/main/java/org/securityrat/casemanagement/domain/AccessToken.java b/src/main/java/org/securityrat/casemanagement/domain/AccessToken.java index 8ee1182..c5fe969 100644 --- a/src/main/java/org/securityrat/casemanagement/domain/AccessToken.java +++ b/src/main/java/org/securityrat/casemanagement/domain/AccessToken.java @@ -1,11 +1,10 @@ package org.securityrat.casemanagement.domain; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import javax.persistence.*; -import javax.validation.constraints.*; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.io.Serializable; import java.time.ZonedDateTime; +import javax.persistence.*; +import javax.validation.constraints.*; /** * A AccessToken. @@ -17,7 +16,8 @@ public class AccessToken implements Serializable { private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") private Long id; @NotNull @@ -27,15 +27,21 @@ public class AccessToken implements Serializable { @Column(name = "expiration_date") private ZonedDateTime expirationDate; + @NotNull + @Column(name = "salt", nullable = false) + private String salt; + + @Column(name = "refresh_token") + private String refreshToken; + @ManyToOne - @JsonIgnoreProperties("accessTokens") private User user; @ManyToOne - @JsonIgnoreProperties("accessTokens") + @JsonIgnoreProperties(value = { "accessTokens" }, allowSetters = true) private TicketSystemInstance ticketInstance; - // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove + // jhipster-needle-entity-add-field - JHipster will add fields here public Long getId() { return id; } @@ -44,8 +50,13 @@ public void setId(Long id) { this.id = id; } + public AccessToken id(Long id) { + this.id = id; + return this; + } + public String getToken() { - return token; + return this.token; } public AccessToken token(String token) { @@ -58,7 +69,7 @@ public void setToken(String token) { } public ZonedDateTime getExpirationDate() { - return expirationDate; + return this.expirationDate; } public AccessToken expirationDate(ZonedDateTime expirationDate) { @@ -70,12 +81,38 @@ public void setExpirationDate(ZonedDateTime expirationDate) { this.expirationDate = expirationDate; } + public String getSalt() { + return this.salt; + } + + public AccessToken salt(String salt) { + this.salt = salt; + return this; + } + + public void setSalt(String salt) { + this.salt = salt; + } + + public String getRefreshToken() { + return this.refreshToken; + } + + public AccessToken refreshToken(String refreshToken) { + this.refreshToken = refreshToken; + return this; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } + public User getUser() { - return user; + return this.user; } public AccessToken user(User user) { - this.user = user; + this.setUser(user); return this; } @@ -84,18 +121,19 @@ public void setUser(User user) { } public TicketSystemInstance getTicketInstance() { - return ticketInstance; + return this.ticketInstance; } public AccessToken ticketInstance(TicketSystemInstance ticketSystemInstance) { - this.ticketInstance = ticketSystemInstance; + this.setTicketInstance(ticketSystemInstance); return this; } public void setTicketInstance(TicketSystemInstance ticketSystemInstance) { this.ticketInstance = ticketSystemInstance; } - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here @Override public boolean equals(Object o) { @@ -110,15 +148,19 @@ public boolean equals(Object o) { @Override public int hashCode() { - return 31; + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); } + // prettier-ignore @Override public String toString() { return "AccessToken{" + "id=" + getId() + ", token='" + getToken() + "'" + ", expirationDate='" + getExpirationDate() + "'" + + ", salt='" + getSalt() + "'" + + ", refreshToken='" + getRefreshToken() + "'" + "}"; } } diff --git a/src/main/java/org/securityrat/casemanagement/domain/Authority.java b/src/main/java/org/securityrat/casemanagement/domain/Authority.java index 4d7ada1..0d4cce0 100644 --- a/src/main/java/org/securityrat/casemanagement/domain/Authority.java +++ b/src/main/java/org/securityrat/casemanagement/domain/Authority.java @@ -1,13 +1,13 @@ package org.securityrat.casemanagement.domain; +import java.io.Serializable; +import java.util.Objects; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; -import javax.persistence.Column; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -import java.io.Serializable; -import java.util.Objects; /** * An authority (a security role) used by Spring Security. @@ -48,6 +48,7 @@ public int hashCode() { return Objects.hashCode(name); } + // prettier-ignore @Override public String toString() { return "Authority{" + diff --git a/src/main/java/org/securityrat/casemanagement/domain/PersistentAuditEvent.java b/src/main/java/org/securityrat/casemanagement/domain/PersistentAuditEvent.java deleted file mode 100644 index bf997bf..0000000 --- a/src/main/java/org/securityrat/casemanagement/domain/PersistentAuditEvent.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.securityrat.casemanagement.domain; - -import javax.persistence.*; -import javax.validation.constraints.NotNull; -import java.io.Serializable; -import java.time.Instant; -import java.util.HashMap; -import java.util.Map; - -/** - * Persist AuditEvent managed by the Spring Boot actuator. - * - * @see org.springframework.boot.actuate.audit.AuditEvent - */ -@Entity -@Table(name = "jhi_persistent_audit_event") -public class PersistentAuditEvent implements Serializable { - - private static final long serialVersionUID = 1L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "event_id") - private Long id; - - @NotNull - @Column(nullable = false) - private String principal; - - @Column(name = "event_date") - private Instant auditEventDate; - - @Column(name = "event_type") - private String auditEventType; - - @ElementCollection - @MapKeyColumn(name = "name") - @Column(name = "value") - @CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id")) - private Map data = new HashMap<>(); - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getPrincipal() { - return principal; - } - - public void setPrincipal(String principal) { - this.principal = principal; - } - - public Instant getAuditEventDate() { - return auditEventDate; - } - - public void setAuditEventDate(Instant auditEventDate) { - this.auditEventDate = auditEventDate; - } - - public String getAuditEventType() { - return auditEventType; - } - - public void setAuditEventType(String auditEventType) { - this.auditEventType = auditEventType; - } - - public Map getData() { - return data; - } - - public void setData(Map data) { - this.data = data; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof PersistentAuditEvent)) { - return false; - } - return id != null && id.equals(((PersistentAuditEvent) o).id); - } - - @Override - public int hashCode() { - return 31; - } - - @Override - public String toString() { - return "PersistentAuditEvent{" + - "principal='" + principal + '\'' + - ", auditEventDate=" + auditEventDate + - ", auditEventType='" + auditEventType + '\'' + - '}'; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/domain/TicketSystemInstance.java b/src/main/java/org/securityrat/casemanagement/domain/TicketSystemInstance.java index 851118d..0028fd6 100644 --- a/src/main/java/org/securityrat/casemanagement/domain/TicketSystemInstance.java +++ b/src/main/java/org/securityrat/casemanagement/domain/TicketSystemInstance.java @@ -1,12 +1,11 @@ package org.securityrat.casemanagement.domain; -import javax.persistence.*; -import javax.validation.constraints.*; - +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.io.Serializable; import java.util.HashSet; import java.util.Set; - +import javax.persistence.*; +import javax.validation.constraints.*; import org.securityrat.casemanagement.domain.enumeration.TicketSystem; /** @@ -19,7 +18,8 @@ public class TicketSystemInstance implements Serializable { private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") private Long id; @Column(name = "name") @@ -34,10 +34,20 @@ public class TicketSystemInstance implements Serializable { @Column(name = "url", nullable = false) private String url; + @Column(name = "consumer_key") + private String consumerKey; + + @Column(name = "client_id") + private String clientId; + + @Column(name = "client_secret") + private String clientSecret; + @OneToMany(mappedBy = "ticketInstance") + @JsonIgnoreProperties(value = { "user", "ticketInstance" }, allowSetters = true) private Set accessTokens = new HashSet<>(); - // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove + // jhipster-needle-entity-add-field - JHipster will add fields here public Long getId() { return id; } @@ -46,8 +56,13 @@ public void setId(Long id) { this.id = id; } + public TicketSystemInstance id(Long id) { + this.id = id; + return this; + } + public String getName() { - return name; + return this.name; } public TicketSystemInstance name(String name) { @@ -60,7 +75,7 @@ public void setName(String name) { } public TicketSystem getType() { - return type; + return this.type; } public TicketSystemInstance type(TicketSystem type) { @@ -73,7 +88,7 @@ public void setType(TicketSystem type) { } public String getUrl() { - return url; + return this.url; } public TicketSystemInstance url(String url) { @@ -85,12 +100,51 @@ public void setUrl(String url) { this.url = url; } + public String getConsumerKey() { + return this.consumerKey; + } + + public TicketSystemInstance consumerKey(String consumerKey) { + this.consumerKey = consumerKey; + return this; + } + + public void setConsumerKey(String consumerKey) { + this.consumerKey = consumerKey; + } + + public String getClientId() { + return this.clientId; + } + + public TicketSystemInstance clientId(String clientId) { + this.clientId = clientId; + return this; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return this.clientSecret; + } + + public TicketSystemInstance clientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return this; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + public Set getAccessTokens() { - return accessTokens; + return this.accessTokens; } public TicketSystemInstance accessTokens(Set accessTokens) { - this.accessTokens = accessTokens; + this.setAccessTokens(accessTokens); return this; } @@ -107,9 +161,16 @@ public TicketSystemInstance removeAccessToken(AccessToken accessToken) { } public void setAccessTokens(Set accessTokens) { + if (this.accessTokens != null) { + this.accessTokens.forEach(i -> i.setTicketInstance(null)); + } + if (accessTokens != null) { + accessTokens.forEach(i -> i.setTicketInstance(this)); + } this.accessTokens = accessTokens; } - // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove + + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here @Override public boolean equals(Object o) { @@ -124,9 +185,11 @@ public boolean equals(Object o) { @Override public int hashCode() { - return 31; + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); } + // prettier-ignore @Override public String toString() { return "TicketSystemInstance{" + @@ -134,6 +197,9 @@ public String toString() { ", name='" + getName() + "'" + ", type='" + getType() + "'" + ", url='" + getUrl() + "'" + + ", consumerKey='" + getConsumerKey() + "'" + + ", clientId='" + getClientId() + "'" + + ", clientSecret='" + getClientSecret() + "'" + "}"; } } diff --git a/src/main/java/org/securityrat/casemanagement/domain/User.java b/src/main/java/org/securityrat/casemanagement/domain/User.java index 3a08af7..b781fe4 100644 --- a/src/main/java/org/securityrat/casemanagement/domain/User.java +++ b/src/main/java/org/securityrat/casemanagement/domain/User.java @@ -1,23 +1,21 @@ package org.securityrat.casemanagement.domain; -import org.securityrat.casemanagement.config.Constants; - import com.fasterxml.jackson.annotation.JsonIgnore; -import org.apache.commons.lang3.StringUtils; -import org.hibernate.annotations.BatchSize; - +import java.io.Serializable; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; import javax.persistence.*; import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; -import java.io.Serializable; -import java.util.HashSet; -import java.util.Locale; -import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.hibernate.annotations.BatchSize; +import org.securityrat.casemanagement.config.Constants; /** - * A appUser. + * A user. */ @Entity @Table(name = "jhi_user") @@ -63,9 +61,9 @@ public class User extends AbstractAuditingEntity implements Serializable { @ManyToMany @JoinTable( name = "jhi_user_authority", - joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, - inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name")}) - + joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") }, + inverseJoinColumns = { @JoinColumn(name = "authority_name", referencedColumnName = "name") } + ) @BatchSize(size = 20) private Set authorities = new HashSet<>(); @@ -118,7 +116,7 @@ public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } - public boolean getActivated() { + public boolean isActivated() { return activated; } @@ -155,9 +153,11 @@ public boolean equals(Object o) { @Override public int hashCode() { - return 31; + // see https://vladmihalcea.com/how-to-implement-equals-and-hashcode-using-the-jpa-entity-identifier/ + return getClass().hashCode(); } + // prettier-ignore @Override public String toString() { return "User{" + diff --git a/src/main/java/org/securityrat/casemanagement/domain/enumeration/AttributeType.java b/src/main/java/org/securityrat/casemanagement/domain/enumeration/AttributeType.java deleted file mode 100644 index 9993bcf..0000000 --- a/src/main/java/org/securityrat/casemanagement/domain/enumeration/AttributeType.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.securityrat.casemanagement.domain.enumeration; - -/** - * The AttributeType enumeration. - */ -public enum AttributeType { - FE_TAG, PARAMETER, CATEGORY -} diff --git a/src/main/java/org/securityrat/casemanagement/domain/enumeration/ExtensionSection.java b/src/main/java/org/securityrat/casemanagement/domain/enumeration/ExtensionSection.java deleted file mode 100644 index 1c2ea65..0000000 --- a/src/main/java/org/securityrat/casemanagement/domain/enumeration/ExtensionSection.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.securityrat.casemanagement.domain.enumeration; - -public enum ExtensionSection { - STATUS, ENHANCEMENT -} diff --git a/src/main/java/org/securityrat/casemanagement/domain/enumeration/ExtensionType.java b/src/main/java/org/securityrat/casemanagement/domain/enumeration/ExtensionType.java deleted file mode 100644 index d8258a2..0000000 --- a/src/main/java/org/securityrat/casemanagement/domain/enumeration/ExtensionType.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.securityrat.casemanagement.domain.enumeration; - -/** - * The extension type enumeration - * - */ -public enum ExtensionType { - ENUM,FREETEXT -} diff --git a/src/main/java/org/securityrat/casemanagement/domain/enumeration/TicketSystem.java b/src/main/java/org/securityrat/casemanagement/domain/enumeration/TicketSystem.java index 3bd33ee..cb80891 100644 --- a/src/main/java/org/securityrat/casemanagement/domain/enumeration/TicketSystem.java +++ b/src/main/java/org/securityrat/casemanagement/domain/enumeration/TicketSystem.java @@ -4,5 +4,5 @@ * The TicketSystem enumeration. */ public enum TicketSystem { - JIRA + JIRA, } diff --git a/src/main/java/org/securityrat/casemanagement/repository/AccessTokenRepository.java b/src/main/java/org/securityrat/casemanagement/repository/AccessTokenRepository.java index c0676fa..ba81e06 100644 --- a/src/main/java/org/securityrat/casemanagement/repository/AccessTokenRepository.java +++ b/src/main/java/org/securityrat/casemanagement/repository/AccessTokenRepository.java @@ -1,15 +1,16 @@ package org.securityrat.casemanagement.repository; +import java.util.List; import org.securityrat.casemanagement.domain.AccessToken; import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.Repository; - /** - * Spring Data repository for the AccessToken entity. + * Spring Data SQL repository for the AccessToken entity. */ @SuppressWarnings("unused") @Repository public interface AccessTokenRepository extends JpaRepository { - + @Query("select accessToken from AccessToken accessToken where accessToken.user.login = ?#{principal.preferredUsername}") + List findByUserIsCurrentUser(); } diff --git a/src/main/java/org/securityrat/casemanagement/repository/AuthorityRepository.java b/src/main/java/org/securityrat/casemanagement/repository/AuthorityRepository.java index aa346eb..93d350c 100644 --- a/src/main/java/org/securityrat/casemanagement/repository/AuthorityRepository.java +++ b/src/main/java/org/securityrat/casemanagement/repository/AuthorityRepository.java @@ -1,11 +1,9 @@ package org.securityrat.casemanagement.repository; import org.securityrat.casemanagement.domain.Authority; - import org.springframework.data.jpa.repository.JpaRepository; /** * Spring Data JPA repository for the {@link Authority} entity. */ -public interface AuthorityRepository extends JpaRepository { -} +public interface AuthorityRepository extends JpaRepository {} diff --git a/src/main/java/org/securityrat/casemanagement/repository/CustomAuditEventRepository.java b/src/main/java/org/securityrat/casemanagement/repository/CustomAuditEventRepository.java deleted file mode 100644 index 3da6fc0..0000000 --- a/src/main/java/org/securityrat/casemanagement/repository/CustomAuditEventRepository.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.securityrat.casemanagement.repository; - -import org.securityrat.casemanagement.config.Constants; -import org.securityrat.casemanagement.config.audit.AuditEventConverter; -import org.securityrat.casemanagement.domain.PersistentAuditEvent; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.actuate.audit.AuditEvent; -import org.springframework.boot.actuate.audit.AuditEventRepository; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.time.Instant; -import java.util.*; - -/** - * An implementation of Spring Boot's {@link AuditEventRepository}. - */ -@Repository -public class CustomAuditEventRepository implements AuditEventRepository { - - private static final String AUTHORIZATION_FAILURE = "AUTHORIZATION_FAILURE"; - - /** - * Should be the same as in Liquibase migration. - */ - protected static final int EVENT_DATA_COLUMN_MAX_LENGTH = 255; - - private final PersistenceAuditEventRepository persistenceAuditEventRepository; - - private final AuditEventConverter auditEventConverter; - - private final Logger log = LoggerFactory.getLogger(getClass()); - - public CustomAuditEventRepository(PersistenceAuditEventRepository persistenceAuditEventRepository, - AuditEventConverter auditEventConverter) { - - this.persistenceAuditEventRepository = persistenceAuditEventRepository; - this.auditEventConverter = auditEventConverter; - } - - @Override - public List find(String principal, Instant after, String type) { - Iterable persistentAuditEvents = - persistenceAuditEventRepository.findByPrincipalAndAuditEventDateAfterAndAuditEventType(principal, after, type); - return auditEventConverter.convertToAuditEvent(persistentAuditEvents); - } - - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public void add(AuditEvent event) { - if (!AUTHORIZATION_FAILURE.equals(event.getType()) && - !Constants.ANONYMOUS_USER.equals(event.getPrincipal())) { - - PersistentAuditEvent persistentAuditEvent = new PersistentAuditEvent(); - persistentAuditEvent.setPrincipal(event.getPrincipal()); - persistentAuditEvent.setAuditEventType(event.getType()); - persistentAuditEvent.setAuditEventDate(event.getTimestamp()); - Map eventData = auditEventConverter.convertDataToStrings(event.getData()); - persistentAuditEvent.setData(truncate(eventData)); - persistenceAuditEventRepository.save(persistentAuditEvent); - } - } - - /** - * Truncate event data that might exceed column length. - */ - private Map truncate(Map data) { - Map results = new HashMap<>(); - - if (data != null) { - for (Map.Entry entry : data.entrySet()) { - String value = entry.getValue(); - if (value != null) { - int length = value.length(); - if (length > EVENT_DATA_COLUMN_MAX_LENGTH) { - value = value.substring(0, EVENT_DATA_COLUMN_MAX_LENGTH); - log.warn("Event data for {} too long ({}) has been truncated to {}. Consider increasing column width.", - entry.getKey(), length, EVENT_DATA_COLUMN_MAX_LENGTH); - } - } - results.put(entry.getKey(), value); - } - } - return results; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/repository/PersistenceAuditEventRepository.java b/src/main/java/org/securityrat/casemanagement/repository/PersistenceAuditEventRepository.java deleted file mode 100644 index 702baaa..0000000 --- a/src/main/java/org/securityrat/casemanagement/repository/PersistenceAuditEventRepository.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.securityrat.casemanagement.repository; - -import org.securityrat.casemanagement.domain.PersistentAuditEvent; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.time.Instant; -import java.util.List; - -/** - * Spring Data JPA repository for the {@link PersistentAuditEvent} entity. - */ -public interface PersistenceAuditEventRepository extends JpaRepository { - - List findByPrincipal(String principal); - - List findByPrincipalAndAuditEventDateAfterAndAuditEventType(String principal, Instant after, String type); - - Page findAllByAuditEventDateBetween(Instant fromDate, Instant toDate, Pageable pageable); - - List findByAuditEventDateBefore(Instant before); -} diff --git a/src/main/java/org/securityrat/casemanagement/repository/TicketSystemInstanceRepository.java b/src/main/java/org/securityrat/casemanagement/repository/TicketSystemInstanceRepository.java index 0fbeb99..9973246 100644 --- a/src/main/java/org/securityrat/casemanagement/repository/TicketSystemInstanceRepository.java +++ b/src/main/java/org/securityrat/casemanagement/repository/TicketSystemInstanceRepository.java @@ -4,12 +4,9 @@ import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.Repository; - /** - * Spring Data repository for the TicketSystemInstance entity. + * Spring Data SQL repository for the TicketSystemInstance entity. */ @SuppressWarnings("unused") @Repository -public interface TicketSystemInstanceRepository extends JpaRepository { - -} +public interface TicketSystemInstanceRepository extends JpaRepository {} diff --git a/src/main/java/org/securityrat/casemanagement/repository/UserRepository.java b/src/main/java/org/securityrat/casemanagement/repository/UserRepository.java index 0b10459..e5c28c7 100644 --- a/src/main/java/org/securityrat/casemanagement/repository/UserRepository.java +++ b/src/main/java/org/securityrat/casemanagement/repository/UserRepository.java @@ -1,36 +1,23 @@ package org.securityrat.casemanagement.repository; +import java.util.List; +import java.util.Optional; import org.securityrat.casemanagement.domain.User; - import org.springframework.data.domain.Page; - import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; -import java.util.List; -import java.util.Optional; -import java.time.Instant; - /** * Spring Data JPA repository for the {@link User} entity. */ @Repository public interface UserRepository extends JpaRepository { - - Optional findOneByEmailIgnoreCase(String email); - Optional findOneByLogin(String login); - @EntityGraph(attributePaths = "authorities") - Optional findOneWithAuthoritiesById(Long id); - @EntityGraph(attributePaths = "authorities") Optional findOneWithAuthoritiesByLogin(String login); - @EntityGraph(attributePaths = "authorities") - Optional findOneWithAuthoritiesByEmailIgnoreCase(String email); - - Page findAllByLoginNot(Pageable pageable, String login); + Page findAllByIdNotNullAndActivatedIsTrue(Pageable pageable); } diff --git a/src/main/java/org/securityrat/casemanagement/security/AuthoritiesConstants.java b/src/main/java/org/securityrat/casemanagement/security/AuthoritiesConstants.java index 924381d..a6a3a3c 100644 --- a/src/main/java/org/securityrat/casemanagement/security/AuthoritiesConstants.java +++ b/src/main/java/org/securityrat/casemanagement/security/AuthoritiesConstants.java @@ -11,6 +11,5 @@ public final class AuthoritiesConstants { public static final String ANONYMOUS = "ROLE_ANONYMOUS"; - private AuthoritiesConstants() { - } + private AuthoritiesConstants() {} } diff --git a/src/main/java/org/securityrat/casemanagement/security/SecurityUtils.java b/src/main/java/org/securityrat/casemanagement/security/SecurityUtils.java index 19aab77..e1f2f84 100644 --- a/src/main/java/org/securityrat/casemanagement/security/SecurityUtils.java +++ b/src/main/java/org/securityrat/casemanagement/security/SecurityUtils.java @@ -1,5 +1,8 @@ package org.securityrat.casemanagement.security; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -9,92 +12,80 @@ import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - /** * Utility class for Spring Security. */ public final class SecurityUtils { - private SecurityUtils() { - } + private SecurityUtils() {} /** - * Get the login of the current appUser. + * Get the login of the current user. * - * @return the login of the current appUser. + * @return the login of the current user. */ public static Optional getCurrentUserLogin() { SecurityContext securityContext = SecurityContextHolder.getContext(); - return Optional.ofNullable(securityContext.getAuthentication()) - .map(authentication -> { - if (authentication.getPrincipal() instanceof UserDetails) { - UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); - return springSecurityUser.getUsername(); - } else if (authentication instanceof JwtAuthenticationToken) { - return (String) ((JwtAuthenticationToken)authentication).getToken().getClaims().get("preferred_username"); - } else if (authentication.getPrincipal() instanceof DefaultOidcUser) { - Map attributes = ((DefaultOidcUser) authentication.getPrincipal()).getAttributes(); - if (attributes.containsKey("preferred_username")) { - return (String) attributes.get("preferred_username"); - } - } else if (authentication.getPrincipal() instanceof String) { - return (String) authentication.getPrincipal(); - } - return null; - }); + return Optional.ofNullable(extractPrincipal(securityContext.getAuthentication())); + } + + private static String extractPrincipal(Authentication authentication) { + if (authentication == null) { + return null; + } else if (authentication.getPrincipal() instanceof UserDetails) { + UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); + return springSecurityUser.getUsername(); + } else if (authentication instanceof JwtAuthenticationToken) { + return (String) ((JwtAuthenticationToken) authentication).getToken().getClaims().get("preferred_username"); + } else if (authentication.getPrincipal() instanceof DefaultOidcUser) { + Map attributes = ((DefaultOidcUser) authentication.getPrincipal()).getAttributes(); + if (attributes.containsKey("preferred_username")) { + return (String) attributes.get("preferred_username"); + } + } else if (authentication.getPrincipal() instanceof String) { + return (String) authentication.getPrincipal(); + } + return null; } /** - * Check if a appUser is authenticated. + * Check if a user is authenticated. * - * @return true if the appUser is authenticated, false otherwise. + * @return true if the user is authenticated, false otherwise. */ public static boolean isAuthenticated() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - return authentication != null && - getAuthorities(authentication).noneMatch(AuthoritiesConstants.ANONYMOUS::equals); + return authentication != null && getAuthorities(authentication).noneMatch(AuthoritiesConstants.ANONYMOUS::equals); } /** - * If the current appUser has a specific authority (security role). - *

- * The name of this method comes from the {@code isUserInRole()} method in the Servlet API. + * Checks if the current user has a specific authority. * * @param authority the authority to check. - * @return true if the current appUser has the authority, false otherwise. + * @return true if the current user has the authority, false otherwise. */ - public static boolean isCurrentUserInRole(String authority) { + public static boolean hasCurrentUserThisAuthority(String authority) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - return authentication != null && - getAuthorities(authentication).anyMatch(authority::equals); + return authentication != null && getAuthorities(authentication).anyMatch(authority::equals); } private static Stream getAuthorities(Authentication authentication) { - Collection authorities = authentication instanceof JwtAuthenticationToken ? - extractAuthorityFromClaims(((JwtAuthenticationToken) authentication).getToken().getClaims()) + Collection authorities = authentication instanceof JwtAuthenticationToken + ? extractAuthorityFromClaims(((JwtAuthenticationToken) authentication).getToken().getClaims()) : authentication.getAuthorities(); - return authorities.stream() - .map(GrantedAuthority::getAuthority); + return authorities.stream().map(GrantedAuthority::getAuthority); } public static List extractAuthorityFromClaims(Map claims) { - return mapRolesToGrantedAuthorities( - getRolesFromClaims(claims)); + return mapRolesToGrantedAuthorities(getRolesFromClaims(claims)); } @SuppressWarnings("unchecked") private static Collection getRolesFromClaims(Map claims) { - return (Collection) claims.getOrDefault("groups", - claims.getOrDefault("roles", new ArrayList<>())); + return (Collection) claims.getOrDefault("groups", claims.getOrDefault("roles", new ArrayList<>())); } private static List mapRolesToGrantedAuthorities(Collection roles) { - return roles.stream() - .filter(role -> role.startsWith("ROLE_")) - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); + return roles.stream().filter(role -> role.startsWith("ROLE_")).map(SimpleGrantedAuthority::new).collect(Collectors.toList()); } } diff --git a/src/main/java/org/securityrat/casemanagement/security/SpringSecurityAuditorAware.java b/src/main/java/org/securityrat/casemanagement/security/SpringSecurityAuditorAware.java index 02b0056..c9e8f34 100644 --- a/src/main/java/org/securityrat/casemanagement/security/SpringSecurityAuditorAware.java +++ b/src/main/java/org/securityrat/casemanagement/security/SpringSecurityAuditorAware.java @@ -1,9 +1,7 @@ package org.securityrat.casemanagement.security; -import org.securityrat.casemanagement.config.Constants; - import java.util.Optional; - +import org.securityrat.casemanagement.config.Constants; import org.springframework.data.domain.AuditorAware; import org.springframework.stereotype.Component; @@ -15,6 +13,6 @@ public class SpringSecurityAuditorAware implements AuditorAware { @Override public Optional getCurrentAuditor() { - return Optional.of(SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM_ACCOUNT)); + return Optional.of(SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM)); } } diff --git a/src/main/java/org/securityrat/casemanagement/security/oauth2/AudienceValidator.java b/src/main/java/org/securityrat/casemanagement/security/oauth2/AudienceValidator.java index d403a6b..58c3d9b 100644 --- a/src/main/java/org/securityrat/casemanagement/security/oauth2/AudienceValidator.java +++ b/src/main/java/org/securityrat/casemanagement/security/oauth2/AudienceValidator.java @@ -1,5 +1,6 @@ package org.securityrat.casemanagement.security.oauth2; +import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.oauth2.core.OAuth2Error; @@ -8,11 +9,10 @@ import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.util.Assert; -import java.util.List; - public class AudienceValidator implements OAuth2TokenValidator { + private final Logger log = LoggerFactory.getLogger(AudienceValidator.class); - private OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null); + private final OAuth2Error error = new OAuth2Error("invalid_token", "The required audience is missing", null); private final List allowedAudience; @@ -23,7 +23,7 @@ public AudienceValidator(List allowedAudience) { public OAuth2TokenValidatorResult validate(Jwt jwt) { List audience = jwt.getAudience(); - if(audience.stream().anyMatch(aud -> allowedAudience.contains(aud))) { + if (audience.stream().anyMatch(allowedAudience::contains)) { return OAuth2TokenValidatorResult.success(); } else { log.warn("Invalid audience: {}", audience); diff --git a/src/main/java/org/securityrat/casemanagement/security/oauth2/AuthorizationHeaderUtil.java b/src/main/java/org/securityrat/casemanagement/security/oauth2/AuthorizationHeaderUtil.java index 11cdda4..02a10c1 100644 --- a/src/main/java/org/securityrat/casemanagement/security/oauth2/AuthorizationHeaderUtil.java +++ b/src/main/java/org/securityrat/casemanagement/security/oauth2/AuthorizationHeaderUtil.java @@ -6,7 +6,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; - +import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.securityrat.casemanagement.security.oauth2.OAuthIdpTokenResponseDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,9 +32,6 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - @Component public class AuthorizationHeaderUtil { @@ -52,9 +50,7 @@ public Optional getAuthorizationHeader() { OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication; String name = oauthToken.getName(); String registrationId = oauthToken.getAuthorizedClientRegistrationId(); - OAuth2AuthorizedClient client = clientService.loadAuthorizedClient( - registrationId, - name); + OAuth2AuthorizedClient client = clientService.loadAuthorizedClient(registrationId, name); if (null == client) { throw new OAuth2AuthorizationException(new OAuth2Error("access_denied", "The token is expired", null)); @@ -75,7 +71,6 @@ public Optional getAuthorizationHeader() { String authorizationHeaderValue = String.format("%s %s", tokenType, accessTokenValue); return Optional.of(authorizationHeaderValue); } - } else if (authentication instanceof JwtAuthenticationToken) { JwtAuthenticationToken accessToken = (JwtAuthenticationToken) authentication; String tokenValue = accessToken.getToken().getTokenValue(); @@ -88,11 +83,11 @@ public Optional getAuthorizationHeader() { private String refreshToken(OAuth2AuthorizedClient client, OAuth2AuthenticationToken oauthToken) { OAuth2AccessTokenResponse atr = refreshTokenClient(client); if (atr == null || atr.getAccessToken() == null) { - log.info("Failed to refresh token for appUser"); + log.info("Failed to refresh token for user"); return null; } - OAuth2RefreshToken refreshToken = atr.getRefreshToken() != null ? atr.getRefreshToken(): client.getRefreshToken(); + OAuth2RefreshToken refreshToken = atr.getRefreshToken() != null ? atr.getRefreshToken() : client.getRefreshToken(); OAuth2AuthorizedClient updatedClient = new OAuth2AuthorizedClient( client.getClientRegistration(), client.getPrincipalName(), @@ -105,7 +100,6 @@ private String refreshToken(OAuth2AuthorizedClient client, OAuth2AuthenticationT } private OAuth2AccessTokenResponse refreshTokenClient(OAuth2AuthorizedClient currentClient) { - MultiValueMap formParameters = new LinkedMultiValueMap<>(); formParameters.add(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.REFRESH_TOKEN.getValue()); formParameters.add(OAuth2ParameterNames.REFRESH_TOKEN, currentClient.getRefreshToken().getTokenValue()); @@ -115,7 +109,10 @@ private OAuth2AccessTokenResponse refreshTokenClient(OAuth2AuthorizedClient curr .contentType(MediaType.APPLICATION_FORM_URLENCODED) .body(formParameters); try { - RestTemplate r = restTemplate(currentClient.getClientRegistration().getClientId(), currentClient.getClientRegistration().getClientSecret()); + RestTemplate r = restTemplate( + currentClient.getClientRegistration().getClientId(), + currentClient.getClientRegistration().getClientSecret() + ); ResponseEntity responseEntity = r.exchange(requestEntity, OAuthIdpTokenResponseDTO.class); return toOAuth2AccessTokenResponse(responseEntity.getBody()); } catch (OAuth2AuthorizationException e) { @@ -130,7 +127,8 @@ private OAuth2AccessTokenResponse toOAuth2AccessTokenResponse(OAuthIdpTokenRespo additionalParameters.put("not-before-policy", oAuthIdpResponse.getNotBefore()); additionalParameters.put("refresh_expires_in", oAuthIdpResponse.getRefreshExpiresIn()); additionalParameters.put("session_state", oAuthIdpResponse.getSessionState()); - return OAuth2AccessTokenResponse.withToken(oAuthIdpResponse.getAccessToken()) + return OAuth2AccessTokenResponse + .withToken(oAuthIdpResponse.getAccessToken()) .expiresIn(oAuthIdpResponse.getExpiresIn()) .refreshToken(oAuthIdpResponse.getRefreshToken()) .scopes(Pattern.compile("\\s").splitAsStream(oAuthIdpResponse.getScope()).collect(Collectors.toSet())) @@ -141,9 +139,7 @@ private OAuth2AccessTokenResponse toOAuth2AccessTokenResponse(OAuthIdpTokenRespo private RestTemplate restTemplate(String clientId, String clientSecret) { return restTemplateBuilder - .additionalMessageConverters( - new FormHttpMessageConverter(), - new OAuth2AccessTokenResponseHttpMessageConverter()) + .additionalMessageConverters(new FormHttpMessageConverter(), new OAuth2AccessTokenResponseHttpMessageConverter()) .errorHandler(new OAuth2ErrorResponseErrorHandler()) .basicAuthentication(clientId, clientSecret) .build(); diff --git a/src/main/java/org/securityrat/casemanagement/security/oauth2/JwtAuthorityExtractor.java b/src/main/java/org/securityrat/casemanagement/security/oauth2/JwtGrantedAuthorityConverter.java similarity index 58% rename from src/main/java/org/securityrat/casemanagement/security/oauth2/JwtAuthorityExtractor.java rename to src/main/java/org/securityrat/casemanagement/security/oauth2/JwtGrantedAuthorityConverter.java index 41cbc55..0d1225f 100644 --- a/src/main/java/org/securityrat/casemanagement/security/oauth2/JwtAuthorityExtractor.java +++ b/src/main/java/org/securityrat/casemanagement/security/oauth2/JwtGrantedAuthorityConverter.java @@ -1,21 +1,21 @@ package org.securityrat.casemanagement.security.oauth2; +import java.util.Collection; import org.securityrat.casemanagement.security.SecurityUtils; +import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; -import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; import org.springframework.stereotype.Component; -import java.util.Collection; - @Component -public class JwtAuthorityExtractor extends JwtAuthenticationConverter { +public class JwtGrantedAuthorityConverter implements Converter> { - public JwtAuthorityExtractor() { + public JwtGrantedAuthorityConverter() { + // Bean extracting authority. } @Override - protected Collection extractAuthorities(Jwt jwt) { + public Collection convert(Jwt jwt) { return SecurityUtils.extractAuthorityFromClaims(jwt.getClaims()); } } diff --git a/src/main/java/org/securityrat/casemanagement/security/oauth2/OAuthIdpTokenResponseDTO.java b/src/main/java/org/securityrat/casemanagement/security/oauth2/OAuthIdpTokenResponseDTO.java index f6d1b4d..4dc0a9a 100644 --- a/src/main/java/org/securityrat/casemanagement/security/oauth2/OAuthIdpTokenResponseDTO.java +++ b/src/main/java/org/securityrat/casemanagement/security/oauth2/OAuthIdpTokenResponseDTO.java @@ -1,7 +1,6 @@ package org.securityrat.casemanagement.security.oauth2; import com.fasterxml.jackson.annotation.JsonProperty; - import java.io.Serializable; import java.util.UUID; @@ -41,7 +40,9 @@ public class OAuthIdpTokenResponseDTO implements Serializable { @JsonProperty("refresh_expires_in") private String refreshExpiresIn; - public OAuthIdpTokenResponseDTO() {} + public OAuthIdpTokenResponseDTO() { + // Empty constructor for serialization. + } public String getRefreshExpiresIn() { return refreshExpiresIn; diff --git a/src/main/java/org/securityrat/casemanagement/service/AuditEventService.java b/src/main/java/org/securityrat/casemanagement/service/AuditEventService.java deleted file mode 100644 index 4969ab2..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/AuditEventService.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.securityrat.casemanagement.service; - -import io.github.jhipster.config.JHipsterProperties; -import org.securityrat.casemanagement.config.audit.AuditEventConverter; -import org.securityrat.casemanagement.repository.PersistenceAuditEventRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.actuate.audit.AuditEvent; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Optional; - -/** - * Service for managing audit events. - *

- * This is the default implementation to support SpringBoot Actuator {@code AuditEventRepository}. - */ -@Service -@Transactional -public class AuditEventService { - - private final Logger log = LoggerFactory.getLogger(AuditEventService.class); - - private final JHipsterProperties jHipsterProperties; - - private final PersistenceAuditEventRepository persistenceAuditEventRepository; - - private final AuditEventConverter auditEventConverter; - - public AuditEventService( - PersistenceAuditEventRepository persistenceAuditEventRepository, - AuditEventConverter auditEventConverter, JHipsterProperties jhipsterProperties) { - - this.persistenceAuditEventRepository = persistenceAuditEventRepository; - this.auditEventConverter = auditEventConverter; - this.jHipsterProperties = jhipsterProperties; - } - - /** - * Old audit events should be automatically deleted after 30 days. - * - * This is scheduled to get fired at 12:00 (am). - */ - @Scheduled(cron = "0 0 12 * * ?") - public void removeOldAuditEvents() { - persistenceAuditEventRepository - .findByAuditEventDateBefore(Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod(), ChronoUnit.DAYS)) - .forEach(auditEvent -> { - log.debug("Deleting audit data {}", auditEvent); - persistenceAuditEventRepository.delete(auditEvent); - }); - } - - public Page findAll(Pageable pageable) { - return persistenceAuditEventRepository.findAll(pageable) - .map(auditEventConverter::convertToAuditEvent); - } - - public Page findByDates(Instant fromDate, Instant toDate, Pageable pageable) { - return persistenceAuditEventRepository.findAllByAuditEventDateBetween(fromDate, toDate, pageable) - .map(auditEventConverter::convertToAuditEvent); - } - - public Optional find(Long id) { - return persistenceAuditEventRepository.findById(id) - .map(auditEventConverter::convertToAuditEvent); - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/RequirementManagementAPIService.java b/src/main/java/org/securityrat/casemanagement/service/RequirementManagementAPIService.java deleted file mode 100644 index 2fa46d4..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/RequirementManagementAPIService.java +++ /dev/null @@ -1,427 +0,0 @@ -package org.securityrat.casemanagement.service; - -import org.securityrat.casemanagement.client.RequirementManagementServiceClient; -import org.securityrat.casemanagement.domain.enumeration.AttributeType; -import org.securityrat.casemanagement.domain.enumeration.ExtensionSection; -import org.securityrat.casemanagement.service.dto.*; -import org.securityrat.casemanagement.service.exceptions.IDNotFoundException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.*; -import java.util.stream.Collectors; - -@Service -public class RequirementManagementAPIService { - - private RequirementManagementServiceClient requirementManagementServiceClient; - - private final Logger log = LoggerFactory.getLogger(RequirementManagementAPIService.class); - - @Autowired - public RequirementManagementAPIService(RequirementManagementServiceClient requirementManagementServiceClient) { - this.requirementManagementServiceClient = requirementManagementServiceClient; - } - - public List getActiveRequirementSets() { - return this.requirementManagementServiceClient.getRequirementSetsFromRequirementManagement(true); - } - - public List getActiveAttributes(Long requirementSetId) { - return getActiveAttributes(requirementSetId, null); - } - - public List getActiveAttributeKeys(String type) { - return this.requirementManagementServiceClient.getAttributeKeysFromRequirementManagement(true, type); - } - - /** - * Get active attributes in a given requirement set and with attributes key type - * present in a given list of types - * - * @param requirementSetId the requirement set id - * @param types the list of attribute key types - * @return a list of active attributes - */ - public List getActiveAttributes(Long requirementSetId, List types) { - List result = this.requirementManagementServiceClient - .getAttributesFromRequirementManagement(true); - - if (result != null) { - result.removeIf(attributeDTO -> attributeDTO.getAttributeKey() != null - && !attributeDTO.getAttributeKey().getRequirementSet().getId().equals(requirementSetId)); - result.removeIf(attributeDTO -> attributeDTO.getAttributeKey() != null - && !attributeDTO.getAttributeKey().isActive()); // include only attributes with active attributeKey - // or no attributeKey - if (types != null && !types.isEmpty()) - result.removeIf(attributeDTO -> attributeDTO.getAttributeKey() != null - && !types.contains(attributeDTO.getAttributeKey().getType())); - } - - return unflattenAttributeHierarchy(result); - } - - public List getAttributesByIds(List ids) { - List result = this.requirementManagementServiceClient.getAllAttributesFromRequirementManagement(); - - if (result != null) - result.removeIf(attributeDTO -> !ids.contains(attributeDTO.getId())); - - if (result != null && result.size() < ids.size()) - throw new IDNotFoundException(); // 404 if user requested non-existent ids - - if (result != null) { - result.removeIf(attributeDTO -> !attributeDTO.isActive()); - result.removeIf(attributeDTO -> attributeDTO.getAttributeKey() != null - && !attributeDTO.getAttributeKey().isActive()); // include only attributes with active attributeKey - // or no attributeKey - } - - return unflattenAttributeHierarchy(result); - } - - private List unflattenAttributeHierarchy(List attributeDTOList) { - List result = new LinkedList<>(attributeDTOList); - - // generate a HashMap to map parent relation in result - HashMap> toTreeHelper = new HashMap<>(); // key: parentId, value: list of children - for (AttributeDTO attributeDTO : result) { - if (attributeDTO.getParent() != null) { - Long parentId = attributeDTO.getParent().getId(); - if (parentId != null) { - toTreeHelper.putIfAbsent(parentId, new LinkedList<>()); - toTreeHelper.get(parentId).add(attributeDTO); - } - } - } - - // move children to their parent's list of children (but only if result contains - // both child and parent) - List toRemove = new LinkedList<>(); - for (AttributeDTO possibleParent : result) { - List childAttributes = toTreeHelper.get(possibleParent.getId()); - if (childAttributes != null) { - for (AttributeDTO childAttribute : childAttributes) { - if (result.contains(childAttribute)) { - - if (possibleParent.getChildren() == null) { - possibleParent.setChildren(new LinkedList<>()); - } - possibleParent.getChildren().add(childAttribute); - toRemove.add(childAttribute); - } - } - } - } - - // in case there are cyclic relations this will remove too many elements - result.removeAll(toRemove); - - return result; - } - - /** - * Restructure the given list of attributes to be conform with the - * {@link GenericAttributeGatewayDTO} - * - * @param attributes list of attributes - * @return the generated restructured list - */ - public List generateGatewayAttributeDTO(List attributes) { - List genericGatewayAttributes = new ArrayList<>(); - for (AttributeDTO attrDto : attributes) { - // Checks whether the attribute key is already in array - List foundAttributeKeys = genericGatewayAttributes.stream() - .filter(x -> x.getId().equals(attrDto.getAttributeKey().getId())).collect(Collectors.toList()); - GenericAttributeGatewayDTO genericAttribute; - - if (foundAttributeKeys.isEmpty()) { - // add a new entry to result array - if (attrDto.getAttributeKey() != null) { - genericAttribute = new GenericAttributeGatewayDTO(attrDto.getAttributeKey().getId(), - attrDto.getAttributeKey().getName(), attrDto.getAttributeKey().getType(), - attrDto.getAttributeKey().getDescription(), attrDto.getAttributeKey().getShowOrder()); - List values = new ArrayList<>(); - values.add(attrDto); - genericAttribute.setValues(values); - genericGatewayAttributes.add(genericAttribute); - } - } else { - // update the values array (attributes list for particular attribute key) - genericAttribute = foundAttributeKeys.get(0); - genericAttribute.getValues().add(attrDto); - } - } - return genericGatewayAttributes; - } - - public List getActiveExtensionKeys(Long requirementSetId) { - List activeExtensionKeys = this.requirementManagementServiceClient - .getAllExtensionKeysFromRequirementManagement(true); - activeExtensionKeys.removeIf(ex -> !ex.getRequirementSet().getId().equals(requirementSetId)); - - if (activeExtensionKeys.isEmpty()) { - log.error("Empty list of extension key to requirementSetId {}", requirementSetId); - throw new IDNotFoundException(); - } - - return activeExtensionKeys; - } - - public List getActiveExtensionForReqStructure(Long requirementSetId) { - List result = this.requirementManagementServiceClient - .getAllExtensionsFromRequirementManagement(true); - - result.removeIf(x -> !x.getExtensionKey().getRequirementSet().getId().equals(requirementSetId)); - - return result; - } - - public RequirementStructureDTO generateRequirementStructureDTO(List extensionKeys, - List extensions) { - - RequirementStructureDTO result = new RequirementStructureDTO(true); - - for (ExtensionKeyDTO exKey : extensionKeys) { - switch (exKey.getSection()) { - case ENHANCEMENT: - EnhancementForReqStructureDTO enhacement = new EnhancementForReqStructureDTO(exKey); - result.getEnhancements().add(enhacement); - break; - - case STATUS: - StatusForReqStructureDTO status = new StatusForReqStructureDTO(exKey); - List statusValues = extensions.stream() - .filter(ex -> ex.getExtensionKey().getId().equals(exKey.getId())).collect(Collectors.toList()); - for (GenericExtensionDTO ex : statusValues) { - ExtensionReqStructureDTO value = new ExtensionReqStructureDTO(ex); - status.getValues().add(value); - } - result.getStatus().add(status); - break; - - default: - break; - } - } - return result; - } - - /** - * Adds a AttributeType to the RequirementDTO depending on a given AttributeDTO - * - * @param requirement RequirementDTO we want to add the AttributeType - * @param attributeKey AttributeKey we use to find out the AttributeType - */ - private void addAttributeTypesToRequirement(RequirementDTO requirement, AttributeKeyDTO attributeKey) { - - switch (attributeKey.getType()) { - case FE_TAG: - if (requirement.getFeTags() == null) { - requirement.setFeTags(new ArrayList<>()); - } - if (!requirement.getFeTags().contains(attributeKey.getId())) { - requirement.getFeTags().add(attributeKey.getId()); - } - break; - - case PARAMETER: - if (requirement.getParameters() == null) { - requirement.setParameters(new ArrayList<>()); - } - if (!requirement.getParameters().contains(attributeKey.getId())) { - - requirement.getParameters().add(attributeKey.getId()); - } - - break; - - case CATEGORY: - requirement.setCatergoryId(attributeKey.getId()); - break; - } - } - - /** - * Adds Extensions to the RequirementDTO depending on a given ExtensionDTO - */ - - private void addExtensionsToRequirement(RequirementDTO requirement, ExtensionReqDTO extension) { - ExtensionSection extensionType = extension.getExtensionKey().getSection(); - if (extensionType == ExtensionSection.STATUS) { - boolean extensionKeyFound = false; - boolean extensionFound = false; - - if (requirement.getStatus() == null) { - requirement.setStatus(new ArrayList<>()); - } - - // search if we have already have the extension Key in Our list - for (StatusForReqDTO status : requirement.getStatus()) { - if (status.getKeyId().equals(extension.getExtensionKey().getId())) { - extensionKeyFound = true; - break; - } - } - - // if we didn't find it yet we add the Extension and the extensionKey - if (!extensionKeyFound) { - StatusForReqDTO tempStatus = new StatusForReqDTO(); - tempStatus.setKeyId(extension.getExtensionKey().getId()); - tempStatus.setValues(new ArrayList<>()); - tempStatus.getValues().add(extension.getId()); - requirement.getStatus().add(tempStatus); - } else { - - // if we already have the extensionKey in our list, we need to check if we - // have all extension with the extensiionKey - for (StatusForReqDTO status : requirement.getStatus()) { - if (status.getKeyId().equals(extension.getExtensionKey().getId())) { - for (Long value : status.getValues()) { - if (extension.getId().equals(value)) { - extensionFound = true; - break; - } - } - if (!extensionFound) { - // if the extension isn't in the list we add it - status.getValues().add(extension.getId()); - } - } - } - } - - } else if (extensionType == ExtensionSection.ENHANCEMENT) { - boolean enhancementExtensionKeyFound = false; - boolean enhancementExtensionFound = false; - - if (requirement.getEnhancements() == null) { - requirement.setEnhancements(new ArrayList<>()); - } - - // search if we have already have the extension Key in Our list - for (EnhancementForReqDTO enhancement : requirement.getEnhancements()) { - if (enhancement.getKeyId().equals(extension.getExtensionKey().getId())) { - enhancementExtensionKeyFound = true; - break; - } - } - // if we didn't find it yet we add the Extension and the extensionKey. - // before adding we build up the content - if (!enhancementExtensionKeyFound) { - EnhancementForReqDTO tempEnhancement = new EnhancementForReqDTO(); - GenericExtensionDTO tempExtension = new GenericExtensionDTO(); - - tempEnhancement.setKeyId(extension.getExtensionKey().getId()); - tempEnhancement.setContents(new ArrayList<>()); - - tempExtension.setId(extension.getId()); - tempExtension.setShowOrder(extension.getShowOrder()); - tempExtension.setContent(extension.getContent()); - - tempEnhancement.getContents().add(tempExtension); - - requirement.getEnhancements().add(tempEnhancement); - - } else { - // if we already have the extensionKey in our list, we need to check if we - // have all extension with the extensiionKey - for (EnhancementForReqDTO enhancement : requirement.getEnhancements()) { - - if (enhancement.getKeyId().equals(extension.getExtensionKey().getId())) { - for (GenericExtensionDTO extensionWithoutDescDTO : enhancement.getContents()) { - if (extension.getId().equals(extensionWithoutDescDTO.getId())) { - enhancementExtensionFound = true; - break; - } - } - if (!enhancementExtensionFound) { - // if the extension isn't in the list we add it - // before adding we build up the extension - EnhancementForReqDTO tempEnhancement = new EnhancementForReqDTO(); - GenericExtensionDTO tempExtension = new GenericExtensionDTO(); - - tempEnhancement.setKeyId(extension.getExtensionKey().getId()); - tempExtension.setId(extension.getId()); - tempExtension.setContent(extension.getContent()); - tempExtension.setShowOrder(extension.getShowOrder()); - - enhancement.getContents().add(tempExtension); - } - } - } - } - } - } - - /** - * Return a List of Requirements which have requested conditions. - * - * @param requirementSetId Id of RequirementSet we want to search for the Requirement - * @param parameters Id of Parameters the Requirement - * @return RequirementsDTO which has all the requested conditions - */ - public List getActiveRequirements(Long requirementSetId, List parameters) { - // TODO: currently we only build up the requirements without paying attention to the parameters - - HashSet skeletonHashSet = new HashSet<>(); - HashSet attributeHashSet = new HashSet<>(); - HashSet extensionHashSet = new HashSet<>(); - HashSet attributeKeyHashSet = new HashSet<>(); - HashSet extensionKeyHashSet = new HashSet<>(); - List result = new ArrayList<>(); - - List skAtExDTOs = this.requirementManagementServiceClient - .getAllSkAtExFromRequirementManagement(true); - skAtExDTOs.removeIf(skAtExDTO -> !skAtExDTO.getSkeleton().getRequirementSet().getId().equals(requirementSetId)); - - for (SkAtExDTO skAtExDTO : skAtExDTOs) { - if (skAtExDTO.getSkeleton() != null) { - skeletonHashSet.add(skAtExDTO.getSkeleton()); - } - - if (skAtExDTO.getAttribute() != null) { - attributeHashSet.add(skAtExDTO.getAttribute()); - } - - if (skAtExDTO.getAttribute() != null && skAtExDTO.getAttribute().getAttributeKey() != null) { - attributeKeyHashSet.add(skAtExDTO.getAttribute().getAttributeKey()); - } - - if (skAtExDTO.getExtension() != null && skAtExDTO.getExtension().getExtensionKey() != null) { - extensionKeyHashSet.add(skAtExDTO.getExtension().getExtensionKey()); - } - - if (skAtExDTO.getExtension() != null) { - extensionHashSet.add(skAtExDTO.getExtension()); - } - } - - for (SkeletonDTO skeletonDTO : skeletonHashSet) { - RequirementDTO tempRequirement = new RequirementDTO(); - tempRequirement.setId(skeletonDTO.getId()); - tempRequirement.setName(skeletonDTO.getName()); - tempRequirement.setDescription(skeletonDTO.getDescription()); - tempRequirement.setShowOrder(skeletonDTO.getShowOrder()); - - for (SkAtExDTO skAtExDTO : skAtExDTOs) { - if (skAtExDTO.getSkeleton().getId().equals(skeletonDTO.getId())) { - if (skAtExDTO.getAttribute() != null && skAtExDTO.getAttribute().getAttributeKey() != null) { - addAttributeTypesToRequirement(tempRequirement, skAtExDTO.getAttribute().getAttributeKey()); - } - - if (skAtExDTO.getExtension() != null && skAtExDTO.getExtension().getExtensionKey() != null) { - addExtensionsToRequirement(tempRequirement, skAtExDTO.getExtension()); - } - } - } - - result.add(tempRequirement); - } - - return result; - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/UserService.java b/src/main/java/org/securityrat/casemanagement/service/UserService.java index 567bbdf..ed46403 100644 --- a/src/main/java/org/securityrat/casemanagement/service/UserService.java +++ b/src/main/java/org/securityrat/casemanagement/service/UserService.java @@ -1,13 +1,16 @@ package org.securityrat.casemanagement.service; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; import org.securityrat.casemanagement.config.Constants; import org.securityrat.casemanagement.domain.Authority; import org.securityrat.casemanagement.domain.User; import org.securityrat.casemanagement.repository.AuthorityRepository; import org.securityrat.casemanagement.repository.UserRepository; import org.securityrat.casemanagement.security.SecurityUtils; +import org.securityrat.casemanagement.service.dto.AdminUserDTO; import org.securityrat.casemanagement.service.dto.UserDTO; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -19,10 +22,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.Instant; -import java.util.*; -import java.util.stream.Collectors; - /** * Service class for managing users. */ @@ -32,113 +31,70 @@ public class UserService { private final Logger log = LoggerFactory.getLogger(UserService.class); - private final UserRepository appUserRepository; + private final UserRepository userRepository; private final AuthorityRepository authorityRepository; - public UserService(UserRepository appUserRepository, AuthorityRepository authorityRepository) { - this.appUserRepository = appUserRepository; + public UserService(UserRepository userRepository, AuthorityRepository authorityRepository) { + this.userRepository = userRepository; this.authorityRepository = authorityRepository; } /** - * Update basic information (first name, last name, email, language) for the current appUser. + * Update basic information (first name, last name, email, language) for the current user. * - * @param firstName first name of appUser. - * @param lastName last name of appUser. - * @param email email id of appUser. + * @param firstName first name of user. + * @param lastName last name of user. + * @param email email id of user. * @param langKey language key. - * @param imageUrl image URL of appUser. + * @param imageUrl image URL of user. */ public void updateUser(String firstName, String lastName, String email, String langKey, String imageUrl) { - SecurityUtils.getCurrentUserLogin() - .flatMap(appUserRepository::findOneByLogin) - .ifPresent(appUser -> { - appUser.setFirstName(firstName); - appUser.setLastName(lastName); - if (email != null) { - appUser.setEmail(email.toLowerCase()); - } - appUser.setLangKey(langKey); - appUser.setImageUrl(imageUrl); - log.debug("Changed Information for User: {}", appUser); - }); - } - - /** - * Update all information for a specific appUser, and return the modified appUser. - * - * @param userDTO appUser to update. - * @return updated appUser. - */ - public Optional updateUser(UserDTO userDTO) { - return Optional.of(appUserRepository - .findById(userDTO.getId())) - .filter(Optional::isPresent) - .map(Optional::get) - .map(appUser -> { - appUser.setLogin(userDTO.getLogin().toLowerCase()); - appUser.setFirstName(userDTO.getFirstName()); - appUser.setLastName(userDTO.getLastName()); - if (userDTO.getEmail() != null) { - appUser.setEmail(userDTO.getEmail().toLowerCase()); + SecurityUtils + .getCurrentUserLogin() + .flatMap(userRepository::findOneByLogin) + .ifPresent( + user -> { + user.setFirstName(firstName); + user.setLastName(lastName); + if (email != null) { + user.setEmail(email.toLowerCase()); + } + user.setLangKey(langKey); + user.setImageUrl(imageUrl); + log.debug("Changed Information for User: {}", user); } - appUser.setImageUrl(userDTO.getImageUrl()); - appUser.setActivated(userDTO.isActivated()); - appUser.setLangKey(userDTO.getLangKey()); - Set managedAuthorities = appUser.getAuthorities(); - managedAuthorities.clear(); - userDTO.getAuthorities().stream() - .map(authorityRepository::findById) - .filter(Optional::isPresent) - .map(Optional::get) - .forEach(managedAuthorities::add); - log.debug("Changed Information for User: {}", appUser); - return appUser; - }) - .map(UserDTO::new); - } - - public void deleteUser(String login) { - appUserRepository.findOneByLogin(login).ifPresent(appUser -> { - appUserRepository.delete(appUser); - log.debug("Deleted User: {}", appUser); - }); + ); } @Transactional(readOnly = true) - public Page getAllManagedUsers(Pageable pageable) { - return appUserRepository.findAllByLoginNot(pageable, Constants.ANONYMOUS_USER).map(UserDTO::new); + public Page getAllManagedUsers(Pageable pageable) { + return userRepository.findAll(pageable).map(AdminUserDTO::new); } @Transactional(readOnly = true) - public Optional getUserWithAuthoritiesByLogin(String login) { - return appUserRepository.findOneWithAuthoritiesByLogin(login); + public Page getAllPublicUsers(Pageable pageable) { + return userRepository.findAllByIdNotNullAndActivatedIsTrue(pageable).map(UserDTO::new); } @Transactional(readOnly = true) - public Optional getUserWithAuthorities(Long id) { - return appUserRepository.findOneWithAuthoritiesById(id); - } - - @Transactional(readOnly = true) - public Optional getUserWithAuthorities() { - return SecurityUtils.getCurrentUserLogin().flatMap(appUserRepository::findOneWithAuthoritiesByLogin); + public Optional getUserWithAuthoritiesByLogin(String login) { + return userRepository.findOneWithAuthoritiesByLogin(login); } /** * Gets a list of all the authorities. * @return a list of all the authorities. */ + @Transactional(readOnly = true) public List getAuthorities() { return authorityRepository.findAll().stream().map(Authority::getName).collect(Collectors.toList()); } - private User syncUserWithIdP(Map details, User appUser) { - // save authorities in to sync appUser roles/groups between IdP and JHipster's local database + private User syncUserWithIdP(Map details, User user) { + // save authorities in to sync user roles/groups between IdP and JHipster's local database Collection dbAuthorities = getAuthorities(); - Collection userAuthorities = - appUser.getAuthorities().stream().map(Authority::getName).collect(Collectors.toList()); + Collection userAuthorities = user.getAuthorities().stream().map(Authority::getName).collect(Collectors.toList()); for (String authority : userAuthorities) { if (!dbAuthorities.contains(authority)) { log.debug("Saving authority '{}' in local database", authority); @@ -148,38 +104,37 @@ private User syncUserWithIdP(Map details, User appUser) { } } // save account in to sync users between IdP and JHipster's local database - Optional existingUser = appUserRepository.findOneByLogin(appUser.getLogin()); + Optional existingUser = userRepository.findOneByLogin(user.getLogin()); if (existingUser.isPresent()) { // if IdP sends last updated information, use it to determine if an update should happen if (details.get("updated_at") != null) { Instant dbModifiedDate = existingUser.get().getLastModifiedDate(); - Instant idpModifiedDate = new Date(Long.valueOf((Integer) details.get("updated_at"))).toInstant(); + Instant idpModifiedDate = (Instant) details.get("updated_at"); if (idpModifiedDate.isAfter(dbModifiedDate)) { - log.debug("Updating appUser '{}' in local database", appUser.getLogin()); - updateUser(appUser.getFirstName(), appUser.getLastName(), appUser.getEmail(), - appUser.getLangKey(), appUser.getImageUrl()); + log.debug("Updating user '{}' in local database", user.getLogin()); + updateUser(user.getFirstName(), user.getLastName(), user.getEmail(), user.getLangKey(), user.getImageUrl()); } // no last updated info, blindly update } else { - log.debug("Updating appUser '{}' in local database", appUser.getLogin()); - updateUser(appUser.getFirstName(), appUser.getLastName(), appUser.getEmail(), - appUser.getLangKey(), appUser.getImageUrl()); + log.debug("Updating user '{}' in local database", user.getLogin()); + updateUser(user.getFirstName(), user.getLastName(), user.getEmail(), user.getLangKey(), user.getImageUrl()); } } else { - log.debug("Saving appUser '{}' in local database", appUser.getLogin()); - appUserRepository.save(appUser); + log.debug("Saving user '{}' in local database", user.getLogin()); + userRepository.save(user); } - return appUser; + return user; } /** - * Returns the appUser from an OAuth 2.0 login or resource server with JWT. - * Synchronizes the appUser in the local repository. + * Returns the user from an OAuth 2.0 login or resource server with JWT. + * Synchronizes the user in the local repository. * * @param authToken the authentication token. - * @return the appUser from the authentication. + * @return the user from the authentication. */ - public UserDTO getUserFromAuthentication(AbstractAuthenticationToken authToken) { + @Transactional + public AdminUserDTO getUserFromAuthentication(AbstractAuthenticationToken authToken) { Map attributes; if (authToken instanceof OAuth2AuthenticationToken) { attributes = ((OAuth2AuthenticationToken) authToken).getPrincipal().getAttributes(); @@ -188,65 +143,72 @@ public UserDTO getUserFromAuthentication(AbstractAuthenticationToken authToken) } else { throw new IllegalArgumentException("AuthenticationToken is not OAuth2 or JWT!"); } - User appUser = getUser(attributes); - appUser.setAuthorities(authToken.getAuthorities().stream() - .map(GrantedAuthority::getAuthority) - .map(authority -> { - Authority auth = new Authority(); - auth.setName(authority); - return auth; - }) - .collect(Collectors.toSet())); - return new UserDTO(syncUserWithIdP(attributes, appUser)); + User user = getUser(attributes); + user.setAuthorities( + authToken + .getAuthorities() + .stream() + .map(GrantedAuthority::getAuthority) + .map( + authority -> { + Authority auth = new Authority(); + auth.setName(authority); + return auth; + } + ) + .collect(Collectors.toSet()) + ); + return new AdminUserDTO(syncUserWithIdP(attributes, user)); } private static User getUser(Map details) { - User appUser = new User(); + User user = new User(); + Boolean activated = Boolean.TRUE; // handle resource server JWT, where sub claim is email and uid is ID if (details.get("uid") != null) { - appUser.setId((String) details.get("uid")); - appUser.setLogin((String) details.get("sub")); + user.setId((String) details.get("uid")); + user.setLogin((String) details.get("sub")); } else { - appUser.setId((String) details.get("sub")); + user.setId((String) details.get("sub")); } if (details.get("preferred_username") != null) { - appUser.setLogin(((String) details.get("preferred_username")).toLowerCase()); - } else if (appUser.getLogin() == null) { - appUser.setLogin(appUser.getId()); + user.setLogin(((String) details.get("preferred_username")).toLowerCase()); + } else if (user.getLogin() == null) { + user.setLogin(user.getId()); } if (details.get("given_name") != null) { - appUser.setFirstName((String) details.get("given_name")); + user.setFirstName((String) details.get("given_name")); } if (details.get("family_name") != null) { - appUser.setLastName((String) details.get("family_name")); + user.setLastName((String) details.get("family_name")); } if (details.get("email_verified") != null) { - appUser.setActivated((Boolean) details.get("email_verified")); + activated = (Boolean) details.get("email_verified"); } if (details.get("email") != null) { - appUser.setEmail(((String) details.get("email")).toLowerCase()); + user.setEmail(((String) details.get("email")).toLowerCase()); } else { - appUser.setEmail((String) details.get("sub")); + user.setEmail((String) details.get("sub")); } if (details.get("langKey") != null) { - appUser.setLangKey((String) details.get("langKey")); + user.setLangKey((String) details.get("langKey")); } else if (details.get("locale") != null) { // trim off country code if it exists String locale = (String) details.get("locale"); if (locale.contains("_")) { - locale = locale.substring(0, locale.indexOf("_")); + locale = locale.substring(0, locale.indexOf('_')); } else if (locale.contains("-")) { - locale = locale.substring(0, locale.indexOf("-")); + locale = locale.substring(0, locale.indexOf('-')); } - appUser.setLangKey(locale.toLowerCase()); + user.setLangKey(locale.toLowerCase()); } else { // set langKey to default if not specified by IdP - appUser.setLangKey(Constants.DEFAULT_LANGUAGE); + user.setLangKey(Constants.DEFAULT_LANGUAGE); } if (details.get("picture") != null) { - appUser.setImageUrl((String) details.get("picture")); + user.setImageUrl((String) details.get("picture")); } - appUser.setActivated(true); - return appUser; + user.setActivated(activated); + return user; } } diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/AdminUserDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/AdminUserDTO.java new file mode 100644 index 0000000..ad289bd --- /dev/null +++ b/src/main/java/org/securityrat/casemanagement/service/dto/AdminUserDTO.java @@ -0,0 +1,193 @@ +package org.securityrat.casemanagement.service.dto; + +import java.time.Instant; +import java.util.Set; +import java.util.stream.Collectors; +import javax.validation.constraints.*; +import org.securityrat.casemanagement.config.Constants; +import org.securityrat.casemanagement.domain.Authority; +import org.securityrat.casemanagement.domain.User; + +/** + * A DTO representing a user, with his authorities. + */ +public class AdminUserDTO { + + private String id; + + @NotBlank + @Pattern(regexp = Constants.LOGIN_REGEX) + @Size(min = 1, max = 50) + private String login; + + @Size(max = 50) + private String firstName; + + @Size(max = 50) + private String lastName; + + @Email + @Size(min = 5, max = 254) + private String email; + + @Size(max = 256) + private String imageUrl; + + private boolean activated = false; + + @Size(min = 2, max = 10) + private String langKey; + + private String createdBy; + + private Instant createdDate; + + private String lastModifiedBy; + + private Instant lastModifiedDate; + + private Set authorities; + + public AdminUserDTO() { + // Empty constructor needed for Jackson. + } + + public AdminUserDTO(User user) { + this.id = user.getId(); + this.login = user.getLogin(); + this.firstName = user.getFirstName(); + this.lastName = user.getLastName(); + this.email = user.getEmail(); + this.activated = user.isActivated(); + this.imageUrl = user.getImageUrl(); + this.langKey = user.getLangKey(); + this.createdBy = user.getCreatedBy(); + this.createdDate = user.getCreatedDate(); + this.lastModifiedBy = user.getLastModifiedBy(); + this.lastModifiedDate = user.getLastModifiedDate(); + this.authorities = user.getAuthorities().stream().map(Authority::getName).collect(Collectors.toSet()); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + public boolean isActivated() { + return activated; + } + + public void setActivated(boolean activated) { + this.activated = activated; + } + + public String getLangKey() { + return langKey; + } + + public void setLangKey(String langKey) { + this.langKey = langKey; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public Instant getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(Instant createdDate) { + this.createdDate = createdDate; + } + + public String getLastModifiedBy() { + return lastModifiedBy; + } + + public void setLastModifiedBy(String lastModifiedBy) { + this.lastModifiedBy = lastModifiedBy; + } + + public Instant getLastModifiedDate() { + return lastModifiedDate; + } + + public void setLastModifiedDate(Instant lastModifiedDate) { + this.lastModifiedDate = lastModifiedDate; + } + + public Set getAuthorities() { + return authorities; + } + + public void setAuthorities(Set authorities) { + this.authorities = authorities; + } + + // prettier-ignore + @Override + public String toString() { + return "AdminUserDTO{" + + "login='" + login + '\'' + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", email='" + email + '\'' + + ", imageUrl='" + imageUrl + '\'' + + ", activated=" + activated + + ", langKey='" + langKey + '\'' + + ", createdBy=" + createdBy + + ", createdDate=" + createdDate + + ", lastModifiedBy='" + lastModifiedBy + '\'' + + ", lastModifiedDate=" + lastModifiedDate + + ", authorities=" + authorities + + "}"; + } +} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/AttributeDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/AttributeDTO.java deleted file mode 100644 index 51b7667..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/AttributeDTO.java +++ /dev/null @@ -1,148 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - - -import com.fasterxml.jackson.annotation.JsonProperty; - -import javax.persistence.Lob; -import javax.validation.constraints.NotNull; -import java.io.Serializable; -import java.util.Objects; -import java.util.List; -import java.util.ArrayList; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -/** - * A DTO for the Attribute entity. - */ -public class AttributeDTO implements Serializable { - - private Long id; - - @NotNull - private String name; - - @Lob - private String description; - - private Integer showOrder; - - @NotNull - @JsonIgnore - private Boolean active; - - @JsonIgnore - private AttributeDTO parent; - - @JsonIgnore - private AttributeKeyDTO attributeKey; - - private List children; - - public AttributeDTO() { - children = new ArrayList<>(); - } - - @JsonIgnore - public AttributeDTO getParent() { - return parent; - } - - @JsonProperty - public void setParent(AttributeDTO parent) { - this.parent = parent; - } - - public List getChildren() { - return children; - } - - public void setChildren(List children) { - this.children = children; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Integer getShowOrder() { - return showOrder; - } - - public void setShowOrder(Integer showOrder) { - this.showOrder = showOrder; - } - - @JsonIgnore - public Boolean isActive() { - return active; - } - - @JsonProperty - public void setActive(Boolean active) { - this.active = active; - } - - @JsonIgnore - public AttributeKeyDTO getAttributeKey() { - return attributeKey; - } - - @JsonProperty - public void setAttributeKey(AttributeKeyDTO attributeKey) { - this.attributeKey = attributeKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AttributeDTO attributeDTO = (AttributeDTO) o; - if(attributeDTO.getId() == null || getId() == null) { - return false; - } - return Objects.equals(getId(), attributeDTO.getId()); - } - - @Override - public int hashCode() { - return Objects.hashCode(getId()); - } - - @Override - public String toString() { - return "AttributeDTO{" + - "id=" + getId() + - ", name='" + getName() + "'" + - ", description='" + getDescription() + "'" + - ", showOrder=" + getShowOrder() + - ", active='" + isActive() + "'" + - "}"; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/AttributeKeyDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/AttributeKeyDTO.java deleted file mode 100644 index b891487..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/AttributeKeyDTO.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import javax.validation.constraints.*; -import java.io.Serializable; -import java.util.Objects; -import javax.persistence.Lob; - -import org.securityrat.casemanagement.domain.enumeration.AttributeType; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - - -/** - * A DTO for the AttributeKey entity. - */ -public class AttributeKeyDTO implements Serializable { - - public AttributeKeyDTO() { - } - - public AttributeKeyDTO(Long id, String name, AttributeType type) { - this.id = id; - this.name = name; - this.type = type; - } - public AttributeKeyDTO(Long id, String name, AttributeType type, String description, Integer showOrder) { - this.id = id; - this.name = name; - this.type = type; - this.description = description; - this.showOrder = showOrder; - } - - /** - * - */ - private static final long serialVersionUID = 1L; - - @NotNull - private Long id; - - @NotNull - private String name; - - @Lob - private String description; - - @JsonIgnore - private AttributeType type; - - private Integer showOrder; - - @NotNull - @JsonIgnore - private Boolean active; - - @JsonIgnore - private RequirementSetDTO requirementSet; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @JsonIgnore - public AttributeType getType() { - return type; - } - - @JsonProperty - public void setType(AttributeType type) { - this.type = type; - } - - - public Integer getShowOrder() { - return showOrder; - } - - public void setShowOrder(Integer showOrder) { - this.showOrder = showOrder; - } - - @JsonIgnore - public Boolean isActive() { - return active; - } - - @JsonProperty - public void setActive(Boolean active) { - this.active = active; - } - - @JsonIgnore - public RequirementSetDTO getRequirementSet() { - return requirementSet; - } - - @JsonProperty - public void setRequirementSet(RequirementSetDTO requirementSet) { - this.requirementSet = requirementSet; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AttributeKeyDTO attributeKeyDTO = (AttributeKeyDTO) o; - if(attributeKeyDTO.getId() == null || getId() == null) { - return false; - } - return Objects.equals(getId(), attributeKeyDTO.getId()); - } - - @Override - public int hashCode() { - return Objects.hashCode(getId()); - } - - @Override - public String toString() { - return "AttributeKeyDTO{" + - "id=" + getId() + - ", name='" + getName() + "'" + - ", description='" + getDescription() + "'" + - ", type='" + getType() + "'" + - ", showOrder=" + getShowOrder() + - "}"; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/EnhancementForReqDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/EnhancementForReqDTO.java deleted file mode 100644 index ef91fbd..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/EnhancementForReqDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.List; - -public class EnhancementForReqDTO { - - private Long keyId; - private List contents; - - public Long getKeyId() { - return keyId; - } - - public void setKeyId(Long keyId) { - this.keyId = keyId; - } - - public List getContents() { - return contents; - } - - public void setContents(List contents) { - this.contents = contents; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/EnhancementForReqStructureDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/EnhancementForReqStructureDTO.java deleted file mode 100644 index 27d4c9c..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/EnhancementForReqStructureDTO.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.ArrayList; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties({"type"}) -public class EnhancementForReqStructureDTO extends ExtensionKeyDTO { - - public EnhancementForReqStructureDTO() {} - - public EnhancementForReqStructureDTO(ExtensionKeyDTO exKey) { - this.setId(exKey.getId()); - this.setName(exKey.getName()); - this.setRequirementSet(exKey.getRequirementSet()); - this.setDescription(exKey.getDescription()); - this.setSection(exKey.getSection()); - this.setShowOrder(exKey.getShowOrder()); - this.setType(exKey.getType()); - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionKeyDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionKeyDTO.java deleted file mode 100644 index 12fb2eb..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionKeyDTO.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import org.securityrat.casemanagement.domain.enumeration.ExtensionSection; -import org.securityrat.casemanagement.domain.enumeration.ExtensionType; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -import javax.persistence.Lob; -import javax.validation.constraints.NotNull; - -public class ExtensionKeyDTO { - - @NotNull - private Long id; - - @JsonIgnore - private RequirementSetDTO requirementSet; - - @NotNull - private String name; - - @Lob - private String description; - - @NotNull - @JsonIgnore - private ExtensionSection section; - - private ExtensionType type; - - private Integer showOrder; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - @JsonIgnore - public RequirementSetDTO getRequirementSet() { - return requirementSet; - } - - @JsonProperty - public void setRequirementSet(RequirementSetDTO requirementSet) { - this.requirementSet = requirementSet; - } - - @NotNull - public String getName() { - return name; - } - - public void setName(@NotNull String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @JsonIgnore - public ExtensionSection getSection() { - return section; - } - - @JsonProperty - public void setSection(ExtensionSection section) { - this.section = section; - } - - public ExtensionType getType() { - return type; - } - - public void setType(ExtensionType type) { - this.type = type; - } - - public Integer getShowOrder() { - return showOrder; - } - - public void setShowOrder(Integer showOrder) { - this.showOrder = showOrder; - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionReqDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionReqDTO.java deleted file mode 100644 index 424c8dc..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionReqDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties({"description"}) -public class ExtensionReqDTO extends GenericExtensionDTO { - - public ExtensionReqDTO() {} - - public ExtensionReqDTO(GenericExtensionDTO ex) { - this.setId(ex.getId()); - this.setContent(ex.getContent()); - this.setDescription(ex.getDescription()); - this.setShowOrder(ex.getShowOrder()); - this.setExtensionKey(ex.getExtensionKey()); - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionReqStructureDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionReqStructureDTO.java deleted file mode 100644 index df3ab20..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/ExtensionReqStructureDTO.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties({"extensionKey"}) -public class ExtensionReqStructureDTO extends GenericExtensionDTO { - - public ExtensionReqStructureDTO() {} - - public ExtensionReqStructureDTO(GenericExtensionDTO ex) { - this.setId(ex.getId()); - this.setContent(ex.getContent()); - this.setDescription(ex.getDescription()); - this.setShowOrder(ex.getShowOrder()); - this.setExtensionKey(ex.getExtensionKey()); - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/GenericAttributeGatewayDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/GenericAttributeGatewayDTO.java deleted file mode 100644 index beb4ae9..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/GenericAttributeGatewayDTO.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.List; - -import org.securityrat.casemanagement.domain.enumeration.AttributeType; - -public class GenericAttributeGatewayDTO extends AttributeKeyDTO{ - - private static final long serialVersionUID = 1L; - - public GenericAttributeGatewayDTO(Long id, String name, AttributeType type) { - super(id, name, type); - } - public GenericAttributeGatewayDTO(Long id, String name, AttributeType type, String description, Integer showOrder) { - super(id, name, type, description, showOrder); - } - - - private List values; - - public List getValues() { - return values; - } - - public void setValues(List values) { - this.values = values; - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/GenericExtensionDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/GenericExtensionDTO.java deleted file mode 100644 index 2dc21bf..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/GenericExtensionDTO.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import javax.persistence.Lob; -import javax.validation.constraints.NotNull; - - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class GenericExtensionDTO { - - @NotNull - private Long id; - - @Lob - @NotNull - private String content; - - private Integer showOrder; - - @Lob - private String description; - - @JsonIgnore - private ExtensionKeyDTO extensionKey; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - public Integer getShowOrder() { - return showOrder; - } - - public void setShowOrder(Integer showOrder) { - this.showOrder = showOrder; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @JsonIgnore - public ExtensionKeyDTO getExtensionKey() { - return extensionKey; - } - - @JsonProperty - public void setExtensionKey(ExtensionKeyDTO extensionKey) { - this.extensionKey = extensionKey; - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/RequirementDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/RequirementDTO.java deleted file mode 100644 index 6fc9be5..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/RequirementDTO.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.List; - -public class RequirementDTO { - - private Long id; - private String name; - private String description; - private Integer showOrder; - private List feTags; - private List parameters; - private Long catergoryId; - private List enhancements; - private List status; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Integer getShowOrder() { - return showOrder; - } - - public void setShowOrder(Integer showOrder) { - this.showOrder = showOrder; - } - - public List getFeTags() { - return feTags; - } - - public void setFeTags(List feTags) { - this.feTags = feTags; - } - - public List getParameters() { - return parameters; - } - - public void setParameters(List parameters) { - this.parameters = parameters; - } - - public Long getCatergoryId() { - return catergoryId; - } - - public void setCatergoryId(Long catergoryId) { - this.catergoryId = catergoryId; - } - - public List getEnhancements() { - return enhancements; - } - - public void setEnhancements(List enhancements) { - this.enhancements = enhancements; - } - - public List getStatus() { - return status; - } - - public void setStatus(List status) { - this.status = status; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/RequirementSetDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/RequirementSetDTO.java deleted file mode 100644 index 8fa02cc..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/RequirementSetDTO.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - - -import javax.persistence.Lob; -import javax.validation.constraints.NotNull; -import java.io.Serializable; -import java.util.Objects; - -/** - * A DTO for the (remote) RequirementSet entity. - */ -public class RequirementSetDTO implements Serializable { - - private Long id; - - @NotNull - private String name; - - @Lob - private String description; - - private Integer showOrder; - - @NotNull - private Boolean active; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Integer getShowOrder() { - return showOrder; - } - - public void setShowOrder(Integer showOrder) { - this.showOrder = showOrder; - } - - public Boolean isActive() { - return active; - } - - public void setActive(Boolean active) { - this.active = active; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - RequirementSetDTO requirementSetDTO = (RequirementSetDTO) o; - if(requirementSetDTO.getId() == null || getId() == null) { - return false; - } - return Objects.equals(getId(), requirementSetDTO.getId()); - } - - @Override - public int hashCode() { - return Objects.hashCode(getId()); - } - - @Override - public String toString() { - return "RequirementSetDTO{" + - "id=" + getId() + - ", name='" + getName() + "'" + - ", description='" + getDescription() + "'" + - ", showOrder=" + getShowOrder() + - ", active='" + isActive() + "'" + - "}"; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/RequirementStructureDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/RequirementStructureDTO.java deleted file mode 100644 index 0f3ae41..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/RequirementStructureDTO.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.ArrayList; -import java.util.List; - -public class RequirementStructureDTO { - - public RequirementStructureDTO() { - - } - - public RequirementStructureDTO(boolean init) { - if (init) { - this.enhancements = new ArrayList<>(); - this.status = new ArrayList<>(); - } - } - - private List enhancements; - - private List status; - - public List getEnhancements() { - return enhancements; - } - - public void setEnhancements(List enhancements) { - this.enhancements = enhancements; - } - - public List getStatus() { - return status; - } - - public void setStatus(List status) { - this.status = status; - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/SkAtExDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/SkAtExDTO.java deleted file mode 100644 index 0441bc0..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/SkAtExDTO.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -public class SkAtExDTO { - - private Long id; - private SkeletonDTO skeleton; - private AttributeDTO attribute; - private ExtensionReqDTO extension; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public SkeletonDTO getSkeleton() { - return skeleton; - } - - public void setSkeleton(SkeletonDTO skeleton) { - this.skeleton = skeleton; - } - - public AttributeDTO getAttribute() { - return attribute; - } - - public void setAttribute(AttributeDTO attribute) { - this.attribute = attribute; - } - - public ExtensionReqDTO getExtension() { - return extension; - } - - public void setExtension(ExtensionReqDTO extension) { - this.extension = extension; - } - - - -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/SkeletonDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/SkeletonDTO.java deleted file mode 100644 index d7bd246..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/SkeletonDTO.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.Objects; - -public class SkeletonDTO { - - private boolean active; - private String description; - private Long id; - private String name; - private RequirementSetDTO requirementSet; - private Integer showOrder; - - public boolean isActive() { - return active; - } - - public void setActive(boolean active) { - this.active = active; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public RequirementSetDTO getRequirementSet() { - return requirementSet; - } - - public void setRequirementSet(RequirementSetDTO requirementSet) { - this.requirementSet = requirementSet; - } - - public Integer getShowOrder() { - return showOrder; - } - - public void setShowOrder(Integer showOrder) { - this.showOrder = showOrder; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SkeletonDTO skeletonDTO = (SkeletonDTO) o; - if(skeletonDTO.getId() == null || getId() == null) { - return false; - } - return Objects.equals(getId(), skeletonDTO.getId()); - } - - @Override - public int hashCode() { - return Objects.hashCode(getId()); - } - - @Override - public String toString() { - return "SkeletonDTO{" + - "id=" + getId() + - ", name='" + getName() + '\'' + - ", description='" + getDescription() + '\'' + - ", requirementSet=" + getRequirementSet() + - ", showOrder=" + getShowOrder() + - ", active=" + isActive() + - '}'; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/StatusForReqDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/StatusForReqDTO.java deleted file mode 100644 index abab987..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/StatusForReqDTO.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.List; - -public class StatusForReqDTO { - - private Long keyId; - private List values; - - public Long getKeyId() { - return keyId; - } - - public void setKeyId(Long keyId) { - this.keyId = keyId; - } - - public List getValues() { - return values; - } - - public void setValues(List values) { - this.values = values; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/StatusForReqStructureDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/StatusForReqStructureDTO.java deleted file mode 100644 index e0d5178..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/dto/StatusForReqStructureDTO.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.securityrat.casemanagement.service.dto; - -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -public class StatusForReqStructureDTO extends ExtensionKeyDTO { - - public StatusForReqStructureDTO() {} - - public StatusForReqStructureDTO(ExtensionKeyDTO exKey) { - this.setId(exKey.getId()); - this.setName(exKey.getName()); - this.setRequirementSet(exKey.getRequirementSet()); - this.setDescription(exKey.getDescription()); - this.setSection(exKey.getSection()); - this.setShowOrder(exKey.getShowOrder()); - this.setType(exKey.getType()); - this.values = new ArrayList<>(); - } - - private List values; - - public List getValues() { - return values; - } - - public void setValues(List values) { - this.values = values; - } -} diff --git a/src/main/java/org/securityrat/casemanagement/service/dto/UserDTO.java b/src/main/java/org/securityrat/casemanagement/service/dto/UserDTO.java index 0b21d7b..a337e78 100644 --- a/src/main/java/org/securityrat/casemanagement/service/dto/UserDTO.java +++ b/src/main/java/org/securityrat/casemanagement/service/dto/UserDTO.java @@ -1,75 +1,24 @@ package org.securityrat.casemanagement.service.dto; -import org.securityrat.casemanagement.config.Constants; - -import org.securityrat.casemanagement.domain.Authority; import org.securityrat.casemanagement.domain.User; -import javax.validation.constraints.*; -import java.time.Instant; -import java.util.Set; -import java.util.stream.Collectors; - /** - * A DTO representing a appUser, with his authorities. + * A DTO representing a user, with only the public attributes. */ public class UserDTO { private String id; - @NotBlank - @Pattern(regexp = Constants.LOGIN_REGEX) - @Size(min = 1, max = 50) private String login; - @Size(max = 50) - private String firstName; - - @Size(max = 50) - private String lastName; - - @Email - @Size(min = 5, max = 254) - private String email; - - @Size(max = 256) - private String imageUrl; - - private boolean activated = false; - - @Size(min = 2, max = 10) - private String langKey; - - private String createdBy; - - private Instant createdDate; - - private String lastModifiedBy; - - private Instant lastModifiedDate; - - private Set authorities; - public UserDTO() { // Empty constructor needed for Jackson. } - public UserDTO(User appUser) { - this.id = appUser.getId(); - this.login = appUser.getLogin(); - this.firstName = appUser.getFirstName(); - this.lastName = appUser.getLastName(); - this.email = appUser.getEmail(); - this.activated = appUser.getActivated(); - this.imageUrl = appUser.getImageUrl(); - this.langKey = appUser.getLangKey(); - this.createdBy = appUser.getCreatedBy(); - this.createdDate = appUser.getCreatedDate(); - this.lastModifiedBy = appUser.getLastModifiedBy(); - this.lastModifiedDate = appUser.getLastModifiedDate(); - this.authorities = appUser.getAuthorities().stream() - .map(Authority::getName) - .collect(Collectors.toSet()); + public UserDTO(User user) { + this.id = user.getId(); + // Customize it here if you need, or not, firstName/lastName/etc + this.login = user.getLogin(); } public String getId() { @@ -88,109 +37,12 @@ public void setLogin(String login) { this.login = login; } - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getImageUrl() { - return imageUrl; - } - - public void setImageUrl(String imageUrl) { - this.imageUrl = imageUrl; - } - - public boolean isActivated() { - return activated; - } - - public void setActivated(boolean activated) { - this.activated = activated; - } - - public String getLangKey() { - return langKey; - } - - public void setLangKey(String langKey) { - this.langKey = langKey; - } - - public String getCreatedBy() { - return createdBy; - } - - public void setCreatedBy(String createdBy) { - this.createdBy = createdBy; - } - - public Instant getCreatedDate() { - return createdDate; - } - - public void setCreatedDate(Instant createdDate) { - this.createdDate = createdDate; - } - - public String getLastModifiedBy() { - return lastModifiedBy; - } - - public void setLastModifiedBy(String lastModifiedBy) { - this.lastModifiedBy = lastModifiedBy; - } - - public Instant getLastModifiedDate() { - return lastModifiedDate; - } - - public void setLastModifiedDate(Instant lastModifiedDate) { - this.lastModifiedDate = lastModifiedDate; - } - - public Set getAuthorities() { - return authorities; - } - - public void setAuthorities(Set authorities) { - this.authorities = authorities; - } - + // prettier-ignore @Override public String toString() { return "UserDTO{" + - "login='" + login + '\'' + - ", firstName='" + firstName + '\'' + - ", lastName='" + lastName + '\'' + - ", email='" + email + '\'' + - ", imageUrl='" + imageUrl + '\'' + - ", activated=" + activated + - ", langKey='" + langKey + '\'' + - ", createdBy=" + createdBy + - ", createdDate=" + createdDate + - ", lastModifiedBy='" + lastModifiedBy + '\'' + - ", lastModifiedDate=" + lastModifiedDate + - ", authorities=" + authorities + + "id='" + id + '\'' + + ", login='" + login + '\'' + "}"; } } diff --git a/src/main/java/org/securityrat/casemanagement/service/exceptions/IDNotFoundException.java b/src/main/java/org/securityrat/casemanagement/service/exceptions/IDNotFoundException.java deleted file mode 100644 index 287867c..0000000 --- a/src/main/java/org/securityrat/casemanagement/service/exceptions/IDNotFoundException.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.securityrat.casemanagement.service.exceptions; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(value = HttpStatus.NOT_FOUND) -public class IDNotFoundException extends RuntimeException { -} diff --git a/src/main/java/org/securityrat/casemanagement/service/mapper/UserMapper.java b/src/main/java/org/securityrat/casemanagement/service/mapper/UserMapper.java index 2f71aee..fcb92d4 100644 --- a/src/main/java/org/securityrat/casemanagement/service/mapper/UserMapper.java +++ b/src/main/java/org/securityrat/casemanagement/service/mapper/UserMapper.java @@ -1,14 +1,16 @@ package org.securityrat.casemanagement.service.mapper; +import java.util.*; +import java.util.stream.Collectors; +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapping; +import org.mapstruct.Named; import org.securityrat.casemanagement.domain.Authority; import org.securityrat.casemanagement.domain.User; +import org.securityrat.casemanagement.service.dto.AdminUserDTO; import org.securityrat.casemanagement.service.dto.UserDTO; - import org.springframework.stereotype.Service; -import java.util.*; -import java.util.stream.Collectors; - /** * Mapper for the entity {@link User} and its DTO called {@link UserDTO}. * @@ -19,52 +21,59 @@ public class UserMapper { public List usersToUserDTOs(List users) { - return users.stream() - .filter(Objects::nonNull) - .map(this::userToUserDTO) - .collect(Collectors.toList()); + return users.stream().filter(Objects::nonNull).map(this::userToUserDTO).collect(Collectors.toList()); + } + + public UserDTO userToUserDTO(User user) { + return new UserDTO(user); } - public UserDTO userToUserDTO(User appUser) { - return new UserDTO(appUser); + public List usersToAdminUserDTOs(List users) { + return users.stream().filter(Objects::nonNull).map(this::userToAdminUserDTO).collect(Collectors.toList()); } - public List userDTOsToUsers(List userDTOs) { - return userDTOs.stream() - .filter(Objects::nonNull) - .map(this::userDTOToUser) - .collect(Collectors.toList()); + public AdminUserDTO userToAdminUserDTO(User user) { + return new AdminUserDTO(user); } - public User userDTOToUser(UserDTO userDTO) { + public List userDTOsToUsers(List userDTOs) { + return userDTOs.stream().filter(Objects::nonNull).map(this::userDTOToUser).collect(Collectors.toList()); + } + + public User userDTOToUser(AdminUserDTO userDTO) { if (userDTO == null) { return null; } else { - User appUser = new User(); - appUser.setId(userDTO.getId()); - appUser.setLogin(userDTO.getLogin()); - appUser.setFirstName(userDTO.getFirstName()); - appUser.setLastName(userDTO.getLastName()); - appUser.setEmail(userDTO.getEmail()); - appUser.setImageUrl(userDTO.getImageUrl()); - appUser.setActivated(userDTO.isActivated()); - appUser.setLangKey(userDTO.getLangKey()); + User user = new User(); + user.setId(userDTO.getId()); + user.setLogin(userDTO.getLogin()); + user.setFirstName(userDTO.getFirstName()); + user.setLastName(userDTO.getLastName()); + user.setEmail(userDTO.getEmail()); + user.setImageUrl(userDTO.getImageUrl()); + user.setActivated(userDTO.isActivated()); + user.setLangKey(userDTO.getLangKey()); Set authorities = this.authoritiesFromStrings(userDTO.getAuthorities()); - appUser.setAuthorities(authorities); - return appUser; + user.setAuthorities(authorities); + return user; } } - private Set authoritiesFromStrings(Set authoritiesAsString) { Set authorities = new HashSet<>(); - if(authoritiesAsString != null){ - authorities = authoritiesAsString.stream().map(string -> { - Authority auth = new Authority(); - auth.setName(string); - return auth; - }).collect(Collectors.toSet()); + if (authoritiesAsString != null) { + authorities = + authoritiesAsString + .stream() + .map( + string -> { + Authority auth = new Authority(); + auth.setName(string); + return auth; + } + ) + .collect(Collectors.toSet()); } return authorities; @@ -74,8 +83,67 @@ public User userFromId(String id) { if (id == null) { return null; } - User appUser = new User(); - appUser.setId(id); - return appUser; + User user = new User(); + user.setId(id); + return user; + } + + @Named("id") + @BeanMapping(ignoreByDefault = true) + @Mapping(target = "id", source = "id") + public UserDTO toDtoId(User user) { + if (user == null) { + return null; + } + UserDTO userDto = new UserDTO(); + userDto.setId(user.getId()); + return userDto; + } + + @Named("idSet") + @BeanMapping(ignoreByDefault = true) + @Mapping(target = "id", source = "id") + public Set toDtoIdSet(Set users) { + if (users == null) { + return null; + } + + Set userSet = new HashSet<>(); + for (User userEntity : users) { + userSet.add(this.toDtoId(userEntity)); + } + + return userSet; + } + + @Named("login") + @BeanMapping(ignoreByDefault = true) + @Mapping(target = "id", source = "id") + @Mapping(target = "login", source = "login") + public UserDTO toDtoLogin(User user) { + if (user == null) { + return null; + } + UserDTO userDto = new UserDTO(); + userDto.setId(user.getId()); + userDto.setLogin(user.getLogin()); + return userDto; + } + + @Named("loginSet") + @BeanMapping(ignoreByDefault = true) + @Mapping(target = "id", source = "id") + @Mapping(target = "login", source = "login") + public Set toDtoLoginSet(Set users) { + if (users == null) { + return null; + } + + Set userSet = new HashSet<>(); + for (User userEntity : users) { + userSet.add(this.toDtoLogin(userEntity)); + } + + return userSet; } } diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/AccessTokenResource.java b/src/main/java/org/securityrat/casemanagement/web/rest/AccessTokenResource.java index 7e4633c..5e9a86c 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/AccessTokenResource.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/AccessTokenResource.java @@ -1,13 +1,16 @@ package org.securityrat.casemanagement.web.rest; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; import org.securityrat.casemanagement.domain.AccessToken; import org.securityrat.casemanagement.repository.AccessTokenRepository; import org.securityrat.casemanagement.repository.UserRepository; import org.securityrat.casemanagement.web.rest.errors.BadRequestAlertException; - -import io.github.jhipster.web.util.HeaderUtil; -import io.github.jhipster.web.util.PaginationUtil; -import io.github.jhipster.web.util.ResponseUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -15,16 +18,12 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import java.net.URI; -import java.net.URISyntaxException; - -import java.util.List; -import java.util.Optional; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; /** * REST controller for managing {@link org.securityrat.casemanagement.domain.AccessToken}. @@ -42,11 +41,11 @@ public class AccessTokenResource { private final AccessTokenRepository accessTokenRepository; - private final UserRepository appUserRepository; + private final UserRepository userRepository; - public AccessTokenResource(AccessTokenRepository accessTokenRepository, UserRepository appUserRepository) { + public AccessTokenResource(AccessTokenRepository accessTokenRepository, UserRepository userRepository) { this.accessTokenRepository = accessTokenRepository; - this.appUserRepository = appUserRepository; + this.userRepository = userRepository; } /** @@ -62,49 +61,120 @@ public ResponseEntity createAccessToken(@Valid @RequestBody AccessT if (accessToken.getId() != null) { throw new BadRequestAlertException("A new accessToken cannot already have an ID", ENTITY_NAME, "idexists"); } - if (accessToken.getUser() != null) { - // Save appUser in case it's new and only exists in gateway - appUserRepository.save(accessToken.getUser()); + // Save user in case it's new and only exists in gateway + userRepository.save(accessToken.getUser()); } AccessToken result = accessTokenRepository.save(accessToken); - return ResponseEntity.created(new URI("/api/access-tokens/" + result.getId())) + return ResponseEntity + .created(new URI("/api/access-tokens/" + result.getId())) .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) .body(result); } /** - * {@code PUT /access-tokens} : Updates an existing accessToken. + * {@code PUT /access-tokens/:id} : Updates an existing accessToken. * + * @param id the id of the accessToken to save. * @param accessToken the accessToken to update. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated accessToken, * or with status {@code 400 (Bad Request)} if the accessToken is not valid, * or with status {@code 500 (Internal Server Error)} if the accessToken couldn't be updated. * @throws URISyntaxException if the Location URI syntax is incorrect. */ - @PutMapping("/access-tokens") - public ResponseEntity updateAccessToken(@Valid @RequestBody AccessToken accessToken) throws URISyntaxException { - log.debug("REST request to update AccessToken : {}", accessToken); + @PutMapping("/access-tokens/{id}") + public ResponseEntity updateAccessToken( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody AccessToken accessToken + ) throws URISyntaxException { + log.debug("REST request to update AccessToken : {}, {}", id, accessToken); if (accessToken.getId() == null) { throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); } + if (!Objects.equals(id, accessToken.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!accessTokenRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } if (accessToken.getUser() != null) { - // Save appUser in case it's new and only exists in gateway - appUserRepository.save(accessToken.getUser()); + // Save user in case it's new and only exists in gateway + userRepository.save(accessToken.getUser()); } AccessToken result = accessTokenRepository.save(accessToken); - return ResponseEntity.ok() + return ResponseEntity + .ok() .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, accessToken.getId().toString())) .body(result); } /** - * {@code GET /access-tokens} : get all the accessTokens. + * {@code PATCH /access-tokens/:id} : Partial updates given fields of an existing accessToken, field will ignore if it is null * + * @param id the id of the accessToken to save. + * @param accessToken the accessToken to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated accessToken, + * or with status {@code 400 (Bad Request)} if the accessToken is not valid, + * or with status {@code 404 (Not Found)} if the accessToken is not found, + * or with status {@code 500 (Internal Server Error)} if the accessToken couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/access-tokens/{id}", consumes = "application/merge-patch+json") + public ResponseEntity partialUpdateAccessToken( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody AccessToken accessToken + ) throws URISyntaxException { + log.debug("REST request to partial update AccessToken partially : {}, {}", id, accessToken); + if (accessToken.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, accessToken.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } - * @param pageable the pagination information. + if (!accessTokenRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + if (accessToken.getUser() != null) { + // Save user in case it's new and only exists in gateway + userRepository.save(accessToken.getUser()); + } + + Optional result = accessTokenRepository + .findById(accessToken.getId()) + .map( + existingAccessToken -> { + if (accessToken.getToken() != null) { + existingAccessToken.setToken(accessToken.getToken()); + } + if (accessToken.getExpirationDate() != null) { + existingAccessToken.setExpirationDate(accessToken.getExpirationDate()); + } + if (accessToken.getSalt() != null) { + existingAccessToken.setSalt(accessToken.getSalt()); + } + if (accessToken.getRefreshToken() != null) { + existingAccessToken.setRefreshToken(accessToken.getRefreshToken()); + } + + return existingAccessToken; + } + ) + .map(accessTokenRepository::save); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, accessToken.getId().toString()) + ); + } + /** + * {@code GET /access-tokens} : get all the accessTokens. + * + * @param pageable the pagination information. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of accessTokens in body. */ @GetMapping("/access-tokens") @@ -138,6 +208,9 @@ public ResponseEntity getAccessToken(@PathVariable Long id) { public ResponseEntity deleteAccessToken(@PathVariable Long id) { log.debug("REST request to delete AccessToken : {}", id); accessTokenRepository.deleteById(id); - return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())).build(); + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); } } diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/AuditResource.java b/src/main/java/org/securityrat/casemanagement/web/rest/AuditResource.java deleted file mode 100644 index 277e3e4..0000000 --- a/src/main/java/org/securityrat/casemanagement/web/rest/AuditResource.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.securityrat.casemanagement.web.rest; - -import org.securityrat.casemanagement.service.AuditEventService; - -import io.github.jhipster.web.util.PaginationUtil; -import io.github.jhipster.web.util.ResponseUtil; -import org.springframework.boot.actuate.audit.AuditEvent; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import java.time.Instant; -import java.time.LocalDate; -import java.time.ZoneId; -import java.util.List; - -/** - * REST controller for getting the {@link AuditEvent}s. - */ -@RestController -@RequestMapping("/management/audits") -public class AuditResource { - - private final AuditEventService auditEventService; - - public AuditResource(AuditEventService auditEventService) { - this.auditEventService = auditEventService; - } - - /** - * {@code GET /audits} : get a page of {@link AuditEvent}s. - * - * @param pageable the pagination information. - * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of {@link AuditEvent}s in body. - */ - @GetMapping - public ResponseEntity> getAll(Pageable pageable) { - Page page = auditEventService.findAll(pageable); - HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); - return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); - } - - /** - * {@code GET /audits} : get a page of {@link AuditEvent} between the {@code fromDate} and {@code toDate}. - * - * @param fromDate the start of the time period of {@link AuditEvent} to get. - * @param toDate the end of the time period of {@link AuditEvent} to get. - * @param pageable the pagination information. - * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of {@link AuditEvent} in body. - */ - @GetMapping(params = {"fromDate", "toDate"}) - public ResponseEntity> getByDates( - @RequestParam(value = "fromDate") LocalDate fromDate, - @RequestParam(value = "toDate") LocalDate toDate, - Pageable pageable) { - - Instant from = fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant(); - Instant to = toDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant(); - - Page page = auditEventService.findByDates(from, to, pageable); - HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); - return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); - } - - /** - * {@code GET /audits/:id} : get an {@link AuditEvent} by id. - * - * @param id the id of the entity to get. - * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the {@link AuditEvent} in body, or status {@code 404 (Not Found)}. - */ - @GetMapping("/{id:.+}") - public ResponseEntity get(@PathVariable Long id) { - return ResponseUtil.wrapOrNotFound(auditEventService.find(id)); - } -} diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/GatewayAPI.java b/src/main/java/org/securityrat/casemanagement/web/rest/GatewayAPI.java deleted file mode 100644 index e431868..0000000 --- a/src/main/java/org/securityrat/casemanagement/web/rest/GatewayAPI.java +++ /dev/null @@ -1,191 +0,0 @@ -package org.securityrat.casemanagement.web.rest; - - -import io.micrometer.core.annotation.Timed; -import org.securityrat.casemanagement.domain.enumeration.AttributeType; -import org.securityrat.casemanagement.service.RequirementManagementAPIService; -import org.securityrat.casemanagement.service.dto.AttributeDTO; -import org.securityrat.casemanagement.service.dto.ExtensionKeyDTO; -import org.securityrat.casemanagement.service.dto.GenericAttributeGatewayDTO; -import org.securityrat.casemanagement.service.dto.GenericExtensionDTO; -import org.securityrat.casemanagement.service.dto.RequirementDTO; -import org.securityrat.casemanagement.service.dto.RequirementSetDTO; -import org.securityrat.casemanagement.service.dto.RequirementStructureDTO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.ArrayList; -import java.util.List; - -@RestController -@RequestMapping("/api") -public class GatewayAPI { - private final Logger log = LoggerFactory.getLogger(GatewayAPI.class); - - @Autowired - private RequirementManagementAPIService requirementManagementAPIService; - - /** - * GET /requirementSets : Get active requirementSets. - * - * @return the ResponseEntity with status 200 (OK) and the list of - * requirementSets in body - */ - @GetMapping("/requirementSets") - @Timed - public ResponseEntity> getActiveRequirementSets() { - log.debug("REST request to get active RequirementSets"); - - List result = requirementManagementAPIService.getActiveRequirementSets(); - return new ResponseEntity<>(result, HttpStatus.OK); - } - - /** - * GET /parameters?requirementSet : Get parameters for a given requirementSet. - * - * @param requirementSetId - * The requirementSet ID. - * - * @return the ResponseEntity with status 200 (OK) and the list of parameters in - * body - */ - @GetMapping(value="/parameters", params="requirementSet") - @Timed - public ResponseEntity> getParameters( - @RequestParam(value = "requirementSet") Long requirementSetId) { - log.info("REST request to get all active parameter for RequirementSet with ID {}", requirementSetId); - - return new ResponseEntity<>(this.getAttributes(requirementSetId, AttributeType.PARAMETER), HttpStatus.OK); - } - - /** - * GET /parameters?ids : Get parameters of the given parameter ids. - * - * @param paramterValueIds - * List of parameter ids. - * - * @return the ResponseEntity with status 200 (OK) and the list of parameters in - * body - */ - @GetMapping(value="/parameters", params="ids") - @Timed - public ResponseEntity> getParametersByIds( - @RequestParam(value = "ids") String paramterValueIds) { - log.info("REST request to get all active parameters in a given list of ids"); - List ids = this.parseStringToList(paramterValueIds); - List attributes = requirementManagementAPIService.getAttributesByIds(ids); - - List result = requirementManagementAPIService - .generateGatewayAttributeDTO(attributes); - return new ResponseEntity<>(result, HttpStatus.OK); - } - - /** - * GET /parameters?requirementSet : Get all tags for a given requirementSet. - * - * @param requirementSetId - * The requirementSet ID. - * - * @return the ResponseEntity with status 200 (OK) and the list of tags in - * body - */ - @GetMapping("/tags") - @Timed - public ResponseEntity> getTags( - @RequestParam(value = "requirementSet") Long requirementSetId) { - log.info("REST request to get all active tags for RequirementSet with ID {}", requirementSetId); - return new ResponseEntity<>(this.getAttributes(requirementSetId, AttributeType.FE_TAG), HttpStatus.OK); - } - - /** - * GET /parameters?requirementSet : Get all categories for a given requirementSet. - * - * @param requirementSetId - * The requirementSet ID. - * - * @return the ResponseEntity with status 200 (OK) and the list of categories in - * body - */ - @GetMapping("/categories") - @Timed - public ResponseEntity> getCategories( - @RequestParam(value = "requirementSet") Long requirementSetId) { - log.info("REST request to get all active parameter for RequirementSet with ID {}", requirementSetId); - - return new ResponseEntity<>(this.getAttributes(requirementSetId, AttributeType.CATEGORY), HttpStatus.OK); - } - - /** - * GET /requirementStructure?requirementSet : Retrieves the requirement table structure of a given requirement set. - * @param requirementSetId the requirementSet ID - * @return - */ - @GetMapping("/requirementStructure") - public ResponseEntity getRequirementStructure( - @RequestParam(value = "requirementSet") Long requirementSetId - ) { - List extensionKeys = requirementManagementAPIService.getActiveExtensionKeys(requirementSetId); - List extensions = requirementManagementAPIService.getActiveExtensionForReqStructure(requirementSetId); - - - return new ResponseEntity<>(this.requirementManagementAPIService.generateRequirementStructureDTO(extensionKeys, extensions), HttpStatus.OK); - } - - /** - * GET /requirements : Get active attributes with given ids. - * - * @param requirementSetId - * Id of requirementSet - * @param List - * of parameter ids (comma seperated string) - * @return the ResponseEntity with status 200 (OK) and the list of requirements - * in body or 404 (Not found) if one of the specified IDs does not exist - */ - @GetMapping("/requirements") - @Timed - public ResponseEntity> getRequirements( - @RequestParam(value = "requirementSet") Long requirementSetId, - @RequestParam(value = "parameters") String parameters) { - List params = new ArrayList<>(); - if (parameters != null) { - for (String idAsString : parameters.split(",")) { - params.add(Long.parseLong(idAsString)); - } - } - List result; - result = requirementManagementAPIService.getActiveRequirements(requirementSetId, params); - - return new ResponseEntity<>(result, HttpStatus.OK); - } - - - /** - * Parse a comma separated string to long values. - * @param values comma separated string - * @return - */ - private List parseStringToList(String values) { - List result = new ArrayList<>(); - for (String value: values.split(",")) { - result.add(Long.parseLong(value)); - } - - return result; - } - - private List getAttributes(Long requirementSetId, AttributeType type) { - List types = new ArrayList<>(); - types.add(type); - List attributes = requirementManagementAPIService.getActiveAttributes(requirementSetId, types); - - return requirementManagementAPIService.generateGatewayAttributeDTO(attributes); - } - -} diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/PublicUserResource.java b/src/main/java/org/securityrat/casemanagement/web/rest/PublicUserResource.java new file mode 100644 index 0000000..6c4ded6 --- /dev/null +++ b/src/main/java/org/securityrat/casemanagement/web/rest/PublicUserResource.java @@ -0,0 +1,52 @@ +package org.securityrat.casemanagement.web.rest; + +import java.util.*; +import org.securityrat.casemanagement.service.UserService; +import org.securityrat.casemanagement.service.dto.UserDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.PaginationUtil; + +@RestController +@RequestMapping("/api") +public class PublicUserResource { + + private final Logger log = LoggerFactory.getLogger(PublicUserResource.class); + + private final UserService userService; + + public PublicUserResource(UserService userService) { + this.userService = userService; + } + + /** + * {@code GET /users} : get all users with only the public informations - calling this are allowed for anyone. + * + * @param pageable the pagination information. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body all users. + */ + @GetMapping("/users") + public ResponseEntity> getAllPublicUsers(Pageable pageable) { + log.debug("REST request to get all public User names"); + + final Page page = userService.getAllPublicUsers(pageable); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); + } + + /** + * Gets a list of all roles. + * @return a string list of all roles. + */ + @GetMapping("/authorities") + public List getAuthorities() { + return userService.getAuthorities(); + } +} diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResource.java b/src/main/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResource.java index c2c2b9a..c8fa0c0 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResource.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResource.java @@ -1,12 +1,15 @@ package org.securityrat.casemanagement.web.rest; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; import org.securityrat.casemanagement.domain.TicketSystemInstance; import org.securityrat.casemanagement.repository.TicketSystemInstanceRepository; import org.securityrat.casemanagement.web.rest.errors.BadRequestAlertException; - -import io.github.jhipster.web.util.HeaderUtil; -import io.github.jhipster.web.util.PaginationUtil; -import io.github.jhipster.web.util.ResponseUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -14,17 +17,13 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.http.ResponseEntity; -import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import java.net.URI; -import java.net.URISyntaxException; - -import java.util.List; -import java.util.Optional; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; /** * REST controller for managing {@link org.securityrat.casemanagement.domain.TicketSystemInstance}. @@ -55,44 +54,120 @@ public TicketSystemInstanceResource(TicketSystemInstanceRepository ticketSystemI * @throws URISyntaxException if the Location URI syntax is incorrect. */ @PostMapping("/ticket-system-instances") - public ResponseEntity createTicketSystemInstance(@Valid @RequestBody TicketSystemInstance ticketSystemInstance) throws URISyntaxException { + public ResponseEntity createTicketSystemInstance(@Valid @RequestBody TicketSystemInstance ticketSystemInstance) + throws URISyntaxException { log.debug("REST request to save TicketSystemInstance : {}", ticketSystemInstance); if (ticketSystemInstance.getId() != null) { throw new BadRequestAlertException("A new ticketSystemInstance cannot already have an ID", ENTITY_NAME, "idexists"); } TicketSystemInstance result = ticketSystemInstanceRepository.save(ticketSystemInstance); - return ResponseEntity.created(new URI("/api/ticket-system-instances/" + result.getId())) + return ResponseEntity + .created(new URI("/api/ticket-system-instances/" + result.getId())) .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString())) .body(result); } /** - * {@code PUT /ticket-system-instances} : Updates an existing ticketSystemInstance. + * {@code PUT /ticket-system-instances/:id} : Updates an existing ticketSystemInstance. * + * @param id the id of the ticketSystemInstance to save. * @param ticketSystemInstance the ticketSystemInstance to update. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated ticketSystemInstance, * or with status {@code 400 (Bad Request)} if the ticketSystemInstance is not valid, * or with status {@code 500 (Internal Server Error)} if the ticketSystemInstance couldn't be updated. * @throws URISyntaxException if the Location URI syntax is incorrect. */ - @PutMapping("/ticket-system-instances") - public ResponseEntity updateTicketSystemInstance(@Valid @RequestBody TicketSystemInstance ticketSystemInstance) throws URISyntaxException { - log.debug("REST request to update TicketSystemInstance : {}", ticketSystemInstance); + @PutMapping("/ticket-system-instances/{id}") + public ResponseEntity updateTicketSystemInstance( + @PathVariable(value = "id", required = false) final Long id, + @Valid @RequestBody TicketSystemInstance ticketSystemInstance + ) throws URISyntaxException { + log.debug("REST request to update TicketSystemInstance : {}, {}", id, ticketSystemInstance); if (ticketSystemInstance.getId() == null) { throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); } + if (!Objects.equals(id, ticketSystemInstance.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } + + if (!ticketSystemInstanceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + TicketSystemInstance result = ticketSystemInstanceRepository.save(ticketSystemInstance); - return ResponseEntity.ok() + return ResponseEntity + .ok() .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, ticketSystemInstance.getId().toString())) .body(result); } /** - * {@code GET /ticket-system-instances} : get all the ticketSystemInstances. + * {@code PATCH /ticket-system-instances/:id} : Partial updates given fields of an existing ticketSystemInstance, field will ignore if it is null * + * @param id the id of the ticketSystemInstance to save. + * @param ticketSystemInstance the ticketSystemInstance to update. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated ticketSystemInstance, + * or with status {@code 400 (Bad Request)} if the ticketSystemInstance is not valid, + * or with status {@code 404 (Not Found)} if the ticketSystemInstance is not found, + * or with status {@code 500 (Internal Server Error)} if the ticketSystemInstance couldn't be updated. + * @throws URISyntaxException if the Location URI syntax is incorrect. + */ + @PatchMapping(value = "/ticket-system-instances/{id}", consumes = "application/merge-patch+json") + public ResponseEntity partialUpdateTicketSystemInstance( + @PathVariable(value = "id", required = false) final Long id, + @NotNull @RequestBody TicketSystemInstance ticketSystemInstance + ) throws URISyntaxException { + log.debug("REST request to partial update TicketSystemInstance partially : {}, {}", id, ticketSystemInstance); + if (ticketSystemInstance.getId() == null) { + throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); + } + if (!Objects.equals(id, ticketSystemInstance.getId())) { + throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid"); + } - * @param pageable the pagination information. + if (!ticketSystemInstanceRepository.existsById(id)) { + throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound"); + } + + Optional result = ticketSystemInstanceRepository + .findById(ticketSystemInstance.getId()) + .map( + existingTicketSystemInstance -> { + if (ticketSystemInstance.getName() != null) { + existingTicketSystemInstance.setName(ticketSystemInstance.getName()); + } + if (ticketSystemInstance.getType() != null) { + existingTicketSystemInstance.setType(ticketSystemInstance.getType()); + } + if (ticketSystemInstance.getUrl() != null) { + existingTicketSystemInstance.setUrl(ticketSystemInstance.getUrl()); + } + if (ticketSystemInstance.getConsumerKey() != null) { + existingTicketSystemInstance.setConsumerKey(ticketSystemInstance.getConsumerKey()); + } + if (ticketSystemInstance.getClientId() != null) { + existingTicketSystemInstance.setClientId(ticketSystemInstance.getClientId()); + } + if (ticketSystemInstance.getClientSecret() != null) { + existingTicketSystemInstance.setClientSecret(ticketSystemInstance.getClientSecret()); + } + + return existingTicketSystemInstance; + } + ) + .map(ticketSystemInstanceRepository::save) + .map(ticketSystemInstanceMapper::toDto); + + return ResponseUtil.wrapOrNotFound( + result, + HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, ticketSystemInstance.getId().toString()) + ); + } + /** + * {@code GET /ticket-system-instances} : get all the ticketSystemInstances. + * + * @param pageable the pagination information. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of ticketSystemInstances in body. */ @GetMapping("/ticket-system-instances") @@ -126,6 +201,9 @@ public ResponseEntity getTicketSystemInstance(@PathVariabl public ResponseEntity deleteTicketSystemInstance(@PathVariable Long id) { log.debug("REST request to delete TicketSystemInstance : {}", id); ticketSystemInstanceRepository.deleteById(id); - return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())).build(); + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())) + .build(); } } diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/UserResource.java b/src/main/java/org/securityrat/casemanagement/web/rest/UserResource.java index 6b08512..6d3d2dd 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/UserResource.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/UserResource.java @@ -1,14 +1,11 @@ package org.securityrat.casemanagement.web.rest; +import java.util.*; +import javax.validation.constraints.Pattern; import org.securityrat.casemanagement.config.Constants; import org.securityrat.casemanagement.security.AuthoritiesConstants; import org.securityrat.casemanagement.service.UserService; -import org.securityrat.casemanagement.service.dto.UserDTO; - -import io.github.jhipster.web.util.HeaderUtil; -import io.github.jhipster.web.util.PaginationUtil; -import io.github.jhipster.web.util.ResponseUtil; - +import org.securityrat.casemanagement.service.dto.AdminUserDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -20,8 +17,9 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import java.util.*; +import tech.jhipster.web.util.HeaderUtil; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; /** * REST controller for managing users. @@ -34,8 +32,8 @@ *

* We use a View Model and a DTO for 3 reasons: *

    - *
  • We want to keep a lazy association between the appUser and the authorities, because people will - * quite often do relationships with the appUser, and we don't want them to get the authorities all + *
  • We want to keep a lazy association between the user and the authorities, because people will + * quite often do relationships with the user, and we don't want them to get the authorities all * the time for nothing (for performance reasons). This is the #1 goal: we should not impact our users' * application because of this use-case.
  • *
  • Not having an outer join causes n+1 requests to the database. This is not a real issue as @@ -48,7 +46,7 @@ * Another option would be to have a specific JPA entity graph to handle this case. */ @RestController -@RequestMapping("/api") +@RequestMapping("/api/admin") public class UserResource { private final Logger log = LoggerFactory.getLogger(UserResource.class); @@ -59,44 +57,35 @@ public class UserResource { private final UserService userService; public UserResource(UserService userService) { - this.userService = userService; } /** - * {@code GET /users} : get all users. + * {@code GET /admin/users} : get all users with all the details - calling this are only allowed for the administrators. * * @param pageable the pagination information. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body all users. */ @GetMapping("/users") - public ResponseEntity> getAllUsers(Pageable pageable) { - final Page page = userService.getAllManagedUsers(pageable); + @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")") + public ResponseEntity> getAllUsers(Pageable pageable) { + log.debug("REST request to get all User for an admin"); + + final Page page = userService.getAllManagedUsers(pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK); } /** - * Gets a list of all roles. - * @return a string list of all roles. - */ - @GetMapping("/users/authorities") - @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")") - public List getAuthorities() { - return userService.getAuthorities(); - } - - /** - * {@code GET /users/:login} : get the "login" appUser. + * {@code GET /admin/users/:login} : get the "login" user. * - * @param login the login of the appUser to find. - * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the "login" appUser, or with status {@code 404 (Not Found)}. + * @param login the login of the user to find. + * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the "login" user, or with status {@code 404 (Not Found)}. */ - @GetMapping("/users/{login:" + Constants.LOGIN_REGEX + "}") - public ResponseEntity getUser(@PathVariable String login) { + @GetMapping("/users/{login}") + @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")") + public ResponseEntity getUser(@PathVariable @Pattern(regexp = Constants.LOGIN_REGEX) String login) { log.debug("REST request to get User : {}", login); - return ResponseUtil.wrapOrNotFound( - userService.getUserWithAuthoritiesByLogin(login) - .map(UserDTO::new)); + return ResponseUtil.wrapOrNotFound(userService.getUserWithAuthoritiesByLogin(login).map(AdminUserDTO::new)); } } diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/errors/BadRequestAlertException.java b/src/main/java/org/securityrat/casemanagement/web/rest/errors/BadRequestAlertException.java index 4494b21..403c9ab 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/errors/BadRequestAlertException.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/errors/BadRequestAlertException.java @@ -1,11 +1,10 @@ package org.securityrat.casemanagement.web.rest.errors; -import org.zalando.problem.AbstractThrowableProblem; -import org.zalando.problem.Status; - import java.net.URI; import java.util.HashMap; import java.util.Map; +import org.zalando.problem.AbstractThrowableProblem; +import org.zalando.problem.Status; public class BadRequestAlertException extends AbstractThrowableProblem { diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/errors/ErrorConstants.java b/src/main/java/org/securityrat/casemanagement/web/rest/errors/ErrorConstants.java index e85bd99..1218251 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/errors/ErrorConstants.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/errors/ErrorConstants.java @@ -10,6 +10,5 @@ public final class ErrorConstants { public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message"); public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation"); - private ErrorConstants() { - } + private ErrorConstants() {} } diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslator.java b/src/main/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslator.java index ac9e551..dac61bf 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslator.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslator.java @@ -1,10 +1,21 @@ package org.securityrat.casemanagement.web.rest.errors; -import io.github.jhipster.web.util.HeaderUtil; - +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; import org.springframework.dao.ConcurrencyFailureException; +import org.springframework.dao.DataAccessException; import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConversionException; import org.springframework.validation.BindingResult; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; @@ -14,15 +25,12 @@ import org.zalando.problem.Problem; import org.zalando.problem.ProblemBuilder; import org.zalando.problem.Status; +import org.zalando.problem.StatusType; import org.zalando.problem.spring.web.advice.ProblemHandling; import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait; import org.zalando.problem.violations.ConstraintViolationProblem; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.stream.Collectors; +import tech.jhipster.config.JHipsterConstants; +import tech.jhipster.web.util.HeaderUtil; /** * Controller advice to translate the server side exceptions to client-friendly json structures. @@ -39,33 +47,40 @@ public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait @Value("${jhipster.clientApp.name}") private String applicationName; + private final Environment env; + + public ExceptionTranslator(Environment env) { + this.env = env; + } + /** * Post-process the Problem payload to add the message key for the front-end if needed. */ @Override public ResponseEntity process(@Nullable ResponseEntity entity, NativeWebRequest request) { if (entity == null) { - return entity; + return null; } Problem problem = entity.getBody(); if (!(problem instanceof ConstraintViolationProblem || problem instanceof DefaultProblem)) { return entity; } - ProblemBuilder builder = Problem.builder() + + HttpServletRequest nativeRequest = request.getNativeRequest(HttpServletRequest.class); + String requestUri = nativeRequest != null ? nativeRequest.getRequestURI() : StringUtils.EMPTY; + ProblemBuilder builder = Problem + .builder() .withType(Problem.DEFAULT_TYPE.equals(problem.getType()) ? ErrorConstants.DEFAULT_TYPE : problem.getType()) .withStatus(problem.getStatus()) .withTitle(problem.getTitle()) - .with(PATH_KEY, request.getNativeRequest(HttpServletRequest.class).getRequestURI()); + .with(PATH_KEY, requestUri); if (problem instanceof ConstraintViolationProblem) { builder .with(VIOLATIONS_KEY, ((ConstraintViolationProblem) problem).getViolations()) .with(MESSAGE_KEY, ErrorConstants.ERR_VALIDATION); } else { - builder - .withCause(((DefaultProblem) problem).getCause()) - .withDetail(problem.getDetail()) - .withInstance(problem.getInstance()); + builder.withCause(((DefaultProblem) problem).getCause()).withDetail(problem.getDetail()).withInstance(problem.getInstance()); problem.getParameters().forEach(builder::with); if (!problem.getParameters().containsKey(MESSAGE_KEY) && problem.getStatus() != null) { builder.with(MESSAGE_KEY, "error.http." + problem.getStatus().getStatusCode()); @@ -77,11 +92,21 @@ public ResponseEntity process(@Nullable ResponseEntity entity, @Override public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotValidException ex, @Nonnull NativeWebRequest request) { BindingResult result = ex.getBindingResult(); - List fieldErrors = result.getFieldErrors().stream() - .map(f -> new FieldErrorVM(f.getObjectName().replaceFirst("DTO$", ""), f.getField(), f.getCode())) + List fieldErrors = result + .getFieldErrors() + .stream() + .map( + f -> + new FieldErrorVM( + f.getObjectName().replaceFirst("DTO$", ""), + f.getField(), + StringUtils.isNotBlank(f.getDefaultMessage()) ? f.getDefaultMessage() : f.getCode() + ) + ) .collect(Collectors.toList()); - Problem problem = Problem.builder() + Problem problem = Problem + .builder() .withType(ErrorConstants.CONSTRAINT_VIOLATION_TYPE) .withTitle("Method argument not valid") .withStatus(defaultConstraintViolationStatus()) @@ -93,15 +118,72 @@ public ResponseEntity handleMethodArgumentNotValid(MethodArgumentNotVal @ExceptionHandler public ResponseEntity handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) { - return create(ex, request, HeaderUtil.createFailureAlert(applicationName, false, ex.getEntityName(), ex.getErrorKey(), ex.getMessage())); + return create( + ex, + request, + HeaderUtil.createFailureAlert(applicationName, false, ex.getEntityName(), ex.getErrorKey(), ex.getMessage()) + ); } @ExceptionHandler public ResponseEntity handleConcurrencyFailure(ConcurrencyFailureException ex, NativeWebRequest request) { - Problem problem = Problem.builder() - .withStatus(Status.CONFLICT) - .with(MESSAGE_KEY, ErrorConstants.ERR_CONCURRENCY_FAILURE) - .build(); + Problem problem = Problem.builder().withStatus(Status.CONFLICT).with(MESSAGE_KEY, ErrorConstants.ERR_CONCURRENCY_FAILURE).build(); return create(ex, problem, request); } + + @Override + public ProblemBuilder prepare(final Throwable throwable, final StatusType status, final URI type) { + Collection activeProfiles = Arrays.asList(env.getActiveProfiles()); + + if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) { + if (throwable instanceof HttpMessageConversionException) { + return Problem + .builder() + .withType(type) + .withTitle(status.getReasonPhrase()) + .withStatus(status) + .withDetail("Unable to convert http message") + .withCause( + Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) + ); + } + if (throwable instanceof DataAccessException) { + return Problem + .builder() + .withType(type) + .withTitle(status.getReasonPhrase()) + .withStatus(status) + .withDetail("Failure during data access") + .withCause( + Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) + ); + } + if (containsPackageName(throwable.getMessage())) { + return Problem + .builder() + .withType(type) + .withTitle(status.getReasonPhrase()) + .withStatus(status) + .withDetail("Unexpected runtime exception") + .withCause( + Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) + ); + } + } + + return Problem + .builder() + .withType(type) + .withTitle(status.getReasonPhrase()) + .withStatus(status) + .withDetail(throwable.getMessage()) + .withCause( + Optional.ofNullable(throwable.getCause()).filter(cause -> isCausalChainsEnabled()).map(this::toProblem).orElse(null) + ); + } + + private boolean containsPackageName(String message) { + // This list is for sure not complete + return StringUtils.containsAny(message, "org.", "java.", "net.", "javax.", "com.", "io.", "de.", "org.securityrat.casemanagement"); + } } diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/errors/FieldErrorVM.java b/src/main/java/org/securityrat/casemanagement/web/rest/errors/FieldErrorVM.java index 71dd84d..229cc83 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/errors/FieldErrorVM.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/errors/FieldErrorVM.java @@ -29,5 +29,4 @@ public String getField() { public String getMessage() { return message; } - } diff --git a/src/main/java/org/securityrat/casemanagement/web/rest/vm/ManagedUserVM.java b/src/main/java/org/securityrat/casemanagement/web/rest/vm/ManagedUserVM.java index 48be1b1..60c475c 100644 --- a/src/main/java/org/securityrat/casemanagement/web/rest/vm/ManagedUserVM.java +++ b/src/main/java/org/securityrat/casemanagement/web/rest/vm/ManagedUserVM.java @@ -1,16 +1,17 @@ package org.securityrat.casemanagement.web.rest.vm; -import org.securityrat.casemanagement.service.dto.UserDTO; +import org.securityrat.casemanagement.service.dto.AdminUserDTO; /** - * View Model extending the UserDTO, which is meant to be used in the appUser management UI. + * View Model extending the AdminUserDTO, which is meant to be used in the user management UI. */ -public class ManagedUserVM extends UserDTO { +public class ManagedUserVM extends AdminUserDTO { public ManagedUserVM() { // Empty constructor needed for Jackson. } + // prettier-ignore @Override public String toString() { return "ManagedUserVM{" + super.toString() + "} "; diff --git a/src/main/resources/.h2.server.properties b/src/main/resources/.h2.server.properties index 3c49b47..c5f790a 100644 --- a/src/main/resources/.h2.server.properties +++ b/src/main/resources/.h2.server.properties @@ -1,5 +1,5 @@ #H2 Server Properties 0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/casemanagement|caseManagement webAllowOthers=true -webPort=8082 +webPort=8092 webSSL=false diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml index da39260..75ccf1e 100644 --- a/src/main/resources/config/application-dev.yml +++ b/src/main/resources/config/application-dev.yml @@ -16,16 +16,11 @@ logging: level: ROOT: DEBUG - io.github.jhipster: DEBUG + tech.jhipster: DEBUG + org.hibernate.SQL: DEBUG org.securityrat.casemanagement: DEBUG spring: - profiles: - active: dev - include: - - swagger - # Uncomment to activate TLS for the dev profile - #- tls devtools: restart: enabled: true @@ -37,8 +32,18 @@ spring: indent-output: true cloud: consul: + config: + fail-fast: false # if not in "prod" profile, do not force to use Spring Cloud Config + format: yaml + profile-separator: '-' discovery: prefer-ip-address: true + tags: + - profile=${spring.profiles.active} + - version=#project.version# + - git-version=${git.commit.id.describe:} + - git-commit=${git.commit.id.abbrev:} + - git-branch=${git.branch:} host: localhost port: 8500 datasource: @@ -53,23 +58,10 @@ spring: console: enabled: false jpa: - database-platform: io.github.jhipster.domain.util.FixedH2Dialect - database: H2 - show-sql: true - properties: - hibernate.id.new_generator_mappings: true - hibernate.connection.provider_disables_autocommit: true - hibernate.cache.use_second_level_cache: false - hibernate.cache.use_query_cache: false - hibernate.generate_statistics: false + database-platform: tech.jhipster.domain.util.FixedH2Dialect liquibase: # Remove 'faker' if you do not want the sample data to be loaded automatically contexts: dev, faker - mail: - host: localhost - port: 25 - username: - password: messages: cache-duration: PT1S # 1 second, see the ISO 8601 standard thymeleaf: @@ -85,7 +77,7 @@ spring: enabled: true server: - port: 8083 + port: 8082 # =================================================================== # JHipster specific properties @@ -97,18 +89,12 @@ jhipster: # CORS is disabled by default on microservices, as you should access them through a gateway. # If you want to enable it, please uncomment the configuration below. # cors: - # allowed-origins: "*" - # allowed-methods: "*" - # allowed-headers: "*" - # exposed-headers: "Authorization,Link,X-Total-Count" - # allow-credentials: true - # max-age: 1800 - mail: # specific JHipster mail property, for standard properties see MailProperties - base-url: http://127.0.0.1:8082 - metrics: - logs: # Reports metrics in the logs - enabled: false - report-frequency: 60 # in seconds + # allowed-origins: "*" + # allowed-methods: "*" + # allowed-headers: "*" + # exposed-headers: "Authorization,Link,X-Total-Count" + # allow-credentials: true + # max-age: 1800 logging: use-json-format: false # By default, logs are not in Json format logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration @@ -116,9 +102,6 @@ jhipster: host: localhost port: 5000 queue-size: 512 - audit-events: - retention-period: 30 # Number of days before audit events are deleted. - # =================================================================== # Application specific properties # Add your own application properties here, see the ApplicationProperties class diff --git a/src/main/resources/config/application-prod.yml b/src/main/resources/config/application-prod.yml index 2b0da31..d862db2 100644 --- a/src/main/resources/config/application-prod.yml +++ b/src/main/resources/config/application-prod.yml @@ -16,7 +16,7 @@ logging: level: ROOT: INFO - io.github.jhipster: INFO + tech.jhipster: INFO org.securityrat.casemanagement: INFO management: @@ -51,29 +51,9 @@ spring: prepStmtCacheSqlLimit: 2048 useServerPrepStmts: true jpa: - database-platform: org.hibernate.dialect.MariaDB103Dialect - database: MYSQL - show-sql: false - properties: - hibernate.id.new_generator_mappings: true - hibernate.connection.provider_disables_autocommit: true - hibernate.cache.use_second_level_cache: false - hibernate.cache.use_query_cache: false - hibernate.generate_statistics: false - # modify batch size as necessary - hibernate.jdbc.batch_size: 25 - hibernate.order_inserts: true - hibernate.order_updates: true - hibernate.query.fail_on_pagination_over_collection_fetch: true - hibernate.query.in_clause_parameter_padding: true # Replace by 'prod, faker' to add the faker context and have sample data loaded in production liquibase: contexts: prod - mail: - host: localhost - port: 25 - username: - password: thymeleaf: cache: true sleuth: @@ -96,17 +76,18 @@ spring: # Then, modify the server.ssl properties so your "server" configuration looks like: # # server: -# port: 443 -# ssl: -# key-store: classpath:config/tls/keystore.p12 -# key-store-password: password -# key-store-type: PKCS12 -# key-alias: casemanagement -# # The ciphers suite enforce the security by deactivating some old and deprecated SSL cipher, this list was tested against SSL Labs (https://www.ssllabs.com/ssltest/) -# ciphers: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA +# port: 443 +# ssl: +# key-store: classpath:config/tls/keystore.p12 +# key-store-password: password +# key-store-type: PKCS12 +# key-alias: selfsigned +# # The ciphers suite enforce the security by deactivating some old and deprecated SSL cipher, this list was tested against SSL Labs (https://www.ssllabs.com/ssltest/) +# ciphers: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA # =================================================================== server: port: 8082 + shutdown: graceful # see https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-graceful-shutdown compression: enabled: true mime-types: text/html,text/xml,text/plain,text/css, application/javascript, application/json @@ -122,12 +103,6 @@ jhipster: http: cache: # Used by the CachingHttpHeadersFilter timeToLiveInDays: 1461 - mail: # specific JHipster mail property, for standard properties see MailProperties - base-url: http://my-server-url-to-change # Modify according to your server's URL - metrics: - logs: # Reports metrics in the logs - enabled: false - report-frequency: 60 # in seconds logging: use-json-format: false # By default, logs are not in Json format logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration @@ -135,9 +110,6 @@ jhipster: host: localhost port: 5000 queue-size: 512 - audit-events: - retention-period: 30 # Number of days before audit events are deleted. - # =================================================================== # Application specific properties # Add your own application properties here, see the ApplicationProperties class diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 8a75c26..190b950 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -18,10 +18,10 @@ feign: hystrix: enabled: true # client: - # config: - # default: - # connectTimeout: 5000 - # readTimeout: 5000 + # config: + # default: + # connectTimeout: 5000 + # readTimeout: 5000 # See https://github.com/Netflix/Hystrix/wiki/Configuration hystrix: @@ -32,7 +32,7 @@ hystrix: strategy: SEMAPHORE # See https://github.com/spring-cloud/spring-cloud-netflix/issues/1330 # thread: - # timeoutInMilliseconds: 10000 + # timeoutInMilliseconds: 10000 shareSecurityContext: true management: @@ -40,17 +40,24 @@ management: web: base-path: /management exposure: - include: ['configprops', 'env', 'health', 'info', 'jhimetrics', 'logfile', 'loggers', 'prometheus', 'threaddump'] + include: ['configprops', 'env', 'health', 'info', 'jhimetrics', 'logfile', 'loggers', 'prometheus', 'threaddump', 'liquibase'] endpoint: health: - show-details: when-authorized + show-details: when_authorized roles: 'ROLE_ADMIN' + probes: + enabled: true jhimetrics: enabled: true info: git: mode: full health: + group: + liveness: + include: livenessState + readiness: + include: readinessState,datasource mail: enabled: false # When using the MailService, configure an SMTP server and set this to true metrics: @@ -74,7 +81,9 @@ management: application: ${spring.application.name} web: server: - auto-time-requests: true + request: + autotime: + enabled: true spring: application: @@ -88,6 +97,17 @@ spring: config: watch: enabled: false + profiles: + # The commented value for `active` can be replaced with valid Spring profiles to load. + # Otherwise, it will be filled in by maven when building the JAR file + # Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS` + active: #spring.profiles.active# + group: + dev: + - dev + - api-docs + # Uncomment to activate TLS for the dev profile + #- tls jmx: enabled: false data: @@ -98,6 +118,17 @@ spring: open-in-view: false properties: hibernate.jdbc.time_zone: UTC + hibernate.id.new_generator_mappings: true + hibernate.connection.provider_disables_autocommit: true + hibernate.cache.use_second_level_cache: false + hibernate.cache.use_query_cache: false + hibernate.generate_statistics: false + # modify batch size as necessary + hibernate.jdbc.batch_size: 25 + hibernate.order_inserts: true + hibernate.order_updates: true + hibernate.query.fail_on_pagination_over_collection_fetch: true + hibernate.query.in_clause_parameter_padding: true hibernate: ddl-auto: none naming: @@ -107,9 +138,6 @@ spring: basename: i18n/messages main: allow-bean-definition-overriding: true - mvc: - favicon: - enabled: false task: execution: thread-name-prefix: case-management-task- @@ -136,6 +164,7 @@ spring: oidc: client-id: internal client-secret: internal + scope: openid,profile,email server: servlet: @@ -159,16 +188,17 @@ jhipster: name: 'caseManagementApp' # By default CORS is disabled. Uncomment to enable. # cors: - # allowed-origins: "*" - # allowed-methods: "*" - # allowed-headers: "*" - # exposed-headers: "Authorization,Link,X-Total-Count" - # allow-credentials: true - # max-age: 1800 + # allowed-origins: "*" + # allowed-methods: "*" + # allowed-headers: "*" + # exposed-headers: "Authorization,Link,X-Total-Count,X-${jhipster.clientApp.name}-alert,X-${jhipster.clientApp.name}-error,X-${jhipster.clientApp.name}-params" + # allow-credentials: true + # max-age: 1800 mail: from: caseManagement@localhost - swagger: - default-include-pattern: /api/.* + api-docs: + default-include-pattern: ${server.servlet.context-path:}/api/.* + management-include-pattern: ${server.servlet.context-path:}/management/.* title: caseManagement API description: caseManagement API documentation version: 0.0.1 @@ -176,7 +206,7 @@ jhipster: contact-name: contact-url: contact-email: - license: + license: unlicensed license-url: security: oauth2: diff --git a/src/main/resources/config/bootstrap.yml b/src/main/resources/config/bootstrap.yml index a4bdb71..86a1c73 100644 --- a/src/main/resources/config/bootstrap.yml +++ b/src/main/resources/config/bootstrap.yml @@ -24,5 +24,7 @@ spring: - git-version=${git.commit.id.describe:} - git-commit=${git.commit.id.abbrev:} - git-branch=${git.branch:} + - context-path=${server.servlet.context-path:} + host: localhost port: 8500 diff --git a/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml b/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml index b1ac55b..7468f74 100644 --- a/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml +++ b/src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml @@ -3,10 +3,12 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> - + + + - + - + + + + + + + - + - + - + - + + + + + + + + + + + - - diff --git a/src/main/resources/config/liquibase/changelog/20201108111723_added_entity_constraints_AccessToken.xml b/src/main/resources/config/liquibase/changelog/20201108111723_added_entity_constraints_AccessToken.xml index 52da1c6..a244886 100644 --- a/src/main/resources/config/liquibase/changelog/20201108111723_added_entity_constraints_AccessToken.xml +++ b/src/main/resources/config/liquibase/changelog/20201108111723_added_entity_constraints_AccessToken.xml @@ -2,7 +2,7 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> @@ -10,13 +10,13 @@ diff --git a/src/main/resources/config/liquibase/changelog/20201108112112_added_entity_TicketSystemInstance.xml b/src/main/resources/config/liquibase/changelog/20201108112112_added_entity_TicketSystemInstance.xml index adfb0ab..d690e47 100644 --- a/src/main/resources/config/liquibase/changelog/20201108112112_added_entity_TicketSystemInstance.xml +++ b/src/main/resources/config/liquibase/changelog/20201108112112_added_entity_TicketSystemInstance.xml @@ -3,17 +3,15 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd"> - - - + @@ -25,13 +23,42 @@ - + + + + + + + + + + - + + + + + + + + + + + + + - - diff --git a/src/main/resources/config/liquibase/fake-data/access_token.csv b/src/main/resources/config/liquibase/fake-data/access_token.csv new file mode 100644 index 0000000..12a6179 --- /dev/null +++ b/src/main/resources/config/liquibase/fake-data/access_token.csv @@ -0,0 +1,11 @@ +id;token;expiration_date;salt;refresh_token +1;Operations;2020-11-08T01:53:19;access violet;protocol +2;Customer stable;2020-11-08T01:43:10;Keyboard International harness;Music Soap drive +3;asymmetric Account;2020-11-07T15:56:08;Liechtenstein;firmware Frozen +4;China Tools;2020-11-07T20:25:12;payment 24/7 azure;Music Mills +5;executive;2020-11-07T18:57:42;Business-focused ubiquitous;Soap bricks-and-clicks +6;ubiquitous quantify Washington;2020-11-07T17:36:57;Hat Toys French;Keyboard bluetooth +7;quantifying Intranet solution;2020-11-08T06:28:06;Health application;Strategist Swaziland +8;USB CSS;2020-11-07T17:33:18;Executive;connect Pre-emptive Analyst +9;Interface Brand Market;2020-11-07T23:34:50;project purple Ergonomic;black Som Strategist +10;technologies Movies dot-com;2020-11-08T00:58:17;e-business;Frozen synergies Bosnia diff --git a/src/main/resources/config/liquibase/fake-data/ticket_system_instance.csv b/src/main/resources/config/liquibase/fake-data/ticket_system_instance.csv new file mode 100644 index 0000000..c13c852 --- /dev/null +++ b/src/main/resources/config/liquibase/fake-data/ticket_system_instance.csv @@ -0,0 +1,11 @@ +id;name;type;url;consumer_key;client_id;client_secret +1;Indiana Cheese;JIRA;http://greyson.name;Oklahoma circuit;Grocery grow Hat;Sausages Small +2;Pants Versatile Sheqel;JIRA;http://johathan.info;protocol Niue extend;24/7;calculate +3;invoice;JIRA;http://tate.net;Lead Mexico;bypass Assistant Forward;Zloty Regional +4;killer Chips Car;JIRA;http://keenan.org;Massachusetts e-tailers;Cambridgeshire exploit;Bacon +5;Soft embrace;JIRA;http://johan.info;invoice back Dynamic;Coordinator Haiti;Borders up Plain +6;COM New EXE;JIRA;http://ila.name;Music Tools Practical;Books;Dalasi withdrawal +7;invoice;JIRA;http://darby.com;Virtual archive Investor;driver protocol;payment revolutionary Music +8;North Steel dynamic;JIRA;http://maxime.biz;Checking Missouri Salad;services connect;mobile +9;deposit open-source asynchronous;JIRA;http://amparo.org;SMTP Administrator Chief;Street Market;Pakistan Argentine +10;visualize open-source;JIRA;https://weldon.net;composite monetize;innovative Locks;invoice Reactive driver diff --git a/src/main/resources/config/liquibase/master.xml b/src/main/resources/config/liquibase/master.xml index 93aded6..688f643 100644 --- a/src/main/resources/config/liquibase/master.xml +++ b/src/main/resources/config/liquibase/master.xml @@ -2,16 +2,17 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd"> - - + + + @@ -19,4 +20,5 @@ + diff --git a/src/main/resources/config/tls/keystore.p12 b/src/main/resources/config/tls/keystore.p12 deleted file mode 100644 index 4b05f51..0000000 Binary files a/src/main/resources/config/tls/keystore.p12 and /dev/null differ diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties index 3d8dcf1..5fb5c54 100644 --- a/src/main/resources/i18n/messages.properties +++ b/src/main/resources/i18n/messages.properties @@ -4,18 +4,3 @@ error.subtitle=Sorry, an error has occurred. error.status=Status: error.message=Message: -# Activation email -email.activation.title=caseManagement account activation is required -email.activation.greeting=Dear {0} -email.activation.text1=Your caseManagement account has been created, please click on the URL below to activate it: -email.activation.text2=Regards, -email.signature=caseManagement Team. - -# Creation email -email.creation.text1=Your caseManagement account has been created, please click on the URL below to access it: - -# Reset email -email.reset.title=caseManagement password reset -email.reset.greeting=Dear {0} -email.reset.text1=For your caseManagement account a password reset was requested, please click on the URL below to reset it: -email.reset.text2=Regards, diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index 0377650..279be5e 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -59,6 +59,7 @@ + diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 68659ba..6ff911e 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -1,103 +1,130 @@ - - - + + + JHipster microservice homepage - - -
    -

    Welcome, Java Hipster!

    - -

    This application is a microservice, which has been generated using JHipster.

    - -
      -
    • It does not have a front-end. The front-end should be generated on a JHipster gateway
    • + + +
      +

      Welcome, Java Hipster!

      + +

      + This application is a microservice, which has been generated using + JHipster. +

      + +
        +
      • It does not have a front-end. The front-end should be generated on a JHipster gateway.
      • It is serving REST APIs, under the '/api' URLs.
      • -
      • Swagger documentation endpoint for those APIs is at /v2/api-docs, but if you want access to the full Swagger UI, you should use a JHipster gateway, which will serve as an API developer portal
      • -
      - -

      - If you have any question on JHipster: -

      - - - -

      - If you like JHipster, don't forget to give us a star on GitHub! -

      - -
      - +
    • + To manage this microservice, you will probably want to use the + JHipster Registry: +
        +
      • + To run the JHipster Registry locally, you can use Docker:
        docker-compose -f src/main/docker/jhipster-registry.yml up -d +
      • +
      • + Its default URL is http://localhost:8761/ and its default login/password is + admin/admin +
      • +
      +
    • +
    • + OpenAPI documentation endpoint for those APIs is at /v3/api-docs, but if you want access to the full + Swagger UI, you should use a JHipster gateway or a JHipster Registry, which will serve as API developer portals. +
    • +
    + +

    If you have any question on JHipster:

    + + + +

    + If you like JHipster, don't forget to give us a star on + GitHub! +

    +
    + diff --git a/src/main/resources/templates/error.html b/src/main/resources/templates/error.html index b703488..690e856 100644 --- a/src/main/resources/templates/error.html +++ b/src/main/resources/templates/error.html @@ -1,87 +1,92 @@ - - - - + + + + Your request cannot be processed - - -
    -

    Your request cannot be processed :(

    + + +
    +

    Your request cannot be processed :(

    -

    Sorry, an error has occurred.

    +

    Sorry, an error has occurred.

    - Status:  ()
    - - Message: 
    -
    -
    - + Status:  ()
    + + Message: 
    +
    +
    + diff --git a/src/test/java/org/securityrat/casemanagement/ArchTest.java b/src/test/java/org/securityrat/casemanagement/ArchTest.java index 56c3f49..188d071 100644 --- a/src/test/java/org/securityrat/casemanagement/ArchTest.java +++ b/src/test/java/org/securityrat/casemanagement/ArchTest.java @@ -1,29 +1,29 @@ package org.securityrat.casemanagement; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; + import com.tngtech.archunit.core.domain.JavaClasses; import com.tngtech.archunit.core.importer.ClassFileImporter; import com.tngtech.archunit.core.importer.ImportOption; import org.junit.jupiter.api.Test; -import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; - class ArchTest { @Test void servicesAndRepositoriesShouldNotDependOnWebLayer() { - JavaClasses importedClasses = new ClassFileImporter() .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) .importPackages("org.securityrat.casemanagement"); noClasses() .that() - .resideInAnyPackage("..service..") + .resideInAnyPackage("org.securityrat.casemanagement.service..") .or() - .resideInAnyPackage("..repository..") - .should().dependOnClassesThat() - .resideInAnyPackage("..org.securityrat.casemanagement.web..") - .because("Services and repositories should not depend on web layer") - .check(importedClasses); + .resideInAnyPackage("org.securityrat.casemanagement.repository..") + .should() + .dependOnClassesThat() + .resideInAnyPackage("..org.securityrat.casemanagement.web..") + .because("Services and repositories should not depend on web layer") + .check(importedClasses); } } diff --git a/src/test/java/org/securityrat/casemanagement/IntegrationTest.java b/src/test/java/org/securityrat/casemanagement/IntegrationTest.java new file mode 100644 index 0000000..11478e3 --- /dev/null +++ b/src/test/java/org/securityrat/casemanagement/IntegrationTest.java @@ -0,0 +1,18 @@ +package org.securityrat.casemanagement; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.securityrat.casemanagement.CaseManagementApp; +import org.securityrat.casemanagement.config.TestSecurityConfiguration; +import org.springframework.boot.test.context.SpringBootTest; + +/** + * Base composite annotation for integration tests. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@SpringBootTest(classes = { CaseManagementApp.class, TestSecurityConfiguration.class }) +public @interface IntegrationTest { +} diff --git a/src/test/java/org/securityrat/casemanagement/config/TestSecurityConfiguration.java b/src/test/java/org/securityrat/casemanagement/config/TestSecurityConfiguration.java index 80c29c3..17381d8 100644 --- a/src/test/java/org/securityrat/casemanagement/config/TestSecurityConfiguration.java +++ b/src/test/java/org/securityrat/casemanagement/config/TestSecurityConfiguration.java @@ -1,9 +1,14 @@ package org.securityrat.casemanagement.config; +import static org.mockito.Mockito.mock; + +import java.util.HashMap; +import java.util.Map; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; @@ -13,16 +18,12 @@ import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.jwt.JwtDecoder; -import java.util.HashMap; -import java.util.Map; - -import static org.mockito.Mockito.mock; - /** * This class allows you to run unit and integration tests without an IdP. */ @TestConfiguration public class TestSecurityConfiguration { + private final ClientRegistration clientRegistration; public TestSecurityConfiguration() { @@ -38,15 +39,16 @@ private ClientRegistration.Builder clientRegistration() { Map metadata = new HashMap<>(); metadata.put("end_session_endpoint", "https://jhipster.org/logout"); - return ClientRegistration.withRegistrationId("oidc") - .redirectUriTemplate("{baseUrl}/{action}/oauth2/code/{registrationId}") + return ClientRegistration + .withRegistrationId("oidc") + .redirectUri("{baseUrl}/{action}/oauth2/code/{registrationId}") .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) - .scope("read:appUser") + .scope("read:user") .authorizationUri("https://jhipster.org/login/oauth/authorize") .tokenUri("https://jhipster.org/login/oauth/access_token") .jwkSetUri("https://jhipster.org/oauth/jwk") - .userInfoUri("https://api.jhipster.org/appUser") + .userInfoUri("https://api.jhipster.org/user") .providerConfigurationMetadata(metadata) .userNameAttributeName("id") .clientName("Client Name") diff --git a/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTest.java b/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTest.java index 8205a83..de52aa9 100644 --- a/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTest.java +++ b/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTest.java @@ -1,7 +1,16 @@ package org.securityrat.casemanagement.config; -import io.github.jhipster.config.JHipsterConstants; -import io.github.jhipster.config.JHipsterProperties; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.*; +import javax.servlet.*; import org.h2.server.web.WebServlet; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -10,22 +19,13 @@ import org.springframework.mock.web.MockServletContext; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import javax.servlet.*; -import java.util.*; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import tech.jhipster.config.JHipsterConstants; +import tech.jhipster.config.JHipsterProperties; /** * Unit tests for the {@link WebConfigurer} class. */ -public class WebConfigurerTest { +class WebConfigurerTest { private WebConfigurer webConfigurer; @@ -38,10 +38,8 @@ public class WebConfigurerTest { @BeforeEach public void setup() { servletContext = spy(new MockServletContext()); - doReturn(mock(FilterRegistration.Dynamic.class)) - .when(servletContext).addFilter(anyString(), any(Filter.class)); - doReturn(mock(ServletRegistration.Dynamic.class)) - .when(servletContext).addServlet(anyString(), any(Servlet.class)); + doReturn(mock(FilterRegistration.Dynamic.class)).when(servletContext).addFilter(anyString(), any(Filter.class)); + doReturn(mock(ServletRegistration.Dynamic.class)).when(servletContext).addServlet(anyString(), any(Servlet.class)); env = new MockEnvironment(); props = new JHipsterProperties(); @@ -50,37 +48,37 @@ public void setup() { } @Test - public void testStartUpProdServletContext() throws ServletException { + void shouldStartUpProdServletContext() throws ServletException { env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION); - webConfigurer.onStartup(servletContext); + assertThatCode(() -> webConfigurer.onStartup(servletContext)).doesNotThrowAnyException(); verify(servletContext, never()).addServlet(eq("H2Console"), any(WebServlet.class)); } @Test - public void testStartUpDevServletContext() throws ServletException { + void shouldStartUpDevServletContext() throws ServletException { env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT); - webConfigurer.onStartup(servletContext); + assertThatCode(() -> webConfigurer.onStartup(servletContext)).doesNotThrowAnyException(); verify(servletContext).addServlet(eq("H2Console"), any(WebServlet.class)); } @Test - public void testCorsFilterOnApiPath() throws Exception { - props.getCors().setAllowedOrigins(Collections.singletonList("*")); + void shouldCorsFilterOnApiPath() throws Exception { + props.getCors().setAllowedOrigins(Collections.singletonList("other.domain.com")); props.getCors().setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); props.getCors().setAllowedHeaders(Collections.singletonList("*")); props.getCors().setMaxAge(1800L); props.getCors().setAllowCredentials(true); - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()) - .addFilters(webConfigurer.corsFilter()) - .build(); + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()).addFilters(webConfigurer.corsFilter()).build(); - mockMvc.perform( - options("/api/test-cors") - .header(HttpHeaders.ORIGIN, "other.domain.com") - .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")) + mockMvc + .perform( + options("/api/test-cors") + .header(HttpHeaders.ORIGIN, "other.domain.com") + .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST") + ) .andExpect(status().isOk()) .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "other.domain.com")) .andExpect(header().string(HttpHeaders.VARY, "Origin")) @@ -88,58 +86,48 @@ public void testCorsFilterOnApiPath() throws Exception { .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true")) .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "1800")); - mockMvc.perform( - get("/api/test-cors") - .header(HttpHeaders.ORIGIN, "other.domain.com")) + mockMvc + .perform(get("/api/test-cors").header(HttpHeaders.ORIGIN, "other.domain.com")) .andExpect(status().isOk()) .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "other.domain.com")); } @Test - public void testCorsFilterOnOtherPath() throws Exception { + void shouldCorsFilterOnOtherPath() throws Exception { props.getCors().setAllowedOrigins(Collections.singletonList("*")); props.getCors().setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); props.getCors().setAllowedHeaders(Collections.singletonList("*")); props.getCors().setMaxAge(1800L); props.getCors().setAllowCredentials(true); - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()) - .addFilters(webConfigurer.corsFilter()) - .build(); + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()).addFilters(webConfigurer.corsFilter()).build(); - mockMvc.perform( - get("/test/test-cors") - .header(HttpHeaders.ORIGIN, "other.domain.com")) + mockMvc + .perform(get("/test/test-cors").header(HttpHeaders.ORIGIN, "other.domain.com")) .andExpect(status().isOk()) .andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); } @Test - public void testCorsFilterDeactivated() throws Exception { + void shouldCorsFilterDeactivatedForNullAllowedOrigins() throws Exception { props.getCors().setAllowedOrigins(null); - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()) - .addFilters(webConfigurer.corsFilter()) - .build(); + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()).addFilters(webConfigurer.corsFilter()).build(); - mockMvc.perform( - get("/api/test-cors") - .header(HttpHeaders.ORIGIN, "other.domain.com")) + mockMvc + .perform(get("/api/test-cors").header(HttpHeaders.ORIGIN, "other.domain.com")) .andExpect(status().isOk()) .andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); } @Test - public void testCorsFilterDeactivated2() throws Exception { + void shouldCorsFilterDeactivatedForEmptyAllowedOrigins() throws Exception { props.getCors().setAllowedOrigins(new ArrayList<>()); - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()) - .addFilters(webConfigurer.corsFilter()) - .build(); + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController()).addFilters(webConfigurer.corsFilter()).build(); - mockMvc.perform( - get("/api/test-cors") - .header(HttpHeaders.ORIGIN, "other.domain.com")) + mockMvc + .perform(get("/api/test-cors").header(HttpHeaders.ORIGIN, "other.domain.com")) .andExpect(status().isOk()) .andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); } diff --git a/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTestController.java b/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTestController.java index 54e2715..e5d7ea8 100644 --- a/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTestController.java +++ b/src/test/java/org/securityrat/casemanagement/config/WebConfigurerTestController.java @@ -7,10 +7,8 @@ public class WebConfigurerTestController { @GetMapping("/api/test-cors") - public void testCorsOnApiPath() { - } + public void testCorsOnApiPath() {} @GetMapping("/test/test-cors") - public void testCorsOnOtherPath() { - } + public void testCorsOnOtherPath() {} } diff --git a/src/test/java/org/securityrat/casemanagement/config/timezone/HibernateTimeZoneIT.java b/src/test/java/org/securityrat/casemanagement/config/timezone/HibernateTimeZoneIT.java index 8aa6a63..8a3f378 100644 --- a/src/test/java/org/securityrat/casemanagement/config/timezone/HibernateTimeZoneIT.java +++ b/src/test/java/org/securityrat/casemanagement/config/timezone/HibernateTimeZoneIT.java @@ -1,34 +1,36 @@ package org.securityrat.casemanagement.config.timezone; -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; -import org.securityrat.casemanagement.repository.timezone.DateTimeWrapper; -import org.securityrat.casemanagement.repository.timezone.DateTimeWrapperRepository; +import static java.lang.String.format; +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.*; +import java.time.format.DateTimeFormatter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.securityrat.casemanagement.IntegrationTest; +import org.securityrat.casemanagement.repository.timezone.DateTimeWrapper; +import org.securityrat.casemanagement.repository.timezone.DateTimeWrapperRepository; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.transaction.annotation.Transactional; -import java.time.*; -import java.time.format.DateTimeFormatter; - -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; - /** - * Integration tests for the UTC Hibernate configuration. + * Integration tests for the ZoneId Hibernate configuration. */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -public class HibernateTimeZoneIT { +@IntegrationTest +class HibernateTimeZoneIT { @Autowired private DateTimeWrapperRepository dateTimeWrapperRepository; + @Autowired private JdbcTemplate jdbcTemplate; + @Value("${spring.jpa.properties.hibernate.jdbc.time_zone:UTC}") + private String zoneId; + private DateTimeWrapper dateTimeWrapper; private DateTimeFormatter dateTimeFormatter; private DateTimeFormatter timeFormatter; @@ -45,21 +47,16 @@ public void setup() { dateTimeWrapper.setOffsetTime(OffsetTime.parse("14:30:00+02:00")); dateTimeWrapper.setLocalDate(LocalDate.parse("2016-09-10")); - dateTimeFormatter = DateTimeFormatter - .ofPattern("yyyy-MM-dd HH:mm:ss.S") - .withZone(ZoneId.of("UTC")); + dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S").withZone(ZoneId.of(zoneId)); - timeFormatter = DateTimeFormatter - .ofPattern("HH:mm:ss") - .withZone(ZoneId.of("UTC")); + timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss").withZone(ZoneId.of(zoneId)); - dateFormatter = DateTimeFormatter - .ofPattern("yyyy-MM-dd"); + dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); } @Test @Transactional - public void storeInstantWithUtcConfigShouldBeStoredOnGMTTimeZone() { + void storeInstantWithZoneIdConfigShouldBeStoredOnGMTTimeZone() { dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); String request = generateSqlRequest("instant", dateTimeWrapper.getId()); @@ -71,50 +68,43 @@ public void storeInstantWithUtcConfigShouldBeStoredOnGMTTimeZone() { @Test @Transactional - public void storeLocalDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() { + void storeLocalDateTimeWithZoneIdConfigShouldBeStoredOnGMTTimeZone() { dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); String request = generateSqlRequest("local_date_time", dateTimeWrapper.getId()); SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); - String expectedValue = dateTimeWrapper - .getLocalDateTime() - .atZone(ZoneId.systemDefault()) - .format(dateTimeFormatter); + String expectedValue = dateTimeWrapper.getLocalDateTime().atZone(ZoneId.systemDefault()).format(dateTimeFormatter); assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); } @Test @Transactional - public void storeOffsetDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() { + void storeOffsetDateTimeWithZoneIdConfigShouldBeStoredOnGMTTimeZone() { dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); String request = generateSqlRequest("offset_date_time", dateTimeWrapper.getId()); SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); - String expectedValue = dateTimeWrapper - .getOffsetDateTime() - .format(dateTimeFormatter); + String expectedValue = dateTimeWrapper.getOffsetDateTime().format(dateTimeFormatter); assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); } @Test @Transactional - public void storeZoneDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() { + void storeZoneDateTimeWithZoneIdConfigShouldBeStoredOnGMTTimeZone() { dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); String request = generateSqlRequest("zoned_date_time", dateTimeWrapper.getId()); SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); - String expectedValue = dateTimeWrapper - .getZonedDateTime() - .format(dateTimeFormatter); + String expectedValue = dateTimeWrapper.getZonedDateTime().format(dateTimeFormatter); assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); } @Test @Transactional - public void storeLocalTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() { + void storeLocalTimeWithZoneIdConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() { dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); String request = generateSqlRequest("local_time", dateTimeWrapper.getId()); @@ -130,7 +120,7 @@ public void storeLocalTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHis @Test @Transactional - public void storeOffsetTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() { + void storeOffsetTimeWithZoneIdConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() { dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); String request = generateSqlRequest("offset_time", dateTimeWrapper.getId()); @@ -147,14 +137,12 @@ public void storeOffsetTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHi @Test @Transactional - public void storeLocalDateWithUtcConfigShouldBeStoredWithoutTransformation() { + void storeLocalDateWithZoneIdConfigShouldBeStoredWithoutTransformation() { dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper); String request = generateSqlRequest("local_date", dateTimeWrapper.getId()); SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request); - String expectedValue = dateTimeWrapper - .getLocalDate() - .format(dateFormatter); + String expectedValue = dateTimeWrapper.getLocalDate().format(dateFormatter); assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue); } diff --git a/src/test/java/org/securityrat/casemanagement/domain/AccessTokenTest.java b/src/test/java/org/securityrat/casemanagement/domain/AccessTokenTest.java index a30fb99..dea261e 100644 --- a/src/test/java/org/securityrat/casemanagement/domain/AccessTokenTest.java +++ b/src/test/java/org/securityrat/casemanagement/domain/AccessTokenTest.java @@ -1,13 +1,14 @@ package org.securityrat.casemanagement.domain; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; import org.securityrat.casemanagement.web.rest.TestUtil; -public class AccessTokenTest { +class AccessTokenTest { @Test - public void equalsVerifier() throws Exception { + void equalsVerifier() throws Exception { TestUtil.equalsVerifier(AccessToken.class); AccessToken accessToken1 = new AccessToken(); accessToken1.setId(1L); diff --git a/src/test/java/org/securityrat/casemanagement/domain/TicketSystemInstanceTest.java b/src/test/java/org/securityrat/casemanagement/domain/TicketSystemInstanceTest.java index eb964c8..8d8b7e2 100644 --- a/src/test/java/org/securityrat/casemanagement/domain/TicketSystemInstanceTest.java +++ b/src/test/java/org/securityrat/casemanagement/domain/TicketSystemInstanceTest.java @@ -1,13 +1,14 @@ package org.securityrat.casemanagement.domain; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; import org.securityrat.casemanagement.web.rest.TestUtil; -public class TicketSystemInstanceTest { +class TicketSystemInstanceTest { @Test - public void equalsVerifier() throws Exception { + void equalsVerifier() throws Exception { TestUtil.equalsVerifier(TicketSystemInstance.class); TicketSystemInstance ticketSystemInstance1 = new TicketSystemInstance(); ticketSystemInstance1.setId(1L); diff --git a/src/test/java/org/securityrat/casemanagement/repository/CustomAuditEventRepositoryIT.java b/src/test/java/org/securityrat/casemanagement/repository/CustomAuditEventRepositoryIT.java deleted file mode 100644 index 0d7ce21..0000000 --- a/src/test/java/org/securityrat/casemanagement/repository/CustomAuditEventRepositoryIT.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.securityrat.casemanagement.repository; - -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.Constants; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; -import org.securityrat.casemanagement.config.audit.AuditEventConverter; -import org.securityrat.casemanagement.domain.PersistentAuditEvent; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.audit.AuditEvent; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpSession; -import org.springframework.security.web.authentication.WebAuthenticationDetails; -import org.springframework.transaction.annotation.Transactional; - -import javax.servlet.http.HttpSession; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.securityrat.casemanagement.repository.CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH; - -/** - * Integration tests for {@link CustomAuditEventRepository}. - */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -@Transactional -public class CustomAuditEventRepositoryIT { - - @Autowired - private PersistenceAuditEventRepository persistenceAuditEventRepository; - - @Autowired - private AuditEventConverter auditEventConverter; - - private CustomAuditEventRepository customAuditEventRepository; - - private PersistentAuditEvent testUserEvent; - - private PersistentAuditEvent testOtherUserEvent; - - private PersistentAuditEvent testOldUserEvent; - - @BeforeEach - public void setup() { - customAuditEventRepository = new CustomAuditEventRepository(persistenceAuditEventRepository, auditEventConverter); - persistenceAuditEventRepository.deleteAll(); - Instant oneHourAgo = Instant.now().minusSeconds(3600); - - testUserEvent = new PersistentAuditEvent(); - testUserEvent.setPrincipal("test-appUser"); - testUserEvent.setAuditEventType("test-type"); - testUserEvent.setAuditEventDate(oneHourAgo); - Map data = new HashMap<>(); - data.put("test-key", "test-value"); - testUserEvent.setData(data); - - testOldUserEvent = new PersistentAuditEvent(); - testOldUserEvent.setPrincipal("test-appUser"); - testOldUserEvent.setAuditEventType("test-type"); - testOldUserEvent.setAuditEventDate(oneHourAgo.minusSeconds(10000)); - - testOtherUserEvent = new PersistentAuditEvent(); - testOtherUserEvent.setPrincipal("other-test-appUser"); - testOtherUserEvent.setAuditEventType("test-type"); - testOtherUserEvent.setAuditEventDate(oneHourAgo); - } - - @Test - public void addAuditEvent() { - Map data = new HashMap<>(); - data.put("test-key", "test-value"); - AuditEvent event = new AuditEvent("test-appUser", "test-type", data); - customAuditEventRepository.add(event); - List persistentAuditEvents = persistenceAuditEventRepository.findAll(); - assertThat(persistentAuditEvents).hasSize(1); - PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); - assertThat(persistentAuditEvent.getPrincipal()).isEqualTo(event.getPrincipal()); - assertThat(persistentAuditEvent.getAuditEventType()).isEqualTo(event.getType()); - assertThat(persistentAuditEvent.getData()).containsKey("test-key"); - assertThat(persistentAuditEvent.getData().get("test-key")).isEqualTo("test-value"); - assertThat(persistentAuditEvent.getAuditEventDate().truncatedTo(ChronoUnit.MILLIS)) - .isEqualTo(event.getTimestamp().truncatedTo(ChronoUnit.MILLIS)); - } - - @Test - public void addAuditEventTruncateLargeData() { - Map data = new HashMap<>(); - StringBuilder largeData = new StringBuilder(); - for (int i = 0; i < EVENT_DATA_COLUMN_MAX_LENGTH + 10; i++) { - largeData.append("a"); - } - data.put("test-key", largeData); - AuditEvent event = new AuditEvent("test-appUser", "test-type", data); - customAuditEventRepository.add(event); - List persistentAuditEvents = persistenceAuditEventRepository.findAll(); - assertThat(persistentAuditEvents).hasSize(1); - PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); - assertThat(persistentAuditEvent.getPrincipal()).isEqualTo(event.getPrincipal()); - assertThat(persistentAuditEvent.getAuditEventType()).isEqualTo(event.getType()); - assertThat(persistentAuditEvent.getData()).containsKey("test-key"); - String actualData = persistentAuditEvent.getData().get("test-key"); - assertThat(actualData.length()).isEqualTo(EVENT_DATA_COLUMN_MAX_LENGTH); - assertThat(actualData).isSubstringOf(largeData); - assertThat(persistentAuditEvent.getAuditEventDate().truncatedTo(ChronoUnit.MILLIS)) - .isEqualTo(event.getTimestamp().truncatedTo(ChronoUnit.MILLIS)); - } - - @Test - public void testAddEventWithWebAuthenticationDetails() { - HttpSession session = new MockHttpSession(null, "test-session-id"); - MockHttpServletRequest request = new MockHttpServletRequest(); - request.setSession(session); - request.setRemoteAddr("1.2.3.4"); - WebAuthenticationDetails details = new WebAuthenticationDetails(request); - Map data = new HashMap<>(); - data.put("test-key", details); - AuditEvent event = new AuditEvent("test-appUser", "test-type", data); - customAuditEventRepository.add(event); - List persistentAuditEvents = persistenceAuditEventRepository.findAll(); - assertThat(persistentAuditEvents).hasSize(1); - PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); - assertThat(persistentAuditEvent.getData().get("remoteAddress")).isEqualTo("1.2.3.4"); - assertThat(persistentAuditEvent.getData().get("sessionId")).isEqualTo("test-session-id"); - } - - @Test - public void testAddEventWithNullData() { - Map data = new HashMap<>(); - data.put("test-key", null); - AuditEvent event = new AuditEvent("test-appUser", "test-type", data); - customAuditEventRepository.add(event); - List persistentAuditEvents = persistenceAuditEventRepository.findAll(); - assertThat(persistentAuditEvents).hasSize(1); - PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0); - assertThat(persistentAuditEvent.getData().get("test-key")).isEqualTo("null"); - } - - @Test - public void addAuditEventWithAnonymousUser() { - Map data = new HashMap<>(); - data.put("test-key", "test-value"); - AuditEvent event = new AuditEvent(Constants.ANONYMOUS_USER, "test-type", data); - customAuditEventRepository.add(event); - List persistentAuditEvents = persistenceAuditEventRepository.findAll(); - assertThat(persistentAuditEvents).hasSize(0); - } - - @Test - public void addAuditEventWithAuthorizationFailureType() { - Map data = new HashMap<>(); - data.put("test-key", "test-value"); - AuditEvent event = new AuditEvent("test-appUser", "AUTHORIZATION_FAILURE", data); - customAuditEventRepository.add(event); - List persistentAuditEvents = persistenceAuditEventRepository.findAll(); - assertThat(persistentAuditEvents).hasSize(0); - } - -} diff --git a/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapper.java b/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapper.java index 6dc59bf..f083c61 100644 --- a/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapper.java +++ b/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapper.java @@ -1,9 +1,9 @@ package org.securityrat.casemanagement.repository.timezone; -import javax.persistence.*; import java.io.Serializable; import java.time.*; import java.util.Objects; +import javax.persistence.*; @Entity @Table(name = "jhi_date_time_wrapper") @@ -12,7 +12,8 @@ public class DateTimeWrapper implements Serializable { private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") + @SequenceGenerator(name = "sequenceGenerator") private Long id; @Column(name = "instant") @@ -118,6 +119,7 @@ public int hashCode() { return Objects.hashCode(getId()); } + // prettier-ignore @Override public String toString() { return "TimeZoneTest{" + diff --git a/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapperRepository.java b/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapperRepository.java index 699bbc3..14894b6 100644 --- a/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapperRepository.java +++ b/src/test/java/org/securityrat/casemanagement/repository/timezone/DateTimeWrapperRepository.java @@ -7,6 +7,4 @@ * Spring Data JPA repository for the {@link DateTimeWrapper} entity. */ @Repository -public interface DateTimeWrapperRepository extends JpaRepository { - -} +public interface DateTimeWrapperRepository extends JpaRepository {} diff --git a/src/test/java/org/securityrat/casemanagement/security/SecurityUtilsUnitTest.java b/src/test/java/org/securityrat/casemanagement/security/SecurityUtilsUnitTest.java index 9639440..80de7ad 100644 --- a/src/test/java/org/securityrat/casemanagement/security/SecurityUtilsUnitTest.java +++ b/src/test/java/org/securityrat/casemanagement/security/SecurityUtilsUnitTest.java @@ -1,5 +1,12 @@ package org.securityrat.casemanagement.security; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames.ID_TOKEN; + +import java.time.Instant; +import java.util.*; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; @@ -11,19 +18,19 @@ import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; -import java.time.Instant; -import java.util.*; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames.ID_TOKEN; - /** * Test class for the {@link SecurityUtils} utility class. */ -public class SecurityUtilsUnitTest { +class SecurityUtilsUnitTest { + + @BeforeEach + @AfterEach + void cleanup() { + SecurityContextHolder.clearContext(); + } @Test - public void testGetCurrentUserLogin() { + void testGetCurrentUserLogin() { SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("admin", "admin")); SecurityContextHolder.setContext(securityContext); @@ -32,19 +39,18 @@ public void testGetCurrentUserLogin() { } @Test - public void testGetCurrentUserLoginForOAuth2() { + void testGetCurrentUserLoginForOAuth2() { SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); Map claims = new HashMap<>(); - claims.put("groups", "ROLE_USER"); + claims.put("groups", AuthoritiesConstants.USER); claims.put("sub", 123); claims.put("preferred_username", "admin"); - OidcIdToken idToken = new OidcIdToken(ID_TOKEN, Instant.now(), - Instant.now().plusSeconds(60), claims); + OidcIdToken idToken = new OidcIdToken(ID_TOKEN, Instant.now(), Instant.now().plusSeconds(60), claims); Collection authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.USER)); - OidcUser appUser = new DefaultOidcUser(authorities, idToken); - OAuth2AuthenticationToken bla = new OAuth2AuthenticationToken(appUser, authorities, "oidc"); - securityContext.setAuthentication(bla); + OidcUser user = new DefaultOidcUser(authorities, idToken); + OAuth2AuthenticationToken auth2AuthenticationToken = new OAuth2AuthenticationToken(user, authorities, "oidc"); + securityContext.setAuthentication(auth2AuthenticationToken); SecurityContextHolder.setContext(securityContext); Optional login = SecurityUtils.getCurrentUserLogin(); @@ -53,7 +59,7 @@ public void testGetCurrentUserLoginForOAuth2() { } @Test - public void testIsAuthenticated() { + void testIsAuthenticated() { SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("admin", "admin")); SecurityContextHolder.setContext(securityContext); @@ -62,7 +68,7 @@ public void testIsAuthenticated() { } @Test - public void testAnonymousIsNotAuthenticated() { + void testAnonymousIsNotAuthenticated() { SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); Collection authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS)); @@ -73,15 +79,14 @@ public void testAnonymousIsNotAuthenticated() { } @Test - public void testIsCurrentUserInRole() { + void testHasCurrentUserThisAuthority() { SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); Collection authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.USER)); - securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("appUser", "appUser", authorities)); + securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("user", "user", authorities)); SecurityContextHolder.setContext(securityContext); - assertThat(SecurityUtils.isCurrentUserInRole(AuthoritiesConstants.USER)).isTrue(); - assertThat(SecurityUtils.isCurrentUserInRole(AuthoritiesConstants.ADMIN)).isFalse(); + assertThat(SecurityUtils.hasCurrentUserThisAuthority(AuthoritiesConstants.USER)).isTrue(); + assertThat(SecurityUtils.hasCurrentUserThisAuthority(AuthoritiesConstants.ADMIN)).isFalse(); } - } diff --git a/src/test/java/org/securityrat/casemanagement/security/oauth2/AudienceValidatorTest.java b/src/test/java/org/securityrat/casemanagement/security/oauth2/AudienceValidatorTest.java index efd25ae..782f67c 100644 --- a/src/test/java/org/securityrat/casemanagement/security/oauth2/AudienceValidatorTest.java +++ b/src/test/java/org/securityrat/casemanagement/security/oauth2/AudienceValidatorTest.java @@ -1,27 +1,26 @@ package org.securityrat.casemanagement.security.oauth2; -import org.junit.jupiter.api.Test; -import org.springframework.security.oauth2.jwt.Jwt; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import org.junit.jupiter.api.Test; +import org.springframework.security.oauth2.jwt.Jwt; /** * Test class for the {@link AudienceValidator} utility class. */ -public class AudienceValidatorTest { +class AudienceValidatorTest { - private AudienceValidator validator = new AudienceValidator(Arrays.asList("api://default")); + private final AudienceValidator validator = new AudienceValidator(Arrays.asList("api://default")); @Test @SuppressWarnings("unchecked") - public void testInvalidAudience() { + void testInvalidAudience() { Map claims = new HashMap<>(); claims.put("aud", "bar"); Jwt badJwt = mock(Jwt.class); @@ -31,7 +30,7 @@ public void testInvalidAudience() { @Test @SuppressWarnings("unchecked") - public void testValidAudience() { + void testValidAudience() { Map claims = new HashMap<>(); claims.put("aud", "api://default"); Jwt jwt = mock(Jwt.class); diff --git a/src/test/java/org/securityrat/casemanagement/security/oauth2/AuthorizationHeaderUtilTest.java b/src/test/java/org/securityrat/casemanagement/security/oauth2/AuthorizationHeaderUtilTest.java new file mode 100644 index 0000000..e3f367a --- /dev/null +++ b/src/test/java/org/securityrat/casemanagement/security/oauth2/AuthorizationHeaderUtilTest.java @@ -0,0 +1,226 @@ +package org.securityrat.casemanagement.security.oauth2; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.core.*; +import org.springframework.security.oauth2.core.oidc.OidcIdToken; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.RestTemplate; + +/** + * Test class for the {@link AuthorizationHeaderUtil} utility class. + */ +class AuthorizationHeaderUtilTest { + + public static final String VALID_REGISTRATION_ID = "OIDC"; + public static final String SUB_VALUE = "123456"; + + @Mock + private OAuth2AuthorizedClientService clientService; + + @Mock + private RestTemplateBuilder restTemplateBuilder; + + @Mock + private SecurityContext securityContext; + + @InjectMocks + private AuthorizationHeaderUtil authorizationHeaderUtil; + + @BeforeEach + public void setup() { + MockitoAnnotations.initMocks(this); + SecurityContextHolder.setContext(securityContext); + + doReturn(restTemplateBuilder).when(restTemplateBuilder).additionalMessageConverters(any(HttpMessageConverter.class)); + doReturn(restTemplateBuilder).when(restTemplateBuilder).errorHandler(any(ResponseErrorHandler.class)); + doReturn(restTemplateBuilder).when(restTemplateBuilder).basicAuthentication(anyString(), anyString()); + } + + @Test + void getAuthorizationHeader_Authentication() { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken("principal", "credentials"); + doReturn(authenticationToken).when(securityContext).getAuthentication(); + + Optional header = authorizationHeaderUtil.getAuthorizationHeader(); + + Assertions.assertThat(header).isNotNull().isEmpty(); + } + + @Test + void getAuthorizationHeader_JwtAuthentication() { + JwtAuthenticationToken jwtToken = new JwtAuthenticationToken( + new Jwt("tokenVal", Instant.now(), Instant.now().plus(Duration.ofMinutes(3)), Map.of("alg", "HS256"), Map.of("sub", SUB_VALUE)) + ); + doReturn(jwtToken).when(securityContext).getAuthentication(); + + Optional header = authorizationHeaderUtil.getAuthorizationHeader(); + + Assertions.assertThat(header).isNotNull().isNotEmpty().get().isEqualTo("Bearer tokenVal"); + } + + @Test + void getAuthorizationHeader_OAuth2Authentication_InvalidClient() { + OAuth2AuthenticationToken oauth2Token = getTestOAuth2AuthenticationToken("INVALID"); + OAuth2AuthorizedClient authorizedClient = getTestOAuth2AuthorizedClient(); + + doReturn(oauth2Token).when(securityContext).getAuthentication(); + doReturn(authorizedClient).when(clientService).loadAuthorizedClient(eq(VALID_REGISTRATION_ID), eq(SUB_VALUE)); + + Assertions + .assertThatThrownBy( + () -> { + Optional header = authorizationHeaderUtil.getAuthorizationHeader(); + } + ) + .isInstanceOf(OAuth2AuthorizationException.class) + .hasMessageContaining("[access_denied] The token is expired"); + } + + @Test + void getAuthorizationHeader_OAuth2Authentication() { + OAuth2AuthenticationToken oauth2Token = getTestOAuth2AuthenticationToken(VALID_REGISTRATION_ID); + OAuth2AuthorizedClient authorizedClient = getTestOAuth2AuthorizedClient(); + + doReturn(oauth2Token).when(securityContext).getAuthentication(); + doReturn(authorizedClient).when(clientService).loadAuthorizedClient(eq(VALID_REGISTRATION_ID), eq(SUB_VALUE)); + + Optional header = authorizationHeaderUtil.getAuthorizationHeader(); + Assertions.assertThat(header).isNotNull().isNotEmpty().get().isEqualTo("Bearer tokenVal"); + } + + @Test + void getAuthorizationHeader_OAuth2Authentication_RefreshToken() { + OAuth2AuthenticationToken oauth2Token = getTestOAuth2AuthenticationToken(VALID_REGISTRATION_ID); + OAuth2AuthorizedClient authorizedClient = getTestOAuth2AuthorizedClient(true); + + doReturn(oauth2Token).when(securityContext).getAuthentication(); + doReturn(authorizedClient).when(clientService).loadAuthorizedClient(eq(VALID_REGISTRATION_ID), eq(SUB_VALUE)); + + RestTemplate restTemplate = mock(RestTemplate.class); + ResponseEntity refreshResponse = ResponseEntity.of(getTestOAuthIdpTokenResponseDTO(true)); + doReturn(refreshResponse).when(restTemplate).exchange(any(RequestEntity.class), eq(OAuthIdpTokenResponseDTO.class)); + doReturn(restTemplate).when(restTemplateBuilder).build(); + + Optional header = authorizationHeaderUtil.getAuthorizationHeader(); + Assertions.assertThat(header).isNotNull().isNotEmpty().get().isEqualTo("Bearer tokenVal"); + } + + @Test + void getAuthorizationHeader_OAuth2Authentication_RefreshToken_NoRefreshToken() { + OAuth2AuthenticationToken oauth2Token = getTestOAuth2AuthenticationToken(VALID_REGISTRATION_ID); + OAuth2AuthorizedClient authorizedClient = getTestOAuth2AuthorizedClient(true); + + doReturn(oauth2Token).when(securityContext).getAuthentication(); + doReturn(authorizedClient).when(clientService).loadAuthorizedClient(eq(VALID_REGISTRATION_ID), eq(SUB_VALUE)); + + RestTemplate restTemplate = mock(RestTemplate.class); + ResponseEntity refreshResponse = ResponseEntity.of(getTestOAuthIdpTokenResponseDTO(false)); + doReturn(refreshResponse).when(restTemplate).exchange(any(RequestEntity.class), eq(OAuthIdpTokenResponseDTO.class)); + doReturn(restTemplate).when(restTemplateBuilder).build(); + + Optional header = authorizationHeaderUtil.getAuthorizationHeader(); + Assertions.assertThat(header).isNotNull().isNotEmpty().get().isEqualTo("Bearer tokenVal"); + } + + @Test + void getAuthorizationHeader_OAuth2Authentication_RefreshTokenFails() { + OAuth2AuthenticationToken oauth2Token = getTestOAuth2AuthenticationToken(VALID_REGISTRATION_ID); + OAuth2AuthorizedClient authorizedClient = getTestOAuth2AuthorizedClient(true); + + doReturn(oauth2Token).when(securityContext).getAuthentication(); + doReturn(authorizedClient).when(clientService).loadAuthorizedClient(eq(VALID_REGISTRATION_ID), eq(SUB_VALUE)); + + RestTemplate restTemplate = mock(RestTemplate.class); + doThrow(new OAuth2AuthorizationException(new OAuth2Error("E"), "error")) + .when(restTemplate) + .exchange(any(RequestEntity.class), eq(OAuthIdpTokenResponseDTO.class)); + doReturn(restTemplate).when(restTemplateBuilder).build(); + + Assertions + .assertThatThrownBy( + () -> { + Optional header = authorizationHeaderUtil.getAuthorizationHeader(); + } + ) + .isInstanceOf(OAuth2AuthenticationException.class) + .hasMessageContaining("error"); + } + + private OAuth2AuthorizedClient getTestOAuth2AuthorizedClient() { + return getTestOAuth2AuthorizedClient(false); + } + + private OAuth2AuthorizedClient getTestOAuth2AuthorizedClient(boolean accessTokenExpired) { + return new OAuth2AuthorizedClient( + ClientRegistration + .withRegistrationId(VALID_REGISTRATION_ID) + .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) + .clientId("web-app") + .clientSecret("secret") + .redirectUriTemplate("/login/oauth2/code/oidc") + .authorizationUri("http://localhost:8080/auth/realms/master/protocol/openid-connect/auth") + .tokenUri("https://localhost:8080/auth/realms/master/protocol/openid-connect/token") + .build(), + "sub", + new OAuth2AccessToken( + OAuth2AccessToken.TokenType.BEARER, + "tokenVal", + Instant.now(), + accessTokenExpired ? Instant.now() : Instant.now().plus(Duration.ofMinutes(3)) + ), + new OAuth2RefreshToken("refreshVal", Instant.now()) + ); + } + + private OAuth2AuthenticationToken getTestOAuth2AuthenticationToken(String registrationId) { + return new OAuth2AuthenticationToken( + new DefaultOidcUser( + List.of(new SimpleGrantedAuthority("USER")), + OidcIdToken.withTokenValue("tokenVal").claim("sub", SUB_VALUE).build() + ), + List.of(new SimpleGrantedAuthority("USER")), + registrationId + ); + } + + private Optional getTestOAuthIdpTokenResponseDTO(boolean hasRefreshToken) { + OAuthIdpTokenResponseDTO dto = new OAuthIdpTokenResponseDTO(); + dto.setAccessToken("tokenVal"); + dto.setIdToken("tokenVal"); + dto.setNotBefore(0l); + dto.setRefreshExpiresIn("1800"); + dto.setSessionState("ccea4a55"); + dto.setExpiresIn(300l); + dto.setRefreshToken(hasRefreshToken ? "tokenVal" : null); + dto.setScope("openid email profile offline_access"); + return Optional.of(dto); + } +} diff --git a/src/test/java/org/securityrat/casemanagement/service/UserServiceIT.java b/src/test/java/org/securityrat/casemanagement/service/UserServiceIT.java index 28e0011..f9dcb39 100644 --- a/src/test/java/org/securityrat/casemanagement/service/UserServiceIT.java +++ b/src/test/java/org/securityrat/casemanagement/service/UserServiceIT.java @@ -1,34 +1,36 @@ package org.securityrat.casemanagement.service; -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.Constants; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; -import org.securityrat.casemanagement.security.AuthoritiesConstants; -import org.securityrat.casemanagement.service.dto.UserDTO; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.securityrat.casemanagement.IntegrationTest; +import org.securityrat.casemanagement.config.Constants; +import org.securityrat.casemanagement.domain.User; +import org.securityrat.casemanagement.repository.UserRepository; +import org.securityrat.casemanagement.security.AuthoritiesConstants; +import org.securityrat.casemanagement.service.dto.AdminUserDTO; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; +import org.springframework.transaction.annotation.Transactional; /** * Integration tests for {@link UserService}. */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -public class UserServiceIT { +@IntegrationTest +@Transactional +class UserServiceIT { private static final String DEFAULT_LOGIN = "johndoe"; @@ -42,13 +44,26 @@ public class UserServiceIT { private static final String DEFAULT_LANGKEY = "dummy"; + @Autowired + private UserRepository userRepository; + @Autowired private UserService userService; + private User user; + private Map userDetails; @BeforeEach public void init() { + user = new User(); + user.setLogin(DEFAULT_LOGIN); + user.setActivated(true); + user.setEmail(DEFAULT_EMAIL); + user.setFirstName(DEFAULT_FIRSTNAME); + user.setLastName(DEFAULT_LASTNAME); + user.setImageUrl(DEFAULT_IMAGEURL); + user.setLangKey(DEFAULT_LANGKEY); userDetails = new HashMap<>(); userDetails.put("sub", DEFAULT_LOGIN); @@ -59,9 +74,10 @@ public void init() { } @Test - public void testDefaultUserDetails() { + @Transactional + void testDefaultUserDetails() { OAuth2AuthenticationToken authentication = createMockOAuth2AuthenticationToken(userDetails); - UserDTO userDTO = userService.getUserFromAuthentication(authentication); + AdminUserDTO userDTO = userService.getUserFromAuthentication(authentication); assertThat(userDTO.getLogin()).isEqualTo(DEFAULT_LOGIN); assertThat(userDTO.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME); @@ -74,59 +90,68 @@ public void testDefaultUserDetails() { } @Test - public void testUserDetailsWithUsername() { + @Transactional + void testUserDetailsWithUsername() { userDetails.put("preferred_username", "TEST"); OAuth2AuthenticationToken authentication = createMockOAuth2AuthenticationToken(userDetails); - UserDTO userDTO = userService.getUserFromAuthentication(authentication); + AdminUserDTO userDTO = userService.getUserFromAuthentication(authentication); assertThat(userDTO.getLogin()).isEqualTo("test"); } @Test - public void testUserDetailsWithLangKey() { + @Transactional + void testUserDetailsWithLangKey() { userDetails.put("langKey", DEFAULT_LANGKEY); userDetails.put("locale", "en-US"); OAuth2AuthenticationToken authentication = createMockOAuth2AuthenticationToken(userDetails); - UserDTO userDTO = userService.getUserFromAuthentication(authentication); + AdminUserDTO userDTO = userService.getUserFromAuthentication(authentication); assertThat(userDTO.getLangKey()).isEqualTo(DEFAULT_LANGKEY); } @Test - public void testUserDetailsWithLocale() { + @Transactional + void testUserDetailsWithLocale() { userDetails.put("locale", "it-IT"); OAuth2AuthenticationToken authentication = createMockOAuth2AuthenticationToken(userDetails); - UserDTO userDTO = userService.getUserFromAuthentication(authentication); + AdminUserDTO userDTO = userService.getUserFromAuthentication(authentication); assertThat(userDTO.getLangKey()).isEqualTo("it"); } @Test - public void testUserDetailsWithUSLocaleUnderscore() { + @Transactional + void testUserDetailsWithUSLocaleUnderscore() { userDetails.put("locale", "en_US"); OAuth2AuthenticationToken authentication = createMockOAuth2AuthenticationToken(userDetails); - UserDTO userDTO = userService.getUserFromAuthentication(authentication); + AdminUserDTO userDTO = userService.getUserFromAuthentication(authentication); assertThat(userDTO.getLangKey()).isEqualTo("en"); } @Test - public void testUserDetailsWithUSLocaleDash() { + @Transactional + void testUserDetailsWithUSLocaleDash() { userDetails.put("locale", "en-US"); OAuth2AuthenticationToken authentication = createMockOAuth2AuthenticationToken(userDetails); - UserDTO userDTO = userService.getUserFromAuthentication(authentication); + AdminUserDTO userDTO = userService.getUserFromAuthentication(authentication); assertThat(userDTO.getLangKey()).isEqualTo("en"); } private OAuth2AuthenticationToken createMockOAuth2AuthenticationToken(Map userDetails) { Collection authorities = Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS)); - UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(Constants.ANONYMOUS_USER, Constants.ANONYMOUS_USER, authorities); + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken( + "anonymous", + "anonymous", + authorities + ); usernamePasswordAuthenticationToken.setDetails(userDetails); OAuth2User user = new DefaultOAuth2User(authorities, userDetails, "sub"); diff --git a/src/test/java/org/securityrat/casemanagement/service/mapper/UserMapperTest.java b/src/test/java/org/securityrat/casemanagement/service/mapper/UserMapperTest.java index 8848c7a..819f065 100644 --- a/src/test/java/org/securityrat/casemanagement/service/mapper/UserMapperTest.java +++ b/src/test/java/org/securityrat/casemanagement/service/mapper/UserMapperTest.java @@ -1,133 +1,129 @@ package org.securityrat.casemanagement.service.mapper; -import org.securityrat.casemanagement.domain.User; -import org.securityrat.casemanagement.service.dto.UserDTO; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.securityrat.casemanagement.domain.User; +import org.securityrat.casemanagement.service.dto.AdminUserDTO; +import org.securityrat.casemanagement.service.dto.UserDTO; /** * Unit tests for {@link UserMapper}. */ -public class UserMapperTest { +class UserMapperTest { private static final String DEFAULT_LOGIN = "johndoe"; private static final String DEFAULT_ID = "id1"; private UserMapper userMapper; - private User appUser; - private UserDTO userDto; + private User user; + private AdminUserDTO userDto; @BeforeEach public void init() { userMapper = new UserMapper(); - appUser = new User(); - appUser.setLogin(DEFAULT_LOGIN); - appUser.setActivated(true); - appUser.setEmail("johndoe@localhost"); - appUser.setFirstName("john"); - appUser.setLastName("doe"); - appUser.setImageUrl("image_url"); - appUser.setLangKey("en"); - - userDto = new UserDTO(appUser); + user = new User(); + user.setLogin(DEFAULT_LOGIN); + user.setActivated(true); + user.setEmail("johndoe@localhost"); + user.setFirstName("john"); + user.setLastName("doe"); + user.setImageUrl("image_url"); + user.setLangKey("en"); + + userDto = new AdminUserDTO(user); } @Test - public void usersToUserDTOsShouldMapOnlyNonNullUsers() { + void usersToUserDTOsShouldMapOnlyNonNullUsers() { List users = new ArrayList<>(); - users.add(appUser); + users.add(user); users.add(null); List userDTOS = userMapper.usersToUserDTOs(users); - assertThat(userDTOS).isNotEmpty(); - assertThat(userDTOS).size().isEqualTo(1); + assertThat(userDTOS).isNotEmpty().size().isEqualTo(1); } @Test - public void userDTOsToUsersShouldMapOnlyNonNullUsers() { - List usersDto = new ArrayList<>(); + void userDTOsToUsersShouldMapOnlyNonNullUsers() { + List usersDto = new ArrayList<>(); usersDto.add(userDto); usersDto.add(null); List users = userMapper.userDTOsToUsers(usersDto); - assertThat(users).isNotEmpty(); - assertThat(users).size().isEqualTo(1); + assertThat(users).isNotEmpty().size().isEqualTo(1); } @Test - public void userDTOsToUsersWithAuthoritiesStringShouldMapToUsersWithAuthoritiesDomain() { + void userDTOsToUsersWithAuthoritiesStringShouldMapToUsersWithAuthoritiesDomain() { Set authoritiesAsString = new HashSet<>(); authoritiesAsString.add("ADMIN"); userDto.setAuthorities(authoritiesAsString); - List usersDto = new ArrayList<>(); + List usersDto = new ArrayList<>(); usersDto.add(userDto); List users = userMapper.userDTOsToUsers(usersDto); - assertThat(users).isNotEmpty(); - assertThat(users).size().isEqualTo(1); + assertThat(users).isNotEmpty().size().isEqualTo(1); assertThat(users.get(0).getAuthorities()).isNotNull(); assertThat(users.get(0).getAuthorities()).isNotEmpty(); assertThat(users.get(0).getAuthorities().iterator().next().getName()).isEqualTo("ADMIN"); } @Test - public void userDTOsToUsersMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() { + void userDTOsToUsersMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() { userDto.setAuthorities(null); - List usersDto = new ArrayList<>(); + List usersDto = new ArrayList<>(); usersDto.add(userDto); List users = userMapper.userDTOsToUsers(usersDto); - assertThat(users).isNotEmpty(); - assertThat(users).size().isEqualTo(1); + assertThat(users).isNotEmpty().size().isEqualTo(1); assertThat(users.get(0).getAuthorities()).isNotNull(); assertThat(users.get(0).getAuthorities()).isEmpty(); } @Test - public void userDTOToUserMapWithAuthoritiesStringShouldReturnUserWithAuthorities() { + void userDTOToUserMapWithAuthoritiesStringShouldReturnUserWithAuthorities() { Set authoritiesAsString = new HashSet<>(); authoritiesAsString.add("ADMIN"); userDto.setAuthorities(authoritiesAsString); - User appUser = userMapper.userDTOToUser(userDto); + User user = userMapper.userDTOToUser(userDto); - assertThat(appUser).isNotNull(); - assertThat(appUser.getAuthorities()).isNotNull(); - assertThat(appUser.getAuthorities()).isNotEmpty(); - assertThat(appUser.getAuthorities().iterator().next().getName()).isEqualTo("ADMIN"); + assertThat(user).isNotNull(); + assertThat(user.getAuthorities()).isNotNull(); + assertThat(user.getAuthorities()).isNotEmpty(); + assertThat(user.getAuthorities().iterator().next().getName()).isEqualTo("ADMIN"); } @Test - public void userDTOToUserMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() { + void userDTOToUserMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() { userDto.setAuthorities(null); - User appUser = userMapper.userDTOToUser(userDto); + User user = userMapper.userDTOToUser(userDto); - assertThat(appUser).isNotNull(); - assertThat(appUser.getAuthorities()).isNotNull(); - assertThat(appUser.getAuthorities()).isEmpty(); + assertThat(user).isNotNull(); + assertThat(user.getAuthorities()).isNotNull(); + assertThat(user.getAuthorities()).isEmpty(); } @Test - public void userDTOToUserMapWithNullUserShouldReturnNull() { + void userDTOToUserMapWithNullUserShouldReturnNull() { assertThat(userMapper.userDTOToUser(null)).isNull(); } @Test - public void testUserFromId() { + void testUserFromId() { assertThat(userMapper.userFromId(DEFAULT_ID).getId()).isEqualTo(DEFAULT_ID); assertThat(userMapper.userFromId(null)).isNull(); } diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/AccessTokenResourceIT.java b/src/test/java/org/securityrat/casemanagement/web/rest/AccessTokenResourceIT.java index 59bab81..887900d 100644 --- a/src/test/java/org/securityrat/casemanagement/web/rest/AccessTokenResourceIT.java +++ b/src/test/java/org/securityrat/casemanagement/web/rest/AccessTokenResourceIT.java @@ -1,44 +1,40 @@ package org.securityrat.casemanagement.web.rest; -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; -import org.securityrat.casemanagement.domain.AccessToken; -import org.securityrat.casemanagement.repository.UserRepository; -import org.securityrat.casemanagement.repository.AccessTokenRepository; -import org.securityrat.casemanagement.web.rest.errors.ExceptionTranslator; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.securityrat.casemanagement.web.rest.TestUtil.sameInstant; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; +import javax.persistence.EntityManager; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.MockitoAnnotations; +import org.securityrat.casemanagement.IntegrationTest; +import org.securityrat.casemanagement.domain.AccessToken; +import org.securityrat.casemanagement.repository.AccessTokenRepository; +import org.securityrat.casemanagement.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.Validator; - -import javax.persistence.EntityManager; -import java.time.Instant; -import java.time.ZonedDateTime; -import java.time.ZoneOffset; -import java.time.ZoneId; -import java.util.List; - -import static org.securityrat.casemanagement.web.rest.TestUtil.sameInstant; -import static org.securityrat.casemanagement.web.rest.TestUtil.createFormattingConversionService; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.hasItem; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; /** * Integration tests for the {@link AccessTokenResource} REST controller. */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -public class AccessTokenResourceIT { +@IntegrationTest +@AutoConfigureMockMvc +@WithMockUser +class AccessTokenResourceIT { private static final String DEFAULT_TOKEN = "AAAAAAAAAA"; private static final String UPDATED_TOKEN = "BBBBBBBBBB"; @@ -46,43 +42,32 @@ public class AccessTokenResourceIT { private static final ZonedDateTime DEFAULT_EXPIRATION_DATE = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0L), ZoneOffset.UTC); private static final ZonedDateTime UPDATED_EXPIRATION_DATE = ZonedDateTime.now(ZoneId.systemDefault()).withNano(0); - @Autowired - private AccessTokenRepository accessTokenRepository; + private static final String DEFAULT_SALT = "AAAAAAAAAA"; + private static final String UPDATED_SALT = "BBBBBBBBBB"; - @Autowired - private UserRepository appUserRepository; + private static final String DEFAULT_REFRESH_TOKEN = "AAAAAAAAAA"; + private static final String UPDATED_REFRESH_TOKEN = "BBBBBBBBBB"; - @Autowired - private MappingJackson2HttpMessageConverter jacksonMessageConverter; + private static final String ENTITY_API_URL = "/api/access-tokens"; + private static final String ENTITY_API_URL_ID = ENTITY_API_URL + "/{id}"; + + private static Random random = new Random(); + private static AtomicLong count = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE)); @Autowired - private PageableHandlerMethodArgumentResolver pageableArgumentResolver; + private AccessTokenRepository accessTokenRepository; @Autowired - private ExceptionTranslator exceptionTranslator; + private UserRepository userRepository; @Autowired private EntityManager em; @Autowired - private Validator validator; - private MockMvc restAccessTokenMockMvc; private AccessToken accessToken; - @BeforeEach - public void setup() { - MockitoAnnotations.initMocks(this); - final AccessTokenResource accessTokenResource = new AccessTokenResource(accessTokenRepository, appUserRepository); - this.restAccessTokenMockMvc = MockMvcBuilders.standaloneSetup(accessTokenResource) - .setCustomArgumentResolvers(pageableArgumentResolver) - .setControllerAdvice(exceptionTranslator) - .setConversionService(createFormattingConversionService()) - .setMessageConverters(jacksonMessageConverter) - .setValidator(validator).build(); - } - /** * Create an entity for this test. * @@ -92,9 +77,12 @@ public void setup() { public static AccessToken createEntity(EntityManager em) { AccessToken accessToken = new AccessToken() .token(DEFAULT_TOKEN) - .expirationDate(DEFAULT_EXPIRATION_DATE); + .expirationDate(DEFAULT_EXPIRATION_DATE) + .salt(DEFAULT_SALT) + .refreshToken(DEFAULT_REFRESH_TOKEN); return accessToken; } + /** * Create an updated entity for this test. * @@ -104,7 +92,9 @@ public static AccessToken createEntity(EntityManager em) { public static AccessToken createUpdatedEntity(EntityManager em) { AccessToken accessToken = new AccessToken() .token(UPDATED_TOKEN) - .expirationDate(UPDATED_EXPIRATION_DATE); + .expirationDate(UPDATED_EXPIRATION_DATE) + .salt(UPDATED_SALT) + .refreshToken(UPDATED_REFRESH_TOKEN); return accessToken; } @@ -115,13 +105,16 @@ public void initTest() { @Test @Transactional - public void createAccessToken() throws Exception { + void createAccessToken() throws Exception { int databaseSizeBeforeCreate = accessTokenRepository.findAll().size(); - // Create the AccessToken - restAccessTokenMockMvc.perform(post("/api/access-tokens") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(accessToken))) + restAccessTokenMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) .andExpect(status().isCreated()); // Validate the AccessToken in the database @@ -130,20 +123,26 @@ public void createAccessToken() throws Exception { AccessToken testAccessToken = accessTokenList.get(accessTokenList.size() - 1); assertThat(testAccessToken.getToken()).isEqualTo(DEFAULT_TOKEN); assertThat(testAccessToken.getExpirationDate()).isEqualTo(DEFAULT_EXPIRATION_DATE); + assertThat(testAccessToken.getSalt()).isEqualTo(DEFAULT_SALT); + assertThat(testAccessToken.getRefreshToken()).isEqualTo(DEFAULT_REFRESH_TOKEN); } @Test @Transactional - public void createAccessTokenWithExistingId() throws Exception { - int databaseSizeBeforeCreate = accessTokenRepository.findAll().size(); - + void createAccessTokenWithExistingId() throws Exception { // Create the AccessToken with an existing ID accessToken.setId(1L); + int databaseSizeBeforeCreate = accessTokenRepository.findAll().size(); + // An entity with an existing ID cannot be created, so this API call must fail - restAccessTokenMockMvc.perform(post("/api/access-tokens") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(accessToken))) + restAccessTokenMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) .andExpect(status().isBadRequest()); // Validate the AccessToken in the database @@ -151,19 +150,22 @@ public void createAccessTokenWithExistingId() throws Exception { assertThat(accessTokenList).hasSize(databaseSizeBeforeCreate); } - @Test @Transactional - public void checkTokenIsRequired() throws Exception { + void checkTokenIsRequired() throws Exception { int databaseSizeBeforeTest = accessTokenRepository.findAll().size(); // set the field null accessToken.setToken(null); // Create the AccessToken, which fails. - restAccessTokenMockMvc.perform(post("/api/access-tokens") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(accessToken))) + restAccessTokenMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) .andExpect(status().isBadRequest()); List accessTokenList = accessTokenRepository.findAll(); @@ -172,45 +174,72 @@ public void checkTokenIsRequired() throws Exception { @Test @Transactional - public void getAllAccessTokens() throws Exception { + void checkSaltIsRequired() throws Exception { + int databaseSizeBeforeTest = accessTokenRepository.findAll().size(); + // set the field null + accessToken.setSalt(null); + + // Create the AccessToken, which fails. + + restAccessTokenMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) + .andExpect(status().isBadRequest()); + + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeTest); + } + + @Test + @Transactional + void getAllAccessTokens() throws Exception { // Initialize the database accessTokenRepository.saveAndFlush(accessToken); // Get all the accessTokenList - restAccessTokenMockMvc.perform(get("/api/access-tokens?sort=id,desc")) + restAccessTokenMockMvc + .perform(get(ENTITY_API_URL + "?sort=id,desc")) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].id").value(hasItem(accessToken.getId().intValue()))) .andExpect(jsonPath("$.[*].token").value(hasItem(DEFAULT_TOKEN))) - .andExpect(jsonPath("$.[*].expirationDate").value(hasItem(sameInstant(DEFAULT_EXPIRATION_DATE)))); + .andExpect(jsonPath("$.[*].expirationDate").value(hasItem(sameInstant(DEFAULT_EXPIRATION_DATE)))) + .andExpect(jsonPath("$.[*].salt").value(hasItem(DEFAULT_SALT))) + .andExpect(jsonPath("$.[*].refreshToken").value(hasItem(DEFAULT_REFRESH_TOKEN))); } - + @Test @Transactional - public void getAccessToken() throws Exception { + void getAccessToken() throws Exception { // Initialize the database accessTokenRepository.saveAndFlush(accessToken); // Get the accessToken - restAccessTokenMockMvc.perform(get("/api/access-tokens/{id}", accessToken.getId())) + restAccessTokenMockMvc + .perform(get(ENTITY_API_URL_ID, accessToken.getId())) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.id").value(accessToken.getId().intValue())) .andExpect(jsonPath("$.token").value(DEFAULT_TOKEN)) - .andExpect(jsonPath("$.expirationDate").value(sameInstant(DEFAULT_EXPIRATION_DATE))); + .andExpect(jsonPath("$.expirationDate").value(sameInstant(DEFAULT_EXPIRATION_DATE))) + .andExpect(jsonPath("$.salt").value(DEFAULT_SALT)) + .andExpect(jsonPath("$.refreshToken").value(DEFAULT_REFRESH_TOKEN)); } @Test @Transactional - public void getNonExistingAccessToken() throws Exception { + void getNonExistingAccessToken() throws Exception { // Get the accessToken - restAccessTokenMockMvc.perform(get("/api/access-tokens/{id}", Long.MAX_VALUE)) - .andExpect(status().isNotFound()); + restAccessTokenMockMvc.perform(get(ENTITY_API_URL_ID, Long.MAX_VALUE)).andExpect(status().isNotFound()); } @Test @Transactional - public void updateAccessToken() throws Exception { + void putNewAccessToken() throws Exception { // Initialize the database accessTokenRepository.saveAndFlush(accessToken); @@ -222,11 +251,17 @@ public void updateAccessToken() throws Exception { em.detach(updatedAccessToken); updatedAccessToken .token(UPDATED_TOKEN) - .expirationDate(UPDATED_EXPIRATION_DATE); - - restAccessTokenMockMvc.perform(put("/api/access-tokens") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(updatedAccessToken))) + .expirationDate(UPDATED_EXPIRATION_DATE) + .salt(UPDATED_SALT) + .refreshToken(UPDATED_REFRESH_TOKEN); + + restAccessTokenMockMvc + .perform( + put(ENTITY_API_URL_ID, updatedAccessToken.getId()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(updatedAccessToken)) + ) .andExpect(status().isOk()); // Validate the AccessToken in the database @@ -235,19 +270,157 @@ public void updateAccessToken() throws Exception { AccessToken testAccessToken = accessTokenList.get(accessTokenList.size() - 1); assertThat(testAccessToken.getToken()).isEqualTo(UPDATED_TOKEN); assertThat(testAccessToken.getExpirationDate()).isEqualTo(UPDATED_EXPIRATION_DATE); + assertThat(testAccessToken.getSalt()).isEqualTo(UPDATED_SALT); + assertThat(testAccessToken.getRefreshToken()).isEqualTo(UPDATED_REFRESH_TOKEN); } @Test @Transactional - public void updateNonExistingAccessToken() throws Exception { + void putNonExistingAccessToken() throws Exception { int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + accessToken.setId(count.incrementAndGet()); - // Create the AccessToken + // If the entity doesn't have an ID, it will throw BadRequestAlertException + restAccessTokenMockMvc + .perform( + put(ENTITY_API_URL_ID, accessToken.getId()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) + .andExpect(status().isBadRequest()); + + // Validate the AccessToken in the database + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void putWithIdMismatchAccessToken() throws Exception { + int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + accessToken.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restAccessTokenMockMvc + .perform( + put(ENTITY_API_URL_ID, count.incrementAndGet()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) + .andExpect(status().isBadRequest()); + + // Validate the AccessToken in the database + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void putWithMissingIdPathParamAccessToken() throws Exception { + int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + accessToken.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restAccessTokenMockMvc + .perform( + put(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) + .andExpect(status().isMethodNotAllowed()); + + // Validate the AccessToken in the database + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void partialUpdateAccessTokenWithPatch() throws Exception { + // Initialize the database + accessTokenRepository.saveAndFlush(accessToken); + + int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + + // Update the accessToken using partial update + AccessToken partialUpdatedAccessToken = new AccessToken(); + partialUpdatedAccessToken.setId(accessToken.getId()); + + partialUpdatedAccessToken.expirationDate(UPDATED_EXPIRATION_DATE).salt(UPDATED_SALT).refreshToken(UPDATED_REFRESH_TOKEN); + + restAccessTokenMockMvc + .perform( + patch(ENTITY_API_URL_ID, partialUpdatedAccessToken.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(partialUpdatedAccessToken)) + ) + .andExpect(status().isOk()); + + // Validate the AccessToken in the database + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeUpdate); + AccessToken testAccessToken = accessTokenList.get(accessTokenList.size() - 1); + assertThat(testAccessToken.getToken()).isEqualTo(DEFAULT_TOKEN); + assertThat(testAccessToken.getExpirationDate()).isEqualTo(UPDATED_EXPIRATION_DATE); + assertThat(testAccessToken.getSalt()).isEqualTo(UPDATED_SALT); + assertThat(testAccessToken.getRefreshToken()).isEqualTo(UPDATED_REFRESH_TOKEN); + } + + @Test + @Transactional + void fullUpdateAccessTokenWithPatch() throws Exception { + // Initialize the database + accessTokenRepository.saveAndFlush(accessToken); + + int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + + // Update the accessToken using partial update + AccessToken partialUpdatedAccessToken = new AccessToken(); + partialUpdatedAccessToken.setId(accessToken.getId()); + + partialUpdatedAccessToken + .token(UPDATED_TOKEN) + .expirationDate(UPDATED_EXPIRATION_DATE) + .salt(UPDATED_SALT) + .refreshToken(UPDATED_REFRESH_TOKEN); + + restAccessTokenMockMvc + .perform( + patch(ENTITY_API_URL_ID, partialUpdatedAccessToken.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(partialUpdatedAccessToken)) + ) + .andExpect(status().isOk()); + + // Validate the AccessToken in the database + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeUpdate); + AccessToken testAccessToken = accessTokenList.get(accessTokenList.size() - 1); + assertThat(testAccessToken.getToken()).isEqualTo(UPDATED_TOKEN); + assertThat(testAccessToken.getExpirationDate()).isEqualTo(UPDATED_EXPIRATION_DATE); + assertThat(testAccessToken.getSalt()).isEqualTo(UPDATED_SALT); + assertThat(testAccessToken.getRefreshToken()).isEqualTo(UPDATED_REFRESH_TOKEN); + } + + @Test + @Transactional + void patchNonExistingAccessToken() throws Exception { + int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + accessToken.setId(count.incrementAndGet()); // If the entity doesn't have an ID, it will throw BadRequestAlertException - restAccessTokenMockMvc.perform(put("/api/access-tokens") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(accessToken))) + restAccessTokenMockMvc + .perform( + patch(ENTITY_API_URL_ID, accessToken.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) .andExpect(status().isBadRequest()); // Validate the AccessToken in the database @@ -257,15 +430,57 @@ public void updateNonExistingAccessToken() throws Exception { @Test @Transactional - public void deleteAccessToken() throws Exception { + void patchWithIdMismatchAccessToken() throws Exception { + int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + accessToken.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restAccessTokenMockMvc + .perform( + patch(ENTITY_API_URL_ID, count.incrementAndGet()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) + .andExpect(status().isBadRequest()); + + // Validate the AccessToken in the database + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void patchWithMissingIdPathParamAccessToken() throws Exception { + int databaseSizeBeforeUpdate = accessTokenRepository.findAll().size(); + accessToken.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restAccessTokenMockMvc + .perform( + patch(ENTITY_API_URL) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(accessToken)) + ) + .andExpect(status().isMethodNotAllowed()); + + // Validate the AccessToken in the database + List accessTokenList = accessTokenRepository.findAll(); + assertThat(accessTokenList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void deleteAccessToken() throws Exception { // Initialize the database accessTokenRepository.saveAndFlush(accessToken); int databaseSizeBeforeDelete = accessTokenRepository.findAll().size(); // Delete the accessToken - restAccessTokenMockMvc.perform(delete("/api/access-tokens/{id}", accessToken.getId()) - .accept(TestUtil.APPLICATION_JSON_UTF8)) + restAccessTokenMockMvc + .perform(delete(ENTITY_API_URL_ID, accessToken.getId()).with(csrf()).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); // Validate the database contains one less item diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/AuditResourceIT.java b/src/test/java/org/securityrat/casemanagement/web/rest/AuditResourceIT.java deleted file mode 100644 index 555ae5b..0000000 --- a/src/test/java/org/securityrat/casemanagement/web/rest/AuditResourceIT.java +++ /dev/null @@ -1,165 +0,0 @@ -package org.securityrat.casemanagement.web.rest; - -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; -import io.github.jhipster.config.JHipsterProperties; -import org.securityrat.casemanagement.config.audit.AuditEventConverter; -import org.securityrat.casemanagement.domain.PersistentAuditEvent; -import org.securityrat.casemanagement.repository.PersistenceAuditEventRepository; - -import org.securityrat.casemanagement.service.AuditEventService; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.MockitoAnnotations; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; -import org.springframework.format.support.FormattingConversionService; -import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.transaction.annotation.Transactional; - -import java.time.Instant; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.hamcrest.Matchers.hasItem; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -/** - * Integration tests for the {@link AuditResource} REST controller. - */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -@Transactional -public class AuditResourceIT { - - private static final String SAMPLE_PRINCIPAL = "SAMPLE_PRINCIPAL"; - private static final String SAMPLE_TYPE = "SAMPLE_TYPE"; - private static final Instant SAMPLE_TIMESTAMP = Instant.parse("2015-08-04T10:11:30Z"); - private static final long SECONDS_PER_DAY = 60 * 60 * 24; - - @Autowired - private PersistenceAuditEventRepository auditEventRepository; - - @Autowired - private AuditEventConverter auditEventConverter; - - @Autowired - private JHipsterProperties jhipsterProperties; - - @Autowired - private MappingJackson2HttpMessageConverter jacksonMessageConverter; - - @Autowired - @Qualifier("mvcConversionService") - private FormattingConversionService formattingConversionService; - - @Autowired - private PageableHandlerMethodArgumentResolver pageableArgumentResolver; - - private PersistentAuditEvent auditEvent; - - private MockMvc restAuditMockMvc; - - @BeforeEach - public void setup() { - MockitoAnnotations.initMocks(this); - AuditEventService auditEventService = - new AuditEventService(auditEventRepository, auditEventConverter, jhipsterProperties); - AuditResource auditResource = new AuditResource(auditEventService); - this.restAuditMockMvc = MockMvcBuilders.standaloneSetup(auditResource) - .setCustomArgumentResolvers(pageableArgumentResolver) - .setConversionService(formattingConversionService) - .setMessageConverters(jacksonMessageConverter).build(); - } - - @BeforeEach - public void initTest() { - auditEventRepository.deleteAll(); - auditEvent = new PersistentAuditEvent(); - auditEvent.setAuditEventType(SAMPLE_TYPE); - auditEvent.setPrincipal(SAMPLE_PRINCIPAL); - auditEvent.setAuditEventDate(SAMPLE_TIMESTAMP); - } - - @Test - public void getAllAudits() throws Exception { - // Initialize the database - auditEventRepository.save(auditEvent); - - // Get all the audits - restAuditMockMvc.perform(get("/management/audits")) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) - .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL))); - } - - @Test - public void getAudit() throws Exception { - // Initialize the database - auditEventRepository.save(auditEvent); - - // Get the audit - restAuditMockMvc.perform(get("/management/audits/{id}", auditEvent.getId())) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) - .andExpect(jsonPath("$.principal").value(SAMPLE_PRINCIPAL)); - } - - @Test - public void getAuditsByDate() throws Exception { - // Initialize the database - auditEventRepository.save(auditEvent); - - // Generate dates for selecting audits by date, making sure the period will contain the audit - String fromDate = SAMPLE_TIMESTAMP.minusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); - String toDate = SAMPLE_TIMESTAMP.plusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); - - // Get the audit - restAuditMockMvc.perform(get("/management/audits?fromDate="+fromDate+"&toDate="+toDate)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) - .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL))); - } - - @Test - public void getNonExistingAuditsByDate() throws Exception { - // Initialize the database - auditEventRepository.save(auditEvent); - - // Generate dates for selecting audits by date, making sure the period will not contain the sample audit - String fromDate = SAMPLE_TIMESTAMP.minusSeconds(2*SECONDS_PER_DAY).toString().substring(0, 10); - String toDate = SAMPLE_TIMESTAMP.minusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); - - // Query audits but expect no results - restAuditMockMvc.perform(get("/management/audits?fromDate=" + fromDate + "&toDate=" + toDate)) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) - .andExpect(header().string("X-Total-Count", "0")); - } - - @Test - public void getNonExistingAudit() throws Exception { - // Get the audit - restAuditMockMvc.perform(get("/management/audits/{id}", Long.MAX_VALUE)) - .andExpect(status().isNotFound()); - } - - @Test - @Transactional - public void testPersistentAuditEventEquals() throws Exception { - TestUtil.equalsVerifier(PersistentAuditEvent.class); - PersistentAuditEvent auditEvent1 = new PersistentAuditEvent(); - auditEvent1.setId(1L); - PersistentAuditEvent auditEvent2 = new PersistentAuditEvent(); - auditEvent2.setId(auditEvent1.getId()); - assertThat(auditEvent1).isEqualTo(auditEvent2); - auditEvent2.setId(2L); - assertThat(auditEvent1).isNotEqualTo(auditEvent2); - auditEvent1.setId(null); - assertThat(auditEvent1).isNotEqualTo(auditEvent2); - } -} diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/PublicUserResourceIT.java b/src/test/java/org/securityrat/casemanagement/web/rest/PublicUserResourceIT.java new file mode 100644 index 0000000..aa8f568 --- /dev/null +++ b/src/test/java/org/securityrat/casemanagement/web/rest/PublicUserResourceIT.java @@ -0,0 +1,65 @@ +package org.securityrat.casemanagement.web.rest; + +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasItems; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import javax.persistence.EntityManager; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.securityrat.casemanagement.IntegrationTest; +import org.securityrat.casemanagement.config.TestSecurityConfiguration; +import org.securityrat.casemanagement.domain.User; +import org.securityrat.casemanagement.repository.UserRepository; +import org.securityrat.casemanagement.security.AuthoritiesConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +/** + * Integration tests for the {@link UserResource} REST controller. + */ +@AutoConfigureMockMvc +@WithMockUser(authorities = AuthoritiesConstants.ADMIN) +@IntegrationTest +class PublicUserResourceIT { + + private static final String DEFAULT_LOGIN = "johndoe"; + + @Autowired + private UserRepository userRepository; + + @Autowired + private EntityManager em; + + @Autowired + private MockMvc restUserMockMvc; + + private User user; + + @BeforeEach + public void initTest() { + user = UserResourceIT.initTestUser(userRepository, em); + } + + @Test + @Transactional + void getAllPublicUsers() throws Exception { + // Initialize the database + userRepository.saveAndFlush(user); + + // Get all the users + restUserMockMvc + .perform(get("/api/users?sort=id,desc").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.[*].login").value(hasItem(DEFAULT_LOGIN))) + .andExpect(jsonPath("$.[*].email").doesNotExist()) + .andExpect(jsonPath("$.[*].imageUrl").doesNotExist()) + .andExpect(jsonPath("$.[*].langKey").doesNotExist()); + } +} diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/TestUtil.java b/src/test/java/org/securityrat/casemanagement/web/rest/TestUtil.java index 3568b2d..5e12ae4 100644 --- a/src/test/java/org/securityrat/casemanagement/web/rest/TestUtil.java +++ b/src/test/java/org/securityrat/casemanagement/web/rest/TestUtil.java @@ -1,27 +1,34 @@ package org.securityrat.casemanagement.web.rest; +import static org.assertj.core.api.Assertions.assertThat; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import org.hamcrest.Description; -import org.hamcrest.TypeSafeDiagnosingMatcher; -import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar; -import org.springframework.format.support.DefaultFormattingConversionService; -import org.springframework.format.support.FormattingConversionService; -import org.springframework.http.MediaType; - import java.io.IOException; +import java.math.BigDecimal; import java.time.ZonedDateTime; import java.time.format.DateTimeParseException; +import java.util.Collection; import java.util.List; - import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; - -import static org.assertj.core.api.Assertions.assertThat; +import org.hamcrest.Description; +import org.hamcrest.TypeSafeDiagnosingMatcher; +import org.hamcrest.TypeSafeMatcher; +import org.securityrat.casemanagement.security.SecurityUtils; +import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar; +import org.springframework.format.support.DefaultFormattingConversionService; +import org.springframework.format.support.FormattingConversionService; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.core.oidc.OidcIdToken; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.security.oauth2.core.oidc.user.OidcUser; /** * Utility class for testing REST controllers. @@ -30,11 +37,9 @@ public final class TestUtil { private static final ObjectMapper mapper = createObjectMapper(); - /** MediaType for JSON UTF8 */ - public static final MediaType APPLICATION_JSON_UTF8 = MediaType.APPLICATION_JSON_UTF8; - private static ObjectMapper createObjectMapper() { ObjectMapper mapper = new ObjectMapper(); + mapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false); mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); mapper.registerModule(new JavaTimeModule()); return mapper; @@ -86,11 +91,9 @@ protected boolean matchesSafely(String item, Description mismatchDescription) { } return true; } catch (DateTimeParseException e) { - mismatchDescription.appendText("was ").appendValue(item) - .appendText(", which could not be parsed as a ZonedDateTime"); + mismatchDescription.appendText("was ").appendValue(item).appendText(", which could not be parsed as a ZonedDateTime"); return false; } - } @Override @@ -101,12 +104,64 @@ public void describeTo(Description description) { /** * Creates a matcher that matches when the examined string represents the same instant as the reference datetime. + * * @param date the reference datetime against which the examined string is checked. */ public static ZonedDateTimeMatcher sameInstant(ZonedDateTime date) { return new ZonedDateTimeMatcher(date); } + /** + * A matcher that tests that the examined number represents the same value - it can be Long, Double, etc - as the reference BigDecimal. + */ + public static class NumberMatcher extends TypeSafeMatcher { + + final BigDecimal value; + + public NumberMatcher(BigDecimal value) { + this.value = value; + } + + @Override + public void describeTo(Description description) { + description.appendText("a numeric value is ").appendValue(value); + } + + @Override + protected boolean matchesSafely(Number item) { + BigDecimal bigDecimal = asDecimal(item); + return bigDecimal != null && value.compareTo(bigDecimal) == 0; + } + + private static BigDecimal asDecimal(Number item) { + if (item == null) { + return null; + } + if (item instanceof BigDecimal) { + return (BigDecimal) item; + } else if (item instanceof Long) { + return BigDecimal.valueOf((Long) item); + } else if (item instanceof Integer) { + return BigDecimal.valueOf((Integer) item); + } else if (item instanceof Double) { + return BigDecimal.valueOf((Double) item); + } else if (item instanceof Float) { + return BigDecimal.valueOf((Float) item); + } else { + return BigDecimal.valueOf(item.doubleValue()); + } + } + } + + /** + * Creates a matcher that matches when the examined number represents the same value as the reference BigDecimal. + * + * @param number the reference BigDecimal against which the examined number is checked. + */ + public static NumberMatcher sameNumber(BigDecimal number) { + return new NumberMatcher(number); + } + /** * Verifies the equals/hashcode contract on the domain object. */ @@ -114,7 +169,7 @@ public static void equalsVerifier(Class clazz) throws Exception { T domainObject1 = clazz.getConstructor().newInstance(); assertThat(domainObject1.toString()).isNotNull(); assertThat(domainObject1).isEqualTo(domainObject1); - assertThat(domainObject1.hashCode()).isEqualTo(domainObject1.hashCode()); + assertThat(domainObject1).hasSameHashCodeAs(domainObject1); // Test with an instance of another class Object testOtherObject = new Object(); assertThat(domainObject1).isNotEqualTo(testOtherObject); @@ -123,7 +178,7 @@ public static void equalsVerifier(Class clazz) throws Exception { T domainObject2 = clazz.getConstructor().newInstance(); assertThat(domainObject1).isNotEqualTo(domainObject2); // HashCodes are equals because the objects are not persisted yet - assertThat(domainObject1.hashCode()).isEqualTo(domainObject2.hashCode()); + assertThat(domainObject1).hasSameHashCodeAs(domainObject2); } /** @@ -131,7 +186,7 @@ public static void equalsVerifier(Class clazz) throws Exception { * @return the {@link FormattingConversionService}. */ public static FormattingConversionService createFormattingConversionService() { - DefaultFormattingConversionService dfcs = new DefaultFormattingConversionService (); + DefaultFormattingConversionService dfcs = new DefaultFormattingConversionService(); DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar(); registrar.setUseIsoFormat(true); registrar.registerFormatters(dfcs); @@ -154,5 +209,18 @@ public static List findAll(EntityManager em, Class clss) { return allQuery.getResultList(); } + static final String ID_TOKEN = + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" + + ".eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsIm" + + "p0aSI6ImQzNWRmMTRkLTA5ZjYtNDhmZi04YTkzLTdjNmYwMzM5MzE1OSIsImlhdCI6MTU0M" + + "Tk3MTU4MywiZXhwIjoxNTQxOTc1MTgzfQ.QaQOarmV8xEUYV7yvWzX3cUE_4W1luMcWCwpr" + + "oqqUrg"; + + public static OAuth2AuthenticationToken authenticationToken(OidcIdToken idToken) { + Collection authorities = SecurityUtils.extractAuthorityFromClaims(idToken.getClaims()); + OidcUser user = new DefaultOidcUser(authorities, idToken); + return new OAuth2AuthenticationToken(user, authorities, "oidc"); + } + private TestUtil() {} } diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResourceIT.java b/src/test/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResourceIT.java index 6d20c9e..4b45a87 100644 --- a/src/test/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResourceIT.java +++ b/src/test/java/org/securityrat/casemanagement/web/rest/TicketSystemInstanceResourceIT.java @@ -1,39 +1,35 @@ package org.securityrat.casemanagement.web.rest; -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; -import org.securityrat.casemanagement.domain.TicketSystemInstance; -import org.securityrat.casemanagement.repository.TicketSystemInstanceRepository; -import org.securityrat.casemanagement.web.rest.errors.ExceptionTranslator; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import java.util.List; +import java.util.Random; +import java.util.concurrent.atomic.AtomicLong; +import javax.persistence.EntityManager; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.MockitoAnnotations; +import org.securityrat.casemanagement.IntegrationTest; +import org.securityrat.casemanagement.domain.TicketSystemInstance; +import org.securityrat.casemanagement.domain.enumeration.TicketSystem; +import org.securityrat.casemanagement.repository.TicketSystemInstanceRepository; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.Validator; - -import javax.persistence.EntityManager; -import java.util.List; -import static org.securityrat.casemanagement.web.rest.TestUtil.createFormattingConversionService; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.hasItem; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import org.securityrat.casemanagement.domain.enumeration.TicketSystem; /** * Integration tests for the {@link TicketSystemInstanceResource} REST controller. */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -public class TicketSystemInstanceResourceIT { +@IntegrationTest +@AutoConfigureMockMvc +@WithMockUser +class TicketSystemInstanceResourceIT { private static final String DEFAULT_NAME = "AAAAAAAAAA"; private static final String UPDATED_NAME = "BBBBBBBBBB"; @@ -44,40 +40,32 @@ public class TicketSystemInstanceResourceIT { private static final String DEFAULT_URL = "AAAAAAAAAA"; private static final String UPDATED_URL = "BBBBBBBBBB"; - @Autowired - private TicketSystemInstanceRepository ticketSystemInstanceRepository; + private static final String DEFAULT_CONSUMER_KEY = "AAAAAAAAAA"; + private static final String UPDATED_CONSUMER_KEY = "BBBBBBBBBB"; - @Autowired - private MappingJackson2HttpMessageConverter jacksonMessageConverter; + private static final String DEFAULT_CLIENT_ID = "AAAAAAAAAA"; + private static final String UPDATED_CLIENT_ID = "BBBBBBBBBB"; - @Autowired - private PageableHandlerMethodArgumentResolver pageableArgumentResolver; + private static final String DEFAULT_CLIENT_SECRET = "AAAAAAAAAA"; + private static final String UPDATED_CLIENT_SECRET = "BBBBBBBBBB"; + + private static final String ENTITY_API_URL = "/api/ticket-system-instances"; + private static final String ENTITY_API_URL_ID = ENTITY_API_URL + "/{id}"; + + private static Random random = new Random(); + private static AtomicLong count = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE)); @Autowired - private ExceptionTranslator exceptionTranslator; + private TicketSystemInstanceRepository ticketSystemInstanceRepository; @Autowired private EntityManager em; @Autowired - private Validator validator; - private MockMvc restTicketSystemInstanceMockMvc; private TicketSystemInstance ticketSystemInstance; - @BeforeEach - public void setup() { - MockitoAnnotations.initMocks(this); - final TicketSystemInstanceResource ticketSystemInstanceResource = new TicketSystemInstanceResource(ticketSystemInstanceRepository); - this.restTicketSystemInstanceMockMvc = MockMvcBuilders.standaloneSetup(ticketSystemInstanceResource) - .setCustomArgumentResolvers(pageableArgumentResolver) - .setControllerAdvice(exceptionTranslator) - .setConversionService(createFormattingConversionService()) - .setMessageConverters(jacksonMessageConverter) - .setValidator(validator).build(); - } - /** * Create an entity for this test. * @@ -88,9 +76,13 @@ public static TicketSystemInstance createEntity(EntityManager em) { TicketSystemInstance ticketSystemInstance = new TicketSystemInstance() .name(DEFAULT_NAME) .type(DEFAULT_TYPE) - .url(DEFAULT_URL); + .url(DEFAULT_URL) + .consumerKey(DEFAULT_CONSUMER_KEY) + .clientId(DEFAULT_CLIENT_ID) + .clientSecret(DEFAULT_CLIENT_SECRET); return ticketSystemInstance; } + /** * Create an updated entity for this test. * @@ -101,7 +93,10 @@ public static TicketSystemInstance createUpdatedEntity(EntityManager em) { TicketSystemInstance ticketSystemInstance = new TicketSystemInstance() .name(UPDATED_NAME) .type(UPDATED_TYPE) - .url(UPDATED_URL); + .url(UPDATED_URL) + .consumerKey(UPDATED_CONSUMER_KEY) + .clientId(UPDATED_CLIENT_ID) + .clientSecret(UPDATED_CLIENT_SECRET); return ticketSystemInstance; } @@ -112,13 +107,16 @@ public void initTest() { @Test @Transactional - public void createTicketSystemInstance() throws Exception { + void createTicketSystemInstance() throws Exception { int databaseSizeBeforeCreate = ticketSystemInstanceRepository.findAll().size(); - // Create the TicketSystemInstance - restTicketSystemInstanceMockMvc.perform(post("/api/ticket-system-instances") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance))) + restTicketSystemInstanceMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) .andExpect(status().isCreated()); // Validate the TicketSystemInstance in the database @@ -128,20 +126,27 @@ public void createTicketSystemInstance() throws Exception { assertThat(testTicketSystemInstance.getName()).isEqualTo(DEFAULT_NAME); assertThat(testTicketSystemInstance.getType()).isEqualTo(DEFAULT_TYPE); assertThat(testTicketSystemInstance.getUrl()).isEqualTo(DEFAULT_URL); + assertThat(testTicketSystemInstance.getConsumerKey()).isEqualTo(DEFAULT_CONSUMER_KEY); + assertThat(testTicketSystemInstance.getClientId()).isEqualTo(DEFAULT_CLIENT_ID); + assertThat(testTicketSystemInstance.getClientSecret()).isEqualTo(DEFAULT_CLIENT_SECRET); } @Test @Transactional - public void createTicketSystemInstanceWithExistingId() throws Exception { - int databaseSizeBeforeCreate = ticketSystemInstanceRepository.findAll().size(); - + void createTicketSystemInstanceWithExistingId() throws Exception { // Create the TicketSystemInstance with an existing ID ticketSystemInstance.setId(1L); + int databaseSizeBeforeCreate = ticketSystemInstanceRepository.findAll().size(); + // An entity with an existing ID cannot be created, so this API call must fail - restTicketSystemInstanceMockMvc.perform(post("/api/ticket-system-instances") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance))) + restTicketSystemInstanceMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) .andExpect(status().isBadRequest()); // Validate the TicketSystemInstance in the database @@ -149,19 +154,22 @@ public void createTicketSystemInstanceWithExistingId() throws Exception { assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeCreate); } - @Test @Transactional - public void checkTypeIsRequired() throws Exception { + void checkTypeIsRequired() throws Exception { int databaseSizeBeforeTest = ticketSystemInstanceRepository.findAll().size(); // set the field null ticketSystemInstance.setType(null); // Create the TicketSystemInstance, which fails. - restTicketSystemInstanceMockMvc.perform(post("/api/ticket-system-instances") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance))) + restTicketSystemInstanceMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) .andExpect(status().isBadRequest()); List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); @@ -170,16 +178,20 @@ public void checkTypeIsRequired() throws Exception { @Test @Transactional - public void checkUrlIsRequired() throws Exception { + void checkUrlIsRequired() throws Exception { int databaseSizeBeforeTest = ticketSystemInstanceRepository.findAll().size(); // set the field null ticketSystemInstance.setUrl(null); // Create the TicketSystemInstance, which fails. - restTicketSystemInstanceMockMvc.perform(post("/api/ticket-system-instances") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance))) + restTicketSystemInstanceMockMvc + .perform( + post(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) .andExpect(status().isBadRequest()); List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); @@ -188,47 +200,54 @@ public void checkUrlIsRequired() throws Exception { @Test @Transactional - public void getAllTicketSystemInstances() throws Exception { + void getAllTicketSystemInstances() throws Exception { // Initialize the database ticketSystemInstanceRepository.saveAndFlush(ticketSystemInstance); // Get all the ticketSystemInstanceList - restTicketSystemInstanceMockMvc.perform(get("/api/ticket-system-instances?sort=id,desc")) + restTicketSystemInstanceMockMvc + .perform(get(ENTITY_API_URL + "?sort=id,desc")) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].id").value(hasItem(ticketSystemInstance.getId().intValue()))) .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME))) .andExpect(jsonPath("$.[*].type").value(hasItem(DEFAULT_TYPE.toString()))) - .andExpect(jsonPath("$.[*].url").value(hasItem(DEFAULT_URL))); + .andExpect(jsonPath("$.[*].url").value(hasItem(DEFAULT_URL))) + .andExpect(jsonPath("$.[*].consumerKey").value(hasItem(DEFAULT_CONSUMER_KEY))) + .andExpect(jsonPath("$.[*].clientId").value(hasItem(DEFAULT_CLIENT_ID))) + .andExpect(jsonPath("$.[*].clientSecret").value(hasItem(DEFAULT_CLIENT_SECRET))); } - + @Test @Transactional - public void getTicketSystemInstance() throws Exception { + void getTicketSystemInstance() throws Exception { // Initialize the database ticketSystemInstanceRepository.saveAndFlush(ticketSystemInstance); // Get the ticketSystemInstance - restTicketSystemInstanceMockMvc.perform(get("/api/ticket-system-instances/{id}", ticketSystemInstance.getId())) + restTicketSystemInstanceMockMvc + .perform(get(ENTITY_API_URL_ID, ticketSystemInstance.getId())) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.id").value(ticketSystemInstance.getId().intValue())) .andExpect(jsonPath("$.name").value(DEFAULT_NAME)) .andExpect(jsonPath("$.type").value(DEFAULT_TYPE.toString())) - .andExpect(jsonPath("$.url").value(DEFAULT_URL)); + .andExpect(jsonPath("$.url").value(DEFAULT_URL)) + .andExpect(jsonPath("$.consumerKey").value(DEFAULT_CONSUMER_KEY)) + .andExpect(jsonPath("$.clientId").value(DEFAULT_CLIENT_ID)) + .andExpect(jsonPath("$.clientSecret").value(DEFAULT_CLIENT_SECRET)); } @Test @Transactional - public void getNonExistingTicketSystemInstance() throws Exception { + void getNonExistingTicketSystemInstance() throws Exception { // Get the ticketSystemInstance - restTicketSystemInstanceMockMvc.perform(get("/api/ticket-system-instances/{id}", Long.MAX_VALUE)) - .andExpect(status().isNotFound()); + restTicketSystemInstanceMockMvc.perform(get(ENTITY_API_URL_ID, Long.MAX_VALUE)).andExpect(status().isNotFound()); } @Test @Transactional - public void updateTicketSystemInstance() throws Exception { + void putNewTicketSystemInstance() throws Exception { // Initialize the database ticketSystemInstanceRepository.saveAndFlush(ticketSystemInstance); @@ -241,11 +260,18 @@ public void updateTicketSystemInstance() throws Exception { updatedTicketSystemInstance .name(UPDATED_NAME) .type(UPDATED_TYPE) - .url(UPDATED_URL); - - restTicketSystemInstanceMockMvc.perform(put("/api/ticket-system-instances") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(updatedTicketSystemInstance))) + .url(UPDATED_URL) + .consumerKey(UPDATED_CONSUMER_KEY) + .clientId(UPDATED_CLIENT_ID) + .clientSecret(UPDATED_CLIENT_SECRET); + + restTicketSystemInstanceMockMvc + .perform( + put(ENTITY_API_URL_ID, updatedTicketSystemInstance.getId()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(updatedTicketSystemInstance)) + ) .andExpect(status().isOk()); // Validate the TicketSystemInstance in the database @@ -255,19 +281,185 @@ public void updateTicketSystemInstance() throws Exception { assertThat(testTicketSystemInstance.getName()).isEqualTo(UPDATED_NAME); assertThat(testTicketSystemInstance.getType()).isEqualTo(UPDATED_TYPE); assertThat(testTicketSystemInstance.getUrl()).isEqualTo(UPDATED_URL); + assertThat(testTicketSystemInstance.getConsumerKey()).isEqualTo(UPDATED_CONSUMER_KEY); + assertThat(testTicketSystemInstance.getClientId()).isEqualTo(UPDATED_CLIENT_ID); + assertThat(testTicketSystemInstance.getClientSecret()).isEqualTo(UPDATED_CLIENT_SECRET); } @Test @Transactional - public void updateNonExistingTicketSystemInstance() throws Exception { + void putNonExistingTicketSystemInstance() throws Exception { int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + ticketSystemInstance.setId(count.incrementAndGet()); - // Create the TicketSystemInstance + // If the entity doesn't have an ID, it will throw BadRequestAlertException + restTicketSystemInstanceMockMvc + .perform( + put(ENTITY_API_URL_ID, ticketSystemInstance.getId()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) + .andExpect(status().isBadRequest()); + + // Validate the TicketSystemInstance in the database + List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); + assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void putWithIdMismatchTicketSystemInstance() throws Exception { + int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + ticketSystemInstance.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restTicketSystemInstanceMockMvc + .perform( + put(ENTITY_API_URL_ID, count.incrementAndGet()) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) + .andExpect(status().isBadRequest()); + + // Validate the TicketSystemInstance in the database + List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); + assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void putWithMissingIdPathParamTicketSystemInstance() throws Exception { + int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + ticketSystemInstance.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restTicketSystemInstanceMockMvc + .perform( + put(ENTITY_API_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) + .andExpect(status().isMethodNotAllowed()); + + // Validate the TicketSystemInstance in the database + List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); + assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void partialUpdateTicketSystemInstanceWithPatch() throws Exception { + // Initialize the database + ticketSystemInstanceRepository.saveAndFlush(ticketSystemInstance); + + int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + + // Update the ticketSystemInstance using partial update + TicketSystemInstance partialUpdatedTicketSystemInstance = new TicketSystemInstance(); + partialUpdatedTicketSystemInstance.setId(ticketSystemInstance.getId()); + + partialUpdatedTicketSystemInstance.type(UPDATED_TYPE).clientSecret(UPDATED_CLIENT_SECRET); + + restTicketSystemInstanceMockMvc + .perform( + patch(ENTITY_API_URL_ID, partialUpdatedTicketSystemInstance.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(partialUpdatedTicketSystemInstance)) + ) + .andExpect(status().isOk()); + + // Validate the TicketSystemInstance in the database + List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); + assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeUpdate); + TicketSystemInstance testTicketSystemInstance = ticketSystemInstanceList.get(ticketSystemInstanceList.size() - 1); + assertThat(testTicketSystemInstance.getName()).isEqualTo(DEFAULT_NAME); + assertThat(testTicketSystemInstance.getType()).isEqualTo(UPDATED_TYPE); + assertThat(testTicketSystemInstance.getUrl()).isEqualTo(DEFAULT_URL); + assertThat(testTicketSystemInstance.getConsumerKey()).isEqualTo(DEFAULT_CONSUMER_KEY); + assertThat(testTicketSystemInstance.getClientId()).isEqualTo(DEFAULT_CLIENT_ID); + assertThat(testTicketSystemInstance.getClientSecret()).isEqualTo(UPDATED_CLIENT_SECRET); + } + + @Test + @Transactional + void fullUpdateTicketSystemInstanceWithPatch() throws Exception { + // Initialize the database + ticketSystemInstanceRepository.saveAndFlush(ticketSystemInstance); + + int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + + // Update the ticketSystemInstance using partial update + TicketSystemInstance partialUpdatedTicketSystemInstance = new TicketSystemInstance(); + partialUpdatedTicketSystemInstance.setId(ticketSystemInstance.getId()); + + partialUpdatedTicketSystemInstance + .name(UPDATED_NAME) + .type(UPDATED_TYPE) + .url(UPDATED_URL) + .consumerKey(UPDATED_CONSUMER_KEY) + .clientId(UPDATED_CLIENT_ID) + .clientSecret(UPDATED_CLIENT_SECRET); + + restTicketSystemInstanceMockMvc + .perform( + patch(ENTITY_API_URL_ID, partialUpdatedTicketSystemInstance.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(partialUpdatedTicketSystemInstance)) + ) + .andExpect(status().isOk()); + + // Validate the TicketSystemInstance in the database + List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); + assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeUpdate); + TicketSystemInstance testTicketSystemInstance = ticketSystemInstanceList.get(ticketSystemInstanceList.size() - 1); + assertThat(testTicketSystemInstance.getName()).isEqualTo(UPDATED_NAME); + assertThat(testTicketSystemInstance.getType()).isEqualTo(UPDATED_TYPE); + assertThat(testTicketSystemInstance.getUrl()).isEqualTo(UPDATED_URL); + assertThat(testTicketSystemInstance.getConsumerKey()).isEqualTo(UPDATED_CONSUMER_KEY); + assertThat(testTicketSystemInstance.getClientId()).isEqualTo(UPDATED_CLIENT_ID); + assertThat(testTicketSystemInstance.getClientSecret()).isEqualTo(UPDATED_CLIENT_SECRET); + } + + @Test + @Transactional + void patchNonExistingTicketSystemInstance() throws Exception { + int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + ticketSystemInstance.setId(count.incrementAndGet()); // If the entity doesn't have an ID, it will throw BadRequestAlertException - restTicketSystemInstanceMockMvc.perform(put("/api/ticket-system-instances") - .contentType(TestUtil.APPLICATION_JSON_UTF8) - .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance))) + restTicketSystemInstanceMockMvc + .perform( + patch(ENTITY_API_URL_ID, ticketSystemInstance.getId()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) + .andExpect(status().isBadRequest()); + + // Validate the TicketSystemInstance in the database + List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); + assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void patchWithIdMismatchTicketSystemInstance() throws Exception { + int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + ticketSystemInstance.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restTicketSystemInstanceMockMvc + .perform( + patch(ENTITY_API_URL_ID, count.incrementAndGet()) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) .andExpect(status().isBadRequest()); // Validate the TicketSystemInstance in the database @@ -277,15 +469,36 @@ public void updateNonExistingTicketSystemInstance() throws Exception { @Test @Transactional - public void deleteTicketSystemInstance() throws Exception { + void patchWithMissingIdPathParamTicketSystemInstance() throws Exception { + int databaseSizeBeforeUpdate = ticketSystemInstanceRepository.findAll().size(); + ticketSystemInstance.setId(count.incrementAndGet()); + + // If url ID doesn't match entity ID, it will throw BadRequestAlertException + restTicketSystemInstanceMockMvc + .perform( + patch(ENTITY_API_URL) + .with(csrf()) + .contentType("application/merge-patch+json") + .content(TestUtil.convertObjectToJsonBytes(ticketSystemInstance)) + ) + .andExpect(status().isMethodNotAllowed()); + + // Validate the TicketSystemInstance in the database + List ticketSystemInstanceList = ticketSystemInstanceRepository.findAll(); + assertThat(ticketSystemInstanceList).hasSize(databaseSizeBeforeUpdate); + } + + @Test + @Transactional + void deleteTicketSystemInstance() throws Exception { // Initialize the database ticketSystemInstanceRepository.saveAndFlush(ticketSystemInstance); int databaseSizeBeforeDelete = ticketSystemInstanceRepository.findAll().size(); // Delete the ticketSystemInstance - restTicketSystemInstanceMockMvc.perform(delete("/api/ticket-system-instances/{id}", ticketSystemInstance.getId()) - .accept(TestUtil.APPLICATION_JSON_UTF8)) + restTicketSystemInstanceMockMvc + .perform(delete(ENTITY_API_URL_ID, ticketSystemInstance.getId()).with(csrf()).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); // Validate the database contains one less item diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/UserResourceIT.java b/src/test/java/org/securityrat/casemanagement/web/rest/UserResourceIT.java index 892e451..187ddc3 100644 --- a/src/test/java/org/securityrat/casemanagement/web/rest/UserResourceIT.java +++ b/src/test/java/org/securityrat/casemanagement/web/rest/UserResourceIT.java @@ -1,50 +1,46 @@ package org.securityrat.casemanagement.web.rest; -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasItems; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.Instant; +import java.util.*; +import java.util.function.Consumer; +import javax.persistence.EntityManager; +import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.securityrat.casemanagement.IntegrationTest; import org.securityrat.casemanagement.domain.Authority; import org.securityrat.casemanagement.domain.User; import org.securityrat.casemanagement.repository.UserRepository; import org.securityrat.casemanagement.security.AuthoritiesConstants; - -import org.securityrat.casemanagement.service.UserService; +import org.securityrat.casemanagement.service.dto.AdminUserDTO; import org.securityrat.casemanagement.service.dto.UserDTO; import org.securityrat.casemanagement.service.mapper.UserMapper; -import org.securityrat.casemanagement.web.rest.errors.ExceptionTranslator; -import org.apache.commons.lang3.RandomStringUtils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityManager; -import java.time.Instant; -import java.util.*; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.hasItems; -import static org.hamcrest.Matchers.hasItem; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - /** * Integration tests for the {@link UserResource} REST controller. */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -public class UserResourceIT { +@AutoConfigureMockMvc +@WithMockUser(authorities = AuthoritiesConstants.ADMIN) +@IntegrationTest +class UserResourceIT { private static final String DEFAULT_LOGIN = "johndoe"; private static final String DEFAULT_ID = "id1"; - private static final String DEFAULT_PASSWORD = "passjohndoe"; - private static final String DEFAULT_EMAIL = "johndoe@localhost"; private static final String DEFAULT_FIRSTNAME = "john"; @@ -56,40 +52,18 @@ public class UserResourceIT { private static final String DEFAULT_LANGKEY = "en"; @Autowired - private UserRepository appUserRepository; - - @Autowired - private UserService userService; + private UserRepository userRepository; @Autowired private UserMapper userMapper; - @Autowired - private MappingJackson2HttpMessageConverter jacksonMessageConverter; - - @Autowired - private PageableHandlerMethodArgumentResolver pageableArgumentResolver; - - @Autowired - private ExceptionTranslator exceptionTranslator; - @Autowired private EntityManager em; + @Autowired private MockMvc restUserMockMvc; - private User appUser; - - @BeforeEach - public void setup() { - UserResource appUserResource = new UserResource(userService); - - this.restUserMockMvc = MockMvcBuilders.standaloneSetup(appUserResource) - .setCustomArgumentResolvers(pageableArgumentResolver) - .setControllerAdvice(exceptionTranslator) - .setMessageConverters(jacksonMessageConverter) - .build(); - } + private User user; /** * Create a User. @@ -98,36 +72,44 @@ public void setup() { * if they test an entity which has a required relationship to the User entity. */ public static User createEntity(EntityManager em) { - User appUser = new User(); - appUser.setId(UUID.randomUUID().toString()); - appUser.setLogin(DEFAULT_LOGIN + RandomStringUtils.randomAlphabetic(5)); - appUser.setActivated(true); - appUser.setEmail(RandomStringUtils.randomAlphabetic(5) + DEFAULT_EMAIL); - appUser.setFirstName(DEFAULT_FIRSTNAME); - appUser.setLastName(DEFAULT_LASTNAME); - appUser.setImageUrl(DEFAULT_IMAGEURL); - appUser.setLangKey(DEFAULT_LANGKEY); - return appUser; + User user = new User(); + user.setId(UUID.randomUUID().toString()); + user.setLogin(DEFAULT_LOGIN + RandomStringUtils.randomAlphabetic(5)); + user.setActivated(true); + user.setEmail(RandomStringUtils.randomAlphabetic(5) + DEFAULT_EMAIL); + user.setFirstName(DEFAULT_FIRSTNAME); + user.setLastName(DEFAULT_LASTNAME); + user.setImageUrl(DEFAULT_IMAGEURL); + user.setLangKey(DEFAULT_LANGKEY); + return user; + } + + /** + * Setups the database with one user. + */ + public static User initTestUser(UserRepository userRepository, EntityManager em) { + User user = createEntity(em); + user.setLogin(DEFAULT_LOGIN); + user.setEmail(DEFAULT_EMAIL); + return user; } @BeforeEach public void initTest() { - appUser = createEntity(em); - appUser.setLogin(DEFAULT_LOGIN); - appUser.setEmail(DEFAULT_EMAIL); + user = initTestUser(userRepository, em); } @Test @Transactional - public void getAllUsers() throws Exception { + void getAllUsers() throws Exception { // Initialize the database - appUserRepository.saveAndFlush(appUser); + userRepository.saveAndFlush(user); // Get all the users - restUserMockMvc.perform(get("/api/users?sort=id,desc") - .accept(MediaType.APPLICATION_JSON)) + restUserMockMvc + .perform(get("/api/admin/users?sort=id,desc").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].login").value(hasItem(DEFAULT_LOGIN))) .andExpect(jsonPath("$.[*].firstName").value(hasItem(DEFAULT_FIRSTNAME))) .andExpect(jsonPath("$.[*].lastName").value(hasItem(DEFAULT_LASTNAME))) @@ -138,48 +120,46 @@ public void getAllUsers() throws Exception { @Test @Transactional - public void getUser() throws Exception { + void getUser() throws Exception { // Initialize the database - appUserRepository.saveAndFlush(appUser); + userRepository.saveAndFlush(user); - // Get the appUser - restUserMockMvc.perform(get("/api/users/{login}", appUser.getLogin())) + // Get the user + restUserMockMvc + .perform(get("/api/admin/users/{login}", user.getLogin())) .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) - .andExpect(jsonPath("$.login").value(appUser.getLogin())) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.login").value(user.getLogin())) .andExpect(jsonPath("$.firstName").value(DEFAULT_FIRSTNAME)) .andExpect(jsonPath("$.lastName").value(DEFAULT_LASTNAME)) .andExpect(jsonPath("$.email").value(DEFAULT_EMAIL)) .andExpect(jsonPath("$.imageUrl").value(DEFAULT_IMAGEURL)) .andExpect(jsonPath("$.langKey").value(DEFAULT_LANGKEY)); - } @Test @Transactional - public void getNonExistingUser() throws Exception { - restUserMockMvc.perform(get("/api/users/unknown")) - .andExpect(status().isNotFound()); + void getNonExistingUser() throws Exception { + restUserMockMvc.perform(get("/api/admin/users/unknown")).andExpect(status().isNotFound()); } @Test - @Transactional - public void testUserEquals() throws Exception { + void testUserEquals() throws Exception { TestUtil.equalsVerifier(User.class); - User appUser1 = new User(); - appUser1.setId("id1"); - User appUser2 = new User(); - appUser2.setId(appUser1.getId()); - assertThat(appUser1).isEqualTo(appUser2); - appUser2.setId("id2"); - assertThat(appUser1).isNotEqualTo(appUser2); - appUser1.setId(null); - assertThat(appUser1).isNotEqualTo(appUser2); + User user1 = new User(); + user1.setId(DEFAULT_ID); + User user2 = new User(); + user2.setId(user1.getId()); + assertThat(user1).isEqualTo(user2); + user2.setId("id2"); + assertThat(user1).isNotEqualTo(user2); + user1.setId(null); + assertThat(user1).isNotEqualTo(user2); } @Test - public void testUserDTOtoUser() { - UserDTO userDTO = new UserDTO(); + void testUserDTOtoUser() { + AdminUserDTO userDTO = new AdminUserDTO(); userDTO.setId(DEFAULT_ID); userDTO.setLogin(DEFAULT_LOGIN); userDTO.setFirstName(DEFAULT_FIRSTNAME); @@ -192,60 +172,58 @@ public void testUserDTOtoUser() { userDTO.setLastModifiedBy(DEFAULT_LOGIN); userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); - User appUser = userMapper.userDTOToUser(userDTO); - assertThat(appUser.getId()).isEqualTo(DEFAULT_ID); - assertThat(appUser.getLogin()).isEqualTo(DEFAULT_LOGIN); - assertThat(appUser.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME); - assertThat(appUser.getLastName()).isEqualTo(DEFAULT_LASTNAME); - assertThat(appUser.getEmail()).isEqualTo(DEFAULT_EMAIL); - assertThat(appUser.getActivated()).isEqualTo(true); - assertThat(appUser.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL); - assertThat(appUser.getLangKey()).isEqualTo(DEFAULT_LANGKEY); - assertThat(appUser.getCreatedBy()).isNull(); - assertThat(appUser.getCreatedDate()).isNotNull(); - assertThat(appUser.getLastModifiedBy()).isNull(); - assertThat(appUser.getLastModifiedDate()).isNotNull(); - assertThat(appUser.getAuthorities()).extracting("name").containsExactly(AuthoritiesConstants.USER); + User user = userMapper.userDTOToUser(userDTO); + assertThat(user.getId()).isEqualTo(DEFAULT_ID); + assertThat(user.getLogin()).isEqualTo(DEFAULT_LOGIN); + assertThat(user.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME); + assertThat(user.getLastName()).isEqualTo(DEFAULT_LASTNAME); + assertThat(user.getEmail()).isEqualTo(DEFAULT_EMAIL); + assertThat(user.isActivated()).isTrue(); + assertThat(user.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL); + assertThat(user.getLangKey()).isEqualTo(DEFAULT_LANGKEY); + assertThat(user.getCreatedBy()).isNull(); + assertThat(user.getCreatedDate()).isNotNull(); + assertThat(user.getLastModifiedBy()).isNull(); + assertThat(user.getLastModifiedDate()).isNotNull(); + assertThat(user.getAuthorities()).extracting("name").containsExactly(AuthoritiesConstants.USER); } @Test - public void testUserToUserDTO() { - appUser.setId(DEFAULT_ID); - appUser.setCreatedBy(DEFAULT_LOGIN); - appUser.setCreatedDate(Instant.now()); - appUser.setLastModifiedBy(DEFAULT_LOGIN); - appUser.setLastModifiedDate(Instant.now()); + void testUserToUserDTO() { + user.setId(DEFAULT_ID); + user.setCreatedBy(DEFAULT_LOGIN); + user.setCreatedDate(Instant.now()); + user.setLastModifiedBy(DEFAULT_LOGIN); + user.setLastModifiedDate(Instant.now()); Set authorities = new HashSet<>(); Authority authority = new Authority(); authority.setName(AuthoritiesConstants.USER); authorities.add(authority); - appUser.setAuthorities(authorities); + user.setAuthorities(authorities); - UserDTO userDTO = userMapper.userToUserDTO(appUser); + AdminUserDTO userDTO = userMapper.userToAdminUserDTO(user); assertThat(userDTO.getId()).isEqualTo(DEFAULT_ID); assertThat(userDTO.getLogin()).isEqualTo(DEFAULT_LOGIN); assertThat(userDTO.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME); assertThat(userDTO.getLastName()).isEqualTo(DEFAULT_LASTNAME); assertThat(userDTO.getEmail()).isEqualTo(DEFAULT_EMAIL); - assertThat(userDTO.isActivated()).isEqualTo(true); + assertThat(userDTO.isActivated()).isTrue(); assertThat(userDTO.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL); assertThat(userDTO.getLangKey()).isEqualTo(DEFAULT_LANGKEY); assertThat(userDTO.getCreatedBy()).isEqualTo(DEFAULT_LOGIN); - assertThat(userDTO.getCreatedDate()).isEqualTo(appUser.getCreatedDate()); + assertThat(userDTO.getCreatedDate()).isEqualTo(user.getCreatedDate()); assertThat(userDTO.getLastModifiedBy()).isEqualTo(DEFAULT_LOGIN); - assertThat(userDTO.getLastModifiedDate()).isEqualTo(appUser.getLastModifiedDate()); + assertThat(userDTO.getLastModifiedDate()).isEqualTo(user.getLastModifiedDate()); assertThat(userDTO.getAuthorities()).containsExactly(AuthoritiesConstants.USER); assertThat(userDTO.toString()).isNotNull(); } @Test - public void testAuthorityEquals() { + void testAuthorityEquals() { Authority authorityA = new Authority(); - assertThat(authorityA).isEqualTo(authorityA); - assertThat(authorityA).isNotEqualTo(null); - assertThat(authorityA).isNotEqualTo(new Object()); - assertThat(authorityA.hashCode()).isEqualTo(0); + assertThat(authorityA).isNotEqualTo(null).isNotEqualTo(new Object()); + assertThat(authorityA.hashCode()).isZero(); assertThat(authorityA.toString()).isNotNull(); Authority authorityB = new Authority(); @@ -258,7 +236,10 @@ public void testAuthorityEquals() { assertThat(authorityA).isNotEqualTo(authorityB); authorityB.setName(AuthoritiesConstants.USER); - assertThat(authorityA).isEqualTo(authorityB); - assertThat(authorityA.hashCode()).isEqualTo(authorityB.hashCode()); + assertThat(authorityA).isEqualTo(authorityB).hasSameHashCodeAs(authorityB); + } + + private void assertPersistedUsers(Consumer> userAssertion) { + userAssertion.accept(userRepository.findAll()); } } diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorIT.java b/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorIT.java index d4bb7b2..0d48b64 100644 --- a/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorIT.java +++ b/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorIT.java @@ -1,85 +1,77 @@ package org.securityrat.casemanagement.web.rest.errors; -import org.securityrat.casemanagement.CaseManagementApp; -import org.securityrat.casemanagement.config.TestSecurityConfiguration; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import org.junit.jupiter.api.Test; +import org.securityrat.casemanagement.IntegrationTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; + /** * Integration tests {@link ExceptionTranslator} controller advice. */ -@SpringBootTest(classes = {CaseManagementApp.class, TestSecurityConfiguration.class}) -public class ExceptionTranslatorIT { - - @Autowired - private ExceptionTranslatorTestController controller; +@WithMockUser +@AutoConfigureMockMvc +@IntegrationTest +class ExceptionTranslatorIT { @Autowired - private ExceptionTranslator exceptionTranslator; - - @Autowired - private MappingJackson2HttpMessageConverter jacksonMessageConverter; - private MockMvc mockMvc; - @BeforeEach - public void setup() { - mockMvc = MockMvcBuilders.standaloneSetup(controller) - .setControllerAdvice(exceptionTranslator) - .setMessageConverters(jacksonMessageConverter) - .build(); - } - @Test - public void testConcurrencyFailure() throws Exception { - mockMvc.perform(get("/test/concurrency-failure")) + void testConcurrencyFailure() throws Exception { + mockMvc + .perform(get("/api/exception-translator-test/concurrency-failure").with(csrf())) .andExpect(status().isConflict()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_CONCURRENCY_FAILURE)); } @Test - public void testMethodArgumentNotValid() throws Exception { - mockMvc.perform(post("/test/method-argument").content("{}").contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isBadRequest()) - .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) - .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_VALIDATION)) - .andExpect(jsonPath("$.fieldErrors.[0].objectName").value("test")) - .andExpect(jsonPath("$.fieldErrors.[0].field").value("test")) - .andExpect(jsonPath("$.fieldErrors.[0].message").value("NotNull")); + void testMethodArgumentNotValid() throws Exception { + mockMvc + .perform( + post("/api/exception-translator-test/method-argument").content("{}").contentType(MediaType.APPLICATION_JSON).with(csrf()) + ) + .andExpect(status().isBadRequest()) + .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) + .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_VALIDATION)) + .andExpect(jsonPath("$.fieldErrors.[0].objectName").value("test")) + .andExpect(jsonPath("$.fieldErrors.[0].field").value("test")) + .andExpect(jsonPath("$.fieldErrors.[0].message").value("must not be null")); } @Test - public void testMissingServletRequestPartException() throws Exception { - mockMvc.perform(get("/test/missing-servlet-request-part")) + void testMissingServletRequestPartException() throws Exception { + mockMvc + .perform(get("/api/exception-translator-test/missing-servlet-request-part").with(csrf())) .andExpect(status().isBadRequest()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.400")); } @Test - public void testMissingServletRequestParameterException() throws Exception { - mockMvc.perform(get("/test/missing-servlet-request-parameter")) + void testMissingServletRequestParameterException() throws Exception { + mockMvc + .perform(get("/api/exception-translator-test/missing-servlet-request-parameter").with(csrf())) .andExpect(status().isBadRequest()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.400")); } @Test - public void testAccessDenied() throws Exception { - mockMvc.perform(get("/test/access-denied")) + void testAccessDenied() throws Exception { + mockMvc + .perform(get("/api/exception-translator-test/access-denied").with(csrf())) .andExpect(status().isForbidden()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.403")) @@ -87,18 +79,20 @@ public void testAccessDenied() throws Exception { } @Test - public void testUnauthorized() throws Exception { - mockMvc.perform(get("/test/unauthorized")) + void testUnauthorized() throws Exception { + mockMvc + .perform(get("/api/exception-translator-test/unauthorized").with(csrf())) .andExpect(status().isUnauthorized()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.401")) - .andExpect(jsonPath("$.path").value("/test/unauthorized")) + .andExpect(jsonPath("$.path").value("/api/exception-translator-test/unauthorized")) .andExpect(jsonPath("$.detail").value("test authentication failed!")); } @Test - public void testMethodNotSupported() throws Exception { - mockMvc.perform(post("/test/access-denied")) + void testMethodNotSupported() throws Exception { + mockMvc + .perform(post("/api/exception-translator-test/access-denied").with(csrf())) .andExpect(status().isMethodNotAllowed()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.405")) @@ -106,8 +100,9 @@ public void testMethodNotSupported() throws Exception { } @Test - public void testExceptionWithResponseStatus() throws Exception { - mockMvc.perform(get("/test/response-status")) + void testExceptionWithResponseStatus() throws Exception { + mockMvc + .perform(get("/api/exception-translator-test/response-status").with(csrf())) .andExpect(status().isBadRequest()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.400")) @@ -115,12 +110,12 @@ public void testExceptionWithResponseStatus() throws Exception { } @Test - public void testInternalServerError() throws Exception { - mockMvc.perform(get("/test/internal-server-error")) + void testInternalServerError() throws Exception { + mockMvc + .perform(get("/api/exception-translator-test/internal-server-error").with(csrf())) .andExpect(status().isInternalServerError()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.500")) .andExpect(jsonPath("$.title").value("Internal Server Error")); } - } diff --git a/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorTestController.java b/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorTestController.java index 13ea32c..7ff9ab1 100644 --- a/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorTestController.java +++ b/src/test/java/org/securityrat/casemanagement/web/rest/errors/ExceptionTranslatorTestController.java @@ -1,50 +1,47 @@ package org.securityrat.casemanagement.web.rest.errors; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.http.HttpStatus; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.web.bind.annotation.*; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - @RestController +@RequestMapping("/api/exception-translator-test") public class ExceptionTranslatorTestController { - @GetMapping("/test/concurrency-failure") + @GetMapping("/concurrency-failure") public void concurrencyFailure() { throw new ConcurrencyFailureException("test concurrency failure"); } - @PostMapping("/test/method-argument") - public void methodArgument(@Valid @RequestBody TestDTO testDTO) { - } + @PostMapping("/method-argument") + public void methodArgument(@Valid @RequestBody TestDTO testDTO) {} - @GetMapping("/test/missing-servlet-request-part") - public void missingServletRequestPartException(@RequestPart String part) { - } + @GetMapping("/missing-servlet-request-part") + public void missingServletRequestPartException(@RequestPart String part) {} - @GetMapping("/test/missing-servlet-request-parameter") - public void missingServletRequestParameterException(@RequestParam String param) { - } + @GetMapping("/missing-servlet-request-parameter") + public void missingServletRequestParameterException(@RequestParam String param) {} - @GetMapping("/test/access-denied") + @GetMapping("/access-denied") public void accessdenied() { throw new AccessDeniedException("test access denied!"); } - @GetMapping("/test/unauthorized") + @GetMapping("/unauthorized") public void unauthorized() { throw new BadCredentialsException("test authentication failed!"); } - @GetMapping("/test/response-status") + @GetMapping("/response-status") public void exceptionWithResponseStatus() { throw new TestResponseStatusException(); } - @GetMapping("/test/internal-server-error") + @GetMapping("/internal-server-error") public void internalServerError() { throw new RuntimeException(); } @@ -65,7 +62,5 @@ public void setTest(String test) { @ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "test response status") @SuppressWarnings("serial") - public static class TestResponseStatusException extends RuntimeException { - } - + public static class TestResponseStatusException extends RuntimeException {} } diff --git a/src/test/resources/config/application-testcontainers.yml b/src/test/resources/config/application-testcontainers.yml new file mode 100644 index 0000000..b4c090b --- /dev/null +++ b/src/test/resources/config/application-testcontainers.yml @@ -0,0 +1,27 @@ +# =================================================================== +# Spring Boot configuration. +# +# This configuration is used for unit/integration tests with testcontainers database containers. +# +# To activate this configuration launch integration tests with the 'testcontainers' profile +# +# More information on database containers: https://www.testcontainers.org/modules/databases/ +# =================================================================== + +spring: + datasource: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver + url: jdbc:tc:mariadb:10.5.9:///caseManagement?TC_MY_CNF=testcontainers/mariadb&useLegacyDatetimeCode=false&serverTimezone=${user.timezone}&TC_TMPFS=/testtmpfs:rw + username: root + password: + hikari: + poolName: Hikari + auto-commit: false + data-source-properties: + cachePrepStmts: true + prepStmtCacheSize: 250 + prepStmtCacheSqlLimit: 2048 + useServerPrepStmts: true + jpa: + database-platform: org.hibernate.dialect.MariaDB103Dialect diff --git a/src/test/resources/config/application.yml b/src/test/resources/config/application.yml index a930a08..81de599 100644 --- a/src/test/resources/config/application.yml +++ b/src/test/resources/config/application.yml @@ -14,21 +14,33 @@ # =================================================================== spring: + profiles: + # Uncomment the following line to enable tests against production database type rather than H2, using Testcontainers + #active: testcontainers application: name: caseManagement + cloud: + consul: + discovery: + enabled: false + instanceId: ${spring.application.name}:${spring.application.instance-id:${random.value}} + config: + enabled: false + enabled: false datasource: type: com.zaxxer.hikari.HikariDataSource - url: jdbc:h2:mem:caseManagement;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + url: jdbc:h2:mem:casemanagement;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE name: username: password: hikari: auto-commit: false + jackson: + serialization: + write-durations-as-timestamps: false jpa: - database-platform: io.github.jhipster.domain.util.FixedH2Dialect - database: H2 + database-platform: tech.jhipster.domain.util.FixedH2Dialect open-in-view: false - show-sql: false hibernate: ddl-auto: none naming: @@ -42,6 +54,7 @@ spring: hibernate.generate_statistics: false hibernate.hbm2ddl.auto: validate hibernate.jdbc.time_zone: UTC + hibernate.query.fail_on_pagination_over_collection_fetch: true liquibase: contexts: test mail: @@ -50,9 +63,6 @@ spring: allow-bean-definition-overriding: true messages: basename: i18n/messages - mvc: - favicon: - enabled: false task: execution: thread-name-prefix: case-management-task- @@ -89,7 +99,7 @@ jhipster: name: 'caseManagementApp' logging: # To test json console appender - use-json-format: true # By default, logs are in Json format + use-json-format: false logstash: enabled: false host: localhost @@ -98,11 +108,6 @@ jhipster: mail: from: test@localhost base-url: http://127.0.0.1:8080 - metrics: - logs: # Reports metrics in the logs - enabled: true - report-frequency: 60 # in seconds - # =================================================================== # Application specific properties # Add your own application properties here, see the ApplicationProperties class diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 111cd1d..b2fad23 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -6,7 +6,7 @@ - + @@ -15,9 +15,12 @@ + + + @@ -38,8 +41,10 @@ + - + + WARN diff --git a/src/test/resources/testcontainers/mariadb/my.cnf b/src/test/resources/testcontainers/mariadb/my.cnf new file mode 100644 index 0000000..194faef --- /dev/null +++ b/src/test/resources/testcontainers/mariadb/my.cnf @@ -0,0 +1,2 @@ +[mysqld] +character-set-server = utf8mb4 diff --git a/travis/scripts/docker_push b/travis/scripts/docker_push deleted file mode 100644 index 277b27a..0000000 --- a/travis/scripts/docker_push +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - -docker push $DOCKER_REPO \ No newline at end of file diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 21aaf3b..0000000 --- a/yarn.lock +++ /dev/null @@ -1,4872 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.6.3": - version "7.7.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.7.tgz#194769ca8d6d7790ec23605af9ee3e42a0aa79cf" - integrity sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA== - dependencies: - regenerator-runtime "^0.13.2" - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@openapitools/openapi-generator-cli@0.0.14-4.0.2": - version "0.0.14-4.0.2" - resolved "https://registry.yarnpkg.com/@openapitools/openapi-generator-cli/-/openapi-generator-cli-0.0.14-4.0.2.tgz#244394f7487a7744a267165828d3d5249842d2a7" - integrity sha512-x4gKaGNgG5Eqt43B4V814Bp0zUBT5h9/K0Tz4oTi5wGy+5sqU5/gElKys0jmM6wvEio2OXJm728BIFuKPuFi5w== - -"@sindresorhus/is@^0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" - integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== - -"@types/concat-stream@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@types/concat-stream/-/concat-stream-1.6.0.tgz#394dbe0bb5fee46b38d896735e8b68ef2390d00d" - integrity sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0= - dependencies: - "@types/node" "*" - -"@types/form-data@0.0.33": - version "0.0.33" - resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" - integrity sha1-yayFsqX9GENbjIXZ7LUObWyJP/g= - dependencies: - "@types/node" "*" - -"@types/node@*": - version "12.12.21" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.21.tgz#aa44a6363291c7037111c47e4661ad210aded23f" - integrity sha512-8sRGhbpU+ck1n0PGAUgVrWrWdjSW2aqNeyC15W88GRsMpSwzv6RJGlLhE7s2RhVSOdyDmxbqlWSeThq4/7xqlA== - -"@types/node@^10.0.3": - version "10.17.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.11.tgz#46ba035fb917b31c948280dbea22ab8838f386a4" - integrity sha512-dNd2pp8qTzzNLAs3O8nH3iU9DG9866KHq9L3ISPB7DOGERZN81nW/5/g/KzMJpCU8jrbCiMRBzV9/sCEdRosig== - -"@types/node@^8.0.0": - version "8.10.59" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.59.tgz#9e34261f30183f9777017a13d185dfac6b899e04" - integrity sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ== - -"@types/qs@^6.2.31": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.0.tgz#2a5fa918786d07d3725726f7f650527e1cfeaffd" - integrity sha512-c4zji5CjWv1tJxIZkz1oUtGcdOlsH3aza28Nqmm+uNDWBRHoMsjooBEN4czZp1V3iXPihE/VRUOBqg+4Xq0W4g== - -aggregate-error@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-1.0.0.tgz#888344dad0220a72e3af50906117f48771925fac" - integrity sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w= - dependencies: - clean-stack "^1.0.0" - indent-string "^3.0.0" - -ajv@^6.5.5: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= - dependencies: - string-width "^2.0.0" - -ansi-cyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" - integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= - dependencies: - ansi-wrap "0.1.0" - -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= - -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-red@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" - integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= - dependencies: - ansi-wrap "0.1.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.0.0, ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-wrap@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= - -ansi@^0.3.0, ansi@~0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/ansi/-/ansi-0.3.1.tgz#0c42d4fb17160d5a9af1e484bace1c66922c1b21" - integrity sha1-DELU+xcWDVqa8eSEus4cZpIsGyE= - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" - integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= - dependencies: - arr-flatten "^1.0.1" - array-slice "^0.2.3" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" - integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - -array-slice@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" - integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.0, array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= - -asap@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async@^2.1.4, async@^2.6.0, async@^2.6.1, async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sdk@2.533.0: - version "2.533.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.533.0.tgz#69298d2e6c646ce5cb5ba2bf414c9e53ec3f7761" - integrity sha512-OSe7C0jnBdgfzedOtK+TgBEwtJaaZovm+Q2fbqIlfhUWg3rhhkt3oLyQ9bRD30/CFaunLhLr/8HAAN+/x+DWAA== - dependencies: - buffer "4.9.1" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.15.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - uuid "3.3.2" - xml2js "0.4.19" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" - integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A== - -axios@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" - integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== - dependencies: - follow-redirects "1.5.10" - is-buffer "^2.0.2" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -bin-version-check@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bin-version-check/-/bin-version-check-3.0.0.tgz#e24ebfa6b63cb0387c5fc174f86e5cc812ca7cc9" - integrity sha1-4k6/prY8sDh8X8F0+G5cyBLKfMk= - dependencies: - bin-version "^2.0.0" - semver "^5.1.0" - semver-truncate "^1.0.0" - -bin-version@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/bin-version/-/bin-version-2.0.0.tgz#2cc95d83b522bdef2e99978e76aeb5491c8114ff" - integrity sha1-LMldg7Uive8umZeOdq61SRyBFP8= - dependencies: - execa "^0.1.1" - find-versions "^2.0.0" - -binaryextensions@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.2.0.tgz#e7c6ba82d4f5f5758c26078fe8eea28881233311" - integrity sha512-bHhs98rj/7i/RZpCSJ3uk55pLXOItjIrh2sRQZSM6OoktScX+LxJzvlU+FELp9j3TdcddTmmYArLSGptCTwjuw== - -boolean@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.0.tgz#fab78d5907dbae6216ab46d32733bb7b76b99e76" - integrity sha512-OElxJ1lUSinuoUnkpOgLmxp0DC4ytEhODEL6QJU0NpxE/mI4rUSh8h1P1Wkvfi3xQEBcxXR2gBIPNYNuaFcAbQ== - -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer@4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-request@^2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" - integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= - dependencies: - clone-response "1.0.2" - get-stream "3.0.0" - http-cache-semantics "3.8.1" - keyv "3.0.0" - lowercase-keys "1.0.0" - normalize-url "2.0.1" - responselike "1.0.2" - -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase-keys@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" - integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= - dependencies: - camelcase "^4.1.0" - map-obj "^2.0.0" - quick-lru "^1.0.0" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - -camelcase@^4.0.0, camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -capture-stack-trace@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== - -caseless@^0.12.0, caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chevrotain@6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/chevrotain/-/chevrotain-6.5.0.tgz#dcbef415516b0af80fd423cc0d96b28d3f11374e" - integrity sha512-BwqQ/AgmKJ8jcMEjaSnfMybnKMgGTrtDKowfTP3pX4jwVy0kNjRsT/AP6h+wC3+3NC+X8X15VWBnTCQlX+wQFg== - dependencies: - regexp-to-ast "0.4.0" - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -clean-stack@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" - integrity sha1-noIVAa6XmYbEax1m0tQy2y/UrjE= - -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= - -cli-cursor@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" - integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= - dependencies: - restore-cursor "^1.0.1" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-list@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/cli-list/-/cli-list-0.2.0.tgz#7e673ee0dd39a611a486476e53f3c6b3941cb582" - integrity sha1-fmc+4N05phGkhkduU/PGs5QctYI= - -cli-spinners@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" - integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ== - -cli-table@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" - integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= - dependencies: - colors "1.0.3" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= - -clone-regexp@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.1.tgz#051805cd33173375d82118fc0918606da39fd60f" - integrity sha512-Fcij9IwRW27XedRIJnSOEupS7RVcXtObJXbcUOX93UCLqqOdRpkvzKywOOSizmEK/Is3S/RHX9dLdfo6R1Q1mw== - dependencies: - is-regexp "^1.0.0" - is-supported-regexp-flag "^1.0.0" - -clone-response@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -clone-stats@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" - integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= - -clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= - -clone@^1.0.0, clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -cloneable-readable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" - integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== - dependencies: - inherits "^2.0.1" - process-nextick-args "^2.0.0" - readable-stream "^2.3.5" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0, color-convert@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@3.0.x: - version "3.0.0" - resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" - integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== - dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" - -colornames@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" - integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y= - -colors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" - integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= - -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -colorspace@1.1.x: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" - integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== - dependencies: - color "3.0.x" - text-hex "1.0.x" - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.4.7, concat-stream@^1.6.0, concat-stream@^1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -conf@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/conf/-/conf-2.2.0.tgz#ee282efafc1450b61e205372041ad7d866802d9a" - integrity sha512-93Kz74FOMo6aWRVpAZsonOdl2I57jKtHrNmxhumehFQw4X8Sk37SohNY11PG7Q8Okta+UnrVaI006WLeyp8/XA== - dependencies: - dot-prop "^4.1.0" - env-paths "^1.0.0" - make-dir "^1.0.0" - pkg-up "^2.0.0" - write-file-atomic "^2.3.0" - -conf@^1.3.1, conf@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/conf/-/conf-1.4.0.tgz#1ea66c9d7a9b601674a5bb9d2b8dc3c726625e67" - integrity sha512-bzlVWS2THbMetHqXKB8ypsXN4DQ/1qopGwNJi1eYbpwesJcd86FBjFciCQX/YwAhp9bM7NVnPFqZ5LpV7gP0Dg== - dependencies: - dot-prop "^4.1.0" - env-paths "^1.0.0" - make-dir "^1.0.0" - pkg-up "^2.0.0" - write-file-atomic "^2.3.0" - -config-chain@^1.1.11: - version "1.1.12" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" - integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -configstore@^3.0.0, configstore@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" - integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-js@^3.4.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.0.tgz#2b854e451de1967d1e29896025cdc13a2518d9ea" - integrity sha512-AHPTNKzyB+YwgDWoSOCaid9PUSEF6781vsfiK8qUz62zRR448/XgK2NtCbpiUGizbep8Lrpt0Du19PpGGZvw3Q== - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= - dependencies: - capture-stack-trace "^1.0.0" - -cross-spawn-async@^2.1.1: - version "2.2.5" - resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc" - integrity sha1-hF/wwINKPe2dFg2sptOQkGuyiMw= - dependencies: - lru-cache "^4.0.0" - which "^1.2.8" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= - dependencies: - array-find-index "^1.0.1" - -dargs@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-6.1.0.tgz#1f3b9b56393ecf8caa7cbfd6c31496ffcfb9b272" - integrity sha512-5dVBvpBLBnPwSsYXqfybFyehMmC/EenKEcf23AhCTgTf48JFBbmJKqoZBsERDnjL0FyiVTYWdFsRfTLHxLyKdQ== - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -dateformat@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== - -debug@=3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -decamelize-keys@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.0.0, decamelize@^1.1.0, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^3.2.0, decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -default-uid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-uid/-/default-uid-1.0.0.tgz#fcefa9df9f5ac40c8916d912dd1fe1146aa3c59e" - integrity sha1-/O+p359axAyJFtkS3R/hFGqjxZ4= - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -detect-conflict@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e" - integrity sha1-CIZXpmqWHAUBnbfEIwiDsca0F24= - -detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== - -diagnostics@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" - integrity sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ== - dependencies: - colorspace "1.1.x" - enabled "1.0.x" - kuler "1.0.x" - -didyoumean@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" - integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= - -diff@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -dir-glob@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" - integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== - dependencies: - arrify "^1.0.1" - path-type "^3.0.0" - -dot-prop@^4.1.0, dot-prop@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== - dependencies: - is-obj "^1.0.0" - -downgrade-root@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/downgrade-root/-/downgrade-root-1.2.2.tgz#531319715b0e81ffcc22eb28478ba27643e12c6c" - integrity sha1-UxMZcVsOgf/MIusoR4uidkPhLGw= - dependencies: - default-uid "^1.0.0" - is-root "^1.0.0" - -drange@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/drange/-/drange-1.1.1.tgz#b2aecec2aab82fcef11dbbd7b9e32b83f8f6c0b8" - integrity sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA== - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -editions@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/editions/-/editions-2.3.0.tgz#47f2d5309340bce93ab5eb6ad755b9e90ff825e4" - integrity sha512-jeXYwHPKbitU1l14dWlsl5Nm+b1Hsm7VX73BsrQ4RVwEcAQQIPFHTZAbVtuIGxZBrpdT2FXd8lbtrNBrzZxIsA== - dependencies: - errlop "^2.0.0" - semver "^6.3.0" - -ejs@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" - integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== - -ejs@^2.5.9: - version "2.7.4" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" - integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== - -enabled@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" - integrity sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M= - dependencies: - env-variable "0.0.x" - -encodeurl@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -env-paths@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" - integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA= - -env-variable@0.0.x: - version "0.0.5" - resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" - integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA== - -errlop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/errlop/-/errlop-2.0.0.tgz#52b97d35da1b0795e2647b5d2d3a46d17776f55a" - integrity sha512-z00WIrQhtOMUnjdTG0O4f6hMG64EVccVDBy2WwgjcF8S4UB1exGYuc2OFwmdQmsJwLQVEIHWHPCz/omXXgAZHw== - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -error@^7.0.2: - version "7.2.1" - resolved "https://registry.yarnpkg.com/error/-/error-7.2.1.tgz#eab21a4689b5f684fc83da84a0e390de82d94894" - integrity sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA== - dependencies: - string-template "~0.2.1" - -es6-error@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -es6-promise@^4.2.5: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -events@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= - -execa@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.1.1.tgz#b09c2a9309bc0ef0501479472db3180f8d4c3edd" - integrity sha1-sJwqkwm8DvBQFHlHLbMYD41MPt0= - dependencies: - cross-spawn-async "^2.1.1" - object-assign "^4.0.1" - strip-eof "^1.0.0" - -execa@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.4.0.tgz#4eb6467a36a095fabb2970ff9d5e3fb7bce6ebc3" - integrity sha1-TrZGejaglfq7KXD/nV4/t7zm68M= - dependencies: - cross-spawn-async "^2.1.1" - is-stream "^1.1.0" - npm-run-path "^1.0.0" - object-assign "^4.0.1" - path-key "^1.0.0" - strip-eof "^1.0.0" - -execa@^0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.6.3.tgz#57b69a594f081759c69e5370f0d17b9cb11658fe" - integrity sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execall@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73" - integrity sha1-c9CQTjlbPKsGWLCNCewlMH8pu3M= - dependencies: - clone-regexp "^1.0.0" - -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extend-shallow@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" - integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= - dependencies: - kind-of "^1.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-1.1.1.tgz#12d7b0db850f7ff7e7081baf4005700060c4600b" - integrity sha1-Etew24UPf/fnCBuvQAVwAGDEYAs= - dependencies: - extend "^3.0.0" - spawn-sync "^1.0.15" - tmp "^0.0.29" - -external-editor@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" - integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -faker@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" - integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8= - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-glob@^2.0.2: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-safe-stringify@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== - -fecha@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" - integrity sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg== - -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -filter-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-versions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-2.0.0.tgz#2ad90d490f6828c1aa40292cf709ac3318210c3c" - integrity sha1-KtkNSQ9oKMGqQCks9wmsMxghDDw= - dependencies: - array-uniq "^1.0.0" - semver-regex "^1.0.0" - -first-chunk-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" - integrity sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA= - dependencies: - readable-stream "^2.0.2" - -follow-redirects@1.5.10: - version "1.5.10" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - dependencies: - debug "=3.1.0" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -foreachasync@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6" - integrity sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@^2.2.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -from2@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-extra@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fullname@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/fullname/-/fullname-3.3.0.tgz#a08747d6921229610b8178b7614fce10cb185f5a" - integrity sha1-oIdH1pISKWELgXi3YU/OEMsYX1o= - dependencies: - execa "^0.6.0" - filter-obj "^1.1.0" - mem "^1.1.0" - p-any "^1.0.0" - p-try "^1.0.0" - passwd-appUser "^2.1.0" - rc "^1.1.6" - -gauge@~1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-1.2.7.tgz#e9cec5483d3d4ee0ef44b60a7d99e4935e136d93" - integrity sha1-6c7FSD09TuDvRLYKfZnkk14TbZM= - dependencies: - ansi "^0.3.0" - has-unicode "^2.0.0" - lodash.pad "^4.1.0" - lodash.padend "^4.1.0" - lodash.padstart "^4.1.0" - -generator-jhipster@6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/generator-jhipster/-/generator-jhipster-6.6.0.tgz#b8fb0b61166687e845911fc91783339014080eea" - integrity sha512-iaP48cv7wlDCr/Y1r3JqsVbElU3rahgQcTt/2nofTLiJYWUA8Q3xmXlqIhhas5ThFuZlkczKsVv6DtKAvaQArg== - dependencies: - aws-sdk "2.533.0" - axios "0.19.0" - chalk "2.4.2" - commander "2.19.0" - conf "2.2.0" - didyoumean "1.2.1" - ejs "2.6.1" - faker "4.1.0" - glob "7.1.3" - gulp-filter "5.1.0" - insight "0.10.1" - jhipster-core "6.0.5" - js-object-pretty-print "0.3.0" - js-yaml "3.13.1" - lodash "4.17.13" - meow "5.0.0" - mkdirp "0.5.1" - ora "3.4.0" - os-locale "3.1.0" - parse-gitignore "1.0.1" - pluralize "7.0.0" - prettier "1.19.1" - progress "2.0.3" - randexp "0.5.3" - semver "5.6.0" - shelljs "0.8.3" - sync-request "6.0.0" - tabtab "2.2.2" - through2 "3.0.1" - uuid "3.3.3" - yeoman-environment "2.3.4" - yeoman-generator "3.2.0" - yo "3.1.0" - -get-port@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= - -get-stream@3.0.0, get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -gh-got@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0" - integrity sha512-F/mS+fsWQMo1zfgG9MD8KWvTWPPzzhuVwY++fhQ5Ggd+0P+CAMHtzMZhNxG+TqGfHDChJKsbh6otfMGqO2AKBw== - dependencies: - got "^7.0.0" - is-plain-obj "^1.1.0" - -github-username@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417" - integrity sha1-y+KABBiDIG2kISrp5LXxacML9Bc= - dependencies: - gh-got "^6.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= - -glob@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-agent@^2.0.0: - version "2.1.7" - resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.1.7.tgz#12d7bc2b07cd862d0fa76b0f1b2c48cd5ffcf150" - integrity sha512-ooK7eqGYZku+LgnbfH/Iv0RJ74XfhrBZDlke1QSzcBt0bw1PmJcnRADPAQuFE+R45pKKDTynAr25SBasY2kvow== - dependencies: - boolean "^3.0.0" - core-js "^3.4.1" - es6-error "^4.1.1" - matcher "^2.0.0" - roarr "^2.14.5" - semver "^6.3.0" - serialize-error "^5.0.0" - -global-dirs@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= - dependencies: - ini "^1.3.4" - -global-tunnel-ng@^2.5.3, global-tunnel-ng@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f" - integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg== - dependencies: - encodeurl "^1.0.2" - lodash "^4.17.10" - npm-conf "^1.1.3" - tunnel "^0.0.6" - -globalthis@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.1.tgz#40116f5d9c071f9e8fb0037654df1ab3a83b7ef9" - integrity sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw== - dependencies: - define-properties "^1.1.3" - -globby@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" - integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== - dependencies: - array-union "^1.0.1" - dir-glob "2.0.0" - fast-glob "^2.0.2" - glob "^7.1.2" - ignore "^3.3.5" - pify "^3.0.0" - slash "^1.0.0" - -got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - -got@^7.0.0, got@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" - integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== - dependencies: - decompress-response "^3.2.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-plain-obj "^1.1.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - isurl "^1.0.0-alpha5" - lowercase-keys "^1.0.0" - p-cancelable "^0.3.0" - p-timeout "^1.1.1" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - url-parse-lax "^1.0.0" - url-to-options "^1.0.1" - -got@^8.3.1, got@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" - integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== - dependencies: - "@sindresorhus/is" "^0.7.0" - cacheable-request "^2.1.1" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - into-stream "^3.1.0" - is-retry-allowed "^1.1.0" - isurl "^1.0.0-alpha5" - lowercase-keys "^1.0.0" - mimic-response "^1.0.0" - p-cancelable "^0.4.0" - p-timeout "^2.0.1" - pify "^3.0.0" - safe-buffer "^5.1.1" - timed-out "^4.0.1" - url-parse-lax "^3.0.0" - url-to-options "^1.0.1" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - -grouped-queue@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c" - integrity sha1-wWfSpTGcWg4JZO9qJbfC34mWyFw= - dependencies: - lodash "^4.17.2" - -gulp-filter@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/gulp-filter/-/gulp-filter-5.1.0.tgz#a05e11affb07cf7dcf41a7de1cb7b63ac3783e73" - integrity sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM= - dependencies: - multimatch "^2.0.0" - plugin-error "^0.1.2" - streamfilter "^1.0.5" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbol-support-x@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" - integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== - -has-to-string-tag-x@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" - integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== - dependencies: - has-symbol-support-x "^1.4.1" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -hosted-git-info@^2.1.4: - version "2.8.5" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" - integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== - -http-basic@^8.1.1: - version "8.1.3" - resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" - integrity sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw== - dependencies: - caseless "^0.12.0" - concat-stream "^1.6.2" - http-response-object "^3.0.1" - parse-cache-control "^1.0.1" - -http-cache-semantics@3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" - integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== - -http-response-object@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" - integrity sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA== - dependencies: - "@types/node" "^10.0.3" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -humanize-string@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/humanize-string/-/humanize-string-1.0.2.tgz#fef0a8bc9b1b857ca4013bbfaea75071736988f6" - integrity sha512-PH5GBkXqFxw5+4eKaKRIkD23y6vRd/IXSl7IldyJxEXpDH9SEIXRORkBtkGni/ae2P7RVOw6Wxypd2tGXhha1w== - dependencies: - decamelize "^1.0.0" - -iconv-lite@^0.4.17, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ieee754@1.1.13, ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -ignore@^3.3.5: - version "3.3.10" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" - integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= - dependencies: - repeating "^2.0.0" - -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.4, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@^1.0.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-1.2.3.tgz#4dec6f32f37ef7bb0b2ed3f1d1a5c3f545074918" - integrity sha1-TexvMvN+97sLLtPx0aXD9UUHSRg= - dependencies: - ansi-escapes "^1.1.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" - cli-width "^2.0.0" - external-editor "^1.1.0" - figures "^1.3.5" - lodash "^4.3.0" - mute-stream "0.0.6" - pinkie-promise "^2.0.0" - run-async "^2.2.0" - rx "^4.1.0" - string-width "^1.0.1" - strip-ansi "^3.0.0" - through "^2.3.6" - -inquirer@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" - integrity sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.1.0" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^5.5.2" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -inquirer@^6.0.0, inquirer@^6.3.1: - version "6.5.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" - integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.12" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.1.0" - through "^2.3.6" - -insight@0.10.1: - version "0.10.1" - resolved "https://registry.yarnpkg.com/insight/-/insight-0.10.1.tgz#a0ecf668484a95d66e9be59644964e719cc83380" - integrity sha512-kLGeYQkh18f8KuC68QKdi0iwUcIaayJVB/STpX7x452/7pAUm1yfG4giJwcxbrTh0zNYtc8kBR+6maLMOzglOQ== - dependencies: - async "^2.1.4" - chalk "^2.3.0" - conf "^1.3.1" - inquirer "^5.0.0" - lodash.debounce "^4.0.8" - os-name "^2.0.1" - request "^2.74.0" - tough-cookie "^2.0.0" - uuid "^3.0.0" - -insight@^0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/insight/-/insight-0.10.3.tgz#e7fa6593fd11323d227154cc8ce5f8bff638bf02" - integrity sha512-YOncxSN6Omh+1Oqxt+OJAvJVMDKw7l6IEG0wT2cTMGxjsTcroOGW4IR926QDzxg/uZHcFZ2cZbckDWdZhc2pZw== - dependencies: - async "^2.6.2" - chalk "^2.4.2" - conf "^1.4.0" - inquirer "^6.3.1" - lodash.debounce "^4.0.8" - os-name "^3.1.0" - request "^2.88.0" - tough-cookie "^3.0.1" - uuid "^3.3.2" - -interpret@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - -into-stream@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" - integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= - dependencies: - from2 "^2.1.1" - p-is-promise "^1.1.0" - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-buffer@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-docker@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-1.1.0.tgz#f04374d4eee5310e9a8e113bf1495411e46176a1" - integrity sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" - integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= - dependencies: - path-is-inside "^1.0.1" - -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= - -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= - -is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - -is-root@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" - integrity sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU= - -is-scoped@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-scoped/-/is-scoped-1.0.0.tgz#449ca98299e713038256289ecb2b540dc437cb30" - integrity sha1-RJypgpnnEwOCViieyytUDcQ3yzA= - dependencies: - scoped-regex "^1.0.0" - -is-stream@^1.0.0, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-supported-regexp-flag@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz#21ee16518d2c1dd3edd3e9a0d57e50207ac364ca" - integrity sha512-3vcJecUUrpgCqc/ca0aWeNu64UGgxcvO60K/Fkr1N6RSvfGCTU60UKN68JDmKokgba0rFFJs12EnzOQa14ubKQ== - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isbinaryfile@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" - integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== - dependencies: - buffer-alloc "^1.2.0" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istextorbinary@^2.2.1: - version "2.6.0" - resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.6.0.tgz#60776315fb0fa3999add276c02c69557b9ca28ab" - integrity sha512-+XRlFseT8B3L9KyjxxLjfXSLMuErKDsd8DBNrsaxoViABMEZlOSCstwmw0qpoFX3+U6yWU1yhLudAe6/lETGGA== - dependencies: - binaryextensions "^2.1.2" - editions "^2.2.0" - textextensions "^2.5.0" - -isurl@^1.0.0-alpha5: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" - integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== - dependencies: - has-to-string-tag-x "^1.2.0" - is-object "^1.0.1" - -jhipster-core@6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/jhipster-core/-/jhipster-core-6.0.5.tgz#a7c34796262d01026e608a5e0c729f6baa1b6364" - integrity sha512-wajVDw31QbqqnVHryqh3EEnmNskKvm7ddGavRx9FcX1Kb+pMIv48y2KbNeYWDyG9HJeZKsrttMWAF7ma+BFTxA== - dependencies: - chevrotain "6.5.0" - fs-extra "8.1.0" - lodash "4.17.15" - winston "3.2.1" - -jmespath@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= - -js-object-pretty-print@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/js-object-pretty-print/-/js-object-pretty-print-0.3.0.tgz#4670e450066ee1eccf35174c7d197f5aa38bcf74" - integrity sha1-RnDkUAZu4ezPNRdMfRl/WqOLz3Q= - -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -keyv@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" - integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== - dependencies: - json-buffer "3.0.0" - -kind-of@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" - integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - -kuler@1.0.x: - version "1.0.1" - resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" - integrity sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ== - dependencies: - colornames "^1.1.1" - -latest-version@^3.0.0, latest-version@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= - dependencies: - package-json "^4.0.0" - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locutus@^2.0.5: - version "2.0.11" - resolved "https://registry.yarnpkg.com/locutus/-/locutus-2.0.11.tgz#83f85109971fd3dd620482a04381916e4a31d4f0" - integrity sha512-C0q1L38lK5q1t+wE0KY21/9szrBHxye6o2z5EJzU+5B79tubNOC+nLAEzTTn1vPUGoUuehKh8kYKqiVUTWRyaQ== - dependencies: - es6-promise "^4.2.5" - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - -lodash.difference@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" - integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= - -lodash.pad@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/lodash.pad/-/lodash.pad-4.5.1.tgz#4330949a833a7c8da22cc20f6a26c4d59debba70" - integrity sha1-QzCUmoM6fI2iLMIPaibE1Z3runA= - -lodash.padend@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" - integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= - -lodash.padstart@^4.1.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padstart/-/lodash.padstart-4.6.1.tgz#d2e3eebff0d9d39ad50f5cbd1b52a7bce6bb611b" - integrity sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs= - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= - -lodash@4.17.13: - version "4.17.13" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" - integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA== - -lodash@4.17.15, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.2, lodash@^4.3.0: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== - -log-symbols@^2.1.0, log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" - -logform@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.1.2.tgz#957155ebeb67a13164069825ce67ddb5bb2dd360" - integrity sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ== - dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" - fecha "^2.3.3" - ms "^2.1.1" - triple-beam "^1.3.0" - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= - -lowercase-keys@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lru-cache@^4.0.0, lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -macos-release@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb" - integrity sha512-mmLbumEYMi5nXReB9js3WGsB8UE6cDBWyIO62Z4DNx6GbRhDxHNjA1MlzSpJ2S2KM1wyiPRA0d19uHWYYvMHjA== - -macos-release@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" - integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== - -make-dir@^1.0.0, make-dir@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - -map-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" - integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -matcher@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-2.1.0.tgz#64e1041c15b993e23b786f93320a7474bf833c28" - integrity sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ== - dependencies: - escape-string-regexp "^2.0.0" - -mem-fs-editor@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-5.1.0.tgz#51972241640be8567680a04f7adaffe5fc603667" - integrity sha512-2Yt2GCYEbcotYbIJagmow4gEtHDqzpq5XN94+yAx/NT5+bGqIjkXnm3KCUQfE6kRfScGp9IZknScoGRKu8L78w== - dependencies: - commondir "^1.0.1" - deep-extend "^0.6.0" - ejs "^2.5.9" - glob "^7.0.3" - globby "^8.0.1" - isbinaryfile "^3.0.2" - mkdirp "^0.5.0" - multimatch "^2.0.0" - rimraf "^2.2.8" - through2 "^2.0.0" - vinyl "^2.0.1" - -mem-fs@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc" - integrity sha1-uK6NLj/Lb10/kWXBLUVRoGXZicw= - dependencies: - through2 "^2.0.0" - vinyl "^1.1.0" - vinyl-file "^2.0.0" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -meow@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" - integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - yargs-parser "^10.0.0" - -meow@^3.0.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -merge2@^1.2.3: - version "1.3.0" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" - integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== - -micromatch@^3.1.10: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -mime-db@1.42.0: - version "1.42.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== - dependencies: - mime-db "1.42.0" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -minimatch@3.0.x, minimatch@^3.0.0, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist-options@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" - integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -multimatch@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" - integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= - dependencies: - array-differ "^1.0.0" - array-union "^1.0.1" - arrify "^1.0.0" - minimatch "^3.0.0" - -mute-stream@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" - integrity sha1-SJYrGeFp/R38JAs/HnMXYnu8R9s= - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-url@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" - integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== - dependencies: - prepend-http "^2.0.0" - query-string "^5.0.1" - sort-keys "^2.0.0" - -npm-conf@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" - integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== - dependencies: - config-chain "^1.1.11" - pify "^3.0.0" - -npm-keyword@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/npm-keyword/-/npm-keyword-5.0.0.tgz#99b85aec29fcb388d2dd351f0013bf5268787e67" - integrity sha1-mbha7Cn8s4jS3TUfABO/Umh4fmc= - dependencies: - got "^7.1.0" - registry-url "^3.0.3" - -npm-run-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-1.0.0.tgz#f5c32bf595fe81ae927daec52e82f8b000ac3c8f" - integrity sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8= - dependencies: - path-key "^1.0.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npmlog@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-2.0.4.tgz#98b52530f2514ca90d09ec5b22c8846722375692" - integrity sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI= - dependencies: - ansi "~0.3.1" - are-we-there-yet "~1.1.2" - gauge "~1.2.5" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-keys@^1.0.12: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -one-time@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" - integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4= - -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" - integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -open@^6.3.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" - integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== - dependencies: - is-wsl "^1.1.0" - -ora@3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" - integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== - dependencies: - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-spinners "^2.0.0" - log-symbols "^2.2.0" - strip-ansi "^5.2.0" - wcwidth "^1.0.1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-name@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/os-name/-/os-name-2.0.1.tgz#b9a386361c17ae3a21736ef0599405c9a8c5dc5e" - integrity sha1-uaOGNhwXrjohc27wWZQFyajF3F4= - dependencies: - macos-release "^1.0.0" - win-release "^1.0.0" - -os-name@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" - integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== - dependencies: - macos-release "^2.2.0" - windows-release "^3.1.0" - -os-shim@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" - integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc= - -os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-any@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-any/-/p-any-1.1.0.tgz#1d03835c7eed1e34b8e539c47b7b60d0d015d4e1" - integrity sha512-Ef0tVa4CZ5pTAmKn+Cg3w8ABBXh+hHO1aV8281dKOoUHfX+3tjG2EaFcC+aZyagg9b4EYGsHEjz21DnEE8Og2g== - dependencies: - p-some "^2.0.0" - -p-cancelable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" - integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== - -p-cancelable@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" - integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" - integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-some@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-some/-/p-some-2.0.1.tgz#65d87c8b154edbcf5221d167778b6d2e150f6f06" - integrity sha1-Zdh8ixVO289SIdFnd4ttLhUPbwY= - dependencies: - aggregate-error "^1.0.0" - -p-timeout@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" - integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= - dependencies: - p-finally "^1.0.0" - -p-timeout@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" - integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== - dependencies: - p-finally "^1.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0, p-try@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -package-json@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-5.0.0.tgz#a7dbe2725edcc7dc9bcee627672275e323882433" - integrity sha512-EeHQFFTlEmLrkIQoxbE9w0FuAWHoc1XpthDqnZ/i9keOt701cteyXwAxQFLpVqVjj3feh2TodkihjLaRUtIgLg== - dependencies: - got "^8.3.1" - registry-auth-token "^3.3.2" - registry-url "^3.1.0" - semver "^5.5.0" - -pad-component@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pad-component/-/pad-component-0.0.1.tgz#ad1f22ce1bf0fdc0d6ddd908af17f351a404b8ac" - integrity sha1-rR8izhvw/cDW3dkIrxfzUaQEuKw= - -parse-cache-control@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" - integrity sha1-juqz5U+laSD+Fro493+iGqzC104= - -parse-gitignore@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-gitignore/-/parse-gitignore-1.0.1.tgz#8b9dc57f17b810d495c5dfa62eb07caffe7758c7" - integrity sha512-UGyowyjtx26n65kdAMWhm6/3uy5uSrpcuH7tt+QEVudiBoVS+eqHxD5kbi9oWVRwj7sCzXqwuM+rUGw7earl6A== - -parse-help@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-help/-/parse-help-1.0.0.tgz#a260363ec71a96c0bad4a2ce0208c14a35dd0349" - integrity sha512-dlOrbBba6Rrw/nrJ+V7/vkGZdiimWJQzMHZZrYsUq03JE8AV3fAv6kOYX7dP/w2h67lIdmRf8ES8mU44xAgE/Q== - dependencies: - execall "^1.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -passwd-appUser@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/passwd-appUser/-/passwd-appUser-2.1.0.tgz#fad9db6ae252f8b088e0c5decd20a7da0c5d9f1e" - integrity sha1-+tnbauJS+LCI4MXezSCn2gxdnx4= - dependencies: - execa "^0.4.0" - pify "^2.3.0" - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-1.0.0.tgz#5d53d578019646c0d68800db4e146e6bdc2ac7af" - integrity sha1-XVPVeAGWRsDWiADbThRua9wqx68= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -plugin-error@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" - integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= - dependencies: - ansi-cyan "^0.1.1" - ansi-red "^0.1.1" - arr-diff "^1.0.1" - arr-union "^2.0.1" - extend-shallow "^1.1.2" - -pluralize@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier@1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -pretty-bytes@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" - integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== - -process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise@^8.0.0: - version "8.0.3" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.3.tgz#f592e099c6cddc000d538ee7283bb190452b0bf6" - integrity sha512-HeRDUL1RJiLhyA0/grn+PTShlBAcLuh/1BJGtrvjwbvRDCTLLMEz9rOGCV+R3vHY4MixIuoMEd9Yq/XvsTPcjw== - dependencies: - asap "~2.0.6" - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.24, psl@^1.1.28: - version "1.6.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" - integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@^6.4.0: - version "6.9.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9" - integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= - -quick-lru@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" - integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= - -randexp@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.5.3.tgz#f31c2de3148b30bdeb84b7c3f59b0ebb9fec3738" - integrity sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w== - dependencies: - drange "^1.0.2" - ret "^0.2.0" - -rc@^1.0.1, rc@^1.1.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-chunk@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-3.2.0.tgz#2984afe78ca9bfbbdb74b19387bf9e86289c16ca" - integrity sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ== - dependencies: - pify "^4.0.1" - with-open-file "^0.1.6" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -"readable-stream@2 || 3", readable-stream@^3.1.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -redent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" - integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= - dependencies: - indent-string "^3.0.0" - strip-indent "^2.0.0" - -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp-to-ast@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/regexp-to-ast/-/regexp-to-ast-0.4.0.tgz#f3dbcb42726cd71902ba50193f63eab5325cd7cb" - integrity sha512-4qf/7IsIKfSNHQXSwial1IFmfM1Cc/whNBQqRwe0V2stPe7KmN1U0tWQiIx6JiirgSrisjE0eECdNf7Tav1Ntw== - -registry-auth-token@^3.0.1, registry-auth-token@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" - integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-url@^3.0.3, registry-url@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= - dependencies: - rc "^1.0.1" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -replace-ext@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" - integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= - -replace-ext@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= - -request@^2.74.0, request@^2.88.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.1.6, resolve@^1.10.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.14.1.tgz#9e018c540fcf0c427d678b9931cbf45e984bcaff" - integrity sha512-fn5Wobh4cxbLzuHaE+nphztHy43/b++4M6SsGFC2gB8uYwf0C8LcarfCz1un7UTW8OFQg9iNjZ4xpcFVGebDPg== - dependencies: - path-parse "^1.0.6" - -responselike@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" - integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= - dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -ret@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.2.2.tgz#b6861782a1f4762dce43402a71eb7a283f44573c" - integrity sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ== - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@^2.2.8, rimraf@^2.6.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -roarr@^2.14.5: - version "2.14.6" - resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.14.6.tgz#cebe8ad7ecbfd15bfa37b02dacf00809dd633912" - integrity sha512-qjbw0BEesKA+3XFBPt+KVe1PC/Z6ShfJ4wPlx2XifqH5h2Lj8/KQT5XJTsy3n1Es5kai+BwKALaECW3F70B1cg== - dependencies: - boolean "^3.0.0" - detect-node "^2.0.4" - globalthis "^1.0.0" - json-stringify-safe "^5.0.1" - semver-compare "^1.0.0" - sprintf-js "^1.1.2" - -root-check@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/root-check/-/root-check-1.0.0.tgz#c52a794bf0db9fad567536e41898f0c9e0a86697" - integrity sha1-xSp5S/Dbn61WdTbkGJjwyeCoZpc= - dependencies: - downgrade-root "^1.0.0" - sudo-block "^1.1.0" - -run-async@^2.0.0, run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - -rx@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" - integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= - -rxjs@^5.5.2: - version "5.5.12" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" - integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== - dependencies: - symbol-observable "1.0.1" - -rxjs@^6.4.0: - version "6.5.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" - integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sax@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= - -sax@>=0.6.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -scoped-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8" - integrity sha1-o0a7Gs1CB65wvXwMfKnlZra63bg= - -semver-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= - -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= - dependencies: - semver "^5.0.3" - -semver-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9" - integrity sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk= - -semver-truncate@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/semver-truncate/-/semver-truncate-1.1.2.tgz#57f41de69707a62709a7e0104ba2117109ea47e8" - integrity sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g= - dependencies: - semver "^5.3.0" - -"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -serialize-error@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-5.0.0.tgz#a7ebbcdb03a5d71a6ed8461ffe0fc1a1afed62ac" - integrity sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA== - dependencies: - type-fest "^0.8.0" - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shelljs@0.8.3, shelljs@^0.8.0: - version "0.8.3" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.3.tgz#a7f3319520ebf09ee81275b2368adb286659b097" - integrity sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= - dependencies: - is-arrayish "^0.3.1" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= - dependencies: - is-plain-obj "^1.0.0" - -sort-on@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/sort-on/-/sort-on-3.0.0.tgz#8094005281bf450e91ac4cb4c4cf00c3d6569c41" - integrity sha512-e2RHeY1iM6dT9od3RoqeJSyz3O7naNFsGy34+EFEcwghjAncuOXC2/Xwq87S4FbypqLVp6PcizYEsGEGsGIDXA== - dependencies: - arrify "^1.0.0" - dot-prop "^4.1.1" - -source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -spawn-sync@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" - integrity sha1-sAeZVX63+wyDdsKdROih6mfldHY= - dependencies: - concat-stream "^1.4.7" - os-shim "^0.1.2" - -spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== - -spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-trace@0.0.x: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -streamfilter@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/streamfilter/-/streamfilter-1.0.7.tgz#ae3e64522aa5a35c061fd17f67620c7653c643c9" - integrity sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ== - dependencies: - readable-stream "^2.0.2" - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= - dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" - -string-template@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" - integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-bom-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca" - integrity sha1-+H217yYT9paKpUWr/h7HKLaoKco= - dependencies: - first-chunk-stream "^2.0.0" - strip-bom "^2.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" - -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -sudo-block@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/sudo-block/-/sudo-block-1.2.0.tgz#cc539bf8191624d4f507d83eeb45b4cea27f3463" - integrity sha1-zFOb+BkWJNT1B9g+60W0zqJ/NGM= - dependencies: - chalk "^1.0.0" - is-docker "^1.0.0" - is-root "^1.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^3.1.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -symbol-observable@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= - -sync-request@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.0.0.tgz#db867eccc4ed31bbcb9fa3732393a3413da582ed" - integrity sha512-jGNIAlCi9iU4X3Dm4oQnNQshDD3h0/1A7r79LyqjbjUnj69sX6mShAXlhRXgImsfVKtTcnra1jfzabdZvp+Lmw== - dependencies: - http-response-object "^3.0.1" - sync-rpc "^1.2.1" - then-request "^6.0.0" - -sync-rpc@^1.2.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7" - integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw== - dependencies: - get-port "^3.1.0" - -tabtab@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tabtab/-/tabtab-2.2.2.tgz#7a047f143b010b4cbd31f857e82961512cbf4e14" - integrity sha1-egR/FDsBC0y9MfhX6ClhUSy/ThQ= - dependencies: - debug "^2.2.0" - inquirer "^1.0.2" - lodash.difference "^4.5.0" - lodash.uniq "^4.5.0" - minimist "^1.2.0" - mkdirp "^0.5.1" - npmlog "^2.0.3" - object-assign "^4.1.0" - -tabtab@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/tabtab/-/tabtab-1.3.2.tgz#bb9c2ca6324f659fde7634c2caf3c096e1187ca7" - integrity sha1-u5wspjJPZZ/edjTCyvPAluEYfKc= - dependencies: - debug "^2.2.0" - inquirer "^1.0.2" - minimist "^1.2.0" - mkdirp "^0.5.1" - npmlog "^2.0.3" - object-assign "^4.1.0" - -taketalk@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/taketalk/-/taketalk-1.0.0.tgz#b4d4f0deed206ae7df775b129ea2ca6de52f26dd" - integrity sha1-tNTw3u0gauffd1sSnqLKbeUvJt0= - dependencies: - get-stdin "^4.0.1" - minimist "^1.1.0" - -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= - dependencies: - execa "^0.7.0" - -text-hex@1.0.x: - version "1.0.0" - resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" - integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -textextensions@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.6.0.tgz#d7e4ab13fe54e32e08873be40d51b74229b00fc4" - integrity sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ== - -then-request@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" - integrity sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA== - dependencies: - "@types/concat-stream" "^1.6.0" - "@types/form-data" "0.0.33" - "@types/node" "^8.0.0" - "@types/qs" "^6.2.31" - caseless "~0.12.0" - concat-stream "^1.6.0" - form-data "^2.2.0" - http-basic "^8.1.1" - http-response-object "^3.0.1" - promise "^8.0.0" - qs "^6.4.0" - -through2@3.0.1, through2@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" - integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== - dependencies: - readable-stream "2 || 3" - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -timed-out@^4.0.0, timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -titleize@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/titleize/-/titleize-1.0.1.tgz#21bc24fcca658eadc6d3bd3c38f2bd173769b4c5" - integrity sha512-rUwGDruKq1gX+FFHbTl5qjI7teVO7eOe+C8IcQ7QT+1BK3eEUXJqbZcBOeaRP4FwSC/C1A5jDoIVta0nIQ9yew== - -tmp@^0.0.29: - version "0.0.29" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0" - integrity sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA= - dependencies: - os-tmpdir "~1.0.1" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -tough-cookie@^2.0.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= - -trim-newlines@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" - integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= - -triple-beam@^1.2.0, triple-beam@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" - integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== - -tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tunnel@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" - integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -twig@^1.10.5: - version "1.14.0" - resolved "https://registry.yarnpkg.com/twig/-/twig-1.14.0.tgz#64b64d4dae3e34c157f356a270d7dfff9ee3aa0c" - integrity sha512-ut1LslUKAeF56TYQglabJaATUqbNuGO3EcXDhUspAdNbxez5VwTk2n8H00V0VfNy9Scet+VGQP8oPxt4v6mykQ== - dependencies: - "@babel/runtime" "^7.6.3" - locutus "^2.0.5" - minimatch "3.0.x" - walk "2.3.x" - -type-fest@^0.8.0: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= - dependencies: - crypto-random-string "^1.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -untildify@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" - integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA== - -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= - -update-notifier@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -url-to-options@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" - integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= - -url@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -appUser-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/appUser-home/-/appUser-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= - dependencies: - os-homedir "^1.0.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -uuid@3.3.3, uuid@^3.0.0, uuid@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vinyl-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a" - integrity sha1-p+v1/779obfRjRQPyweyI++2dRo= - dependencies: - graceful-fs "^4.1.2" - pify "^2.3.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - strip-bom-stream "^2.0.0" - vinyl "^1.1.0" - -vinyl@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" - integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - -vinyl@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" - integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" - -walk@2.3.x: - version "2.3.14" - resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.14.tgz#60ec8631cfd23276ae1e7363ce11d626452e1ef3" - integrity sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg== - dependencies: - foreachasync "^3.0.0" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - -which@^1.2.8, which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== - dependencies: - string-width "^2.1.1" - -win-release@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209" - integrity sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk= - dependencies: - semver "^5.0.1" - -windows-release@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" - integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== - dependencies: - execa "^1.0.0" - -winston-transport@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.3.0.tgz#df68c0c202482c448d9b47313c07304c2d7c2c66" - integrity sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A== - dependencies: - readable-stream "^2.3.6" - triple-beam "^1.2.0" - -winston@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.2.1.tgz#63061377976c73584028be2490a1846055f77f07" - integrity sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw== - dependencies: - async "^2.6.1" - diagnostics "^1.1.1" - is-stream "^1.1.0" - logform "^2.1.1" - one-time "0.0.4" - readable-stream "^3.1.1" - stack-trace "0.0.x" - triple-beam "^1.3.0" - winston-transport "^4.3.0" - -with-open-file@^0.1.6: - version "0.1.7" - resolved "https://registry.yarnpkg.com/with-open-file/-/with-open-file-0.1.7.tgz#e2de8d974e8a8ae6e58886be4fe8e7465b58a729" - integrity sha512-ecJS2/oHtESJ1t3ZfMI3B7KIDKyfN0O16miWxdn30zdh66Yd3LsRFebXZXq6GU4xfxLf6nVxp9kIqElb5fqczA== - dependencies: - p-finally "^1.0.0" - p-try "^2.1.0" - pify "^4.0.1" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^2.0.0, write-file-atomic@^2.3.0: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= - -xml2js@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== - dependencies: - sax ">=0.6.0" - xmlbuilder "~9.0.1" - -xmlbuilder@~9.0.1: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= - -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yargs-parser@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - -yeoman-character@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/yeoman-character/-/yeoman-character-1.1.0.tgz#90d4b5beaf92759086177015b2fdfa2e0684d7c7" - integrity sha1-kNS1vq+SdZCGF3AVsv36LgaE18c= - dependencies: - supports-color "^3.1.2" - -yeoman-doctor@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yeoman-doctor/-/yeoman-doctor-4.0.0.tgz#f063ed0e782a918f419b7258b9b92d54d010abea" - integrity sha512-CP0fwGk5Y+jel+A0AQbyqnIFZRRpkKOeYUibiTSmlgV9PcgNFFVwn86VcUIpDLOqVjF+9v+O9FWQMo+IUcV2mA== - dependencies: - ansi-styles "^3.2.0" - bin-version-check "^3.0.0" - chalk "^2.3.0" - global-agent "^2.0.0" - global-tunnel-ng "^2.5.3" - latest-version "^3.1.0" - log-symbols "^2.1.0" - semver "^5.0.3" - twig "^1.10.5" - appUser-home "^2.0.0" - -yeoman-environment@2.3.4: - version "2.3.4" - resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.3.4.tgz#ae156147a1b85de939366e5438b00cb3eb54c3e9" - integrity sha512-KLxE5ft/74Qj7h3AsQZv8G6MEEHYJwmD5F99nfOVaep3rBzCtbrJKkdqWc7bDV141Nr8UZZsIXmzc3IcCm6E2w== - dependencies: - chalk "^2.4.1" - cross-spawn "^6.0.5" - debug "^3.1.0" - diff "^3.5.0" - escape-string-regexp "^1.0.2" - globby "^8.0.1" - grouped-queue "^0.3.3" - inquirer "^6.0.0" - is-scoped "^1.0.0" - lodash "^4.17.10" - log-symbols "^2.2.0" - mem-fs "^1.1.0" - strip-ansi "^4.0.0" - text-table "^0.2.0" - untildify "^3.0.3" - -yeoman-environment@^2.0.5, yeoman-environment@^2.4.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.7.0.tgz#d1b6679de883ce14a68b869c4b19d55a0d66f477" - integrity sha512-YNzSUWgJVSgnm0qgLON4Gb2nTm+kywBiWjK4MbvosjUP2YJJ30lNhEx7ukyzKRPUlsavd5IsuALtF6QaVrq81A== - dependencies: - chalk "^2.4.1" - cross-spawn "^6.0.5" - debug "^3.1.0" - diff "^3.5.0" - escape-string-regexp "^1.0.2" - globby "^8.0.1" - grouped-queue "^0.3.3" - inquirer "^6.0.0" - is-scoped "^1.0.0" - lodash "^4.17.10" - log-symbols "^2.2.0" - mem-fs "^1.1.0" - strip-ansi "^4.0.0" - text-table "^0.2.0" - untildify "^3.0.3" - -yeoman-generator@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-3.2.0.tgz#02077d2d7ff28fedc1ed7dad7f9967fd7c3604cc" - integrity sha512-iR/qb2je3GdXtSfxgvOXxUW0Cp8+C6LaZaNlK2BAICzFNzwHtM10t/QBwz5Ea9nk6xVDQNj4Q889TjCXGuIv8w== - dependencies: - async "^2.6.0" - chalk "^2.3.0" - cli-table "^0.3.1" - cross-spawn "^6.0.5" - dargs "^6.0.0" - dateformat "^3.0.3" - debug "^4.1.0" - detect-conflict "^1.0.0" - error "^7.0.2" - find-up "^3.0.0" - github-username "^4.0.0" - istextorbinary "^2.2.1" - lodash "^4.17.10" - make-dir "^1.1.0" - mem-fs-editor "^5.0.0" - minimist "^1.2.0" - pretty-bytes "^5.1.0" - read-chunk "^3.0.0" - read-pkg-up "^4.0.0" - rimraf "^2.6.2" - run-async "^2.0.0" - shelljs "^0.8.0" - text-table "^0.2.0" - through2 "^3.0.0" - yeoman-environment "^2.0.5" - -yo@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/yo/-/yo-3.1.0.tgz#b835da951657ed5105ac7a47ba385983dba6bb51" - integrity sha512-boSESRRyvfyns3DfzxF2F0LVV97wSEFbKUi1oC7RwnZTA66KZ7Bo3JjOLe7mM6IjjeI0vEZcr4BbFjrSHh8d0Q== - dependencies: - async "^2.6.1" - chalk "^2.4.1" - cli-list "^0.2.0" - configstore "^3.1.2" - cross-spawn "^6.0.5" - figures "^2.0.0" - fullname "^3.2.0" - global-agent "^2.0.0" - global-tunnel-ng "^2.7.1" - got "^8.3.2" - humanize-string "^1.0.2" - inquirer "^6.0.0" - insight "^0.10.3" - lodash "^4.17.11" - meow "^3.0.0" - npm-keyword "^5.0.0" - open "^6.3.0" - package-json "^5.0.0" - parse-help "^1.0.0" - read-pkg-up "^4.0.0" - root-check "^1.0.0" - sort-on "^3.0.0" - string-length "^2.0.0" - tabtab "^1.3.2" - titleize "^1.0.1" - update-notifier "^2.5.0" - appUser-home "^2.0.0" - yeoman-character "^1.0.0" - yeoman-doctor "^4.0.0" - yeoman-environment "^2.4.0" - yosay "^2.0.2" - -yosay@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/yosay/-/yosay-2.0.2.tgz#a7017e764cd88d64a1ae64812201de5b157adf6d" - integrity sha512-avX6nz2esp7IMXGag4gu6OyQBsMh/SEn+ZybGu3yKPlOTE6z9qJrzG/0X5vCq/e0rPFy0CUYCze0G5hL310ibA== - dependencies: - ansi-regex "^2.0.0" - ansi-styles "^3.0.0" - chalk "^1.0.0" - cli-boxes "^1.0.0" - pad-component "0.0.1" - string-width "^2.0.0" - strip-ansi "^3.0.0" - taketalk "^1.0.0" - wrap-ansi "^2.0.0"