List of commits:
Subject Hash Author Date (UTC)
Initial version of honlap generated by JHipster-6.8.0 fbabb2905b7786b5e91bb5347b816854e35ac3bb hd 2020-03-26 08:59:15
Commit fbabb2905b7786b5e91bb5347b816854e35ac3bb - Initial version of honlap generated by JHipster-6.8.0
Author: hd
Author date (UTC): 2020-03-26 08:59
Committer name: hd
Committer date (UTC): 2020-03-26 08:59
Parent(s):
Signing key:
Tree: bc3d5ba2910c8c630a1b37c5b37028303b8f9ae0
File Lines added Lines deleted
.editorconfig 23 0
.eslintignore 9 0
.eslintrc.json 24 0
.gitattributes 150 0
.gitignore 147 0
.huskyrc 5 0
.jhipster/PieceOfNews.json 81 0
.lintstagedrc.js 3 0
.mvn/wrapper/MavenWrapperDownloader.java 117 0
.mvn/wrapper/maven-wrapper.jar 0 0
.mvn/wrapper/maven-wrapper.properties 2 0
.prettierignore 4 0
.prettierrc 18 0
.yo-rc.json 43 0
README.md 197 0
angular.json 36 0
checkstyle.xml 21 0
jdl/News_1585209808.jdl 37 0
mvnw 310 0
mvnw.cmd 182 0
package-lock.json 21585 0
package.json 139 0
pom.xml 1149 0
postcss.config.js 5 0
proxy.conf.json 7 0
sonar-project.properties 33 0
src/main/docker/app.yml 16 0
src/main/docker/grafana/provisioning/dashboards/JVM.json 3778 0
src/main/docker/grafana/provisioning/dashboards/dashboard.yml 11 0
src/main/docker/grafana/provisioning/datasources/datasource.yml 50 0
src/main/docker/monitoring.yml 26 0
src/main/docker/postgresql.yml 11 0
src/main/docker/prometheus/prometheus.yml 31 0
src/main/docker/sonar.yml 7 0
src/main/java/hu/dns/honlap/ApplicationWebXml.java 20 0
src/main/java/hu/dns/honlap/HonlapApp.java 98 0
src/main/java/hu/dns/honlap/aop/logging/LoggingAspect.java 113 0
src/main/java/hu/dns/honlap/config/ApplicationProperties.java 13 0
src/main/java/hu/dns/honlap/config/AsyncConfiguration.java 47 0
src/main/java/hu/dns/honlap/config/CacheConfiguration.java 57 0
src/main/java/hu/dns/honlap/config/CloudDatabaseConfiguration.java 28 0
src/main/java/hu/dns/honlap/config/Constants.java 17 0
src/main/java/hu/dns/honlap/config/DatabaseConfiguration.java 59 0
src/main/java/hu/dns/honlap/config/DateTimeFormatConfiguration.java 20 0
src/main/java/hu/dns/honlap/config/JacksonConfiguration.java 61 0
src/main/java/hu/dns/honlap/config/LiquibaseConfiguration.java 60 0
src/main/java/hu/dns/honlap/config/LocaleConfiguration.java 27 0
src/main/java/hu/dns/honlap/config/LoggingAspectConfiguration.java 19 0
src/main/java/hu/dns/honlap/config/LoggingConfiguration.java 50 0
src/main/java/hu/dns/honlap/config/SecurityConfiguration.java 100 0
src/main/java/hu/dns/honlap/config/WebConfigurer.java 153 0
src/main/java/hu/dns/honlap/config/audit/AuditEventConverter.java 86 0
src/main/java/hu/dns/honlap/config/audit/package-info.java 4 0
src/main/java/hu/dns/honlap/config/package-info.java 4 0
src/main/java/hu/dns/honlap/domain/AbstractAuditingEntity.java 77 0
src/main/java/hu/dns/honlap/domain/Authority.java 60 0
src/main/java/hu/dns/honlap/domain/PersistentAuditEvent.java 107 0
src/main/java/hu/dns/honlap/domain/PieceOfNews.java 240 0
src/main/java/hu/dns/honlap/domain/User.java 232 0
src/main/java/hu/dns/honlap/domain/package-info.java 4 0
src/main/java/hu/dns/honlap/repository/AuthorityRepository.java 11 0
src/main/java/hu/dns/honlap/repository/CustomAuditEventRepository.java 89 0
src/main/java/hu/dns/honlap/repository/PersistenceAuditEventRepository.java 23 0
src/main/java/hu/dns/honlap/repository/PieceOfNewsRepository.java 14 0
src/main/java/hu/dns/honlap/repository/UserRepository.java 51 0
src/main/java/hu/dns/honlap/repository/package-info.java 4 0
src/main/java/hu/dns/honlap/security/AuthoritiesConstants.java 16 0
src/main/java/hu/dns/honlap/security/DomainUserDetailsService.java 62 0
src/main/java/hu/dns/honlap/security/SecurityUtils.java 85 0
src/main/java/hu/dns/honlap/security/SpringSecurityAuditorAware.java 20 0
src/main/java/hu/dns/honlap/security/UserNotActivatedException.java 19 0
src/main/java/hu/dns/honlap/security/jwt/JWTConfigurer.java 21 0
src/main/java/hu/dns/honlap/security/jwt/JWTFilter.java 48 0
src/main/java/hu/dns/honlap/security/jwt/TokenProvider.java 110 0
src/main/java/hu/dns/honlap/security/package-info.java 4 0
src/main/java/hu/dns/honlap/service/AuditEventService.java 74 0
src/main/java/hu/dns/honlap/service/EmailAlreadyUsedException.java 11 0
src/main/java/hu/dns/honlap/service/InvalidPasswordException.java 11 0
src/main/java/hu/dns/honlap/service/MailService.java 106 0
src/main/java/hu/dns/honlap/service/UserService.java 306 0
src/main/java/hu/dns/honlap/service/UsernameAlreadyUsedException.java 11 0
src/main/java/hu/dns/honlap/service/dto/PasswordChangeDTO.java 35 0
src/main/java/hu/dns/honlap/service/dto/UserDTO.java 196 0
src/main/java/hu/dns/honlap/service/dto/package-info.java 4 0
src/main/java/hu/dns/honlap/service/mapper/UserMapper.java 81 0
src/main/java/hu/dns/honlap/service/mapper/package-info.java 4 0
src/main/java/hu/dns/honlap/service/package-info.java 4 0
src/main/java/hu/dns/honlap/web/rest/AccountResource.java 187 0
src/main/java/hu/dns/honlap/web/rest/AuditResource.java 79 0
src/main/java/hu/dns/honlap/web/rest/ClientForwardController.java 17 0
src/main/java/hu/dns/honlap/web/rest/PieceOfNewsResource.java 128 0
src/main/java/hu/dns/honlap/web/rest/UserJWTController.java 70 0
src/main/java/hu/dns/honlap/web/rest/UserResource.java 189 0
src/main/java/hu/dns/honlap/web/rest/errors/BadRequestAlertException.java 42 0
src/main/java/hu/dns/honlap/web/rest/errors/EmailAlreadyUsedException.java 10 0
src/main/java/hu/dns/honlap/web/rest/errors/ErrorConstants.java 18 0
src/main/java/hu/dns/honlap/web/rest/errors/ExceptionTranslator.java 124 0
src/main/java/hu/dns/honlap/web/rest/errors/FieldErrorVM.java 33 0
src/main/java/hu/dns/honlap/web/rest/errors/InvalidPasswordException.java 13 0
src/main/java/hu/dns/honlap/web/rest/errors/LoginAlreadyUsedException.java 10 0
src/main/java/hu/dns/honlap/web/rest/errors/package-info.java 6 0
src/main/java/hu/dns/honlap/web/rest/package-info.java 4 0
src/main/java/hu/dns/honlap/web/rest/vm/KeyAndPasswordVM.java 27 0
src/main/java/hu/dns/honlap/web/rest/vm/LoginVM.java 52 0
src/main/java/hu/dns/honlap/web/rest/vm/ManagedUserVM.java 34 0
src/main/java/hu/dns/honlap/web/rest/vm/package-info.java 4 0
src/main/jib/entrypoint.sh 4 0
src/main/resources/.h2.server.properties 5 0
src/main/resources/banner.txt 10 0
src/main/resources/config/application-dev.yml 125 0
src/main/resources/config/application-prod.yml 133 0
src/main/resources/config/application-tls.yml 19 0
src/main/resources/config/application.yml 168 0
src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml 159 0
src/main/resources/config/liquibase/changelog/20200326085000_added_entity_PieceOfNews.xml 89 0
src/main/resources/config/liquibase/data/authority.csv 3 0
src/main/resources/config/liquibase/data/user.csv 5 0
src/main/resources/config/liquibase/data/user_authority.csv 6 0
src/main/resources/config/liquibase/fake-data/piece_of_news.csv 11 0
src/main/resources/config/liquibase/master.xml 20 0
src/main/resources/config/tls/keystore.p12 0 0
src/main/resources/i18n/messages.properties 21 0
src/main/resources/i18n/messages_en.properties 21 0
src/main/resources/i18n/messages_hu.properties 21 0
src/main/resources/logback-spring.xml 69 0
src/main/resources/templates/error.html 87 0
src/main/resources/templates/mail/activationEmail.html 25 0
src/main/resources/templates/mail/creationEmail.html 25 0
src/main/resources/templates/mail/passwordResetEmail.html 25 0
src/main/webapp/404.html 61 0
src/main/webapp/WEB-INF/web.xml 13 0
src/main/webapp/app/account/account.module.ts 27 0
src/main/webapp/app/account/account.route.ts 17 0
src/main/webapp/app/account/activate/activate.component.html 16 0
src/main/webapp/app/account/activate/activate.component.ts 28 0
src/main/webapp/app/account/activate/activate.route.ts 12 0
src/main/webapp/app/account/activate/activate.service.ts 16 0
src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html 90 0
src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts 69 0
src/main/webapp/app/account/password-reset/finish/password-reset-finish.route.ts 12 0
src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts 14 0
src/main/webapp/app/account/password-reset/init/password-reset-init.component.html 53 0
src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts 30 0
src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts 12 0
src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts 14 0
src/main/webapp/app/account/password/password-strength-bar.component.ts 85 0
src/main/webapp/app/account/password/password-strength-bar.scss 23 0
src/main/webapp/app/account/password/password.component.html 94 0
src/main/webapp/app/account/password/password.component.ts 45 0
src/main/webapp/app/account/password/password.route.ts 15 0
src/main/webapp/app/account/password/password.service.ts 14 0
src/main/webapp/app/account/register/register.component.html 158 0
src/main/webapp/app/account/register/register.component.ts 76 0
src/main/webapp/app/account/register/register.route.ts 12 0
src/main/webapp/app/account/register/register.service.ts 15 0
src/main/webapp/app/account/settings/settings.component.html 108 0
src/main/webapp/app/account/settings/settings.component.ts 59 0
src/main/webapp/app/account/settings/settings.route.ts 15 0
src/main/webapp/app/admin/admin-routing.module.ts 44 0
src/main/webapp/app/admin/audits/audit-data.model.ts 3 0
src/main/webapp/app/admin/audits/audit.model.ts 5 0
src/main/webapp/app/admin/audits/audits.component.html 67 0
src/main/webapp/app/admin/audits/audits.component.ts 110 0
src/main/webapp/app/admin/audits/audits.module.ts 13 0
src/main/webapp/app/admin/audits/audits.route.ts 16 0
src/main/webapp/app/admin/audits/audits.service.ts 28 0
src/main/webapp/app/admin/configuration/configuration.component.html 50 0
src/main/webapp/app/admin/configuration/configuration.component.ts 32 0
src/main/webapp/app/admin/configuration/configuration.module.ts 13 0
src/main/webapp/app/admin/configuration/configuration.route.ts 11 0
src/main/webapp/app/admin/configuration/configuration.service.ts 68 0
src/main/webapp/app/admin/docs/docs.component.html 2 0
src/main/webapp/app/admin/docs/docs.component.ts 8 0
src/main/webapp/app/admin/docs/docs.module.ts 13 0
src/main/webapp/app/admin/docs/docs.route.ts 11 0
src/main/webapp/app/admin/docs/docs.scss 6 0
src/main/webapp/app/admin/health/health-modal.component.html 36 0
src/main/webapp/app/admin/health/health-modal.component.ts 37 0
src/main/webapp/app/admin/health/health.component.html 38 0
src/main/webapp/app/admin/health/health.component.ts 44 0
src/main/webapp/app/admin/health/health.module.ts 15 0
src/main/webapp/app/admin/health/health.route.ts 11 0
src/main/webapp/app/admin/health/health.service.ts 30 0
src/main/webapp/app/admin/logs/log.model.ts 15 0
src/main/webapp/app/admin/logs/logs.component.html 28 0
src/main/webapp/app/admin/logs/logs.component.ts 34 0
src/main/webapp/app/admin/logs/logs.module.ts 13 0
src/main/webapp/app/admin/logs/logs.route.ts 11 0
src/main/webapp/app/admin/logs/logs.service.ts 19 0
src/main/webapp/app/admin/metrics/metrics.component.html 65 0
src/main/webapp/app/admin/metrics/metrics.component.ts 47 0
src/main/webapp/app/admin/metrics/metrics.module.ts 13 0
src/main/webapp/app/admin/metrics/metrics.route.ts 11 0
src/main/webapp/app/admin/metrics/metrics.service.ts 23 0
src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.html 23 0
src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts 27 0
src/main/webapp/app/admin/user-management/user-management-detail.component.html 58 0
src/main/webapp/app/admin/user-management/user-management-detail.component.ts 18 0
src/main/webapp/app/admin/user-management/user-management-update.component.html 140 0
src/main/webapp/app/admin/user-management/user-management-update.component.ts 98 0
src/main/webapp/app/admin/user-management/user-management.component.html 88 0
src/main/webapp/app/admin/user-management/user-management.component.ts 118 0
src/main/webapp/app/admin/user-management/user-management.module.ts 21 0
src/main/webapp/app/admin/user-management/user-management.route.ts 57 0
src/main/webapp/app/app-routing.module.ts 35 0
src/main/webapp/app/app.constants.ts 8 0
src/main/webapp/app/app.main.ts 16 0
src/main/webapp/app/app.module.ts 31 0
src/main/webapp/app/blocks/config/prod.config.ts 9 0
src/main/webapp/app/blocks/config/uib-pagination.config.ts 13 0
src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts 32 0
src/main/webapp/app/blocks/interceptor/auth.interceptor.ts 27 0
src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.ts 20 0
src/main/webapp/app/blocks/interceptor/notification.interceptor.ts 33 0
src/main/webapp/app/core/auth/account.service.ts 97 0
src/main/webapp/app/core/auth/auth-jwt.service.ts 44 0
src/main/webapp/app/core/auth/csrf.service.ts 11 0
src/main/webapp/app/core/auth/state-storage.service.ts 21 0
src/main/webapp/app/core/auth/user-route-access-service.ts 53 0
src/main/webapp/app/core/core.module.ts 85 0
src/main/webapp/app/core/icons/font-awesome-icons.ts 75 0
src/main/webapp/app/core/language/language.constants.ts 9 0
src/main/webapp/app/core/login/login-modal.service.ts 20 0
src/main/webapp/app/core/login/login.model.ts 3 0
src/main/webapp/app/core/login/login.service.ts 21 0
src/main/webapp/app/core/user/account.model.ts 12 0
src/main/webapp/app/core/user/user.model.ts 33 0
src/main/webapp/app/core/user/user.service.ts 39 0
src/main/webapp/app/entities/entity.module.ts 15 0
src/main/webapp/app/entities/piece-of-news/piece-of-news-delete-dialog.component.html 24 0
src/main/webapp/app/entities/piece-of-news/piece-of-news-delete-dialog.component.ts 30 0
src/main/webapp/app/entities/piece-of-news/piece-of-news-detail.component.html 66 0
src/main/webapp/app/entities/piece-of-news/piece-of-news-detail.component.ts 22 0
src/main/webapp/app/entities/piece-of-news/piece-of-news-update.component.html 140 0
src/main/webapp/app/entities/piece-of-news/piece-of-news-update.component.ts 118 0
src/main/webapp/app/entities/piece-of-news/piece-of-news.component.html 89 0
src/main/webapp/app/entities/piece-of-news/piece-of-news.component.ts 106 0
src/main/webapp/app/entities/piece-of-news/piece-of-news.module.ts 16 0
src/main/webapp/app/entities/piece-of-news/piece-of-news.route.ts 88 0
src/main/webapp/app/entities/piece-of-news/piece-of-news.service.ts 83 0
src/main/webapp/app/home/home.component.html 44 0
src/main/webapp/app/home/home.component.ts 36 0
src/main/webapp/app/home/home.module.ts 12 0
src/main/webapp/app/home/home.route.ts 12 0
src/main/webapp/app/home/home.scss 23 0
src/main/webapp/app/layouts/error/error.component.html 15 0
src/main/webapp/app/layouts/error/error.component.ts 39 0
src/main/webapp/app/layouts/error/error.route.ts 36 0
src/main/webapp/app/layouts/footer/footer.component.html 3 0
src/main/webapp/app/layouts/footer/footer.component.ts 7 0
src/main/webapp/app/layouts/main/main.component.html 13 0
src/main/webapp/app/layouts/main/main.component.ts 60 0
src/main/webapp/app/layouts/navbar/active-menu.directive.ts 27 0
src/main/webapp/app/layouts/navbar/navbar.component.html 158 0
src/main/webapp/app/layouts/navbar/navbar.component.ts 74 0
src/main/webapp/app/layouts/navbar/navbar.route.ts 9 0
src/main/webapp/app/layouts/navbar/navbar.scss 42 0
src/main/webapp/app/layouts/profiles/page-ribbon.component.ts 23 0
src/main/webapp/app/layouts/profiles/page-ribbon.scss 31 0
src/main/webapp/app/layouts/profiles/profile-info.model.ts 15 0
src/main/webapp/app/layouts/profiles/profile.service.ts 43 0
src/main/webapp/app/polyfills.ts 3 0
src/main/webapp/app/shared/alert/alert-error.component.ts 118 0
src/main/webapp/app/shared/alert/alert-error.model.ts 3 0
src/main/webapp/app/shared/alert/alert.component.ts 36 0
src/main/webapp/app/shared/auth/has-any-authority.directive.ts 47 0
src/main/webapp/app/shared/constants/authority.constants.ts 4 0
src/main/webapp/app/shared/constants/error.constants.ts 3 0
src/main/webapp/app/shared/constants/input.constants.ts 2 0
src/main/webapp/app/shared/constants/pagination.constants.ts 1 0
src/main/webapp/app/shared/language/find-language-from-key.pipe.ts 14 0
src/main/webapp/app/shared/login/login.component.html 51 0
src/main/webapp/app/shared/login/login.component.ts 73 0
src/main/webapp/app/shared/model/piece-of-news.model.ts 31 0
src/main/webapp/app/shared/shared-libs.module.ts 22 0
src/main/webapp/app/shared/shared.module.ts 22 0
src/main/webapp/app/shared/util/datepicker-adapter.ts 23 0
src/main/webapp/app/shared/util/request-util.ts 33 0
src/main/webapp/app/vendor.ts 2 0
src/main/webapp/content/css/loading.css 152 0
src/main/webapp/content/images/jhipster_family_member_0.svg 0 0
src/main/webapp/content/images/jhipster_family_member_0_head-192.png 0 0
src/main/webapp/content/images/jhipster_family_member_0_head-256.png 0 0
src/main/webapp/content/images/jhipster_family_member_0_head-384.png 0 0
src/main/webapp/content/images/jhipster_family_member_0_head-512.png 0 0
src/main/webapp/content/images/jhipster_family_member_1.svg 0 0
src/main/webapp/content/images/jhipster_family_member_1_head-192.png 0 0
src/main/webapp/content/images/jhipster_family_member_1_head-256.png 0 0
src/main/webapp/content/images/jhipster_family_member_1_head-384.png 0 0
src/main/webapp/content/images/jhipster_family_member_1_head-512.png 0 0
src/main/webapp/content/images/jhipster_family_member_2.svg 0 0
src/main/webapp/content/images/jhipster_family_member_2_head-192.png 0 0
src/main/webapp/content/images/jhipster_family_member_2_head-256.png 0 0
src/main/webapp/content/images/jhipster_family_member_2_head-384.png 0 0
src/main/webapp/content/images/jhipster_family_member_2_head-512.png 0 0
src/main/webapp/content/images/jhipster_family_member_3.svg 0 0
src/main/webapp/content/images/jhipster_family_member_3_head-192.png 0 0
src/main/webapp/content/images/jhipster_family_member_3_head-256.png 0 0
src/main/webapp/content/images/jhipster_family_member_3_head-384.png 0 0
src/main/webapp/content/images/jhipster_family_member_3_head-512.png 0 0
src/main/webapp/content/images/logo-jhipster.png 0 0
src/main/webapp/content/scss/_bootstrap-variables.scss 45 0
src/main/webapp/content/scss/global.scss 195 0
src/main/webapp/content/scss/vendor.scss 12 0
src/main/webapp/favicon.ico 0 0
src/main/webapp/i18n/en/activate.json 9 0
src/main/webapp/i18n/en/audits.json 28 0
src/main/webapp/i18n/en/configuration.json 10 0
src/main/webapp/i18n/en/error.json 14 0
src/main/webapp/i18n/en/global.json 141 0
src/main/webapp/i18n/en/health.json 29 0
src/main/webapp/i18n/en/home.json 19 0
src/main/webapp/i18n/en/login.json 19 0
src/main/webapp/i18n/en/logs.json 11 0
src/main/webapp/i18n/en/metrics.json 102 0
src/main/webapp/i18n/en/password.json 12 0
src/main/webapp/i18n/en/pieceOfNews.json 31 0
src/main/webapp/i18n/en/register.json 24 0
src/main/webapp/i18n/en/reset.json 26 0
src/main/webapp/i18n/en/sessions.json 15 0
src/main/webapp/i18n/en/settings.json 32 0
src/main/webapp/i18n/en/user-management.json 30 0
src/main/webapp/i18n/hu/activate.json 9 0
src/main/webapp/i18n/hu/audits.json 28 0
src/main/webapp/i18n/hu/configuration.json 10 0
src/main/webapp/i18n/hu/error.json 14 0
src/main/webapp/i18n/hu/global.json 140 0
src/main/webapp/i18n/hu/health.json 29 0
src/main/webapp/i18n/hu/home.json 19 0
src/main/webapp/i18n/hu/login.json 19 0
src/main/webapp/i18n/hu/logs.json 11 0
src/main/webapp/i18n/hu/metrics.json 93 0
src/main/webapp/i18n/hu/password.json 12 0
src/main/webapp/i18n/hu/pieceOfNews.json 31 0
src/main/webapp/i18n/hu/register.json 24 0
src/main/webapp/i18n/hu/reset.json 26 0
src/main/webapp/i18n/hu/sessions.json 15 0
src/main/webapp/i18n/hu/settings.json 32 0
src/main/webapp/i18n/hu/user-management.json 30 0
src/main/webapp/index.html 109 0
src/main/webapp/manifest.webapp 31 0
src/main/webapp/robots.txt 11 0
src/main/webapp/swagger-ui/dist/images/throbber.gif 0 0
src/main/webapp/swagger-ui/index.html 65 0
src/test/features/gitkeep 0 0
src/test/features/user/user.feature 6 0
src/test/java/hu/dns/honlap/ArchTest.java 29 0
src/test/java/hu/dns/honlap/config/NoOpMailConfiguration.java 24 0
src/test/java/hu/dns/honlap/config/WebConfigurerTest.java 165 0
src/test/java/hu/dns/honlap/config/WebConfigurerTestController.java 16 0
src/test/java/hu/dns/honlap/config/timezone/HibernateTimeZoneIT.java 173 0
src/test/java/hu/dns/honlap/cucumber/CucumberContextConfiguration.java 20 0
src/test/java/hu/dns/honlap/cucumber/CucumberIT.java 12 0
src/test/java/hu/dns/honlap/cucumber/stepdefs/StepDefs.java 9 0
src/test/java/hu/dns/honlap/cucumber/stepdefs/UserStepDefs.java 47 0
src/test/java/hu/dns/honlap/domain/PieceOfNewsTest.java 22 0
src/test/java/hu/dns/honlap/repository/CustomAuditEventRepositoryIT.java 158 0
src/test/java/hu/dns/honlap/repository/timezone/DateTimeWrapper.java 132 0
src/test/java/hu/dns/honlap/repository/timezone/DateTimeWrapperRepository.java 12 0
src/test/java/hu/dns/honlap/security/DomainUserDetailsServiceIT.java 125 0
src/test/java/hu/dns/honlap/security/SecurityUtilsUnitTest.java 71 0
src/test/java/hu/dns/honlap/security/jwt/JWTFilterTest.java 115 0
src/test/java/hu/dns/honlap/security/jwt/TokenProviderTest.java 109 0
src/test/java/hu/dns/honlap/service/AuditEventServiceIT.java 73 0
src/test/java/hu/dns/honlap/service/MailServiceIT.java 247 0
src/test/java/hu/dns/honlap/service/UserServiceIT.java 201 0
src/test/java/hu/dns/honlap/service/mapper/UserMapperTest.java 136 0
src/test/java/hu/dns/honlap/web/rest/AccountResourceIT.java 782 0
src/test/java/hu/dns/honlap/web/rest/AuditResourceIT.java 142 0
src/test/java/hu/dns/honlap/web/rest/ClientForwardControllerTest.java 64 0
src/test/java/hu/dns/honlap/web/rest/PieceOfNewsResourceIT.java 393 0
src/test/java/hu/dns/honlap/web/rest/TestUtil.java 157 0
src/test/java/hu/dns/honlap/web/rest/UserJWTControllerIT.java 103 0
src/test/java/hu/dns/honlap/web/rest/UserResourceIT.java 584 0
src/test/java/hu/dns/honlap/web/rest/WithUnauthenticatedMockUser.java 24 0
src/test/java/hu/dns/honlap/web/rest/errors/ExceptionTranslatorIT.java 110 0
src/test/java/hu/dns/honlap/web/rest/errors/ExceptionTranslatorTestController.java 72 0
src/test/javascript/e2e/account/account.spec.ts 121 0
src/test/javascript/e2e/admin/administration.spec.ts 71 0
src/test/javascript/e2e/entities/piece-of-news/piece-of-news.page-object.ts 151 0
src/test/javascript/e2e/entities/piece-of-news/piece-of-news.spec.ts 105 0
src/test/javascript/e2e/page-objects/jhi-page-objects.ts 233 0
src/test/javascript/jest-global-mocks.ts 3 0
src/test/javascript/jest.conf.js 58 0
src/test/javascript/jest.ts 2 0
src/test/javascript/protractor.conf.js 56 0
src/test/javascript/spec/app/account/activate/activate.component.spec.ts 72 0
src/test/javascript/spec/app/account/password-reset/finish/password-reset-finish.component.spec.ts 102 0
src/test/javascript/spec/app/account/password-reset/init/password-reset-init.component.spec.ts 66 0
src/test/javascript/spec/app/account/password/password-strength-bar.component.spec.ts 48 0
src/test/javascript/spec/app/account/password/password.component.spec.ts 102 0
src/test/javascript/spec/app/account/register/register.component.spec.ts 137 0
src/test/javascript/spec/app/account/settings/settings.component.spec.ts 89 0
src/test/javascript/spec/app/admin/audits/audits.component.spec.ts 224 0
src/test/javascript/spec/app/admin/audits/audits.service.spec.ts 70 0
src/test/javascript/spec/app/admin/configuration/configuration.component.spec.ts 68 0
src/test/javascript/spec/app/admin/configuration/configuration.service.spec.ts 81 0
src/test/javascript/spec/app/admin/health/health.component.spec.ts 67 0
src/test/javascript/spec/app/admin/logs/logs.component.spec.ts 85 0
src/test/javascript/spec/app/admin/logs/logs.service.spec.ts 44 0
src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts 54 0
src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts 68 0
src/test/javascript/spec/app/admin/user-management/user-management-delete-dialog.component.spec.ts 56 0
src/test/javascript/spec/app/admin/user-management/user-management-detail.component.spec.ts 62 0
src/test/javascript/spec/app/admin/user-management/user-management-update.component.spec.ts 104 0
src/test/javascript/spec/app/admin/user-management/user-management.component.spec.ts 86 0
src/test/javascript/spec/app/core/user/account.service.spec.ts 214 0
src/test/javascript/spec/app/core/user/user.service.spec.ts 79 0
src/test/javascript/spec/app/entities/piece-of-news/piece-of-news-delete-dialog.component.spec.ts 65 0
src/test/javascript/spec/app/entities/piece-of-news/piece-of-news-detail.component.spec.ts 37 0
src/test/javascript/spec/app/entities/piece-of-news/piece-of-news-update.component.spec.ts 61 0
src/test/javascript/spec/app/entities/piece-of-news/piece-of-news.component.spec.ts 110 0
src/test/javascript/spec/app/entities/piece-of-news/piece-of-news.service.spec.ts 172 0
src/test/javascript/spec/app/layouts/main/main.component.spec.ts 183 0
src/test/javascript/spec/app/shared/alert/alert-error.component.spec.ts 141 0
src/test/javascript/spec/app/shared/login/login.component.spec.ts 116 0
src/test/javascript/spec/helpers/mock-account.service.ts 29 0
src/test/javascript/spec/helpers/mock-active-modal.service.ts 15 0
src/test/javascript/spec/helpers/mock-alert.service.ts 13 0
src/test/javascript/spec/helpers/mock-event-manager.service.ts 13 0
src/test/javascript/spec/helpers/mock-language.service.ts 14 0
src/test/javascript/spec/helpers/mock-login.service.ts 27 0
src/test/javascript/spec/helpers/mock-route.service.ts 43 0
src/test/javascript/spec/helpers/mock-state-storage.service.ts 21 0
src/test/javascript/spec/helpers/spyobject.ts 48 0
src/test/javascript/spec/test.module.ts 61 0
src/test/resources/config/application.yml 117 0
src/test/resources/i18n/messages_en.properties 4 0
src/test/resources/i18n/messages_hu.properties 1 0
src/test/resources/logback.xml 45 0
src/test/resources/templates/mail/testEmail.html 1 0
tsconfig.app.json 4 0
tsconfig.e2e.json 6 0
tsconfig.json 28 0
tslint.json 17 0
webpack/logo-jhipster.png 0 0
webpack/utils.js 39 0
webpack/webpack.common.js 108 0
webpack/webpack.dev.js 120 0
webpack/webpack.prod.js 150 0
File .editorconfig added (mode: 100644) (index 0000000..0439866)
1 # EditorConfig helps developers define and maintain consistent
2 # coding styles between different editors and IDEs
3 # editorconfig.org
4
5 root = true
6
7 [*]
8
9 # We recommend you to keep these unchanged
10 end_of_line = lf
11 charset = utf-8
12 trim_trailing_whitespace = true
13 insert_final_newline = true
14
15 # Change these settings to your own preference
16 indent_style = space
17 indent_size = 4
18
19 [*.{ts,tsx,js,jsx,json,css,scss,yml}]
20 indent_size = 2
21
22 [*.md]
23 trim_trailing_whitespace = false
File .eslintignore added (mode: 100644) (index 0000000..c8d1f55)
1 node_modules/
2 src/main/docker/
3 src/test/javascript/protractor.conf.js
4 src/test/javascript/jest.conf.js
5 webpack/
6 target/
7 build/
8 node/
9 postcss.config.js
File .eslintrc.json added (mode: 100644) (index 0000000..2e22599)
1 {
2 "plugins": ["@typescript-eslint/tslint"],
3 "extends": ["jhipster"],
4 "parserOptions": {
5 "project": "./tsconfig.json"
6 },
7 "rules": {
8 "@typescript-eslint/tslint/config": [
9 "error",
10 {
11 "lintFile": "./tslint.json"
12 }
13 ],
14 "@typescript-eslint/no-unused-vars": [
15 "warn",
16 {
17 "vars": "all",
18 "args": "after-used",
19 "ignoreRestSiblings": false
20 }
21 ],
22 "@typescript-eslint/no-non-null-assertion": "off"
23 }
24 }
File .gitattributes added (mode: 100644) (index 0000000..ca61722)
1 # This file is inspired by https://github.com/alexkaratarakis/gitattributes
2 #
3 # Auto detect text files and perform LF normalization
4 # http://davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/
5 * text=auto
6
7 # The above will handle all files NOT found below
8 # These files are text and should be normalized (Convert crlf => lf)
9
10 *.bat text eol=crlf
11 *.cmd text eol=crlf
12 *.ps1 text eol=crlf
13 *.coffee text
14 *.css text
15 *.cql text
16 *.df text
17 *.ejs text
18 *.html text
19 *.java text
20 *.js text
21 *.json text
22 *.less text
23 *.properties text
24 *.sass text
25 *.scss text
26 *.sh text eol=lf
27 *.sql text
28 *.txt text
29 *.ts text
30 *.xml text
31 *.yaml text
32 *.yml text
33
34 # Documents
35 *.doc diff=astextplain
36 *.DOC diff=astextplain
37 *.docx diff=astextplain
38 *.DOCX diff=astextplain
39 *.dot diff=astextplain
40 *.DOT diff=astextplain
41 *.pdf diff=astextplain
42 *.PDF diff=astextplain
43 *.rtf diff=astextplain
44 *.RTF diff=astextplain
45 *.markdown text
46 *.md text
47 *.adoc text
48 *.textile text
49 *.mustache text
50 *.csv text
51 *.tab text
52 *.tsv text
53 *.txt text
54 AUTHORS text
55 CHANGELOG text
56 CHANGES text
57 CONTRIBUTING text
58 COPYING text
59 copyright text
60 *COPYRIGHT* text
61 INSTALL text
62 license text
63 LICENSE text
64 NEWS text
65 readme text
66 *README* text
67 TODO text
68
69 # Graphics
70 *.png binary
71 *.jpg binary
72 *.jpeg binary
73 *.gif binary
74 *.tif binary
75 *.tiff binary
76 *.ico binary
77 # SVG treated as an asset (binary) by default. If you want to treat it as text,
78 # comment-out the following line and uncomment the line after.
79 *.svg binary
80 #*.svg text
81 *.eps binary
82
83 # These files are binary and should be left untouched
84 # (binary is a macro for -text -diff)
85 *.class binary
86 *.jar binary
87 *.war binary
88
89 ## LINTERS
90 .csslintrc text
91 .eslintrc text
92 .jscsrc text
93 .jshintrc text
94 .jshintignore text
95 .stylelintrc text
96
97 ## CONFIGS
98 *.conf text
99 *.config text
100 .editorconfig text
101 .gitattributes text
102 .gitconfig text
103 .gitignore text
104 .htaccess text
105 *.npmignore text
106
107 ## HEROKU
108 Procfile text
109 .slugignore text
110
111 ## AUDIO
112 *.kar binary
113 *.m4a binary
114 *.mid binary
115 *.midi binary
116 *.mp3 binary
117 *.ogg binary
118 *.ra binary
119
120 ## VIDEO
121 *.3gpp binary
122 *.3gp binary
123 *.as binary
124 *.asf binary
125 *.asx binary
126 *.fla binary
127 *.flv binary
128 *.m4v binary
129 *.mng binary
130 *.mov binary
131 *.mp4 binary
132 *.mpeg binary
133 *.mpg binary
134 *.swc binary
135 *.swf binary
136 *.webm binary
137
138 ## ARCHIVES
139 *.7z binary
140 *.gz binary
141 *.rar binary
142 *.tar binary
143 *.zip binary
144
145 ## FONTS
146 *.ttf binary
147 *.eot binary
148 *.otf binary
149 *.woff binary
150 *.woff2 binary
File .gitignore added (mode: 100644) (index 0000000..3bf145e)
1 ######################
2 # Project Specific
3 ######################
4 /src/main/webapp/content/css/main.css
5 /target/classes/static/**
6 /src/test/javascript/coverage/
7
8 ######################
9 # Node
10 ######################
11 /node/
12 node_tmp/
13 node_modules/
14 npm-debug.log.*
15 /.awcache/*
16 /.cache-loader/*
17
18 ######################
19 # SASS
20 ######################
21 .sass-cache/
22
23 ######################
24 # Eclipse
25 ######################
26 *.pydevproject
27 .project
28 .metadata
29 tmp/
30 tmp/**/*
31 *.tmp
32 *.bak
33 *.swp
34 *~.nib
35 local.properties
36 .classpath
37 .settings/
38 .loadpath
39 .factorypath
40 /src/main/resources/rebel.xml
41
42 # External tool builders
43 .externalToolBuilders/**
44
45 # Locally stored "Eclipse launch configurations"
46 *.launch
47
48 # CDT-specific
49 .cproject
50
51 # PDT-specific
52 .buildpath
53
54 # STS-specific
55 /.sts4-cache/*
56 ######################
57 # Intellij
58 ######################
59 .idea/
60 *.iml
61 *.iws
62 *.ipr
63 *.ids
64 *.orig
65 classes/
66 out/
67
68 ######################
69 # Visual Studio Code
70 ######################
71 .vscode/
72
73 ######################
74 # Maven
75 ######################
76 /log/
77 /target/
78
79 ######################
80 # Gradle
81 ######################
82 .gradle/
83 /build/
84
85 ######################
86 # Package Files
87 ######################
88 *.jar
89 *.war
90 *.ear
91 *.db
92
93 ######################
94 # Windows
95 ######################
96 # Windows image file caches
97 Thumbs.db
98
99 # Folder config file
100 Desktop.ini
101
102 ######################
103 # Mac OSX
104 ######################
105 .DS_Store
106 .svn
107
108 # Thumbnails
109 ._*
110
111 # Files that might appear on external disk
112 .Spotlight-V100
113 .Trashes
114
115 ######################
116 # Directories
117 ######################
118 /bin/
119 /deploy/
120
121 ######################
122 # Logs
123 ######################
124 *.log*
125
126 ######################
127 # Others
128 ######################
129 *.class
130 *.*~
131 *~
132 .merge_file*
133
134 ######################
135 # Gradle Wrapper
136 ######################
137 !gradle/wrapper/gradle-wrapper.jar
138
139 ######################
140 # Maven Wrapper
141 ######################
142 !.mvn/wrapper/maven-wrapper.jar
143
144 ######################
145 # ESLint
146 ######################
147 .eslintcache
File .huskyrc added (mode: 100644) (index 0000000..4d077c8)
1 {
2 "hooks": {
3 "pre-commit": "lint-staged"
4 }
5 }
File .jhipster/PieceOfNews.json added (mode: 100644) (index 0000000..620a6da)
1 {
2 "name": "PieceOfNews",
3 "fields": [
4 {
5 "fieldName": "appId",
6 "fieldType": "Integer",
7 "fieldValidateRules": [
8 "required"
9 ]
10 },
11 {
12 "fieldName": "newsDate",
13 "fieldType": "Instant",
14 "fieldValidateRules": [
15 "required"
16 ]
17 },
18 {
19 "fieldName": "headline",
20 "fieldType": "String",
21 "fieldValidateRules": [
22 "required",
23 "maxlength"
24 ],
25 "fieldValidateRulesMaxlength": "300"
26 },
27 {
28 "fieldName": "content",
29 "fieldType": "String",
30 "fieldValidateRules": [
31 "required",
32 "maxlength"
33 ],
34 "fieldValidateRulesMaxlength": "600"
35 },
36 {
37 "fieldName": "link",
38 "fieldType": "String",
39 "fieldValidateRules": [
40 "required",
41 "maxlength"
42 ],
43 "fieldValidateRulesMaxlength": "600"
44 },
45 {
46 "fieldName": "publishDate",
47 "fieldType": "Instant"
48 },
49 {
50 "fieldName": "createdBy",
51 "fieldType": "String"
52 },
53 {
54 "fieldName": "createdDate",
55 "fieldType": "Instant"
56 },
57 {
58 "fieldName": "lastModifiedBy",
59 "fieldType": "String"
60 },
61 {
62 "fieldName": "lastModifiedDate",
63 "fieldType": "Instant"
64 }
65 ],
66 "relationships": [],
67 "changelogDate": "20200326085000",
68 "javadoc": "Hírek",
69 "entityTableName": "piece_of_news",
70 "dto": "no",
71 "pagination": "pagination",
72 "service": "no",
73 "jpaMetamodelFiltering": false,
74 "fluentMethods": true,
75 "readOnly": false,
76 "embedded": false,
77 "clientRootFolder": "",
78 "applications": [
79 "honlap"
80 ]
81 }
File .lintstagedrc.js added (mode: 100644) (index 0000000..58dedb0)
1 module.exports = {
2 '{,src/**/}*.{md,json,ts,css,scss,yml}': ['prettier --write', 'git add']
3 };
File .mvn/wrapper/MavenWrapperDownloader.java added (mode: 100644) (index 0000000..b901097)
1 /*
2 * Copyright 2007-present the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 import java.net.*;
17 import java.io.*;
18 import java.nio.channels.*;
19 import java.util.Properties;
20
21 public class MavenWrapperDownloader {
22
23 private static final String WRAPPER_VERSION = "0.5.6";
24 /**
25 * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
26 */
27 private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
28 + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
29
30 /**
31 * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
32 * use instead of the default one.
33 */
34 private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
35 ".mvn/wrapper/maven-wrapper.properties";
36
37 /**
38 * Path where the maven-wrapper.jar will be saved to.
39 */
40 private static final String MAVEN_WRAPPER_JAR_PATH =
41 ".mvn/wrapper/maven-wrapper.jar";
42
43 /**
44 * Name of the property which should be used to override the default download url for the wrapper.
45 */
46 private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
47
48 public static void main(String args[]) {
49 System.out.println("- Downloader started");
50 File baseDirectory = new File(args[0]);
51 System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
52
53 // If the maven-wrapper.properties exists, read it and check if it contains a custom
54 // wrapperUrl parameter.
55 File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
56 String url = DEFAULT_DOWNLOAD_URL;
57 if(mavenWrapperPropertyFile.exists()) {
58 FileInputStream mavenWrapperPropertyFileInputStream = null;
59 try {
60 mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
61 Properties mavenWrapperProperties = new Properties();
62 mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
63 url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
64 } catch (IOException e) {
65 System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
66 } finally {
67 try {
68 if(mavenWrapperPropertyFileInputStream != null) {
69 mavenWrapperPropertyFileInputStream.close();
70 }
71 } catch (IOException e) {
72 // Ignore ...
73 }
74 }
75 }
76 System.out.println("- Downloading from: " + url);
77
78 File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
79 if(!outputFile.getParentFile().exists()) {
80 if(!outputFile.getParentFile().mkdirs()) {
81 System.out.println(
82 "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
83 }
84 }
85 System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
86 try {
87 downloadFileFromURL(url, outputFile);
88 System.out.println("Done");
89 System.exit(0);
90 } catch (Throwable e) {
91 System.out.println("- Error downloading");
92 e.printStackTrace();
93 System.exit(1);
94 }
95 }
96
97 private static void downloadFileFromURL(String urlString, File destination) throws Exception {
98 if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
99 String username = System.getenv("MVNW_USERNAME");
100 char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
101 Authenticator.setDefault(new Authenticator() {
102 @Override
103 protected PasswordAuthentication getPasswordAuthentication() {
104 return new PasswordAuthentication(username, password);
105 }
106 });
107 }
108 URL website = new URL(urlString);
109 ReadableByteChannel rbc;
110 rbc = Channels.newChannel(website.openStream());
111 FileOutputStream fos = new FileOutputStream(destination);
112 fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
113 fos.close();
114 rbc.close();
115 }
116
117 }
File .mvn/wrapper/maven-wrapper.jar added (mode: 100644) (index 0000000..2cc7d4a)
File .mvn/wrapper/maven-wrapper.properties added (mode: 100644) (index 0000000..642d572)
1 distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
File .prettierignore added (mode: 100644) (index 0000000..91b1ba3)
1 node_modules
2 target
3 package-lock.json
4 .git
File .prettierrc added (mode: 100644) (index 0000000..f9b9911)
1 # Prettier configuration
2
3 printWidth: 140
4 singleQuote: true
5 tabWidth: 2
6 useTabs: false
7
8 # js and ts rules:
9 arrowParens: avoid
10
11 # jsx and tsx rules:
12 jsxBracketSameLine: false
13
14 # java rules:
15 overrides:
16 - files: "*.java"
17 options:
18 tabWidth: 4
File .yo-rc.json added (mode: 100644) (index 0000000..8e18ebf)
1 {
2 "generator-jhipster": {
3 "authenticationType": "jwt",
4 "cacheProvider": "ehcache",
5 "clientFramework": "angularX",
6 "serverPort": "8080",
7 "serviceDiscoveryType": false,
8 "skipUserManagement": false,
9 "baseName": "honlap",
10 "buildTool": "maven",
11 "databaseType": "sql",
12 "devDatabaseType": "h2Disk",
13 "enableHibernateCache": true,
14 "enableSwaggerCodegen": false,
15 "enableTranslation": true,
16 "jhiPrefix": "auth",
17 "languages": ["hu", "en"],
18 "messageBroker": false,
19 "nativeLanguage": "hu",
20 "prodDatabaseType": "postgresql",
21 "searchEngine": false,
22 "skipClient": false,
23 "testFrameworks": ["protractor", "cucumber"],
24 "websocket": false,
25 "packageName": "hu.dns.honlap",
26 "packageFolder": "hu/dns/honlap",
27 "applicationType": "monolith",
28 "jhipsterVersion": "6.8.0",
29 "creationTimestamp": 1585212540093,
30 "skipServer": false,
31 "clientPackageManager": "npm",
32 "clientTheme": "none",
33 "clientThemeVariant": "",
34 "useSass": true,
35 "jwtSecretKey": "ZmYxOTYwOGZiYTY1OTJiMTQ3MDNhNGJiNTM3ZWMxN2U1ZTVjODdlMDhmZmNkMGRhYTQxY2ZiMGQzM2Q0ZTNmYzc2YjNjMzU5ZmVkZDgzZDc3OTYxZDMzNzdiNzc3MmVkYjA0NDFkOGIxMTI0MjRiNTMzYzRkNzFkMTJiYWE4Y2Y=",
36 "embeddableLaunchScript": false,
37 "entitySuffix": "",
38 "dtoSuffix": "DTO",
39 "otherModules": [],
40 "blueprints": []
41 },
42 "entities": ["PieceOfNews"]
43 }
File README.md added (mode: 100644) (index 0000000..c3393ce)
1 # honlap
2
3 This application was generated using JHipster 6.8.0, you can find documentation and help at [https://www.jhipster.tech/documentation-archive/v6.8.0](https://www.jhipster.tech/documentation-archive/v6.8.0).
4
5 ## Development
6
7 Before you can build this project, you must install and configure the following dependencies on your machine:
8
9 1. [Node.js][]: We use Node to run a development web server and build the project.
10 Depending on your system, you can install Node either from source or as a pre-packaged bundle.
11
12 After installing Node, you should be able to run the following command to install development tools.
13 You will only need to run this command when dependencies change in [package.json](package.json).
14
15 npm install
16
17 We use npm scripts and [Webpack][] as our build system.
18
19 Run the following commands in two separate terminals to create a blissful development experience where your browser
20 auto-refreshes when files change on your hard drive.
21
22 ./mvnw
23 npm start
24
25 Npm is also used to manage CSS and JavaScript dependencies used in this application. You can upgrade dependencies by
26 specifying a newer version in [package.json](package.json). You can also run `npm update` and `npm install` to manage dependencies.
27 Add the `help` flag on any command to see how you can use it. For example, `npm help update`.
28
29 The `npm run` command will list all of the scripts available to run for this project.
30
31 ### PWA Support
32
33 JHipster ships with PWA (Progressive Web App) support, and it's turned off by default. One of the main components of a PWA is a service worker.
34
35 The service worker initialization code is commented out by default. To enable it, uncomment the following code in `src/main/webapp/index.html`:
36
37 ```html
38 <script>
39 if ('serviceWorker' in navigator) {
40 navigator.serviceWorker.register('./service-worker.js').then(function() {
41 console.log('Service Worker Registered');
42 });
43 }
44 </script>
45 ```
46
47 Note: [Workbox](https://developers.google.com/web/tools/workbox/) powers JHipster's service worker. It dynamically generates the `service-worker.js` file.
48
49 ### Managing dependencies
50
51 For example, to add [Leaflet][] library as a runtime dependency of your application, you would run following command:
52
53 npm install --save --save-exact leaflet
54
55 To benefit from TypeScript type definitions from [DefinitelyTyped][] repository in development, you would run following command:
56
57 npm install --save-dev --save-exact @types/leaflet
58
59 Then you would import the JS and CSS files specified in library's installation instructions so that [Webpack][] knows about them:
60 Edit [src/main/webapp/app/vendor.ts](src/main/webapp/app/vendor.ts) file:
61
62 ```
63 import 'leaflet/dist/leaflet.js';
64 ```
65
66 Edit [src/main/webapp/content/scss/vendor.scss](src/main/webapp/content/scss/vendor.scss) file:
67
68 ```
69 @import '~leaflet/dist/leaflet.css';
70 ```
71
72 Note: There are still a few other things remaining to do for Leaflet that we won't detail here.
73
74 For further instructions on how to develop with JHipster, have a look at [Using JHipster in development][].
75
76 ### Using Angular CLI
77
78 You can also use [Angular CLI][] to generate some custom client code.
79
80 For example, the following command:
81
82 ng generate component my-component
83
84 will generate few files:
85
86 create src/main/webapp/app/my-component/my-component.component.html
87 create src/main/webapp/app/my-component/my-component.component.ts
88 update src/main/webapp/app/app.module.ts
89
90 ## Building for production
91
92 ### Packaging as jar
93
94 To build the final jar and optimize the honlap application for production, run:
95
96 ./mvnw -Pprod clean verify
97
98 This will concatenate and minify the client CSS and JavaScript files. It will also modify `index.html` so it references these new files.
99 To ensure everything worked, run:
100
101 java -jar target/*.jar
102
103 Then navigate to [http://localhost:8080](http://localhost:8080) in your browser.
104
105 Refer to [Using JHipster in production][] for more details.
106
107 ### Packaging as war
108
109 To package your application as a war in order to deploy it to an application server, run:
110
111 ./mvnw -Pprod,war clean verify
112
113 ## Testing
114
115 To launch your application's tests, run:
116
117 ./mvnw verify
118
119 ### Client tests
120
121 Unit tests are run by [Jest][] and written with [Jasmine][]. They're located in [src/test/javascript/](src/test/javascript/) and can be run with:
122
123 npm test
124
125 For more information, refer to the [Running tests page][].
126
127 ### Code quality
128
129 Sonar is used to analyse code quality. You can start a local Sonar server (accessible on http://localhost:9001) with:
130
131 ```
132 docker-compose -f src/main/docker/sonar.yml up -d
133 ```
134
135 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.
136
137 Then, run a Sonar analysis:
138
139 ```
140 ./mvnw -Pprod clean verify sonar:sonar
141 ```
142
143 If you need to re-run the Sonar phase, please be sure to specify at least the `initialize` phase since Sonar properties are loaded from the sonar-project.properties file.
144
145 ```
146 ./mvnw initialize sonar:sonar
147 ```
148
149 or
150
151 For more information, refer to the [Code quality page][].
152
153 ## Using Docker to simplify development (optional)
154
155 You can use Docker to improve your JHipster development experience. A number of docker-compose configuration are available in the [src/main/docker](src/main/docker) folder to launch required third party services.
156
157 For example, to start a postgresql database in a docker container, run:
158
159 docker-compose -f src/main/docker/postgresql.yml up -d
160
161 To stop it and remove the container, run:
162
163 docker-compose -f src/main/docker/postgresql.yml down
164
165 You can also fully dockerize your application and all the services that it depends on.
166 To achieve this, first build a docker image of your app by running:
167
168 ./mvnw -Pprod verify jib:dockerBuild
169
170 Then run:
171
172 docker-compose -f src/main/docker/app.yml up -d
173
174 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.
175
176 ## Continuous Integration (optional)
177
178 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.
179
180 [jhipster homepage and latest documentation]: https://www.jhipster.tech
181 [jhipster 6.8.0 archive]: https://www.jhipster.tech/documentation-archive/v6.8.0
182 [using jhipster in development]: https://www.jhipster.tech/documentation-archive/v6.8.0/development/
183 [using docker and docker-compose]: https://www.jhipster.tech/documentation-archive/v6.8.0/docker-compose
184 [using jhipster in production]: https://www.jhipster.tech/documentation-archive/v6.8.0/production/
185 [running tests page]: https://www.jhipster.tech/documentation-archive/v6.8.0/running-tests/
186 [code quality page]: https://www.jhipster.tech/documentation-archive/v6.8.0/code-quality/
187 [setting up continuous integration]: https://www.jhipster.tech/documentation-archive/v6.8.0/setting-up-ci/
188 [node.js]: https://nodejs.org/
189 [yarn]: https://yarnpkg.org/
190 [webpack]: https://webpack.github.io/
191 [angular cli]: https://cli.angular.io/
192 [browsersync]: https://www.browsersync.io/
193 [jest]: https://facebook.github.io/jest/
194 [jasmine]: https://jasmine.github.io/2.0/introduction.html
195 [protractor]: https://angular.github.io/protractor/
196 [leaflet]: https://leafletjs.com/
197 [definitelytyped]: https://definitelytyped.org/
File angular.json added (mode: 100644) (index 0000000..ebe0f65)
1 {
2 "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 "version": 1,
4 "newProjectRoot": "projects",
5 "projects": {
6 "honlap": {
7 "root": "",
8 "sourceRoot": "src/main/webapp",
9 "projectType": "application",
10 "schematics": {
11 "@schematics/angular:component": {
12 "skipTests": true,
13 "style": "scss"
14 },
15 "@schematics/angular:directive": {
16 "skipTests": true
17 },
18 "@schematics/angular:guard": {
19 "skipTests": true
20 },
21 "@schematics/angular:pipe": {
22 "skipTests": true
23 },
24 "@schematics/angular:service": {
25 "skipTests": true
26 }
27 },
28 "prefix": "auth",
29 "architect": {}
30 }
31 },
32 "defaultProject": "honlap",
33 "cli": {
34 "packageManager": "npm"
35 }
36 }
File checkstyle.xml added (mode: 100644) (index 0000000..6e3dbaf)
1 <?xml version="1.0"?>
2 <!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
3 "https://www.puppycrawl.com/dtds/configuration_1_3.dtd">
4 <module name="Checker">
5
6 <!-- Configure checker to use UTF-8 encoding -->
7 <property name="charset" value="UTF-8"/>
8 <!-- Configure checker to run on files with these extensions -->
9 <property name="fileExtensions" value=""/>
10 <!-- For detailed checkstyle configuration, see https://github.com/spring-io/nohttp/tree/master/nohttp-checkstyle -->
11 <module name="io.spring.nohttp.checkstyle.check.NoHttpCheck">
12 <property name="whitelist" value="http://maven.apache.org/POM/4.0.0&#10;
13 http://www.w3.org/2001/XMLSchema-instance&#10;http://maven.apache.org/maven-v4_0_0.xsd"/>
14 </module>
15 <!-- Allow suppression with comments
16 // CHECKSTYLE:OFF
17 ... ignored content ...
18 // CHECKSTYLE:ON
19 -->
20 <module name="SuppressWithPlainTextCommentFilter"/>
21 </module>
File jdl/News_1585209808.jdl added (mode: 100644) (index 0000000..150e5c5)
1 /**
2 * The application configuration.
3 */
4 application {
5 config {
6 baseName honlap,
7 jhiPrefix auth,
8 packageName hu.dns.honlap,
9 applicationType monolith,
10 buildTool maven,
11 prodDatabaseType postgresql,
12 testFrameworks [protractor,cucumber]
13 nativeLanguage hu,
14 languages [hu, en]
15 }
16 entities *
17 }
18
19
20 /**
21 * Hírek
22 */
23 entity PieceOfNews {
24 appId Integer required,
25 newsDate Instant required,
26 headline String required maxlength(300),
27 content String required maxlength(600),
28 link String required maxlength(600),
29 publishDate Instant,
30 createdBy String,
31 createdDate Instant,
32 lastModifiedBy String,
33 lastModifiedDate Instant
34 }
35
36
37 paginate PieceOfNews with pagination
File mvnw added (mode: 100644) (index 0000000..41c0f0c)
1 #!/bin/sh
2 # ----------------------------------------------------------------------------
3 # Licensed to the Apache Software Foundation (ASF) under one
4 # or more contributor license agreements. See the NOTICE file
5 # distributed with this work for additional information
6 # regarding copyright ownership. The ASF licenses this file
7 # to you under the Apache License, Version 2.0 (the
8 # "License"); you may not use this file except in compliance
9 # with the License. You may obtain a copy of the License at
10 #
11 # http://www.apache.org/licenses/LICENSE-2.0
12 #
13 # Unless required by applicable law or agreed to in writing,
14 # software distributed under the License is distributed on an
15 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 # KIND, either express or implied. See the License for the
17 # specific language governing permissions and limitations
18 # under the License.
19 # ----------------------------------------------------------------------------
20
21 # ----------------------------------------------------------------------------
22 # Maven Start Up Batch script
23 #
24 # Required ENV vars:
25 # ------------------
26 # JAVA_HOME - location of a JDK home dir
27 #
28 # Optional ENV vars
29 # -----------------
30 # M2_HOME - location of maven2's installed home dir
31 # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 # e.g. to debug Maven itself, use
33 # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 # ----------------------------------------------------------------------------
36
37 if [ -z "$MAVEN_SKIP_RC" ] ; then
38
39 if [ -f /etc/mavenrc ] ; then
40 . /etc/mavenrc
41 fi
42
43 if [ -f "$HOME/.mavenrc" ] ; then
44 . "$HOME/.mavenrc"
45 fi
46
47 fi
48
49 # OS specific support. $var _must_ be set to either true or false.
50 cygwin=false;
51 darwin=false;
52 mingw=false
53 case "`uname`" in
54 CYGWIN*) cygwin=true ;;
55 MINGW*) mingw=true;;
56 Darwin*) darwin=true
57 # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 if [ -z "$JAVA_HOME" ]; then
60 if [ -x "/usr/libexec/java_home" ]; then
61 export JAVA_HOME="`/usr/libexec/java_home`"
62 else
63 export JAVA_HOME="/Library/Java/Home"
64 fi
65 fi
66 ;;
67 esac
68
69 if [ -z "$JAVA_HOME" ] ; then
70 if [ -r /etc/gentoo-release ] ; then
71 JAVA_HOME=`java-config --jre-home`
72 fi
73 fi
74
75 if [ -z "$M2_HOME" ] ; then
76 ## resolve links - $0 may be a link to maven's home
77 PRG="$0"
78
79 # need this for relative symlinks
80 while [ -h "$PRG" ] ; do
81 ls=`ls -ld "$PRG"`
82 link=`expr "$ls" : '.*-> \(.*\)$'`
83 if expr "$link" : '/.*' > /dev/null; then
84 PRG="$link"
85 else
86 PRG="`dirname "$PRG"`/$link"
87 fi
88 done
89
90 saveddir=`pwd`
91
92 M2_HOME=`dirname "$PRG"`/..
93
94 # make it fully qualified
95 M2_HOME=`cd "$M2_HOME" && pwd`
96
97 cd "$saveddir"
98 # echo Using m2 at $M2_HOME
99 fi
100
101 # For Cygwin, ensure paths are in UNIX format before anything is touched
102 if $cygwin ; then
103 [ -n "$M2_HOME" ] &&
104 M2_HOME=`cygpath --unix "$M2_HOME"`
105 [ -n "$JAVA_HOME" ] &&
106 JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 [ -n "$CLASSPATH" ] &&
108 CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 fi
110
111 # For Mingw, ensure paths are in UNIX format before anything is touched
112 if $mingw ; then
113 [ -n "$M2_HOME" ] &&
114 M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 [ -n "$JAVA_HOME" ] &&
116 JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 fi
118
119 if [ -z "$JAVA_HOME" ]; then
120 javaExecutable="`which javac`"
121 if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
122 # readlink(1) is not available as standard on Solaris 10.
123 readLink=`which readlink`
124 if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
125 if $darwin ; then
126 javaHome="`dirname \"$javaExecutable\"`"
127 javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
128 else
129 javaExecutable="`readlink -f \"$javaExecutable\"`"
130 fi
131 javaHome="`dirname \"$javaExecutable\"`"
132 javaHome=`expr "$javaHome" : '\(.*\)/bin'`
133 JAVA_HOME="$javaHome"
134 export JAVA_HOME
135 fi
136 fi
137 fi
138
139 if [ -z "$JAVACMD" ] ; then
140 if [ -n "$JAVA_HOME" ] ; then
141 if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
142 # IBM's JDK on AIX uses strange locations for the executables
143 JAVACMD="$JAVA_HOME/jre/sh/java"
144 else
145 JAVACMD="$JAVA_HOME/bin/java"
146 fi
147 else
148 JAVACMD="`which java`"
149 fi
150 fi
151
152 if [ ! -x "$JAVACMD" ] ; then
153 echo "Error: JAVA_HOME is not defined correctly." >&2
154 echo " We cannot execute $JAVACMD" >&2
155 exit 1
156 fi
157
158 if [ -z "$JAVA_HOME" ] ; then
159 echo "Warning: JAVA_HOME environment variable is not set."
160 fi
161
162 CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
163
164 # traverses directory structure from process work directory to filesystem root
165 # first directory with .mvn subdirectory is considered project base directory
166 find_maven_basedir() {
167
168 if [ -z "$1" ]
169 then
170 echo "Path not specified to find_maven_basedir"
171 return 1
172 fi
173
174 basedir="$1"
175 wdir="$1"
176 while [ "$wdir" != '/' ] ; do
177 if [ -d "$wdir"/.mvn ] ; then
178 basedir=$wdir
179 break
180 fi
181 # workaround for JBEAP-8937 (on Solaris 10/Sparc)
182 if [ -d "${wdir}" ]; then
183 wdir=`cd "$wdir/.."; pwd`
184 fi
185 # end of workaround
186 done
187 echo "${basedir}"
188 }
189
190 # concatenates all lines of a file
191 concat_lines() {
192 if [ -f "$1" ]; then
193 echo "$(tr -s '\n' ' ' < "$1")"
194 fi
195 }
196
197 BASE_DIR=`find_maven_basedir "$(pwd)"`
198 if [ -z "$BASE_DIR" ]; then
199 exit 1;
200 fi
201
202 ##########################################################################################
203 # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
204 # This allows using the maven wrapper in projects that prohibit checking in binary data.
205 ##########################################################################################
206 if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
207 if [ "$MVNW_VERBOSE" = true ]; then
208 echo "Found .mvn/wrapper/maven-wrapper.jar"
209 fi
210 else
211 if [ "$MVNW_VERBOSE" = true ]; then
212 echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
213 fi
214 if [ -n "$MVNW_REPOURL" ]; then
215 jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
216 else
217 jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
218 fi
219 while IFS="=" read key value; do
220 case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
221 esac
222 done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
223 if [ "$MVNW_VERBOSE" = true ]; then
224 echo "Downloading from: $jarUrl"
225 fi
226 wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
227 if $cygwin; then
228 wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
229 fi
230
231 if command -v wget > /dev/null; then
232 if [ "$MVNW_VERBOSE" = true ]; then
233 echo "Found wget ... using wget"
234 fi
235 if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
236 wget "$jarUrl" -O "$wrapperJarPath"
237 else
238 wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
239 fi
240 elif command -v curl > /dev/null; then
241 if [ "$MVNW_VERBOSE" = true ]; then
242 echo "Found curl ... using curl"
243 fi
244 if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
245 curl -o "$wrapperJarPath" "$jarUrl" -f
246 else
247 curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
248 fi
249
250 else
251 if [ "$MVNW_VERBOSE" = true ]; then
252 echo "Falling back to using Java to download"
253 fi
254 javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
255 # For Cygwin, switch paths to Windows format before running javac
256 if $cygwin; then
257 javaClass=`cygpath --path --windows "$javaClass"`
258 fi
259 if [ -e "$javaClass" ]; then
260 if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
261 if [ "$MVNW_VERBOSE" = true ]; then
262 echo " - Compiling MavenWrapperDownloader.java ..."
263 fi
264 # Compiling the Java class
265 ("$JAVA_HOME/bin/javac" "$javaClass")
266 fi
267 if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
268 # Running the downloader
269 if [ "$MVNW_VERBOSE" = true ]; then
270 echo " - Running MavenWrapperDownloader.java ..."
271 fi
272 ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
273 fi
274 fi
275 fi
276 fi
277 ##########################################################################################
278 # End of extension
279 ##########################################################################################
280
281 export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
282 if [ "$MVNW_VERBOSE" = true ]; then
283 echo $MAVEN_PROJECTBASEDIR
284 fi
285 MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
286
287 # For Cygwin, switch paths to Windows format before running java
288 if $cygwin; then
289 [ -n "$M2_HOME" ] &&
290 M2_HOME=`cygpath --path --windows "$M2_HOME"`
291 [ -n "$JAVA_HOME" ] &&
292 JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
293 [ -n "$CLASSPATH" ] &&
294 CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
295 [ -n "$MAVEN_PROJECTBASEDIR" ] &&
296 MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
297 fi
298
299 # Provide a "standardized" way to retrieve the CLI args that will
300 # work with both Windows and non-Windows executions.
301 MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
302 export MAVEN_CMD_LINE_ARGS
303
304 WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
305
306 exec "$JAVACMD" \
307 $MAVEN_OPTS \
308 -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
309 "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
310 ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
File mvnw.cmd added (mode: 100644) (index 0000000..8611571)
1 @REM ----------------------------------------------------------------------------
2 @REM Licensed to the Apache Software Foundation (ASF) under one
3 @REM or more contributor license agreements. See the NOTICE file
4 @REM distributed with this work for additional information
5 @REM regarding copyright ownership. The ASF licenses this file
6 @REM to you under the Apache License, Version 2.0 (the
7 @REM "License"); you may not use this file except in compliance
8 @REM with the License. You may obtain a copy of the License at
9 @REM
10 @REM http://www.apache.org/licenses/LICENSE-2.0
11 @REM
12 @REM Unless required by applicable law or agreed to in writing,
13 @REM software distributed under the License is distributed on an
14 @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 @REM KIND, either express or implied. See the License for the
16 @REM specific language governing permissions and limitations
17 @REM under the License.
18 @REM ----------------------------------------------------------------------------
19
20 @REM ----------------------------------------------------------------------------
21 @REM Maven Start Up Batch script
22 @REM
23 @REM Required ENV vars:
24 @REM JAVA_HOME - location of a JDK home dir
25 @REM
26 @REM Optional ENV vars
27 @REM M2_HOME - location of maven2's installed home dir
28 @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
30 @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 @REM e.g. to debug Maven itself, use
32 @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 @REM ----------------------------------------------------------------------------
35
36 @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 @echo off
38 @REM set title of command window
39 title %0
40 @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
41 @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42
43 @REM set %HOME% to equivalent of $HOME
44 if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45
46 @REM Execute a user defined script before this one
47 if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
50 if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
51 :skipRcPre
52
53 @setlocal
54
55 set ERROR_CODE=0
56
57 @REM To isolate internal variables from possible post scripts, we use another setlocal
58 @setlocal
59
60 @REM ==== START VALIDATION ====
61 if not "%JAVA_HOME%" == "" goto OkJHome
62
63 echo.
64 echo Error: JAVA_HOME not found in your environment. >&2
65 echo Please set the JAVA_HOME variable in your environment to match the >&2
66 echo location of your Java installation. >&2
67 echo.
68 goto error
69
70 :OkJHome
71 if exist "%JAVA_HOME%\bin\java.exe" goto init
72
73 echo.
74 echo Error: JAVA_HOME is set to an invalid directory. >&2
75 echo JAVA_HOME = "%JAVA_HOME%" >&2
76 echo Please set the JAVA_HOME variable in your environment to match the >&2
77 echo location of your Java installation. >&2
78 echo.
79 goto error
80
81 @REM ==== END VALIDATION ====
82
83 :init
84
85 @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 @REM Fallback to current working directory if not found.
87
88 set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90
91 set EXEC_DIR=%CD%
92 set WDIR=%EXEC_DIR%
93 :findBaseDir
94 IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 cd ..
96 IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 set WDIR=%CD%
98 goto findBaseDir
99
100 :baseDirFound
101 set MAVEN_PROJECTBASEDIR=%WDIR%
102 cd "%EXEC_DIR%"
103 goto endDetectBaseDir
104
105 :baseDirNotFound
106 set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 cd "%EXEC_DIR%"
108
109 :endDetectBaseDir
110
111 IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112
113 @setlocal EnableExtensions EnableDelayedExpansion
114 for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116
117 :endReadAdditionalConfig
118
119 SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122
123 set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
124
125 FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
126 IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
127 )
128
129 @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
130 @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
131 if exist %WRAPPER_JAR% (
132 if "%MVNW_VERBOSE%" == "true" (
133 echo Found %WRAPPER_JAR%
134 )
135 ) else (
136 if not "%MVNW_REPOURL%" == "" (
137 SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
138 )
139 if "%MVNW_VERBOSE%" == "true" (
140 echo Couldn't find %WRAPPER_JAR%, downloading it ...
141 echo Downloading from: %DOWNLOAD_URL%
142 )
143
144 powershell -Command "&{"^
145 "$webclient = new-object System.Net.WebClient;"^
146 "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
147 "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
148 "}"^
149 "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
150 "}"
151 if "%MVNW_VERBOSE%" == "true" (
152 echo Finished downloading %WRAPPER_JAR%
153 )
154 )
155 @REM End of extension
156
157 @REM Provide a "standardized" way to retrieve the CLI args that will
158 @REM work with both Windows and non-Windows executions.
159 set MAVEN_CMD_LINE_ARGS=%*
160
161 %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
162 if ERRORLEVEL 1 goto error
163 goto end
164
165 :error
166 set ERROR_CODE=1
167
168 :end
169 @endlocal & set ERROR_CODE=%ERROR_CODE%
170
171 if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
172 @REM check for post script, once with legacy .bat ending and once with .cmd ending
173 if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
174 if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
175 :skipRcPost
176
177 @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
178 if "%MAVEN_BATCH_PAUSE%" == "on" pause
179
180 if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
181
182 exit /B %ERROR_CODE%
The diff for file package-lock.json is too big (21585 changes) and cannot be shown.
File package.json added (mode: 100644) (index 0000000..32de50b)
1 {
2 "name": "honlap",
3 "version": "0.0.1-SNAPSHOT",
4 "description": "Description for honlap",
5 "private": true,
6 "license": "UNLICENSED",
7 "cacheDirectories": [
8 "node_modules"
9 ],
10 "dependencies": {
11 "@angular/common": "9.0.4",
12 "@angular/compiler": "9.0.4",
13 "@angular/core": "9.0.4",
14 "@angular/forms": "9.0.4",
15 "@angular/localize": "9.0.4",
16 "@angular/platform-browser": "9.0.4",
17 "@angular/platform-browser-dynamic": "9.0.4",
18 "@angular/router": "9.0.4",
19 "@fortawesome/angular-fontawesome": "0.6.0",
20 "@fortawesome/fontawesome-svg-core": "1.2.26",
21 "@fortawesome/free-solid-svg-icons": "5.12.0",
22 "@ng-bootstrap/ng-bootstrap": "6.0.0",
23 "@ngx-translate/core": "11.0.1",
24 "@ngx-translate/http-loader": "4.0.0",
25 "bootstrap": "4.4.1",
26 "moment": "2.24.0",
27 "ng-jhipster": "0.12.0",
28 "ngx-cookie": "4.0.2",
29 "ngx-infinite-scroll": "8.0.1",
30 "ngx-webstorage": "5.0.0",
31 "rxjs": "6.5.3",
32 "swagger-ui-dist": "3.24.3",
33 "tslib": "1.10.0",
34 "zone.js": "0.10.2"
35 },
36 "devDependencies": {
37 "@angular/cli": "9.0.4",
38 "@angular/compiler-cli": "9.0.4",
39 "@ngtools/webpack": "9.0.4",
40 "@openapitools/openapi-generator-cli": "1.0.10-4.2.3",
41 "@types/chai": "4.2.7",
42 "@types/chai-string": "1.4.2",
43 "@types/jest": "24.0.23",
44 "@types/mocha": "5.2.7",
45 "@types/node": "12.12.17",
46 "@types/selenium-webdriver": "4.0.5",
47 "@typescript-eslint/eslint-plugin": "2.11.0",
48 "@typescript-eslint/eslint-plugin-tslint": "2.11.0",
49 "@typescript-eslint/parser": "2.11.0",
50 "autoprefixer": "9.7.3",
51 "base-href-webpack-plugin": "2.0.0",
52 "browser-sync": "2.26.7",
53 "browser-sync-webpack-plugin": "2.2.2",
54 "chai": "4.2.0",
55 "chai-as-promised": "7.1.1",
56 "chai-string": "1.5.0",
57 "codelyzer": "5.2.0",
58 "copy-webpack-plugin": "5.1.1",
59 "css-loader": "3.3.2",
60 "eslint": "6.7.2",
61 "eslint-config-jhipster": "0.0.1",
62 "eslint-config-prettier": "6.7.0",
63 "eslint-loader": "3.0.3",
64 "file-loader": "5.0.2",
65 "friendly-errors-webpack-plugin": "1.7.0",
66 "generator-jhipster": "6.8.0",
67 "html-loader": "0.5.5",
68 "html-webpack-plugin": "3.2.0",
69 "husky": "3.1.0",
70 "jest": "24.9.0",
71 "jest-date-mock": "1.0.7",
72 "jest-junit": "10.0.0",
73 "jest-preset-angular": "8.0.0",
74 "jest-sonar-reporter": "2.0.0",
75 "lint-staged": "8.2.1",
76 "merge-jsons-webpack-plugin": "1.0.20",
77 "mini-css-extract-plugin": "0.8.0",
78 "mocha": "6.2.2",
79 "moment-locales-webpack-plugin": "1.1.2",
80 "optimize-css-assets-webpack-plugin": "5.0.3",
81 "postcss-loader": "3.0.0",
82 "prettier": "1.19.1",
83 "protractor": "5.4.2",
84 "reflect-metadata": "0.1.13",
85 "rimraf": "3.0.0",
86 "sass": "1.23.7",
87 "sass-loader": "8.0.0",
88 "simple-progress-webpack-plugin": "1.1.2",
89 "style-loader": "1.0.1",
90 "terser-webpack-plugin": "2.3.0",
91 "thread-loader": "2.1.3",
92 "to-string-loader": "1.1.6",
93 "ts-loader": "6.2.1",
94 "ts-node": "8.5.4",
95 "tslint": "6.0.0",
96 "typescript": "3.7.5",
97 "webdriver-manager": "12.1.7",
98 "webpack": "4.41.2",
99 "webpack-bundle-analyzer": "3.6.0",
100 "webpack-cli": "3.3.10",
101 "webpack-dev-server": "3.9.0",
102 "webpack-merge": "4.2.2",
103 "webpack-notifier": "1.8.0",
104 "workbox-webpack-plugin": "4.3.1",
105 "write-file-webpack-plugin": "4.5.1"
106 },
107 "engines": {
108 "node": ">=8.9.0"
109 },
110 "scripts": {
111 "prettier:format": "prettier --write \"{,src/**/}*.{md,json,ts,css,scss,yml}\"",
112 "lint": "eslint . --ext .js,.ts",
113 "lint:fix": "npm run lint -- --fix",
114 "ngc": "ngc -p tsconfig.app.json",
115 "cleanup": "rimraf target/classes/static/ target/classes/aot",
116 "clean-www": "rimraf target/classes/static/app/{src,target/}",
117 "e2e": "protractor src/test/javascript/protractor.conf.js",
118 "postinstall": "node node_modules/protractor/bin/webdriver-manager update --gecko false",
119 "start": "npm run webpack:dev",
120 "start-tls": "npm run webpack:dev -- --env.tls",
121 "serve": "npm run start",
122 "build": "npm run webpack:prod",
123 "test": "npm run lint && jest --coverage --logHeapUsage -w=2 --config src/test/javascript/jest.conf.js",
124 "test:watch": "npm run test -- --watch",
125 "webpack:dev": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --inline --hot --port=9060 --watch-content-base --env.stats=minimal",
126 "webpack:dev-verbose": "npm run webpack-dev-server -- --config webpack/webpack.dev.js --inline --hot --port=9060 --watch-content-base --profile --progress --env.stats=normal",
127 "webpack:build:main": "npm run webpack -- --config webpack/webpack.dev.js --env.stats=minimal",
128 "webpack:build": "npm run cleanup && npm run webpack:build:main",
129 "webpack:prod:main": "npm run webpack -- --config webpack/webpack.prod.js --profile",
130 "webpack:prod": "npm run cleanup && npm run webpack:prod:main && npm run clean-www",
131 "webpack:test": "npm run test",
132 "webpack-dev-server": "node --max_old_space_size=4096 node_modules/webpack-dev-server/bin/webpack-dev-server.js",
133 "webpack": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js"
134 },
135 "jestSonar": {
136 "reportPath": "target/test-results/jest",
137 "reportFile": "TESTS-results-sonar.xml"
138 }
139 }
File pom.xml added (mode: 100644) (index 0000000..2b4e616)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5
6 <groupId>hu.dns.honlap</groupId>
7 <artifactId>honlap</artifactId>
8 <version>0.0.1-SNAPSHOT</version>
9 <packaging>jar</packaging>
10 <name>Honlap</name>
11
12 <repositories>
13 <!-- jhipster-needle-maven-repository -->
14 </repositories>
15
16 <pluginRepositories>
17 <!-- jhipster-needle-maven-plugin-repository -->
18 </pluginRepositories>
19
20 <!-- jhipster-needle-distribution-management -->
21
22 <properties>
23 <!-- Build properties -->
24 <maven.version>3.3.9</maven.version>
25 <java.version>1.8</java.version>
26 <node.version>v12.16.1</node.version>
27 <npm.version>6.14.2</npm.version>
28 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
29 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
30 <project.testresult.directory>${project.build.directory}/test-results</project.testresult.directory>
31 <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
32 <maven.compiler.source>${java.version}</maven.compiler.source>
33 <maven.compiler.target>${java.version}</maven.compiler.target>
34 <argLine>-Djava.security.egd=file:/dev/./urandom -Xmx256m</argLine>
35 <m2e.apt.activation>jdt_apt</m2e.apt.activation>
36 <run.addResources>false</run.addResources>
37 <!-- These remain empty unless the corresponding profile is active -->
38 <profile.no-liquibase />
39 <profile.swagger />
40 <profile.tls />
41
42 <!-- Dependency versions -->
43 <jhipster-dependencies.version>3.6.0</jhipster-dependencies.version>
44 <!-- The spring-boot version should match the one managed by
45 https://mvnrepository.com/artifact/io.github.jhipster/jhipster-dependencies/${jhipster-dependencies.version} -->
46 <spring-boot.version>2.2.5.RELEASE</spring-boot.version>
47 <!-- The hibernate version should match the one managed by
48 https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies/${spring-boot.version} -->
49 <hibernate.version>5.4.12.Final</hibernate.version>
50 <!-- The javassist version should match the one managed by
51 https://mvnrepository.com/artifact/org.hibernate/hibernate-core/${hibernate.version} -->
52 <javassist.version>3.24.0-GA</javassist.version>
53 <!-- The liquibase version should match the one managed by
54 https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies/${spring-boot.version} -->
55 <liquibase.version>3.8.7</liquibase.version>
56 <liquibase-hibernate5.version>3.8</liquibase-hibernate5.version>
57 <h2.version>1.4.200</h2.version>
58 <validation-api.version>2.0.1.Final</validation-api.version>
59 <jaxb-runtime.version>2.3.2</jaxb-runtime.version>
60 <archunit-junit5.version>0.13.1</archunit-junit5.version>
61 <mapstruct.version>1.3.1.Final</mapstruct.version>
62 <!-- Plugin versions -->
63 <maven-clean-plugin.version>3.1.0</maven-clean-plugin.version>
64 <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
65 <maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
66 <maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
67 <maven-enforcer-plugin.version>3.0.0-M3</maven-enforcer-plugin.version>
68 <maven-failsafe-plugin.version>3.0.0-M4</maven-failsafe-plugin.version>
69 <maven-idea-plugin.version>2.2.1</maven-idea-plugin.version>
70 <maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
71 <maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version>
72 <maven-war-plugin.version>3.2.3</maven-war-plugin.version>
73 <maven-checkstyle.version>3.1.1</maven-checkstyle.version>
74 <checkstyle.version>8.29</checkstyle.version>
75 <spring-nohttp-checkstyle.version>0.0.4.RELEASE</spring-nohttp-checkstyle.version>
76 <frontend-maven-plugin.version>1.9.1</frontend-maven-plugin.version>
77 <git-commit-id-plugin.version>4.0.0</git-commit-id-plugin.version>
78 <jacoco-maven-plugin.version>0.8.5</jacoco-maven-plugin.version>
79 <jib-maven-plugin.version>2.0.0</jib-maven-plugin.version>
80 <lifecycle-mapping.version>1.0.0</lifecycle-mapping.version>
81 <properties-maven-plugin.version>1.0.0</properties-maven-plugin.version>
82 <sonar-maven-plugin.version>3.7.0.1746</sonar-maven-plugin.version>
83 <jacoco.utReportFolder>${project.build.directory}/jacoco/test</jacoco.utReportFolder>
84 <jacoco.utReportFile>${jacoco.utReportFolder}/test.exec</jacoco.utReportFile>
85 <jacoco.itReportFolder>${project.build.directory}/jacoco/integrationTest</jacoco.itReportFolder>
86 <jacoco.itReportFile>${jacoco.itReportFolder}/integrationTest.exec</jacoco.itReportFile>
87 <junit.utReportFolder>${project.testresult.directory}/test</junit.utReportFolder>
88 <junit.itReportFolder>${project.testresult.directory}/integrationTest</junit.itReportFolder>
89 <!-- jhipster-needle-maven-property -->
90 </properties>
91
92 <dependencyManagement>
93 <dependencies>
94 <dependency>
95 <groupId>io.github.jhipster</groupId>
96 <artifactId>jhipster-dependencies</artifactId>
97 <version>${jhipster-dependencies.version}</version>
98 <type>pom</type>
99 <scope>import</scope>
100 </dependency>
101 <!-- jhipster-needle-maven-add-dependency-management -->
102 </dependencies>
103 </dependencyManagement>
104
105 <dependencies>
106 <dependency>
107 <groupId>io.github.jhipster</groupId>
108 <artifactId>jhipster-framework</artifactId>
109 </dependency>
110 <dependency>
111 <groupId>javax.annotation</groupId>
112 <artifactId>javax.annotation-api</artifactId>
113 </dependency>
114
115 <dependency>
116 <groupId>org.springframework.boot</groupId>
117 <artifactId>spring-boot-starter-cache</artifactId>
118 </dependency>
119 <dependency>
120 <groupId>com.fasterxml.jackson.module</groupId>
121 <artifactId>jackson-module-jaxb-annotations</artifactId>
122 </dependency>
123 <dependency>
124 <groupId>com.fasterxml.jackson.datatype</groupId>
125 <artifactId>jackson-datatype-hibernate5</artifactId>
126 </dependency>
127 <dependency>
128 <groupId>com.fasterxml.jackson.datatype</groupId>
129 <artifactId>jackson-datatype-hppc</artifactId>
130 </dependency>
131 <dependency>
132 <groupId>com.fasterxml.jackson.datatype</groupId>
133 <artifactId>jackson-datatype-jsr310</artifactId>
134 </dependency>
135 <dependency>
136 <groupId>com.fasterxml.jackson.module</groupId>
137 <artifactId>jackson-module-afterburner</artifactId>
138 </dependency>
139 <dependency>
140 <groupId>com.h2database</groupId>
141 <artifactId>h2</artifactId>
142 <scope>test</scope>
143 </dependency>
144 <dependency>
145 <groupId>io.springfox</groupId>
146 <artifactId>springfox-swagger2</artifactId>
147 </dependency>
148 <dependency>
149 <groupId>io.springfox</groupId>
150 <artifactId>springfox-bean-validators</artifactId>
151 </dependency>
152 <dependency>
153 <groupId>com.zaxxer</groupId>
154 <artifactId>HikariCP</artifactId>
155 </dependency>
156 <dependency>
157 <groupId>commons-io</groupId>
158 <artifactId>commons-io</artifactId>
159 </dependency>
160 <dependency>
161 <groupId>org.apache.commons</groupId>
162 <artifactId>commons-lang3</artifactId>
163 </dependency>
164 <dependency>
165 <groupId>javax.cache</groupId>
166 <artifactId>cache-api</artifactId>
167 </dependency>
168 <dependency>
169 <groupId>org.ehcache</groupId>
170 <artifactId>ehcache</artifactId>
171 </dependency>
172 <dependency>
173 <groupId>org.hibernate</groupId>
174 <artifactId>hibernate-jcache</artifactId>
175 </dependency>
176 <dependency>
177 <groupId>org.hibernate</groupId>
178 <artifactId>hibernate-jpamodelgen</artifactId>
179 <scope>provided</scope>
180 </dependency>
181 <dependency>
182 <groupId>org.hibernate</groupId>
183 <artifactId>hibernate-core</artifactId>
184 </dependency>
185 <dependency>
186 <groupId>org.hibernate.validator</groupId>
187 <artifactId>hibernate-validator</artifactId>
188 </dependency>
189 <dependency>
190 <groupId>org.liquibase</groupId>
191 <artifactId>liquibase-core</artifactId>
192 <!-- Inherited version from Spring Boot can't be used because of regressions -->
193 <version>${liquibase.version}</version>
194 </dependency>
195 <dependency>
196 <groupId>net.logstash.logback</groupId>
197 <artifactId>logstash-logback-encoder</artifactId>
198 </dependency>
199 <dependency>
200 <groupId>org.postgresql</groupId>
201 <artifactId>postgresql</artifactId>
202 </dependency>
203 <dependency>
204 <groupId>org.mapstruct</groupId>
205 <artifactId>mapstruct</artifactId>
206 </dependency>
207 <dependency>
208 <groupId>org.mapstruct</groupId>
209 <artifactId>mapstruct-processor</artifactId>
210 <scope>provided</scope>
211 </dependency>
212 <dependency>
213 <groupId>org.springframework.boot</groupId>
214 <artifactId>spring-boot-configuration-processor</artifactId>
215 <scope>provided</scope>
216 </dependency>
217 <dependency>
218 <groupId>org.springframework.boot</groupId>
219 <artifactId>spring-boot-loader-tools</artifactId>
220 </dependency>
221 <dependency>
222 <groupId>org.springframework.boot</groupId>
223 <artifactId>spring-boot-starter-actuator</artifactId>
224 </dependency>
225 <dependency>
226 <groupId>org.springframework.boot</groupId>
227 <artifactId>spring-boot-starter-aop</artifactId>
228 </dependency>
229 <dependency>
230 <groupId>org.springframework.boot</groupId>
231 <artifactId>spring-boot-starter-data-jpa</artifactId>
232 </dependency>
233 <dependency>
234 <groupId>org.springframework.boot</groupId>
235 <artifactId>spring-boot-starter-logging</artifactId>
236 </dependency>
237 <dependency>
238 <groupId>org.springframework.boot</groupId>
239 <artifactId>spring-boot-starter-mail</artifactId>
240 </dependency>
241 <dependency>
242 <groupId>org.springframework.boot</groupId>
243 <artifactId>spring-boot-starter-security</artifactId>
244 </dependency>
245 <dependency>
246 <groupId>org.springframework.boot</groupId>
247 <artifactId>spring-boot-starter-thymeleaf</artifactId>
248 </dependency>
249 <dependency>
250 <groupId>org.springframework.boot</groupId>
251 <artifactId>spring-boot-starter-web</artifactId>
252 </dependency>
253 <dependency>
254 <groupId>org.springframework.boot</groupId>
255 <artifactId>spring-boot-starter-test</artifactId>
256 <scope>test</scope>
257 </dependency>
258 <dependency>
259 <groupId>org.springframework.boot</groupId>
260 <artifactId>spring-boot-test</artifactId>
261 <scope>test</scope>
262 </dependency>
263 <dependency>
264 <groupId>org.springframework.security</groupId>
265 <artifactId>spring-security-test</artifactId>
266 <scope>test</scope>
267 </dependency>
268 <dependency>
269 <groupId>com.tngtech.archunit</groupId>
270 <artifactId>archunit-junit5-api</artifactId>
271 <version>${archunit-junit5.version}</version>
272 <scope>test</scope>
273 </dependency>
274 <!-- Adding the engine dependency to the surefire-plugin unfortunately does not work in the current version. -->
275 <!-- https://www.archunit.org/userguide/html/000_Index.html#_junit_5 -->
276 <dependency>
277 <groupId>com.tngtech.archunit</groupId>
278 <artifactId>archunit-junit5-engine</artifactId>
279 <version>${archunit-junit5.version}</version>
280 <scope>test</scope>
281 </dependency>
282 <dependency>
283 <groupId>org.zalando</groupId>
284 <artifactId>problem-spring-web</artifactId>
285 </dependency>
286 <dependency>
287 <groupId>io.jsonwebtoken</groupId>
288 <artifactId>jjwt-api</artifactId>
289 </dependency>
290 <dependency>
291 <groupId>io.jsonwebtoken</groupId>
292 <artifactId>jjwt-impl</artifactId>
293 <scope>runtime</scope>
294 </dependency>
295 <dependency>
296 <groupId>io.jsonwebtoken</groupId>
297 <artifactId>jjwt-jackson</artifactId>
298 <scope>runtime</scope>
299 </dependency>
300 <!-- Spring Cloud -->
301 <dependency>
302 <groupId>org.springframework.boot</groupId>
303 <artifactId>spring-boot-starter-cloud-connectors</artifactId>
304 </dependency>
305 <dependency>
306 <groupId>org.springframework.security</groupId>
307 <artifactId>spring-security-data</artifactId>
308 </dependency>
309 <dependency>
310 <groupId>io.micrometer</groupId>
311 <artifactId>micrometer-registry-prometheus</artifactId>
312 </dependency>
313 <dependency>
314 <groupId>io.dropwizard.metrics</groupId>
315 <artifactId>metrics-core</artifactId>
316 </dependency>
317 <!-- Cucumber -->
318 <dependency>
319 <groupId>io.cucumber</groupId>
320 <artifactId>cucumber-junit</artifactId>
321 <scope>test</scope>
322 </dependency>
323 <dependency>
324 <groupId>io.cucumber</groupId>
325 <artifactId>cucumber-spring</artifactId>
326 <scope>test</scope>
327 </dependency>
328 <!-- jhipster-needle-maven-add-dependency -->
329 </dependencies>
330
331 <build>
332 <defaultGoal>spring-boot:run</defaultGoal>
333 <testResources>
334 <testResource>
335 <directory>src/test/resources/</directory>
336 </testResource>
337 <testResource>
338 <directory>src/test/features</directory>
339 </testResource>
340 </testResources>
341 <plugins>
342 <plugin>
343 <groupId>org.apache.maven.plugins</groupId>
344 <artifactId>maven-compiler-plugin</artifactId>
345 </plugin>
346 <plugin>
347 <groupId>org.apache.maven.plugins</groupId>
348 <artifactId>maven-checkstyle-plugin</artifactId>
349 </plugin>
350 <plugin>
351 <groupId>org.apache.maven.plugins</groupId>
352 <artifactId>maven-javadoc-plugin</artifactId>
353 </plugin>
354 <plugin>
355 <groupId>org.apache.maven.plugins</groupId>
356 <artifactId>maven-eclipse-plugin</artifactId>
357 </plugin>
358 <plugin>
359 <groupId>org.apache.maven.plugins</groupId>
360 <artifactId>maven-enforcer-plugin</artifactId>
361 </plugin>
362 <plugin>
363 <groupId>org.apache.maven.plugins</groupId>
364 <artifactId>maven-failsafe-plugin</artifactId>
365 </plugin>
366 <plugin>
367 <groupId>org.apache.maven.plugins</groupId>
368 <artifactId>maven-idea-plugin</artifactId>
369 </plugin>
370 <plugin>
371 <groupId>org.apache.maven.plugins</groupId>
372 <artifactId>maven-resources-plugin</artifactId>
373 </plugin>
374 <plugin>
375 <groupId>org.apache.maven.plugins</groupId>
376 <artifactId>maven-surefire-plugin</artifactId>
377 </plugin>
378 <plugin>
379 <groupId>org.jacoco</groupId>
380 <artifactId>jacoco-maven-plugin</artifactId>
381 </plugin>
382 <plugin>
383 <groupId>org.sonarsource.scanner.maven</groupId>
384 <artifactId>sonar-maven-plugin</artifactId>
385 </plugin>
386 <plugin>
387 <groupId>org.liquibase</groupId>
388 <artifactId>liquibase-maven-plugin</artifactId>
389 </plugin>
390 <plugin>
391 <groupId>org.springframework.boot</groupId>
392 <artifactId>spring-boot-maven-plugin</artifactId>
393 </plugin>
394 <plugin>
395 <groupId>com.google.cloud.tools</groupId>
396 <artifactId>jib-maven-plugin</artifactId>
397 </plugin>
398 <plugin>
399 <groupId>org.codehaus.mojo</groupId>
400 <artifactId>properties-maven-plugin</artifactId>
401 </plugin>
402 <!-- jhipster-needle-maven-add-plugin -->
403 </plugins>
404 <pluginManagement>
405 <plugins>
406 <plugin>
407 <groupId>org.apache.maven.plugins</groupId>
408 <artifactId>maven-checkstyle-plugin</artifactId>
409 <version>${maven-checkstyle.version}</version>
410 <dependencies>
411 <dependency>
412 <groupId>com.puppycrawl.tools</groupId>
413 <artifactId>checkstyle</artifactId>
414 <version>${checkstyle.version}</version>
415 </dependency>
416 <dependency>
417 <groupId>io.spring.nohttp</groupId>
418 <artifactId>nohttp-checkstyle</artifactId>
419 <version>${spring-nohttp-checkstyle.version}</version>
420 </dependency>
421 </dependencies>
422 <configuration>
423 <configLocation>checkstyle.xml</configLocation>
424 <includes>pom.xml,README.md</includes>
425 <excludes>.git/**/*,target/**/*,node_modules/**/*,node/**/*</excludes>
426 <sourceDirectories>./</sourceDirectories>
427 </configuration>
428 <executions>
429 <execution>
430 <goals>
431 <goal>check</goal>
432 </goals>
433 </execution>
434 </executions>
435 </plugin>
436 <plugin>
437 <groupId>org.apache.maven.plugins</groupId>
438 <artifactId>maven-compiler-plugin</artifactId>
439 <version>${maven-compiler-plugin.version}</version>
440 <configuration>
441 <source>${java.version}</source>
442 <target>${java.version}</target>
443 <annotationProcessorPaths>
444 <path>
445 <groupId>org.springframework.boot</groupId>
446 <artifactId>spring-boot-configuration-processor</artifactId>
447 <version>${spring-boot.version}</version>
448 </path>
449 <path>
450 <groupId>org.mapstruct</groupId>
451 <artifactId>mapstruct-processor</artifactId>
452 <version>${mapstruct.version}</version>
453 </path>
454 <!-- For JPA static metamodel generation -->
455 <path>
456 <groupId>org.hibernate</groupId>
457 <artifactId>hibernate-jpamodelgen</artifactId>
458 <version>${hibernate.version}</version>
459 </path>
460 <path>
461 <groupId>org.glassfish.jaxb</groupId>
462 <artifactId>jaxb-runtime</artifactId>
463 <version>${jaxb-runtime.version}</version>
464 </path>
465 <!-- jhipster-needle-maven-add-annotation-processor -->
466 </annotationProcessorPaths>
467 </configuration>
468 </plugin>
469 <plugin>
470 <groupId>org.apache.maven.plugins</groupId>
471 <artifactId>maven-javadoc-plugin</artifactId>
472 <version>${maven-javadoc-plugin.version}</version>
473 <configuration>
474 <source>${maven.compiler.source}</source>
475 </configuration>
476 </plugin>
477 <plugin>
478 <groupId>org.apache.maven.plugins</groupId>
479 <artifactId>maven-war-plugin</artifactId>
480 <version>${maven-war-plugin.version}</version>
481 <executions>
482 <execution>
483 <goals>
484 <goal>war</goal>
485 </goals>
486 <phase>package</phase>
487 </execution>
488 </executions>
489 <configuration>
490 <warSourceIncludes>WEB-INF/**,META-INF/**</warSourceIncludes>
491 <failOnMissingWebXml>false</failOnMissingWebXml>
492 <warSourceDirectory>target/classes/static/</warSourceDirectory>
493 <webResources>
494 <resource>
495 <directory>src/main/webapp</directory>
496 <includes>
497 <include>WEB-INF/**</include>
498 </includes>
499 </resource>
500 </webResources>
501 </configuration>
502 </plugin>
503 <plugin>
504 <groupId>com.github.eirslett</groupId>
505 <artifactId>frontend-maven-plugin</artifactId>
506 <version>${frontend-maven-plugin.version}</version>
507 </plugin>
508 <plugin>
509 <groupId>org.codehaus.mojo</groupId>
510 <artifactId>properties-maven-plugin</artifactId>
511 <version>${properties-maven-plugin.version}</version>
512 <executions>
513 <execution>
514 <phase>initialize</phase>
515 <goals>
516 <goal>read-project-properties</goal>
517 </goals>
518 <configuration>
519 <files>
520 <file>sonar-project.properties</file>
521 </files>
522 </configuration>
523 </execution>
524 </executions>
525 </plugin>
526
527 <plugin>
528 <groupId>pl.project13.maven</groupId>
529 <artifactId>git-commit-id-plugin</artifactId>
530 <version>${git-commit-id-plugin.version}</version>
531 <executions>
532 <execution>
533 <goals>
534 <goal>revision</goal>
535 </goals>
536 </execution>
537 </executions>
538 <configuration>
539 <failOnNoGitDirectory>false</failOnNoGitDirectory>
540 <failOnUnableToExtractRepoInfo>false</failOnUnableToExtractRepoInfo>
541 <generateGitPropertiesFile>true</generateGitPropertiesFile>
542 <includeOnlyProperties>
543 <includeOnlyProperty>^git.commit.id.abbrev$</includeOnlyProperty>
544 <includeOnlyProperty>^git.commit.id.describe$</includeOnlyProperty>
545 <includeOnlyProperty>^git.branch$</includeOnlyProperty>
546 </includeOnlyProperties>
547 </configuration>
548 </plugin>
549 <plugin>
550 <groupId>org.jacoco</groupId>
551 <artifactId>jacoco-maven-plugin</artifactId>
552 <version>${jacoco-maven-plugin.version}</version>
553 <executions>
554 <execution>
555 <id>pre-unit-tests</id>
556 <goals>
557 <goal>prepare-agent</goal>
558 </goals>
559 <configuration>
560 <!-- Sets the path to the file which contains the execution data. -->
561 <destFile>${jacoco.utReportFile}</destFile>
562 </configuration>
563 </execution>
564 <!-- Ensures that the code coverage report for unit tests is created after unit tests have been run -->
565 <execution>
566 <id>post-unit-test</id>
567 <phase>test</phase>
568 <goals>
569 <goal>report</goal>
570 </goals>
571 <configuration>
572 <dataFile>${jacoco.utReportFile}</dataFile>
573 <outputDirectory>${jacoco.utReportFolder}</outputDirectory>
574 </configuration>
575 </execution>
576 <execution>
577 <id>pre-integration-tests</id>
578 <goals>
579 <goal>prepare-agent-integration</goal>
580 </goals>
581 <configuration>
582 <!-- Sets the path to the file which contains the execution data. -->
583 <destFile>${jacoco.itReportFile}</destFile>
584 </configuration>
585 </execution>
586 <!-- Ensures that the code coverage report for integration tests is created after integration tests have been run -->
587 <execution>
588 <id>post-integration-tests</id>
589 <phase>post-integration-test</phase>
590 <goals>
591 <goal>report-integration</goal>
592 </goals>
593 <configuration>
594 <dataFile>${jacoco.itReportFile}</dataFile>
595 <outputDirectory>${jacoco.itReportFolder}</outputDirectory>
596 </configuration>
597 </execution>
598 </executions>
599 </plugin>
600 <plugin>
601 <groupId>com.google.cloud.tools</groupId>
602 <artifactId>jib-maven-plugin</artifactId>
603 <version>${jib-maven-plugin.version}</version>
604 <configuration>
605 <from>
606 <image>adoptopenjdk:11-jre-hotspot</image>
607 </from>
608 <to>
609 <image>honlap:latest</image>
610 </to>
611 <container>
612 <entrypoint>
613 <shell>bash</shell>
614 <option>-c</option>
615 <arg>/entrypoint.sh</arg>
616 </entrypoint>
617 <ports>
618 <port>8080</port>
619 </ports>
620 <environment>
621 <SPRING_OUTPUT_ANSI_ENABLED>ALWAYS</SPRING_OUTPUT_ANSI_ENABLED>
622 <JHIPSTER_SLEEP>0</JHIPSTER_SLEEP>
623 </environment>
624 <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
625 </container>
626 <extraDirectories>
627 <paths>src/main/jib</paths>
628 <permissions>
629 <permission>
630 <file>/entrypoint.sh</file>
631 <mode>755</mode>
632 </permission>
633 </permissions>
634 </extraDirectories>
635 </configuration>
636 </plugin>
637 <plugin>
638 <groupId>org.liquibase</groupId>
639 <artifactId>liquibase-maven-plugin</artifactId>
640 <version>${liquibase.version}</version>
641 <configuration>
642 <changeLogFile>${project.basedir}/src/main/resources/config/liquibase/master.xml</changeLogFile>
643 <diffChangeLogFile>${project.basedir}/src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>
644 <driver>org.h2.Driver</driver>
645 <url>jdbc:h2:file:${project.build.directory}/h2db/db/honlap</url>
646 <defaultSchemaName></defaultSchemaName>
647 <username>honlap</username>
648 <password></password>
649 <referenceUrl>hibernate:spring:hu.dns.honlap.domain?dialect=org.hibernate.dialect.H2Dialect&amp;hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&amp;hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy</referenceUrl>
650 <verbose>true</verbose>
651 <logging>debug</logging>
652 <contexts>!test</contexts>
653 </configuration>
654 <dependencies>
655 <dependency>
656 <groupId>org.liquibase</groupId>
657 <artifactId>liquibase-core</artifactId>
658 <version>${liquibase.version}</version>
659 </dependency>
660 <dependency>
661 <groupId>org.liquibase.ext</groupId>
662 <artifactId>liquibase-hibernate5</artifactId>
663 <version>${liquibase-hibernate5.version}</version>
664 </dependency>
665 <dependency>
666 <groupId>org.springframework.boot</groupId>
667 <artifactId>spring-boot-starter-data-jpa</artifactId>
668 <version>${spring-boot.version}</version>
669 </dependency>
670 <dependency>
671 <groupId>javax.validation</groupId>
672 <artifactId>validation-api</artifactId>
673 <version>${validation-api.version}</version>
674 </dependency>
675 <dependency>
676 <groupId>org.javassist</groupId>
677 <artifactId>javassist</artifactId>
678 <version>${javassist.version}</version>
679 </dependency>
680 <dependency>
681 <groupId>com.h2database</groupId>
682 <artifactId>h2</artifactId>
683 <version>${h2.version}</version>
684 </dependency>
685 </dependencies>
686 </plugin>
687 <plugin>
688 <artifactId>maven-clean-plugin</artifactId>
689 <version>${maven-clean-plugin.version}</version>
690 </plugin>
691 <plugin>
692 <groupId>org.apache.maven.plugins</groupId>
693 <artifactId>maven-eclipse-plugin</artifactId>
694 <version>${maven-eclipse-plugin.version}</version>
695 <configuration>
696 <downloadSources>true</downloadSources>
697 <downloadJavadocs>true</downloadJavadocs>
698 </configuration>
699 </plugin>
700 <plugin>
701 <groupId>org.apache.maven.plugins</groupId>
702 <artifactId>maven-enforcer-plugin</artifactId>
703 <version>${maven-enforcer-plugin.version}</version>
704 <executions>
705 <execution>
706 <id>enforce-versions</id>
707 <goals>
708 <goal>enforce</goal>
709 </goals>
710 </execution>
711 <execution>
712 <id>enforce-dependencyConvergence</id>
713 <configuration>
714 <rules>
715 <DependencyConvergence />
716 </rules>
717 <fail>false</fail>
718 </configuration>
719 <goals>
720 <goal>enforce</goal>
721 </goals>
722 </execution>
723 </executions>
724 <configuration>
725 <rules>
726 <requireMavenVersion>
727 <message>You are running an older version of Maven. JHipster requires at least Maven ${maven.version}</message>
728 <version>[${maven.version},)</version>
729 </requireMavenVersion>
730 <requireJavaVersion>
731 <message>You are running an incompatible version of Java. JHipster supports JDK 8 to 13.</message>
732 <version>[1.8,14)</version>
733 </requireJavaVersion>
734 </rules>
735 </configuration>
736 </plugin>
737 <plugin>
738 <groupId>org.apache.maven.plugins</groupId>
739 <artifactId>maven-idea-plugin</artifactId>
740 <version>${maven-idea-plugin.version}</version>
741 <configuration>
742 <exclude>node_modules</exclude>
743 </configuration>
744 </plugin>
745 <plugin>
746 <groupId>org.apache.maven.plugins</groupId>
747 <artifactId>maven-resources-plugin</artifactId>
748 <version>${maven-resources-plugin.version}</version>
749 <executions>
750 <execution>
751 <id>default-resources</id>
752 <phase>validate</phase>
753 <goals>
754 <goal>copy-resources</goal>
755 </goals>
756 <configuration>
757 <outputDirectory>${project.build.directory}/classes</outputDirectory>
758 <useDefaultDelimiters>false</useDefaultDelimiters>
759 <delimiters>
760 <delimiter>#</delimiter>
761 </delimiters>
762 <resources>
763 <resource>
764 <directory>src/main/resources/</directory>
765 <filtering>true</filtering>
766 <includes>
767 <include>config/*.yml</include>
768 </includes>
769 </resource>
770 <resource>
771 <directory>src/main/resources/</directory>
772 <filtering>false</filtering>
773 <excludes>
774 <exclude>config/*.yml</exclude>
775 </excludes>
776 </resource>
777 </resources>
778 </configuration>
779 </execution>
780 </executions>
781 </plugin>
782 <plugin>
783 <groupId>org.apache.maven.plugins</groupId>
784 <artifactId>maven-surefire-plugin</artifactId>
785 <version>${maven-surefire-plugin.version}</version>
786 <configuration>
787 <!-- Force alphabetical order to have a reproducible build -->
788 <runOrder>alphabetical</runOrder>
789 <reportsDirectory>${junit.utReportFolder}</reportsDirectory>
790 <excludes>
791 <exclude>**/*IT*</exclude>
792 <exclude>**/*IntTest*</exclude>
793 </excludes>
794 </configuration>
795 </plugin>
796 <plugin>
797 <groupId>org.apache.maven.plugins</groupId>
798 <artifactId>maven-failsafe-plugin</artifactId>
799 <version>${maven-failsafe-plugin.version}</version>
800 <configuration>
801 <!-- Due to spring-boot repackage, without adding this property test classes are not found
802 See https://github.com/spring-projects/spring-boot/issues/6254 -->
803 <classesDirectory>${project.build.outputDirectory}</classesDirectory>
804 <!-- Force alphabetical order to have a reproducible build -->
805 <runOrder>alphabetical</runOrder>
806 <reportsDirectory>${junit.itReportFolder}</reportsDirectory>
807 <includes>
808 <include>**/*IT*</include>
809 <include>**/*IntTest*</include>
810 </includes>
811 </configuration>
812 <executions>
813 <execution>
814 <id>integration-test</id>
815 <goals>
816 <goal>integration-test</goal>
817 </goals>
818 </execution>
819 <execution>
820 <id>verify</id>
821 <goals>
822 <goal>verify</goal>
823 </goals>
824 </execution>
825 </executions>
826 </plugin>
827 <plugin>
828 <groupId>org.sonarsource.scanner.maven</groupId>
829 <artifactId>sonar-maven-plugin</artifactId>
830 <version>${sonar-maven-plugin.version}</version>
831 </plugin>
832 <plugin>
833 <groupId>org.springframework.boot</groupId>
834 <artifactId>spring-boot-maven-plugin</artifactId>
835 <version>${spring-boot.version}</version>
836 <executions>
837 <execution>
838 <goals>
839 <goal>repackage</goal>
840 </goals>
841 </execution>
842 </executions>
843 <configuration>
844 <mainClass>${start-class}</mainClass>
845 <fork>true</fork>
846 <!--
847 Enable the line below to have remote debugging of your application on port 5005
848 <jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmArguments>
849 -->
850 </configuration>
851
852 </plugin>
853 <!-- jhipster-needle-maven-add-plugin-management -->
854 </plugins>
855 </pluginManagement>
856 </build>
857 <profiles>
858 <profile>
859 <id>no-liquibase</id>
860 <properties>
861 <profile.no-liquibase>,no-liquibase</profile.no-liquibase>
862 </properties>
863 </profile>
864 <profile>
865 <id>swagger</id>
866 <properties>
867 <profile.swagger>,swagger</profile.swagger>
868 </properties>
869 </profile>
870 <profile>
871 <id>tls</id>
872 <properties>
873 <profile.tls>,tls</profile.tls>
874 </properties>
875 </profile>
876 <profile>
877 <id>webpack</id>
878 <activation>
879 <activeByDefault>true</activeByDefault>
880 </activation>
881 <dependencies>
882 <dependency>
883 <groupId>com.h2database</groupId>
884 <artifactId>h2</artifactId>
885 </dependency>
886 </dependencies>
887 <build>
888 <plugins>
889 <plugin>
890 <groupId>com.github.eirslett</groupId>
891 <artifactId>frontend-maven-plugin</artifactId>
892 <executions>
893 <execution>
894 <id>install node and npm</id>
895 <goals>
896 <goal>install-node-and-npm</goal>
897 </goals>
898 <configuration>
899 <nodeVersion>${node.version}</nodeVersion>
900 <npmVersion>${npm.version}</npmVersion>
901 </configuration>
902 </execution>
903 <execution>
904 <id>npm install</id>
905 <goals>
906 <goal>npm</goal>
907 </goals>
908 </execution>
909 <execution>
910 <id>webpack build dev</id>
911 <goals>
912 <goal>npm</goal>
913 </goals>
914 <phase>generate-resources</phase>
915 <configuration>
916 <arguments>run webpack:build</arguments>
917 <environmentVariables>
918 <APP_VERSION>${project.version}</APP_VERSION>
919 </environmentVariables>
920 <npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
921 </configuration>
922 </execution>
923 </executions>
924 </plugin>
925 </plugins>
926 </build>
927 <properties>
928 <!-- default Spring profiles -->
929 <spring.profiles.active>dev${profile.no-liquibase}</spring.profiles.active>
930 </properties>
931 </profile>
932 <profile>
933 <id>dev</id>
934 <activation>
935 <activeByDefault>true</activeByDefault>
936 </activation>
937 <dependencies>
938 <dependency>
939 <groupId>org.springframework.boot</groupId>
940 <artifactId>spring-boot-starter-undertow</artifactId>
941 </dependency>
942 <dependency>
943 <groupId>org.springframework.boot</groupId>
944 <artifactId>spring-boot-devtools</artifactId>
945 <optional>true</optional>
946 </dependency>
947 <dependency>
948 <groupId>com.h2database</groupId>
949 <artifactId>h2</artifactId>
950 </dependency>
951 </dependencies>
952 <properties>
953 <!-- default Spring profiles -->
954 <spring.profiles.active>dev${profile.tls}${profile.no-liquibase}</spring.profiles.active>
955 </properties>
956 </profile>
957 <profile>
958 <id>prod</id>
959 <dependencies>
960 <dependency>
961 <groupId>org.springframework.boot</groupId>
962 <artifactId>spring-boot-starter-undertow</artifactId>
963 </dependency>
964 </dependencies>
965 <build>
966 <plugins>
967 <plugin>
968 <artifactId>maven-clean-plugin</artifactId>
969 <configuration>
970 <filesets>
971 <fileset>
972 <directory>target/classes/static/</directory>
973 </fileset>
974 </filesets>
975 </configuration>
976 </plugin>
977 <plugin>
978 <groupId>org.springframework.boot</groupId>
979 <artifactId>spring-boot-maven-plugin</artifactId>
980 <executions>
981 <execution>
982 <goals>
983 <goal>build-info</goal>
984 </goals>
985 </execution>
986 </executions>
987 </plugin>
988 <plugin>
989 <groupId>com.github.eirslett</groupId>
990 <artifactId>frontend-maven-plugin</artifactId>
991 <executions>
992 <execution>
993 <id>install node and npm</id>
994 <goals>
995 <goal>install-node-and-npm</goal>
996 </goals>
997 <configuration>
998 <nodeVersion>${node.version}</nodeVersion>
999 <npmVersion>${npm.version}</npmVersion>
1000 </configuration>
1001 </execution>
1002 <execution>
1003 <id>npm install</id>
1004 <goals>
1005 <goal>npm</goal>
1006 </goals>
1007 <configuration>
1008 <arguments>install</arguments>
1009 </configuration>
1010 </execution>
1011 <execution>
1012 <id>webpack build test</id>
1013 <goals>
1014 <goal>npm</goal>
1015 </goals>
1016 <phase>test</phase>
1017 <configuration>
1018 <arguments>run webpack:test</arguments>
1019 <npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
1020 </configuration>
1021 </execution>
1022 <execution>
1023 <id>webpack build prod</id>
1024 <goals>
1025 <goal>npm</goal>
1026 </goals>
1027 <phase>generate-resources</phase>
1028 <configuration>
1029 <arguments>run webpack:prod</arguments>
1030 <environmentVariables>
1031 <APP_VERSION>${project.version}</APP_VERSION>
1032 </environmentVariables>
1033 <npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
1034 </configuration>
1035 </execution>
1036 </executions>
1037 </plugin>
1038 <plugin>
1039 <groupId>pl.project13.maven</groupId>
1040 <artifactId>git-commit-id-plugin</artifactId>
1041 </plugin>
1042 </plugins>
1043 </build>
1044 <properties>
1045 <!-- default Spring profiles -->
1046 <spring.profiles.active>prod${profile.swagger}${profile.no-liquibase}</spring.profiles.active>
1047 </properties>
1048 </profile>
1049 <profile>
1050 <id>war</id>
1051 <build>
1052 <plugins>
1053 <plugin>
1054 <groupId>org.apache.maven.plugins</groupId>
1055 <artifactId>maven-war-plugin</artifactId>
1056 </plugin>
1057 </plugins>
1058 </build>
1059 </profile>
1060 <profile>
1061 <!--
1062 Profile for applying IDE-specific configuration.
1063 At the moment it configures MapStruct and Hibernate JPA Metamodel Generator, which you need when working
1064 with DTOs and entity filtering.
1065 -->
1066 <id>IDE</id>
1067 <dependencies>
1068 <dependency>
1069 <groupId>org.mapstruct</groupId>
1070 <artifactId>mapstruct-processor</artifactId>
1071 </dependency>
1072 <dependency>
1073 <groupId>org.hibernate</groupId>
1074 <artifactId>hibernate-jpamodelgen</artifactId>
1075 </dependency>
1076 </dependencies>
1077 </profile>
1078 <profile>
1079 <!-- This is automatically activated when working in Eclipse -->
1080 <id>eclipse</id>
1081 <activation>
1082 <property>
1083 <name>m2e.version</name>
1084 </property>
1085 </activation>
1086 <dependencies>
1087 <!-- The following dependency is added due to issue #9175-->
1088 <dependency>
1089 <groupId>org.springframework.boot</groupId>
1090 <artifactId>spring-boot-starter-undertow</artifactId>
1091 </dependency>
1092 </dependencies>
1093 <build>
1094 <pluginManagement>
1095 <plugins>
1096 <!--
1097 This plugin's configuration is used to store Eclipse m2e settings only.
1098 It has no influence on the Maven build itself.
1099 Remove when the m2e plugin can correctly bind to Maven lifecycle
1100 -->
1101 <plugin>
1102 <groupId>org.eclipse.m2e</groupId>
1103 <artifactId>lifecycle-mapping</artifactId>
1104 <version>${lifecycle-mapping.version}</version>
1105 <configuration>
1106 <lifecycleMappingMetadata>
1107 <pluginExecutions>
1108 <pluginExecution>
1109 <pluginExecutionFilter>
1110 <groupId>org.jacoco</groupId>
1111 <artifactId>
1112 jacoco-maven-plugin
1113 </artifactId>
1114 <versionRange>
1115 ${jacoco-maven-plugin.version}
1116 </versionRange>
1117 <goals>
1118 <goal>prepare-agent</goal>
1119 </goals>
1120 </pluginExecutionFilter>
1121 <action>
1122 <ignore/>
1123 </action>
1124 </pluginExecution>
1125 <pluginExecution>
1126 <pluginExecutionFilter>
1127 <groupId>com.github.eirslett</groupId>
1128 <artifactId>frontend-maven-plugin</artifactId>
1129 <versionRange>${frontend-maven-plugin.version}</versionRange>
1130 <goals>
1131 <goal>install-node-and-npm</goal>
1132 <goal>npm</goal>
1133 </goals>
1134 </pluginExecutionFilter>
1135 <action>
1136 <ignore/>
1137 </action>
1138 </pluginExecution>
1139 </pluginExecutions>
1140 </lifecycleMappingMetadata>
1141 </configuration>
1142 </plugin>
1143 </plugins>
1144 </pluginManagement>
1145 </build>
1146 </profile>
1147 <!-- jhipster-needle-maven-add-profile -->
1148 </profiles>
1149 </project>
File postcss.config.js added (mode: 100644) (index 0000000..a26de7e)
1 module.exports = {
2 plugins: [
3 require('autoprefixer')
4 ]
5 }
File proxy.conf.json added (mode: 100644) (index 0000000..3bfe56a)
1 {
2 "*": {
3 "target": "http://localhost:8080",
4 "secure": false,
5 "loglevel": "debug"
6 }
7 }
File sonar-project.properties added (mode: 100644) (index 0000000..6023e77)
1 sonar.projectKey=honlap
2 sonar.projectName=honlap generated by jhipster
3 sonar.projectVersion=1.0
4
5 sonar.sources=src/main/
6 sonar.host.url=http://localhost:9001
7
8 sonar.tests=src/test/
9 sonar.coverage.jacoco.xmlReportPaths=target/jacoco/test/jacoco.xml,target/jacoco/integrationTest/jacoco.xml
10 sonar.java.codeCoveragePlugin=jacoco
11 sonar.junit.reportPaths=target/test-results/test,target/test-results/integrationTest
12 sonar.testExecutionReportPaths=target/test-results/jest/TESTS-results-sonar.xml
13 sonar.typescript.lcov.reportPaths=target/test-results/lcov.info
14
15 sonar.sourceEncoding=UTF-8
16 sonar.exclusions=src/main/webapp/content/**/*.*, src/main/webapp/i18n/*.js, target/classes/static/**/*.*
17
18 sonar.issue.ignore.multicriteria=S3437,S4502,S4684,UndocumentedApi,BoldAndItalicTagsCheck
19 # Rule https://sonarcloud.io/coding_rules?open=squid%3AS3437&rule_key=squid%3AS3437 is ignored, as a JPA-managed field cannot be transient
20 sonar.issue.ignore.multicriteria.S3437.resourceKey=src/main/java/**/*
21 sonar.issue.ignore.multicriteria.S3437.ruleKey=squid:S3437
22 # 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
23 sonar.issue.ignore.multicriteria.UndocumentedApi.resourceKey=src/main/java/**/*
24 sonar.issue.ignore.multicriteria.UndocumentedApi.ruleKey=squid:UndocumentedApi
25 # Rule https://sonarcloud.io/coding_rules?open=squid%3AS4502&rule_key=squid%3AS4502 is ignored, as for JWT tokens we are not subject to CSRF attack
26 sonar.issue.ignore.multicriteria.S4502.resourceKey=src/main/java/**/*
27 sonar.issue.ignore.multicriteria.S4502.ruleKey=squid:S4502
28 # Rule https://sonarcloud.io/coding_rules?open=squid%3AS4684&rule_key=squid%3AS4684
29 sonar.issue.ignore.multicriteria.S4684.resourceKey=src/main/java/**/*
30 sonar.issue.ignore.multicriteria.S4684.ruleKey=squid:S4684
31 # Rule https://sonarcloud.io/coding_rules?open=Web%3ABoldAndItalicTagsCheck&rule_key=Web%3ABoldAndItalicTagsCheck is ignored. Even if we agree that using the "i" tag is an awful practice, this is what is recommended by http://fontawesome.io/examples/
32 sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.resourceKey=src/main/webapp/app/**/*.*
33 sonar.issue.ignore.multicriteria.BoldAndItalicTagsCheck.ruleKey=Web:BoldAndItalicTagsCheck
File src/main/docker/app.yml added (mode: 100644) (index 0000000..ec96436)
1 version: '2'
2 services:
3 honlap-app:
4 image: honlap
5 environment:
6 - _JAVA_OPTIONS=-Xmx512m -Xms256m
7 - SPRING_PROFILES_ACTIVE=prod,swagger
8 - MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED=true
9 - SPRING_DATASOURCE_URL=jdbc:postgresql://honlap-postgresql:5432/honlap
10 - JHIPSTER_SLEEP=30 # gives time for other services to boot before the application
11 ports:
12 - 8080:8080
13 honlap-postgresql:
14 extends:
15 file: postgresql.yml
16 service: honlap-postgresql
File src/main/docker/grafana/provisioning/dashboards/JVM.json added (mode: 100644) (index 0000000..5104abc)
1 {
2 "annotations": {
3 "list": [
4 {
5 "builtIn": 1,
6 "datasource": "-- Grafana --",
7 "enable": true,
8 "hide": true,
9 "iconColor": "rgba(0, 211, 255, 1)",
10 "limit": 100,
11 "name": "Annotations & Alerts",
12 "showIn": 0,
13 "type": "dashboard"
14 },
15 {
16 "datasource": "Prometheus",
17 "enable": true,
18 "expr": "resets(process_uptime_seconds{application=\"$application\", instance=\"$instance\"}[1m]) > 0",
19 "iconColor": "rgba(255, 96, 96, 1)",
20 "name": "Restart Detection",
21 "showIn": 0,
22 "step": "1m",
23 "tagKeys": "restart-tag",
24 "textFormat": "uptime reset",
25 "titleFormat": "Restart"
26 }
27 ]
28 },
29 "description": "Dashboard for Micrometer instrumented applications (Java, Spring Boot, Micronaut)",
30 "editable": true,
31 "gnetId": 4701,
32 "graphTooltip": 1,
33 "iteration": 1553765841423,
34 "links": [],
35 "panels": [
36 {
37 "content": "\n# Acknowledgments\n\nThank you to [Michael Weirauch](https://twitter.com/emwexx) for creating this dashboard: see original JVM (Micrometer) dashboard at [https://grafana.com/dashboards/4701](https://grafana.com/dashboards/4701)\n\n\n\n",
38 "gridPos": {
39 "h": 3,
40 "w": 24,
41 "x": 0,
42 "y": 0
43 },
44 "id": 141,
45 "links": [],
46 "mode": "markdown",
47 "timeFrom": null,
48 "timeShift": null,
49 "title": "Acknowledgments",
50 "type": "text"
51 },
52 {
53 "collapsed": false,
54 "gridPos": {
55 "h": 1,
56 "w": 24,
57 "x": 0,
58 "y": 3
59 },
60 "id": 125,
61 "panels": [],
62 "repeat": null,
63 "title": "Quick Facts",
64 "type": "row"
65 },
66 {
67 "cacheTimeout": null,
68 "colorBackground": false,
69 "colorValue": true,
70 "colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
71 "datasource": "Prometheus",
72 "decimals": 1,
73 "editable": true,
74 "error": false,
75 "format": "s",
76 "gauge": {
77 "maxValue": 100,
78 "minValue": 0,
79 "show": false,
80 "thresholdLabels": false,
81 "thresholdMarkers": true
82 },
83 "gridPos": {
84 "h": 3,
85 "w": 6,
86 "x": 0,
87 "y": 4
88 },
89 "height": "",
90 "id": 63,
91 "interval": null,
92 "links": [],
93 "mappingType": 1,
94 "mappingTypes": [
95 {
96 "name": "value to text",
97 "value": 1
98 },
99 {
100 "name": "range to text",
101 "value": 2
102 }
103 ],
104 "maxDataPoints": 100,
105 "nullPointMode": "connected",
106 "nullText": null,
107 "postfix": "",
108 "postfixFontSize": "50%",
109 "prefix": "",
110 "prefixFontSize": "70%",
111 "rangeMaps": [
112 {
113 "from": "null",
114 "text": "N/A",
115 "to": "null"
116 }
117 ],
118 "sparkline": {
119 "fillColor": "rgba(31, 118, 189, 0.18)",
120 "full": false,
121 "lineColor": "rgb(31, 120, 193)",
122 "show": false
123 },
124 "tableColumn": "",
125 "targets": [
126 {
127 "expr": "process_uptime_seconds{application=\"$application\", instance=\"$instance\"}",
128 "format": "time_series",
129 "intervalFactor": 2,
130 "legendFormat": "",
131 "metric": "",
132 "refId": "A",
133 "step": 14400
134 }
135 ],
136 "thresholds": "",
137 "title": "Uptime",
138 "type": "singlestat",
139 "valueFontSize": "80%",
140 "valueMaps": [
141 {
142 "op": "=",
143 "text": "N/A",
144 "value": "null"
145 }
146 ],
147 "valueName": "current"
148 },
149 {
150 "cacheTimeout": null,
151 "colorBackground": false,
152 "colorValue": true,
153 "colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
154 "datasource": "Prometheus",
155 "decimals": null,
156 "editable": true,
157 "error": false,
158 "format": "dateTimeAsIso",
159 "gauge": {
160 "maxValue": 100,
161 "minValue": 0,
162 "show": false,
163 "thresholdLabels": false,
164 "thresholdMarkers": true
165 },
166 "gridPos": {
167 "h": 3,
168 "w": 6,
169 "x": 6,
170 "y": 4
171 },
172 "height": "",
173 "id": 92,
174 "interval": null,
175 "links": [],
176 "mappingType": 1,
177 "mappingTypes": [
178 {
179 "name": "value to text",
180 "value": 1
181 },
182 {
183 "name": "range to text",
184 "value": 2
185 }
186 ],
187 "maxDataPoints": 100,
188 "nullPointMode": "connected",
189 "nullText": null,
190 "postfix": "",
191 "postfixFontSize": "50%",
192 "prefix": "",
193 "prefixFontSize": "70%",
194 "rangeMaps": [
195 {
196 "from": "null",
197 "text": "N/A",
198 "to": "null"
199 }
200 ],
201 "sparkline": {
202 "fillColor": "rgba(31, 118, 189, 0.18)",
203 "full": false,
204 "lineColor": "rgb(31, 120, 193)",
205 "show": false
206 },
207 "tableColumn": "",
208 "targets": [
209 {
210 "expr": "process_start_time_seconds{application=\"$application\", instance=\"$instance\"}*1000",
211 "format": "time_series",
212 "intervalFactor": 2,
213 "legendFormat": "",
214 "metric": "",
215 "refId": "A",
216 "step": 14400
217 }
218 ],
219 "thresholds": "",
220 "title": "Start time",
221 "type": "singlestat",
222 "valueFontSize": "70%",
223 "valueMaps": [
224 {
225 "op": "=",
226 "text": "N/A",
227 "value": "null"
228 }
229 ],
230 "valueName": "current"
231 },
232 {
233 "cacheTimeout": null,
234 "colorBackground": false,
235 "colorValue": true,
236 "colors": ["rgba(50, 172, 45, 0.97)", "rgba(237, 129, 40, 0.89)", "rgba(245, 54, 54, 0.9)"],
237 "datasource": "Prometheus",
238 "decimals": 2,
239 "editable": true,
240 "error": false,
241 "format": "percent",
242 "gauge": {
243 "maxValue": 100,
244 "minValue": 0,
245 "show": false,
246 "thresholdLabels": false,
247 "thresholdMarkers": true
248 },
249 "gridPos": {
250 "h": 3,
251 "w": 6,
252 "x": 12,
253 "y": 4
254 },
255 "id": 65,
256 "interval": null,
257 "links": [],
258 "mappingType": 1,
259 "mappingTypes": [
260 {
261 "name": "value to text",
262 "value": 1
263 },
264 {
265 "name": "range to text",
266 "value": 2
267 }
268 ],
269 "maxDataPoints": 100,
270 "nullPointMode": "connected",
271 "nullText": null,
272 "postfix": "",
273 "postfixFontSize": "50%",
274 "prefix": "",
275 "prefixFontSize": "70%",
276 "rangeMaps": [
277 {
278 "from": "null",
279 "text": "N/A",
280 "to": "null"
281 }
282 ],
283 "sparkline": {
284 "fillColor": "rgba(31, 118, 189, 0.18)",
285 "full": false,
286 "lineColor": "rgb(31, 120, 193)",
287 "show": false
288 },
289 "tableColumn": "",
290 "targets": [
291 {
292 "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})*100/sum(jvm_memory_max_bytes{application=\"$application\",instance=\"$instance\", area=\"heap\"})",
293 "format": "time_series",
294 "intervalFactor": 2,
295 "legendFormat": "",
296 "refId": "A",
297 "step": 14400
298 }
299 ],
300 "thresholds": "70,90",
301 "title": "Heap used",
302 "type": "singlestat",
303 "valueFontSize": "80%",
304 "valueMaps": [
305 {
306 "op": "=",
307 "text": "N/A",
308 "value": "null"
309 }
310 ],
311 "valueName": "current"
312 },
313 {
314 "cacheTimeout": null,
315 "colorBackground": false,
316 "colorValue": true,
317 "colors": ["rgba(50, 172, 45, 0.97)", "rgba(237, 129, 40, 0.89)", "rgba(245, 54, 54, 0.9)"],
318 "datasource": "Prometheus",
319 "decimals": 2,
320 "editable": true,
321 "error": false,
322 "format": "percent",
323 "gauge": {
324 "maxValue": 100,
325 "minValue": 0,
326 "show": false,
327 "thresholdLabels": false,
328 "thresholdMarkers": true
329 },
330 "gridPos": {
331 "h": 3,
332 "w": 6,
333 "x": 18,
334 "y": 4
335 },
336 "id": 75,
337 "interval": null,
338 "links": [],
339 "mappingType": 2,
340 "mappingTypes": [
341 {
342 "name": "value to text",
343 "value": 1
344 },
345 {
346 "name": "range to text",
347 "value": 2
348 }
349 ],
350 "maxDataPoints": 100,
351 "nullPointMode": "connected",
352 "nullText": null,
353 "postfix": "",
354 "postfixFontSize": "50%",
355 "prefix": "",
356 "prefixFontSize": "70%",
357 "rangeMaps": [
358 {
359 "from": "null",
360 "text": "N/A",
361 "to": "null"
362 },
363 {
364 "from": "-99999999999999999999999999999999",
365 "text": "N/A",
366 "to": "0"
367 }
368 ],
369 "sparkline": {
370 "fillColor": "rgba(31, 118, 189, 0.18)",
371 "full": false,
372 "lineColor": "rgb(31, 120, 193)",
373 "show": false
374 },
375 "tableColumn": "",
376 "targets": [
377 {
378 "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})*100/sum(jvm_memory_max_bytes{application=\"$application\",instance=\"$instance\", area=\"nonheap\"})",
379 "format": "time_series",
380 "intervalFactor": 2,
381 "legendFormat": "",
382 "refId": "A",
383 "step": 14400
384 }
385 ],
386 "thresholds": "70,90",
387 "title": "Non-Heap used",
388 "type": "singlestat",
389 "valueFontSize": "80%",
390 "valueMaps": [
391 {
392 "op": "=",
393 "text": "N/A",
394 "value": "null"
395 },
396 {
397 "op": "=",
398 "text": "x",
399 "value": ""
400 }
401 ],
402 "valueName": "current"
403 },
404 {
405 "collapsed": false,
406 "gridPos": {
407 "h": 1,
408 "w": 24,
409 "x": 0,
410 "y": 7
411 },
412 "id": 126,
413 "panels": [],
414 "repeat": null,
415 "title": "I/O Overview",
416 "type": "row"
417 },
418 {
419 "aliasColors": {},
420 "bars": false,
421 "dashLength": 10,
422 "dashes": false,
423 "datasource": "Prometheus",
424 "fill": 1,
425 "gridPos": {
426 "h": 7,
427 "w": 8,
428 "x": 0,
429 "y": 8
430 },
431 "id": 111,
432 "legend": {
433 "avg": false,
434 "current": true,
435 "max": false,
436 "min": false,
437 "show": true,
438 "total": false,
439 "values": true
440 },
441 "lines": true,
442 "linewidth": 1,
443 "links": [],
444 "nullPointMode": "null",
445 "paceLength": 10,
446 "percentage": false,
447 "pointradius": 5,
448 "points": false,
449 "renderer": "flot",
450 "seriesOverrides": [],
451 "spaceLength": 10,
452 "stack": false,
453 "steppedLine": false,
454 "targets": [
455 {
456 "expr": "sum(rate(http_server_requests_seconds_count{application=\"$application\", instance=\"$instance\"}[1m]))",
457 "format": "time_series",
458 "intervalFactor": 1,
459 "legendFormat": "HTTP",
460 "refId": "A"
461 }
462 ],
463 "thresholds": [],
464 "timeFrom": null,
465 "timeRegions": [],
466 "timeShift": null,
467 "title": "Rate",
468 "tooltip": {
469 "shared": true,
470 "sort": 0,
471 "value_type": "individual"
472 },
473 "type": "graph",
474 "xaxis": {
475 "buckets": null,
476 "mode": "time",
477 "name": null,
478 "show": true,
479 "values": []
480 },
481 "yaxes": [
482 {
483 "decimals": null,
484 "format": "ops",
485 "label": null,
486 "logBase": 1,
487 "max": null,
488 "min": "0",
489 "show": true
490 },
491 {
492 "format": "short",
493 "label": null,
494 "logBase": 1,
495 "max": null,
496 "min": null,
497 "show": true
498 }
499 ],
500 "yaxis": {
501 "align": false,
502 "alignLevel": null
503 }
504 },
505 {
506 "aliasColors": {
507 "HTTP": "#890f02",
508 "HTTP - 5xx": "#bf1b00"
509 },
510 "bars": false,
511 "dashLength": 10,
512 "dashes": false,
513 "datasource": "Prometheus",
514 "fill": 1,
515 "gridPos": {
516 "h": 7,
517 "w": 8,
518 "x": 8,
519 "y": 8
520 },
521 "id": 112,
522 "legend": {
523 "avg": false,
524 "current": true,
525 "max": false,
526 "min": false,
527 "show": true,
528 "total": false,
529 "values": true
530 },
531 "lines": true,
532 "linewidth": 1,
533 "links": [],
534 "nullPointMode": "null",
535 "paceLength": 10,
536 "percentage": false,
537 "pointradius": 5,
538 "points": false,
539 "renderer": "flot",
540 "seriesOverrides": [],
541 "spaceLength": 10,
542 "stack": false,
543 "steppedLine": false,
544 "targets": [
545 {
546 "expr": "sum(rate(http_server_requests_seconds_count{application=\"$application\", instance=\"$instance\", status=~\"5..\"}[1m]))",
547 "format": "time_series",
548 "intervalFactor": 1,
549 "legendFormat": "HTTP - 5xx",
550 "refId": "A"
551 }
552 ],
553 "thresholds": [],
554 "timeFrom": null,
555 "timeRegions": [],
556 "timeShift": null,
557 "title": "Errors",
558 "tooltip": {
559 "shared": true,
560 "sort": 0,
561 "value_type": "individual"
562 },
563 "type": "graph",
564 "xaxis": {
565 "buckets": null,
566 "mode": "time",
567 "name": null,
568 "show": true,
569 "values": []
570 },
571 "yaxes": [
572 {
573 "decimals": null,
574 "format": "ops",
575 "label": null,
576 "logBase": 1,
577 "max": null,
578 "min": "0",
579 "show": true
580 },
581 {
582 "format": "short",
583 "label": null,
584 "logBase": 1,
585 "max": null,
586 "min": null,
587 "show": true
588 }
589 ],
590 "yaxis": {
591 "align": false,
592 "alignLevel": null
593 }
594 },
595 {
596 "aliasColors": {},
597 "bars": false,
598 "dashLength": 10,
599 "dashes": false,
600 "datasource": "Prometheus",
601 "fill": 1,
602 "gridPos": {
603 "h": 7,
604 "w": 8,
605 "x": 16,
606 "y": 8
607 },
608 "id": 113,
609 "legend": {
610 "avg": false,
611 "current": true,
612 "max": false,
613 "min": false,
614 "show": true,
615 "total": false,
616 "values": true
617 },
618 "lines": true,
619 "linewidth": 1,
620 "links": [],
621 "nullPointMode": "null",
622 "paceLength": 10,
623 "percentage": false,
624 "pointradius": 5,
625 "points": false,
626 "renderer": "flot",
627 "seriesOverrides": [],
628 "spaceLength": 10,
629 "stack": false,
630 "steppedLine": false,
631 "targets": [
632 {
633 "expr": "sum(rate(http_server_requests_seconds_sum{application=\"$application\", instance=\"$instance\", status!~\"5..\"}[1m]))/sum(rate(http_server_requests_seconds_count{application=\"$application\", instance=\"$instance\", status!~\"5..\"}[1m]))",
634 "format": "time_series",
635 "hide": false,
636 "intervalFactor": 1,
637 "legendFormat": "HTTP - AVG",
638 "refId": "A"
639 },
640 {
641 "expr": "max(http_server_requests_seconds_max{application=\"$application\", instance=\"$instance\", status!~\"5..\"})",
642 "format": "time_series",
643 "hide": false,
644 "intervalFactor": 1,
645 "legendFormat": "HTTP - MAX",
646 "refId": "B"
647 }
648 ],
649 "thresholds": [],
650 "timeFrom": null,
651 "timeRegions": [],
652 "timeShift": null,
653 "title": "Duration",
654 "tooltip": {
655 "shared": true,
656 "sort": 0,
657 "value_type": "individual"
658 },
659 "type": "graph",
660 "xaxis": {
661 "buckets": null,
662 "mode": "time",
663 "name": null,
664 "show": true,
665 "values": []
666 },
667 "yaxes": [
668 {
669 "format": "s",
670 "label": null,
671 "logBase": 1,
672 "max": null,
673 "min": "0",
674 "show": true
675 },
676 {
677 "format": "short",
678 "label": null,
679 "logBase": 1,
680 "max": null,
681 "min": null,
682 "show": true
683 }
684 ],
685 "yaxis": {
686 "align": false,
687 "alignLevel": null
688 }
689 },
690 {
691 "collapsed": false,
692 "gridPos": {
693 "h": 1,
694 "w": 24,
695 "x": 0,
696 "y": 15
697 },
698 "id": 127,
699 "panels": [],
700 "repeat": null,
701 "title": "JVM Memory",
702 "type": "row"
703 },
704 {
705 "aliasColors": {},
706 "bars": false,
707 "dashLength": 10,
708 "dashes": false,
709 "datasource": "Prometheus",
710 "editable": true,
711 "error": false,
712 "fill": 1,
713 "grid": {
714 "leftLogBase": 1,
715 "leftMax": null,
716 "leftMin": null,
717 "rightLogBase": 1,
718 "rightMax": null,
719 "rightMin": null
720 },
721 "gridPos": {
722 "h": 7,
723 "w": 8,
724 "x": 0,
725 "y": 16
726 },
727 "id": 24,
728 "legend": {
729 "avg": false,
730 "current": true,
731 "max": true,
732 "min": false,
733 "show": true,
734 "total": false,
735 "values": true
736 },
737 "lines": true,
738 "linewidth": 1,
739 "links": [],
740 "nullPointMode": "null",
741 "paceLength": 10,
742 "percentage": false,
743 "pointradius": 5,
744 "points": false,
745 "renderer": "flot",
746 "seriesOverrides": [],
747 "spaceLength": 10,
748 "stack": false,
749 "steppedLine": false,
750 "targets": [
751 {
752 "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})",
753 "format": "time_series",
754 "intervalFactor": 2,
755 "legendFormat": "used",
756 "metric": "",
757 "refId": "A",
758 "step": 2400
759 },
760 {
761 "expr": "sum(jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})",
762 "format": "time_series",
763 "intervalFactor": 2,
764 "legendFormat": "committed",
765 "refId": "B",
766 "step": 2400
767 },
768 {
769 "expr": "sum(jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"})",
770 "format": "time_series",
771 "intervalFactor": 2,
772 "legendFormat": "max",
773 "refId": "C",
774 "step": 2400
775 }
776 ],
777 "thresholds": [],
778 "timeFrom": null,
779 "timeRegions": [],
780 "timeShift": null,
781 "title": "JVM Heap",
782 "tooltip": {
783 "msResolution": false,
784 "shared": true,
785 "sort": 0,
786 "value_type": "cumulative"
787 },
788 "type": "graph",
789 "x-axis": true,
790 "xaxis": {
791 "buckets": null,
792 "mode": "time",
793 "name": null,
794 "show": true,
795 "values": []
796 },
797 "y-axis": true,
798 "y_formats": ["mbytes", "short"],
799 "yaxes": [
800 {
801 "format": "bytes",
802 "label": null,
803 "logBase": 1,
804 "max": null,
805 "min": 0,
806 "show": true
807 },
808 {
809 "format": "short",
810 "label": null,
811 "logBase": 1,
812 "max": null,
813 "min": null,
814 "show": true
815 }
816 ],
817 "yaxis": {
818 "align": false,
819 "alignLevel": null
820 }
821 },
822 {
823 "aliasColors": {},
824 "bars": false,
825 "dashLength": 10,
826 "dashes": false,
827 "datasource": "Prometheus",
828 "editable": true,
829 "error": false,
830 "fill": 1,
831 "grid": {
832 "leftLogBase": 1,
833 "leftMax": null,
834 "leftMin": null,
835 "rightLogBase": 1,
836 "rightMax": null,
837 "rightMin": null
838 },
839 "gridPos": {
840 "h": 7,
841 "w": 8,
842 "x": 8,
843 "y": 16
844 },
845 "id": 25,
846 "legend": {
847 "avg": false,
848 "current": true,
849 "max": true,
850 "min": false,
851 "show": true,
852 "total": false,
853 "values": true
854 },
855 "lines": true,
856 "linewidth": 1,
857 "links": [],
858 "nullPointMode": "null",
859 "paceLength": 10,
860 "percentage": false,
861 "pointradius": 5,
862 "points": false,
863 "renderer": "flot",
864 "seriesOverrides": [],
865 "spaceLength": 10,
866 "stack": false,
867 "steppedLine": false,
868 "targets": [
869 {
870 "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})",
871 "format": "time_series",
872 "interval": "",
873 "intervalFactor": 2,
874 "legendFormat": "used",
875 "metric": "",
876 "refId": "A",
877 "step": 2400
878 },
879 {
880 "expr": "sum(jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})",
881 "format": "time_series",
882 "intervalFactor": 2,
883 "legendFormat": "committed",
884 "refId": "B",
885 "step": 2400
886 },
887 {
888 "expr": "sum(jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"})",
889 "format": "time_series",
890 "intervalFactor": 2,
891 "legendFormat": "max",
892 "refId": "C",
893 "step": 2400
894 }
895 ],
896 "thresholds": [],
897 "timeFrom": null,
898 "timeRegions": [],
899 "timeShift": null,
900 "title": "JVM Non-Heap",
901 "tooltip": {
902 "msResolution": false,
903 "shared": true,
904 "sort": 0,
905 "value_type": "cumulative"
906 },
907 "type": "graph",
908 "x-axis": true,
909 "xaxis": {
910 "buckets": null,
911 "mode": "time",
912 "name": null,
913 "show": true,
914 "values": []
915 },
916 "y-axis": true,
917 "y_formats": ["mbytes", "short"],
918 "yaxes": [
919 {
920 "format": "bytes",
921 "label": null,
922 "logBase": 1,
923 "max": null,
924 "min": 0,
925 "show": true
926 },
927 {
928 "format": "short",
929 "label": null,
930 "logBase": 1,
931 "max": null,
932 "min": null,
933 "show": true
934 }
935 ],
936 "yaxis": {
937 "align": false,
938 "alignLevel": null
939 }
940 },
941 {
942 "aliasColors": {},
943 "bars": false,
944 "dashLength": 10,
945 "dashes": false,
946 "datasource": "Prometheus",
947 "editable": true,
948 "error": false,
949 "fill": 1,
950 "grid": {
951 "leftLogBase": 1,
952 "leftMax": null,
953 "leftMin": null,
954 "rightLogBase": 1,
955 "rightMax": null,
956 "rightMin": null
957 },
958 "gridPos": {
959 "h": 7,
960 "w": 8,
961 "x": 16,
962 "y": 16
963 },
964 "id": 26,
965 "legend": {
966 "alignAsTable": false,
967 "avg": false,
968 "current": true,
969 "max": true,
970 "min": false,
971 "show": true,
972 "total": false,
973 "values": true
974 },
975 "lines": true,
976 "linewidth": 1,
977 "links": [],
978 "nullPointMode": "null",
979 "paceLength": 10,
980 "percentage": false,
981 "pointradius": 5,
982 "points": false,
983 "renderer": "flot",
984 "seriesOverrides": [],
985 "spaceLength": 10,
986 "stack": false,
987 "steppedLine": false,
988 "targets": [
989 {
990 "expr": "sum(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\"})",
991 "format": "time_series",
992 "intervalFactor": 2,
993 "legendFormat": "used",
994 "metric": "",
995 "refId": "A",
996 "step": 2400
997 },
998 {
999 "expr": "sum(jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\"})",
1000 "format": "time_series",
1001 "intervalFactor": 2,
1002 "legendFormat": "committed",
1003 "refId": "B",
1004 "step": 2400
1005 },
1006 {
1007 "expr": "sum(jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\"})",
1008 "format": "time_series",
1009 "intervalFactor": 2,
1010 "legendFormat": "max",
1011 "refId": "C",
1012 "step": 2400
1013 },
1014 {
1015 "expr": "process_memory_vss_bytes{application=\"$application\", instance=\"$instance\"}",
1016 "format": "time_series",
1017 "hide": true,
1018 "intervalFactor": 2,
1019 "legendFormat": "vss",
1020 "metric": "",
1021 "refId": "D",
1022 "step": 2400
1023 },
1024 {
1025 "expr": "process_memory_rss_bytes{application=\"$application\", instance=\"$instance\"}",
1026 "format": "time_series",
1027 "intervalFactor": 2,
1028 "legendFormat": "rss",
1029 "refId": "E",
1030 "step": 2400
1031 },
1032 {
1033 "expr": "process_memory_pss_bytes{application=\"$application\", instance=\"$instance\"}",
1034 "format": "time_series",
1035 "intervalFactor": 2,
1036 "legendFormat": "pss",
1037 "refId": "F",
1038 "step": 2400
1039 },
1040 {
1041 "expr": "process_memory_swap_bytes{application=\"$application\", instance=\"$instance\"}",
1042 "format": "time_series",
1043 "intervalFactor": 2,
1044 "legendFormat": "swap",
1045 "refId": "G",
1046 "step": 2400
1047 },
1048 {
1049 "expr": "process_memory_swappss_bytes{application=\"$application\", instance=\"$instance\"}",
1050 "format": "time_series",
1051 "intervalFactor": 2,
1052 "legendFormat": "swappss",
1053 "refId": "H",
1054 "step": 2400
1055 },
1056 {
1057 "expr": "process_memory_pss_bytes{application=\"$application\", instance=\"$instance\"} + process_memory_swap_bytes{application=\"$application\", instance=\"$instance\"}",
1058 "format": "time_series",
1059 "intervalFactor": 2,
1060 "legendFormat": "phys (pss+swap)",
1061 "refId": "I",
1062 "step": 2400
1063 }
1064 ],
1065 "thresholds": [],
1066 "timeFrom": null,
1067 "timeRegions": [],
1068 "timeShift": null,
1069 "title": "JVM Total",
1070 "tooltip": {
1071 "msResolution": false,
1072 "shared": true,
1073 "sort": 0,
1074 "value_type": "cumulative"
1075 },
1076 "type": "graph",
1077 "x-axis": true,
1078 "xaxis": {
1079 "buckets": null,
1080 "mode": "time",
1081 "name": null,
1082 "show": true,
1083 "values": []
1084 },
1085 "y-axis": true,
1086 "y_formats": ["mbytes", "short"],
1087 "yaxes": [
1088 {
1089 "format": "bytes",
1090 "label": "",
1091 "logBase": 1,
1092 "max": null,
1093 "min": 0,
1094 "show": true
1095 },
1096 {
1097 "format": "short",
1098 "label": null,
1099 "logBase": 1,
1100 "max": null,
1101 "min": null,
1102 "show": true
1103 }
1104 ],
1105 "yaxis": {
1106 "align": false,
1107 "alignLevel": null
1108 }
1109 },
1110 {
1111 "collapsed": false,
1112 "gridPos": {
1113 "h": 1,
1114 "w": 24,
1115 "x": 0,
1116 "y": 23
1117 },
1118 "id": 128,
1119 "panels": [],
1120 "repeat": null,
1121 "title": "JVM Misc",
1122 "type": "row"
1123 },
1124 {
1125 "aliasColors": {},
1126 "bars": false,
1127 "dashLength": 10,
1128 "dashes": false,
1129 "datasource": "Prometheus",
1130 "editable": true,
1131 "error": false,
1132 "fill": 1,
1133 "grid": {
1134 "leftLogBase": 1,
1135 "leftMax": null,
1136 "leftMin": null,
1137 "rightLogBase": 1,
1138 "rightMax": null,
1139 "rightMin": null
1140 },
1141 "gridPos": {
1142 "h": 7,
1143 "w": 6,
1144 "x": 0,
1145 "y": 24
1146 },
1147 "id": 106,
1148 "legend": {
1149 "avg": false,
1150 "current": true,
1151 "max": true,
1152 "min": false,
1153 "show": true,
1154 "total": false,
1155 "values": true
1156 },
1157 "lines": true,
1158 "linewidth": 1,
1159 "links": [],
1160 "nullPointMode": "null",
1161 "paceLength": 10,
1162 "percentage": false,
1163 "pointradius": 5,
1164 "points": false,
1165 "renderer": "flot",
1166 "seriesOverrides": [],
1167 "spaceLength": 10,
1168 "stack": false,
1169 "steppedLine": false,
1170 "targets": [
1171 {
1172 "expr": "system_cpu_usage{application=\"$application\", instance=\"$instance\"}",
1173 "format": "time_series",
1174 "hide": false,
1175 "intervalFactor": 1,
1176 "legendFormat": "system",
1177 "metric": "",
1178 "refId": "A",
1179 "step": 2400
1180 },
1181 {
1182 "expr": "process_cpu_usage{application=\"$application\", instance=\"$instance\"}",
1183 "format": "time_series",
1184 "hide": false,
1185 "intervalFactor": 1,
1186 "legendFormat": "process",
1187 "refId": "B"
1188 },
1189 {
1190 "expr": "avg_over_time(process_cpu_usage{application=\"$application\", instance=\"$instance\"}[1h])",
1191 "format": "time_series",
1192 "hide": false,
1193 "intervalFactor": 1,
1194 "legendFormat": "process-1h",
1195 "refId": "C"
1196 }
1197 ],
1198 "thresholds": [],
1199 "timeFrom": null,
1200 "timeRegions": [],
1201 "timeShift": null,
1202 "title": "CPU",
1203 "tooltip": {
1204 "msResolution": false,
1205 "shared": true,
1206 "sort": 0,
1207 "value_type": "cumulative"
1208 },
1209 "type": "graph",
1210 "x-axis": true,
1211 "xaxis": {
1212 "buckets": null,
1213 "mode": "time",
1214 "name": null,
1215 "show": true,
1216 "values": []
1217 },
1218 "y-axis": true,
1219 "y_formats": ["short", "short"],
1220 "yaxes": [
1221 {
1222 "decimals": 1,
1223 "format": "percentunit",
1224 "label": "",
1225 "logBase": 1,
1226 "max": "1",
1227 "min": 0,
1228 "show": true
1229 },
1230 {
1231 "format": "short",
1232 "label": null,
1233 "logBase": 1,
1234 "max": null,
1235 "min": null,
1236 "show": true
1237 }
1238 ],
1239 "yaxis": {
1240 "align": false,
1241 "alignLevel": null
1242 }
1243 },
1244 {
1245 "aliasColors": {},
1246 "bars": false,
1247 "dashLength": 10,
1248 "dashes": false,
1249 "datasource": "Prometheus",
1250 "editable": true,
1251 "error": false,
1252 "fill": 1,
1253 "grid": {
1254 "leftLogBase": 1,
1255 "leftMax": null,
1256 "leftMin": null,
1257 "rightLogBase": 1,
1258 "rightMax": null,
1259 "rightMin": null
1260 },
1261 "gridPos": {
1262 "h": 7,
1263 "w": 6,
1264 "x": 6,
1265 "y": 24
1266 },
1267 "id": 93,
1268 "legend": {
1269 "avg": false,
1270 "current": true,
1271 "max": true,
1272 "min": false,
1273 "show": true,
1274 "total": false,
1275 "values": true
1276 },
1277 "lines": true,
1278 "linewidth": 1,
1279 "links": [],
1280 "nullPointMode": "null",
1281 "paceLength": 10,
1282 "percentage": false,
1283 "pointradius": 5,
1284 "points": false,
1285 "renderer": "flot",
1286 "seriesOverrides": [],
1287 "spaceLength": 10,
1288 "stack": false,
1289 "steppedLine": false,
1290 "targets": [
1291 {
1292 "expr": "system_load_average_1m{application=\"$application\", instance=\"$instance\"}",
1293 "format": "time_series",
1294 "intervalFactor": 2,
1295 "legendFormat": "system-1m",
1296 "metric": "",
1297 "refId": "A",
1298 "step": 2400
1299 },
1300 {
1301 "expr": "",
1302 "format": "time_series",
1303 "intervalFactor": 2,
1304 "refId": "B"
1305 },
1306 {
1307 "expr": "system_cpu_count{application=\"$application\", instance=\"$instance\"}",
1308 "format": "time_series",
1309 "intervalFactor": 2,
1310 "legendFormat": "cpu",
1311 "refId": "C"
1312 }
1313 ],
1314 "thresholds": [],
1315 "timeFrom": null,
1316 "timeRegions": [],
1317 "timeShift": null,
1318 "title": "Load",
1319 "tooltip": {
1320 "msResolution": false,
1321 "shared": true,
1322 "sort": 0,
1323 "value_type": "cumulative"
1324 },
1325 "type": "graph",
1326 "x-axis": true,
1327 "xaxis": {
1328 "buckets": null,
1329 "mode": "time",
1330 "name": null,
1331 "show": true,
1332 "values": []
1333 },
1334 "y-axis": true,
1335 "y_formats": ["short", "short"],
1336 "yaxes": [
1337 {
1338 "decimals": 1,
1339 "format": "short",
1340 "label": "",
1341 "logBase": 1,
1342 "max": null,
1343 "min": 0,
1344 "show": true
1345 },
1346 {
1347 "format": "short",
1348 "label": null,
1349 "logBase": 1,
1350 "max": null,
1351 "min": null,
1352 "show": true
1353 }
1354 ],
1355 "yaxis": {
1356 "align": false,
1357 "alignLevel": null
1358 }
1359 },
1360 {
1361 "aliasColors": {},
1362 "bars": false,
1363 "dashLength": 10,
1364 "dashes": false,
1365 "datasource": "Prometheus",
1366 "editable": true,
1367 "error": false,
1368 "fill": 1,
1369 "grid": {
1370 "leftLogBase": 1,
1371 "leftMax": null,
1372 "leftMin": null,
1373 "rightLogBase": 1,
1374 "rightMax": null,
1375 "rightMin": null
1376 },
1377 "gridPos": {
1378 "h": 7,
1379 "w": 6,
1380 "x": 12,
1381 "y": 24
1382 },
1383 "id": 32,
1384 "legend": {
1385 "avg": false,
1386 "current": true,
1387 "max": true,
1388 "min": false,
1389 "show": true,
1390 "total": false,
1391 "values": true
1392 },
1393 "lines": true,
1394 "linewidth": 1,
1395 "links": [],
1396 "nullPointMode": "null",
1397 "paceLength": 10,
1398 "percentage": false,
1399 "pointradius": 5,
1400 "points": false,
1401 "renderer": "flot",
1402 "seriesOverrides": [],
1403 "spaceLength": 10,
1404 "stack": false,
1405 "steppedLine": false,
1406 "targets": [
1407 {
1408 "expr": "jvm_threads_live{application=\"$application\", instance=\"$instance\"} or jvm_threads_live_threads{application=\"$application\", instance=\"$instance\"}",
1409 "format": "time_series",
1410 "intervalFactor": 2,
1411 "legendFormat": "live",
1412 "metric": "",
1413 "refId": "A",
1414 "step": 2400
1415 },
1416 {
1417 "expr": "jvm_threads_daemon{application=\"$application\", instance=\"$instance\"} or jvm_threads_daemon_threads{application=\"$application\", instance=\"$instance\"}",
1418 "format": "time_series",
1419 "intervalFactor": 2,
1420 "legendFormat": "daemon",
1421 "metric": "",
1422 "refId": "B",
1423 "step": 2400
1424 },
1425 {
1426 "expr": "jvm_threads_peak{application=\"$application\", instance=\"$instance\"} or jvm_threads_peak_threads{application=\"$application\", instance=\"$instance\"}",
1427 "format": "time_series",
1428 "intervalFactor": 2,
1429 "legendFormat": "peak",
1430 "refId": "C",
1431 "step": 2400
1432 },
1433 {
1434 "expr": "process_threads{application=\"$application\", instance=\"$instance\"}",
1435 "format": "time_series",
1436 "interval": "",
1437 "intervalFactor": 2,
1438 "legendFormat": "process",
1439 "refId": "D",
1440 "step": 2400
1441 }
1442 ],
1443 "thresholds": [],
1444 "timeFrom": null,
1445 "timeRegions": [],
1446 "timeShift": null,
1447 "title": "Threads",
1448 "tooltip": {
1449 "msResolution": false,
1450 "shared": true,
1451 "sort": 0,
1452 "value_type": "cumulative"
1453 },
1454 "type": "graph",
1455 "x-axis": true,
1456 "xaxis": {
1457 "buckets": null,
1458 "mode": "time",
1459 "name": null,
1460 "show": true,
1461 "values": []
1462 },
1463 "y-axis": true,
1464 "y_formats": ["short", "short"],
1465 "yaxes": [
1466 {
1467 "decimals": 0,
1468 "format": "short",
1469 "label": null,
1470 "logBase": 1,
1471 "max": null,
1472 "min": 0,
1473 "show": true
1474 },
1475 {
1476 "format": "short",
1477 "label": null,
1478 "logBase": 1,
1479 "max": null,
1480 "min": null,
1481 "show": true
1482 }
1483 ],
1484 "yaxis": {
1485 "align": false,
1486 "alignLevel": null
1487 }
1488 },
1489 {
1490 "aliasColors": {
1491 "blocked": "#bf1b00",
1492 "new": "#fce2de",
1493 "runnable": "#7eb26d",
1494 "terminated": "#511749",
1495 "timed-waiting": "#c15c17",
1496 "waiting": "#eab839"
1497 },
1498 "bars": false,
1499 "dashLength": 10,
1500 "dashes": false,
1501 "datasource": "Prometheus",
1502 "fill": 1,
1503 "gridPos": {
1504 "h": 7,
1505 "w": 6,
1506 "x": 18,
1507 "y": 24
1508 },
1509 "id": 124,
1510 "legend": {
1511 "alignAsTable": false,
1512 "avg": false,
1513 "current": true,
1514 "max": true,
1515 "min": false,
1516 "rightSide": false,
1517 "show": true,
1518 "total": false,
1519 "values": true
1520 },
1521 "lines": true,
1522 "linewidth": 1,
1523 "links": [],
1524 "nullPointMode": "null",
1525 "paceLength": 10,
1526 "percentage": false,
1527 "pointradius": 5,
1528 "points": false,
1529 "renderer": "flot",
1530 "seriesOverrides": [],
1531 "spaceLength": 10,
1532 "stack": false,
1533 "steppedLine": false,
1534 "targets": [
1535 {
1536 "expr": "jvm_threads_states_threads{application=\"$application\", instance=\"$instance\"}",
1537 "format": "time_series",
1538 "intervalFactor": 2,
1539 "legendFormat": "{{state}}",
1540 "refId": "A"
1541 }
1542 ],
1543 "thresholds": [],
1544 "timeFrom": null,
1545 "timeRegions": [],
1546 "timeShift": null,
1547 "title": "Thread States",
1548 "tooltip": {
1549 "shared": true,
1550 "sort": 0,
1551 "value_type": "individual"
1552 },
1553 "type": "graph",
1554 "xaxis": {
1555 "buckets": null,
1556 "mode": "time",
1557 "name": null,
1558 "show": true,
1559 "values": []
1560 },
1561 "yaxes": [
1562 {
1563 "format": "short",
1564 "label": null,
1565 "logBase": 1,
1566 "max": null,
1567 "min": null,
1568 "show": true
1569 },
1570 {
1571 "format": "short",
1572 "label": null,
1573 "logBase": 1,
1574 "max": null,
1575 "min": null,
1576 "show": true
1577 }
1578 ],
1579 "yaxis": {
1580 "align": false,
1581 "alignLevel": null
1582 }
1583 },
1584 {
1585 "aliasColors": {
1586 "debug": "#1F78C1",
1587 "error": "#BF1B00",
1588 "info": "#508642",
1589 "trace": "#6ED0E0",
1590 "warn": "#EAB839"
1591 },
1592 "bars": false,
1593 "dashLength": 10,
1594 "dashes": false,
1595 "datasource": "Prometheus",
1596 "editable": true,
1597 "error": false,
1598 "fill": 1,
1599 "grid": {
1600 "leftLogBase": 1,
1601 "leftMax": null,
1602 "leftMin": null,
1603 "rightLogBase": 1,
1604 "rightMax": null,
1605 "rightMin": null
1606 },
1607 "gridPos": {
1608 "h": 7,
1609 "w": 18,
1610 "x": 0,
1611 "y": 31
1612 },
1613 "height": "",
1614 "id": 91,
1615 "legend": {
1616 "alignAsTable": false,
1617 "avg": false,
1618 "current": true,
1619 "hideEmpty": false,
1620 "hideZero": false,
1621 "max": true,
1622 "min": false,
1623 "rightSide": false,
1624 "show": true,
1625 "total": false,
1626 "values": true
1627 },
1628 "lines": true,
1629 "linewidth": 1,
1630 "links": [],
1631 "nullPointMode": "null",
1632 "paceLength": 10,
1633 "percentage": true,
1634 "pointradius": 5,
1635 "points": false,
1636 "renderer": "flot",
1637 "seriesOverrides": [
1638 {
1639 "alias": "error",
1640 "yaxis": 1
1641 },
1642 {
1643 "alias": "warn",
1644 "yaxis": 1
1645 }
1646 ],
1647 "spaceLength": 10,
1648 "stack": false,
1649 "steppedLine": false,
1650 "targets": [
1651 {
1652 "expr": "increase(logback_events_total{application=\"$application\", instance=\"$instance\"}[1m])",
1653 "format": "time_series",
1654 "interval": "",
1655 "intervalFactor": 2,
1656 "legendFormat": "{{level}}",
1657 "metric": "",
1658 "refId": "A",
1659 "step": 1200
1660 }
1661 ],
1662 "thresholds": [],
1663 "timeFrom": null,
1664 "timeRegions": [],
1665 "timeShift": null,
1666 "title": "Log Events (1m)",
1667 "tooltip": {
1668 "msResolution": false,
1669 "shared": true,
1670 "sort": 0,
1671 "value_type": "individual"
1672 },
1673 "type": "graph",
1674 "x-axis": true,
1675 "xaxis": {
1676 "buckets": null,
1677 "mode": "time",
1678 "name": null,
1679 "show": true,
1680 "values": []
1681 },
1682 "y-axis": true,
1683 "y_formats": ["short", "short"],
1684 "yaxes": [
1685 {
1686 "decimals": 0,
1687 "format": "short",
1688 "label": null,
1689 "logBase": 1,
1690 "max": null,
1691 "min": "0",
1692 "show": true
1693 },
1694 {
1695 "format": "short",
1696 "label": null,
1697 "logBase": 1,
1698 "max": null,
1699 "min": null,
1700 "show": true
1701 }
1702 ],
1703 "yaxis": {
1704 "align": false,
1705 "alignLevel": null
1706 }
1707 },
1708 {
1709 "aliasColors": {},
1710 "bars": false,
1711 "dashLength": 10,
1712 "dashes": false,
1713 "datasource": "Prometheus",
1714 "editable": true,
1715 "error": false,
1716 "fill": 1,
1717 "grid": {
1718 "leftLogBase": 1,
1719 "leftMax": null,
1720 "leftMin": null,
1721 "rightLogBase": 1,
1722 "rightMax": null,
1723 "rightMin": null
1724 },
1725 "gridPos": {
1726 "h": 7,
1727 "w": 6,
1728 "x": 18,
1729 "y": 31
1730 },
1731 "id": 61,
1732 "legend": {
1733 "avg": false,
1734 "current": true,
1735 "max": true,
1736 "min": false,
1737 "show": true,
1738 "total": false,
1739 "values": true
1740 },
1741 "lines": true,
1742 "linewidth": 1,
1743 "links": [],
1744 "nullPointMode": "null",
1745 "paceLength": 10,
1746 "percentage": false,
1747 "pointradius": 5,
1748 "points": false,
1749 "renderer": "flot",
1750 "seriesOverrides": [],
1751 "spaceLength": 10,
1752 "stack": false,
1753 "steppedLine": false,
1754 "targets": [
1755 {
1756 "expr": "process_open_fds{application=\"$application\", instance=\"$instance\"}",
1757 "format": "time_series",
1758 "hide": false,
1759 "intervalFactor": 2,
1760 "legendFormat": "open",
1761 "metric": "",
1762 "refId": "A",
1763 "step": 2400
1764 },
1765 {
1766 "expr": "process_max_fds{application=\"$application\", instance=\"$instance\"}",
1767 "format": "time_series",
1768 "hide": false,
1769 "intervalFactor": 2,
1770 "legendFormat": "max",
1771 "metric": "",
1772 "refId": "B",
1773 "step": 2400
1774 },
1775 {
1776 "expr": "process_files_open{application=\"$application\", instance=\"$instance\"} or process_files_open_files{application=\"$application\", instance=\"$instance\"}",
1777 "format": "time_series",
1778 "intervalFactor": 2,
1779 "legendFormat": "open",
1780 "refId": "C"
1781 },
1782 {
1783 "expr": "process_files_max{application=\"$application\", instance=\"$instance\"} or process_files_max_files{application=\"$application\", instance=\"$instance\"}",
1784 "format": "time_series",
1785 "intervalFactor": 2,
1786 "legendFormat": "max",
1787 "refId": "D"
1788 }
1789 ],
1790 "thresholds": [],
1791 "timeFrom": null,
1792 "timeRegions": [],
1793 "timeShift": null,
1794 "title": "File Descriptors",
1795 "tooltip": {
1796 "msResolution": false,
1797 "shared": true,
1798 "sort": 0,
1799 "value_type": "cumulative"
1800 },
1801 "type": "graph",
1802 "x-axis": true,
1803 "xaxis": {
1804 "buckets": null,
1805 "mode": "time",
1806 "name": null,
1807 "show": true,
1808 "values": []
1809 },
1810 "y-axis": true,
1811 "y_formats": ["short", "short"],
1812 "yaxes": [
1813 {
1814 "decimals": 0,
1815 "format": "short",
1816 "label": null,
1817 "logBase": 10,
1818 "max": null,
1819 "min": 0,
1820 "show": true
1821 },
1822 {
1823 "format": "short",
1824 "label": null,
1825 "logBase": 1,
1826 "max": null,
1827 "min": null,
1828 "show": true
1829 }
1830 ],
1831 "yaxis": {
1832 "align": false,
1833 "alignLevel": null
1834 }
1835 },
1836 {
1837 "collapsed": false,
1838 "gridPos": {
1839 "h": 1,
1840 "w": 24,
1841 "x": 0,
1842 "y": 38
1843 },
1844 "id": 129,
1845 "panels": [],
1846 "repeat": "persistence_counts",
1847 "title": "JVM Memory Pools (Heap)",
1848 "type": "row"
1849 },
1850 {
1851 "aliasColors": {},
1852 "bars": false,
1853 "dashLength": 10,
1854 "dashes": false,
1855 "datasource": "Prometheus",
1856 "editable": true,
1857 "error": false,
1858 "fill": 1,
1859 "grid": {
1860 "leftLogBase": 1,
1861 "leftMax": null,
1862 "leftMin": null,
1863 "rightLogBase": 1,
1864 "rightMax": null,
1865 "rightMin": null
1866 },
1867 "gridPos": {
1868 "h": 7,
1869 "w": 8,
1870 "x": 0,
1871 "y": 39
1872 },
1873 "id": 3,
1874 "legend": {
1875 "alignAsTable": false,
1876 "avg": false,
1877 "current": true,
1878 "max": true,
1879 "min": false,
1880 "rightSide": false,
1881 "show": true,
1882 "total": false,
1883 "values": true
1884 },
1885 "lines": true,
1886 "linewidth": 1,
1887 "links": [],
1888 "maxPerRow": 3,
1889 "nullPointMode": "null",
1890 "paceLength": 10,
1891 "percentage": false,
1892 "pointradius": 5,
1893 "points": false,
1894 "renderer": "flot",
1895 "repeat": "jvm_memory_pool_heap",
1896 "scopedVars": {
1897 "jvm_memory_pool_heap": {
1898 "selected": false,
1899 "text": "PS Eden Space",
1900 "value": "PS Eden Space"
1901 }
1902 },
1903 "seriesOverrides": [],
1904 "spaceLength": 10,
1905 "stack": false,
1906 "steppedLine": false,
1907 "targets": [
1908 {
1909 "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
1910 "format": "time_series",
1911 "hide": false,
1912 "interval": "",
1913 "intervalFactor": 2,
1914 "legendFormat": "used",
1915 "metric": "",
1916 "refId": "A",
1917 "step": 1800
1918 },
1919 {
1920 "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
1921 "format": "time_series",
1922 "hide": false,
1923 "interval": "",
1924 "intervalFactor": 2,
1925 "legendFormat": "commited",
1926 "metric": "",
1927 "refId": "B",
1928 "step": 1800
1929 },
1930 {
1931 "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
1932 "format": "time_series",
1933 "hide": false,
1934 "interval": "",
1935 "intervalFactor": 2,
1936 "legendFormat": "max",
1937 "metric": "",
1938 "refId": "C",
1939 "step": 1800
1940 }
1941 ],
1942 "thresholds": [],
1943 "timeFrom": null,
1944 "timeRegions": [],
1945 "timeShift": null,
1946 "title": "$jvm_memory_pool_heap",
1947 "tooltip": {
1948 "msResolution": false,
1949 "shared": true,
1950 "sort": 0,
1951 "value_type": "cumulative"
1952 },
1953 "type": "graph",
1954 "x-axis": true,
1955 "xaxis": {
1956 "buckets": null,
1957 "mode": "time",
1958 "name": null,
1959 "show": true,
1960 "values": []
1961 },
1962 "y-axis": true,
1963 "y_formats": ["mbytes", "short"],
1964 "yaxes": [
1965 {
1966 "format": "bytes",
1967 "label": null,
1968 "logBase": 1,
1969 "max": null,
1970 "min": 0,
1971 "show": true
1972 },
1973 {
1974 "format": "short",
1975 "label": null,
1976 "logBase": 1,
1977 "max": null,
1978 "min": null,
1979 "show": true
1980 }
1981 ],
1982 "yaxis": {
1983 "align": false,
1984 "alignLevel": null
1985 }
1986 },
1987 {
1988 "aliasColors": {},
1989 "bars": false,
1990 "dashLength": 10,
1991 "dashes": false,
1992 "datasource": "Prometheus",
1993 "editable": true,
1994 "error": false,
1995 "fill": 1,
1996 "grid": {
1997 "leftLogBase": 1,
1998 "leftMax": null,
1999 "leftMin": null,
2000 "rightLogBase": 1,
2001 "rightMax": null,
2002 "rightMin": null
2003 },
2004 "gridPos": {
2005 "h": 7,
2006 "w": 8,
2007 "x": 8,
2008 "y": 39
2009 },
2010 "id": 134,
2011 "legend": {
2012 "alignAsTable": false,
2013 "avg": false,
2014 "current": true,
2015 "max": true,
2016 "min": false,
2017 "rightSide": false,
2018 "show": true,
2019 "total": false,
2020 "values": true
2021 },
2022 "lines": true,
2023 "linewidth": 1,
2024 "links": [],
2025 "maxPerRow": 3,
2026 "nullPointMode": "null",
2027 "paceLength": 10,
2028 "percentage": false,
2029 "pointradius": 5,
2030 "points": false,
2031 "renderer": "flot",
2032 "repeat": null,
2033 "repeatIteration": 1553765841423,
2034 "repeatPanelId": 3,
2035 "scopedVars": {
2036 "jvm_memory_pool_heap": {
2037 "selected": false,
2038 "text": "PS Old Gen",
2039 "value": "PS Old Gen"
2040 }
2041 },
2042 "seriesOverrides": [],
2043 "spaceLength": 10,
2044 "stack": false,
2045 "steppedLine": false,
2046 "targets": [
2047 {
2048 "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
2049 "format": "time_series",
2050 "hide": false,
2051 "interval": "",
2052 "intervalFactor": 2,
2053 "legendFormat": "used",
2054 "metric": "",
2055 "refId": "A",
2056 "step": 1800
2057 },
2058 {
2059 "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
2060 "format": "time_series",
2061 "hide": false,
2062 "interval": "",
2063 "intervalFactor": 2,
2064 "legendFormat": "commited",
2065 "metric": "",
2066 "refId": "B",
2067 "step": 1800
2068 },
2069 {
2070 "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
2071 "format": "time_series",
2072 "hide": false,
2073 "interval": "",
2074 "intervalFactor": 2,
2075 "legendFormat": "max",
2076 "metric": "",
2077 "refId": "C",
2078 "step": 1800
2079 }
2080 ],
2081 "thresholds": [],
2082 "timeFrom": null,
2083 "timeRegions": [],
2084 "timeShift": null,
2085 "title": "$jvm_memory_pool_heap",
2086 "tooltip": {
2087 "msResolution": false,
2088 "shared": true,
2089 "sort": 0,
2090 "value_type": "cumulative"
2091 },
2092 "type": "graph",
2093 "x-axis": true,
2094 "xaxis": {
2095 "buckets": null,
2096 "mode": "time",
2097 "name": null,
2098 "show": true,
2099 "values": []
2100 },
2101 "y-axis": true,
2102 "y_formats": ["mbytes", "short"],
2103 "yaxes": [
2104 {
2105 "format": "bytes",
2106 "label": null,
2107 "logBase": 1,
2108 "max": null,
2109 "min": 0,
2110 "show": true
2111 },
2112 {
2113 "format": "short",
2114 "label": null,
2115 "logBase": 1,
2116 "max": null,
2117 "min": null,
2118 "show": true
2119 }
2120 ],
2121 "yaxis": {
2122 "align": false,
2123 "alignLevel": null
2124 }
2125 },
2126 {
2127 "aliasColors": {},
2128 "bars": false,
2129 "dashLength": 10,
2130 "dashes": false,
2131 "datasource": "Prometheus",
2132 "editable": true,
2133 "error": false,
2134 "fill": 1,
2135 "grid": {
2136 "leftLogBase": 1,
2137 "leftMax": null,
2138 "leftMin": null,
2139 "rightLogBase": 1,
2140 "rightMax": null,
2141 "rightMin": null
2142 },
2143 "gridPos": {
2144 "h": 7,
2145 "w": 8,
2146 "x": 16,
2147 "y": 39
2148 },
2149 "id": 135,
2150 "legend": {
2151 "alignAsTable": false,
2152 "avg": false,
2153 "current": true,
2154 "max": true,
2155 "min": false,
2156 "rightSide": false,
2157 "show": true,
2158 "total": false,
2159 "values": true
2160 },
2161 "lines": true,
2162 "linewidth": 1,
2163 "links": [],
2164 "maxPerRow": 3,
2165 "nullPointMode": "null",
2166 "paceLength": 10,
2167 "percentage": false,
2168 "pointradius": 5,
2169 "points": false,
2170 "renderer": "flot",
2171 "repeat": null,
2172 "repeatIteration": 1553765841423,
2173 "repeatPanelId": 3,
2174 "scopedVars": {
2175 "jvm_memory_pool_heap": {
2176 "selected": false,
2177 "text": "PS Survivor Space",
2178 "value": "PS Survivor Space"
2179 }
2180 },
2181 "seriesOverrides": [],
2182 "spaceLength": 10,
2183 "stack": false,
2184 "steppedLine": false,
2185 "targets": [
2186 {
2187 "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
2188 "format": "time_series",
2189 "hide": false,
2190 "interval": "",
2191 "intervalFactor": 2,
2192 "legendFormat": "used",
2193 "metric": "",
2194 "refId": "A",
2195 "step": 1800
2196 },
2197 {
2198 "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
2199 "format": "time_series",
2200 "hide": false,
2201 "interval": "",
2202 "intervalFactor": 2,
2203 "legendFormat": "commited",
2204 "metric": "",
2205 "refId": "B",
2206 "step": 1800
2207 },
2208 {
2209 "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_heap\"}",
2210 "format": "time_series",
2211 "hide": false,
2212 "interval": "",
2213 "intervalFactor": 2,
2214 "legendFormat": "max",
2215 "metric": "",
2216 "refId": "C",
2217 "step": 1800
2218 }
2219 ],
2220 "thresholds": [],
2221 "timeFrom": null,
2222 "timeRegions": [],
2223 "timeShift": null,
2224 "title": "$jvm_memory_pool_heap",
2225 "tooltip": {
2226 "msResolution": false,
2227 "shared": true,
2228 "sort": 0,
2229 "value_type": "cumulative"
2230 },
2231 "type": "graph",
2232 "x-axis": true,
2233 "xaxis": {
2234 "buckets": null,
2235 "mode": "time",
2236 "name": null,
2237 "show": true,
2238 "values": []
2239 },
2240 "y-axis": true,
2241 "y_formats": ["mbytes", "short"],
2242 "yaxes": [
2243 {
2244 "format": "bytes",
2245 "label": null,
2246 "logBase": 1,
2247 "max": null,
2248 "min": 0,
2249 "show": true
2250 },
2251 {
2252 "format": "short",
2253 "label": null,
2254 "logBase": 1,
2255 "max": null,
2256 "min": null,
2257 "show": true
2258 }
2259 ],
2260 "yaxis": {
2261 "align": false,
2262 "alignLevel": null
2263 }
2264 },
2265 {
2266 "collapsed": false,
2267 "gridPos": {
2268 "h": 1,
2269 "w": 24,
2270 "x": 0,
2271 "y": 46
2272 },
2273 "id": 130,
2274 "panels": [],
2275 "repeat": null,
2276 "title": "JVM Memory Pools (Non-Heap)",
2277 "type": "row"
2278 },
2279 {
2280 "aliasColors": {},
2281 "bars": false,
2282 "dashLength": 10,
2283 "dashes": false,
2284 "datasource": "Prometheus",
2285 "editable": true,
2286 "error": false,
2287 "fill": 1,
2288 "grid": {
2289 "leftLogBase": 1,
2290 "leftMax": null,
2291 "leftMin": null,
2292 "rightLogBase": 1,
2293 "rightMax": null,
2294 "rightMin": null
2295 },
2296 "gridPos": {
2297 "h": 7,
2298 "w": 8,
2299 "x": 0,
2300 "y": 47
2301 },
2302 "id": 78,
2303 "legend": {
2304 "alignAsTable": false,
2305 "avg": false,
2306 "current": true,
2307 "max": true,
2308 "min": false,
2309 "rightSide": false,
2310 "show": true,
2311 "total": false,
2312 "values": true
2313 },
2314 "lines": true,
2315 "linewidth": 1,
2316 "links": [],
2317 "maxPerRow": 3,
2318 "nullPointMode": "null",
2319 "paceLength": 10,
2320 "percentage": false,
2321 "pointradius": 5,
2322 "points": false,
2323 "renderer": "flot",
2324 "repeat": "jvm_memory_pool_nonheap",
2325 "scopedVars": {
2326 "jvm_memory_pool_nonheap": {
2327 "selected": false,
2328 "text": "Metaspace",
2329 "value": "Metaspace"
2330 }
2331 },
2332 "seriesOverrides": [],
2333 "spaceLength": 10,
2334 "stack": false,
2335 "steppedLine": false,
2336 "targets": [
2337 {
2338 "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2339 "format": "time_series",
2340 "hide": false,
2341 "interval": "",
2342 "intervalFactor": 2,
2343 "legendFormat": "used",
2344 "metric": "",
2345 "refId": "A",
2346 "step": 1800
2347 },
2348 {
2349 "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2350 "format": "time_series",
2351 "hide": false,
2352 "interval": "",
2353 "intervalFactor": 2,
2354 "legendFormat": "commited",
2355 "metric": "",
2356 "refId": "B",
2357 "step": 1800
2358 },
2359 {
2360 "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2361 "format": "time_series",
2362 "hide": false,
2363 "interval": "",
2364 "intervalFactor": 2,
2365 "legendFormat": "max",
2366 "metric": "",
2367 "refId": "C",
2368 "step": 1800
2369 }
2370 ],
2371 "thresholds": [],
2372 "timeFrom": null,
2373 "timeRegions": [],
2374 "timeShift": null,
2375 "title": "$jvm_memory_pool_nonheap",
2376 "tooltip": {
2377 "msResolution": false,
2378 "shared": true,
2379 "sort": 0,
2380 "value_type": "cumulative"
2381 },
2382 "type": "graph",
2383 "x-axis": true,
2384 "xaxis": {
2385 "buckets": null,
2386 "mode": "time",
2387 "name": null,
2388 "show": true,
2389 "values": []
2390 },
2391 "y-axis": true,
2392 "y_formats": ["mbytes", "short"],
2393 "yaxes": [
2394 {
2395 "format": "bytes",
2396 "label": null,
2397 "logBase": 1,
2398 "max": null,
2399 "min": 0,
2400 "show": true
2401 },
2402 {
2403 "format": "short",
2404 "label": null,
2405 "logBase": 1,
2406 "max": null,
2407 "min": null,
2408 "show": true
2409 }
2410 ],
2411 "yaxis": {
2412 "align": false,
2413 "alignLevel": null
2414 }
2415 },
2416 {
2417 "aliasColors": {},
2418 "bars": false,
2419 "dashLength": 10,
2420 "dashes": false,
2421 "datasource": "Prometheus",
2422 "editable": true,
2423 "error": false,
2424 "fill": 1,
2425 "grid": {
2426 "leftLogBase": 1,
2427 "leftMax": null,
2428 "leftMin": null,
2429 "rightLogBase": 1,
2430 "rightMax": null,
2431 "rightMin": null
2432 },
2433 "gridPos": {
2434 "h": 7,
2435 "w": 8,
2436 "x": 8,
2437 "y": 47
2438 },
2439 "id": 136,
2440 "legend": {
2441 "alignAsTable": false,
2442 "avg": false,
2443 "current": true,
2444 "max": true,
2445 "min": false,
2446 "rightSide": false,
2447 "show": true,
2448 "total": false,
2449 "values": true
2450 },
2451 "lines": true,
2452 "linewidth": 1,
2453 "links": [],
2454 "maxPerRow": 3,
2455 "nullPointMode": "null",
2456 "paceLength": 10,
2457 "percentage": false,
2458 "pointradius": 5,
2459 "points": false,
2460 "renderer": "flot",
2461 "repeat": null,
2462 "repeatIteration": 1553765841423,
2463 "repeatPanelId": 78,
2464 "scopedVars": {
2465 "jvm_memory_pool_nonheap": {
2466 "selected": false,
2467 "text": "Compressed Class Space",
2468 "value": "Compressed Class Space"
2469 }
2470 },
2471 "seriesOverrides": [],
2472 "spaceLength": 10,
2473 "stack": false,
2474 "steppedLine": false,
2475 "targets": [
2476 {
2477 "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2478 "format": "time_series",
2479 "hide": false,
2480 "interval": "",
2481 "intervalFactor": 2,
2482 "legendFormat": "used",
2483 "metric": "",
2484 "refId": "A",
2485 "step": 1800
2486 },
2487 {
2488 "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2489 "format": "time_series",
2490 "hide": false,
2491 "interval": "",
2492 "intervalFactor": 2,
2493 "legendFormat": "commited",
2494 "metric": "",
2495 "refId": "B",
2496 "step": 1800
2497 },
2498 {
2499 "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2500 "format": "time_series",
2501 "hide": false,
2502 "interval": "",
2503 "intervalFactor": 2,
2504 "legendFormat": "max",
2505 "metric": "",
2506 "refId": "C",
2507 "step": 1800
2508 }
2509 ],
2510 "thresholds": [],
2511 "timeFrom": null,
2512 "timeRegions": [],
2513 "timeShift": null,
2514 "title": "$jvm_memory_pool_nonheap",
2515 "tooltip": {
2516 "msResolution": false,
2517 "shared": true,
2518 "sort": 0,
2519 "value_type": "cumulative"
2520 },
2521 "type": "graph",
2522 "x-axis": true,
2523 "xaxis": {
2524 "buckets": null,
2525 "mode": "time",
2526 "name": null,
2527 "show": true,
2528 "values": []
2529 },
2530 "y-axis": true,
2531 "y_formats": ["mbytes", "short"],
2532 "yaxes": [
2533 {
2534 "format": "bytes",
2535 "label": null,
2536 "logBase": 1,
2537 "max": null,
2538 "min": 0,
2539 "show": true
2540 },
2541 {
2542 "format": "short",
2543 "label": null,
2544 "logBase": 1,
2545 "max": null,
2546 "min": null,
2547 "show": true
2548 }
2549 ],
2550 "yaxis": {
2551 "align": false,
2552 "alignLevel": null
2553 }
2554 },
2555 {
2556 "aliasColors": {},
2557 "bars": false,
2558 "dashLength": 10,
2559 "dashes": false,
2560 "datasource": "Prometheus",
2561 "editable": true,
2562 "error": false,
2563 "fill": 1,
2564 "grid": {
2565 "leftLogBase": 1,
2566 "leftMax": null,
2567 "leftMin": null,
2568 "rightLogBase": 1,
2569 "rightMax": null,
2570 "rightMin": null
2571 },
2572 "gridPos": {
2573 "h": 7,
2574 "w": 8,
2575 "x": 16,
2576 "y": 47
2577 },
2578 "id": 137,
2579 "legend": {
2580 "alignAsTable": false,
2581 "avg": false,
2582 "current": true,
2583 "max": true,
2584 "min": false,
2585 "rightSide": false,
2586 "show": true,
2587 "total": false,
2588 "values": true
2589 },
2590 "lines": true,
2591 "linewidth": 1,
2592 "links": [],
2593 "maxPerRow": 3,
2594 "nullPointMode": "null",
2595 "paceLength": 10,
2596 "percentage": false,
2597 "pointradius": 5,
2598 "points": false,
2599 "renderer": "flot",
2600 "repeat": null,
2601 "repeatIteration": 1553765841423,
2602 "repeatPanelId": 78,
2603 "scopedVars": {
2604 "jvm_memory_pool_nonheap": {
2605 "selected": false,
2606 "text": "Code Cache",
2607 "value": "Code Cache"
2608 }
2609 },
2610 "seriesOverrides": [],
2611 "spaceLength": 10,
2612 "stack": false,
2613 "steppedLine": false,
2614 "targets": [
2615 {
2616 "expr": "jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2617 "format": "time_series",
2618 "hide": false,
2619 "interval": "",
2620 "intervalFactor": 2,
2621 "legendFormat": "used",
2622 "metric": "",
2623 "refId": "A",
2624 "step": 1800
2625 },
2626 {
2627 "expr": "jvm_memory_committed_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2628 "format": "time_series",
2629 "hide": false,
2630 "interval": "",
2631 "intervalFactor": 2,
2632 "legendFormat": "commited",
2633 "metric": "",
2634 "refId": "B",
2635 "step": 1800
2636 },
2637 {
2638 "expr": "jvm_memory_max_bytes{application=\"$application\", instance=\"$instance\", id=\"$jvm_memory_pool_nonheap\"}",
2639 "format": "time_series",
2640 "hide": false,
2641 "interval": "",
2642 "intervalFactor": 2,
2643 "legendFormat": "max",
2644 "metric": "",
2645 "refId": "C",
2646 "step": 1800
2647 }
2648 ],
2649 "thresholds": [],
2650 "timeFrom": null,
2651 "timeRegions": [],
2652 "timeShift": null,
2653 "title": "$jvm_memory_pool_nonheap",
2654 "tooltip": {
2655 "msResolution": false,
2656 "shared": true,
2657 "sort": 0,
2658 "value_type": "cumulative"
2659 },
2660 "type": "graph",
2661 "x-axis": true,
2662 "xaxis": {
2663 "buckets": null,
2664 "mode": "time",
2665 "name": null,
2666 "show": true,
2667 "values": []
2668 },
2669 "y-axis": true,
2670 "y_formats": ["mbytes", "short"],
2671 "yaxes": [
2672 {
2673 "format": "bytes",
2674 "label": null,
2675 "logBase": 1,
2676 "max": null,
2677 "min": 0,
2678 "show": true
2679 },
2680 {
2681 "format": "short",
2682 "label": null,
2683 "logBase": 1,
2684 "max": null,
2685 "min": null,
2686 "show": true
2687 }
2688 ],
2689 "yaxis": {
2690 "align": false,
2691 "alignLevel": null
2692 }
2693 },
2694 {
2695 "collapsed": false,
2696 "gridPos": {
2697 "h": 1,
2698 "w": 24,
2699 "x": 0,
2700 "y": 54
2701 },
2702 "id": 131,
2703 "panels": [],
2704 "repeat": null,
2705 "title": "Garbage Collection",
2706 "type": "row"
2707 },
2708 {
2709 "aliasColors": {},
2710 "bars": false,
2711 "dashLength": 10,
2712 "dashes": false,
2713 "datasource": "Prometheus",
2714 "fill": 1,
2715 "gridPos": {
2716 "h": 7,
2717 "w": 8,
2718 "x": 0,
2719 "y": 55
2720 },
2721 "id": 98,
2722 "legend": {
2723 "avg": false,
2724 "current": false,
2725 "max": false,
2726 "min": false,
2727 "show": true,
2728 "total": false,
2729 "values": false
2730 },
2731 "lines": true,
2732 "linewidth": 1,
2733 "links": [],
2734 "nullPointMode": "null",
2735 "paceLength": 10,
2736 "percentage": false,
2737 "pointradius": 5,
2738 "points": false,
2739 "renderer": "flot",
2740 "seriesOverrides": [],
2741 "spaceLength": 10,
2742 "stack": false,
2743 "steppedLine": false,
2744 "targets": [
2745 {
2746 "expr": "rate(jvm_gc_pause_seconds_count{application=\"$application\", instance=\"$instance\"}[1m])",
2747 "format": "time_series",
2748 "hide": false,
2749 "intervalFactor": 2,
2750 "legendFormat": "{{action}} ({{cause}})",
2751 "refId": "A"
2752 }
2753 ],
2754 "thresholds": [],
2755 "timeFrom": null,
2756 "timeRegions": [],
2757 "timeShift": null,
2758 "title": "Collections",
2759 "tooltip": {
2760 "shared": true,
2761 "sort": 0,
2762 "value_type": "individual"
2763 },
2764 "type": "graph",
2765 "xaxis": {
2766 "buckets": null,
2767 "mode": "time",
2768 "name": null,
2769 "show": true,
2770 "values": []
2771 },
2772 "yaxes": [
2773 {
2774 "format": "ops",
2775 "label": null,
2776 "logBase": 1,
2777 "max": null,
2778 "min": "0",
2779 "show": true
2780 },
2781 {
2782 "format": "short",
2783 "label": "",
2784 "logBase": 1,
2785 "max": null,
2786 "min": null,
2787 "show": true
2788 }
2789 ],
2790 "yaxis": {
2791 "align": false,
2792 "alignLevel": null
2793 }
2794 },
2795 {
2796 "aliasColors": {},
2797 "bars": false,
2798 "dashLength": 10,
2799 "dashes": false,
2800 "datasource": "Prometheus",
2801 "fill": 1,
2802 "gridPos": {
2803 "h": 7,
2804 "w": 8,
2805 "x": 8,
2806 "y": 55
2807 },
2808 "id": 101,
2809 "legend": {
2810 "avg": false,
2811 "current": false,
2812 "max": false,
2813 "min": false,
2814 "show": true,
2815 "total": false,
2816 "values": false
2817 },
2818 "lines": true,
2819 "linewidth": 1,
2820 "links": [],
2821 "nullPointMode": "null",
2822 "paceLength": 10,
2823 "percentage": false,
2824 "pointradius": 5,
2825 "points": false,
2826 "renderer": "flot",
2827 "seriesOverrides": [],
2828 "spaceLength": 10,
2829 "stack": false,
2830 "steppedLine": false,
2831 "targets": [
2832 {
2833 "expr": "rate(jvm_gc_pause_seconds_sum{application=\"$application\", instance=\"$instance\"}[1m])/rate(jvm_gc_pause_seconds_count{application=\"$application\", instance=\"$instance\"}[1m])",
2834 "format": "time_series",
2835 "hide": false,
2836 "instant": false,
2837 "intervalFactor": 1,
2838 "legendFormat": "avg {{action}} ({{cause}})",
2839 "refId": "A"
2840 },
2841 {
2842 "expr": "jvm_gc_pause_seconds_max{application=\"$application\", instance=\"$instance\"}",
2843 "format": "time_series",
2844 "hide": false,
2845 "instant": false,
2846 "intervalFactor": 1,
2847 "legendFormat": "max {{action}} ({{cause}})",
2848 "refId": "B"
2849 }
2850 ],
2851 "thresholds": [],
2852 "timeFrom": null,
2853 "timeRegions": [],
2854 "timeShift": null,
2855 "title": "Pause Durations",
2856 "tooltip": {
2857 "shared": true,
2858 "sort": 0,
2859 "value_type": "individual"
2860 },
2861 "type": "graph",
2862 "xaxis": {
2863 "buckets": null,
2864 "mode": "time",
2865 "name": null,
2866 "show": true,
2867 "values": []
2868 },
2869 "yaxes": [
2870 {
2871 "format": "s",
2872 "label": null,
2873 "logBase": 1,
2874 "max": null,
2875 "min": "0",
2876 "show": true
2877 },
2878 {
2879 "format": "short",
2880 "label": "",
2881 "logBase": 1,
2882 "max": null,
2883 "min": null,
2884 "show": true
2885 }
2886 ],
2887 "yaxis": {
2888 "align": false,
2889 "alignLevel": null
2890 }
2891 },
2892 {
2893 "aliasColors": {},
2894 "bars": false,
2895 "dashLength": 10,
2896 "dashes": false,
2897 "datasource": "Prometheus",
2898 "fill": 1,
2899 "gridPos": {
2900 "h": 7,
2901 "w": 8,
2902 "x": 16,
2903 "y": 55
2904 },
2905 "id": 99,
2906 "legend": {
2907 "avg": false,
2908 "current": false,
2909 "max": false,
2910 "min": false,
2911 "show": true,
2912 "total": false,
2913 "values": false
2914 },
2915 "lines": true,
2916 "linewidth": 1,
2917 "links": [],
2918 "nullPointMode": "null",
2919 "paceLength": 10,
2920 "percentage": false,
2921 "pointradius": 5,
2922 "points": false,
2923 "renderer": "flot",
2924 "seriesOverrides": [],
2925 "spaceLength": 10,
2926 "stack": false,
2927 "steppedLine": false,
2928 "targets": [
2929 {
2930 "expr": "rate(jvm_gc_memory_allocated_bytes_total{application=\"$application\", instance=\"$instance\"}[1m])",
2931 "format": "time_series",
2932 "interval": "",
2933 "intervalFactor": 1,
2934 "legendFormat": "allocated",
2935 "refId": "A"
2936 },
2937 {
2938 "expr": "rate(jvm_gc_memory_promoted_bytes_total{application=\"$application\", instance=\"$instance\"}[1m])",
2939 "format": "time_series",
2940 "interval": "",
2941 "intervalFactor": 1,
2942 "legendFormat": "promoted",
2943 "refId": "B"
2944 }
2945 ],
2946 "thresholds": [],
2947 "timeFrom": null,
2948 "timeRegions": [],
2949 "timeShift": null,
2950 "title": "Allocated/Promoted",
2951 "tooltip": {
2952 "shared": true,
2953 "sort": 0,
2954 "value_type": "individual"
2955 },
2956 "type": "graph",
2957 "xaxis": {
2958 "buckets": null,
2959 "mode": "time",
2960 "name": null,
2961 "show": true,
2962 "values": []
2963 },
2964 "yaxes": [
2965 {
2966 "format": "bytes",
2967 "label": null,
2968 "logBase": 1,
2969 "max": null,
2970 "min": "0",
2971 "show": true
2972 },
2973 {
2974 "format": "short",
2975 "label": null,
2976 "logBase": 1,
2977 "max": null,
2978 "min": null,
2979 "show": true
2980 }
2981 ],
2982 "yaxis": {
2983 "align": false,
2984 "alignLevel": null
2985 }
2986 },
2987 {
2988 "collapsed": false,
2989 "gridPos": {
2990 "h": 1,
2991 "w": 24,
2992 "x": 0,
2993 "y": 62
2994 },
2995 "id": 132,
2996 "panels": [],
2997 "repeat": null,
2998 "title": "Classloading",
2999 "type": "row"
3000 },
3001 {
3002 "aliasColors": {},
3003 "bars": false,
3004 "dashLength": 10,
3005 "dashes": false,
3006 "datasource": "Prometheus",
3007 "editable": true,
3008 "error": false,
3009 "fill": 1,
3010 "grid": {
3011 "leftLogBase": 1,
3012 "leftMax": null,
3013 "leftMin": null,
3014 "rightLogBase": 1,
3015 "rightMax": null,
3016 "rightMin": null
3017 },
3018 "gridPos": {
3019 "h": 7,
3020 "w": 12,
3021 "x": 0,
3022 "y": 63
3023 },
3024 "id": 37,
3025 "legend": {
3026 "avg": false,
3027 "current": false,
3028 "max": false,
3029 "min": false,
3030 "show": true,
3031 "total": false,
3032 "values": false
3033 },
3034 "lines": true,
3035 "linewidth": 1,
3036 "links": [],
3037 "nullPointMode": "null",
3038 "paceLength": 10,
3039 "percentage": false,
3040 "pointradius": 5,
3041 "points": false,
3042 "renderer": "flot",
3043 "seriesOverrides": [],
3044 "spaceLength": 10,
3045 "stack": false,
3046 "steppedLine": false,
3047 "targets": [
3048 {
3049 "expr": "jvm_classes_loaded{application=\"$application\", instance=\"$instance\"} or jvm_classes_loaded_classes{application=\"$application\", instance=\"$instance\"}",
3050 "format": "time_series",
3051 "intervalFactor": 2,
3052 "legendFormat": "loaded",
3053 "metric": "",
3054 "refId": "A",
3055 "step": 1200
3056 }
3057 ],
3058 "thresholds": [],
3059 "timeFrom": null,
3060 "timeRegions": [],
3061 "timeShift": null,
3062 "title": "Classes loaded",
3063 "tooltip": {
3064 "msResolution": false,
3065 "shared": true,
3066 "sort": 0,
3067 "value_type": "cumulative"
3068 },
3069 "type": "graph",
3070 "x-axis": true,
3071 "xaxis": {
3072 "buckets": null,
3073 "mode": "time",
3074 "name": null,
3075 "show": true,
3076 "values": []
3077 },
3078 "y-axis": true,
3079 "y_formats": ["short", "short"],
3080 "yaxes": [
3081 {
3082 "format": "short",
3083 "label": null,
3084 "logBase": 1,
3085 "max": null,
3086 "min": 0,
3087 "show": true
3088 },
3089 {
3090 "format": "short",
3091 "label": null,
3092 "logBase": 1,
3093 "max": null,
3094 "min": null,
3095 "show": true
3096 }
3097 ],
3098 "yaxis": {
3099 "align": false,
3100 "alignLevel": null
3101 }
3102 },
3103 {
3104 "aliasColors": {},
3105 "bars": false,
3106 "dashLength": 10,
3107 "dashes": false,
3108 "datasource": "Prometheus",
3109 "editable": true,
3110 "error": false,
3111 "fill": 1,
3112 "grid": {
3113 "leftLogBase": 1,
3114 "leftMax": null,
3115 "leftMin": null,
3116 "rightLogBase": 1,
3117 "rightMax": null,
3118 "rightMin": null
3119 },
3120 "gridPos": {
3121 "h": 7,
3122 "w": 12,
3123 "x": 12,
3124 "y": 63
3125 },
3126 "id": 38,
3127 "legend": {
3128 "avg": false,
3129 "current": false,
3130 "max": false,
3131 "min": false,
3132 "show": true,
3133 "total": false,
3134 "values": false
3135 },
3136 "lines": true,
3137 "linewidth": 1,
3138 "links": [],
3139 "nullPointMode": "null",
3140 "paceLength": 10,
3141 "percentage": false,
3142 "pointradius": 5,
3143 "points": false,
3144 "renderer": "flot",
3145 "seriesOverrides": [],
3146 "spaceLength": 10,
3147 "stack": false,
3148 "steppedLine": false,
3149 "targets": [
3150 {
3151 "expr": "delta(jvm_classes_loaded{application=\"$application\",instance=\"$instance\"}[5m]) or delta(jvm_classes_loaded_classes{application=\"$application\",instance=\"$instance\"}[5m])",
3152 "format": "time_series",
3153 "hide": false,
3154 "interval": "",
3155 "intervalFactor": 2,
3156 "legendFormat": "delta",
3157 "metric": "",
3158 "refId": "A",
3159 "step": 1200
3160 }
3161 ],
3162 "thresholds": [],
3163 "timeFrom": null,
3164 "timeRegions": [],
3165 "timeShift": null,
3166 "title": "Class delta (5m)",
3167 "tooltip": {
3168 "msResolution": false,
3169 "shared": true,
3170 "sort": 0,
3171 "value_type": "cumulative"
3172 },
3173 "type": "graph",
3174 "x-axis": true,
3175 "xaxis": {
3176 "buckets": null,
3177 "mode": "time",
3178 "name": null,
3179 "show": true,
3180 "values": []
3181 },
3182 "y-axis": true,
3183 "y_formats": ["ops", "short"],
3184 "yaxes": [
3185 {
3186 "decimals": null,
3187 "format": "short",
3188 "label": "",
3189 "logBase": 1,
3190 "max": null,
3191 "min": null,
3192 "show": true
3193 },
3194 {
3195 "format": "short",
3196 "label": null,
3197 "logBase": 1,
3198 "max": null,
3199 "min": null,
3200 "show": true
3201 }
3202 ],
3203 "yaxis": {
3204 "align": false,
3205 "alignLevel": null
3206 }
3207 },
3208 {
3209 "collapsed": false,
3210 "gridPos": {
3211 "h": 1,
3212 "w": 24,
3213 "x": 0,
3214 "y": 70
3215 },
3216 "id": 133,
3217 "panels": [],
3218 "repeat": null,
3219 "title": "Buffer Pools",
3220 "type": "row"
3221 },
3222 {
3223 "aliasColors": {},
3224 "bars": false,
3225 "dashLength": 10,
3226 "dashes": false,
3227 "datasource": "Prometheus",
3228 "editable": true,
3229 "error": false,
3230 "fill": 1,
3231 "grid": {
3232 "leftLogBase": 1,
3233 "leftMax": null,
3234 "leftMin": null,
3235 "rightLogBase": 1,
3236 "rightMax": null,
3237 "rightMin": null
3238 },
3239 "gridPos": {
3240 "h": 7,
3241 "w": 6,
3242 "x": 0,
3243 "y": 71
3244 },
3245 "id": 33,
3246 "legend": {
3247 "avg": false,
3248 "current": false,
3249 "max": false,
3250 "min": false,
3251 "show": true,
3252 "total": false,
3253 "values": false
3254 },
3255 "lines": true,
3256 "linewidth": 1,
3257 "links": [],
3258 "nullPointMode": "null",
3259 "paceLength": 10,
3260 "percentage": false,
3261 "pointradius": 5,
3262 "points": false,
3263 "renderer": "flot",
3264 "seriesOverrides": [],
3265 "spaceLength": 10,
3266 "stack": false,
3267 "steppedLine": false,
3268 "targets": [
3269 {
3270 "expr": "jvm_buffer_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"direct\"}",
3271 "format": "time_series",
3272 "intervalFactor": 2,
3273 "legendFormat": "used",
3274 "metric": "",
3275 "refId": "A",
3276 "step": 2400
3277 },
3278 {
3279 "expr": "jvm_buffer_total_capacity_bytes{application=\"$application\", instance=\"$instance\", id=\"direct\"}",
3280 "format": "time_series",
3281 "intervalFactor": 2,
3282 "legendFormat": "capacity",
3283 "metric": "",
3284 "refId": "B",
3285 "step": 2400
3286 }
3287 ],
3288 "thresholds": [],
3289 "timeFrom": null,
3290 "timeRegions": [],
3291 "timeShift": null,
3292 "title": "Direct Buffers",
3293 "tooltip": {
3294 "msResolution": false,
3295 "shared": true,
3296 "sort": 0,
3297 "value_type": "cumulative"
3298 },
3299 "type": "graph",
3300 "x-axis": true,
3301 "xaxis": {
3302 "buckets": null,
3303 "mode": "time",
3304 "name": null,
3305 "show": true,
3306 "values": []
3307 },
3308 "y-axis": true,
3309 "y_formats": ["short", "short"],
3310 "yaxes": [
3311 {
3312 "format": "bytes",
3313 "label": null,
3314 "logBase": 1,
3315 "max": null,
3316 "min": 0,
3317 "show": true
3318 },
3319 {
3320 "format": "short",
3321 "label": null,
3322 "logBase": 1,
3323 "max": null,
3324 "min": null,
3325 "show": true
3326 }
3327 ],
3328 "yaxis": {
3329 "align": false,
3330 "alignLevel": null
3331 }
3332 },
3333 {
3334 "aliasColors": {},
3335 "bars": false,
3336 "dashLength": 10,
3337 "dashes": false,
3338 "datasource": "Prometheus",
3339 "editable": true,
3340 "error": false,
3341 "fill": 1,
3342 "grid": {
3343 "leftLogBase": 1,
3344 "leftMax": null,
3345 "leftMin": null,
3346 "rightLogBase": 1,
3347 "rightMax": null,
3348 "rightMin": null
3349 },
3350 "gridPos": {
3351 "h": 7,
3352 "w": 6,
3353 "x": 6,
3354 "y": 71
3355 },
3356 "id": 83,
3357 "legend": {
3358 "avg": false,
3359 "current": false,
3360 "max": false,
3361 "min": false,
3362 "show": true,
3363 "total": false,
3364 "values": false
3365 },
3366 "lines": true,
3367 "linewidth": 1,
3368 "links": [],
3369 "nullPointMode": "null",
3370 "paceLength": 10,
3371 "percentage": false,
3372 "pointradius": 5,
3373 "points": false,
3374 "renderer": "flot",
3375 "seriesOverrides": [],
3376 "spaceLength": 10,
3377 "stack": false,
3378 "steppedLine": false,
3379 "targets": [
3380 {
3381 "expr": "jvm_buffer_count{application=\"$application\", instance=\"$instance\", id=\"direct\"} or jvm_buffer_count_buffers{application=\"$application\", instance=\"$instance\", id=\"direct\"}",
3382 "format": "time_series",
3383 "intervalFactor": 2,
3384 "legendFormat": "count",
3385 "metric": "",
3386 "refId": "A",
3387 "step": 2400
3388 }
3389 ],
3390 "thresholds": [],
3391 "timeFrom": null,
3392 "timeRegions": [],
3393 "timeShift": null,
3394 "title": "Direct Buffers",
3395 "tooltip": {
3396 "msResolution": false,
3397 "shared": true,
3398 "sort": 0,
3399 "value_type": "cumulative"
3400 },
3401 "type": "graph",
3402 "x-axis": true,
3403 "xaxis": {
3404 "buckets": null,
3405 "mode": "time",
3406 "name": null,
3407 "show": true,
3408 "values": []
3409 },
3410 "y-axis": true,
3411 "y_formats": ["short", "short"],
3412 "yaxes": [
3413 {
3414 "decimals": 0,
3415 "format": "short",
3416 "label": null,
3417 "logBase": 1,
3418 "max": null,
3419 "min": 0,
3420 "show": true
3421 },
3422 {
3423 "format": "short",
3424 "label": null,
3425 "logBase": 1,
3426 "max": null,
3427 "min": null,
3428 "show": true
3429 }
3430 ],
3431 "yaxis": {
3432 "align": false,
3433 "alignLevel": null
3434 }
3435 },
3436 {
3437 "aliasColors": {},
3438 "bars": false,
3439 "dashLength": 10,
3440 "dashes": false,
3441 "datasource": "Prometheus",
3442 "editable": true,
3443 "error": false,
3444 "fill": 1,
3445 "grid": {
3446 "leftLogBase": 1,
3447 "leftMax": null,
3448 "leftMin": null,
3449 "rightLogBase": 1,
3450 "rightMax": null,
3451 "rightMin": null
3452 },
3453 "gridPos": {
3454 "h": 7,
3455 "w": 6,
3456 "x": 12,
3457 "y": 71
3458 },
3459 "id": 85,
3460 "legend": {
3461 "avg": false,
3462 "current": false,
3463 "max": false,
3464 "min": false,
3465 "show": true,
3466 "total": false,
3467 "values": false
3468 },
3469 "lines": true,
3470 "linewidth": 1,
3471 "links": [],
3472 "nullPointMode": "null",
3473 "paceLength": 10,
3474 "percentage": false,
3475 "pointradius": 5,
3476 "points": false,
3477 "renderer": "flot",
3478 "seriesOverrides": [],
3479 "spaceLength": 10,
3480 "stack": false,
3481 "steppedLine": false,
3482 "targets": [
3483 {
3484 "expr": "jvm_buffer_memory_used_bytes{application=\"$application\", instance=\"$instance\", id=\"mapped\"}",
3485 "format": "time_series",
3486 "intervalFactor": 2,
3487 "legendFormat": "used",
3488 "metric": "",
3489 "refId": "A",
3490 "step": 2400
3491 },
3492 {
3493 "expr": "jvm_buffer_total_capacity_bytes{application=\"$application\", instance=\"$instance\", id=\"mapped\"}",
3494 "format": "time_series",
3495 "intervalFactor": 2,
3496 "legendFormat": "capacity",
3497 "metric": "",
3498 "refId": "B",
3499 "step": 2400
3500 }
3501 ],
3502 "thresholds": [],
3503 "timeFrom": null,
3504 "timeRegions": [],
3505 "timeShift": null,
3506 "title": "Mapped Buffers",
3507 "tooltip": {
3508 "msResolution": false,
3509 "shared": true,
3510 "sort": 0,
3511 "value_type": "cumulative"
3512 },
3513 "type": "graph",
3514 "x-axis": true,
3515 "xaxis": {
3516 "buckets": null,
3517 "mode": "time",
3518 "name": null,
3519 "show": true,
3520 "values": []
3521 },
3522 "y-axis": true,
3523 "y_formats": ["short", "short"],
3524 "yaxes": [
3525 {
3526 "format": "bytes",
3527 "label": null,
3528 "logBase": 1,
3529 "max": null,
3530 "min": 0,
3531 "show": true
3532 },
3533 {
3534 "format": "short",
3535 "label": null,
3536 "logBase": 1,
3537 "max": null,
3538 "min": null,
3539 "show": true
3540 }
3541 ],
3542 "yaxis": {
3543 "align": false,
3544 "alignLevel": null
3545 }
3546 },
3547 {
3548 "aliasColors": {},
3549 "bars": false,
3550 "dashLength": 10,
3551 "dashes": false,
3552 "datasource": "Prometheus",
3553 "editable": true,
3554 "error": false,
3555 "fill": 1,
3556 "grid": {
3557 "leftLogBase": 1,
3558 "leftMax": null,
3559 "leftMin": null,
3560 "rightLogBase": 1,
3561 "rightMax": null,
3562 "rightMin": null
3563 },
3564 "gridPos": {
3565 "h": 7,
3566 "w": 6,
3567 "x": 18,
3568 "y": 71
3569 },
3570 "id": 84,
3571 "legend": {
3572 "avg": false,
3573 "current": false,
3574 "max": false,
3575 "min": false,
3576 "show": true,
3577 "total": false,
3578 "values": false
3579 },
3580 "lines": true,
3581 "linewidth": 1,
3582 "links": [],
3583 "nullPointMode": "null",
3584 "paceLength": 10,
3585 "percentage": false,
3586 "pointradius": 5,
3587 "points": false,
3588 "renderer": "flot",
3589 "seriesOverrides": [],
3590 "spaceLength": 10,
3591 "stack": false,
3592 "steppedLine": false,
3593 "targets": [
3594 {
3595 "expr": "jvm_buffer_count{application=\"$application\", instance=\"$instance\", id=\"mapped\"} or jvm_buffer_count_buffers{application=\"$application\", instance=\"$instance\", id=\"mapped\"}",
3596 "format": "time_series",
3597 "intervalFactor": 2,
3598 "legendFormat": "count",
3599 "metric": "",
3600 "refId": "A",
3601 "step": 2400
3602 }
3603 ],
3604 "thresholds": [],
3605 "timeFrom": null,
3606 "timeRegions": [],
3607 "timeShift": null,
3608 "title": "Mapped Buffers",
3609 "tooltip": {
3610 "msResolution": false,
3611 "shared": true,
3612 "sort": 0,
3613 "value_type": "cumulative"
3614 },
3615 "type": "graph",
3616 "x-axis": true,
3617 "xaxis": {
3618 "buckets": null,
3619 "mode": "time",
3620 "name": null,
3621 "show": true,
3622 "values": []
3623 },
3624 "y-axis": true,
3625 "y_formats": ["short", "short"],
3626 "yaxes": [
3627 {
3628 "decimals": 0,
3629 "format": "short",
3630 "label": null,
3631 "logBase": 1,
3632 "max": null,
3633 "min": 0,
3634 "show": true
3635 },
3636 {
3637 "format": "short",
3638 "label": null,
3639 "logBase": 1,
3640 "max": null,
3641 "min": null,
3642 "show": true
3643 }
3644 ],
3645 "yaxis": {
3646 "align": false,
3647 "alignLevel": null
3648 }
3649 }
3650 ],
3651 "refresh": "10s",
3652 "schemaVersion": 18,
3653 "style": "dark",
3654 "tags": [],
3655 "templating": {
3656 "list": [
3657 {
3658 "allValue": null,
3659 "current": {
3660 "text": "test",
3661 "value": "test"
3662 },
3663 "datasource": "Prometheus",
3664 "definition": "",
3665 "hide": 0,
3666 "includeAll": false,
3667 "label": "Application",
3668 "multi": false,
3669 "name": "application",
3670 "options": [],
3671 "query": "label_values(application)",
3672 "refresh": 2,
3673 "regex": "",
3674 "skipUrlSync": false,
3675 "sort": 0,
3676 "tagValuesQuery": "",
3677 "tags": [],
3678 "tagsQuery": "",
3679 "type": "query",
3680 "useTags": false
3681 },
3682 {
3683 "allFormat": "glob",
3684 "allValue": null,
3685 "current": {
3686 "text": "localhost:8080",
3687 "value": "localhost:8080"
3688 },
3689 "datasource": "Prometheus",
3690 "definition": "",
3691 "hide": 0,
3692 "includeAll": false,
3693 "label": "Instance",
3694 "multi": false,
3695 "multiFormat": "glob",
3696 "name": "instance",
3697 "options": [],
3698 "query": "label_values(jvm_memory_used_bytes{application=\"$application\"}, instance)",
3699 "refresh": 2,
3700 "regex": "",
3701 "skipUrlSync": false,
3702 "sort": 0,
3703 "tagValuesQuery": "",
3704 "tags": [],
3705 "tagsQuery": "",
3706 "type": "query",
3707 "useTags": false
3708 },
3709 {
3710 "allFormat": "glob",
3711 "allValue": null,
3712 "current": {
3713 "text": "All",
3714 "value": "$__all"
3715 },
3716 "datasource": "Prometheus",
3717 "definition": "",
3718 "hide": 0,
3719 "includeAll": true,
3720 "label": "JVM Memory Pools Heap",
3721 "multi": false,
3722 "multiFormat": "glob",
3723 "name": "jvm_memory_pool_heap",
3724 "options": [],
3725 "query": "label_values(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"heap\"},id)",
3726 "refresh": 1,
3727 "regex": "",
3728 "skipUrlSync": false,
3729 "sort": 1,
3730 "tagValuesQuery": "",
3731 "tags": [],
3732 "tagsQuery": "",
3733 "type": "query",
3734 "useTags": false
3735 },
3736 {
3737 "allFormat": "glob",
3738 "allValue": null,
3739 "current": {
3740 "text": "All",
3741 "value": "$__all"
3742 },
3743 "datasource": "Prometheus",
3744 "definition": "",
3745 "hide": 0,
3746 "includeAll": true,
3747 "label": "JVM Memory Pools Non-Heap",
3748 "multi": false,
3749 "multiFormat": "glob",
3750 "name": "jvm_memory_pool_nonheap",
3751 "options": [],
3752 "query": "label_values(jvm_memory_used_bytes{application=\"$application\", instance=\"$instance\", area=\"nonheap\"},id)",
3753 "refresh": 1,
3754 "regex": "",
3755 "skipUrlSync": false,
3756 "sort": 2,
3757 "tagValuesQuery": "",
3758 "tags": [],
3759 "tagsQuery": "",
3760 "type": "query",
3761 "useTags": false
3762 }
3763 ]
3764 },
3765 "time": {
3766 "from": "now-30m",
3767 "to": "now"
3768 },
3769 "timepicker": {
3770 "now": true,
3771 "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
3772 "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
3773 },
3774 "timezone": "browser",
3775 "title": "JVM (Micrometer)",
3776 "uid": "Ud1CFe3iz",
3777 "version": 1
3778 }
File src/main/docker/grafana/provisioning/dashboards/dashboard.yml added (mode: 100644) (index 0000000..4817a83)
1 apiVersion: 1
2
3 providers:
4 - name: 'Prometheus'
5 orgId: 1
6 folder: ''
7 type: file
8 disableDeletion: false
9 editable: true
10 options:
11 path: /etc/grafana/provisioning/dashboards
File src/main/docker/grafana/provisioning/datasources/datasource.yml added (mode: 100644) (index 0000000..57b2bb3)
1 apiVersion: 1
2
3 # list of datasources that should be deleted from the database
4 deleteDatasources:
5 - name: Prometheus
6 orgId: 1
7
8 # list of datasources to insert/update depending
9 # whats available in the database
10 datasources:
11 # <string, required> name of the datasource. Required
12 - name: Prometheus
13 # <string, required> datasource type. Required
14 type: prometheus
15 # <string, required> access mode. direct or proxy. Required
16 access: proxy
17 # <int> org id. will default to orgId 1 if not specified
18 orgId: 1
19 # <string> url
20 # On MacOS, replace localhost by host.docker.internal
21 url: http://localhost:9090
22 # <string> database password, if used
23 password:
24 # <string> database user, if used
25 user:
26 # <string> database name, if used
27 database:
28 # <bool> enable/disable basic auth
29 basicAuth: false
30 # <string> basic auth username
31 basicAuthUser: admin
32 # <string> basic auth password
33 basicAuthPassword: admin
34 # <bool> enable/disable with credentials headers
35 withCredentials:
36 # <bool> mark as default datasource. Max one per org
37 isDefault: true
38 # <map> fields that will be converted to json and stored in json_data
39 jsonData:
40 graphiteVersion: '1.1'
41 tlsAuth: false
42 tlsAuthWithCACert: false
43 # <string> json object of data that will be encrypted.
44 secureJsonData:
45 tlsCACert: '...'
46 tlsClientCert: '...'
47 tlsClientKey: '...'
48 version: 1
49 # <bool> allow users to edit datasources from the UI.
50 editable: true
File src/main/docker/monitoring.yml added (mode: 100644) (index 0000000..4d20182)
1 version: '2'
2 services:
3 honlap-prometheus:
4 image: prom/prometheus:v2.16.0
5 volumes:
6 - ./prometheus/:/etc/prometheus/
7 command:
8 - '--config.file=/etc/prometheus/prometheus.yml'
9 ports:
10 - 9090:9090
11 # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and
12 # grafana/provisioning/datasources/datasource.yml
13 network_mode: 'host' # to test locally running service
14 honlap-grafana:
15 image: grafana/grafana:6.6.2
16 volumes:
17 - ./grafana/provisioning/:/etc/grafana/provisioning/
18 environment:
19 - GF_SECURITY_ADMIN_PASSWORD=admin
20 - GF_USERS_ALLOW_SIGN_UP=false
21 - GF_INSTALL_PLUGINS=grafana-piechart-panel
22 ports:
23 - 3000:3000
24 # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and
25 # grafana/provisioning/datasources/datasource.yml
26 network_mode: 'host' # to test locally running service
File src/main/docker/postgresql.yml added (mode: 100644) (index 0000000..eb04b1f)
1 version: '2'
2 services:
3 honlap-postgresql:
4 image: postgres:12.1
5 # volumes:
6 # - ~/volumes/jhipster/honlap/postgresql/:/var/lib/postgresql/data/
7 environment:
8 - POSTGRES_USER=honlap
9 - POSTGRES_PASSWORD=
10 ports:
11 - 5432:5432
File src/main/docker/prometheus/prometheus.yml added (mode: 100644) (index 0000000..b370a2f)
1 # Sample global config for monitoring JHipster applications
2 global:
3 scrape_interval: 15s # By default, scrape targets every 15 seconds.
4 evaluation_interval: 15s # By default, scrape targets every 15 seconds.
5 # scrape_timeout is set to the global default (10s).
6
7 # Attach these labels to any time series or alerts when communicating with
8 # external systems (federation, remote storage, Alertmanager).
9 external_labels:
10 monitor: 'jhipster'
11
12 # A scrape configuration containing exactly one endpoint to scrape:
13 # Here it's Prometheus itself.
14 scrape_configs:
15 # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
16 - job_name: 'prometheus'
17
18 # Override the global default and scrape targets from this job every 5 seconds.
19 scrape_interval: 5s
20
21 # scheme defaults to 'http' enable https in case your application is server via https
22 #scheme: https
23 # basic auth is not needed by default. See https://www.jhipster.tech/monitoring/#configuring-metrics-forwarding for details
24 #basic_auth:
25 # username: admin
26 # password: admin
27 metrics_path: /management/prometheus
28 static_configs:
29 - targets:
30 # On MacOS, replace localhost by host.docker.internal
31 - localhost:8080
File src/main/docker/sonar.yml added (mode: 100644) (index 0000000..55b0f39)
1 version: '2'
2 services:
3 honlap-sonar:
4 image: sonarqube:8.2-community
5 ports:
6 - 9001:9000
7 - 9092:9092
File src/main/java/hu/dns/honlap/ApplicationWebXml.java added (mode: 100644) (index 0000000..794441b)
1 package hu.dns.honlap;
2
3 import io.github.jhipster.config.DefaultProfileUtil;
4
5 import org.springframework.boot.builder.SpringApplicationBuilder;
6 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
7
8 /**
9 * This is a helper Java class that provides an alternative to creating a {@code web.xml}.
10 * This will be invoked only when the application is deployed to a Servlet container like Tomcat, JBoss etc.
11 */
12 public class ApplicationWebXml extends SpringBootServletInitializer {
13
14 @Override
15 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
16 // set a default to use when no profile is configured.
17 DefaultProfileUtil.addDefaultProfile(application.application());
18 return application.sources(HonlapApp.class);
19 }
20 }
File src/main/java/hu/dns/honlap/HonlapApp.java added (mode: 100644) (index 0000000..4eda3ac)
1 package hu.dns.honlap;
2
3 import hu.dns.honlap.config.ApplicationProperties;
4
5 import io.github.jhipster.config.DefaultProfileUtil;
6 import io.github.jhipster.config.JHipsterConstants;
7
8 import org.apache.commons.lang3.StringUtils;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.springframework.boot.SpringApplication;
12 import org.springframework.boot.autoconfigure.SpringBootApplication;
13 import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
14 import org.springframework.boot.context.properties.EnableConfigurationProperties;
15 import org.springframework.core.env.Environment;
16
17 import javax.annotation.PostConstruct;
18 import java.net.InetAddress;
19 import java.net.UnknownHostException;
20 import java.util.Arrays;
21 import java.util.Collection;
22
23 @SpringBootApplication
24 @EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
25 public class HonlapApp {
26
27 private static final Logger log = LoggerFactory.getLogger(HonlapApp.class);
28
29 private final Environment env;
30
31 public HonlapApp(Environment env) {
32 this.env = env;
33 }
34
35 /**
36 * Initializes honlap.
37 * <p>
38 * Spring profiles can be configured with a program argument --spring.profiles.active=your-active-profile
39 * <p>
40 * You can find more information on how profiles work with JHipster on <a href="https://www.jhipster.tech/profiles/">https://www.jhipster.tech/profiles/</a>.
41 */
42 @PostConstruct
43 public void initApplication() {
44 Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
45 if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
46 log.error("You have misconfigured your application! It should not run " +
47 "with both the 'dev' and 'prod' profiles at the same time.");
48 }
49 if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_CLOUD)) {
50 log.error("You have misconfigured your application! It should not " +
51 "run with both the 'dev' and 'cloud' profiles at the same time.");
52 }
53 }
54
55 /**
56 * Main method, used to run the application.
57 *
58 * @param args the command line arguments.
59 */
60 public static void main(String[] args) {
61 SpringApplication app = new SpringApplication(HonlapApp.class);
62 DefaultProfileUtil.addDefaultProfile(app);
63 Environment env = app.run(args).getEnvironment();
64 logApplicationStartup(env);
65 }
66
67 private static void logApplicationStartup(Environment env) {
68 String protocol = "http";
69 if (env.getProperty("server.ssl.key-store") != null) {
70 protocol = "https";
71 }
72 String serverPort = env.getProperty("server.port");
73 String contextPath = env.getProperty("server.servlet.context-path");
74 if (StringUtils.isBlank(contextPath)) {
75 contextPath = "/";
76 }
77 String hostAddress = "localhost";
78 try {
79 hostAddress = InetAddress.getLocalHost().getHostAddress();
80 } catch (UnknownHostException e) {
81 log.warn("The host name could not be determined, using `localhost` as fallback");
82 }
83 log.info("\n----------------------------------------------------------\n\t" +
84 "Application '{}' is running! Access URLs:\n\t" +
85 "Local: \t\t{}://localhost:{}{}\n\t" +
86 "External: \t{}://{}:{}{}\n\t" +
87 "Profile(s): \t{}\n----------------------------------------------------------",
88 env.getProperty("spring.application.name"),
89 protocol,
90 serverPort,
91 contextPath,
92 protocol,
93 hostAddress,
94 serverPort,
95 contextPath,
96 env.getActiveProfiles());
97 }
98 }
File src/main/java/hu/dns/honlap/aop/logging/LoggingAspect.java added (mode: 100644) (index 0000000..d33070c)
1 package hu.dns.honlap.aop.logging;
2
3 import io.github.jhipster.config.JHipsterConstants;
4
5 import org.aspectj.lang.JoinPoint;
6 import org.aspectj.lang.ProceedingJoinPoint;
7 import org.aspectj.lang.annotation.AfterThrowing;
8 import org.aspectj.lang.annotation.Around;
9 import org.aspectj.lang.annotation.Aspect;
10 import org.aspectj.lang.annotation.Pointcut;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.springframework.core.env.Environment;
14 import org.springframework.core.env.Profiles;
15
16 import java.util.Arrays;
17
18 /**
19 * Aspect for logging execution of service and repository Spring components.
20 *
21 * By default, it only runs with the "dev" profile.
22 */
23 @Aspect
24 public class LoggingAspect {
25
26 private final Environment env;
27
28 public LoggingAspect(Environment env) {
29 this.env = env;
30 }
31
32 /**
33 * Pointcut that matches all repositories, services and Web REST endpoints.
34 */
35 @Pointcut("within(@org.springframework.stereotype.Repository *)" +
36 " || within(@org.springframework.stereotype.Service *)" +
37 " || within(@org.springframework.web.bind.annotation.RestController *)")
38 public void springBeanPointcut() {
39 // Method is empty as this is just a Pointcut, the implementations are in the advices.
40 }
41
42 /**
43 * Pointcut that matches all Spring beans in the application's main packages.
44 */
45 @Pointcut("within(hu.dns.honlap.repository..*)"+
46 " || within(hu.dns.honlap.service..*)"+
47 " || within(hu.dns.honlap.web.rest..*)")
48 public void applicationPackagePointcut() {
49 // Method is empty as this is just a Pointcut, the implementations are in the advices.
50 }
51
52 /**
53 * Retrieves the {@link Logger} associated to the given {@link JoinPoint}.
54 *
55 * @param joinPoint join point we want the logger for.
56 * @return {@link Logger} associated to the given {@link JoinPoint}.
57 */
58 private Logger logger(JoinPoint joinPoint) {
59 return LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringTypeName());
60 }
61
62 /**
63 * Advice that logs methods throwing exceptions.
64 *
65 * @param joinPoint join point for advice.
66 * @param e exception.
67 */
68 @AfterThrowing(pointcut = "applicationPackagePointcut() && springBeanPointcut()", throwing = "e")
69 public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
70 if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) {
71 logger(joinPoint)
72 .error(
73 "Exception in {}() with cause = \'{}\' and exception = \'{}\'",
74 joinPoint.getSignature().getName(),
75 e.getCause() != null ? e.getCause() : "NULL",
76 e.getMessage(),
77 e
78 );
79 } else {
80 logger(joinPoint)
81 .error(
82 "Exception in {}() with cause = {}",
83 joinPoint.getSignature().getName(),
84 e.getCause() != null ? e.getCause() : "NULL"
85 );
86 }
87 }
88
89 /**
90 * Advice that logs when a method is entered and exited.
91 *
92 * @param joinPoint join point for advice.
93 * @return result.
94 * @throws Throwable throws {@link IllegalArgumentException}.
95 */
96 @Around("applicationPackagePointcut() && springBeanPointcut()")
97 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
98 Logger log = logger(joinPoint);
99 if (log.isDebugEnabled()) {
100 log.debug("Enter: {}() with argument[s] = {}", joinPoint.getSignature().getName(), Arrays.toString(joinPoint.getArgs()));
101 }
102 try {
103 Object result = joinPoint.proceed();
104 if (log.isDebugEnabled()) {
105 log.debug("Exit: {}() with result = {}", joinPoint.getSignature().getName(), result);
106 }
107 return result;
108 } catch (IllegalArgumentException e) {
109 log.error("Illegal argument: {} in {}()", Arrays.toString(joinPoint.getArgs()), joinPoint.getSignature().getName());
110 throw e;
111 }
112 }
113 }
File src/main/java/hu/dns/honlap/config/ApplicationProperties.java added (mode: 100644) (index 0000000..1f99f01)
1 package hu.dns.honlap.config;
2
3 import org.springframework.boot.context.properties.ConfigurationProperties;
4
5 /**
6 * Properties specific to Honlap.
7 * <p>
8 * Properties are configured in the {@code application.yml} file.
9 * See {@link io.github.jhipster.config.JHipsterProperties} for a good example.
10 */
11 @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
12 public class ApplicationProperties {
13 }
File src/main/java/hu/dns/honlap/config/AsyncConfiguration.java added (mode: 100644) (index 0000000..a0bf6f2)
1 package hu.dns.honlap.config;
2
3 import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
7 import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
8 import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
9 import org.springframework.context.annotation.Bean;
10 import org.springframework.context.annotation.Configuration;
11 import org.springframework.scheduling.annotation.AsyncConfigurer;
12 import org.springframework.scheduling.annotation.EnableAsync;
13 import org.springframework.scheduling.annotation.EnableScheduling;
14 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
15
16 import java.util.concurrent.Executor;
17
18 @Configuration
19 @EnableAsync
20 @EnableScheduling
21 public class AsyncConfiguration implements AsyncConfigurer {
22
23 private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);
24
25 private final TaskExecutionProperties taskExecutionProperties;
26
27 public AsyncConfiguration(TaskExecutionProperties taskExecutionProperties) {
28 this.taskExecutionProperties = taskExecutionProperties;
29 }
30
31 @Override
32 @Bean(name = "taskExecutor")
33 public Executor getAsyncExecutor() {
34 log.debug("Creating Async Task Executor");
35 ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
36 executor.setCorePoolSize(taskExecutionProperties.getPool().getCoreSize());
37 executor.setMaxPoolSize(taskExecutionProperties.getPool().getMaxSize());
38 executor.setQueueCapacity(taskExecutionProperties.getPool().getQueueCapacity());
39 executor.setThreadNamePrefix(taskExecutionProperties.getThreadNamePrefix());
40 return new ExceptionHandlingAsyncTaskExecutor(executor);
41 }
42
43 @Override
44 public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
45 return new SimpleAsyncUncaughtExceptionHandler();
46 }
47 }
File src/main/java/hu/dns/honlap/config/CacheConfiguration.java added (mode: 100644) (index 0000000..70d4965)
1 package hu.dns.honlap.config;
2
3 import java.time.Duration;
4
5 import org.ehcache.config.builders.*;
6 import org.ehcache.jsr107.Eh107Configuration;
7
8 import org.hibernate.cache.jcache.ConfigSettings;
9 import io.github.jhipster.config.JHipsterProperties;
10
11 import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
12 import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
13 import org.springframework.cache.annotation.EnableCaching;
14 import org.springframework.context.annotation.*;
15
16 @Configuration
17 @EnableCaching
18 public class CacheConfiguration {
19
20 private final javax.cache.configuration.Configuration<Object, Object> jcacheConfiguration;
21
22 public CacheConfiguration(JHipsterProperties jHipsterProperties) {
23 JHipsterProperties.Cache.Ehcache ehcache = jHipsterProperties.getCache().getEhcache();
24
25 jcacheConfiguration = Eh107Configuration.fromEhcacheCacheConfiguration(
26 CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class,
27 ResourcePoolsBuilder.heap(ehcache.getMaxEntries()))
28 .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(ehcache.getTimeToLiveSeconds())))
29 .build());
30 }
31
32 @Bean
33 public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(javax.cache.CacheManager cacheManager) {
34 return hibernateProperties -> hibernateProperties.put(ConfigSettings.CACHE_MANAGER, cacheManager);
35 }
36
37 @Bean
38 public JCacheManagerCustomizer cacheManagerCustomizer() {
39 return cm -> {
40 createCache(cm, hu.dns.honlap.repository.UserRepository.USERS_BY_LOGIN_CACHE);
41 createCache(cm, hu.dns.honlap.repository.UserRepository.USERS_BY_EMAIL_CACHE);
42 createCache(cm, hu.dns.honlap.domain.User.class.getName());
43 createCache(cm, hu.dns.honlap.domain.Authority.class.getName());
44 createCache(cm, hu.dns.honlap.domain.User.class.getName() + ".authorities");
45 createCache(cm, hu.dns.honlap.domain.PieceOfNews.class.getName());
46 // jhipster-needle-ehcache-add-entry
47 };
48 }
49
50 private void createCache(javax.cache.CacheManager cm, String cacheName) {
51 javax.cache.Cache<Object, Object> cache = cm.getCache(cacheName);
52 if (cache == null) {
53 cm.createCache(cacheName, jcacheConfiguration);
54 }
55 }
56
57 }
File src/main/java/hu/dns/honlap/config/CloudDatabaseConfiguration.java added (mode: 100644) (index 0000000..8969123)
1 package hu.dns.honlap.config;
2
3 import io.github.jhipster.config.JHipsterConstants;
4
5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory;
7 import org.springframework.cloud.config.java.AbstractCloudConfig;
8 import org.springframework.context.annotation.*;
9
10 import javax.sql.DataSource;
11 import org.springframework.boot.context.properties.ConfigurationProperties;
12
13
14 @Configuration
15 @Profile(JHipsterConstants.SPRING_PROFILE_CLOUD)
16 public class CloudDatabaseConfiguration extends AbstractCloudConfig {
17
18 private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class);
19
20 private static final String CLOUD_CONFIGURATION_HIKARI_PREFIX = "spring.datasource.hikari";
21
22 @Bean
23 @ConfigurationProperties(CLOUD_CONFIGURATION_HIKARI_PREFIX)
24 public DataSource dataSource() {
25 log.info("Configuring JDBC datasource from a cloud provider");
26 return connectionFactory().dataSource();
27 }
28 }
File src/main/java/hu/dns/honlap/config/Constants.java added (mode: 100644) (index 0000000..776c47a)
1 package hu.dns.honlap.config;
2
3 /**
4 * Application constants.
5 */
6 public final class Constants {
7
8 // Regex for acceptable logins
9 public static final String LOGIN_REGEX = "^[_.@A-Za-z0-9-]*$";
10
11 public static final String SYSTEM_ACCOUNT = "system";
12 public static final String DEFAULT_LANGUAGE = "hu";
13 public static final String ANONYMOUS_USER = "anonymoususer";
14
15 private Constants() {
16 }
17 }
File src/main/java/hu/dns/honlap/config/DatabaseConfiguration.java added (mode: 100644) (index 0000000..af5ac7e)
1 package hu.dns.honlap.config;
2
3 import io.github.jhipster.config.JHipsterConstants;
4 import io.github.jhipster.config.h2.H2ConfigurationHelper;
5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory;
7 import org.springframework.context.annotation.Bean;
8 import org.springframework.context.annotation.Configuration;
9 import org.springframework.context.annotation.Profile;
10
11 import org.springframework.core.env.Environment;
12 import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
13 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
14 import org.springframework.transaction.annotation.EnableTransactionManagement;
15
16 import java.sql.SQLException;
17
18 @Configuration
19 @EnableJpaRepositories("hu.dns.honlap.repository")
20 @EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
21 @EnableTransactionManagement
22 public class DatabaseConfiguration {
23
24 private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
25
26 private final Environment env;
27
28 public DatabaseConfiguration(Environment env) {
29 this.env = env;
30 }
31
32 /**
33 * Open the TCP port for the H2 database, so it is available remotely.
34 *
35 * @return the H2 database TCP server.
36 * @throws SQLException if the server failed to start.
37 */
38 @Bean(initMethod = "start", destroyMethod = "stop")
39 @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
40 public Object h2TCPServer() throws SQLException {
41 String port = getValidPortForH2();
42 log.debug("H2 database is available on port {}", port);
43 return H2ConfigurationHelper.createServer(port);
44 }
45
46 private String getValidPortForH2() {
47 int port = Integer.parseInt(env.getProperty("server.port"));
48 if (port < 10000) {
49 port = 10000 + port;
50 } else {
51 if (port < 63536) {
52 port = port + 2000;
53 } else {
54 port = port - 2000;
55 }
56 }
57 return String.valueOf(port);
58 }
59 }
File src/main/java/hu/dns/honlap/config/DateTimeFormatConfiguration.java added (mode: 100644) (index 0000000..e38757e)
1 package hu.dns.honlap.config;
2
3 import org.springframework.context.annotation.Configuration;
4 import org.springframework.format.FormatterRegistry;
5 import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
6 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7
8 /**
9 * Configure the converters to use the ISO format for dates by default.
10 */
11 @Configuration
12 public class DateTimeFormatConfiguration implements WebMvcConfigurer {
13
14 @Override
15 public void addFormatters(FormatterRegistry registry) {
16 DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
17 registrar.setUseIsoFormat(true);
18 registrar.registerFormatters(registry);
19 }
20 }
File src/main/java/hu/dns/honlap/config/JacksonConfiguration.java added (mode: 100644) (index 0000000..9993dc0)
1 package hu.dns.honlap.config;
2
3 import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
4 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
5 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
6 import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
7
8 import org.springframework.context.annotation.Bean;
9 import org.springframework.context.annotation.Configuration;
10 import org.zalando.problem.ProblemModule;
11 import org.zalando.problem.violations.ConstraintViolationProblemModule;
12
13 @Configuration
14 public class JacksonConfiguration {
15
16 /**
17 * Support for Java date and time API.
18 * @return the corresponding Jackson module.
19 */
20 @Bean
21 public JavaTimeModule javaTimeModule() {
22 return new JavaTimeModule();
23 }
24
25 @Bean
26 public Jdk8Module jdk8TimeModule() {
27 return new Jdk8Module();
28 }
29
30 /*
31 * Support for Hibernate types in Jackson.
32 */
33 @Bean
34 public Hibernate5Module hibernate5Module() {
35 return new Hibernate5Module();
36 }
37
38 /*
39 * Jackson Afterburner module to speed up serialization/deserialization.
40 */
41 @Bean
42 public AfterburnerModule afterburnerModule() {
43 return new AfterburnerModule();
44 }
45
46 /*
47 * Module for serialization/deserialization of RFC7807 Problem.
48 */
49 @Bean
50 ProblemModule problemModule() {
51 return new ProblemModule();
52 }
53
54 /*
55 * Module for serialization/deserialization of ConstraintViolationProblem.
56 */
57 @Bean
58 ConstraintViolationProblemModule constraintViolationProblemModule() {
59 return new ConstraintViolationProblemModule();
60 }
61 }
File src/main/java/hu/dns/honlap/config/LiquibaseConfiguration.java added (mode: 100644) (index 0000000..f315ddb)
1 package hu.dns.honlap.config;
2
3 import io.github.jhipster.config.JHipsterConstants;
4 import io.github.jhipster.config.liquibase.SpringLiquibaseUtil;
5 import liquibase.integration.spring.SpringLiquibase;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.beans.factory.ObjectProvider;
9 import org.springframework.beans.factory.annotation.Qualifier;
10 import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
11 import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource;
12 import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
13 import org.springframework.context.annotation.Bean;
14 import org.springframework.context.annotation.Configuration;
15 import org.springframework.core.env.Environment;
16 import org.springframework.core.env.Profiles;
17
18 import javax.sql.DataSource;
19 import java.util.concurrent.Executor;
20
21 @Configuration
22 public class LiquibaseConfiguration {
23
24 private final Logger log = LoggerFactory.getLogger(LiquibaseConfiguration.class);
25
26 private final Environment env;
27
28 public LiquibaseConfiguration(Environment env) {
29 this.env = env;
30 }
31
32 @Bean
33 public SpringLiquibase liquibase(@Qualifier("taskExecutor") Executor executor,
34 @LiquibaseDataSource ObjectProvider<DataSource> liquibaseDataSource, LiquibaseProperties liquibaseProperties,
35 ObjectProvider<DataSource> dataSource, DataSourceProperties dataSourceProperties) {
36
37 // If you don't want Liquibase to start asynchronously, substitute by this:
38 // SpringLiquibase liquibase = SpringLiquibaseUtil.createSpringLiquibase(liquibaseDataSource.getIfAvailable(), liquibaseProperties, dataSource.getIfUnique(), dataSourceProperties);
39 SpringLiquibase liquibase = SpringLiquibaseUtil.createAsyncSpringLiquibase(this.env, executor, liquibaseDataSource.getIfAvailable(), liquibaseProperties, dataSource.getIfUnique(), dataSourceProperties);
40 liquibase.setChangeLog("classpath:config/liquibase/master.xml");
41 liquibase.setContexts(liquibaseProperties.getContexts());
42 liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
43 liquibase.setLiquibaseSchema(liquibaseProperties.getLiquibaseSchema());
44 liquibase.setLiquibaseTablespace(liquibaseProperties.getLiquibaseTablespace());
45 liquibase.setDatabaseChangeLogLockTable(liquibaseProperties.getDatabaseChangeLogLockTable());
46 liquibase.setDatabaseChangeLogTable(liquibaseProperties.getDatabaseChangeLogTable());
47 liquibase.setDropFirst(liquibaseProperties.isDropFirst());
48 liquibase.setLabels(liquibaseProperties.getLabels());
49 liquibase.setChangeLogParameters(liquibaseProperties.getParameters());
50 liquibase.setRollbackFile(liquibaseProperties.getRollbackFile());
51 liquibase.setTestRollbackOnUpdate(liquibaseProperties.isTestRollbackOnUpdate());
52 if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE))) {
53 liquibase.setShouldRun(false);
54 } else {
55 liquibase.setShouldRun(liquibaseProperties.isEnabled());
56 log.debug("Configuring Liquibase");
57 }
58 return liquibase;
59 }
60 }
File src/main/java/hu/dns/honlap/config/LocaleConfiguration.java added (mode: 100644) (index 0000000..797eb3b)
1 package hu.dns.honlap.config;
2
3 import io.github.jhipster.config.locale.AngularCookieLocaleResolver;
4
5 import org.springframework.context.annotation.Bean;
6 import org.springframework.context.annotation.Configuration;
7 import org.springframework.web.servlet.LocaleResolver;
8 import org.springframework.web.servlet.config.annotation.*;
9 import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
10
11 @Configuration
12 public class LocaleConfiguration implements WebMvcConfigurer {
13
14 @Bean(name = "localeResolver")
15 public LocaleResolver localeResolver() {
16 AngularCookieLocaleResolver cookieLocaleResolver = new AngularCookieLocaleResolver();
17 cookieLocaleResolver.setCookieName("NG_TRANSLATE_LANG_KEY");
18 return cookieLocaleResolver;
19 }
20
21 @Override
22 public void addInterceptors(InterceptorRegistry registry) {
23 LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
24 localeChangeInterceptor.setParamName("language");
25 registry.addInterceptor(localeChangeInterceptor);
26 }
27 }
File src/main/java/hu/dns/honlap/config/LoggingAspectConfiguration.java added (mode: 100644) (index 0000000..f5a6d0c)
1 package hu.dns.honlap.config;
2
3 import hu.dns.honlap.aop.logging.LoggingAspect;
4
5 import io.github.jhipster.config.JHipsterConstants;
6
7 import org.springframework.context.annotation.*;
8 import org.springframework.core.env.Environment;
9
10 @Configuration
11 @EnableAspectJAutoProxy
12 public class LoggingAspectConfiguration {
13
14 @Bean
15 @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)
16 public LoggingAspect loggingAspect(Environment env) {
17 return new LoggingAspect(env);
18 }
19 }
File src/main/java/hu/dns/honlap/config/LoggingConfiguration.java added (mode: 100644) (index 0000000..d5158ab)
1 package hu.dns.honlap.config;
2
3 import ch.qos.logback.classic.LoggerContext;
4 import com.fasterxml.jackson.core.JsonProcessingException;
5 import com.fasterxml.jackson.databind.ObjectMapper;
6 import io.github.jhipster.config.JHipsterProperties;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.beans.factory.annotation.Value;
9 import org.springframework.context.annotation.Configuration;
10
11 import java.util.HashMap;
12 import java.util.Map;
13
14 import static io.github.jhipster.config.logging.LoggingUtils.*;
15
16 /*
17 * Configures the console and Logstash log appenders from the app properties
18 */
19 @Configuration
20 public class LoggingConfiguration {
21
22 public LoggingConfiguration(@Value("${spring.application.name}") String appName,
23 @Value("${server.port}") String serverPort,
24 JHipsterProperties jHipsterProperties,
25 ObjectMapper mapper) throws JsonProcessingException {
26
27 LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
28
29 Map<String, String> map = new HashMap<>();
30 map.put("app_name", appName);
31 map.put("app_port", serverPort);
32 String customFields = mapper.writeValueAsString(map);
33
34 JHipsterProperties.Logging loggingProperties = jHipsterProperties.getLogging();
35 JHipsterProperties.Logging.Logstash logstashProperties = loggingProperties.getLogstash();
36
37 if (loggingProperties.isUseJsonFormat()) {
38 addJsonConsoleAppender(context, customFields);
39 }
40 if (logstashProperties.isEnabled()) {
41 addLogstashTcpSocketAppender(context, customFields, logstashProperties);
42 }
43 if (loggingProperties.isUseJsonFormat() || logstashProperties.isEnabled()) {
44 addContextListener(context, customFields, loggingProperties);
45 }
46 if (jHipsterProperties.getMetrics().getLogs().isEnabled()) {
47 setMetricsMarkerLogbackFilter(context, loggingProperties.isUseJsonFormat());
48 }
49 }
50 }
File src/main/java/hu/dns/honlap/config/SecurityConfiguration.java added (mode: 100644) (index 0000000..d640719)
1 package hu.dns.honlap.config;
2
3 import hu.dns.honlap.security.*;
4 import hu.dns.honlap.security.jwt.*;
5
6 import org.springframework.context.annotation.Bean;
7 import org.springframework.context.annotation.Import;
8 import org.springframework.http.HttpMethod;
9 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
10 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
11 import org.springframework.security.config.annotation.web.builders.WebSecurity;
12 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
13 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
14 import org.springframework.security.config.http.SessionCreationPolicy;
15 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
16 import org.springframework.security.crypto.password.PasswordEncoder;
17 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
18 import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter;
19 import org.springframework.web.filter.CorsFilter;
20 import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
21
22 @EnableWebSecurity
23 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
24 @Import(SecurityProblemSupport.class)
25 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
26
27 private final TokenProvider tokenProvider;
28
29 private final CorsFilter corsFilter;
30 private final SecurityProblemSupport problemSupport;
31
32 public SecurityConfiguration(TokenProvider tokenProvider, CorsFilter corsFilter, SecurityProblemSupport problemSupport) {
33 this.tokenProvider = tokenProvider;
34 this.corsFilter = corsFilter;
35 this.problemSupport = problemSupport;
36 }
37
38 @Bean
39 public PasswordEncoder passwordEncoder() {
40 return new BCryptPasswordEncoder();
41 }
42
43 @Override
44 public void configure(WebSecurity web) {
45 web.ignoring()
46 .antMatchers(HttpMethod.OPTIONS, "/**")
47 .antMatchers("/app/**/*.{js,html}")
48 .antMatchers("/i18n/**")
49 .antMatchers("/content/**")
50 .antMatchers("/h2-console/**")
51 .antMatchers("/swagger-ui/index.html")
52 .antMatchers("/test/**");
53 }
54
55 @Override
56 public void configure(HttpSecurity http) throws Exception {
57 // @formatter:off
58 http
59 .csrf()
60 .disable()
61 .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
62 .exceptionHandling()
63 .authenticationEntryPoint(problemSupport)
64 .accessDeniedHandler(problemSupport)
65 .and()
66 .headers()
67 .contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:")
68 .and()
69 .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
70 .and()
71 .featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'")
72 .and()
73 .frameOptions()
74 .deny()
75 .and()
76 .sessionManagement()
77 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
78 .and()
79 .authorizeRequests()
80 .antMatchers("/api/authenticate").permitAll()
81 .antMatchers("/api/register").permitAll()
82 .antMatchers("/api/activate").permitAll()
83 .antMatchers("/api/account/reset-password/init").permitAll()
84 .antMatchers("/api/account/reset-password/finish").permitAll()
85 .antMatchers("/api/**").authenticated()
86 .antMatchers("/management/health").permitAll()
87 .antMatchers("/management/info").permitAll()
88 .antMatchers("/management/prometheus").permitAll()
89 .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
90 .and()
91 .httpBasic()
92 .and()
93 .apply(securityConfigurerAdapter());
94 // @formatter:on
95 }
96
97 private JWTConfigurer securityConfigurerAdapter() {
98 return new JWTConfigurer(tokenProvider);
99 }
100 }
File src/main/java/hu/dns/honlap/config/WebConfigurer.java added (mode: 100644) (index 0000000..889fde5)
1 package hu.dns.honlap.config;
2
3 import io.github.jhipster.config.JHipsterConstants;
4 import io.github.jhipster.config.JHipsterProperties;
5 import io.github.jhipster.config.h2.H2ConfigurationHelper;
6 import io.github.jhipster.web.filter.CachingHttpHeadersFilter;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import org.springframework.boot.web.server.*;
10 import org.springframework.boot.web.servlet.ServletContextInitializer;
11 import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
12 import org.springframework.context.annotation.Bean;
13 import org.springframework.context.annotation.Configuration;
14 import org.springframework.core.env.Environment;
15 import org.springframework.core.env.Profiles;
16 import org.springframework.http.MediaType;
17 import org.springframework.web.cors.CorsConfiguration;
18 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
19 import org.springframework.web.filter.CorsFilter;
20
21 import javax.servlet.*;
22 import java.io.File;
23 import java.io.UnsupportedEncodingException;
24 import java.nio.charset.StandardCharsets;
25 import java.nio.file.Paths;
26 import java.util.*;
27
28 import static java.net.URLDecoder.decode;
29
30 /**
31 * Configuration of web application with Servlet 3.0 APIs.
32 */
33 @Configuration
34 public class WebConfigurer implements ServletContextInitializer, WebServerFactoryCustomizer<WebServerFactory> {
35
36 private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
37
38 private final Environment env;
39
40 private final JHipsterProperties jHipsterProperties;
41
42 public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) {
43 this.env = env;
44 this.jHipsterProperties = jHipsterProperties;
45 }
46
47 @Override
48 public void onStartup(ServletContext servletContext) throws ServletException {
49 if (env.getActiveProfiles().length != 0) {
50 log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
51 }
52 EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
53 if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_PRODUCTION))) {
54 initCachingHttpHeadersFilter(servletContext, disps);
55 }
56 if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT))) {
57 initH2Console(servletContext);
58 }
59 log.info("Web application fully configured");
60 }
61
62 /**
63 * Customize the Servlet engine: Mime types, the document root, the cache.
64 */
65 @Override
66 public void customize(WebServerFactory server) {
67 setMimeMappings(server);
68 // When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets.
69 setLocationForStaticAssets(server);
70 }
71
72 private void setMimeMappings(WebServerFactory server) {
73 if (server instanceof ConfigurableServletWebServerFactory) {
74 MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
75 // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
76 mappings.add("html", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
77 // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
78 mappings.add("json", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
79 ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
80 servletWebServer.setMimeMappings(mappings);
81 }
82 }
83
84 private void setLocationForStaticAssets(WebServerFactory server) {
85 if (server instanceof ConfigurableServletWebServerFactory) {
86 ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
87 File root;
88 String prefixPath = resolvePathPrefix();
89 root = new File(prefixPath + "target/classes/static/");
90 if (root.exists() && root.isDirectory()) {
91 servletWebServer.setDocumentRoot(root);
92 }
93 }
94 }
95
96 /**
97 * Resolve path prefix to static resources.
98 */
99 private String resolvePathPrefix() {
100 String fullExecutablePath;
101 try {
102 fullExecutablePath = decode(this.getClass().getResource("").getPath(), StandardCharsets.UTF_8.name());
103 } catch (UnsupportedEncodingException e) {
104 /* try without decoding if this ever happens */
105 fullExecutablePath = this.getClass().getResource("").getPath();
106 }
107 String rootPath = Paths.get(".").toUri().normalize().getPath();
108 String extractedPath = fullExecutablePath.replace(rootPath, "");
109 int extractionEndIndex = extractedPath.indexOf("target/");
110 if (extractionEndIndex <= 0) {
111 return "";
112 }
113 return extractedPath.substring(0, extractionEndIndex);
114 }
115
116 /**
117 * Initializes the caching HTTP Headers Filter.
118 */
119 private void initCachingHttpHeadersFilter(ServletContext servletContext,
120 EnumSet<DispatcherType> disps) {
121 log.debug("Registering Caching HTTP Headers Filter");
122 FilterRegistration.Dynamic cachingHttpHeadersFilter =
123 servletContext.addFilter("cachingHttpHeadersFilter",
124 new CachingHttpHeadersFilter(jHipsterProperties));
125
126 cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/i18n/*");
127 cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/content/*");
128 cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/app/*");
129 cachingHttpHeadersFilter.setAsyncSupported(true);
130 }
131
132 @Bean
133 public CorsFilter corsFilter() {
134 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
135 CorsConfiguration config = jHipsterProperties.getCors();
136 if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
137 log.debug("Registering CORS filter");
138 source.registerCorsConfiguration("/api/**", config);
139 source.registerCorsConfiguration("/management/**", config);
140 source.registerCorsConfiguration("/v2/api-docs", config);
141 }
142 return new CorsFilter(source);
143 }
144
145 /**
146 * Initializes H2 console.
147 */
148 private void initH2Console(ServletContext servletContext) {
149 log.debug("Initialize H2 console");
150 H2ConfigurationHelper.initH2Console(servletContext);
151 }
152
153 }
File src/main/java/hu/dns/honlap/config/audit/AuditEventConverter.java added (mode: 100644) (index 0000000..bf77154)
1 package hu.dns.honlap.config.audit;
2
3 import hu.dns.honlap.domain.PersistentAuditEvent;
4
5 import org.springframework.boot.actuate.audit.AuditEvent;
6 import org.springframework.security.web.authentication.WebAuthenticationDetails;
7 import org.springframework.stereotype.Component;
8
9 import java.util.*;
10
11 @Component
12 public class AuditEventConverter {
13
14 /**
15 * Convert a list of {@link PersistentAuditEvent}s to a list of {@link AuditEvent}s.
16 *
17 * @param persistentAuditEvents the list to convert.
18 * @return the converted list.
19 */
20 public List<AuditEvent> convertToAuditEvent(Iterable<PersistentAuditEvent> persistentAuditEvents) {
21 if (persistentAuditEvents == null) {
22 return Collections.emptyList();
23 }
24 List<AuditEvent> auditEvents = new ArrayList<>();
25 for (PersistentAuditEvent persistentAuditEvent : persistentAuditEvents) {
26 auditEvents.add(convertToAuditEvent(persistentAuditEvent));
27 }
28 return auditEvents;
29 }
30
31 /**
32 * Convert a {@link PersistentAuditEvent} to an {@link AuditEvent}.
33 *
34 * @param persistentAuditEvent the event to convert.
35 * @return the converted list.
36 */
37 public AuditEvent convertToAuditEvent(PersistentAuditEvent persistentAuditEvent) {
38 if (persistentAuditEvent == null) {
39 return null;
40 }
41 return new AuditEvent(persistentAuditEvent.getAuditEventDate(), persistentAuditEvent.getPrincipal(),
42 persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData()));
43 }
44
45 /**
46 * Internal conversion. This is needed to support the current SpringBoot actuator {@code AuditEventRepository} interface.
47 *
48 * @param data the data to convert.
49 * @return a map of {@link String}, {@link Object}.
50 */
51 public Map<String, Object> convertDataToObjects(Map<String, String> data) {
52 Map<String, Object> results = new HashMap<>();
53
54 if (data != null) {
55 for (Map.Entry<String, String> entry : data.entrySet()) {
56 results.put(entry.getKey(), entry.getValue());
57 }
58 }
59 return results;
60 }
61
62 /**
63 * Internal conversion. This method will allow to save additional data.
64 * By default, it will save the object as string.
65 *
66 * @param data the data to convert.
67 * @return a map of {@link String}, {@link String}.
68 */
69 public Map<String, String> convertDataToStrings(Map<String, Object> data) {
70 Map<String, String> results = new HashMap<>();
71
72 if (data != null) {
73 for (Map.Entry<String, Object> entry : data.entrySet()) {
74 // Extract the data that will be saved.
75 if (entry.getValue() instanceof WebAuthenticationDetails) {
76 WebAuthenticationDetails authenticationDetails = (WebAuthenticationDetails) entry.getValue();
77 results.put("remoteAddress", authenticationDetails.getRemoteAddress());
78 results.put("sessionId", authenticationDetails.getSessionId());
79 } else {
80 results.put(entry.getKey(), Objects.toString(entry.getValue()));
81 }
82 }
83 }
84 return results;
85 }
86 }
File src/main/java/hu/dns/honlap/config/audit/package-info.java added (mode: 100644) (index 0000000..a98b0f9)
1 /**
2 * Audit specific code.
3 */
4 package hu.dns.honlap.config.audit;
File src/main/java/hu/dns/honlap/config/package-info.java added (mode: 100644) (index 0000000..9888ec0)
1 /**
2 * Spring Framework configuration files.
3 */
4 package hu.dns.honlap.config;
File src/main/java/hu/dns/honlap/domain/AbstractAuditingEntity.java added (mode: 100644) (index 0000000..ad4a763)
1 package hu.dns.honlap.domain;
2
3 import com.fasterxml.jackson.annotation.JsonIgnore;
4 import org.springframework.data.annotation.CreatedBy;
5 import org.springframework.data.annotation.CreatedDate;
6 import org.springframework.data.annotation.LastModifiedBy;
7 import org.springframework.data.annotation.LastModifiedDate;
8 import org.springframework.data.jpa.domain.support.AuditingEntityListener;
9
10 import java.io.Serializable;
11 import java.time.Instant;
12 import javax.persistence.Column;
13 import javax.persistence.EntityListeners;
14 import javax.persistence.MappedSuperclass;
15
16 /**
17 * Base abstract class for entities which will hold definitions for created, last modified, created by,
18 * last modified by attributes.
19 */
20 @MappedSuperclass
21 @EntityListeners(AuditingEntityListener.class)
22 public abstract class AbstractAuditingEntity implements Serializable {
23
24 private static final long serialVersionUID = 1L;
25
26 @CreatedBy
27 @Column(name = "created_by", nullable = false, length = 50, updatable = false)
28 @JsonIgnore
29 private String createdBy;
30
31 @CreatedDate
32 @Column(name = "created_date", updatable = false)
33 @JsonIgnore
34 private Instant createdDate = Instant.now();
35
36 @LastModifiedBy
37 @Column(name = "last_modified_by", length = 50)
38 @JsonIgnore
39 private String lastModifiedBy;
40
41 @LastModifiedDate
42 @Column(name = "last_modified_date")
43 @JsonIgnore
44 private Instant lastModifiedDate = Instant.now();
45
46 public String getCreatedBy() {
47 return createdBy;
48 }
49
50 public void setCreatedBy(String createdBy) {
51 this.createdBy = createdBy;
52 }
53
54 public Instant getCreatedDate() {
55 return createdDate;
56 }
57
58 public void setCreatedDate(Instant createdDate) {
59 this.createdDate = createdDate;
60 }
61
62 public String getLastModifiedBy() {
63 return lastModifiedBy;
64 }
65
66 public void setLastModifiedBy(String lastModifiedBy) {
67 this.lastModifiedBy = lastModifiedBy;
68 }
69
70 public Instant getLastModifiedDate() {
71 return lastModifiedDate;
72 }
73
74 public void setLastModifiedDate(Instant lastModifiedDate) {
75 this.lastModifiedDate = lastModifiedDate;
76 }
77 }
File src/main/java/hu/dns/honlap/domain/Authority.java added (mode: 100644) (index 0000000..09a9ae1)
1 package hu.dns.honlap.domain;
2
3 import org.hibernate.annotations.Cache;
4 import org.hibernate.annotations.CacheConcurrencyStrategy;
5 import javax.persistence.Entity;
6 import javax.persistence.Id;
7 import javax.persistence.Table;
8 import javax.persistence.Column;
9 import javax.validation.constraints.NotNull;
10 import javax.validation.constraints.Size;
11 import java.io.Serializable;
12 import java.util.Objects;
13
14 /**
15 * An authority (a security role) used by Spring Security.
16 */
17 @Entity
18 @Table(name = "auth_authority")
19 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
20 public class Authority implements Serializable {
21
22 private static final long serialVersionUID = 1L;
23
24 @NotNull
25 @Size(max = 50)
26 @Id
27 @Column(length = 50)
28 private String name;
29
30 public String getName() {
31 return name;
32 }
33
34 public void setName(String name) {
35 this.name = name;
36 }
37
38 @Override
39 public boolean equals(Object o) {
40 if (this == o) {
41 return true;
42 }
43 if (!(o instanceof Authority)) {
44 return false;
45 }
46 return Objects.equals(name, ((Authority) o).name);
47 }
48
49 @Override
50 public int hashCode() {
51 return Objects.hashCode(name);
52 }
53
54 @Override
55 public String toString() {
56 return "Authority{" +
57 "name='" + name + '\'' +
58 "}";
59 }
60 }
File src/main/java/hu/dns/honlap/domain/PersistentAuditEvent.java added (mode: 100644) (index 0000000..9f8c37e)
1 package hu.dns.honlap.domain;
2
3 import javax.persistence.*;
4 import javax.validation.constraints.NotNull;
5 import java.io.Serializable;
6 import java.time.Instant;
7 import java.util.HashMap;
8 import java.util.Map;
9
10 /**
11 * Persist AuditEvent managed by the Spring Boot actuator.
12 *
13 * @see org.springframework.boot.actuate.audit.AuditEvent
14 */
15 @Entity
16 @Table(name = "auth_persistent_audit_event")
17 public class PersistentAuditEvent implements Serializable {
18
19 private static final long serialVersionUID = 1L;
20
21 @Id
22 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
23 @SequenceGenerator(name = "sequenceGenerator")
24 @Column(name = "event_id")
25 private Long id;
26
27 @NotNull
28 @Column(nullable = false)
29 private String principal;
30
31 @Column(name = "event_date")
32 private Instant auditEventDate;
33
34 @Column(name = "event_type")
35 private String auditEventType;
36
37 @ElementCollection
38 @MapKeyColumn(name = "name")
39 @Column(name = "value")
40 @CollectionTable(name = "auth_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id"))
41 private Map<String, String> data = new HashMap<>();
42
43 public Long getId() {
44 return id;
45 }
46
47 public void setId(Long id) {
48 this.id = id;
49 }
50
51 public String getPrincipal() {
52 return principal;
53 }
54
55 public void setPrincipal(String principal) {
56 this.principal = principal;
57 }
58
59 public Instant getAuditEventDate() {
60 return auditEventDate;
61 }
62
63 public void setAuditEventDate(Instant auditEventDate) {
64 this.auditEventDate = auditEventDate;
65 }
66
67 public String getAuditEventType() {
68 return auditEventType;
69 }
70
71 public void setAuditEventType(String auditEventType) {
72 this.auditEventType = auditEventType;
73 }
74
75 public Map<String, String> getData() {
76 return data;
77 }
78
79 public void setData(Map<String, String> data) {
80 this.data = data;
81 }
82
83 @Override
84 public boolean equals(Object o) {
85 if (this == o) {
86 return true;
87 }
88 if (!(o instanceof PersistentAuditEvent)) {
89 return false;
90 }
91 return id != null && id.equals(((PersistentAuditEvent) o).id);
92 }
93
94 @Override
95 public int hashCode() {
96 return 31;
97 }
98
99 @Override
100 public String toString() {
101 return "PersistentAuditEvent{" +
102 "principal='" + principal + '\'' +
103 ", auditEventDate=" + auditEventDate +
104 ", auditEventType='" + auditEventType + '\'' +
105 '}';
106 }
107 }
File src/main/java/hu/dns/honlap/domain/PieceOfNews.java added (mode: 100644) (index 0000000..4639067)
1 package hu.dns.honlap.domain;
2
3 import io.swagger.annotations.ApiModel;
4 import org.hibernate.annotations.Cache;
5 import org.hibernate.annotations.CacheConcurrencyStrategy;
6
7 import javax.persistence.*;
8 import javax.validation.constraints.*;
9
10 import java.io.Serializable;
11 import java.util.Objects;
12 import java.time.Instant;
13
14 /**
15 * Hírek
16 */
17 @ApiModel(description = "Hírek")
18 @Entity
19 @Table(name = "piece_of_news")
20 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
21 public class PieceOfNews implements Serializable {
22
23 private static final long serialVersionUID = 1L;
24
25 @Id
26 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
27 @SequenceGenerator(name = "sequenceGenerator")
28 private Long id;
29
30 @NotNull
31 @Column(name = "app_id", nullable = false)
32 private Integer appId;
33
34 @NotNull
35 @Column(name = "news_date", nullable = false)
36 private Instant newsDate;
37
38 @NotNull
39 @Size(max = 300)
40 @Column(name = "headline", length = 300, nullable = false)
41 private String headline;
42
43 @NotNull
44 @Size(max = 600)
45 @Column(name = "content", length = 600, nullable = false)
46 private String content;
47
48 @NotNull
49 @Size(max = 600)
50 @Column(name = "link", length = 600, nullable = false)
51 private String link;
52
53 @Column(name = "publish_date")
54 private Instant publishDate;
55
56 @Column(name = "created_by")
57 private String createdBy;
58
59 @Column(name = "created_date")
60 private Instant createdDate;
61
62 @Column(name = "last_modified_by")
63 private String lastModifiedBy;
64
65 @Column(name = "last_modified_date")
66 private Instant lastModifiedDate;
67
68 // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
69 public Long getId() {
70 return id;
71 }
72
73 public void setId(Long id) {
74 this.id = id;
75 }
76
77 public Integer getAppId() {
78 return appId;
79 }
80
81 public PieceOfNews appId(Integer appId) {
82 this.appId = appId;
83 return this;
84 }
85
86 public void setAppId(Integer appId) {
87 this.appId = appId;
88 }
89
90 public Instant getNewsDate() {
91 return newsDate;
92 }
93
94 public PieceOfNews newsDate(Instant newsDate) {
95 this.newsDate = newsDate;
96 return this;
97 }
98
99 public void setNewsDate(Instant newsDate) {
100 this.newsDate = newsDate;
101 }
102
103 public String getHeadline() {
104 return headline;
105 }
106
107 public PieceOfNews headline(String headline) {
108 this.headline = headline;
109 return this;
110 }
111
112 public void setHeadline(String headline) {
113 this.headline = headline;
114 }
115
116 public String getContent() {
117 return content;
118 }
119
120 public PieceOfNews content(String content) {
121 this.content = content;
122 return this;
123 }
124
125 public void setContent(String content) {
126 this.content = content;
127 }
128
129 public String getLink() {
130 return link;
131 }
132
133 public PieceOfNews link(String link) {
134 this.link = link;
135 return this;
136 }
137
138 public void setLink(String link) {
139 this.link = link;
140 }
141
142 public Instant getPublishDate() {
143 return publishDate;
144 }
145
146 public PieceOfNews publishDate(Instant publishDate) {
147 this.publishDate = publishDate;
148 return this;
149 }
150
151 public void setPublishDate(Instant publishDate) {
152 this.publishDate = publishDate;
153 }
154
155 public String getCreatedBy() {
156 return createdBy;
157 }
158
159 public PieceOfNews createdBy(String createdBy) {
160 this.createdBy = createdBy;
161 return this;
162 }
163
164 public void setCreatedBy(String createdBy) {
165 this.createdBy = createdBy;
166 }
167
168 public Instant getCreatedDate() {
169 return createdDate;
170 }
171
172 public PieceOfNews createdDate(Instant createdDate) {
173 this.createdDate = createdDate;
174 return this;
175 }
176
177 public void setCreatedDate(Instant createdDate) {
178 this.createdDate = createdDate;
179 }
180
181 public String getLastModifiedBy() {
182 return lastModifiedBy;
183 }
184
185 public PieceOfNews lastModifiedBy(String lastModifiedBy) {
186 this.lastModifiedBy = lastModifiedBy;
187 return this;
188 }
189
190 public void setLastModifiedBy(String lastModifiedBy) {
191 this.lastModifiedBy = lastModifiedBy;
192 }
193
194 public Instant getLastModifiedDate() {
195 return lastModifiedDate;
196 }
197
198 public PieceOfNews lastModifiedDate(Instant lastModifiedDate) {
199 this.lastModifiedDate = lastModifiedDate;
200 return this;
201 }
202
203 public void setLastModifiedDate(Instant lastModifiedDate) {
204 this.lastModifiedDate = lastModifiedDate;
205 }
206 // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
207
208 @Override
209 public boolean equals(Object o) {
210 if (this == o) {
211 return true;
212 }
213 if (!(o instanceof PieceOfNews)) {
214 return false;
215 }
216 return id != null && id.equals(((PieceOfNews) o).id);
217 }
218
219 @Override
220 public int hashCode() {
221 return 31;
222 }
223
224 @Override
225 public String toString() {
226 return "PieceOfNews{" +
227 "id=" + getId() +
228 ", appId=" + getAppId() +
229 ", newsDate='" + getNewsDate() + "'" +
230 ", headline='" + getHeadline() + "'" +
231 ", content='" + getContent() + "'" +
232 ", link='" + getLink() + "'" +
233 ", publishDate='" + getPublishDate() + "'" +
234 ", createdBy='" + getCreatedBy() + "'" +
235 ", createdDate='" + getCreatedDate() + "'" +
236 ", lastModifiedBy='" + getLastModifiedBy() + "'" +
237 ", lastModifiedDate='" + getLastModifiedDate() + "'" +
238 "}";
239 }
240 }
File src/main/java/hu/dns/honlap/domain/User.java added (mode: 100644) (index 0000000..2d21127)
1 package hu.dns.honlap.domain;
2
3 import hu.dns.honlap.config.Constants;
4
5 import com.fasterxml.jackson.annotation.JsonIgnore;
6 import org.apache.commons.lang3.StringUtils;
7 import org.hibernate.annotations.BatchSize;
8 import org.hibernate.annotations.Cache;
9 import org.hibernate.annotations.CacheConcurrencyStrategy;
10
11 import javax.persistence.*;
12 import javax.validation.constraints.Email;
13 import javax.validation.constraints.NotNull;
14 import javax.validation.constraints.Pattern;
15 import javax.validation.constraints.Size;
16 import java.io.Serializable;
17 import java.time.Instant;
18 import java.util.HashSet;
19 import java.util.Locale;
20 import java.util.Set;
21
22 /**
23 * A user.
24 */
25 @Entity
26 @Table(name = "auth_user")
27 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
28 public class User extends AbstractAuditingEntity implements Serializable {
29
30 private static final long serialVersionUID = 1L;
31
32 @Id
33 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
34 @SequenceGenerator(name = "sequenceGenerator")
35 private Long id;
36
37 @NotNull
38 @Pattern(regexp = Constants.LOGIN_REGEX)
39 @Size(min = 1, max = 50)
40 @Column(length = 50, unique = true, nullable = false)
41 private String login;
42
43 @JsonIgnore
44 @NotNull
45 @Size(min = 60, max = 60)
46 @Column(name = "password_hash", length = 60, nullable = false)
47 private String password;
48
49 @Size(max = 50)
50 @Column(name = "first_name", length = 50)
51 private String firstName;
52
53 @Size(max = 50)
54 @Column(name = "last_name", length = 50)
55 private String lastName;
56
57 @Email
58 @Size(min = 5, max = 254)
59 @Column(length = 254, unique = true)
60 private String email;
61
62 @NotNull
63 @Column(nullable = false)
64 private boolean activated = false;
65
66 @Size(min = 2, max = 10)
67 @Column(name = "lang_key", length = 10)
68 private String langKey;
69
70 @Size(max = 256)
71 @Column(name = "image_url", length = 256)
72 private String imageUrl;
73
74 @Size(max = 20)
75 @Column(name = "activation_key", length = 20)
76 @JsonIgnore
77 private String activationKey;
78
79 @Size(max = 20)
80 @Column(name = "reset_key", length = 20)
81
82 @JsonIgnore
83 private String resetKey;
84
85 @Column(name = "reset_date")
86 private Instant resetDate = null;
87
88 @JsonIgnore
89 @ManyToMany
90 @JoinTable(
91 name = "auth_user_authority",
92 joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
93 inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name")})
94 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
95 @BatchSize(size = 20)
96 private Set<Authority> authorities = new HashSet<>();
97
98 public Long getId() {
99 return id;
100 }
101
102 public void setId(Long id) {
103 this.id = id;
104 }
105
106 public String getLogin() {
107 return login;
108 }
109
110 // Lowercase the login before saving it in database
111 public void setLogin(String login) {
112 this.login = StringUtils.lowerCase(login, Locale.ENGLISH);
113 }
114
115 public String getPassword() {
116 return password;
117 }
118
119 public void setPassword(String password) {
120 this.password = password;
121 }
122
123 public String getFirstName() {
124 return firstName;
125 }
126
127 public void setFirstName(String firstName) {
128 this.firstName = firstName;
129 }
130
131 public String getLastName() {
132 return lastName;
133 }
134
135 public void setLastName(String lastName) {
136 this.lastName = lastName;
137 }
138
139 public String getEmail() {
140 return email;
141 }
142
143 public void setEmail(String email) {
144 this.email = email;
145 }
146
147 public String getImageUrl() {
148 return imageUrl;
149 }
150
151 public void setImageUrl(String imageUrl) {
152 this.imageUrl = imageUrl;
153 }
154
155 public boolean getActivated() {
156 return activated;
157 }
158
159 public void setActivated(boolean activated) {
160 this.activated = activated;
161 }
162
163 public String getActivationKey() {
164 return activationKey;
165 }
166
167 public void setActivationKey(String activationKey) {
168 this.activationKey = activationKey;
169 }
170
171 public String getResetKey() {
172 return resetKey;
173 }
174
175 public void setResetKey(String resetKey) {
176 this.resetKey = resetKey;
177 }
178
179 public Instant getResetDate() {
180 return resetDate;
181 }
182
183 public void setResetDate(Instant resetDate) {
184 this.resetDate = resetDate;
185 }
186
187 public String getLangKey() {
188 return langKey;
189 }
190
191 public void setLangKey(String langKey) {
192 this.langKey = langKey;
193 }
194
195 public Set<Authority> getAuthorities() {
196 return authorities;
197 }
198
199 public void setAuthorities(Set<Authority> authorities) {
200 this.authorities = authorities;
201 }
202
203 @Override
204 public boolean equals(Object o) {
205 if (this == o) {
206 return true;
207 }
208 if (!(o instanceof User)) {
209 return false;
210 }
211 return id != null && id.equals(((User) o).id);
212 }
213
214 @Override
215 public int hashCode() {
216 return 31;
217 }
218
219 @Override
220 public String toString() {
221 return "User{" +
222 "login='" + login + '\'' +
223 ", firstName='" + firstName + '\'' +
224 ", lastName='" + lastName + '\'' +
225 ", email='" + email + '\'' +
226 ", imageUrl='" + imageUrl + '\'' +
227 ", activated='" + activated + '\'' +
228 ", langKey='" + langKey + '\'' +
229 ", activationKey='" + activationKey + '\'' +
230 "}";
231 }
232 }
File src/main/java/hu/dns/honlap/domain/package-info.java added (mode: 100644) (index 0000000..8330bab)
1 /**
2 * JPA domain objects.
3 */
4 package hu.dns.honlap.domain;
File src/main/java/hu/dns/honlap/repository/AuthorityRepository.java added (mode: 100644) (index 0000000..970c3a3)
1 package hu.dns.honlap.repository;
2
3 import hu.dns.honlap.domain.Authority;
4
5 import org.springframework.data.jpa.repository.JpaRepository;
6
7 /**
8 * Spring Data JPA repository for the {@link Authority} entity.
9 */
10 public interface AuthorityRepository extends JpaRepository<Authority, String> {
11 }
File src/main/java/hu/dns/honlap/repository/CustomAuditEventRepository.java added (mode: 100644) (index 0000000..d21aff8)
1 package hu.dns.honlap.repository;
2
3 import hu.dns.honlap.config.Constants;
4 import hu.dns.honlap.config.audit.AuditEventConverter;
5 import hu.dns.honlap.domain.PersistentAuditEvent;
6
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import org.springframework.boot.actuate.audit.AuditEvent;
10 import org.springframework.boot.actuate.audit.AuditEventRepository;
11 import org.springframework.stereotype.Repository;
12 import org.springframework.transaction.annotation.Propagation;
13 import org.springframework.transaction.annotation.Transactional;
14
15 import java.time.Instant;
16 import java.util.*;
17
18 /**
19 * An implementation of Spring Boot's {@link AuditEventRepository}.
20 */
21 @Repository
22 public class CustomAuditEventRepository implements AuditEventRepository {
23
24 private static final String AUTHORIZATION_FAILURE = "AUTHORIZATION_FAILURE";
25
26 /**
27 * Should be the same as in Liquibase migration.
28 */
29 protected static final int EVENT_DATA_COLUMN_MAX_LENGTH = 255;
30
31 private final PersistenceAuditEventRepository persistenceAuditEventRepository;
32
33 private final AuditEventConverter auditEventConverter;
34
35 private final Logger log = LoggerFactory.getLogger(getClass());
36
37 public CustomAuditEventRepository(PersistenceAuditEventRepository persistenceAuditEventRepository,
38 AuditEventConverter auditEventConverter) {
39
40 this.persistenceAuditEventRepository = persistenceAuditEventRepository;
41 this.auditEventConverter = auditEventConverter;
42 }
43
44 @Override
45 public List<AuditEvent> find(String principal, Instant after, String type) {
46 Iterable<PersistentAuditEvent> persistentAuditEvents =
47 persistenceAuditEventRepository.findByPrincipalAndAuditEventDateAfterAndAuditEventType(principal, after, type);
48 return auditEventConverter.convertToAuditEvent(persistentAuditEvents);
49 }
50
51 @Override
52 @Transactional(propagation = Propagation.REQUIRES_NEW)
53 public void add(AuditEvent event) {
54 if (!AUTHORIZATION_FAILURE.equals(event.getType()) &&
55 !Constants.ANONYMOUS_USER.equals(event.getPrincipal())) {
56
57 PersistentAuditEvent persistentAuditEvent = new PersistentAuditEvent();
58 persistentAuditEvent.setPrincipal(event.getPrincipal());
59 persistentAuditEvent.setAuditEventType(event.getType());
60 persistentAuditEvent.setAuditEventDate(event.getTimestamp());
61 Map<String, String> eventData = auditEventConverter.convertDataToStrings(event.getData());
62 persistentAuditEvent.setData(truncate(eventData));
63 persistenceAuditEventRepository.save(persistentAuditEvent);
64 }
65 }
66
67 /**
68 * Truncate event data that might exceed column length.
69 */
70 private Map<String, String> truncate(Map<String, String> data) {
71 Map<String, String> results = new HashMap<>();
72
73 if (data != null) {
74 for (Map.Entry<String, String> entry : data.entrySet()) {
75 String value = entry.getValue();
76 if (value != null) {
77 int length = value.length();
78 if (length > EVENT_DATA_COLUMN_MAX_LENGTH) {
79 value = value.substring(0, EVENT_DATA_COLUMN_MAX_LENGTH);
80 log.warn("Event data for {} too long ({}) has been truncated to {}. Consider increasing column width.",
81 entry.getKey(), length, EVENT_DATA_COLUMN_MAX_LENGTH);
82 }
83 }
84 results.put(entry.getKey(), value);
85 }
86 }
87 return results;
88 }
89 }
File src/main/java/hu/dns/honlap/repository/PersistenceAuditEventRepository.java added (mode: 100644) (index 0000000..a19005e)
1 package hu.dns.honlap.repository;
2
3 import hu.dns.honlap.domain.PersistentAuditEvent;
4 import org.springframework.data.domain.Page;
5 import org.springframework.data.domain.Pageable;
6 import org.springframework.data.jpa.repository.JpaRepository;
7
8 import java.time.Instant;
9 import java.util.List;
10
11 /**
12 * Spring Data JPA repository for the {@link PersistentAuditEvent} entity.
13 */
14 public interface PersistenceAuditEventRepository extends JpaRepository<PersistentAuditEvent, Long> {
15
16 List<PersistentAuditEvent> findByPrincipal(String principal);
17
18 List<PersistentAuditEvent> findByPrincipalAndAuditEventDateAfterAndAuditEventType(String principal, Instant after, String type);
19
20 Page<PersistentAuditEvent> findAllByAuditEventDateBetween(Instant fromDate, Instant toDate, Pageable pageable);
21
22 List<PersistentAuditEvent> findByAuditEventDateBefore(Instant before);
23 }
File src/main/java/hu/dns/honlap/repository/PieceOfNewsRepository.java added (mode: 100644) (index 0000000..5a84329)
1 package hu.dns.honlap.repository;
2
3 import hu.dns.honlap.domain.PieceOfNews;
4
5 import org.springframework.data.jpa.repository.*;
6 import org.springframework.stereotype.Repository;
7
8 /**
9 * Spring Data repository for the PieceOfNews entity.
10 */
11 @SuppressWarnings("unused")
12 @Repository
13 public interface PieceOfNewsRepository extends JpaRepository<PieceOfNews, Long> {
14 }
File src/main/java/hu/dns/honlap/repository/UserRepository.java added (mode: 100644) (index 0000000..ea7b281)
1 package hu.dns.honlap.repository;
2
3 import hu.dns.honlap.domain.User;
4
5 import org.springframework.cache.annotation.Cacheable;
6 import org.springframework.data.domain.Page;
7
8 import org.springframework.data.domain.Pageable;
9 import org.springframework.data.jpa.repository.EntityGraph;
10 import org.springframework.data.jpa.repository.JpaRepository;
11 import org.springframework.stereotype.Repository;
12
13 import java.util.List;
14 import java.util.Optional;
15 import java.time.Instant;
16
17 /**
18 * Spring Data JPA repository for the {@link User} entity.
19 */
20 @Repository
21 public interface UserRepository extends JpaRepository<User, Long> {
22
23 String USERS_BY_LOGIN_CACHE = "usersByLogin";
24
25 String USERS_BY_EMAIL_CACHE = "usersByEmail";
26
27 Optional<User> findOneByActivationKey(String activationKey);
28
29 List<User> findAllByActivatedIsFalseAndActivationKeyIsNotNullAndCreatedDateBefore(Instant dateTime);
30
31 Optional<User> findOneByResetKey(String resetKey);
32
33 Optional<User> findOneByEmailIgnoreCase(String email);
34
35 Optional<User> findOneByLogin(String login);
36
37
38
39 @EntityGraph(attributePaths = "authorities")
40 Optional<User> findOneWithAuthoritiesById(Long id);
41
42 @EntityGraph(attributePaths = "authorities")
43 @Cacheable(cacheNames = USERS_BY_LOGIN_CACHE)
44 Optional<User> findOneWithAuthoritiesByLogin(String login);
45
46 @EntityGraph(attributePaths = "authorities")
47 @Cacheable(cacheNames = USERS_BY_EMAIL_CACHE)
48 Optional<User> findOneWithAuthoritiesByEmailIgnoreCase(String email);
49
50 Page<User> findAllByLoginNot(Pageable pageable, String login);
51 }
File src/main/java/hu/dns/honlap/repository/package-info.java added (mode: 100644) (index 0000000..6eefa79)
1 /**
2 * Spring Data JPA repositories.
3 */
4 package hu.dns.honlap.repository;
File src/main/java/hu/dns/honlap/security/AuthoritiesConstants.java added (mode: 100644) (index 0000000..bf07416)
1 package hu.dns.honlap.security;
2
3 /**
4 * Constants for Spring Security authorities.
5 */
6 public final class AuthoritiesConstants {
7
8 public static final String ADMIN = "ROLE_ADMIN";
9
10 public static final String USER = "ROLE_USER";
11
12 public static final String ANONYMOUS = "ROLE_ANONYMOUS";
13
14 private AuthoritiesConstants() {
15 }
16 }
File src/main/java/hu/dns/honlap/security/DomainUserDetailsService.java added (mode: 100644) (index 0000000..f06cbbb)
1 package hu.dns.honlap.security;
2
3 import hu.dns.honlap.domain.User;
4 import hu.dns.honlap.repository.UserRepository;
5 import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.security.core.GrantedAuthority;
9 import org.springframework.security.core.authority.SimpleGrantedAuthority;
10 import org.springframework.security.core.userdetails.UserDetails;
11 import org.springframework.security.core.userdetails.UserDetailsService;
12 import org.springframework.security.core.userdetails.UsernameNotFoundException;
13 import org.springframework.stereotype.Component;
14 import org.springframework.transaction.annotation.Transactional;
15
16 import java.util.*;
17 import java.util.stream.Collectors;
18
19 /**
20 * Authenticate a user from the database.
21 */
22 @Component("userDetailsService")
23 public class DomainUserDetailsService implements UserDetailsService {
24
25 private final Logger log = LoggerFactory.getLogger(DomainUserDetailsService.class);
26
27 private final UserRepository userRepository;
28
29 public DomainUserDetailsService(UserRepository userRepository) {
30 this.userRepository = userRepository;
31 }
32
33 @Override
34 @Transactional
35 public UserDetails loadUserByUsername(final String login) {
36 log.debug("Authenticating {}", login);
37
38 if (new EmailValidator().isValid(login, null)) {
39 return userRepository.findOneWithAuthoritiesByEmailIgnoreCase(login)
40 .map(user -> createSpringSecurityUser(login, user))
41 .orElseThrow(() -> new UsernameNotFoundException("User with email " + login + " was not found in the database"));
42 }
43
44 String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
45 return userRepository.findOneWithAuthoritiesByLogin(lowercaseLogin)
46 .map(user -> createSpringSecurityUser(lowercaseLogin, user))
47 .orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the database"));
48
49 }
50
51 private org.springframework.security.core.userdetails.User createSpringSecurityUser(String lowercaseLogin, User user) {
52 if (!user.getActivated()) {
53 throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated");
54 }
55 List<GrantedAuthority> grantedAuthorities = user.getAuthorities().stream()
56 .map(authority -> new SimpleGrantedAuthority(authority.getName()))
57 .collect(Collectors.toList());
58 return new org.springframework.security.core.userdetails.User(user.getLogin(),
59 user.getPassword(),
60 grantedAuthorities);
61 }
62 }
File src/main/java/hu/dns/honlap/security/SecurityUtils.java added (mode: 100644) (index 0000000..f6e7182)
1 package hu.dns.honlap.security;
2
3 import org.springframework.security.core.Authentication;
4 import org.springframework.security.core.GrantedAuthority;
5 import org.springframework.security.core.context.SecurityContext;
6 import org.springframework.security.core.context.SecurityContextHolder;
7 import org.springframework.security.core.userdetails.UserDetails;
8
9 import java.util.Optional;
10 import java.util.stream.Stream;
11
12 /**
13 * Utility class for Spring Security.
14 */
15 public final class SecurityUtils {
16
17 private SecurityUtils() {
18 }
19
20 /**
21 * Get the login of the current user.
22 *
23 * @return the login of the current user.
24 */
25 public static Optional<String> getCurrentUserLogin() {
26 SecurityContext securityContext = SecurityContextHolder.getContext();
27 return Optional.ofNullable(extractPrincipal(securityContext.getAuthentication()));
28 }
29
30 private static String extractPrincipal(Authentication authentication) {
31 if (authentication == null) {
32 return null;
33 } else if (authentication.getPrincipal() instanceof UserDetails) {
34 UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
35 return springSecurityUser.getUsername();
36 } else if (authentication.getPrincipal() instanceof String) {
37 return (String) authentication.getPrincipal();
38 }
39 return null;
40 }
41
42
43 /**
44 * Get the JWT of the current user.
45 *
46 * @return the JWT of the current user.
47 */
48 public static Optional<String> getCurrentUserJWT() {
49 SecurityContext securityContext = SecurityContextHolder.getContext();
50 return Optional.ofNullable(securityContext.getAuthentication())
51 .filter(authentication -> authentication.getCredentials() instanceof String)
52 .map(authentication -> (String) authentication.getCredentials());
53 }
54
55 /**
56 * Check if a user is authenticated.
57 *
58 * @return true if the user is authenticated, false otherwise.
59 */
60 public static boolean isAuthenticated() {
61 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
62 return authentication != null &&
63 getAuthorities(authentication).noneMatch(AuthoritiesConstants.ANONYMOUS::equals);
64 }
65
66 /**
67 * If the current user has a specific authority (security role).
68 * <p>
69 * The name of this method comes from the {@code isUserInRole()} method in the Servlet API.
70 *
71 * @param authority the authority to check.
72 * @return true if the current user has the authority, false otherwise.
73 */
74 public static boolean isCurrentUserInRole(String authority) {
75 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
76 return authentication != null &&
77 getAuthorities(authentication).anyMatch(authority::equals);
78 }
79
80 private static Stream<String> getAuthorities(Authentication authentication) {
81 return authentication.getAuthorities().stream()
82 .map(GrantedAuthority::getAuthority);
83 }
84
85 }
File src/main/java/hu/dns/honlap/security/SpringSecurityAuditorAware.java added (mode: 100644) (index 0000000..5271e75)
1 package hu.dns.honlap.security;
2
3 import hu.dns.honlap.config.Constants;
4
5 import java.util.Optional;
6
7 import org.springframework.data.domain.AuditorAware;
8 import org.springframework.stereotype.Component;
9
10 /**
11 * Implementation of {@link AuditorAware} based on Spring Security.
12 */
13 @Component
14 public class SpringSecurityAuditorAware implements AuditorAware<String> {
15
16 @Override
17 public Optional<String> getCurrentAuditor() {
18 return Optional.of(SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM_ACCOUNT));
19 }
20 }
File src/main/java/hu/dns/honlap/security/UserNotActivatedException.java added (mode: 100644) (index 0000000..b6c0201)
1 package hu.dns.honlap.security;
2
3 import org.springframework.security.core.AuthenticationException;
4
5 /**
6 * This exception is thrown in case of a not activated user trying to authenticate.
7 */
8 public class UserNotActivatedException extends AuthenticationException {
9
10 private static final long serialVersionUID = 1L;
11
12 public UserNotActivatedException(String message) {
13 super(message);
14 }
15
16 public UserNotActivatedException(String message, Throwable t) {
17 super(message, t);
18 }
19 }
File src/main/java/hu/dns/honlap/security/jwt/JWTConfigurer.java added (mode: 100644) (index 0000000..c8bddf1)
1 package hu.dns.honlap.security.jwt;
2
3 import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
4 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
5 import org.springframework.security.web.DefaultSecurityFilterChain;
6 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
7
8 public class JWTConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
9
10 private final TokenProvider tokenProvider;
11
12 public JWTConfigurer(TokenProvider tokenProvider) {
13 this.tokenProvider = tokenProvider;
14 }
15
16 @Override
17 public void configure(HttpSecurity http) {
18 JWTFilter customFilter = new JWTFilter(tokenProvider);
19 http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
20 }
21 }
File src/main/java/hu/dns/honlap/security/jwt/JWTFilter.java added (mode: 100644) (index 0000000..5be409c)
1 package hu.dns.honlap.security.jwt;
2
3 import org.springframework.security.core.Authentication;
4 import org.springframework.security.core.context.SecurityContextHolder;
5 import org.springframework.util.StringUtils;
6 import org.springframework.web.filter.GenericFilterBean;
7
8 import javax.servlet.FilterChain;
9 import javax.servlet.ServletException;
10 import javax.servlet.ServletRequest;
11 import javax.servlet.ServletResponse;
12 import javax.servlet.http.HttpServletRequest;
13 import java.io.IOException;
14
15 /**
16 * Filters incoming requests and installs a Spring Security principal if a header corresponding to a valid user is
17 * found.
18 */
19 public class JWTFilter extends GenericFilterBean {
20
21 public static final String AUTHORIZATION_HEADER = "Authorization";
22
23 private final TokenProvider tokenProvider;
24
25 public JWTFilter(TokenProvider tokenProvider) {
26 this.tokenProvider = tokenProvider;
27 }
28
29 @Override
30 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
31 throws IOException, ServletException {
32 HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
33 String jwt = resolveToken(httpServletRequest);
34 if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) {
35 Authentication authentication = this.tokenProvider.getAuthentication(jwt);
36 SecurityContextHolder.getContext().setAuthentication(authentication);
37 }
38 filterChain.doFilter(servletRequest, servletResponse);
39 }
40
41 private String resolveToken(HttpServletRequest request) {
42 String bearerToken = request.getHeader(AUTHORIZATION_HEADER);
43 if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
44 return bearerToken.substring(7);
45 }
46 return null;
47 }
48 }
File src/main/java/hu/dns/honlap/security/jwt/TokenProvider.java added (mode: 100644) (index 0000000..dee1a70)
1 package hu.dns.honlap.security.jwt;
2
3 import java.nio.charset.StandardCharsets;
4 import java.security.Key;
5 import java.util.*;
6 import java.util.stream.Collectors;
7 import javax.annotation.PostConstruct;
8
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
12 import org.springframework.security.core.Authentication;
13 import org.springframework.security.core.GrantedAuthority;
14 import org.springframework.security.core.authority.SimpleGrantedAuthority;
15 import org.springframework.security.core.userdetails.User;
16 import org.springframework.stereotype.Component;
17 import org.springframework.util.StringUtils;
18
19 import io.github.jhipster.config.JHipsterProperties;
20 import io.jsonwebtoken.*;
21 import io.jsonwebtoken.io.Decoders;
22 import io.jsonwebtoken.security.Keys;
23
24 @Component
25 public class TokenProvider {
26
27 private final Logger log = LoggerFactory.getLogger(TokenProvider.class);
28
29 private static final String AUTHORITIES_KEY = "auth";
30
31 private Key key;
32
33 private long tokenValidityInMilliseconds;
34
35 private long tokenValidityInMillisecondsForRememberMe;
36
37 private final JHipsterProperties jHipsterProperties;
38
39 public TokenProvider(JHipsterProperties jHipsterProperties) {
40 this.jHipsterProperties = jHipsterProperties;
41 }
42
43 @PostConstruct
44 public void init() {
45 byte[] keyBytes;
46 String secret = jHipsterProperties.getSecurity().getAuthentication().getJwt().getSecret();
47 if (!StringUtils.isEmpty(secret)) {
48 log.warn("Warning: the JWT key used is not Base64-encoded. " +
49 "We recommend using the `jhipster.security.authentication.jwt.base64-secret` key for optimum security.");
50 keyBytes = secret.getBytes(StandardCharsets.UTF_8);
51 } else {
52 log.debug("Using a Base64-encoded JWT secret key");
53 keyBytes = Decoders.BASE64.decode(jHipsterProperties.getSecurity().getAuthentication().getJwt().getBase64Secret());
54 }
55 this.key = Keys.hmacShaKeyFor(keyBytes);
56 this.tokenValidityInMilliseconds =
57 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSeconds();
58 this.tokenValidityInMillisecondsForRememberMe =
59 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt()
60 .getTokenValidityInSecondsForRememberMe();
61 }
62
63 public String createToken(Authentication authentication, boolean rememberMe) {
64 String authorities = authentication.getAuthorities().stream()
65 .map(GrantedAuthority::getAuthority)
66 .collect(Collectors.joining(","));
67
68 long now = (new Date()).getTime();
69 Date validity;
70 if (rememberMe) {
71 validity = new Date(now + this.tokenValidityInMillisecondsForRememberMe);
72 } else {
73 validity = new Date(now + this.tokenValidityInMilliseconds);
74 }
75
76 return Jwts.builder()
77 .setSubject(authentication.getName())
78 .claim(AUTHORITIES_KEY, authorities)
79 .signWith(key, SignatureAlgorithm.HS512)
80 .setExpiration(validity)
81 .compact();
82 }
83
84 public Authentication getAuthentication(String token) {
85 Claims claims = Jwts.parser()
86 .setSigningKey(key)
87 .parseClaimsJws(token)
88 .getBody();
89
90 Collection<? extends GrantedAuthority> authorities =
91 Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
92 .map(SimpleGrantedAuthority::new)
93 .collect(Collectors.toList());
94
95 User principal = new User(claims.getSubject(), "", authorities);
96
97 return new UsernamePasswordAuthenticationToken(principal, token, authorities);
98 }
99
100 public boolean validateToken(String authToken) {
101 try {
102 Jwts.parser().setSigningKey(key).parseClaimsJws(authToken);
103 return true;
104 } catch (JwtException | IllegalArgumentException e) {
105 log.info("Invalid JWT token.");
106 log.trace("Invalid JWT token trace.", e);
107 }
108 return false;
109 }
110 }
File src/main/java/hu/dns/honlap/security/package-info.java added (mode: 100644) (index 0000000..bf2571c)
1 /**
2 * Spring Security configuration.
3 */
4 package hu.dns.honlap.security;
File src/main/java/hu/dns/honlap/service/AuditEventService.java added (mode: 100644) (index 0000000..40ab0e0)
1 package hu.dns.honlap.service;
2
3 import io.github.jhipster.config.JHipsterProperties;
4 import hu.dns.honlap.config.audit.AuditEventConverter;
5 import hu.dns.honlap.repository.PersistenceAuditEventRepository;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.boot.actuate.audit.AuditEvent;
9 import org.springframework.data.domain.Page;
10 import org.springframework.data.domain.Pageable;
11 import org.springframework.scheduling.annotation.Scheduled;
12 import org.springframework.stereotype.Service;
13 import org.springframework.transaction.annotation.Transactional;
14
15 import java.time.Instant;
16 import java.time.temporal.ChronoUnit;
17 import java.util.Optional;
18
19 /**
20 * Service for managing audit events.
21 * <p>
22 * This is the default implementation to support SpringBoot Actuator {@code AuditEventRepository}.
23 */
24 @Service
25 @Transactional
26 public class AuditEventService {
27
28 private final Logger log = LoggerFactory.getLogger(AuditEventService.class);
29
30 private final JHipsterProperties jHipsterProperties;
31
32 private final PersistenceAuditEventRepository persistenceAuditEventRepository;
33
34 private final AuditEventConverter auditEventConverter;
35
36 public AuditEventService(
37 PersistenceAuditEventRepository persistenceAuditEventRepository,
38 AuditEventConverter auditEventConverter, JHipsterProperties jhipsterProperties) {
39
40 this.persistenceAuditEventRepository = persistenceAuditEventRepository;
41 this.auditEventConverter = auditEventConverter;
42 this.jHipsterProperties = jhipsterProperties;
43 }
44
45 /**
46 * Old audit events should be automatically deleted after 30 days.
47 *
48 * This is scheduled to get fired at 12:00 (am).
49 */
50 @Scheduled(cron = "0 0 12 * * ?")
51 public void removeOldAuditEvents() {
52 persistenceAuditEventRepository
53 .findByAuditEventDateBefore(Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod(), ChronoUnit.DAYS))
54 .forEach(auditEvent -> {
55 log.debug("Deleting audit data {}", auditEvent);
56 persistenceAuditEventRepository.delete(auditEvent);
57 });
58 }
59
60 public Page<AuditEvent> findAll(Pageable pageable) {
61 return persistenceAuditEventRepository.findAll(pageable)
62 .map(auditEventConverter::convertToAuditEvent);
63 }
64
65 public Page<AuditEvent> findByDates(Instant fromDate, Instant toDate, Pageable pageable) {
66 return persistenceAuditEventRepository.findAllByAuditEventDateBetween(fromDate, toDate, pageable)
67 .map(auditEventConverter::convertToAuditEvent);
68 }
69
70 public Optional<AuditEvent> find(Long id) {
71 return persistenceAuditEventRepository.findById(id)
72 .map(auditEventConverter::convertToAuditEvent);
73 }
74 }
File src/main/java/hu/dns/honlap/service/EmailAlreadyUsedException.java added (mode: 100644) (index 0000000..30b1739)
1 package hu.dns.honlap.service;
2
3 public class EmailAlreadyUsedException extends RuntimeException {
4
5 private static final long serialVersionUID = 1L;
6
7 public EmailAlreadyUsedException() {
8 super("Email is already in use!");
9 }
10
11 }
File src/main/java/hu/dns/honlap/service/InvalidPasswordException.java added (mode: 100644) (index 0000000..fad3ecb)
1 package hu.dns.honlap.service;
2
3 public class InvalidPasswordException extends RuntimeException {
4
5 private static final long serialVersionUID = 1L;
6
7 public InvalidPasswordException() {
8 super("Incorrect password");
9 }
10
11 }
File src/main/java/hu/dns/honlap/service/MailService.java added (mode: 100644) (index 0000000..44d8ebd)
1 package hu.dns.honlap.service;
2
3 import hu.dns.honlap.domain.User;
4
5 import io.github.jhipster.config.JHipsterProperties;
6
7 import java.nio.charset.StandardCharsets;
8 import java.util.Locale;
9 import javax.mail.MessagingException;
10 import javax.mail.internet.MimeMessage;
11
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14 import org.springframework.context.MessageSource;
15 import org.springframework.mail.MailException;
16 import org.springframework.mail.javamail.JavaMailSender;
17 import org.springframework.mail.javamail.MimeMessageHelper;
18 import org.springframework.scheduling.annotation.Async;
19 import org.springframework.stereotype.Service;
20 import org.thymeleaf.context.Context;
21 import org.thymeleaf.spring5.SpringTemplateEngine;
22
23 /**
24 * Service for sending emails.
25 * <p>
26 * We use the {@link Async} annotation to send emails asynchronously.
27 */
28 @Service
29 public class MailService {
30
31 private final Logger log = LoggerFactory.getLogger(MailService.class);
32
33 private static final String USER = "user";
34
35 private static final String BASE_URL = "baseUrl";
36
37 private final JHipsterProperties jHipsterProperties;
38
39 private final JavaMailSender javaMailSender;
40
41 private final MessageSource messageSource;
42
43 private final SpringTemplateEngine templateEngine;
44
45 public MailService(JHipsterProperties jHipsterProperties, JavaMailSender javaMailSender,
46 MessageSource messageSource, SpringTemplateEngine templateEngine) {
47
48 this.jHipsterProperties = jHipsterProperties;
49 this.javaMailSender = javaMailSender;
50 this.messageSource = messageSource;
51 this.templateEngine = templateEngine;
52 }
53
54 @Async
55 public void sendEmail(String to, String subject, String content, boolean isMultipart, boolean isHtml) {
56 log.debug("Send email[multipart '{}' and html '{}'] to '{}' with subject '{}' and content={}",
57 isMultipart, isHtml, to, subject, content);
58
59 // Prepare message using a Spring helper
60 MimeMessage mimeMessage = javaMailSender.createMimeMessage();
61 try {
62 MimeMessageHelper message = new MimeMessageHelper(mimeMessage, isMultipart, StandardCharsets.UTF_8.name());
63 message.setTo(to);
64 message.setFrom(jHipsterProperties.getMail().getFrom());
65 message.setSubject(subject);
66 message.setText(content, isHtml);
67 javaMailSender.send(mimeMessage);
68 log.debug("Sent email to User '{}'", to);
69 } catch (MailException | MessagingException e) {
70 log.warn("Email could not be sent to user '{}'", to, e);
71 }
72 }
73
74 @Async
75 public void sendEmailFromTemplate(User user, String templateName, String titleKey) {
76 if (user.getEmail() == null) {
77 log.debug("Email doesn't exist for user '{}'", user.getLogin());
78 return;
79 }
80 Locale locale = Locale.forLanguageTag(user.getLangKey());
81 Context context = new Context(locale);
82 context.setVariable(USER, user);
83 context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl());
84 String content = templateEngine.process(templateName, context);
85 String subject = messageSource.getMessage(titleKey, null, locale);
86 sendEmail(user.getEmail(), subject, content, false, true);
87 }
88
89 @Async
90 public void sendActivationEmail(User user) {
91 log.debug("Sending activation email to '{}'", user.getEmail());
92 sendEmailFromTemplate(user, "mail/activationEmail", "email.activation.title");
93 }
94
95 @Async
96 public void sendCreationEmail(User user) {
97 log.debug("Sending creation email to '{}'", user.getEmail());
98 sendEmailFromTemplate(user, "mail/creationEmail", "email.activation.title");
99 }
100
101 @Async
102 public void sendPasswordResetMail(User user) {
103 log.debug("Sending password reset email to '{}'", user.getEmail());
104 sendEmailFromTemplate(user, "mail/passwordResetEmail", "email.reset.title");
105 }
106 }
File src/main/java/hu/dns/honlap/service/UserService.java added (mode: 100644) (index 0000000..cbfa5ce)
1 package hu.dns.honlap.service;
2
3 import hu.dns.honlap.config.Constants;
4 import hu.dns.honlap.domain.Authority;
5 import hu.dns.honlap.domain.User;
6 import hu.dns.honlap.repository.AuthorityRepository;
7 import hu.dns.honlap.repository.UserRepository;
8 import hu.dns.honlap.security.AuthoritiesConstants;
9 import hu.dns.honlap.security.SecurityUtils;
10 import hu.dns.honlap.service.dto.UserDTO;
11
12 import io.github.jhipster.security.RandomUtil;
13
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16 import org.springframework.cache.CacheManager;
17 import org.springframework.data.domain.Page;
18 import org.springframework.data.domain.Pageable;
19 import org.springframework.scheduling.annotation.Scheduled;
20 import org.springframework.security.crypto.password.PasswordEncoder;
21 import org.springframework.stereotype.Service;
22 import org.springframework.transaction.annotation.Transactional;
23
24 import java.time.Instant;
25 import java.time.temporal.ChronoUnit;
26 import java.util.*;
27 import java.util.stream.Collectors;
28
29 /**
30 * Service class for managing users.
31 */
32 @Service
33 @Transactional
34 public class UserService {
35
36 private final Logger log = LoggerFactory.getLogger(UserService.class);
37
38 private final UserRepository userRepository;
39
40 private final PasswordEncoder passwordEncoder;
41
42 private final AuthorityRepository authorityRepository;
43
44 private final CacheManager cacheManager;
45
46 public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, AuthorityRepository authorityRepository, CacheManager cacheManager) {
47 this.userRepository = userRepository;
48 this.passwordEncoder = passwordEncoder;
49 this.authorityRepository = authorityRepository;
50 this.cacheManager = cacheManager;
51 }
52
53 public Optional<User> activateRegistration(String key) {
54 log.debug("Activating user for activation key {}", key);
55 return userRepository.findOneByActivationKey(key)
56 .map(user -> {
57 // activate given user for the registration key.
58 user.setActivated(true);
59 user.setActivationKey(null);
60 this.clearUserCaches(user);
61 log.debug("Activated user: {}", user);
62 return user;
63 });
64 }
65
66 public Optional<User> completePasswordReset(String newPassword, String key) {
67 log.debug("Reset user password for reset key {}", key);
68 return userRepository.findOneByResetKey(key)
69 .filter(user -> user.getResetDate().isAfter(Instant.now().minusSeconds(86400)))
70 .map(user -> {
71 user.setPassword(passwordEncoder.encode(newPassword));
72 user.setResetKey(null);
73 user.setResetDate(null);
74 this.clearUserCaches(user);
75 return user;
76 });
77 }
78
79 public Optional<User> requestPasswordReset(String mail) {
80 return userRepository.findOneByEmailIgnoreCase(mail)
81 .filter(User::getActivated)
82 .map(user -> {
83 user.setResetKey(RandomUtil.generateResetKey());
84 user.setResetDate(Instant.now());
85 this.clearUserCaches(user);
86 return user;
87 });
88 }
89
90 public User registerUser(UserDTO userDTO, String password) {
91 userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()).ifPresent(existingUser -> {
92 boolean removed = removeNonActivatedUser(existingUser);
93 if (!removed) {
94 throw new UsernameAlreadyUsedException();
95 }
96 });
97 userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()).ifPresent(existingUser -> {
98 boolean removed = removeNonActivatedUser(existingUser);
99 if (!removed) {
100 throw new EmailAlreadyUsedException();
101 }
102 });
103 User newUser = new User();
104 String encryptedPassword = passwordEncoder.encode(password);
105 newUser.setLogin(userDTO.getLogin().toLowerCase());
106 // new user gets initially a generated password
107 newUser.setPassword(encryptedPassword);
108 newUser.setFirstName(userDTO.getFirstName());
109 newUser.setLastName(userDTO.getLastName());
110 if (userDTO.getEmail() != null) {
111 newUser.setEmail(userDTO.getEmail().toLowerCase());
112 }
113 newUser.setImageUrl(userDTO.getImageUrl());
114 newUser.setLangKey(userDTO.getLangKey());
115 // new user is not active
116 newUser.setActivated(false);
117 // new user gets registration key
118 newUser.setActivationKey(RandomUtil.generateActivationKey());
119 Set<Authority> authorities = new HashSet<>();
120 authorityRepository.findById(AuthoritiesConstants.USER).ifPresent(authorities::add);
121 newUser.setAuthorities(authorities);
122 userRepository.save(newUser);
123 this.clearUserCaches(newUser);
124 log.debug("Created Information for User: {}", newUser);
125 return newUser;
126 }
127
128 private boolean removeNonActivatedUser(User existingUser) {
129 if (existingUser.getActivated()) {
130 return false;
131 }
132 userRepository.delete(existingUser);
133 userRepository.flush();
134 this.clearUserCaches(existingUser);
135 return true;
136 }
137
138 public User createUser(UserDTO userDTO) {
139 User user = new User();
140 user.setLogin(userDTO.getLogin().toLowerCase());
141 user.setFirstName(userDTO.getFirstName());
142 user.setLastName(userDTO.getLastName());
143 if (userDTO.getEmail() != null) {
144 user.setEmail(userDTO.getEmail().toLowerCase());
145 }
146 user.setImageUrl(userDTO.getImageUrl());
147 if (userDTO.getLangKey() == null) {
148 user.setLangKey(Constants.DEFAULT_LANGUAGE); // default language
149 } else {
150 user.setLangKey(userDTO.getLangKey());
151 }
152 String encryptedPassword = passwordEncoder.encode(RandomUtil.generatePassword());
153 user.setPassword(encryptedPassword);
154 user.setResetKey(RandomUtil.generateResetKey());
155 user.setResetDate(Instant.now());
156 user.setActivated(true);
157 if (userDTO.getAuthorities() != null) {
158 Set<Authority> authorities = userDTO.getAuthorities().stream()
159 .map(authorityRepository::findById)
160 .filter(Optional::isPresent)
161 .map(Optional::get)
162 .collect(Collectors.toSet());
163 user.setAuthorities(authorities);
164 }
165 userRepository.save(user);
166 this.clearUserCaches(user);
167 log.debug("Created Information for User: {}", user);
168 return user;
169 }
170
171 /**
172 * Update basic information (first name, last name, email, language) for the current user.
173 *
174 * @param firstName first name of user.
175 * @param lastName last name of user.
176 * @param email email id of user.
177 * @param langKey language key.
178 * @param imageUrl image URL of user.
179 */
180 public void updateUser(String firstName, String lastName, String email, String langKey, String imageUrl) {
181 SecurityUtils.getCurrentUserLogin()
182 .flatMap(userRepository::findOneByLogin)
183 .ifPresent(user -> {
184 user.setFirstName(firstName);
185 user.setLastName(lastName);
186 if (email != null) {
187 user.setEmail(email.toLowerCase());
188 }
189 user.setLangKey(langKey);
190 user.setImageUrl(imageUrl);
191 this.clearUserCaches(user);
192 log.debug("Changed Information for User: {}", user);
193 });
194 }
195
196 /**
197 * Update all information for a specific user, and return the modified user.
198 *
199 * @param userDTO user to update.
200 * @return updated user.
201 */
202 public Optional<UserDTO> updateUser(UserDTO userDTO) {
203 return Optional.of(userRepository
204 .findById(userDTO.getId()))
205 .filter(Optional::isPresent)
206 .map(Optional::get)
207 .map(user -> {
208 this.clearUserCaches(user);
209 user.setLogin(userDTO.getLogin().toLowerCase());
210 user.setFirstName(userDTO.getFirstName());
211 user.setLastName(userDTO.getLastName());
212 if (userDTO.getEmail() != null) {
213 user.setEmail(userDTO.getEmail().toLowerCase());
214 }
215 user.setImageUrl(userDTO.getImageUrl());
216 user.setActivated(userDTO.isActivated());
217 user.setLangKey(userDTO.getLangKey());
218 Set<Authority> managedAuthorities = user.getAuthorities();
219 managedAuthorities.clear();
220 userDTO.getAuthorities().stream()
221 .map(authorityRepository::findById)
222 .filter(Optional::isPresent)
223 .map(Optional::get)
224 .forEach(managedAuthorities::add);
225 this.clearUserCaches(user);
226 log.debug("Changed Information for User: {}", user);
227 return user;
228 })
229 .map(UserDTO::new);
230 }
231
232 public void deleteUser(String login) {
233 userRepository.findOneByLogin(login).ifPresent(user -> {
234 userRepository.delete(user);
235 this.clearUserCaches(user);
236 log.debug("Deleted User: {}", user);
237 });
238 }
239
240 public void changePassword(String currentClearTextPassword, String newPassword) {
241 SecurityUtils.getCurrentUserLogin()
242 .flatMap(userRepository::findOneByLogin)
243 .ifPresent(user -> {
244 String currentEncryptedPassword = user.getPassword();
245 if (!passwordEncoder.matches(currentClearTextPassword, currentEncryptedPassword)) {
246 throw new InvalidPasswordException();
247 }
248 String encryptedPassword = passwordEncoder.encode(newPassword);
249 user.setPassword(encryptedPassword);
250 this.clearUserCaches(user);
251 log.debug("Changed password for User: {}", user);
252 });
253 }
254
255 @Transactional(readOnly = true)
256 public Page<UserDTO> getAllManagedUsers(Pageable pageable) {
257 return userRepository.findAllByLoginNot(pageable, Constants.ANONYMOUS_USER).map(UserDTO::new);
258 }
259
260 @Transactional(readOnly = true)
261 public Optional<User> getUserWithAuthoritiesByLogin(String login) {
262 return userRepository.findOneWithAuthoritiesByLogin(login);
263 }
264
265 @Transactional(readOnly = true)
266 public Optional<User> getUserWithAuthorities(Long id) {
267 return userRepository.findOneWithAuthoritiesById(id);
268 }
269
270 @Transactional(readOnly = true)
271 public Optional<User> getUserWithAuthorities() {
272 return SecurityUtils.getCurrentUserLogin().flatMap(userRepository::findOneWithAuthoritiesByLogin);
273 }
274
275 /**
276 * Not activated users should be automatically deleted after 3 days.
277 * <p>
278 * This is scheduled to get fired everyday, at 01:00 (am).
279 */
280 @Scheduled(cron = "0 0 1 * * ?")
281 public void removeNotActivatedUsers() {
282 userRepository
283 .findAllByActivatedIsFalseAndActivationKeyIsNotNullAndCreatedDateBefore(Instant.now().minus(3, ChronoUnit.DAYS))
284 .forEach(user -> {
285 log.debug("Deleting not activated user {}", user.getLogin());
286 userRepository.delete(user);
287 this.clearUserCaches(user);
288 });
289 }
290
291 /**
292 * Gets a list of all the authorities.
293 * @return a list of all the authorities.
294 */
295 public List<String> getAuthorities() {
296 return authorityRepository.findAll().stream().map(Authority::getName).collect(Collectors.toList());
297 }
298
299
300 private void clearUserCaches(User user) {
301 Objects.requireNonNull(cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE)).evict(user.getLogin());
302 if (user.getEmail() != null) {
303 Objects.requireNonNull(cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE)).evict(user.getEmail());
304 }
305 }
306 }
File src/main/java/hu/dns/honlap/service/UsernameAlreadyUsedException.java added (mode: 100644) (index 0000000..37566c4)
1 package hu.dns.honlap.service;
2
3 public class UsernameAlreadyUsedException extends RuntimeException {
4
5 private static final long serialVersionUID = 1L;
6
7 public UsernameAlreadyUsedException() {
8 super("Login name already used!");
9 }
10
11 }
File src/main/java/hu/dns/honlap/service/dto/PasswordChangeDTO.java added (mode: 100644) (index 0000000..056edf3)
1 package hu.dns.honlap.service.dto;
2
3 /**
4 * A DTO representing a password change required data - current and new password.
5 */
6 public class PasswordChangeDTO {
7 private String currentPassword;
8 private String newPassword;
9
10 public PasswordChangeDTO() {
11 // Empty constructor needed for Jackson.
12 }
13
14 public PasswordChangeDTO(String currentPassword, String newPassword) {
15 this.currentPassword = currentPassword;
16 this.newPassword = newPassword;
17 }
18
19 public String getCurrentPassword() {
20
21 return currentPassword;
22 }
23
24 public void setCurrentPassword(String currentPassword) {
25 this.currentPassword = currentPassword;
26 }
27
28 public String getNewPassword() {
29 return newPassword;
30 }
31
32 public void setNewPassword(String newPassword) {
33 this.newPassword = newPassword;
34 }
35 }
File src/main/java/hu/dns/honlap/service/dto/UserDTO.java added (mode: 100644) (index 0000000..5cb3af8)
1 package hu.dns.honlap.service.dto;
2
3 import hu.dns.honlap.config.Constants;
4
5 import hu.dns.honlap.domain.Authority;
6 import hu.dns.honlap.domain.User;
7
8 import javax.validation.constraints.*;
9 import java.time.Instant;
10 import java.util.Set;
11 import java.util.stream.Collectors;
12
13 /**
14 * A DTO representing a user, with his authorities.
15 */
16 public class UserDTO {
17
18 private Long id;
19
20 @NotBlank
21 @Pattern(regexp = Constants.LOGIN_REGEX)
22 @Size(min = 1, max = 50)
23 private String login;
24
25 @Size(max = 50)
26 private String firstName;
27
28 @Size(max = 50)
29 private String lastName;
30
31 @Email
32 @Size(min = 5, max = 254)
33 private String email;
34
35 @Size(max = 256)
36 private String imageUrl;
37
38 private boolean activated = false;
39
40 @Size(min = 2, max = 10)
41 private String langKey;
42
43 private String createdBy;
44
45 private Instant createdDate;
46
47 private String lastModifiedBy;
48
49 private Instant lastModifiedDate;
50
51 private Set<String> authorities;
52
53 public UserDTO() {
54 // Empty constructor needed for Jackson.
55 }
56
57 public UserDTO(User user) {
58 this.id = user.getId();
59 this.login = user.getLogin();
60 this.firstName = user.getFirstName();
61 this.lastName = user.getLastName();
62 this.email = user.getEmail();
63 this.activated = user.getActivated();
64 this.imageUrl = user.getImageUrl();
65 this.langKey = user.getLangKey();
66 this.createdBy = user.getCreatedBy();
67 this.createdDate = user.getCreatedDate();
68 this.lastModifiedBy = user.getLastModifiedBy();
69 this.lastModifiedDate = user.getLastModifiedDate();
70 this.authorities = user.getAuthorities().stream()
71 .map(Authority::getName)
72 .collect(Collectors.toSet());
73 }
74
75 public Long getId() {
76 return id;
77 }
78
79 public void setId(Long id) {
80 this.id = id;
81 }
82
83 public String getLogin() {
84 return login;
85 }
86
87 public void setLogin(String login) {
88 this.login = login;
89 }
90
91 public String getFirstName() {
92 return firstName;
93 }
94
95 public void setFirstName(String firstName) {
96 this.firstName = firstName;
97 }
98
99 public String getLastName() {
100 return lastName;
101 }
102
103 public void setLastName(String lastName) {
104 this.lastName = lastName;
105 }
106
107 public String getEmail() {
108 return email;
109 }
110
111 public void setEmail(String email) {
112 this.email = email;
113 }
114
115 public String getImageUrl() {
116 return imageUrl;
117 }
118
119 public void setImageUrl(String imageUrl) {
120 this.imageUrl = imageUrl;
121 }
122
123 public boolean isActivated() {
124 return activated;
125 }
126
127 public void setActivated(boolean activated) {
128 this.activated = activated;
129 }
130
131 public String getLangKey() {
132 return langKey;
133 }
134
135 public void setLangKey(String langKey) {
136 this.langKey = langKey;
137 }
138
139 public String getCreatedBy() {
140 return createdBy;
141 }
142
143 public void setCreatedBy(String createdBy) {
144 this.createdBy = createdBy;
145 }
146
147 public Instant getCreatedDate() {
148 return createdDate;
149 }
150
151 public void setCreatedDate(Instant createdDate) {
152 this.createdDate = createdDate;
153 }
154
155 public String getLastModifiedBy() {
156 return lastModifiedBy;
157 }
158
159 public void setLastModifiedBy(String lastModifiedBy) {
160 this.lastModifiedBy = lastModifiedBy;
161 }
162
163 public Instant getLastModifiedDate() {
164 return lastModifiedDate;
165 }
166
167 public void setLastModifiedDate(Instant lastModifiedDate) {
168 this.lastModifiedDate = lastModifiedDate;
169 }
170
171 public Set<String> getAuthorities() {
172 return authorities;
173 }
174
175 public void setAuthorities(Set<String> authorities) {
176 this.authorities = authorities;
177 }
178
179 @Override
180 public String toString() {
181 return "UserDTO{" +
182 "login='" + login + '\'' +
183 ", firstName='" + firstName + '\'' +
184 ", lastName='" + lastName + '\'' +
185 ", email='" + email + '\'' +
186 ", imageUrl='" + imageUrl + '\'' +
187 ", activated=" + activated +
188 ", langKey='" + langKey + '\'' +
189 ", createdBy=" + createdBy +
190 ", createdDate=" + createdDate +
191 ", lastModifiedBy='" + lastModifiedBy + '\'' +
192 ", lastModifiedDate=" + lastModifiedDate +
193 ", authorities=" + authorities +
194 "}";
195 }
196 }
File src/main/java/hu/dns/honlap/service/dto/package-info.java added (mode: 100644) (index 0000000..21d1c52)
1 /**
2 * Data Transfer Objects.
3 */
4 package hu.dns.honlap.service.dto;
File src/main/java/hu/dns/honlap/service/mapper/UserMapper.java added (mode: 100644) (index 0000000..cc5d50c)
1 package hu.dns.honlap.service.mapper;
2
3 import hu.dns.honlap.domain.Authority;
4 import hu.dns.honlap.domain.User;
5 import hu.dns.honlap.service.dto.UserDTO;
6
7 import org.springframework.stereotype.Service;
8
9 import java.util.*;
10 import java.util.stream.Collectors;
11
12 /**
13 * Mapper for the entity {@link User} and its DTO called {@link UserDTO}.
14 *
15 * Normal mappers are generated using MapStruct, this one is hand-coded as MapStruct
16 * support is still in beta, and requires a manual step with an IDE.
17 */
18 @Service
19 public class UserMapper {
20
21 public List<UserDTO> usersToUserDTOs(List<User> users) {
22 return users.stream()
23 .filter(Objects::nonNull)
24 .map(this::userToUserDTO)
25 .collect(Collectors.toList());
26 }
27
28 public UserDTO userToUserDTO(User user) {
29 return new UserDTO(user);
30 }
31
32 public List<User> userDTOsToUsers(List<UserDTO> userDTOs) {
33 return userDTOs.stream()
34 .filter(Objects::nonNull)
35 .map(this::userDTOToUser)
36 .collect(Collectors.toList());
37 }
38
39 public User userDTOToUser(UserDTO userDTO) {
40 if (userDTO == null) {
41 return null;
42 } else {
43 User user = new User();
44 user.setId(userDTO.getId());
45 user.setLogin(userDTO.getLogin());
46 user.setFirstName(userDTO.getFirstName());
47 user.setLastName(userDTO.getLastName());
48 user.setEmail(userDTO.getEmail());
49 user.setImageUrl(userDTO.getImageUrl());
50 user.setActivated(userDTO.isActivated());
51 user.setLangKey(userDTO.getLangKey());
52 Set<Authority> authorities = this.authoritiesFromStrings(userDTO.getAuthorities());
53 user.setAuthorities(authorities);
54 return user;
55 }
56 }
57
58
59 private Set<Authority> authoritiesFromStrings(Set<String> authoritiesAsString) {
60 Set<Authority> authorities = new HashSet<>();
61
62 if (authoritiesAsString != null) {
63 authorities = authoritiesAsString.stream().map(string -> {
64 Authority auth = new Authority();
65 auth.setName(string);
66 return auth;
67 }).collect(Collectors.toSet());
68 }
69
70 return authorities;
71 }
72
73 public User userFromId(Long id) {
74 if (id == null) {
75 return null;
76 }
77 User user = new User();
78 user.setId(id);
79 return user;
80 }
81 }
File src/main/java/hu/dns/honlap/service/mapper/package-info.java added (mode: 100644) (index 0000000..af2199c)
1 /**
2 * MapStruct mappers for mapping domain objects and Data Transfer Objects.
3 */
4 package hu.dns.honlap.service.mapper;
File src/main/java/hu/dns/honlap/service/package-info.java added (mode: 100644) (index 0000000..0835a98)
1 /**
2 * Service layer beans.
3 */
4 package hu.dns.honlap.service;
File src/main/java/hu/dns/honlap/web/rest/AccountResource.java added (mode: 100644) (index 0000000..1c59eaf)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.domain.User;
4 import hu.dns.honlap.repository.UserRepository;
5 import hu.dns.honlap.security.SecurityUtils;
6 import hu.dns.honlap.service.MailService;
7 import hu.dns.honlap.service.UserService;
8 import hu.dns.honlap.service.dto.PasswordChangeDTO;
9 import hu.dns.honlap.service.dto.UserDTO;
10 import hu.dns.honlap.web.rest.errors.*;
11 import hu.dns.honlap.web.rest.vm.KeyAndPasswordVM;
12 import hu.dns.honlap.web.rest.vm.ManagedUserVM;
13
14 import org.apache.commons.lang3.StringUtils;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.springframework.http.HttpStatus;
18 import org.springframework.web.bind.annotation.*;
19
20 import javax.servlet.http.HttpServletRequest;
21 import javax.validation.Valid;
22 import java.util.*;
23
24 /**
25 * REST controller for managing the current user's account.
26 */
27 @RestController
28 @RequestMapping("/api")
29 public class AccountResource {
30
31 private static class AccountResourceException extends RuntimeException {
32 private AccountResourceException(String message) {
33 super(message);
34 }
35 }
36
37 private final Logger log = LoggerFactory.getLogger(AccountResource.class);
38
39 private final UserRepository userRepository;
40
41 private final UserService userService;
42
43 private final MailService mailService;
44
45 public AccountResource(UserRepository userRepository, UserService userService, MailService mailService) {
46
47 this.userRepository = userRepository;
48 this.userService = userService;
49 this.mailService = mailService;
50 }
51
52 /**
53 * {@code POST /register} : register the user.
54 *
55 * @param managedUserVM the managed user View Model.
56 * @throws InvalidPasswordException {@code 400 (Bad Request)} if the password is incorrect.
57 * @throws EmailAlreadyUsedException {@code 400 (Bad Request)} if the email is already used.
58 * @throws LoginAlreadyUsedException {@code 400 (Bad Request)} if the login is already used.
59 */
60 @PostMapping("/register")
61 @ResponseStatus(HttpStatus.CREATED)
62 public void registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) {
63 if (!checkPasswordLength(managedUserVM.getPassword())) {
64 throw new InvalidPasswordException();
65 }
66 User user = userService.registerUser(managedUserVM, managedUserVM.getPassword());
67 mailService.sendActivationEmail(user);
68 }
69
70 /**
71 * {@code GET /activate} : activate the registered user.
72 *
73 * @param key the activation key.
74 * @throws RuntimeException {@code 500 (Internal Server Error)} if the user couldn't be activated.
75 */
76 @GetMapping("/activate")
77 public void activateAccount(@RequestParam(value = "key") String key) {
78 Optional<User> user = userService.activateRegistration(key);
79 if (!user.isPresent()) {
80 throw new AccountResourceException("No user was found for this activation key");
81 }
82 }
83
84 /**
85 * {@code GET /authenticate} : check if the user is authenticated, and return its login.
86 *
87 * @param request the HTTP request.
88 * @return the login if the user is authenticated.
89 */
90 @GetMapping("/authenticate")
91 public String isAuthenticated(HttpServletRequest request) {
92 log.debug("REST request to check if the current user is authenticated");
93 return request.getRemoteUser();
94 }
95
96 /**
97 * {@code GET /account} : get the current user.
98 *
99 * @return the current user.
100 * @throws RuntimeException {@code 500 (Internal Server Error)} if the user couldn't be returned.
101 */
102 @GetMapping("/account")
103 public UserDTO getAccount() {
104 return userService.getUserWithAuthorities()
105 .map(UserDTO::new)
106 .orElseThrow(() -> new AccountResourceException("User could not be found"));
107 }
108
109 /**
110 * {@code POST /account} : update the current user information.
111 *
112 * @param userDTO the current user information.
113 * @throws EmailAlreadyUsedException {@code 400 (Bad Request)} if the email is already used.
114 * @throws RuntimeException {@code 500 (Internal Server Error)} if the user login wasn't found.
115 */
116 @PostMapping("/account")
117 public void saveAccount(@Valid @RequestBody UserDTO userDTO) {
118 String userLogin = SecurityUtils.getCurrentUserLogin().orElseThrow(() -> new AccountResourceException("Current user login not found"));
119 Optional<User> existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail());
120 if (existingUser.isPresent() && (!existingUser.get().getLogin().equalsIgnoreCase(userLogin))) {
121 throw new EmailAlreadyUsedException();
122 }
123 Optional<User> user = userRepository.findOneByLogin(userLogin);
124 if (!user.isPresent()) {
125 throw new AccountResourceException("User could not be found");
126 }
127 userService.updateUser(userDTO.getFirstName(), userDTO.getLastName(), userDTO.getEmail(),
128 userDTO.getLangKey(), userDTO.getImageUrl());
129 }
130
131 /**
132 * {@code POST /account/change-password} : changes the current user's password.
133 *
134 * @param passwordChangeDto current and new password.
135 * @throws InvalidPasswordException {@code 400 (Bad Request)} if the new password is incorrect.
136 */
137 @PostMapping(path = "/account/change-password")
138 public void changePassword(@RequestBody PasswordChangeDTO passwordChangeDto) {
139 if (!checkPasswordLength(passwordChangeDto.getNewPassword())) {
140 throw new InvalidPasswordException();
141 }
142 userService.changePassword(passwordChangeDto.getCurrentPassword(), passwordChangeDto.getNewPassword());
143 }
144
145 /**
146 * {@code POST /account/reset-password/init} : Send an email to reset the password of the user.
147 *
148 * @param mail the mail of the user.
149 */
150 @PostMapping(path = "/account/reset-password/init")
151 public void requestPasswordReset(@RequestBody String mail) {
152 Optional<User> user = userService.requestPasswordReset(mail);
153 if (user.isPresent()) {
154 mailService.sendPasswordResetMail(user.get());
155 } else {
156 // Pretend the request has been successful to prevent checking which emails really exist
157 // but log that an invalid attempt has been made
158 log.warn("Password reset requested for non existing mail '{}'", mail);
159 }
160 }
161
162 /**
163 * {@code POST /account/reset-password/finish} : Finish to reset the password of the user.
164 *
165 * @param keyAndPassword the generated key and the new password.
166 * @throws InvalidPasswordException {@code 400 (Bad Request)} if the password is incorrect.
167 * @throws RuntimeException {@code 500 (Internal Server Error)} if the password could not be reset.
168 */
169 @PostMapping(path = "/account/reset-password/finish")
170 public void finishPasswordReset(@RequestBody KeyAndPasswordVM keyAndPassword) {
171 if (!checkPasswordLength(keyAndPassword.getNewPassword())) {
172 throw new InvalidPasswordException();
173 }
174 Optional<User> user =
175 userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey());
176
177 if (!user.isPresent()) {
178 throw new AccountResourceException("No user was found for this reset key");
179 }
180 }
181
182 private static boolean checkPasswordLength(String password) {
183 return !StringUtils.isEmpty(password) &&
184 password.length() >= ManagedUserVM.PASSWORD_MIN_LENGTH &&
185 password.length() <= ManagedUserVM.PASSWORD_MAX_LENGTH;
186 }
187 }
File src/main/java/hu/dns/honlap/web/rest/AuditResource.java added (mode: 100644) (index 0000000..4421306)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.service.AuditEventService;
4
5 import io.github.jhipster.web.util.PaginationUtil;
6 import io.github.jhipster.web.util.ResponseUtil;
7 import org.springframework.boot.actuate.audit.AuditEvent;
8 import org.springframework.data.domain.Page;
9 import org.springframework.data.domain.Pageable;
10 import org.springframework.http.HttpHeaders;
11 import org.springframework.http.HttpStatus;
12 import org.springframework.http.ResponseEntity;
13 import org.springframework.web.bind.annotation.*;
14 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
15
16 import java.time.Instant;
17 import java.time.LocalDate;
18 import java.time.ZoneId;
19 import java.util.List;
20
21 /**
22 * REST controller for getting the {@link AuditEvent}s.
23 */
24 @RestController
25 @RequestMapping("/management/audits")
26 public class AuditResource {
27
28 private final AuditEventService auditEventService;
29
30 public AuditResource(AuditEventService auditEventService) {
31 this.auditEventService = auditEventService;
32 }
33
34 /**
35 * {@code GET /audits} : get a page of {@link AuditEvent}s.
36 *
37 * @param pageable the pagination information.
38 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of {@link AuditEvent}s in body.
39 */
40 @GetMapping
41 public ResponseEntity<List<AuditEvent>> getAll(Pageable pageable) {
42 Page<AuditEvent> page = auditEventService.findAll(pageable);
43 HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
44 return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
45 }
46
47 /**
48 * {@code GET /audits} : get a page of {@link AuditEvent} between the {@code fromDate} and {@code toDate}.
49 *
50 * @param fromDate the start of the time period of {@link AuditEvent} to get.
51 * @param toDate the end of the time period of {@link AuditEvent} to get.
52 * @param pageable the pagination information.
53 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of {@link AuditEvent} in body.
54 */
55 @GetMapping(params = {"fromDate", "toDate"})
56 public ResponseEntity<List<AuditEvent>> getByDates(
57 @RequestParam(value = "fromDate") LocalDate fromDate,
58 @RequestParam(value = "toDate") LocalDate toDate,
59 Pageable pageable) {
60
61 Instant from = fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
62 Instant to = toDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant();
63
64 Page<AuditEvent> page = auditEventService.findByDates(from, to, pageable);
65 HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
66 return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
67 }
68
69 /**
70 * {@code GET /audits/:id} : get an {@link AuditEvent} by id.
71 *
72 * @param id the id of the entity to get.
73 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the {@link AuditEvent} in body, or status {@code 404 (Not Found)}.
74 */
75 @GetMapping("/{id:.+}")
76 public ResponseEntity<AuditEvent> get(@PathVariable Long id) {
77 return ResponseUtil.wrapOrNotFound(auditEventService.find(id));
78 }
79 }
File src/main/java/hu/dns/honlap/web/rest/ClientForwardController.java added (mode: 100644) (index 0000000..751a530)
1 package hu.dns.honlap.web.rest;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.web.bind.annotation.GetMapping;
5
6 @Controller
7 public class ClientForwardController {
8
9 /**
10 * Forwards any unmapped paths (except those containing a period) to the client {@code index.html}.
11 * @return forward to client {@code index.html}.
12 */
13 @GetMapping(value = "/**/{path:[^\\.]*}")
14 public String forward() {
15 return "forward:/";
16 }
17 }
File src/main/java/hu/dns/honlap/web/rest/PieceOfNewsResource.java added (mode: 100644) (index 0000000..1f4a43d)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.domain.PieceOfNews;
4 import hu.dns.honlap.repository.PieceOfNewsRepository;
5 import hu.dns.honlap.web.rest.errors.BadRequestAlertException;
6
7 import io.github.jhipster.web.util.HeaderUtil;
8 import io.github.jhipster.web.util.PaginationUtil;
9 import io.github.jhipster.web.util.ResponseUtil;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Value;
13 import org.springframework.data.domain.Page;
14 import org.springframework.data.domain.Pageable;
15 import org.springframework.http.HttpHeaders;
16 import org.springframework.http.HttpStatus;
17 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
18 import org.springframework.http.ResponseEntity;
19 import org.springframework.transaction.annotation.Transactional;
20 import org.springframework.web.bind.annotation.*;
21
22 import javax.validation.Valid;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.util.List;
26 import java.util.Optional;
27
28 /**
29 * REST controller for managing {@link hu.dns.honlap.domain.PieceOfNews}.
30 */
31 @RestController
32 @RequestMapping("/api")
33 @Transactional
34 public class PieceOfNewsResource {
35
36 private final Logger log = LoggerFactory.getLogger(PieceOfNewsResource.class);
37
38 private static final String ENTITY_NAME = "pieceOfNews";
39
40 @Value("${jhipster.clientApp.name}")
41 private String applicationName;
42
43 private final PieceOfNewsRepository pieceOfNewsRepository;
44
45 public PieceOfNewsResource(PieceOfNewsRepository pieceOfNewsRepository) {
46 this.pieceOfNewsRepository = pieceOfNewsRepository;
47 }
48
49 /**
50 * {@code POST /piece-of-news} : Create a new pieceOfNews.
51 *
52 * @param pieceOfNews the pieceOfNews to create.
53 * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new pieceOfNews, or with status {@code 400 (Bad Request)} if the pieceOfNews has already an ID.
54 * @throws URISyntaxException if the Location URI syntax is incorrect.
55 */
56 @PostMapping("/piece-of-news")
57 public ResponseEntity<PieceOfNews> createPieceOfNews(@Valid @RequestBody PieceOfNews pieceOfNews) throws URISyntaxException {
58 log.debug("REST request to save PieceOfNews : {}", pieceOfNews);
59 if (pieceOfNews.getId() != null) {
60 throw new BadRequestAlertException("A new pieceOfNews cannot already have an ID", ENTITY_NAME, "idexists");
61 }
62 PieceOfNews result = pieceOfNewsRepository.save(pieceOfNews);
63 return ResponseEntity.created(new URI("/api/piece-of-news/" + result.getId()))
64 .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString()))
65 .body(result);
66 }
67
68 /**
69 * {@code PUT /piece-of-news} : Updates an existing pieceOfNews.
70 *
71 * @param pieceOfNews the pieceOfNews to update.
72 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated pieceOfNews,
73 * or with status {@code 400 (Bad Request)} if the pieceOfNews is not valid,
74 * or with status {@code 500 (Internal Server Error)} if the pieceOfNews couldn't be updated.
75 * @throws URISyntaxException if the Location URI syntax is incorrect.
76 */
77 @PutMapping("/piece-of-news")
78 public ResponseEntity<PieceOfNews> updatePieceOfNews(@Valid @RequestBody PieceOfNews pieceOfNews) throws URISyntaxException {
79 log.debug("REST request to update PieceOfNews : {}", pieceOfNews);
80 if (pieceOfNews.getId() == null) {
81 throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
82 }
83 PieceOfNews result = pieceOfNewsRepository.save(pieceOfNews);
84 return ResponseEntity.ok()
85 .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, pieceOfNews.getId().toString()))
86 .body(result);
87 }
88
89 /**
90 * {@code GET /piece-of-news} : get all the pieceOfNews.
91 *
92 * @param pageable the pagination information.
93 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of pieceOfNews in body.
94 */
95 @GetMapping("/piece-of-news")
96 public ResponseEntity<List<PieceOfNews>> getAllPieceOfNews(Pageable pageable) {
97 log.debug("REST request to get a page of PieceOfNews");
98 Page<PieceOfNews> page = pieceOfNewsRepository.findAll(pageable);
99 HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
100 return ResponseEntity.ok().headers(headers).body(page.getContent());
101 }
102
103 /**
104 * {@code GET /piece-of-news/:id} : get the "id" pieceOfNews.
105 *
106 * @param id the id of the pieceOfNews to retrieve.
107 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the pieceOfNews, or with status {@code 404 (Not Found)}.
108 */
109 @GetMapping("/piece-of-news/{id}")
110 public ResponseEntity<PieceOfNews> getPieceOfNews(@PathVariable Long id) {
111 log.debug("REST request to get PieceOfNews : {}", id);
112 Optional<PieceOfNews> pieceOfNews = pieceOfNewsRepository.findById(id);
113 return ResponseUtil.wrapOrNotFound(pieceOfNews);
114 }
115
116 /**
117 * {@code DELETE /piece-of-news/:id} : delete the "id" pieceOfNews.
118 *
119 * @param id the id of the pieceOfNews to delete.
120 * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
121 */
122 @DeleteMapping("/piece-of-news/{id}")
123 public ResponseEntity<Void> deletePieceOfNews(@PathVariable Long id) {
124 log.debug("REST request to delete PieceOfNews : {}", id);
125 pieceOfNewsRepository.deleteById(id);
126 return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())).build();
127 }
128 }
File src/main/java/hu/dns/honlap/web/rest/UserJWTController.java added (mode: 100644) (index 0000000..361d9fa)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.security.jwt.JWTFilter;
4 import hu.dns.honlap.security.jwt.TokenProvider;
5 import hu.dns.honlap.web.rest.vm.LoginVM;
6
7 import com.fasterxml.jackson.annotation.JsonProperty;
8
9 import org.springframework.http.HttpHeaders;
10 import org.springframework.http.HttpStatus;
11 import org.springframework.http.ResponseEntity;
12 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
13 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
14 import org.springframework.security.core.Authentication;
15 import org.springframework.security.core.context.SecurityContextHolder;
16 import org.springframework.web.bind.annotation.*;
17
18 import javax.validation.Valid;
19
20 /**
21 * Controller to authenticate users.
22 */
23 @RestController
24 @RequestMapping("/api")
25 public class UserJWTController {
26
27 private final TokenProvider tokenProvider;
28
29 private final AuthenticationManagerBuilder authenticationManagerBuilder;
30
31 public UserJWTController(TokenProvider tokenProvider, AuthenticationManagerBuilder authenticationManagerBuilder) {
32 this.tokenProvider = tokenProvider;
33 this.authenticationManagerBuilder = authenticationManagerBuilder;
34 }
35
36 @PostMapping("/authenticate")
37 public ResponseEntity<JWTToken> authorize(@Valid @RequestBody LoginVM loginVM) {
38
39 UsernamePasswordAuthenticationToken authenticationToken =
40 new UsernamePasswordAuthenticationToken(loginVM.getUsername(), loginVM.getPassword());
41
42 Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
43 SecurityContextHolder.getContext().setAuthentication(authentication);
44 boolean rememberMe = (loginVM.isRememberMe() == null) ? false : loginVM.isRememberMe();
45 String jwt = tokenProvider.createToken(authentication, rememberMe);
46 HttpHeaders httpHeaders = new HttpHeaders();
47 httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt);
48 return new ResponseEntity<>(new JWTToken(jwt), httpHeaders, HttpStatus.OK);
49 }
50 /**
51 * Object to return as body in JWT Authentication.
52 */
53 static class JWTToken {
54
55 private String idToken;
56
57 JWTToken(String idToken) {
58 this.idToken = idToken;
59 }
60
61 @JsonProperty("id_token")
62 String getIdToken() {
63 return idToken;
64 }
65
66 void setIdToken(String idToken) {
67 this.idToken = idToken;
68 }
69 }
70 }
File src/main/java/hu/dns/honlap/web/rest/UserResource.java added (mode: 100644) (index 0000000..187ade8)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.config.Constants;
4 import hu.dns.honlap.domain.User;
5 import hu.dns.honlap.repository.UserRepository;
6 import hu.dns.honlap.security.AuthoritiesConstants;
7 import hu.dns.honlap.service.MailService;
8 import hu.dns.honlap.service.UserService;
9 import hu.dns.honlap.service.dto.UserDTO;
10 import hu.dns.honlap.web.rest.errors.BadRequestAlertException;
11 import hu.dns.honlap.web.rest.errors.EmailAlreadyUsedException;
12 import hu.dns.honlap.web.rest.errors.LoginAlreadyUsedException;
13
14 import io.github.jhipster.web.util.HeaderUtil;
15 import io.github.jhipster.web.util.PaginationUtil;
16 import io.github.jhipster.web.util.ResponseUtil;
17
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20 import org.springframework.beans.factory.annotation.Value;
21 import org.springframework.data.domain.Page;
22 import org.springframework.data.domain.Pageable;
23 import org.springframework.http.HttpHeaders;
24 import org.springframework.http.HttpStatus;
25 import org.springframework.http.ResponseEntity;
26 import org.springframework.security.access.prepost.PreAuthorize;
27 import org.springframework.web.bind.annotation.*;
28 import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
29
30 import javax.validation.Valid;
31 import java.net.URI;
32 import java.net.URISyntaxException;
33 import java.util.*;
34
35 /**
36 * REST controller for managing users.
37 * <p>
38 * This class accesses the {@link User} entity, and needs to fetch its collection of authorities.
39 * <p>
40 * For a normal use-case, it would be better to have an eager relationship between User and Authority,
41 * and send everything to the client side: there would be no View Model and DTO, a lot less code, and an outer-join
42 * which would be good for performance.
43 * <p>
44 * We use a View Model and a DTO for 3 reasons:
45 * <ul>
46 * <li>We want to keep a lazy association between the user and the authorities, because people will
47 * quite often do relationships with the user, and we don't want them to get the authorities all
48 * the time for nothing (for performance reasons). This is the #1 goal: we should not impact our users'
49 * application because of this use-case.</li>
50 * <li> Not having an outer join causes n+1 requests to the database. This is not a real issue as
51 * we have by default a second-level cache. This means on the first HTTP call we do the n+1 requests,
52 * but then all authorities come from the cache, so in fact it's much better than doing an outer join
53 * (which will get lots of data from the database, for each HTTP call).</li>
54 * <li> As this manages users, for security reasons, we'd rather have a DTO layer.</li>
55 * </ul>
56 * <p>
57 * Another option would be to have a specific JPA entity graph to handle this case.
58 */
59 @RestController
60 @RequestMapping("/api")
61 public class UserResource {
62
63 private final Logger log = LoggerFactory.getLogger(UserResource.class);
64
65 @Value("${jhipster.clientApp.name}")
66 private String applicationName;
67
68 private final UserService userService;
69
70 private final UserRepository userRepository;
71
72 private final MailService mailService;
73
74 public UserResource(UserService userService, UserRepository userRepository, MailService mailService) {
75 this.userService = userService;
76 this.userRepository = userRepository;
77 this.mailService = mailService;
78 }
79
80 /**
81 * {@code POST /users} : Creates a new user.
82 * <p>
83 * Creates a new user if the login and email are not already used, and sends an
84 * mail with an activation link.
85 * The user needs to be activated on creation.
86 *
87 * @param userDTO the user to create.
88 * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new user, or with status {@code 400 (Bad Request)} if the login or email is already in use.
89 * @throws URISyntaxException if the Location URI syntax is incorrect.
90 * @throws BadRequestAlertException {@code 400 (Bad Request)} if the login or email is already in use.
91 */
92 @PostMapping("/users")
93 @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
94 public ResponseEntity<User> createUser(@Valid @RequestBody UserDTO userDTO) throws URISyntaxException {
95 log.debug("REST request to save User : {}", userDTO);
96
97 if (userDTO.getId() != null) {
98 throw new BadRequestAlertException("A new user cannot already have an ID", "userManagement", "idexists");
99 // Lowercase the user login before comparing with database
100 } else if (userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()).isPresent()) {
101 throw new LoginAlreadyUsedException();
102 } else if (userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()).isPresent()) {
103 throw new EmailAlreadyUsedException();
104 } else {
105 User newUser = userService.createUser(userDTO);
106 mailService.sendCreationEmail(newUser);
107 return ResponseEntity.created(new URI("/api/users/" + newUser.getLogin()))
108 .headers(HeaderUtil.createAlert(applicationName, "userManagement.created", newUser.getLogin()))
109 .body(newUser);
110 }
111 }
112
113 /**
114 * {@code PUT /users} : Updates an existing User.
115 *
116 * @param userDTO the user to update.
117 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated user.
118 * @throws EmailAlreadyUsedException {@code 400 (Bad Request)} if the email is already in use.
119 * @throws LoginAlreadyUsedException {@code 400 (Bad Request)} if the login is already in use.
120 */
121 @PutMapping("/users")
122 @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
123 public ResponseEntity<UserDTO> updateUser(@Valid @RequestBody UserDTO userDTO) {
124 log.debug("REST request to update User : {}", userDTO);
125 Optional<User> existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail());
126 if (existingUser.isPresent() && (!existingUser.get().getId().equals(userDTO.getId()))) {
127 throw new EmailAlreadyUsedException();
128 }
129 existingUser = userRepository.findOneByLogin(userDTO.getLogin().toLowerCase());
130 if (existingUser.isPresent() && (!existingUser.get().getId().equals(userDTO.getId()))) {
131 throw new LoginAlreadyUsedException();
132 }
133 Optional<UserDTO> updatedUser = userService.updateUser(userDTO);
134
135 return ResponseUtil.wrapOrNotFound(updatedUser,
136 HeaderUtil.createAlert(applicationName, "userManagement.updated", userDTO.getLogin()));
137 }
138
139 /**
140 * {@code GET /users} : get all users.
141 *
142 * @param pageable the pagination information.
143 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body all users.
144 */
145 @GetMapping("/users")
146 public ResponseEntity<List<UserDTO>> getAllUsers(Pageable pageable) {
147 final Page<UserDTO> page = userService.getAllManagedUsers(pageable);
148 HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
149 return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
150 }
151
152 /**
153 * Gets a list of all roles.
154 * @return a string list of all roles.
155 */
156 @GetMapping("/users/authorities")
157 @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
158 public List<String> getAuthorities() {
159 return userService.getAuthorities();
160 }
161
162 /**
163 * {@code GET /users/:login} : get the "login" user.
164 *
165 * @param login the login of the user to find.
166 * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the "login" user, or with status {@code 404 (Not Found)}.
167 */
168 @GetMapping("/users/{login:" + Constants.LOGIN_REGEX + "}")
169 public ResponseEntity<UserDTO> getUser(@PathVariable String login) {
170 log.debug("REST request to get User : {}", login);
171 return ResponseUtil.wrapOrNotFound(
172 userService.getUserWithAuthoritiesByLogin(login)
173 .map(UserDTO::new));
174 }
175
176 /**
177 * {@code DELETE /users/:login} : delete the "login" User.
178 *
179 * @param login the login of the user to delete.
180 * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
181 */
182 @DeleteMapping("/users/{login:" + Constants.LOGIN_REGEX + "}")
183 @PreAuthorize("hasAuthority(\"" + AuthoritiesConstants.ADMIN + "\")")
184 public ResponseEntity<Void> deleteUser(@PathVariable String login) {
185 log.debug("REST request to delete User: {}", login);
186 userService.deleteUser(login);
187 return ResponseEntity.noContent().headers(HeaderUtil.createAlert(applicationName, "userManagement.deleted", login)).build();
188 }
189 }
File src/main/java/hu/dns/honlap/web/rest/errors/BadRequestAlertException.java added (mode: 100644) (index 0000000..d7a8c1d)
1 package hu.dns.honlap.web.rest.errors;
2
3 import org.zalando.problem.AbstractThrowableProblem;
4 import org.zalando.problem.Status;
5
6 import java.net.URI;
7 import java.util.HashMap;
8 import java.util.Map;
9
10 public class BadRequestAlertException extends AbstractThrowableProblem {
11
12 private static final long serialVersionUID = 1L;
13
14 private final String entityName;
15
16 private final String errorKey;
17
18 public BadRequestAlertException(String defaultMessage, String entityName, String errorKey) {
19 this(ErrorConstants.DEFAULT_TYPE, defaultMessage, entityName, errorKey);
20 }
21
22 public BadRequestAlertException(URI type, String defaultMessage, String entityName, String errorKey) {
23 super(type, defaultMessage, Status.BAD_REQUEST, null, null, null, getAlertParameters(entityName, errorKey));
24 this.entityName = entityName;
25 this.errorKey = errorKey;
26 }
27
28 public String getEntityName() {
29 return entityName;
30 }
31
32 public String getErrorKey() {
33 return errorKey;
34 }
35
36 private static Map<String, Object> getAlertParameters(String entityName, String errorKey) {
37 Map<String, Object> parameters = new HashMap<>();
38 parameters.put("message", "error." + errorKey);
39 parameters.put("params", entityName);
40 return parameters;
41 }
42 }
File src/main/java/hu/dns/honlap/web/rest/errors/EmailAlreadyUsedException.java added (mode: 100644) (index 0000000..5666455)
1 package hu.dns.honlap.web.rest.errors;
2
3 public class EmailAlreadyUsedException extends BadRequestAlertException {
4
5 private static final long serialVersionUID = 1L;
6
7 public EmailAlreadyUsedException() {
8 super(ErrorConstants.EMAIL_ALREADY_USED_TYPE, "Email is already in use!", "userManagement", "emailexists");
9 }
10 }
File src/main/java/hu/dns/honlap/web/rest/errors/ErrorConstants.java added (mode: 100644) (index 0000000..c898510)
1 package hu.dns.honlap.web.rest.errors;
2
3 import java.net.URI;
4
5 public final class ErrorConstants {
6
7 public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure";
8 public static final String ERR_VALIDATION = "error.validation";
9 public static final String PROBLEM_BASE_URL = "https://www.jhipster.tech/problem";
10 public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message");
11 public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation");
12 public static final URI INVALID_PASSWORD_TYPE = URI.create(PROBLEM_BASE_URL + "/invalid-password");
13 public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used");
14 public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used");
15
16 private ErrorConstants() {
17 }
18 }
File src/main/java/hu/dns/honlap/web/rest/errors/ExceptionTranslator.java added (mode: 100644) (index 0000000..f325df3)
1 package hu.dns.honlap.web.rest.errors;
2
3 import io.github.jhipster.web.util.HeaderUtil;
4
5 import org.springframework.beans.factory.annotation.Value;
6 import org.springframework.dao.ConcurrencyFailureException;
7 import org.springframework.http.ResponseEntity;
8 import org.springframework.validation.BindingResult;
9 import org.springframework.web.bind.MethodArgumentNotValidException;
10 import org.springframework.web.bind.annotation.ControllerAdvice;
11 import org.springframework.web.bind.annotation.ExceptionHandler;
12 import org.springframework.web.context.request.NativeWebRequest;
13 import org.zalando.problem.DefaultProblem;
14 import org.zalando.problem.Problem;
15 import org.zalando.problem.ProblemBuilder;
16 import org.zalando.problem.Status;
17 import org.zalando.problem.spring.web.advice.ProblemHandling;
18 import org.zalando.problem.spring.web.advice.security.SecurityAdviceTrait;
19 import org.zalando.problem.violations.ConstraintViolationProblem;
20
21 import javax.annotation.Nonnull;
22 import javax.annotation.Nullable;
23 import javax.servlet.http.HttpServletRequest;
24 import java.util.List;
25 import java.util.stream.Collectors;
26
27 /**
28 * Controller advice to translate the server side exceptions to client-friendly json structures.
29 * The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807).
30 */
31 @ControllerAdvice
32 public class ExceptionTranslator implements ProblemHandling, SecurityAdviceTrait {
33
34 private static final String FIELD_ERRORS_KEY = "fieldErrors";
35 private static final String MESSAGE_KEY = "message";
36 private static final String PATH_KEY = "path";
37 private static final String VIOLATIONS_KEY = "violations";
38
39 @Value("${jhipster.clientApp.name}")
40 private String applicationName;
41
42 /**
43 * Post-process the Problem payload to add the message key for the front-end if needed.
44 */
45 @Override
46 public ResponseEntity<Problem> process(@Nullable ResponseEntity<Problem> entity, NativeWebRequest request) {
47 if (entity == null) {
48 return entity;
49 }
50 Problem problem = entity.getBody();
51 if (!(problem instanceof ConstraintViolationProblem || problem instanceof DefaultProblem)) {
52 return entity;
53 }
54 ProblemBuilder builder = Problem.builder()
55 .withType(Problem.DEFAULT_TYPE.equals(problem.getType()) ? ErrorConstants.DEFAULT_TYPE : problem.getType())
56 .withStatus(problem.getStatus())
57 .withTitle(problem.getTitle())
58 .with(PATH_KEY, request.getNativeRequest(HttpServletRequest.class).getRequestURI());
59
60 if (problem instanceof ConstraintViolationProblem) {
61 builder
62 .with(VIOLATIONS_KEY, ((ConstraintViolationProblem) problem).getViolations())
63 .with(MESSAGE_KEY, ErrorConstants.ERR_VALIDATION);
64 } else {
65 builder
66 .withCause(((DefaultProblem) problem).getCause())
67 .withDetail(problem.getDetail())
68 .withInstance(problem.getInstance());
69 problem.getParameters().forEach(builder::with);
70 if (!problem.getParameters().containsKey(MESSAGE_KEY) && problem.getStatus() != null) {
71 builder.with(MESSAGE_KEY, "error.http." + problem.getStatus().getStatusCode());
72 }
73 }
74 return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode());
75 }
76
77 @Override
78 public ResponseEntity<Problem> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, @Nonnull NativeWebRequest request) {
79 BindingResult result = ex.getBindingResult();
80 List<FieldErrorVM> fieldErrors = result.getFieldErrors().stream()
81 .map(f -> new FieldErrorVM(f.getObjectName().replaceFirst("DTO$", ""), f.getField(), f.getCode()))
82 .collect(Collectors.toList());
83
84 Problem problem = Problem.builder()
85 .withType(ErrorConstants.CONSTRAINT_VIOLATION_TYPE)
86 .withTitle("Method argument not valid")
87 .withStatus(defaultConstraintViolationStatus())
88 .with(MESSAGE_KEY, ErrorConstants.ERR_VALIDATION)
89 .with(FIELD_ERRORS_KEY, fieldErrors)
90 .build();
91 return create(ex, problem, request);
92 }
93
94 @ExceptionHandler
95 public ResponseEntity<Problem> handleEmailAlreadyUsedException(hu.dns.honlap.service.EmailAlreadyUsedException ex, NativeWebRequest request) {
96 EmailAlreadyUsedException problem = new EmailAlreadyUsedException();
97 return create(problem, request, HeaderUtil.createFailureAlert(applicationName, true, problem.getEntityName(), problem.getErrorKey(), problem.getMessage()));
98 }
99
100 @ExceptionHandler
101 public ResponseEntity<Problem> handleUsernameAlreadyUsedException(hu.dns.honlap.service.UsernameAlreadyUsedException ex, NativeWebRequest request) {
102 LoginAlreadyUsedException problem = new LoginAlreadyUsedException();
103 return create(problem, request, HeaderUtil.createFailureAlert(applicationName, true, problem.getEntityName(), problem.getErrorKey(), problem.getMessage()));
104 }
105
106 @ExceptionHandler
107 public ResponseEntity<Problem> handleInvalidPasswordException(hu.dns.honlap.service.InvalidPasswordException ex, NativeWebRequest request) {
108 return create(new InvalidPasswordException(), request);
109 }
110
111 @ExceptionHandler
112 public ResponseEntity<Problem> handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) {
113 return create(ex, request, HeaderUtil.createFailureAlert(applicationName, true, ex.getEntityName(), ex.getErrorKey(), ex.getMessage()));
114 }
115
116 @ExceptionHandler
117 public ResponseEntity<Problem> handleConcurrencyFailure(ConcurrencyFailureException ex, NativeWebRequest request) {
118 Problem problem = Problem.builder()
119 .withStatus(Status.CONFLICT)
120 .with(MESSAGE_KEY, ErrorConstants.ERR_CONCURRENCY_FAILURE)
121 .build();
122 return create(ex, problem, request);
123 }
124 }
File src/main/java/hu/dns/honlap/web/rest/errors/FieldErrorVM.java added (mode: 100644) (index 0000000..925a45a)
1 package hu.dns.honlap.web.rest.errors;
2
3 import java.io.Serializable;
4
5 public class FieldErrorVM implements Serializable {
6
7 private static final long serialVersionUID = 1L;
8
9 private final String objectName;
10
11 private final String field;
12
13 private final String message;
14
15 public FieldErrorVM(String dto, String field, String message) {
16 this.objectName = dto;
17 this.field = field;
18 this.message = message;
19 }
20
21 public String getObjectName() {
22 return objectName;
23 }
24
25 public String getField() {
26 return field;
27 }
28
29 public String getMessage() {
30 return message;
31 }
32
33 }
File src/main/java/hu/dns/honlap/web/rest/errors/InvalidPasswordException.java added (mode: 100644) (index 0000000..520dc59)
1 package hu.dns.honlap.web.rest.errors;
2
3 import org.zalando.problem.AbstractThrowableProblem;
4 import org.zalando.problem.Status;
5
6 public class InvalidPasswordException extends AbstractThrowableProblem {
7
8 private static final long serialVersionUID = 1L;
9
10 public InvalidPasswordException() {
11 super(ErrorConstants.INVALID_PASSWORD_TYPE, "Incorrect password", Status.BAD_REQUEST);
12 }
13 }
File src/main/java/hu/dns/honlap/web/rest/errors/LoginAlreadyUsedException.java added (mode: 100644) (index 0000000..ff8f353)
1 package hu.dns.honlap.web.rest.errors;
2
3 public class LoginAlreadyUsedException extends BadRequestAlertException {
4
5 private static final long serialVersionUID = 1L;
6
7 public LoginAlreadyUsedException() {
8 super(ErrorConstants.LOGIN_ALREADY_USED_TYPE, "Login name already used!", "userManagement", "userexists");
9 }
10 }
File src/main/java/hu/dns/honlap/web/rest/errors/package-info.java added (mode: 100644) (index 0000000..298e99b)
1 /**
2 * Specific errors used with Zalando's "problem-spring-web" library.
3 *
4 * More information on https://github.com/zalando/problem-spring-web
5 */
6 package hu.dns.honlap.web.rest.errors;
File src/main/java/hu/dns/honlap/web/rest/package-info.java added (mode: 100644) (index 0000000..4f49cf8)
1 /**
2 * Spring MVC REST controllers.
3 */
4 package hu.dns.honlap.web.rest;
File src/main/java/hu/dns/honlap/web/rest/vm/KeyAndPasswordVM.java added (mode: 100644) (index 0000000..4566146)
1 package hu.dns.honlap.web.rest.vm;
2
3 /**
4 * View Model object for storing the user's key and password.
5 */
6 public class KeyAndPasswordVM {
7
8 private String key;
9
10 private String newPassword;
11
12 public String getKey() {
13 return key;
14 }
15
16 public void setKey(String key) {
17 this.key = key;
18 }
19
20 public String getNewPassword() {
21 return newPassword;
22 }
23
24 public void setNewPassword(String newPassword) {
25 this.newPassword = newPassword;
26 }
27 }
File src/main/java/hu/dns/honlap/web/rest/vm/LoginVM.java added (mode: 100644) (index 0000000..403b1f7)
1 package hu.dns.honlap.web.rest.vm;
2
3 import javax.validation.constraints.NotNull;
4 import javax.validation.constraints.Size;
5
6 /**
7 * View Model object for storing a user's credentials.
8 */
9 public class LoginVM {
10
11 @NotNull
12 @Size(min = 1, max = 50)
13 private String username;
14
15 @NotNull
16 @Size(min = 4, max = 100)
17 private String password;
18
19 private Boolean rememberMe;
20
21 public String getUsername() {
22 return username;
23 }
24
25 public void setUsername(String username) {
26 this.username = username;
27 }
28
29 public String getPassword() {
30 return password;
31 }
32
33 public void setPassword(String password) {
34 this.password = password;
35 }
36
37 public Boolean isRememberMe() {
38 return rememberMe;
39 }
40
41 public void setRememberMe(Boolean rememberMe) {
42 this.rememberMe = rememberMe;
43 }
44
45 @Override
46 public String toString() {
47 return "LoginVM{" +
48 "username='" + username + '\'' +
49 ", rememberMe=" + rememberMe +
50 '}';
51 }
52 }
File src/main/java/hu/dns/honlap/web/rest/vm/ManagedUserVM.java added (mode: 100644) (index 0000000..b9b749b)
1 package hu.dns.honlap.web.rest.vm;
2
3 import hu.dns.honlap.service.dto.UserDTO;
4 import javax.validation.constraints.Size;
5
6 /**
7 * View Model extending the UserDTO, which is meant to be used in the user management UI.
8 */
9 public class ManagedUserVM extends UserDTO {
10
11 public static final int PASSWORD_MIN_LENGTH = 4;
12
13 public static final int PASSWORD_MAX_LENGTH = 100;
14
15 @Size(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH)
16 private String password;
17
18 public ManagedUserVM() {
19 // Empty constructor needed for Jackson.
20 }
21
22 public String getPassword() {
23 return password;
24 }
25
26 public void setPassword(String password) {
27 this.password = password;
28 }
29
30 @Override
31 public String toString() {
32 return "ManagedUserVM{" + super.toString() + "} ";
33 }
34 }
File src/main/java/hu/dns/honlap/web/rest/vm/package-info.java added (mode: 100644) (index 0000000..82fb467)
1 /**
2 * View Models used by Spring MVC REST controllers.
3 */
4 package hu.dns.honlap.web.rest.vm;
File src/main/jib/entrypoint.sh added (mode: 100644) (index 0000000..7abae6c)
1 #!/bin/sh
2
3 echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
4 exec java ${JAVA_OPTS} -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -cp /app/resources/:/app/classes/:/app/libs/* "hu.dns.honlap.HonlapApp" "$@"
File src/main/resources/.h2.server.properties added (mode: 100644) (index 0000000..8c3cf33)
1 #H2 Server Properties
2 0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/honlap|honlap
3 webAllowOthers=true
4 webPort=8082
5 webSSL=false
File src/main/resources/banner.txt added (mode: 100644) (index 0000000..e0bc55a)
1
2 ${AnsiColor.GREEN} ██╗${AnsiColor.RED} ██╗ ██╗ ████████╗ ███████╗ ██████╗ ████████╗ ████████╗ ███████╗
3 ${AnsiColor.GREEN} ██║${AnsiColor.RED} ██║ ██║ ╚══██╔══╝ ██╔═══██╗ ██╔════╝ ╚══██╔══╝ ██╔═════╝ ██╔═══██╗
4 ${AnsiColor.GREEN} ██║${AnsiColor.RED} ████████║ ██║ ███████╔╝ ╚█████╗ ██║ ██████╗ ███████╔╝
5 ${AnsiColor.GREEN}██╗ ██║${AnsiColor.RED} ██╔═══██║ ██║ ██╔════╝ ╚═══██╗ ██║ ██╔═══╝ ██╔══██║
6 ${AnsiColor.GREEN}╚██████╔╝${AnsiColor.RED} ██║ ██║ ████████╗ ██║ ██████╔╝ ██║ ████████╗ ██║ ╚██╗
7 ${AnsiColor.GREEN} ╚═════╝ ${AnsiColor.RED} ╚═╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═╝
8
9 ${AnsiColor.BRIGHT_BLUE}:: JHipster 🤓 :: Running Spring Boot ${spring-boot.version} ::
10 :: https://www.jhipster.tech ::${AnsiColor.DEFAULT}
File src/main/resources/config/application-dev.yml added (mode: 100644) (index 0000000..07b2f5d)
1 # ===================================================================
2 # Spring Boot configuration for the "dev" profile.
3 #
4 # This configuration overrides the application.yml file.
5 #
6 # More information on profiles: https://www.jhipster.tech/profiles/
7 # More information on configuration properties: https://www.jhipster.tech/common-application-properties/
8 # ===================================================================
9
10 # ===================================================================
11 # Standard Spring Boot properties.
12 # Full reference is available at:
13 # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
14 # ===================================================================
15
16 logging:
17 level:
18 ROOT: DEBUG
19 io.github.jhipster: DEBUG
20 hu.dns.honlap: DEBUG
21
22 spring:
23 profiles:
24 active: dev
25 include:
26 - swagger
27 # Uncomment to activate TLS for the dev profile
28 #- tls
29 devtools:
30 restart:
31 enabled: true
32 additional-exclude: static/**,.h2.server.properties
33 livereload:
34 enabled: false # we use Webpack dev server + BrowserSync for livereload
35 jackson:
36 serialization:
37 indent-output: true
38 datasource:
39 type: com.zaxxer.hikari.HikariDataSource
40 url: jdbc:h2:file:./target/h2db/db/honlap;DB_CLOSE_DELAY=-1
41 username: honlap
42 password:
43 hikari:
44 poolName: Hikari
45 auto-commit: false
46 h2:
47 console:
48 enabled: false
49 jpa:
50 show-sql: true
51 properties:
52 hibernate.id.new_generator_mappings: true
53 hibernate.connection.provider_disables_autocommit: true
54 hibernate.cache.use_second_level_cache: true
55 hibernate.cache.use_query_cache: false
56 hibernate.generate_statistics: false
57 liquibase:
58 # Remove 'faker' if you do not want the sample data to be loaded automatically
59 contexts: dev, faker
60 mail:
61 host: localhost
62 port: 25
63 username:
64 password:
65 messages:
66 cache-duration: PT1S # 1 second, see the ISO 8601 standard
67 thymeleaf:
68 cache: false
69
70 server:
71 port: 8080
72
73 # ===================================================================
74 # JHipster specific properties
75 #
76 # Full reference is available at: https://www.jhipster.tech/common-application-properties/
77 # ===================================================================
78
79 jhipster:
80 cache: # Cache configuration
81 ehcache: # Ehcache configuration
82 time-to-live-seconds: 3600 # By default objects stay 1 hour in the cache
83 max-entries: 100 # Number of objects in each cache entry
84 # CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API
85 cors:
86 allowed-origins: '*'
87 allowed-methods: '*'
88 allowed-headers: '*'
89 exposed-headers: 'Authorization,Link,X-Total-Count'
90 allow-credentials: true
91 max-age: 1800
92 security:
93 authentication:
94 jwt:
95 # This token must be encoded using Base64 and be at least 256 bits long (you can type `openssl rand -base64 64` on your command line to generate a 512 bits one)
96 base64-secret: ZmYxOTYwOGZiYTY1OTJiMTQ3MDNhNGJiNTM3ZWMxN2U1ZTVjODdlMDhmZmNkMGRhYTQxY2ZiMGQzM2Q0ZTNmYzc2YjNjMzU5ZmVkZDgzZDc3OTYxZDMzNzdiNzc3MmVkYjA0NDFkOGIxMTI0MjRiNTMzYzRkNzFkMTJiYWE4Y2Y=
97 # Token is valid 24 hours
98 token-validity-in-seconds: 86400
99 token-validity-in-seconds-for-remember-me: 2592000
100 mail: # specific JHipster mail property, for standard properties see MailProperties
101 base-url: http://127.0.0.1:8080
102 metrics:
103 logs: # Reports metrics in the logs
104 enabled: false
105 report-frequency: 60 # in seconds
106 logging:
107 use-json-format: false # By default, logs are not in Json format
108 logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
109 enabled: false
110 host: localhost
111 port: 5000
112 queue-size: 512
113 audit-events:
114 retention-period: 30 # Number of days before audit events are deleted.
115
116 # ===================================================================
117 # Application specific properties
118 # Add your own application properties here, see the ApplicationProperties class
119 # to have type-safe configuration, like in the JHipsterProperties above
120 #
121 # More documentation is available at:
122 # https://www.jhipster.tech/common-application-properties/
123 # ===================================================================
124
125 # application:
File src/main/resources/config/application-prod.yml added (mode: 100644) (index 0000000..fcc6e08)
1 # ===================================================================
2 # Spring Boot configuration for the "prod" profile.
3 #
4 # This configuration overrides the application.yml file.
5 #
6 # More information on profiles: https://www.jhipster.tech/profiles/
7 # More information on configuration properties: https://www.jhipster.tech/common-application-properties/
8 # ===================================================================
9
10 # ===================================================================
11 # Standard Spring Boot properties.
12 # Full reference is available at:
13 # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
14 # ===================================================================
15
16 logging:
17 level:
18 ROOT: INFO
19 io.github.jhipster: INFO
20 hu.dns.honlap: INFO
21
22 management:
23 metrics:
24 export:
25 prometheus:
26 enabled: false
27
28 spring:
29 devtools:
30 restart:
31 enabled: false
32 livereload:
33 enabled: false
34 datasource:
35 type: com.zaxxer.hikari.HikariDataSource
36 url: jdbc:postgresql://localhost:5432/honlap
37 username: honlap
38 password:
39 hikari:
40 poolName: Hikari
41 auto-commit: false
42 jpa:
43 database-platform: io.github.jhipster.domain.util.FixedPostgreSQL10Dialect
44 show-sql: false
45 # Replace by 'prod, faker' to add the faker context and have sample data loaded in production
46 liquibase:
47 contexts: prod
48 mail:
49 host: localhost
50 port: 25
51 username:
52 password:
53 thymeleaf:
54 cache: true
55
56 # ===================================================================
57 # To enable TLS in production, generate a certificate using:
58 # keytool -genkey -alias honlap -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
59 #
60 # You can also use Let's Encrypt:
61 # https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
62 #
63 # Then, modify the server.ssl properties so your "server" configuration looks like:
64 #
65 # server:
66 # port: 443
67 # ssl:
68 # key-store: classpath:config/tls/keystore.p12
69 # key-store-password: password
70 # key-store-type: PKCS12
71 # key-alias: honlap
72 # # 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/)
73 # 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
74 # ===================================================================
75 server:
76 port: 8080
77 compression:
78 enabled: true
79 mime-types: text/html,text/xml,text/plain,text/css, application/javascript, application/json
80 min-response-size: 1024
81
82 # ===================================================================
83 # JHipster specific properties
84 #
85 # Full reference is available at: https://www.jhipster.tech/common-application-properties/
86 # ===================================================================
87
88 jhipster:
89 http:
90 cache: # Used by the CachingHttpHeadersFilter
91 timeToLiveInDays: 1461
92 cache: # Cache configuration
93 ehcache: # Ehcache configuration
94 time-to-live-seconds: 3600 # By default objects stay 1 hour in the cache
95 max-entries: 1000 # Number of objects in each cache entry
96 security:
97 authentication:
98 jwt:
99 # This token must be encoded using Base64 and be at least 256 bits long (you can type `openssl rand -base64 64` on your command line to generate a 512 bits one)
100 # As this is the PRODUCTION configuration, you MUST change the default key, and store it securely:
101 # - In the JHipster Registry (which includes a Spring Cloud Config server)
102 # - In a separate `application-prod.yml` file, in the same folder as your executable JAR file
103 # - In the `JHIPSTER_SECURITY_AUTHENTICATION_JWT_BASE64_SECRET` environment variable
104 base64-secret: ZmYxOTYwOGZiYTY1OTJiMTQ3MDNhNGJiNTM3ZWMxN2U1ZTVjODdlMDhmZmNkMGRhYTQxY2ZiMGQzM2Q0ZTNmYzc2YjNjMzU5ZmVkZDgzZDc3OTYxZDMzNzdiNzc3MmVkYjA0NDFkOGIxMTI0MjRiNTMzYzRkNzFkMTJiYWE4Y2Y=
105 # Token is valid 24 hours
106 token-validity-in-seconds: 86400
107 token-validity-in-seconds-for-remember-me: 2592000
108 mail: # specific JHipster mail property, for standard properties see MailProperties
109 base-url: http://my-server-url-to-change # Modify according to your server's URL
110 metrics:
111 logs: # Reports metrics in the logs
112 enabled: false
113 report-frequency: 60 # in seconds
114 logging:
115 use-json-format: false # By default, logs are not in Json format
116 logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
117 enabled: false
118 host: localhost
119 port: 5000
120 queue-size: 512
121 audit-events:
122 retention-period: 30 # Number of days before audit events are deleted.
123
124 # ===================================================================
125 # Application specific properties
126 # Add your own application properties here, see the ApplicationProperties class
127 # to have type-safe configuration, like in the JHipsterProperties above
128 #
129 # More documentation is available at:
130 # https://www.jhipster.tech/common-application-properties/
131 # ===================================================================
132
133 # application:
File src/main/resources/config/application-tls.yml added (mode: 100644) (index 0000000..27c9cd8)
1 # ===================================================================
2 # Activate this profile to enable TLS and HTTP/2.
3 #
4 # JHipster has generated a self-signed certificate, which will be used to encrypt traffic.
5 # As your browser will not understand this certificate, you will need to import it.
6 #
7 # Another (easiest) solution with Chrome is to enable the "allow-insecure-localhost" flag
8 # at chrome://flags/#allow-insecure-localhost
9 # ===================================================================
10 server:
11 ssl:
12 key-store: classpath:config/tls/keystore.p12
13 key-store-password: password
14 key-store-type: PKCS12
15 key-alias: selfsigned
16 ciphers: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
17 enabled-protocols: TLSv1.2
18 http2:
19 enabled: true
File src/main/resources/config/application.yml added (mode: 100644) (index 0000000..a701c0e)
1 # ===================================================================
2 # Spring Boot configuration.
3 #
4 # This configuration will be overridden by the Spring profile you use,
5 # for example application-dev.yml if you use the "dev" profile.
6 #
7 # More information on profiles: https://www.jhipster.tech/profiles/
8 # More information on configuration properties: https://www.jhipster.tech/common-application-properties/
9 # ===================================================================
10
11 # ===================================================================
12 # Standard Spring Boot properties.
13 # Full reference is available at:
14 # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
15 # ===================================================================
16
17 management:
18 endpoints:
19 web:
20 base-path: /management
21 exposure:
22 include: ['configprops', 'env', 'health', 'info', 'jhimetrics', 'logfile', 'loggers', 'prometheus', 'threaddump']
23 endpoint:
24 health:
25 show-details: when_authorized
26 roles: 'ROLE_ADMIN'
27 jhimetrics:
28 enabled: true
29 info:
30 git:
31 mode: full
32 health:
33 mail:
34 enabled: false # When using the MailService, configure an SMTP server and set this to true
35 metrics:
36 export:
37 # Prometheus is the default metrics backend
38 prometheus:
39 enabled: true
40 step: 60
41 enable:
42 http: true
43 jvm: true
44 logback: true
45 process: true
46 system: true
47 distribution:
48 percentiles-histogram:
49 all: true
50 percentiles:
51 all: 0, 0.5, 0.75, 0.95, 0.99, 1.0
52 tags:
53 application: ${spring.application.name}
54 web:
55 server:
56 request:
57 autotime:
58 enabled: true
59
60 spring:
61 application:
62 name: honlap
63 profiles:
64 # The commented value for `active` can be replaced with valid Spring profiles to load.
65 # Otherwise, it will be filled in by maven when building the JAR file
66 # Either way, it can be overridden by `--spring.profiles.active` value passed in the commandline or `-Dspring.profiles.active` set in `JAVA_OPTS`
67 active: #spring.profiles.active#
68 jmx:
69 enabled: false
70 data:
71 jpa:
72 repositories:
73 bootstrap-mode: deferred
74 jpa:
75 open-in-view: false
76 properties:
77 hibernate.jdbc.time_zone: UTC
78 hibernate.id.new_generator_mappings: true
79 hibernate.connection.provider_disables_autocommit: true
80 hibernate.cache.use_second_level_cache: true
81 hibernate.cache.use_query_cache: false
82 hibernate.generate_statistics: false
83 # modify batch size as necessary
84 hibernate.jdbc.batch_size: 25
85 hibernate.order_inserts: true
86 hibernate.order_updates: true
87 hibernate.query.fail_on_pagination_over_collection_fetch: true
88 hibernate.query.in_clause_parameter_padding: true
89 hibernate:
90 ddl-auto: none
91 naming:
92 physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
93 implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
94 messages:
95 basename: i18n/messages
96 main:
97 allow-bean-definition-overriding: true
98 mvc:
99 favicon:
100 enabled: false
101 task:
102 execution:
103 thread-name-prefix: honlap-task-
104 pool:
105 core-size: 2
106 max-size: 50
107 queue-capacity: 10000
108 scheduling:
109 thread-name-prefix: honlap-scheduling-
110 pool:
111 size: 2
112 thymeleaf:
113 mode: HTML
114 output:
115 ansi:
116 console-available: true
117
118 server:
119 servlet:
120 session:
121 cookie:
122 http-only: true
123
124 # Properties to be exposed on the /info management endpoint
125 info:
126 # Comma separated list of profiles that will trigger the ribbon to show
127 display-ribbon-on-profiles: 'dev'
128
129 # ===================================================================
130 # JHipster specific properties
131 #
132 # Full reference is available at: https://www.jhipster.tech/common-application-properties/
133 # ===================================================================
134
135 jhipster:
136 clientApp:
137 name: 'honlapApp'
138 # By default CORS is disabled. Uncomment to enable.
139 # cors:
140 # allowed-origins: "*"
141 # allowed-methods: "*"
142 # allowed-headers: "*"
143 # exposed-headers: "Authorization,Link,X-Total-Count"
144 # allow-credentials: true
145 # max-age: 1800
146 mail:
147 from: honlap@localhost
148 swagger:
149 default-include-pattern: /api/.*
150 title: honlap API
151 description: honlap API documentation
152 version: 0.0.1
153 terms-of-service-url:
154 contact-name:
155 contact-url:
156 contact-email:
157 license:
158 license-url:
159 # ===================================================================
160 # Application specific properties
161 # Add your own application properties here, see the ApplicationProperties class
162 # to have type-safe configuration, like in the JHipsterProperties above
163 #
164 # More documentation is available at:
165 # https://www.jhipster.tech/common-application-properties/
166 # ===================================================================
167
168 # application:
File src/main/resources/config/liquibase/changelog/00000000000000_initial_schema.xml added (mode: 100644) (index 0000000..10ef5bb)
1 <?xml version="1.0" encoding="utf-8"?>
2 <databaseChangeLog
3 xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4 xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6 xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd
7 http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
8
9 <changeSet id="00000000000000" author="jhipster">
10 <createSequence sequenceName="sequence_generator" startValue="1050" incrementBy="50"/>
11 </changeSet>
12
13 <!--
14 JHipster core tables.
15 The initial schema has the '00000000000001' id, so that it is over-written if we re-generate it.
16 -->
17 <changeSet id="00000000000001" author="jhipster">
18 <createTable tableName="auth_user">
19 <column name="id" type="bigint" >
20 <constraints primaryKey="true" nullable="false"/>
21 </column>
22 <column name="login" type="varchar(50)">
23 <constraints unique="true" nullable="false" uniqueConstraintName="ux_user_login"/>
24 </column>
25 <column name="password_hash" type="varchar(60)"/>
26 <column name="first_name" type="varchar(50)"/>
27 <column name="last_name" type="varchar(50)"/>
28 <column name="email" type="varchar(191)">
29 <constraints unique="true" nullable="true" uniqueConstraintName="ux_user_email"/>
30 </column>
31 <column name="image_url" type="varchar(256)"/>
32 <column name="activated" type="boolean" valueBoolean="false">
33 <constraints nullable="false" />
34 </column>
35 <column name="lang_key" type="varchar(10)"/>
36 <column name="activation_key" type="varchar(20)"/>
37 <column name="reset_key" type="varchar(20)"/>
38 <column name="created_by" type="varchar(50)">
39 <constraints nullable="false"/>
40 </column>
41 <column name="created_date" type="timestamp"/>
42 <column name="reset_date" type="timestamp">
43 <constraints nullable="true"/>
44 </column>
45 <column name="last_modified_by" type="varchar(50)"/>
46 <column name="last_modified_date" type="timestamp"/>
47 </createTable>
48
49 <createTable tableName="auth_authority">
50 <column name="name" type="varchar(50)">
51 <constraints primaryKey="true" nullable="false"/>
52 </column>
53 </createTable>
54
55 <createTable tableName="auth_user_authority">
56 <column name="user_id" type="bigint">
57 <constraints nullable="false"/>
58 </column>
59 <column name="authority_name" type="varchar(50)">
60 <constraints nullable="false"/>
61 </column>
62 </createTable>
63
64 <addPrimaryKey columnNames="user_id, authority_name" tableName="auth_user_authority"/>
65
66 <addForeignKeyConstraint baseColumnNames="authority_name"
67 baseTableName="auth_user_authority"
68 constraintName="fk_authority_name"
69 referencedColumnNames="name"
70 referencedTableName="auth_authority"/>
71
72 <addForeignKeyConstraint baseColumnNames="user_id"
73 baseTableName="auth_user_authority"
74 constraintName="fk_user_id"
75 referencedColumnNames="id"
76 referencedTableName="auth_user"/>
77
78 <addNotNullConstraint columnName="password_hash"
79 columnDataType="varchar(60)"
80 tableName="auth_user"/>
81 <loadData
82 file="config/liquibase/data/user.csv"
83 separator=";"
84 tableName="auth_user">
85 <column name="id" type="numeric"/>
86 <column name="activated" type="boolean"/>
87 <column name="created_date" type="timestamp"/>
88 </loadData>
89 <dropDefaultValue tableName="auth_user" columnName="created_date" columnDataType="datetime"/>
90 <loadData
91 file="config/liquibase/data/authority.csv"
92 separator=";"
93 tableName="auth_authority">
94 <column name="name" type="string"/>
95 </loadData>
96
97 <loadData
98 file="config/liquibase/data/user_authority.csv"
99 separator=";"
100 tableName="auth_user_authority">
101 <column name="user_id" type="numeric"/>
102 </loadData>
103 <createTable tableName="auth_persistent_audit_event">
104 <column name="event_id" type="bigint" >
105 <constraints primaryKey="true" nullable="false"/>
106 </column>
107 <column name="principal" type="varchar(50)">
108 <constraints nullable="false" />
109 </column>
110 <column name="event_date" type="timestamp"/>
111 <column name="event_type" type="varchar(255)"/>
112 </createTable>
113
114 <createTable tableName="auth_persistent_audit_evt_data">
115 <column name="event_id" type="bigint">
116 <constraints nullable="false"/>
117 </column>
118 <column name="name" type="varchar(150)">
119 <constraints nullable="false"/>
120 </column>
121 <column name="value" type="varchar(255)"/>
122 </createTable>
123 <addPrimaryKey columnNames="event_id, name" tableName="auth_persistent_audit_evt_data"/>
124
125 <createIndex indexName="idx_persistent_audit_event"
126 tableName="auth_persistent_audit_event"
127 unique="false">
128 <column name="principal" type="varchar(50)"/>
129 <column name="event_date" type="timestamp"/>
130 </createIndex>
131
132 <createIndex indexName="idx_persistent_audit_evt_data"
133 tableName="auth_persistent_audit_evt_data"
134 unique="false">
135 <column name="event_id" type="bigint"/>
136 </createIndex>
137
138 <addForeignKeyConstraint baseColumnNames="event_id"
139 baseTableName="auth_persistent_audit_evt_data"
140 constraintName="fk_evt_pers_audit_evt_data"
141 referencedColumnNames="event_id"
142 referencedTableName="auth_persistent_audit_event"/>
143 </changeSet>
144
145 <changeSet author="jhipster" id="00000000000002" context="test">
146 <createTable tableName="auth_date_time_wrapper">
147 <column name="id" type="BIGINT">
148 <constraints primaryKey="true" primaryKeyName="auth_date_time_wrapperPK"/>
149 </column>
150 <column name="instant" type="timestamp"/>
151 <column name="local_date_time" type="timestamp"/>
152 <column name="offset_date_time" type="timestamp"/>
153 <column name="zoned_date_time" type="timestamp"/>
154 <column name="local_time" type="time"/>
155 <column name="offset_time" type="time"/>
156 <column name="local_date" type="date"/>
157 </createTable>
158 </changeSet>
159 </databaseChangeLog>
File src/main/resources/config/liquibase/changelog/20200326085000_added_entity_PieceOfNews.xml added (mode: 100644) (index 0000000..bdc5cd6)
1 <?xml version="1.0" encoding="utf-8"?>
2 <databaseChangeLog
3 xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4 xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6 xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd
7 http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
8
9
10 <!--
11 Added the entity PieceOfNews.
12 -->
13 <changeSet id="20200326085000-1" author="jhipster">
14 <createTable tableName="piece_of_news" remarks="Hírek">
15 <column name="id" type="bigint">
16 <constraints primaryKey="true" nullable="false"/>
17 </column>
18 <column name="app_id" type="integer">
19 <constraints nullable="false" />
20 </column>
21 <column name="news_date" type="datetime">
22 <constraints nullable="false" />
23 </column>
24 <column name="headline" type="varchar(300)">
25 <constraints nullable="false" />
26 </column>
27 <column name="content" type="varchar(600)">
28 <constraints nullable="false" />
29 </column>
30 <column name="link" type="varchar(600)">
31 <constraints nullable="false" />
32 </column>
33 <column name="publish_date" type="datetime">
34 <constraints nullable="true" />
35 </column>
36 <column name="created_by" type="varchar(255)">
37 <constraints nullable="true" />
38 </column>
39 <column name="created_date" type="datetime">
40 <constraints nullable="true" />
41 </column>
42 <column name="last_modified_by" type="varchar(255)">
43 <constraints nullable="true" />
44 </column>
45 <column name="last_modified_date" type="datetime">
46 <constraints nullable="true" />
47 </column>
48 <!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
49 </createTable>
50 <dropDefaultValue tableName="piece_of_news" columnName="news_date" columnDataType="datetime"/>
51 <dropDefaultValue tableName="piece_of_news" columnName="publish_date" columnDataType="datetime"/>
52 <dropDefaultValue tableName="piece_of_news" columnName="created_date" columnDataType="datetime"/>
53 <dropDefaultValue tableName="piece_of_news" columnName="last_modified_date" columnDataType="datetime"/>
54 </changeSet>
55
56 <changeSet id="20200326085000-1-relations" author="jhipster">
57
58 </changeSet>
59 <!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here, do not remove-->
60
61 <!--
62 Load sample data generated with Faker.js
63 - This data can be easily edited using a CSV editor (or even MS Excel) and
64 is located in the 'src/main/resources/config/liquibase/fake-data' directory
65 - By default this data is applied when running with the JHipster 'dev' profile.
66 This can be customized by adding or removing 'faker' in the 'spring.liquibase.contexts'
67 Spring Boot configuration key.
68 -->
69 <changeSet id="20200326085000-1-data" author="jhipster" context="faker">
70 <loadData
71 file="config/liquibase/fake-data/piece_of_news.csv"
72 separator=";"
73 tableName="piece_of_news">
74 <column name="id" type="numeric"/>
75 <column name="app_id" type="numeric"/>
76 <column name="news_date" type="datetime"/>
77 <column name="headline" type="string"/>
78 <column name="content" type="string"/>
79 <column name="link" type="string"/>
80 <column name="publish_date" type="datetime"/>
81 <column name="created_by" type="string"/>
82 <column name="created_date" type="datetime"/>
83 <column name="last_modified_by" type="string"/>
84 <column name="last_modified_date" type="datetime"/>
85 <!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here, do not remove-->
86 </loadData>
87 </changeSet>
88
89 </databaseChangeLog>
File src/main/resources/config/liquibase/data/authority.csv added (mode: 100644) (index 0000000..af5c6df)
1 name
2 ROLE_ADMIN
3 ROLE_USER
File src/main/resources/config/liquibase/data/user.csv added (mode: 100644) (index 0000000..3089c1b)
1 id;login;password_hash;first_name;last_name;email;image_url;activated;lang_key;created_by;last_modified_by
2 1;system;$2a$10$mE.qmcV0mFU5NcKh73TZx.z4ueI/.bDWbj0T1BYyqP481kGGarKLG;System;System;system@localhost;;true;hu;system;system
3 2;anonymoususer;$2a$10$j8S5d7Sr7.8VTOYNviDPOeWX8KcYILUVJBsYV83Y5NtECayypx9lO;Anonymous;User;anonymous@localhost;;true;hu;system;system
4 3;admin;$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC;Administrator;Administrator;admin@localhost;;true;hu;system;system
5 4;user;$2a$10$VEjxo0jq2YG9Rbk2HmX9S.k1uZBGYUHdUcid3g/vfiEl7lwWgOH/K;User;User;user@localhost;;true;hu;system;system
File src/main/resources/config/liquibase/data/user_authority.csv added (mode: 100644) (index 0000000..06c5fee)
1 user_id;authority_name
2 1;ROLE_ADMIN
3 1;ROLE_USER
4 3;ROLE_ADMIN
5 3;ROLE_USER
6 4;ROLE_USER
File src/main/resources/config/liquibase/fake-data/piece_of_news.csv added (mode: 100644) (index 0000000..500c7bf)
1 id;app_id;news_date;headline;content;link;publish_date;created_by;created_date;last_modified_by;last_modified_date
2 1;38858;2020-03-25T14:55:01;platforms Music action-items;Cambridgeshire;Florida streamline;2020-03-25T21:03:21;Personal Loan Account tangible Borders;2020-03-25T17:34:45;unleash;2020-03-25T11:34:00
3 2;599;2020-03-25T23:44:13;Hawaii;system engine Investment Account;Malta Soap multi-byte;2020-03-26T08:31:13;Serbian Dinar Cambridgeshire French Southern Territories;2020-03-25T11:48:41;Brand Designer;2020-03-25T23:57:00
4 3;68812;2020-03-25T18:59:45;Books calculate;cross-platform Cambridgeshire Knolls;Decentralized Ball;2020-03-25T16:47:26;Handmade transmit;2020-03-25T15:28:43;mobile;2020-03-25T18:58:38
5 4;30089;2020-03-26T01:55:42;neural iterate;Ergonomic Soft Table;invoice;2020-03-25T22:25:02;generate;2020-03-26T00:51:20;Cotton Burundi;2020-03-26T06:33:58
6 5;31763;2020-03-25T23:12:52;Sri Lanka Rupee;Dynamic Chief hard drive;Maine reboot orange;2020-03-25T17:13:52;Optimized;2020-03-25T19:06:11;Awesome Steel Tuna;2020-03-25T22:26:17
7 6;94138;2020-03-25T17:18:14;composite Executive indexing;frame;Tools Personal Loan Account Bedfordshire;2020-03-25T21:05:21;best-of-breed cultivate;2020-03-25T12:40:51;Metrics navigating;2020-03-25T22:50:17
8 7;88844;2020-03-25T21:09:19;Saint Pierre and Miquelon Stravenue XML;primary initiatives;e-business Books;2020-03-26T06:29:56;array redundant;2020-03-26T04:53:12;brand;2020-03-25T17:27:42
9 8;14466;2020-03-25T11:48:53;payment Bosnia and Herzegovina driver;envisioneer;system Markets;2020-03-26T03:03:46;engineer HTTP Games;2020-03-26T08:27:39;Kids;2020-03-26T00:00:39
10 9;98697;2020-03-26T08:06:27;withdrawal;payment encryption;Senior;2020-03-25T12:00:14;Small Metal Table 1080p;2020-03-25T09:44:31;Missouri;2020-03-25T19:08:41
11 10;46840;2020-03-25T10:51:37;port Analyst Mississippi;Auto Loan Account Outdoors Licensed Plastic Soap;Cambridgeshire Ergonomic Steel Mouse;2020-03-26T03:42:54;seamless Metal bandwidth;2020-03-25T14:00:17;Connecticut bypass Architect;2020-03-25T22:37:51
File src/main/resources/config/liquibase/master.xml added (mode: 100644) (index 0000000..d4c2562)
1 <?xml version="1.0" encoding="utf-8"?>
2 <databaseChangeLog
3 xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
6
7 <property name="now" value="now()" dbms="h2"/>
8 <property name="now" value="current_timestamp" dbms="postgresql"/>
9
10 <property name="floatType" value="float4" dbms="postgresql, h2"/>
11 <property name="floatType" value="float" dbms="mysql, oracle, mssql, mariadb"/>
12 <property name="clobType" value="longvarchar" dbms="h2"/>
13 <property name="clobType" value="clob" dbms="mysql, oracle, mssql, mariadb, postgresql"/>
14 <property name="uuidType" value="uuid" dbms="h2, postgresql"/>
15
16 <include file="config/liquibase/changelog/00000000000000_initial_schema.xml" relativeToChangelogFile="false"/>
17 <include file="config/liquibase/changelog/20200326085000_added_entity_PieceOfNews.xml" relativeToChangelogFile="false"/>
18 <!-- jhipster-needle-liquibase-add-changelog - JHipster will add liquibase changelogs here -->
19 <!-- jhipster-needle-liquibase-add-constraints-changelog - JHipster will add liquibase constraints changelogs here -->
20 </databaseChangeLog>
File src/main/resources/config/tls/keystore.p12 added (mode: 100644) (index 0000000..a9c8793)
File src/main/resources/i18n/messages.properties added (mode: 100644) (index 0000000..e0f2f63)
1 # Error page
2 error.title=Your request cannot be processed
3 error.subtitle=Sorry, an error has occurred.
4 error.status=Status:
5 error.message=Message:
6
7 # Activation email
8 email.activation.title=honlap account activation is required
9 email.activation.greeting=Dear {0}
10 email.activation.text1=Your honlap account has been created, please click on the URL below to activate it:
11 email.activation.text2=Regards,
12 email.signature=honlap Team.
13
14 # Creation email
15 email.creation.text1=Your honlap account has been created, please click on the URL below to access it:
16
17 # Reset email
18 email.reset.title=honlap password reset
19 email.reset.greeting=Dear {0}
20 email.reset.text1=For your honlap account a password reset was requested, please click on the URL below to reset it:
21 email.reset.text2=Regards,
File src/main/resources/i18n/messages_en.properties added (mode: 100644) (index 0000000..9b4d488)
1 # Error page
2 error.title=Your request cannot be processed
3 error.subtitle=Sorry, an error has occurred.
4 error.status=Status:
5 error.message=Message:
6
7 # Activation email
8 email.activation.title=honlap account activation
9 email.activation.greeting=Dear {0}
10 email.activation.text1=Your honlap account has been created, please click on the URL below to activate it:
11 email.activation.text2=Regards,
12 email.signature=honlap Team.
13
14 # Creation email
15 email.creation.text1=Your honlap account has been created, please click on the URL below to access it:
16
17 # Reset email
18 email.reset.title=honlap password reset
19 email.reset.greeting=Dear {0}
20 email.reset.text1=For your honlap account a password reset was requested, please click on the URL below to reset it:
21 email.reset.text2=Regards,
File src/main/resources/i18n/messages_hu.properties added (mode: 100644) (index 0000000..2d72b58)
1 # Error page
2 error.title=A kérése nem hajtható végre
3 error.subtitle=Elnézést, hiba történt
4 error.status=Státusz:
5 error.message=Üzenet:
6
7 # Activation email
8 email.activation.title=honlap hozzáférés aktiválása.
9 email.activation.greeting=Tisztelt {0}
10 email.activation.text1=Az Ön honlap hozzáférése elkészült, kérjük kattintson az alább található linkre az aktiváláshoz.
11 email.activation.text2=Üdvözlettel,
12 email.signature=honlap csapat.
13
14 # Creation email
15 email.creation.text1=Az Ön honlap hozzáférése elkészült, kérjük kattintson az alább található linkre a belépéshez:
16
17 # Reset email
18 email.reset.title=honlap jelszó visszaállítás
19 email.reset.greeting=Tisztelt {0}
20 email.reset.text1=Az Ön honlap fiókjához jelszó-visszaállítót kértek, kérjük kattintson az alábbi linkre, hogy a jelszavát visszaállíthassa :
21 email.reset.text2=Üdvözlettel,
File src/main/resources/logback-spring.xml added (mode: 100644) (index 0000000..1f90362)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration>
3
4 <configuration scan="true">
5 <include resource="org/springframework/boot/logging/logback/base.xml"/>
6
7 <!-- The FILE and ASYNC appenders are here as examples for a production configuration -->
8 <!--
9 <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
10 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
11 <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
12 <maxHistory>90</maxHistory>
13 </rollingPolicy>
14 <encoder>
15 <charset>utf-8</charset>
16 <Pattern>%d %-5level [%thread] %logger{0}: %msg%n</Pattern>
17 </encoder>
18 </appender>
19
20 <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
21 <queueSize>512</queueSize>
22 <appender-ref ref="FILE"/>
23 </appender>
24
25 <root level="${logging.level.root}">
26 <appender-ref ref="ASYNC"/>
27 </root>
28 -->
29
30 <logger name="javax.activation" level="WARN"/>
31 <logger name="javax.mail" level="WARN"/>
32 <logger name="javax.management.remote" level="WARN"/>
33 <logger name="javax.xml.bind" level="WARN"/>
34 <logger name="ch.qos.logback" level="WARN"/>
35 <logger name="com.ryantenney" level="WARN"/>
36 <logger name="com.sun" level="WARN"/>
37 <logger name="com.zaxxer" level="WARN"/>
38 <logger name="io.undertow" level="WARN"/>
39 <logger name="io.undertow.websockets.jsr" level="ERROR"/>
40 <logger name="org.ehcache" level="WARN"/>
41 <logger name="org.apache" level="WARN"/>
42 <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/>
43 <logger name="org.bson" level="WARN"/>
44 <logger name="org.hibernate.validator" level="WARN"/>
45 <logger name="org.hibernate" level="WARN"/>
46 <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
47 <logger name="org.postgresql" level="WARN"/>
48 <logger name="org.springframework" level="WARN"/>
49 <logger name="org.springframework.web" level="WARN"/>
50 <logger name="org.springframework.security" level="WARN"/>
51 <logger name="org.springframework.cache" level="WARN"/>
52 <logger name="org.thymeleaf" level="WARN"/>
53 <logger name="org.xnio" level="WARN"/>
54 <logger name="springfox" level="WARN"/>
55 <logger name="sun.rmi" level="WARN"/>
56 <logger name="liquibase" level="WARN"/>
57 <logger name="LiquibaseSchemaResolver" level="INFO"/>
58 <logger name="springfox.documentation.schema.property" level="ERROR"/>
59 <logger name="sun.rmi.transport" level="WARN"/>
60 <!-- jhipster-needle-logback-add-log - JHipster will add a new log with level, Do not remove -->
61
62 <!-- https://logback.qos.ch/manual/configuration.html#shutdownHook and https://jira.qos.ch/browse/LOGBACK-1090 -->
63 <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
64
65 <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
66 <resetJUL>true</resetJUL>
67 </contextListener>
68
69 </configuration>
File src/main/resources/templates/error.html added (mode: 100644) (index 0000000..b703488)
1 <!DOCTYPE html>
2 <html xmlns:th="http://www.thymeleaf.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://www.thymeleaf.org" th:lang="${#locale.language}" lang="en">
4 <head>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
6 <link rel="shortcut icon" href="${baseUrl}/favicon.ico" />
7 <title>Your request cannot be processed</title>
8 <style>
9 ::-moz-selection {
10 background: #b3d4fc;
11 text-shadow: none;
12 }
13
14 ::selection {
15 background: #b3d4fc;
16 text-shadow: none;
17 }
18
19 html {
20 padding: 30px 10px;
21 font-size: 20px;
22 line-height: 1.4;
23 color: #737373;
24 background: #3E8ACC;
25 -webkit-text-size-adjust: 100%;
26 -ms-text-size-adjust: 100%;
27 }
28
29 html,
30 input {
31 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
32 }
33
34 body {
35 max-width: 1000px;
36 _width: 500px;
37 padding: 30px 20px 50px;
38 border: 1px solid #b3b3b3;
39 border-radius: 4px;
40 margin: 0 auto;
41 box-shadow: 0 1px 10px #a7a7a7, inset 0 1px 0 #fff;
42 background: #fcfcfc;
43 }
44
45 h1 {
46 margin: 0 10px;
47 font-size: 50px;
48 text-align: center;
49 }
50
51 h1 span {
52 color: #bbb;
53 }
54
55 h3 {
56 margin: 1.5em 0 0.5em;
57 }
58
59 p {
60 margin: 1em 0;
61 }
62
63 ul {
64 padding: 0 0 0 40px;
65 margin: 1em 0;
66 }
67
68 .container {
69 max-width: 800px;
70 _width: 380px;
71 margin: 0 auto;
72 }
73 </style>
74 </head>
75 <body>
76 <div class="container">
77 <h1 th:text="#{error.title}">Your request cannot be processed <span>:(</span></h1>
78
79 <p th:text="#{error.subtitle}">Sorry, an error has occurred.</p>
80
81 <span th:text="#{error.status}">Status:</span>&nbsp;<span th:text="${error}"></span>&nbsp;(<span th:text="${error}"></span>)<br/>
82 <span th:if="${!#strings.isEmpty(message)}">
83 <span th:text="#{error.message}">Message:</span>&nbsp;<span th:text="${message}"></span><br/>
84 </span>
85 </div>
86 </body>
87 </html>
File src/main/resources/templates/mail/activationEmail.html added (mode: 100644) (index 0000000..f88aa94)
1 <!DOCTYPE html>
2 <html xmlns:th="http://www.thymeleaf.org" th:lang="${#locale.language}" lang="en">
3 <head>
4 <title th:text="#{email.activation.title}">JHipster activation</title>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6 <link rel="shortcut icon" th:href="@{|${baseUrl}/favicon.ico|}" />
7 </head>
8 <body>
9 <p th:text="#{email.activation.greeting(${user.login})}">
10 Dear
11 </p>
12 <p th:text="#{email.activation.text1}">
13 Your JHipster account has been created, please click on the URL below to activate it:
14 </p>
15 <p>
16 <a th:with="url=(@{|${baseUrl}/account/activate?key=${user.activationKey}|})" th:href="${url}"
17 th:text="${url}">Activation link</a>
18 </p>
19 <p>
20 <span th:text="#{email.activation.text2}">Regards, </span>
21 <br/>
22 <em th:text="#{email.signature}">JHipster.</em>
23 </p>
24 </body>
25 </html>
File src/main/resources/templates/mail/creationEmail.html added (mode: 100644) (index 0000000..26d3fe4)
1 <!DOCTYPE html>
2 <html xmlns:th="http://www.thymeleaf.org" th:lang="${#locale.language}" lang="en">
3 <head>
4 <title th:text="#{email.activation.title}">JHipster creation</title>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6 <link rel="shortcut icon" th:href="@{|${baseUrl}/favicon.ico|}" />
7 </head>
8 <body>
9 <p th:text="#{email.activation.greeting(${user.login})}">
10 Dear
11 </p>
12 <p th:text="#{email.creation.text1}">
13 Your JHipster account has been created, please click on the URL below to access it:
14 </p>
15 <p>
16 <a th:with="url=(@{|${baseUrl}/account/reset/finish?key=${user.resetKey}|})" th:href="${url}"
17 th:text="${url}">Login link</a>
18 </p>
19 <p>
20 <span th:text="#{email.activation.text2}">Regards, </span>
21 <br/>
22 <em th:text="#{email.signature}">JHipster.</em>
23 </p>
24 </body>
25 </html>
File src/main/resources/templates/mail/passwordResetEmail.html added (mode: 100644) (index 0000000..c5ae07f)
1 <!DOCTYPE html>
2 <html xmlns:th="http://www.thymeleaf.org" th:lang="${#locale.language}" lang="en">
3 <head>
4 <title th:text="#{email.reset.title}">JHipster password reset</title>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6 <link rel="shortcut icon" th:href="@{|${baseUrl}/favicon.ico|}" />
7 </head>
8 <body>
9 <p th:text="#{email.reset.greeting(${user.login})}">
10 Dear
11 </p>
12 <p th:text="#{email.reset.text1}">
13 For your JHipster account a password reset was requested, please click on the URL below to reset it:
14 </p>
15 <p>
16 <a th:with="url=(@{|${baseUrl}/account/reset/finish?key=${user.resetKey}|})" th:href="${url}"
17 th:text="${url}">Login link</a>
18 </p>
19 <p>
20 <span th:text="#{email.reset.text2}">Regards, </span>
21 <br/>
22 <em th:text="#{email.signature}">JHipster.</em>
23 </p>
24 </body>
25 </html>
File src/main/webapp/404.html added (mode: 100644) (index 0000000..cf8bb74)
1 <!doctype html>
2 <html lang="hu">
3 <head>
4 <meta charset="utf-8">
5 <title>Page Not Found</title>
6 <meta name="viewport" content="width=device-width, initial-scale=1">
7 <link rel="shortcut icon" href="favicon.ico" />
8 <style>
9
10 * {
11 line-height: 1.2;
12 margin: 0;
13 }
14
15 html {
16 color: #888;
17 display: table;
18 font-family: sans-serif;
19 height: 100%;
20 text-align: center;
21 width: 100%;
22 }
23
24 body {
25 display: table-cell;
26 vertical-align: middle;
27 margin: 2em auto;
28 }
29
30 h1 {
31 color: #555;
32 font-size: 2em;
33 font-weight: 400;
34 }
35
36 p {
37 margin: 0 auto;
38 width: 280px;
39 }
40
41 @media only screen and (max-width: 280px) {
42
43 body, p {
44 width: 95%;
45 }
46
47 h1 {
48 font-size: 1.5em;
49 margin: 0 0 0.3em;
50 }
51
52 }
53
54 </style>
55 </head>
56 <body>
57 <h1>Page Not Found</h1>
58 <p>Sorry, but the page you were trying to view does not exist.</p>
59 </body>
60 </html>
61 <!-- IE needs 512+ bytes: http://blogs.msdn.com/b/ieinternals/archive/2010/08/19/http-error-pages-in-internet-explorer.aspx -->
File src/main/webapp/WEB-INF/web.xml added (mode: 100644) (index 0000000..f1611b5)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app
3 xmlns="http://java.sun.com/xml/ns/javaee"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
6 version="3.0">
7
8 <mime-mapping>
9 <extension>html</extension>
10 <mime-type>text/html;charset=utf-8</mime-type>
11 </mime-mapping>
12
13 </web-app>
File src/main/webapp/app/account/account.module.ts added (mode: 100644) (index 0000000..90fb55c)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3
4 import { HonlapSharedModule } from 'app/shared/shared.module';
5
6 import { PasswordStrengthBarComponent } from './password/password-strength-bar.component';
7 import { RegisterComponent } from './register/register.component';
8 import { ActivateComponent } from './activate/activate.component';
9 import { PasswordComponent } from './password/password.component';
10 import { PasswordResetInitComponent } from './password-reset/init/password-reset-init.component';
11 import { PasswordResetFinishComponent } from './password-reset/finish/password-reset-finish.component';
12 import { SettingsComponent } from './settings/settings.component';
13 import { accountState } from './account.route';
14
15 @NgModule({
16 imports: [HonlapSharedModule, RouterModule.forChild(accountState)],
17 declarations: [
18 ActivateComponent,
19 RegisterComponent,
20 PasswordComponent,
21 PasswordStrengthBarComponent,
22 PasswordResetInitComponent,
23 PasswordResetFinishComponent,
24 SettingsComponent
25 ]
26 })
27 export class AccountModule {}
File src/main/webapp/app/account/account.route.ts added (mode: 100644) (index 0000000..3c15bb7)
1 import { Routes } from '@angular/router';
2
3 import { activateRoute } from './activate/activate.route';
4 import { passwordRoute } from './password/password.route';
5 import { passwordResetFinishRoute } from './password-reset/finish/password-reset-finish.route';
6 import { passwordResetInitRoute } from './password-reset/init/password-reset-init.route';
7 import { registerRoute } from './register/register.route';
8 import { settingsRoute } from './settings/settings.route';
9
10 const ACCOUNT_ROUTES = [activateRoute, passwordRoute, passwordResetFinishRoute, passwordResetInitRoute, registerRoute, settingsRoute];
11
12 export const accountState: Routes = [
13 {
14 path: '',
15 children: ACCOUNT_ROUTES
16 }
17 ];
File src/main/webapp/app/account/activate/activate.component.html added (mode: 100644) (index 0000000..92b942b)
1 <div>
2 <div class="row justify-content-center">
3 <div class="col-md-8">
4 <h1 jhiTranslate="activate.title">Activation</h1>
5
6 <div class="alert alert-success" *ngIf="success">
7 <span jhiTranslate="activate.messages.success"><strong>Your user account has been activated.</strong> Please </span>
8 <a class="alert-link" (click)="login()" jhiTranslate="global.messages.info.authenticated.link">sign in</a>.
9 </div>
10
11 <div class="alert alert-danger" *ngIf="error" jhiTranslate="activate.messages.error">
12 <strong>Your user could not be activated.</strong> Please use the registration form to sign up.
13 </div>
14 </div>
15 </div>
16 </div>
File src/main/webapp/app/account/activate/activate.component.ts added (mode: 100644) (index 0000000..ff525da)
1 import { Component, OnInit } from '@angular/core';
2 import { ActivatedRoute } from '@angular/router';
3 import { flatMap } from 'rxjs/operators';
4
5 import { LoginModalService } from 'app/core/login/login-modal.service';
6 import { ActivateService } from './activate.service';
7
8 @Component({
9 selector: 'auth-activate',
10 templateUrl: './activate.component.html'
11 })
12 export class ActivateComponent implements OnInit {
13 error = false;
14 success = false;
15
16 constructor(private activateService: ActivateService, private loginModalService: LoginModalService, private route: ActivatedRoute) {}
17
18 ngOnInit(): void {
19 this.route.queryParams.pipe(flatMap(params => this.activateService.get(params.key))).subscribe(
20 () => (this.success = true),
21 () => (this.error = true)
22 );
23 }
24
25 login(): void {
26 this.loginModalService.open();
27 }
28 }
File src/main/webapp/app/account/activate/activate.route.ts added (mode: 100644) (index 0000000..a988352)
1 import { Route } from '@angular/router';
2
3 import { ActivateComponent } from './activate.component';
4
5 export const activateRoute: Route = {
6 path: 'activate',
7 component: ActivateComponent,
8 data: {
9 authorities: [],
10 pageTitle: 'activate.title'
11 }
12 };
File src/main/webapp/app/account/activate/activate.service.ts added (mode: 100644) (index 0000000..9cac51e)
1 import { Injectable } from '@angular/core';
2 import { HttpClient, HttpParams } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 @Injectable({ providedIn: 'root' })
8 export class ActivateService {
9 constructor(private http: HttpClient) {}
10
11 get(key: string): Observable<{}> {
12 return this.http.get(SERVER_API_URL + 'api/activate', {
13 params: new HttpParams().set('key', key)
14 });
15 }
16 }
File src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.html added (mode: 100644) (index 0000000..9c5e5b9)
1 <div>
2 <div class="row justify-content-center">
3 <div class="col-md-4">
4 <h1 jhiTranslate="reset.finish.title">Reset password</h1>
5
6 <div class="alert alert-danger" jhiTranslate="reset.finish.messages.keymissing" *ngIf="initialized && !key">
7 <strong>The password reset key is missing.</strong>
8 </div>
9
10 <div class="alert alert-warning" *ngIf="key && !success">
11 <span jhiTranslate="reset.finish.messages.info">Choose a new password</span>
12 </div>
13
14 <div class="alert alert-danger" *ngIf="error">
15 <span jhiTranslate="reset.finish.messages.error">Your password couldn't be reset. Remember a password request is only valid for 24 hours.</span>
16 </div>
17
18 <div class="alert alert-success" *ngIf="success">
19 <span jhiTranslate="reset.finish.messages.success"><strong>Your password has been reset.</strong> Please </span>
20 <a class="alert-link" (click)="login()" jhiTranslate="global.messages.info.authenticated.link">sign in</a>.
21 </div>
22
23 <div class="alert alert-danger" *ngIf="doNotMatch" jhiTranslate="global.messages.error.dontmatch">
24 The password and its confirmation do not match!
25 </div>
26
27 <div *ngIf="key && !success">
28 <form name="form" role="form" (ngSubmit)="finishReset()" [formGroup]="passwordForm">
29 <div class="form-group">
30 <label class="form-control-label" for="newPassword" jhiTranslate="global.form.newpassword.label">New password</label>
31 <input type="password" class="form-control" id="newPassword" name="newPassword"
32 placeholder="{{ 'global.form.newpassword.placeholder' | translate }}"
33 formControlName="newPassword" #newPassword>
34
35 <div *ngIf="passwordForm.get('newPassword')!.invalid && (passwordForm.get('newPassword')!.dirty || passwordForm.get('newPassword')!.touched)">
36 <small class="form-text text-danger"
37 *ngIf="passwordForm.get('newPassword')?.errors?.required"
38 jhiTranslate="global.messages.validate.newpassword.required">
39 Your password is required.
40 </small>
41
42 <small class="form-text text-danger"
43 *ngIf="passwordForm.get('newPassword')?.errors?.minlength"
44 jhiTranslate="global.messages.validate.newpassword.minlength">
45 Your password is required to be at least 4 characters.
46 </small>
47
48 <small class="form-text text-danger"
49 *ngIf="passwordForm.get('newPassword')?.errors?.maxlength"
50 jhiTranslate="global.messages.validate.newpassword.maxlength">
51 Your password cannot be longer than 50 characters.
52 </small>
53 </div>
54
55 <auth-password-strength-bar [passwordToCheck]="passwordForm.get('newPassword')!.value"></auth-password-strength-bar>
56 </div>
57
58 <div class="form-group">
59 <label class="form-control-label" for="confirmPassword" jhiTranslate="global.form.confirmpassword.label">New password confirmation</label>
60 <input type="password" class="form-control" id="confirmPassword" name="confirmPassword"
61 placeholder="{{ 'global.form.confirmpassword.placeholder' | translate }}"
62 formControlName="confirmPassword">
63
64 <div *ngIf="passwordForm.get('confirmPassword')!.invalid && (passwordForm.get('confirmPassword')!.dirty || passwordForm.get('confirmPassword')!.touched)">
65 <small class="form-text text-danger"
66 *ngIf="passwordForm.get('confirmPassword')?.errors?.required"
67 jhiTranslate="global.messages.validate.confirmpassword.required">
68 Your password confirmation is required.
69 </small>
70
71 <small class="form-text text-danger"
72 *ngIf="passwordForm.get('confirmPassword')?.errors?.minlength"
73 jhiTranslate="global.messages.validate.confirmpassword.minlength">
74 Your password confirmation is required to be at least 4 characters.
75 </small>
76
77 <small class="form-text text-danger"
78 *ngIf="passwordForm.get('confirmPassword')?.errors?.maxlength"
79 jhiTranslate="global.messages.validate.confirmpassword.maxlength">
80 Your password confirmation cannot be longer than 50 characters.
81 </small>
82 </div>
83 </div>
84
85 <button type="submit" [disabled]="passwordForm.invalid" class="btn btn-primary" jhiTranslate="reset.finish.form.button">Reset Password</button>
86 </form>
87 </div>
88 </div>
89 </div>
90 </div>
File src/main/webapp/app/account/password-reset/finish/password-reset-finish.component.ts added (mode: 100644) (index 0000000..11f940c)
1 import { Component, OnInit, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
2 import { FormBuilder, Validators } from '@angular/forms';
3 import { ActivatedRoute } from '@angular/router';
4
5 import { LoginModalService } from 'app/core/login/login-modal.service';
6 import { PasswordResetFinishService } from './password-reset-finish.service';
7
8 @Component({
9 selector: 'auth-password-reset-finish',
10 templateUrl: './password-reset-finish.component.html'
11 })
12 export class PasswordResetFinishComponent implements OnInit, AfterViewInit {
13 @ViewChild('newPassword', { static: false })
14 newPassword?: ElementRef;
15
16 initialized = false;
17 doNotMatch = false;
18 error = false;
19 success = false;
20 key = '';
21
22 passwordForm = this.fb.group({
23 newPassword: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(50)]],
24 confirmPassword: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(50)]]
25 });
26
27 constructor(
28 private passwordResetFinishService: PasswordResetFinishService,
29 private loginModalService: LoginModalService,
30 private route: ActivatedRoute,
31 private fb: FormBuilder
32 ) {}
33
34 ngOnInit(): void {
35 this.route.queryParams.subscribe(params => {
36 if (params['key']) {
37 this.key = params['key'];
38 }
39 this.initialized = true;
40 });
41 }
42
43 ngAfterViewInit(): void {
44 if (this.newPassword) {
45 this.newPassword.nativeElement.focus();
46 }
47 }
48
49 finishReset(): void {
50 this.doNotMatch = false;
51 this.error = false;
52
53 const newPassword = this.passwordForm.get(['newPassword'])!.value;
54 const confirmPassword = this.passwordForm.get(['confirmPassword'])!.value;
55
56 if (newPassword !== confirmPassword) {
57 this.doNotMatch = true;
58 } else {
59 this.passwordResetFinishService.save(this.key, newPassword).subscribe(
60 () => (this.success = true),
61 () => (this.error = true)
62 );
63 }
64 }
65
66 login(): void {
67 this.loginModalService.open();
68 }
69 }
File src/main/webapp/app/account/password-reset/finish/password-reset-finish.route.ts added (mode: 100644) (index 0000000..0cff2b0)
1 import { Route } from '@angular/router';
2
3 import { PasswordResetFinishComponent } from './password-reset-finish.component';
4
5 export const passwordResetFinishRoute: Route = {
6 path: 'reset/finish',
7 component: PasswordResetFinishComponent,
8 data: {
9 authorities: [],
10 pageTitle: 'global.menu.account.password'
11 }
12 };
File src/main/webapp/app/account/password-reset/finish/password-reset-finish.service.ts added (mode: 100644) (index 0000000..2473629)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 @Injectable({ providedIn: 'root' })
8 export class PasswordResetFinishService {
9 constructor(private http: HttpClient) {}
10
11 save(key: string, newPassword: string): Observable<{}> {
12 return this.http.post(SERVER_API_URL + 'api/account/reset-password/finish', { key, newPassword });
13 }
14 }
File src/main/webapp/app/account/password-reset/init/password-reset-init.component.html added (mode: 100644) (index 0000000..8396afa)
1 <div>
2 <div class="row justify-content-center">
3 <div class="col-md-8">
4 <h1 jhiTranslate="reset.request.title">Reset your password</h1>
5
6 <auth-alert-error></auth-alert-error>
7
8 <div class="alert alert-warning" *ngIf="!success">
9 <span jhiTranslate="reset.request.messages.info">Enter the email address you used to register.</span>
10 </div>
11
12 <div class="alert alert-success" *ngIf="success">
13 <span jhiTranslate="reset.request.messages.success">Check your emails for details on how to reset your password.</span>
14 </div>
15
16 <form *ngIf="!success" name="form" role="form" (ngSubmit)="requestReset()" [formGroup]="resetRequestForm">
17 <div class="form-group">
18 <label class="form-control-label" for="email" jhiTranslate="global.form.email.label">Email</label>
19 <input type="email" class="form-control" id="email" name="email" placeholder="{{ 'global.form.email.placeholder' | translate }}"
20 formControlName="email" #email>
21
22 <div *ngIf="resetRequestForm.get('email')!.invalid && (resetRequestForm.get('email')!.dirty || resetRequestForm.get('email')!.touched)">
23 <small class="form-text text-danger"
24 *ngIf="resetRequestForm.get('email')?.errors?.required"
25 jhiTranslate="global.messages.validate.email.required">
26 Your email is required.
27 </small>
28
29 <small class="form-text text-danger"
30 *ngIf="resetRequestForm.get('email')?.errors?.email"
31 jhiTranslate="global.messages.validate.email.invalid">
32 Your email is invalid.
33 </small>
34
35 <small class="form-text text-danger"
36 *ngIf="resetRequestForm.get('email')?.errors?.minlength"
37 jhiTranslate="global.messages.validate.email.minlength">
38 Your email is required to be at least 5 characters.
39 </small>
40
41 <small class="form-text text-danger"
42 *ngIf="resetRequestForm.get('email')?.errors?.maxlength"
43 jhiTranslate="global.messages.validate.email.maxlength">
44 Your email cannot be longer than 100 characters.
45 </small>
46 </div>
47 </div>
48
49 <button type="submit" [disabled]="resetRequestForm.invalid" class="btn btn-primary" jhiTranslate="reset.request.form.button">Reset</button>
50 </form>
51 </div>
52 </div>
53 </div>
File src/main/webapp/app/account/password-reset/init/password-reset-init.component.ts added (mode: 100644) (index 0000000..700ad27)
1 import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
2 import { FormBuilder, Validators } from '@angular/forms';
3
4 import { PasswordResetInitService } from './password-reset-init.service';
5
6 @Component({
7 selector: 'auth-password-reset-init',
8 templateUrl: './password-reset-init.component.html'
9 })
10 export class PasswordResetInitComponent implements AfterViewInit {
11 @ViewChild('email', { static: false })
12 email?: ElementRef;
13
14 success = false;
15 resetRequestForm = this.fb.group({
16 email: ['', [Validators.required, Validators.minLength(5), Validators.maxLength(254), Validators.email]]
17 });
18
19 constructor(private passwordResetInitService: PasswordResetInitService, private fb: FormBuilder) {}
20
21 ngAfterViewInit(): void {
22 if (this.email) {
23 this.email.nativeElement.focus();
24 }
25 }
26
27 requestReset(): void {
28 this.passwordResetInitService.save(this.resetRequestForm.get(['email'])!.value).subscribe(() => (this.success = true));
29 }
30 }
File src/main/webapp/app/account/password-reset/init/password-reset-init.route.ts added (mode: 100644) (index 0000000..887c77b)
1 import { Route } from '@angular/router';
2
3 import { PasswordResetInitComponent } from './password-reset-init.component';
4
5 export const passwordResetInitRoute: Route = {
6 path: 'reset/request',
7 component: PasswordResetInitComponent,
8 data: {
9 authorities: [],
10 pageTitle: 'global.menu.account.password'
11 }
12 };
File src/main/webapp/app/account/password-reset/init/password-reset-init.service.ts added (mode: 100644) (index 0000000..368500c)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 @Injectable({ providedIn: 'root' })
8 export class PasswordResetInitService {
9 constructor(private http: HttpClient) {}
10
11 save(mail: string): Observable<{}> {
12 return this.http.post(SERVER_API_URL + 'api/account/reset-password/init', mail);
13 }
14 }
File src/main/webapp/app/account/password/password-strength-bar.component.ts added (mode: 100644) (index 0000000..4e9b236)
1 import { Component, ElementRef, Input, Renderer2 } from '@angular/core';
2
3 @Component({
4 selector: 'auth-password-strength-bar',
5 template: `
6 <div id="strength">
7 <small jhiTranslate="global.messages.validate.newpassword.strength">Password strength:</small>
8 <ul id="strengthBar">
9 <li class="point"></li>
10 <li class="point"></li>
11 <li class="point"></li>
12 <li class="point"></li>
13 <li class="point"></li>
14 </ul>
15 </div>
16 `,
17 styleUrls: ['password-strength-bar.scss']
18 })
19 export class PasswordStrengthBarComponent {
20 colors = ['#F00', '#F90', '#FF0', '#9F0', '#0F0'];
21
22 constructor(private renderer: Renderer2, private elementRef: ElementRef) {}
23
24 measureStrength(p: string): number {
25 let force = 0;
26 const regex = /[$-/:-?{-~!"^_`[\]]/g; // "
27 const lowerLetters = /[a-z]+/.test(p);
28 const upperLetters = /[A-Z]+/.test(p);
29 const numbers = /[0-9]+/.test(p);
30 const symbols = regex.test(p);
31
32 const flags = [lowerLetters, upperLetters, numbers, symbols];
33 const passedMatches = flags.filter((isMatchedFlag: boolean) => {
34 return isMatchedFlag === true;
35 }).length;
36
37 force += 2 * p.length + (p.length >= 10 ? 1 : 0);
38 force += passedMatches * 10;
39
40 // penalty (short password)
41 force = p.length <= 6 ? Math.min(force, 10) : force;
42
43 // penalty (poor variety of characters)
44 force = passedMatches === 1 ? Math.min(force, 10) : force;
45 force = passedMatches === 2 ? Math.min(force, 20) : force;
46 force = passedMatches === 3 ? Math.min(force, 40) : force;
47
48 return force;
49 }
50
51 getColor(s: number): { idx: number; color: string } {
52 let idx = 0;
53 if (s <= 10) {
54 idx = 0;
55 } else if (s <= 20) {
56 idx = 1;
57 } else if (s <= 30) {
58 idx = 2;
59 } else if (s <= 40) {
60 idx = 3;
61 } else {
62 idx = 4;
63 }
64 return { idx: idx + 1, color: this.colors[idx] };
65 }
66
67 @Input()
68 set passwordToCheck(password: string) {
69 if (password) {
70 const c = this.getColor(this.measureStrength(password));
71 const element = this.elementRef.nativeElement;
72 if (element.className) {
73 this.renderer.removeClass(element, element.className);
74 }
75 const lis = element.getElementsByTagName('li');
76 for (let i = 0; i < lis.length; i++) {
77 if (i < c.idx) {
78 this.renderer.setStyle(lis[i], 'backgroundColor', c.color);
79 } else {
80 this.renderer.setStyle(lis[i], 'backgroundColor', '#DDD');
81 }
82 }
83 }
84 }
85 }
File src/main/webapp/app/account/password/password-strength-bar.scss added (mode: 100644) (index 0000000..67ce468)
1 /* ==========================================================================
2 start Password strength bar style
3 ========================================================================== */
4 ul#strength {
5 display: inline;
6 list-style: none;
7 margin: 0;
8 margin-left: 15px;
9 padding: 0;
10 vertical-align: 2px;
11 }
12
13 .point {
14 background: #ddd;
15 border-radius: 2px;
16 display: inline-block;
17 height: 5px;
18 margin-right: 1px;
19 width: 20px;
20 &:last-child {
21 margin: 0 !important;
22 }
23 }
File src/main/webapp/app/account/password/password.component.html added (mode: 100644) (index 0000000..8d7d425)
1 <div>
2 <div class="row justify-content-center">
3 <div class="col-md-8" *ngIf="account$ | async as account">
4 <h2 jhiTranslate="password.title" [translateValues]="{ username: account.login }">Password for [<strong>{{ account.login }}</strong>]</h2>
5
6 <div class="alert alert-success" *ngIf="success" jhiTranslate="password.messages.success">
7 <strong>Password changed!</strong>
8 </div>
9
10 <div class="alert alert-danger" *ngIf="error" jhiTranslate="password.messages.error">
11 <strong>An error has occurred!</strong> The password could not be changed.
12 </div>
13
14 <div class="alert alert-danger" *ngIf="doNotMatch" jhiTranslate="global.messages.error.dontmatch">
15 The password and its confirmation do not match!
16 </div>
17
18 <form name="form" role="form" (ngSubmit)="changePassword()" [formGroup]="passwordForm">
19 <div class="form-group">
20 <label class="form-control-label" for="currentPassword" jhiTranslate="global.form.currentpassword.label">Current password</label>
21 <input type="password" class="form-control" id="currentPassword" name="currentPassword"
22 placeholder="{{ 'global.form.currentpassword.placeholder' | translate }}"
23 formControlName="currentPassword">
24
25 <div *ngIf="passwordForm.get('currentPassword')!.invalid && (passwordForm.get('currentPassword')!.dirty || passwordForm.get('currentPassword')!.touched)" >
26 <small class="form-text text-danger"
27 *ngIf="passwordForm.get('currentPassword')?.errors?.required"
28 jhiTranslate="global.messages.validate.newpassword.required">
29 Your password is required.
30 </small>
31 </div>
32 </div>
33
34 <div class="form-group">
35 <label class="form-control-label" for="newPassword" jhiTranslate="global.form.newpassword.label">New password</label>
36 <input type="password" class="form-control" id="newPassword" name="newPassword"
37 placeholder="{{ 'global.form.newpassword.placeholder' | translate }}"
38 formControlName="newPassword">
39
40 <div *ngIf="passwordForm.get('newPassword')!.invalid && (passwordForm.get('newPassword')!.dirty || passwordForm.get('newPassword')!.touched)">
41 <small class="form-text text-danger"
42 *ngIf="passwordForm.get('newPassword')?.errors?.required"
43 jhiTranslate="global.messages.validate.newpassword.required">
44 Your password is required.
45 </small>
46
47 <small class="form-text text-danger"
48 *ngIf="passwordForm.get('newPassword')?.errors?.minlength"
49 jhiTranslate="global.messages.validate.newpassword.minlength">
50 Your password is required to be at least 4 characters.
51 </small>
52
53 <small class="form-text text-danger"
54 *ngIf="passwordForm.get('newPassword')?.errors?.maxlength"
55 jhiTranslate="global.messages.validate.newpassword.maxlength">
56 Your password cannot be longer than 50 characters.
57 </small>
58 </div>
59
60 <auth-password-strength-bar [passwordToCheck]="passwordForm.get('newPassword')!.value"></auth-password-strength-bar>
61 </div>
62
63 <div class="form-group">
64 <label class="form-control-label" for="confirmPassword" jhiTranslate="global.form.confirmpassword.label">New password confirmation</label>
65 <input type="password" class="form-control" id="confirmPassword" name="confirmPassword"
66 placeholder="{{ 'global.form.confirmpassword.placeholder' | translate }}"
67 formControlName="confirmPassword">
68
69 <div *ngIf="passwordForm.get('confirmPassword')!.invalid && (passwordForm.get('confirmPassword')!.dirty || passwordForm.get('confirmPassword')!.touched)">
70 <small class="form-text text-danger"
71 *ngIf="passwordForm.get('confirmPassword')?.errors?.required"
72 jhiTranslate="global.messages.validate.confirmpassword.required">
73 Your confirmation password is required.
74 </small>
75
76 <small class="form-text text-danger"
77 *ngIf="passwordForm.get('confirmPassword')?.errors?.minlength"
78 jhiTranslate="global.messages.validate.confirmpassword.minlength">
79 Your confirmation password is required to be at least 4 characters.
80 </small>
81
82 <small class="form-text text-danger"
83 *ngIf="passwordForm.get('confirmPassword')?.errors?.maxlength"
84 jhiTranslate="global.messages.validate.confirmpassword.maxlength">
85 Your confirmation password cannot be longer than 50 characters.
86 </small>
87 </div>
88 </div>
89
90 <button type="submit" [disabled]="passwordForm.invalid" class="btn btn-primary" jhiTranslate="password.form.button">Save</button>
91 </form>
92 </div>
93 </div>
94 </div>
File src/main/webapp/app/account/password/password.component.ts added (mode: 100644) (index 0000000..6fabe93)
1 import { Component, OnInit } from '@angular/core';
2 import { FormBuilder, Validators } from '@angular/forms';
3 import { Observable } from 'rxjs';
4
5 import { AccountService } from 'app/core/auth/account.service';
6 import { Account } from 'app/core/user/account.model';
7 import { PasswordService } from './password.service';
8
9 @Component({
10 selector: 'auth-password',
11 templateUrl: './password.component.html'
12 })
13 export class PasswordComponent implements OnInit {
14 doNotMatch = false;
15 error = false;
16 success = false;
17 account$?: Observable<Account | null>;
18 passwordForm = this.fb.group({
19 currentPassword: ['', [Validators.required]],
20 newPassword: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(50)]],
21 confirmPassword: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(50)]]
22 });
23
24 constructor(private passwordService: PasswordService, private accountService: AccountService, private fb: FormBuilder) {}
25
26 ngOnInit(): void {
27 this.account$ = this.accountService.identity();
28 }
29
30 changePassword(): void {
31 this.error = false;
32 this.success = false;
33 this.doNotMatch = false;
34
35 const newPassword = this.passwordForm.get(['newPassword'])!.value;
36 if (newPassword !== this.passwordForm.get(['confirmPassword'])!.value) {
37 this.doNotMatch = true;
38 } else {
39 this.passwordService.save(newPassword, this.passwordForm.get(['currentPassword'])!.value).subscribe(
40 () => (this.success = true),
41 () => (this.error = true)
42 );
43 }
44 }
45 }
File src/main/webapp/app/account/password/password.route.ts added (mode: 100644) (index 0000000..ab3b626)
1 import { Route } from '@angular/router';
2
3 import { UserRouteAccessService } from 'app/core/auth/user-route-access-service';
4 import { PasswordComponent } from './password.component';
5 import { Authority } from 'app/shared/constants/authority.constants';
6
7 export const passwordRoute: Route = {
8 path: 'password',
9 component: PasswordComponent,
10 data: {
11 authorities: [Authority.USER],
12 pageTitle: 'global.menu.account.password'
13 },
14 canActivate: [UserRouteAccessService]
15 };
File src/main/webapp/app/account/password/password.service.ts added (mode: 100644) (index 0000000..13017f8)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 @Injectable({ providedIn: 'root' })
8 export class PasswordService {
9 constructor(private http: HttpClient) {}
10
11 save(newPassword: string, currentPassword: string): Observable<{}> {
12 return this.http.post(SERVER_API_URL + 'api/account/change-password', { currentPassword, newPassword });
13 }
14 }
File src/main/webapp/app/account/register/register.component.html added (mode: 100644) (index 0000000..115cad5)
1 <div>
2 <div class="row justify-content-center">
3 <div class="col-md-8">
4 <h1 jhiTranslate="register.title">Registration</h1>
5
6 <div class="alert alert-success" *ngIf="success" jhiTranslate="register.messages.success">
7 <strong>Registration saved!</strong> Please check your email for confirmation.
8 </div>
9
10 <div class="alert alert-danger" *ngIf="error" jhiTranslate="register.messages.error.fail">
11 <strong>Registration failed!</strong> Please try again later.
12 </div>
13
14 <div class="alert alert-danger" *ngIf="errorUserExists" jhiTranslate="register.messages.error.userexists">
15 <strong>Login name already registered!</strong> Please choose another one.
16 </div>
17
18 <div class="alert alert-danger" *ngIf="errorEmailExists" jhiTranslate="register.messages.error.emailexists">
19 <strong>Email is already in use!</strong> Please choose another one.
20 </div>
21
22 <div class="alert alert-danger" *ngIf="doNotMatch" jhiTranslate="global.messages.error.dontmatch">
23 The password and its confirmation do not match!
24 </div>
25 </div>
26 </div>
27
28 <div class="row justify-content-center">
29 <div class="col-md-8">
30 <form name="form" role="form" (ngSubmit)="register()" [formGroup]="registerForm" *ngIf="!success">
31 <div class="form-group">
32 <label class="form-control-label" for="login" jhiTranslate="global.form.username.label">Username</label>
33 <input type="text" class="form-control" id="login" name="login" placeholder="{{ 'global.form.username.placeholder' | translate }}"
34 formControlName="login" #login>
35
36 <div *ngIf="registerForm.get('login')!.invalid && (registerForm.get('login')!.dirty || registerForm.get('login')!.touched)">
37 <small class="form-text text-danger"
38 *ngIf="registerForm.get('login')?.errors?.required"
39 jhiTranslate="register.messages.validate.login.required">
40 Your username is required.
41 </small>
42
43 <small class="form-text text-danger"
44 *ngIf="registerForm.get('login')?.errors?.minlength"
45 jhiTranslate="register.messages.validate.login.minlength">
46 Your username is required to be at least 1 character.
47 </small>
48
49 <small class="form-text text-danger"
50 *ngIf="registerForm.get('login')?.errors?.maxlength"
51 jhiTranslate="register.messages.validate.login.maxlength">
52 Your username cannot be longer than 50 characters.
53 </small>
54
55 <small class="form-text text-danger"
56 *ngIf="registerForm.get('login')?.errors?.pattern"
57 jhiTranslate="register.messages.validate.login.pattern">
58 Your username can only contain letters and digits.
59 </small>
60 </div>
61 </div>
62
63 <div class="form-group">
64 <label class="form-control-label" for="email" jhiTranslate="global.form.email.label">Email</label>
65 <input type="email" class="form-control" id="email" name="email" placeholder="{{ 'global.form.email.placeholder' | translate }}"
66 formControlName="email">
67
68 <div *ngIf="registerForm.get('email')!.invalid && (registerForm.get('email')!.dirty || registerForm.get('email')!.touched)">
69 <small class="form-text text-danger"
70 *ngIf="registerForm.get('email')?.errors?.required"
71 jhiTranslate="global.messages.validate.email.required">
72 Your email is required.
73 </small>
74
75 <small class="form-text text-danger"
76 *ngIf="registerForm.get('email')?.errors?.invalid"
77 jhiTranslate="global.messages.validate.email.invalid">
78 Your email is invalid.
79 </small>
80
81 <small class="form-text text-danger"
82 *ngIf="registerForm.get('email')?.errors?.minlength"
83 jhiTranslate="global.messages.validate.email.minlength">
84 Your email is required to be at least 5 characters.
85 </small>
86
87 <small class="form-text text-danger"
88 *ngIf="registerForm.get('email')?.errors?.maxlength"
89 jhiTranslate="global.messages.validate.email.maxlength">
90 Your email cannot be longer than 100 characters.
91 </small>
92 </div>
93 </div>
94
95 <div class="form-group">
96 <label class="form-control-label" for="password" jhiTranslate="global.form.newpassword.label">New password</label>
97 <input type="password" class="form-control" id="password" name="password" placeholder="{{ 'global.form.newpassword.placeholder' | translate }}"
98 formControlName="password">
99
100 <div *ngIf="registerForm.get('password')!.invalid && (registerForm.get('password')!.dirty || registerForm.get('password')!.touched)">
101 <small class="form-text text-danger"
102 *ngIf="registerForm.get('password')?.errors?.required"
103 jhiTranslate="global.messages.validate.newpassword.required">
104 Your password is required.
105 </small>
106
107 <small class="form-text text-danger"
108 *ngIf="registerForm.get('password')?.errors?.minlength"
109 jhiTranslate="global.messages.validate.newpassword.minlength">
110 Your password is required to be at least 4 characters.
111 </small>
112
113 <small class="form-text text-danger"
114 *ngIf="registerForm.get('password')?.errors?.maxlength"
115 jhiTranslate="global.messages.validate.newpassword.maxlength">
116 Your password cannot be longer than 50 characters.
117 </small>
118 </div>
119
120 <auth-password-strength-bar [passwordToCheck]="registerForm.get('password')!.value"></auth-password-strength-bar>
121 </div>
122
123 <div class="form-group">
124 <label class="form-control-label" for="confirmPassword" jhiTranslate="global.form.confirmpassword.label">New password confirmation</label>
125 <input type="password" class="form-control" id="confirmPassword" name="confirmPassword" placeholder="{{ 'global.form.confirmpassword.placeholder' | translate }}"
126 formControlName="confirmPassword">
127
128 <div *ngIf="registerForm.get('confirmPassword')!.invalid && (registerForm.get('confirmPassword')!.dirty || registerForm.get('confirmPassword')!.touched)">
129 <small class="form-text text-danger"
130 *ngIf="registerForm.get('confirmPassword')?.errors?.required"
131 jhiTranslate="global.messages.validate.confirmpassword.required">
132 Your confirmation password is required.
133 </small>
134
135 <small class="form-text text-danger"
136 *ngIf="registerForm.get('confirmPassword')?.errors?.minlength"
137 jhiTranslate="global.messages.validate.confirmpassword.minlength">
138 Your confirmation password is required to be at least 4 characters.
139 </small>
140
141 <small class="form-text text-danger"
142 *ngIf="registerForm.get('confirmPassword')?.errors?.maxlength"
143 jhiTranslate="global.messages.validate.confirmpassword.maxlength">
144 Your confirmation password cannot be longer than 50 characters.
145 </small>
146 </div>
147 </div>
148
149 <button type="submit" [disabled]="registerForm.invalid" class="btn btn-primary" jhiTranslate="register.form.button">Register</button>
150 </form>
151
152 <div class="mt-3 alert alert-warning">
153 <span jhiTranslate="global.messages.info.authenticated.prefix">If you want to </span>
154 <a class="alert-link" (click)="openLogin()" jhiTranslate="global.messages.info.authenticated.link">sign in</a><span jhiTranslate="global.messages.info.authenticated.suffix">, you can try the default accounts:<br/>- Administrator (login="admin" and password="admin") <br/>- User (login="user" and password="user").</span>
155 </div>
156 </div>
157 </div>
158 </div>
File src/main/webapp/app/account/register/register.component.ts added (mode: 100644) (index 0000000..22f1808)
1 import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
2 import { HttpErrorResponse } from '@angular/common/http';
3 import { FormBuilder, Validators } from '@angular/forms';
4 import { JhiLanguageService } from 'ng-jhipster';
5
6 import { EMAIL_ALREADY_USED_TYPE, LOGIN_ALREADY_USED_TYPE } from 'app/shared/constants/error.constants';
7 import { LoginModalService } from 'app/core/login/login-modal.service';
8 import { RegisterService } from './register.service';
9
10 @Component({
11 selector: 'auth-register',
12 templateUrl: './register.component.html'
13 })
14 export class RegisterComponent implements AfterViewInit {
15 @ViewChild('login', { static: false })
16 login?: ElementRef;
17
18 doNotMatch = false;
19 error = false;
20 errorEmailExists = false;
21 errorUserExists = false;
22 success = false;
23
24 registerForm = this.fb.group({
25 login: ['', [Validators.required, Validators.minLength(1), Validators.maxLength(50), Validators.pattern('^[_.@A-Za-z0-9-]*$')]],
26 email: ['', [Validators.required, Validators.minLength(5), Validators.maxLength(254), Validators.email]],
27 password: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(50)]],
28 confirmPassword: ['', [Validators.required, Validators.minLength(4), Validators.maxLength(50)]]
29 });
30
31 constructor(
32 private languageService: JhiLanguageService,
33 private loginModalService: LoginModalService,
34 private registerService: RegisterService,
35 private fb: FormBuilder
36 ) {}
37
38 ngAfterViewInit(): void {
39 if (this.login) {
40 this.login.nativeElement.focus();
41 }
42 }
43
44 register(): void {
45 this.doNotMatch = false;
46 this.error = false;
47 this.errorEmailExists = false;
48 this.errorUserExists = false;
49
50 const password = this.registerForm.get(['password'])!.value;
51 if (password !== this.registerForm.get(['confirmPassword'])!.value) {
52 this.doNotMatch = true;
53 } else {
54 const login = this.registerForm.get(['login'])!.value;
55 const email = this.registerForm.get(['email'])!.value;
56 this.registerService.save({ login, email, password, langKey: this.languageService.getCurrentLanguage() }).subscribe(
57 () => (this.success = true),
58 response => this.processError(response)
59 );
60 }
61 }
62
63 openLogin(): void {
64 this.loginModalService.open();
65 }
66
67 private processError(response: HttpErrorResponse): void {
68 if (response.status === 400 && response.error.type === LOGIN_ALREADY_USED_TYPE) {
69 this.errorUserExists = true;
70 } else if (response.status === 400 && response.error.type === EMAIL_ALREADY_USED_TYPE) {
71 this.errorEmailExists = true;
72 } else {
73 this.error = true;
74 }
75 }
76 }
File src/main/webapp/app/account/register/register.route.ts added (mode: 100644) (index 0000000..f4ede9d)
1 import { Route } from '@angular/router';
2
3 import { RegisterComponent } from './register.component';
4
5 export const registerRoute: Route = {
6 path: 'register',
7 component: RegisterComponent,
8 data: {
9 authorities: [],
10 pageTitle: 'register.title'
11 }
12 };
File src/main/webapp/app/account/register/register.service.ts added (mode: 100644) (index 0000000..9a51915)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6 import { IUser } from 'app/core/user/user.model';
7
8 @Injectable({ providedIn: 'root' })
9 export class RegisterService {
10 constructor(private http: HttpClient) {}
11
12 save(account: IUser): Observable<{}> {
13 return this.http.post(SERVER_API_URL + 'api/register', account);
14 }
15 }
File src/main/webapp/app/account/settings/settings.component.html added (mode: 100644) (index 0000000..5077fb2)
1 <div>
2 <div class="row justify-content-center">
3 <div class="col-md-8">
4 <h2 jhiTranslate="settings.title" [translateValues]="{ username: account.login }" *ngIf="account">User settings for [<b>{{ account.login }}</b>]</h2>
5
6 <div class="alert alert-success" *ngIf="success" jhiTranslate="settings.messages.success">
7 <strong>Settings saved!</strong>
8 </div>
9
10 <auth-alert-error></auth-alert-error>
11
12 <form name="form" role="form" (ngSubmit)="save()" [formGroup]="settingsForm" *ngIf="account" novalidate>
13 <div class="form-group">
14 <label class="form-control-label" for="firstName" jhiTranslate="settings.form.firstname">First Name</label>
15 <input type="text" class="form-control" id="firstName" name="firstName" placeholder="{{ 'settings.form.firstname.placeholder' | translate }}"
16 formControlName="firstName">
17
18 <div *ngIf="settingsForm.get('firstName')!.invalid && (settingsForm.get('firstName')!.dirty || settingsForm.get('firstName')!.touched)">
19 <small class="form-text text-danger"
20 *ngIf="settingsForm.get('firstName')?.errors?.required"
21 jhiTranslate="settings.messages.validate.firstname.required">
22 Your first name is required.
23 </small>
24
25 <small class="form-text text-danger"
26 *ngIf="settingsForm.get('firstName')?.errors?.minlength"
27 jhiTranslate="settings.messages.validate.firstname.minlength">
28 Your first name is required to be at least 1 character.
29 </small>
30
31 <small class="form-text text-danger"
32 *ngIf="settingsForm.get('firstName')?.errors?.maxlength"
33 jhiTranslate="settings.messages.validate.firstname.maxlength">
34 Your first name cannot be longer than 50 characters.
35 </small>
36 </div>
37 </div>
38
39 <div class="form-group">
40 <label class="form-control-label" for="lastName" jhiTranslate="settings.form.lastname">Last Name</label>
41 <input type="text" class="form-control" id="lastName" name="lastName" placeholder="{{ 'settings.form.lastname.placeholder' | translate }}"
42 formControlName="lastName">
43
44 <div *ngIf="settingsForm.get('lastName')!.invalid && (settingsForm.get('lastName')!.dirty || settingsForm.get('lastName')!.touched)">
45 <small class="form-text text-danger"
46 *ngIf="settingsForm.get('lastName')?.errors?.required"
47 jhiTranslate="settings.messages.validate.lastname.required">
48 Your last name is required.
49 </small>
50
51 <small class="form-text text-danger"
52 *ngIf="settingsForm.get('lastName')?.errors?.minlength"
53 jhiTranslate="settings.messages.validate.lastname.minlength">
54 Your last name is required to be at least 1 character.
55 </small>
56
57 <small class="form-text text-danger"
58 *ngIf="settingsForm.get('lastName')?.errors?.maxlength"
59 jhiTranslate="settings.messages.validate.lastname.maxlength">
60 Your last name cannot be longer than 50 characters.
61 </small>
62 </div>
63 </div>
64
65 <div class="form-group">
66 <label class="form-control-label" for="email" jhiTranslate="global.form.email.label">Email</label>
67 <input type="email" class="form-control" id="email" name="email" placeholder="{{ 'global.form.email.placeholder' | translate }}"
68 formControlName="email">
69
70 <div *ngIf="settingsForm.get('email')!.invalid && (settingsForm.get('email')!.dirty || settingsForm.get('email')!.touched)">
71 <small class="form-text text-danger"
72 *ngIf="settingsForm.get('email')?.errors?.required"
73 jhiTranslate="global.messages.validate.email.required">
74 Your email is required.
75 </small>
76
77 <small class="form-text text-danger"
78 *ngIf="settingsForm.get('email')?.errors?.email"
79 jhiTranslate="global.messages.validate.email.invalid">
80 Your email is invalid.
81 </small>
82
83 <small class="form-text text-danger"
84 *ngIf="settingsForm.get('email')?.errors?.minlength"
85 jhiTranslate="global.messages.validate.email.minlength">
86 Your email is required to be at least 5 characters.
87 </small>
88
89 <small class="form-text text-danger"
90 *ngIf="settingsForm.get('email')?.errors?.maxlength"
91 jhiTranslate="global.messages.validate.email.maxlength">
92 Your email cannot be longer than 100 characters.
93 </small>
94 </div>
95 </div>
96
97 <div class="form-group" *ngIf="languages && languages.length > 0">
98 <label for="langKey" jhiTranslate="settings.form.language">Language</label>
99 <select class="form-control" id="langKey" name="langKey" formControlName="langKey">
100 <option *ngFor="let language of languages" [value]="language">{{ language | findLanguageFromKey }}</option>
101 </select>
102 </div>
103
104 <button type="submit" [disabled]="settingsForm.invalid" class="btn btn-primary" jhiTranslate="settings.form.button">Save</button>
105 </form>
106 </div>
107 </div>
108 </div>
File src/main/webapp/app/account/settings/settings.component.ts added (mode: 100644) (index 0000000..fdec0c9)
1 import { Component, OnInit } from '@angular/core';
2 import { FormBuilder, Validators } from '@angular/forms';
3 import { JhiLanguageService } from 'ng-jhipster';
4
5 import { AccountService } from 'app/core/auth/account.service';
6 import { Account } from 'app/core/user/account.model';
7 import { LANGUAGES } from 'app/core/language/language.constants';
8
9 @Component({
10 selector: 'auth-settings',
11 templateUrl: './settings.component.html'
12 })
13 export class SettingsComponent implements OnInit {
14 account!: Account;
15 success = false;
16 languages = LANGUAGES;
17 settingsForm = this.fb.group({
18 firstName: [undefined, [Validators.required, Validators.minLength(1), Validators.maxLength(50)]],
19 lastName: [undefined, [Validators.required, Validators.minLength(1), Validators.maxLength(50)]],
20 email: [undefined, [Validators.required, Validators.minLength(5), Validators.maxLength(254), Validators.email]],
21 langKey: [undefined]
22 });
23
24 constructor(private accountService: AccountService, private fb: FormBuilder, private languageService: JhiLanguageService) {}
25
26 ngOnInit(): void {
27 this.accountService.identity().subscribe(account => {
28 if (account) {
29 this.settingsForm.patchValue({
30 firstName: account.firstName,
31 lastName: account.lastName,
32 email: account.email,
33 langKey: account.langKey
34 });
35
36 this.account = account;
37 }
38 });
39 }
40
41 save(): void {
42 this.success = false;
43
44 this.account.firstName = this.settingsForm.get('firstName')!.value;
45 this.account.lastName = this.settingsForm.get('lastName')!.value;
46 this.account.email = this.settingsForm.get('email')!.value;
47 this.account.langKey = this.settingsForm.get('langKey')!.value;
48
49 this.accountService.save(this.account).subscribe(() => {
50 this.success = true;
51
52 this.accountService.authenticate(this.account);
53
54 if (this.account.langKey !== this.languageService.getCurrentLanguage()) {
55 this.languageService.changeLanguage(this.account.langKey);
56 }
57 });
58 }
59 }
File src/main/webapp/app/account/settings/settings.route.ts added (mode: 100644) (index 0000000..2deeda9)
1 import { Route } from '@angular/router';
2
3 import { UserRouteAccessService } from 'app/core/auth/user-route-access-service';
4 import { SettingsComponent } from './settings.component';
5 import { Authority } from 'app/shared/constants/authority.constants';
6
7 export const settingsRoute: Route = {
8 path: 'settings',
9 component: SettingsComponent,
10 data: {
11 authorities: [Authority.USER],
12 pageTitle: 'global.menu.account.settings'
13 },
14 canActivate: [UserRouteAccessService]
15 };
File src/main/webapp/app/admin/admin-routing.module.ts added (mode: 100644) (index 0000000..f10ae68)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 /* jhipster-needle-add-admin-module-import - JHipster will add admin modules imports here */
4
5 @NgModule({
6 imports: [
7 /* jhipster-needle-add-admin-module - JHipster will add admin modules here */
8 RouterModule.forChild([
9 {
10 path: 'user-management',
11 loadChildren: () => import('./user-management/user-management.module').then(m => m.UserManagementModule),
12 data: {
13 pageTitle: 'userManagement.home.title'
14 }
15 },
16 {
17 path: 'audits',
18 loadChildren: () => import('./audits/audits.module').then(m => m.AuditsModule)
19 },
20 {
21 path: 'configuration',
22 loadChildren: () => import('./configuration/configuration.module').then(m => m.ConfigurationModule)
23 },
24 {
25 path: 'docs',
26 loadChildren: () => import('./docs/docs.module').then(m => m.DocsModule)
27 },
28 {
29 path: 'health',
30 loadChildren: () => import('./health/health.module').then(m => m.HealthModule)
31 },
32 {
33 path: 'logs',
34 loadChildren: () => import('./logs/logs.module').then(m => m.LogsModule)
35 },
36 {
37 path: 'metrics',
38 loadChildren: () => import('./metrics/metrics.module').then(m => m.MetricsModule)
39 }
40 /* jhipster-needle-add-admin-route - JHipster will add admin routes here */
41 ])
42 ]
43 })
44 export class AdminRoutingModule {}
File src/main/webapp/app/admin/audits/audit-data.model.ts added (mode: 100644) (index 0000000..904d33d)
1 export class AuditData {
2 constructor(public remoteAddress: string, public sessionId: string) {}
3 }
File src/main/webapp/app/admin/audits/audit.model.ts added (mode: 100644) (index 0000000..5c64107)
1 import { AuditData } from './audit-data.model';
2
3 export class Audit {
4 constructor(public data: AuditData, public principal: string, public timestamp: string, public type: string) {}
5 }
File src/main/webapp/app/admin/audits/audits.component.html added (mode: 100644) (index 0000000..3a15dae)
1 <div>
2 <h2 id="audits-page-heading" jhiTranslate="audits.title">Audits</h2>
3
4 <auth-alert-error></auth-alert-error>
5
6 <div class="row">
7 <div class="col-md-5">
8 <h4 jhiTranslate="audits.filter.title">Filter by date</h4>
9
10 <div class="input-group mb-3">
11 <div class="input-group-prepend">
12 <span class="input-group-text" jhiTranslate="audits.filter.from">from</span>
13 </div>
14 <input type="date" class="form-control" name="start" [(ngModel)]="fromDate" (ngModelChange)="transition()" required/>
15
16 <div class="input-group-append">
17 <span class="input-group-text" jhiTranslate="audits.filter.to">To</span>
18 </div>
19 <input type="date" class="form-control" name="end" [(ngModel)]="toDate" (ngModelChange)="transition()" required/>
20 </div>
21 </div>
22 </div>
23
24 <div class="alert alert-warning" *ngIf="audits?.length === 0">
25 <span jhiTranslate="audits.notFound">No audit found</span>
26 </div>
27
28 <div class="table-responsive" *ngIf="audits?.length > 0">
29 <table class="table table-sm table-striped" aria-describedby="audits-page-heading">
30 <thead [ngSwitch]="canLoad()">
31 <tr jhiSort [(predicate)]="predicate" [(ascending)]="ascending" [callback]="transition.bind(this)" *ngSwitchCase="true">
32 <th scope="col" jhiSortBy="auditEventDate"><span jhiTranslate="audits.table.header.date">Date</span> <fa-icon icon="sort"></fa-icon></th>
33 <th scope="col" jhiSortBy="principal"><span jhiTranslate="audits.table.header.principal">User</span> <fa-icon icon="sort"></fa-icon></th>
34 <th scope="col" jhiSortBy="auditEventType"><span jhiTranslate="audits.table.header.status">State</span> <fa-icon icon="sort"></fa-icon></th>
35 <th scope="col"><span jhiTranslate="audits.table.header.data">Extra data</span></th>
36 </tr>
37 <tr *ngSwitchCase="false">
38 <th scope="col"><span jhiTranslate="audits.table.header.date">Date</span></th>
39 <th scope="col"><span jhiTranslate="audits.table.header.principal">User</span></th>
40 <th scope="col"><span jhiTranslate="audits.table.header.status">State</span></th>
41 <th scope="col"><span jhiTranslate="audits.table.header.data">Extra data</span></th>
42 </tr>
43 </thead>
44 <tbody>
45 <tr *ngFor="let audit of audits">
46 <td><span>{{ audit.timestamp | date:'medium' }}</span></td>
47 <td><small>{{ audit.principal }}</small></td>
48 <td>{{ audit.type }}</td>
49 <td>
50 <span *ngIf="audit.data" ng-show="audit.data.message">{{ audit.data.message }}</span>
51 <span *ngIf="audit.data" ng-show="audit.data.remoteAddress"><span jhiTranslate="audits.table.data.remoteAddress">Remote Address</span> {{ audit.data.remoteAddress }}</span>
52 </td>
53 </tr>
54 </tbody>
55 </table>
56 </div>
57
58 <div *ngIf="audits?.length > 0">
59 <div class="row justify-content-center">
60 <jhi-item-count [page]="page" [total]="totalItems" [itemsPerPage]="itemsPerPage"></jhi-item-count>
61 </div>
62
63 <div class="row justify-content-center">
64 <ngb-pagination [collectionSize]="totalItems" [(page)]="page" [pageSize]="itemsPerPage" [maxSize]="5" [rotate]="true" [boundaryLinks]="true" (pageChange)="loadPage(page)" [disabled]="!canLoad()"></ngb-pagination>
65 </div>
66 </div>
67 </div>
File src/main/webapp/app/admin/audits/audits.component.ts added (mode: 100644) (index 0000000..3591209)
1 import { Component, OnInit } from '@angular/core';
2 import { HttpResponse, HttpHeaders } from '@angular/common/http';
3 import { DatePipe } from '@angular/common';
4 import { ActivatedRoute, Router } from '@angular/router';
5
6 import { ITEMS_PER_PAGE } from 'app/shared/constants/pagination.constants';
7 import { Audit } from './audit.model';
8 import { AuditsService } from './audits.service';
9
10 @Component({
11 selector: 'auth-audit',
12 templateUrl: './audits.component.html'
13 })
14 export class AuditsComponent implements OnInit {
15 audits?: Audit[];
16 fromDate = '';
17 itemsPerPage = ITEMS_PER_PAGE;
18 page!: number;
19 predicate!: string;
20 previousPage!: number;
21 ascending!: boolean;
22 toDate = '';
23 totalItems = 0;
24
25 private dateFormat = 'yyyy-MM-dd';
26
27 constructor(
28 private auditsService: AuditsService,
29 private activatedRoute: ActivatedRoute,
30 private datePipe: DatePipe,
31 private router: Router
32 ) {}
33
34 ngOnInit(): void {
35 this.toDate = this.today();
36 this.fromDate = this.previousMonth();
37 this.activatedRoute.data.subscribe(data => {
38 this.page = data['pagingParams'].page;
39 this.previousPage = data['pagingParams'].page;
40 this.ascending = data['pagingParams'].ascending;
41 this.predicate = data['pagingParams'].predicate;
42 this.loadData();
43 });
44 }
45
46 loadPage(page: number): void {
47 if (page !== this.previousPage) {
48 this.previousPage = page;
49 this.transition();
50 }
51 }
52
53 canLoad(): boolean {
54 return this.fromDate !== '' && this.toDate !== '';
55 }
56
57 transition(): void {
58 if (this.canLoad()) {
59 this.router.navigate(['/admin/audits'], {
60 queryParams: {
61 page: this.page,
62 sort: this.predicate + ',' + (this.ascending ? 'asc' : 'desc')
63 }
64 });
65 this.loadData();
66 }
67 }
68
69 private previousMonth(): string {
70 let date = new Date();
71 if (date.getMonth() === 0) {
72 date = new Date(date.getFullYear() - 1, 11, date.getDate());
73 } else {
74 date = new Date(date.getFullYear(), date.getMonth() - 1, date.getDate());
75 }
76 return this.datePipe.transform(date, this.dateFormat)!;
77 }
78
79 private today(): string {
80 // Today + 1 day - needed if the current day must be included
81 const date = new Date();
82 date.setDate(date.getDate() + 1);
83 return this.datePipe.transform(date, this.dateFormat)!;
84 }
85
86 private loadData(): void {
87 this.auditsService
88 .query({
89 page: this.page - 1,
90 size: this.itemsPerPage,
91 sort: this.sort(),
92 fromDate: this.fromDate,
93 toDate: this.toDate
94 })
95 .subscribe((res: HttpResponse<Audit[]>) => this.onSuccess(res.body, res.headers));
96 }
97
98 private sort(): string[] {
99 const result = [this.predicate + ',' + (this.ascending ? 'asc' : 'desc')];
100 if (this.predicate !== 'id') {
101 result.push('id');
102 }
103 return result;
104 }
105
106 private onSuccess(audits: Audit[] | null, headers: HttpHeaders): void {
107 this.totalItems = Number(headers.get('X-Total-Count'));
108 this.audits = audits || [];
109 }
110 }
File src/main/webapp/app/admin/audits/audits.module.ts added (mode: 100644) (index 0000000..82fd28b)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 import { HonlapSharedModule } from 'app/shared/shared.module';
4
5 import { AuditsComponent } from './audits.component';
6
7 import { auditsRoute } from './audits.route';
8
9 @NgModule({
10 imports: [HonlapSharedModule, RouterModule.forChild([auditsRoute])],
11 declarations: [AuditsComponent]
12 })
13 export class AuditsModule {}
File src/main/webapp/app/admin/audits/audits.route.ts added (mode: 100644) (index 0000000..50576f5)
1 import { Route } from '@angular/router';
2 import { JhiResolvePagingParams } from 'ng-jhipster';
3
4 import { AuditsComponent } from './audits.component';
5
6 export const auditsRoute: Route = {
7 path: '',
8 component: AuditsComponent,
9 resolve: {
10 pagingParams: JhiResolvePagingParams
11 },
12 data: {
13 pageTitle: 'audits.title',
14 defaultSort: 'auditEventDate,desc'
15 }
16 };
File src/main/webapp/app/admin/audits/audits.service.ts added (mode: 100644) (index 0000000..d86bf47)
1 import { Injectable } from '@angular/core';
2 import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { createRequestOption, Pagination } from 'app/shared/util/request-util';
6 import { SERVER_API_URL } from 'app/app.constants';
7 import { Audit } from './audit.model';
8
9 export interface AuditsQuery extends Pagination {
10 fromDate: string;
11 toDate: string;
12 }
13
14 @Injectable({ providedIn: 'root' })
15 export class AuditsService {
16 constructor(private http: HttpClient) {}
17
18 query(req: AuditsQuery): Observable<HttpResponse<Audit[]>> {
19 const params: HttpParams = createRequestOption(req);
20
21 const requestURL = SERVER_API_URL + 'management/audits';
22
23 return this.http.get<Audit[]>(requestURL, {
24 params,
25 observe: 'response'
26 });
27 }
28 }
File src/main/webapp/app/admin/configuration/configuration.component.html added (mode: 100644) (index 0000000..1002f7a)
1 <div *ngIf="allBeans">
2 <h2 id="configuration-page-heading" jhiTranslate="configuration.title">Configuration</h2>
3
4 <span jhiTranslate="configuration.filter">Filter (by prefix)</span> <input type="text" [(ngModel)]="beansFilter" (ngModelChange)="filterAndSortBeans()" class="form-control">
5
6 <h3 id="spring-configuration">Spring configuration</h3>
7
8 <table class="table table-striped table-bordered table-responsive d-table" aria-describedby="spring-configuration">
9 <thead>
10 <tr jhiSort predicate="prefix" [(ascending)]="beansAscending" [callback]="filterAndSortBeans.bind(this)">
11 <th jhiSortBy="prefix" scope="col" class="w-40"><span jhiTranslate="configuration.table.prefix">Prefix</span> <fa-icon icon="sort"></fa-icon></th>
12 <th scope="col" class="w-60"><span jhiTranslate="configuration.table.properties">Properties</span></th>
13 </tr>
14 </thead>
15 <tbody>
16 <tr *ngFor="let bean of beans">
17 <td><span>{{ bean.prefix }}</span></td>
18 <td>
19 <div class="row" *ngFor="let property of bean.properties | keys">
20 <div class="col-md-4">{{ property.key }}</div>
21 <div class="col-md-8">
22 <span class="float-right badge-secondary break">{{ property.value | json }}</span>
23 </div>
24 </div>
25 </td>
26 </tr>
27 </tbody>
28 </table>
29
30 <div *ngFor="let propertySource of propertySources; let i = index">
31 <h4 [id]="'property-source-' + i"><span>{{ propertySource.name }}</span></h4>
32
33 <table class="table table-sm table-striped table-bordered table-responsive d-table" [attr.aria-describedby]="'property-source-' + i"><!-- //NOSONAR -->
34 <thead>
35 <tr>
36 <th scope="col" class="w-40">Property</th>
37 <th scope="col" class="w-60">Value</th>
38 </tr>
39 </thead>
40 <tbody>
41 <tr *ngFor="let property of propertySource.properties | keys">
42 <td class="break">{{ property.key }}</td>
43 <td class="break">
44 <span class="float-right badge-secondary break">{{ property.value.value }}</span>
45 </td>
46 </tr>
47 </tbody>
48 </table>
49 </div>
50 </div>
File src/main/webapp/app/admin/configuration/configuration.component.ts added (mode: 100644) (index 0000000..0b07b39)
1 import { Component, OnInit } from '@angular/core';
2
3 import { ConfigurationService, Bean, PropertySource } from './configuration.service';
4
5 @Component({
6 selector: 'auth-configuration',
7 templateUrl: './configuration.component.html'
8 })
9 export class ConfigurationComponent implements OnInit {
10 allBeans!: Bean[];
11 beans: Bean[] = [];
12 beansFilter = '';
13 beansAscending = true;
14 propertySources: PropertySource[] = [];
15
16 constructor(private configurationService: ConfigurationService) {}
17
18 ngOnInit(): void {
19 this.configurationService.getBeans().subscribe(beans => {
20 this.allBeans = beans;
21 this.filterAndSortBeans();
22 });
23
24 this.configurationService.getPropertySources().subscribe(propertySources => (this.propertySources = propertySources));
25 }
26
27 filterAndSortBeans(): void {
28 this.beans = this.allBeans
29 .filter(bean => !this.beansFilter || bean.prefix.toLowerCase().includes(this.beansFilter.toLowerCase()))
30 .sort((a, b) => (a.prefix < b.prefix ? (this.beansAscending ? -1 : 1) : this.beansAscending ? 1 : -1));
31 }
32 }
File src/main/webapp/app/admin/configuration/configuration.module.ts added (mode: 100644) (index 0000000..2a02331)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 import { HonlapSharedModule } from 'app/shared/shared.module';
4
5 import { ConfigurationComponent } from './configuration.component';
6
7 import { configurationRoute } from './configuration.route';
8
9 @NgModule({
10 imports: [HonlapSharedModule, RouterModule.forChild([configurationRoute])],
11 declarations: [ConfigurationComponent]
12 })
13 export class ConfigurationModule {}
File src/main/webapp/app/admin/configuration/configuration.route.ts added (mode: 100644) (index 0000000..17238c9)
1 import { Route } from '@angular/router';
2
3 import { ConfigurationComponent } from './configuration.component';
4
5 export const configurationRoute: Route = {
6 path: '',
7 component: ConfigurationComponent,
8 data: {
9 pageTitle: 'configuration.title'
10 }
11 };
File src/main/webapp/app/admin/configuration/configuration.service.ts added (mode: 100644) (index 0000000..69ea43a)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4 import { map } from 'rxjs/operators';
5
6 import { SERVER_API_URL } from 'app/app.constants';
7
8 export interface ConfigProps {
9 contexts: Contexts;
10 }
11
12 export interface Contexts {
13 [key: string]: Context;
14 }
15
16 export interface Context {
17 beans: Beans;
18 parentId?: any;
19 }
20
21 export interface Beans {
22 [key: string]: Bean;
23 }
24
25 export interface Bean {
26 prefix: string;
27 properties: any;
28 }
29
30 export interface Env {
31 activeProfiles?: string[];
32 propertySources: PropertySource[];
33 }
34
35 export interface PropertySource {
36 name: string;
37 properties: Properties;
38 }
39
40 export interface Properties {
41 [key: string]: Property;
42 }
43
44 export interface Property {
45 value: string;
46 origin?: string;
47 }
48
49 @Injectable({ providedIn: 'root' })
50 export class ConfigurationService {
51 constructor(private http: HttpClient) {}
52
53 getBeans(): Observable<Bean[]> {
54 return this.http.get<ConfigProps>(SERVER_API_URL + 'management/configprops').pipe(
55 map(configProps =>
56 Object.values(
57 Object.values(configProps.contexts)
58 .map(context => context.beans)
59 .reduce((allBeans: Beans, contextBeans: Beans) => ({ ...allBeans, ...contextBeans }))
60 )
61 )
62 );
63 }
64
65 getPropertySources(): Observable<PropertySource[]> {
66 return this.http.get<Env>(SERVER_API_URL + 'management/env').pipe(map(env => env.propertySources));
67 }
68 }
File src/main/webapp/app/admin/docs/docs.component.html added (mode: 100644) (index 0000000..9d1600b)
1 <iframe src="swagger-ui/index.html" width="100%" height="900" seamless
2 target="_top" title="Swagger UI" class="border-0"></iframe>
File src/main/webapp/app/admin/docs/docs.component.ts added (mode: 100644) (index 0000000..4b6d528)
1 import { Component } from '@angular/core';
2
3 @Component({
4 selector: 'auth-docs',
5 templateUrl: './docs.component.html',
6 styleUrls: ['docs.scss']
7 })
8 export class DocsComponent {}
File src/main/webapp/app/admin/docs/docs.module.ts added (mode: 100644) (index 0000000..dfb0bbc)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 import { HonlapSharedModule } from 'app/shared/shared.module';
4
5 import { DocsComponent } from './docs.component';
6
7 import { docsRoute } from './docs.route';
8
9 @NgModule({
10 imports: [HonlapSharedModule, RouterModule.forChild([docsRoute])],
11 declarations: [DocsComponent]
12 })
13 export class DocsModule {}
File src/main/webapp/app/admin/docs/docs.route.ts added (mode: 100644) (index 0000000..b2aead9)
1 import { Route } from '@angular/router';
2
3 import { DocsComponent } from './docs.component';
4
5 export const docsRoute: Route = {
6 path: '',
7 component: DocsComponent,
8 data: {
9 pageTitle: 'global.menu.admin.apidocs'
10 }
11 };
File src/main/webapp/app/admin/docs/docs.scss added (mode: 100644) (index 0000000..541c3d7)
1 @import '~bootstrap/scss/functions';
2 @import '~bootstrap/scss/variables';
3
4 iframe {
5 background: white;
6 }
File src/main/webapp/app/admin/health/health-modal.component.html added (mode: 100644) (index 0000000..5556f47)
1 <div class="modal-header">
2 <h4 class="modal-title" id="showHealthLabel" *ngIf="health">
3 {{ 'health.indicator.' + health.key | translate }}
4 </h4>
5
6 <button aria-label="Close" data-dismiss="modal" class="close" type="button" (click)="dismiss()">
7 <span aria-hidden="true">&times;</span>
8 </button>
9 </div>
10
11 <div class="modal-body pad">
12 <div *ngIf="health">
13 <h5 jhiTranslate="health.details.properties">Properties</h5>
14
15 <div class="table-responsive">
16 <table class="table table-striped" aria-describedby="showHealthLabel">
17 <thead>
18 <tr>
19 <th scope="col" class="text-left" jhiTranslate="health.details.name">Name</th>
20 <th scope="col" class="text-left" jhiTranslate="health.details.value">Value</th>
21 </tr>
22 </thead>
23 <tbody>
24 <tr *ngFor="let healthDetail of health.value.details | keys">
25 <td class="text-left">{{ healthDetail.key }}</td>
26 <td class="text-left">{{ readableValue(healthDetail.value) }}</td>
27 </tr>
28 </tbody>
29 </table>
30 </div>
31 </div>
32 </div>
33
34 <div class="modal-footer">
35 <button data-dismiss="modal" class="btn btn-secondary float-left" type="button" (click)="dismiss()">Done</button>
36 </div>
File src/main/webapp/app/admin/health/health-modal.component.ts added (mode: 100644) (index 0000000..7655094)
1 import { Component } from '@angular/core';
2 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3
4 import { HealthKey, HealthDetails } from './health.service';
5
6 @Component({
7 selector: 'auth-health-modal',
8 templateUrl: './health-modal.component.html'
9 })
10 export class HealthModalComponent {
11 health?: { key: HealthKey; value: HealthDetails };
12
13 constructor(public activeModal: NgbActiveModal) {}
14
15 readableValue(value: any): string {
16 if (this.health && this.health.key === 'diskSpace') {
17 // Should display storage space in an human readable unit
18 const val = value / 1073741824;
19 if (val > 1) {
20 // Value
21 return val.toFixed(2) + ' GB';
22 } else {
23 return (value / 1048576).toFixed(2) + ' MB';
24 }
25 }
26
27 if (typeof value === 'object') {
28 return JSON.stringify(value);
29 } else {
30 return value.toString();
31 }
32 }
33
34 dismiss(): void {
35 this.activeModal.dismiss();
36 }
37 }
File src/main/webapp/app/admin/health/health.component.html added (mode: 100644) (index 0000000..b686fcb)
1 <div>
2 <h2>
3 <span id="health-page-heading" jhiTranslate="health.title">Health Checks</span>
4
5 <button class="btn btn-primary float-right" (click)="refresh()">
6 <fa-icon icon="sync"></fa-icon> <span jhiTranslate="health.refresh.button">Refresh</span>
7 </button>
8 </h2>
9
10 <div class="table-responsive">
11 <table id="healthCheck" class="table table-striped" aria-describedby="health-page-heading">
12 <thead>
13 <tr>
14 <th scope="col" jhiTranslate="health.table.service">Service Name</th>
15 <th scope="col" class="text-center" jhiTranslate="health.table.status">Status</th>
16 <th scope="col" class="text-center" jhiTranslate="health.details.details">Details</th>
17 </tr>
18 </thead>
19 <tbody *ngIf="health">
20 <tr *ngFor="let componentHealth of health.components | keys">
21 <td>
22 {{ 'health.indicator.' + componentHealth.key | translate }}
23 </td>
24 <td class="text-center">
25 <span class="badge" [ngClass]="getBadgeClass(componentHealth.value.status)" jhiTranslate="{{ 'health.status.' + componentHealth.value.status }}">
26 {{ componentHealth.value.status }}
27 </span>
28 </td>
29 <td class="text-center">
30 <a class="hand" (click)="showHealth(componentHealth)" *ngIf="componentHealth.value.details">
31 <fa-icon icon="eye"></fa-icon>
32 </a>
33 </td>
34 </tr>
35 </tbody>
36 </table>
37 </div>
38 </div>
File src/main/webapp/app/admin/health/health.component.ts added (mode: 100644) (index 0000000..9c07604)
1 import { Component, OnInit } from '@angular/core';
2 import { HttpErrorResponse } from '@angular/common/http';
3 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
4
5 import { HealthService, HealthStatus, Health, HealthKey, HealthDetails } from './health.service';
6 import { HealthModalComponent } from './health-modal.component';
7
8 @Component({
9 selector: 'auth-health',
10 templateUrl: './health.component.html'
11 })
12 export class HealthComponent implements OnInit {
13 health?: Health;
14
15 constructor(private modalService: NgbModal, private healthService: HealthService) {}
16
17 ngOnInit(): void {
18 this.refresh();
19 }
20
21 getBadgeClass(statusState: HealthStatus): string {
22 if (statusState === 'UP') {
23 return 'badge-success';
24 } else {
25 return 'badge-danger';
26 }
27 }
28
29 refresh(): void {
30 this.healthService.checkHealth().subscribe(
31 health => (this.health = health),
32 (error: HttpErrorResponse) => {
33 if (error.status === 503) {
34 this.health = error.error;
35 }
36 }
37 );
38 }
39
40 showHealth(health: { key: HealthKey; value: HealthDetails }): void {
41 const modalRef = this.modalService.open(HealthModalComponent);
42 modalRef.componentInstance.health = health;
43 }
44 }
File src/main/webapp/app/admin/health/health.module.ts added (mode: 100644) (index 0000000..ab9a921)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 import { HonlapSharedModule } from 'app/shared/shared.module';
4
5 import { HealthComponent } from './health.component';
6 import { HealthModalComponent } from './health-modal.component';
7
8 import { healthRoute } from './health.route';
9
10 @NgModule({
11 imports: [HonlapSharedModule, RouterModule.forChild([healthRoute])],
12 declarations: [HealthComponent, HealthModalComponent],
13 entryComponents: [HealthModalComponent]
14 })
15 export class HealthModule {}
File src/main/webapp/app/admin/health/health.route.ts added (mode: 100644) (index 0000000..1055dcc)
1 import { Route } from '@angular/router';
2
3 import { HealthComponent } from './health.component';
4
5 export const healthRoute: Route = {
6 path: '',
7 component: HealthComponent,
8 data: {
9 pageTitle: 'health.title'
10 }
11 };
File src/main/webapp/app/admin/health/health.service.ts added (mode: 100644) (index 0000000..25005f6)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 export type HealthStatus = 'UP' | 'DOWN' | 'UNKNOWN' | 'OUT_OF_SERVICE';
8
9 export type HealthKey = 'diskSpace' | 'mail' | 'ping' | 'db';
10
11 export interface Health {
12 status: HealthStatus;
13 components: {
14 [key in HealthKey]?: HealthDetails;
15 };
16 }
17
18 export interface HealthDetails {
19 status: HealthStatus;
20 details: any;
21 }
22
23 @Injectable({ providedIn: 'root' })
24 export class HealthService {
25 constructor(private http: HttpClient) {}
26
27 checkHealth(): Observable<Health> {
28 return this.http.get<Health>(SERVER_API_URL + 'management/health');
29 }
30 }
File src/main/webapp/app/admin/logs/log.model.ts added (mode: 100644) (index 0000000..83f2e15)
1 export type Level = 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'OFF';
2
3 export interface Logger {
4 configuredLevel: Level | null;
5 effectiveLevel: Level;
6 }
7
8 export interface LoggersResponse {
9 levels: Level[];
10 loggers: { [key: string]: Logger };
11 }
12
13 export class Log {
14 constructor(public name: string, public level: Level) {}
15 }
File src/main/webapp/app/admin/logs/logs.component.html added (mode: 100644) (index 0000000..b0473e3)
1 <div class="table-responsive" *ngIf="loggers">
2 <h2 id="logs-page-heading" jhiTranslate="logs.title">Logs</h2>
3
4 <p jhiTranslate="logs.nbloggers" [translateValues]="{ total: loggers.length }">There are {{ loggers.length }} loggers.</p>
5
6 <span jhiTranslate="logs.filter">Filter</span> <input type="text" [(ngModel)]="filter" class="form-control">
7
8 <table class="table table-sm table-striped table-bordered" aria-describedby="logs-page-heading">
9 <thead>
10 <tr title="click to order">
11 <th scope="col" (click)="orderProp = 'name'; reverse=!reverse"><span jhiTranslate="logs.table.name">Name</span></th>
12 <th scope="col" (click)="orderProp = 'level'; reverse=!reverse"><span jhiTranslate="logs.table.level">Level</span></th>
13 </tr>
14 </thead>
15
16 <tr *ngFor="let logger of (loggers | pureFilter:filter:'name' | orderBy:orderProp:reverse)">
17 <td><small>{{ logger.name | slice:0:140 }}</small></td>
18 <td>
19 <button (click)="changeLevel(logger.name, 'TRACE')" [ngClass]="(logger.level=='TRACE') ? 'btn-primary' : 'btn-light'" class="btn btn-sm">TRACE</button>
20 <button (click)="changeLevel(logger.name, 'DEBUG')" [ngClass]="(logger.level=='DEBUG') ? 'btn-success' : 'btn-light'" class="btn btn-sm">DEBUG</button>
21 <button (click)="changeLevel(logger.name, 'INFO')" [ngClass]="(logger.level=='INFO') ? 'btn-info' : 'btn-light'" class="btn btn-sm">INFO</button>
22 <button (click)="changeLevel(logger.name, 'WARN')" [ngClass]="(logger.level=='WARN') ? 'btn-warning' : 'btn-light'" class="btn btn-sm">WARN</button>
23 <button (click)="changeLevel(logger.name, 'ERROR')" [ngClass]="(logger.level=='ERROR') ? 'btn-danger' : 'btn-light'" class="btn btn-sm">ERROR</button>
24 <button (click)="changeLevel(logger.name, 'OFF')" [ngClass]="(logger.level=='OFF') ? 'btn-secondary' : 'btn-light'" class="btn btn-sm">OFF</button>
25 </td>
26 </tr>
27 </table>
28 </div>
File src/main/webapp/app/admin/logs/logs.component.ts added (mode: 100644) (index 0000000..c41dc22)
1 import { Component, OnInit } from '@angular/core';
2
3 import { Log, LoggersResponse, Logger, Level } from './log.model';
4 import { LogsService } from './logs.service';
5
6 @Component({
7 selector: 'auth-logs',
8 templateUrl: './logs.component.html'
9 })
10 export class LogsComponent implements OnInit {
11 loggers?: Log[];
12 filter = '';
13 orderProp = 'name';
14 reverse = false;
15
16 constructor(private logsService: LogsService) {}
17
18 ngOnInit(): void {
19 this.findAndExtractLoggers();
20 }
21
22 changeLevel(name: string, level: Level): void {
23 this.logsService.changeLevel(name, level).subscribe(() => this.findAndExtractLoggers());
24 }
25
26 private findAndExtractLoggers(): void {
27 this.logsService
28 .findAll()
29 .subscribe(
30 (response: LoggersResponse) =>
31 (this.loggers = Object.entries(response.loggers).map((logger: [string, Logger]) => new Log(logger[0], logger[1].effectiveLevel)))
32 );
33 }
34 }
File src/main/webapp/app/admin/logs/logs.module.ts added (mode: 100644) (index 0000000..6e519be)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 import { HonlapSharedModule } from 'app/shared/shared.module';
4
5 import { LogsComponent } from './logs.component';
6
7 import { logsRoute } from './logs.route';
8
9 @NgModule({
10 imports: [HonlapSharedModule, RouterModule.forChild([logsRoute])],
11 declarations: [LogsComponent]
12 })
13 export class LogsModule {}
File src/main/webapp/app/admin/logs/logs.route.ts added (mode: 100644) (index 0000000..d1cf024)
1 import { Route } from '@angular/router';
2
3 import { LogsComponent } from './logs.component';
4
5 export const logsRoute: Route = {
6 path: '',
7 component: LogsComponent,
8 data: {
9 pageTitle: 'logs.title'
10 }
11 };
File src/main/webapp/app/admin/logs/logs.service.ts added (mode: 100644) (index 0000000..dc9956d)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6 import { LoggersResponse, Level } from './log.model';
7
8 @Injectable({ providedIn: 'root' })
9 export class LogsService {
10 constructor(private http: HttpClient) {}
11
12 changeLevel(name: string, configuredLevel: Level): Observable<{}> {
13 return this.http.post(SERVER_API_URL + 'management/loggers/' + name, { configuredLevel });
14 }
15
16 findAll(): Observable<LoggersResponse> {
17 return this.http.get<LoggersResponse>(SERVER_API_URL + 'management/loggers');
18 }
19 }
File src/main/webapp/app/admin/metrics/metrics.component.html added (mode: 100644) (index 0000000..731a7a9)
1 <div>
2 <h2>
3 <span id="metrics-page-heading" jhiTranslate="metrics.title">Application Metrics</span>
4
5 <button class="btn btn-primary float-right" (click)="refresh()">
6 <fa-icon icon="sync"></fa-icon> <span jhiTranslate="metrics.refresh.button">Refresh</span>
7 </button>
8 </h2>
9
10 <h3 jhiTranslate="metrics.jvm.title">JVM Metrics</h3>
11
12 <div class="row" *ngIf="metrics && !updatingMetrics">
13 <jhi-jvm-memory
14 class="col-md-4"
15 [updating]="updatingMetrics"
16 [jvmMemoryMetrics]="metrics.jvm">
17 </jhi-jvm-memory>
18
19 <jhi-jvm-threads
20 class="col-md-4"
21 [threadData]="threads">
22 </jhi-jvm-threads>
23
24 <jhi-metrics-system
25 class="col-md-4"
26 [updating]="updatingMetrics"
27 [systemMetrics]="metrics.processMetrics">
28 </jhi-metrics-system>
29 </div>
30
31 <div *ngIf="metrics && metricsKeyExists('garbageCollector')">
32 <h3 jhiTranslate="metrics.jvm.gc.title">Garbage collector statistics</h3>
33
34 <jhi-metrics-garbagecollector
35 [updating]="updatingMetrics"
36 [garbageCollectorMetrics]="metrics.garbageCollector">
37 </jhi-metrics-garbagecollector>
38 </div>
39
40 <div class="well well-lg" *ngIf="updatingMetrics" jhiTranslate="metrics.updating">Updating...</div>
41
42 <jhi-metrics-request
43 *ngIf="metrics && metricsKeyExists('http.server.requests')"
44 [updating]="updatingMetrics"
45 [requestMetrics]="metrics['http.server.requests']">
46 </jhi-metrics-request>
47
48 <jhi-metrics-endpoints-requests
49 *ngIf="metrics && metricsKeyExists('services')"
50 [updating]="updatingMetrics"
51 [endpointsRequestsMetrics]="metrics.services">
52 </jhi-metrics-endpoints-requests>
53
54 <jhi-metrics-cache
55 *ngIf="metrics && metricsKeyExists('cache')"
56 [updating]="updatingMetrics"
57 [cacheMetrics]="metrics.cache">
58 </jhi-metrics-cache>
59
60 <jhi-metrics-datasource
61 *ngIf="metrics && metricsKeyExistsAndObjectNotEmpty('databases')"
62 [updating]="updatingMetrics"
63 [datasourceMetrics]="metrics.databases">
64 </jhi-metrics-datasource>
65 </div>
File src/main/webapp/app/admin/metrics/metrics.component.ts added (mode: 100644) (index 0000000..0c49b71)
1 import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
2 import { flatMap } from 'rxjs/operators';
3
4 import { MetricsService, Metrics, MetricsKey, ThreadDump, Thread } from './metrics.service';
5
6 @Component({
7 selector: 'auth-metrics',
8 templateUrl: './metrics.component.html',
9 changeDetection: ChangeDetectionStrategy.OnPush
10 })
11 export class MetricsComponent implements OnInit {
12 metrics?: Metrics;
13 threads?: Thread[];
14 updatingMetrics = true;
15
16 constructor(private metricsService: MetricsService, private changeDetector: ChangeDetectorRef) {}
17
18 ngOnInit(): void {
19 this.refresh();
20 }
21
22 refresh(): void {
23 this.updatingMetrics = true;
24 this.metricsService
25 .getMetrics()
26 .pipe(
27 flatMap(
28 () => this.metricsService.threadDump(),
29 (metrics: Metrics, threadDump: ThreadDump) => {
30 this.metrics = metrics;
31 this.threads = threadDump.threads;
32 this.updatingMetrics = false;
33 this.changeDetector.detectChanges();
34 }
35 )
36 )
37 .subscribe();
38 }
39
40 metricsKeyExists(key: MetricsKey): boolean {
41 return this.metrics && this.metrics[key];
42 }
43
44 metricsKeyExistsAndObjectNotEmpty(key: MetricsKey): boolean {
45 return this.metrics && this.metrics[key] && JSON.stringify(this.metrics[key]) !== '{}';
46 }
47 }
File src/main/webapp/app/admin/metrics/metrics.module.ts added (mode: 100644) (index 0000000..c64edda)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 import { HonlapSharedModule } from 'app/shared/shared.module';
4
5 import { MetricsComponent } from './metrics.component';
6
7 import { metricsRoute } from './metrics.route';
8
9 @NgModule({
10 imports: [HonlapSharedModule, RouterModule.forChild([metricsRoute])],
11 declarations: [MetricsComponent]
12 })
13 export class MetricsModule {}
File src/main/webapp/app/admin/metrics/metrics.route.ts added (mode: 100644) (index 0000000..f85fd61)
1 import { Route } from '@angular/router';
2
3 import { MetricsComponent } from './metrics.component';
4
5 export const metricsRoute: Route = {
6 path: '',
7 component: MetricsComponent,
8 data: {
9 pageTitle: 'metrics.title'
10 }
11 };
File src/main/webapp/app/admin/metrics/metrics.service.ts added (mode: 100644) (index 0000000..a8d0c99)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 export type MetricsKey = 'jvm' | 'http.server.requests' | 'cache' | 'services' | 'databases' | 'garbageCollector' | 'processMetrics';
8 export type Metrics = { [key in MetricsKey]: any };
9 export type Thread = any;
10 export type ThreadDump = { threads: Thread[] };
11
12 @Injectable({ providedIn: 'root' })
13 export class MetricsService {
14 constructor(private http: HttpClient) {}
15
16 getMetrics(): Observable<Metrics> {
17 return this.http.get<Metrics>(SERVER_API_URL + 'management/jhimetrics');
18 }
19
20 threadDump(): Observable<ThreadDump> {
21 return this.http.get<ThreadDump>(SERVER_API_URL + 'management/threaddump');
22 }
23 }
File src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.html added (mode: 100644) (index 0000000..778e450)
1 <form *ngIf="user" name="deleteForm" (ngSubmit)="confirmDelete(user?.login!)">
2 <div class="modal-header">
3 <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4>
4
5 <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">&times;</button>
6 </div>
7
8 <div class="modal-body">
9 <auth-alert-error></auth-alert-error>
10
11 <p jhiTranslate="userManagement.delete.question" [translateValues]="{ login: user.login }">Are you sure you want to delete this User?</p>
12 </div>
13
14 <div class="modal-footer">
15 <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()">
16 <fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
17 </button>
18
19 <button type="submit" class="btn btn-danger">
20 <fa-icon icon="times"></fa-icon>&nbsp;<span jhiTranslate="entity.action.delete">Delete</span>
21 </button>
22 </div>
23 </form>
File src/main/webapp/app/admin/user-management/user-management-delete-dialog.component.ts added (mode: 100644) (index 0000000..86674f4)
1 import { Component } from '@angular/core';
2 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3 import { JhiEventManager } from 'ng-jhipster';
4
5 import { User } from 'app/core/user/user.model';
6 import { UserService } from 'app/core/user/user.service';
7
8 @Component({
9 selector: 'auth-user-mgmt-delete-dialog',
10 templateUrl: './user-management-delete-dialog.component.html'
11 })
12 export class UserManagementDeleteDialogComponent {
13 user?: User;
14
15 constructor(private userService: UserService, public activeModal: NgbActiveModal, private eventManager: JhiEventManager) {}
16
17 cancel(): void {
18 this.activeModal.dismiss();
19 }
20
21 confirmDelete(login: string): void {
22 this.userService.delete(login).subscribe(() => {
23 this.eventManager.broadcast('userListModification');
24 this.activeModal.close();
25 });
26 }
27 }
File src/main/webapp/app/admin/user-management/user-management-detail.component.html added (mode: 100644) (index 0000000..10fb558)
1 <div class="row justify-content-center">
2 <div class="col-8">
3 <div *ngIf="user">
4 <h2>
5 <span jhiTranslate="userManagement.detail.title">User</span> [<b>{{ user.login }}</b>]
6 </h2>
7
8 <dl class="row-md jh-entity-details">
9 <dt><span jhiTranslate="userManagement.login">Login</span></dt>
10 <dd>
11 <span>{{ user.login }}</span>
12 <jhi-boolean
13 [value]="user.activated"
14 [textTrue]="'userManagement.activated' | translate"
15 [textFalse]="'userManagement.deactivated' | translate">
16 </jhi-boolean>
17 </dd>
18
19 <dt><span jhiTranslate="userManagement.firstName">First Name</span></dt>
20 <dd>{{ user.firstName }}</dd>
21
22 <dt><span jhiTranslate="userManagement.lastName">Last Name</span></dt>
23 <dd>{{ user.lastName }}</dd>
24
25 <dt><span jhiTranslate="userManagement.email">Email</span></dt>
26 <dd>{{ user.email }}</dd>
27
28 <dt><span jhiTranslate="userManagement.langKey">Lang Key</span></dt>
29 <dd>{{ user.langKey }}</dd>
30
31 <dt><span jhiTranslate="userManagement.createdBy">Created By</span></dt>
32 <dd>{{ user.createdBy }}</dd>
33
34 <dt><span jhiTranslate="userManagement.createdDate">Created Date</span></dt>
35 <dd>{{ user.createdDate | date:'dd/MM/yy HH:mm' }}</dd>
36
37 <dt><span jhiTranslate="userManagement.lastModifiedBy">Last Modified By</span></dt>
38 <dd>{{ user.lastModifiedBy }}</dd>
39
40 <dt><span jhiTranslate="userManagement.lastModifiedDate">Last Modified Date</span></dt>
41 <dd>{{ user.lastModifiedDate | date:'dd/MM/yy HH:mm' }}</dd>
42
43 <dt><span jhiTranslate="userManagement.profiles">Profiles</span></dt>
44 <dd>
45 <ul class="list-unstyled">
46 <li *ngFor="let authority of user.authorities">
47 <span class="badge badge-info">{{ authority }}</span>
48 </li>
49 </ul>
50 </dd>
51 </dl>
52
53 <button type="submit" routerLink="../../" class="btn btn-info">
54 <fa-icon icon="arrow-left"></fa-icon>&nbsp;<span jhiTranslate="entity.action.back">Back</span>
55 </button>
56 </div>
57 </div>
58 </div>
File src/main/webapp/app/admin/user-management/user-management-detail.component.ts added (mode: 100644) (index 0000000..22b4198)
1 import { Component, OnInit } from '@angular/core';
2 import { ActivatedRoute } from '@angular/router';
3
4 import { User } from 'app/core/user/user.model';
5
6 @Component({
7 selector: 'auth-user-mgmt-detail',
8 templateUrl: './user-management-detail.component.html'
9 })
10 export class UserManagementDetailComponent implements OnInit {
11 user: User | null = null;
12
13 constructor(private route: ActivatedRoute) {}
14
15 ngOnInit(): void {
16 this.route.data.subscribe(({ user }) => (this.user = user));
17 }
18 }
File src/main/webapp/app/admin/user-management/user-management-update.component.html added (mode: 100644) (index 0000000..16b6620)
1 <div class="row justify-content-center">
2 <div class="col-8">
3 <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm">
4 <h2 id="myUserLabel" jhiTranslate="userManagement.home.createOrEditLabel">
5 Create or edit a User
6 </h2>
7
8 <div *ngIf="user">
9 <auth-alert-error></auth-alert-error>
10
11 <div class="form-group" [hidden]="!user.id">
12 <label jhiTranslate="global.field.id">ID</label>
13 <input type="text" class="form-control" name="id" formControlName="id" readonly>
14 </div>
15
16 <div class="form-group">
17 <label class="form-control-label" jhiTranslate="userManagement.login">Login</label>
18 <input type="text" class="form-control" name="login"
19 formControlName="login">
20
21 <div *ngIf="editForm.get('login')!.invalid && (editForm.get('login')!.dirty || editForm.get('login')!.touched)">
22 <small class="form-text text-danger"
23 *ngIf="editForm.get('login')?.errors?.required"
24 jhiTranslate="entity.validation.required">
25 This field is required.
26 </small>
27
28 <small class="form-text text-danger"
29 *ngIf="editForm.get('login')?.errors?.maxlength"
30 jhiTranslate="entity.validation.maxlength"
31 [translateValues]="{ max: 50 }">
32 This field cannot be longer than 50 characters.
33 </small>
34
35 <small class="form-text text-danger"
36 *ngIf="editForm.get('login')?.errors?.pattern"
37 jhiTranslate="entity.validation.patternLogin">
38 This field can only contain letters, digits and e-mail addresses.
39 </small>
40 </div>
41 </div>
42
43 <div class="form-group">
44 <label class="form-control-label" jhiTranslate="userManagement.firstName">First Name</label>
45 <input type="text" class="form-control" name="firstName"
46 formControlName="firstName">
47
48 <div *ngIf="editForm.get('firstName')!.invalid && (editForm.get('firstName')!.dirty || editForm.get('firstName')!.touched)">
49 <small class="form-text text-danger"
50 *ngIf="editForm.get('firstName')?.errors?.maxlength"
51 jhiTranslate="entity.validation.maxlength"
52 [translateValues]="{ max: 50 }">
53 This field cannot be longer than 50 characters.
54 </small>
55 </div>
56 </div>
57
58 <div class="form-group">
59 <label jhiTranslate="userManagement.lastName">Last Name</label>
60 <input type="text" class="form-control" name="lastName"
61 formControlName="lastName">
62
63 <div *ngIf="editForm.get('lastName')!.invalid && (editForm.get('lastName')!.dirty || editForm.get('lastName')!.touched)">
64 <small class="form-text text-danger"
65 *ngIf="editForm.get('lastName')?.errors?.maxlength"
66 jhiTranslate="entity.validation.maxlength"
67 [translateValues]="{ max: 50 }">
68 This field cannot be longer than 50 characters.
69 </small>
70 </div>
71 </div>
72
73 <div class="form-group">
74 <label class="form-control-label" jhiTranslate="userManagement.email">Email</label>
75 <input type="email" class="form-control" name="email" formControlName="email">
76
77 <div *ngIf="editForm.get('email')!.invalid && (editForm.get('email')!.dirty || editForm.get('email')!.touched)">
78 <small class="form-text text-danger"
79 *ngIf="editForm.get('email')?.errors?.required"
80 jhiTranslate="entity.validation.required">
81 This field is required.
82 </small>
83
84 <small class="form-text text-danger"
85 *ngIf="editForm.get('email')?.errors?.maxlength"
86 jhiTranslate="entity.validation.maxlength"
87 [translateValues]="{ max: 100 }">
88 This field cannot be longer than 100 characters.
89 </small>
90
91 <small class="form-text text-danger"
92 *ngIf="editForm.get('email')?.errors?.minlength"
93 jhiTranslate="entity.validation.minlength"
94 [translateValues]="{ min: 5 }">
95 This field is required to be at least 5 characters.
96 </small>
97
98 <small class="form-text text-danger"
99 *ngIf="editForm.get('email')?.errors?.email"
100 jhiTranslate="global.messages.validate.email.invalid">
101 Your email is invalid.
102 </small>
103 </div>
104 </div>
105
106 <div class="form-check">
107 <label class="form-check-label" for="activated">
108 <input class="form-check-input" [attr.disabled]="user.id === undefined ? 'disabled' : null"
109 type="checkbox" id="activated" name="activated" formControlName="activated">
110 <span jhiTranslate="userManagement.activated">Activated</span>
111 </label>
112 </div>
113
114 <div class="form-group" *ngIf="languages && languages.length > 0">
115 <label jhiTranslate="userManagement.langKey">Lang Key</label>
116 <select class="form-control" id="langKey" name="langKey" formControlName="langKey">
117 <option *ngFor="let language of languages" [value]="language">{{ language | findLanguageFromKey }}</option>
118 </select>
119 </div>
120
121 <div class="form-group">
122 <label jhiTranslate="userManagement.profiles">Profiles</label>
123 <select class="form-control" multiple name="authority" formControlName="authorities">
124 <option *ngFor="let authority of authorities" [value]="authority">{{ authority }}</option>
125 </select>
126 </div>
127 </div>
128
129 <div *ngIf="user">
130 <button type="button" class="btn btn-secondary" (click)="previousState()">
131 <fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
132 </button>
133
134 <button type="submit" [disabled]="editForm.invalid || isSaving" class="btn btn-primary">
135 <fa-icon icon="save"></fa-icon>&nbsp;<span jhiTranslate="entity.action.save">Save</span>
136 </button>
137 </div>
138 </form>
139 </div>
140 </div>
File src/main/webapp/app/admin/user-management/user-management-update.component.ts added (mode: 100644) (index 0000000..6e04cbe)
1 import { Component, OnInit } from '@angular/core';
2 import { FormBuilder, Validators } from '@angular/forms';
3 import { ActivatedRoute } from '@angular/router';
4
5 import { LANGUAGES } from 'app/core/language/language.constants';
6 import { User } from 'app/core/user/user.model';
7 import { UserService } from 'app/core/user/user.service';
8
9 @Component({
10 selector: 'auth-user-mgmt-update',
11 templateUrl: './user-management-update.component.html'
12 })
13 export class UserManagementUpdateComponent implements OnInit {
14 user!: User;
15 languages = LANGUAGES;
16 authorities: string[] = [];
17 isSaving = false;
18
19 editForm = this.fb.group({
20 id: [],
21 login: ['', [Validators.required, Validators.minLength(1), Validators.maxLength(50), Validators.pattern('^[_.@A-Za-z0-9-]*')]],
22 firstName: ['', [Validators.maxLength(50)]],
23 lastName: ['', [Validators.maxLength(50)]],
24 email: ['', [Validators.minLength(5), Validators.maxLength(254), Validators.email]],
25 activated: [],
26 langKey: [],
27 authorities: []
28 });
29
30 constructor(private userService: UserService, private route: ActivatedRoute, private fb: FormBuilder) {}
31
32 ngOnInit(): void {
33 this.route.data.subscribe(({ user }) => {
34 if (user) {
35 this.user = user;
36 if (this.user.id === undefined) {
37 this.user.activated = true;
38 }
39 this.updateForm(user);
40 }
41 });
42 this.userService.authorities().subscribe(authorities => {
43 this.authorities = authorities;
44 });
45 }
46
47 previousState(): void {
48 window.history.back();
49 }
50
51 save(): void {
52 this.isSaving = true;
53 this.updateUser(this.user);
54 if (this.user.id !== undefined) {
55 this.userService.update(this.user).subscribe(
56 () => this.onSaveSuccess(),
57 () => this.onSaveError()
58 );
59 } else {
60 this.userService.create(this.user).subscribe(
61 () => this.onSaveSuccess(),
62 () => this.onSaveError()
63 );
64 }
65 }
66
67 private updateForm(user: User): void {
68 this.editForm.patchValue({
69 id: user.id,
70 login: user.login,
71 firstName: user.firstName,
72 lastName: user.lastName,
73 email: user.email,
74 activated: user.activated,
75 langKey: user.langKey,
76 authorities: user.authorities
77 });
78 }
79
80 private updateUser(user: User): void {
81 user.login = this.editForm.get(['login'])!.value;
82 user.firstName = this.editForm.get(['firstName'])!.value;
83 user.lastName = this.editForm.get(['lastName'])!.value;
84 user.email = this.editForm.get(['email'])!.value;
85 user.activated = this.editForm.get(['activated'])!.value;
86 user.langKey = this.editForm.get(['langKey'])!.value;
87 user.authorities = this.editForm.get(['authorities'])!.value;
88 }
89
90 private onSaveSuccess(): void {
91 this.isSaving = false;
92 this.previousState();
93 }
94
95 private onSaveError(): void {
96 this.isSaving = false;
97 }
98 }
File src/main/webapp/app/admin/user-management/user-management.component.html added (mode: 100644) (index 0000000..21b53e9)
1 <div>
2 <h2>
3 <span id="user-management-page-heading" jhiTranslate="userManagement.home.title">Users</span>
4
5 <button class="btn btn-primary float-right jh-create-entity" [routerLink]="['./new']">
6 <fa-icon icon="plus"></fa-icon> <span jhiTranslate="userManagement.home.createLabel">Create a new User</span>
7 </button>
8 </h2>
9
10 <auth-alert-error></auth-alert-error>
11
12 <auth-alert></auth-alert>
13
14 <div class="table-responsive" *ngIf="users">
15 <table class="table table-striped" aria-describedby="user-management-page-heading">
16 <thead>
17 <tr jhiSort [(predicate)]="predicate" [(ascending)]="ascending" [callback]="transition.bind(this)">
18 <th scope="col" jhiSortBy="id"><span jhiTranslate="global.field.id">ID</span> <fa-icon icon="sort"></fa-icon></th>
19 <th scope="col" jhiSortBy="login"><span jhiTranslate="userManagement.login">Login</span> <fa-icon icon="sort"></fa-icon></th>
20 <th scope="col" jhiSortBy="email"><span jhiTranslate="userManagement.email">Email</span> <fa-icon icon="sort"></fa-icon></th>
21 <th scope="col"></th>
22 <th scope="col" jhiSortBy="langKey"> <span jhiTranslate="userManagement.langKey">Lang Key</span> <fa-icon icon="sort"></fa-icon></th>
23 <th scope="col"><span jhiTranslate="userManagement.profiles">Profiles</span></th>
24 <th scope="col" jhiSortBy="createdDate"><span jhiTranslate="userManagement.createdDate">Created Date</span> <fa-icon icon="sort"></fa-icon></th>
25 <th scope="col" jhiSortBy="lastModifiedBy"><span jhiTranslate="userManagement.lastModifiedBy">Last Modified By</span> <fa-icon icon="sort"></fa-icon></th>
26 <th scope="col" jhiSortBy="lastModifiedDate"><span jhiTranslate="userManagement.lastModifiedDate">Last Modified Date</span> <fa-icon icon="sort"></fa-icon></th>
27 <th scope="col"></th>
28 </tr>
29 </thead>
30 <tbody *ngIf="users">
31 <tr *ngFor="let user of users; trackBy: trackIdentity">
32 <td><a [routerLink]="['./', user.login, 'view']">{{ user.id }}</a></td>
33 <td>{{ user.login }}</td>
34 <td>{{ user.email }}</td>
35 <td>
36 <button class="btn btn-danger btn-sm" (click)="setActive(user, true)" *ngIf="!user.activated"
37 jhiTranslate="userManagement.deactivated">Deactivated</button>
38 <button class="btn btn-success btn-sm" (click)="setActive(user, false)" *ngIf="user.activated"
39 [disabled]="!currentAccount || currentAccount.login === user.login" jhiTranslate="userManagement.activated">Activated</button>
40 </td>
41 <td>{{ user.langKey }}</td>
42 <td>
43 <div *ngFor="let authority of user.authorities">
44 <span class="badge badge-info">{{ authority }}</span>
45 </div>
46 </td>
47 <td>{{ user.createdDate | date:'dd/MM/yy HH:mm' }}</td>
48 <td>{{ user.lastModifiedBy }}</td>
49 <td>{{ user.lastModifiedDate | date:'dd/MM/yy HH:mm' }}</td>
50 <td class="text-right">
51 <div class="btn-group">
52 <button type="submit"
53 [routerLink]="['./', user.login, 'view']"
54 class="btn btn-info btn-sm">
55 <fa-icon icon="eye"></fa-icon>
56 <span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
57 </button>
58
59 <button type="submit"
60 [routerLink]="['./', user.login, 'edit']"
61 queryParamsHandling="merge"
62 class="btn btn-primary btn-sm">
63 <fa-icon icon="pencil-alt"></fa-icon>
64 <span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
65 </button>
66
67 <button type="button" (click)="deleteUser(user)"
68 class="btn btn-danger btn-sm" [disabled]="!currentAccount || currentAccount.login === user.login">
69 <fa-icon icon="times"></fa-icon>
70 <span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
71 </button>
72 </div>
73 </td>
74 </tr>
75 </tbody>
76 </table>
77 </div>
78
79 <div *ngIf="users">
80 <div class="row justify-content-center">
81 <jhi-item-count [page]="page" [total]="totalItems" [itemsPerPage]="itemsPerPage"></jhi-item-count>
82 </div>
83
84 <div class="row justify-content-center">
85 <ngb-pagination [collectionSize]="totalItems" [(page)]="page" [pageSize]="itemsPerPage" [maxSize]="5" [rotate]="true" [boundaryLinks]="true" (pageChange)="loadPage(page)"></ngb-pagination>
86 </div>
87 </div>
88 </div>
File src/main/webapp/app/admin/user-management/user-management.component.ts added (mode: 100644) (index 0000000..17bfcd9)
1 import { Component, OnInit, OnDestroy } from '@angular/core';
2 import { HttpResponse, HttpHeaders } from '@angular/common/http';
3 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
4 import { Subscription } from 'rxjs';
5 import { flatMap } from 'rxjs/operators';
6 import { ActivatedRoute, Router } from '@angular/router';
7 import { JhiEventManager } from 'ng-jhipster';
8
9 import { ITEMS_PER_PAGE } from 'app/shared/constants/pagination.constants';
10 import { AccountService } from 'app/core/auth/account.service';
11 import { Account } from 'app/core/user/account.model';
12 import { UserService } from 'app/core/user/user.service';
13 import { User } from 'app/core/user/user.model';
14 import { UserManagementDeleteDialogComponent } from './user-management-delete-dialog.component';
15
16 @Component({
17 selector: 'auth-user-mgmt',
18 templateUrl: './user-management.component.html'
19 })
20 export class UserManagementComponent implements OnInit, OnDestroy {
21 currentAccount: Account | null = null;
22 users: User[] | null = null;
23 userListSubscription?: Subscription;
24 totalItems = 0;
25 itemsPerPage = ITEMS_PER_PAGE;
26 page!: number;
27 predicate!: string;
28 previousPage!: number;
29 ascending!: boolean;
30
31 constructor(
32 private userService: UserService,
33 private accountService: AccountService,
34 private activatedRoute: ActivatedRoute,
35 private router: Router,
36 private eventManager: JhiEventManager,
37 private modalService: NgbModal
38 ) {}
39
40 ngOnInit(): void {
41 this.activatedRoute.data
42 .pipe(
43 flatMap(
44 () => this.accountService.identity(),
45 (data, account) => {
46 this.page = data.pagingParams.page;
47 this.previousPage = data.pagingParams.page;
48 this.ascending = data.pagingParams.ascending;
49 this.predicate = data.pagingParams.predicate;
50 this.currentAccount = account;
51 this.loadAll();
52 this.userListSubscription = this.eventManager.subscribe('userListModification', () => this.loadAll());
53 }
54 )
55 )
56 .subscribe();
57 }
58
59 ngOnDestroy(): void {
60 if (this.userListSubscription) {
61 this.eventManager.destroy(this.userListSubscription);
62 }
63 }
64
65 setActive(user: User, isActivated: boolean): void {
66 this.userService.update({ ...user, activated: isActivated }).subscribe(() => this.loadAll());
67 }
68
69 trackIdentity(index: number, item: User): any {
70 return item.id;
71 }
72
73 loadPage(page: number): void {
74 if (page !== this.previousPage) {
75 this.previousPage = page;
76 this.transition();
77 }
78 }
79
80 transition(): void {
81 this.router.navigate(['./'], {
82 relativeTo: this.activatedRoute.parent,
83 queryParams: {
84 page: this.page,
85 sort: this.predicate + ',' + (this.ascending ? 'asc' : 'desc')
86 }
87 });
88 this.loadAll();
89 }
90
91 deleteUser(user: User): void {
92 const modalRef = this.modalService.open(UserManagementDeleteDialogComponent, { size: 'lg', backdrop: 'static' });
93 modalRef.componentInstance.user = user;
94 }
95
96 private loadAll(): void {
97 this.userService
98 .query({
99 page: this.page - 1,
100 size: this.itemsPerPage,
101 sort: this.sort()
102 })
103 .subscribe((res: HttpResponse<User[]>) => this.onSuccess(res.body, res.headers));
104 }
105
106 private sort(): string[] {
107 const result = [this.predicate + ',' + (this.ascending ? 'asc' : 'desc')];
108 if (this.predicate !== 'id') {
109 result.push('id');
110 }
111 return result;
112 }
113
114 private onSuccess(users: User[] | null, headers: HttpHeaders): void {
115 this.totalItems = Number(headers.get('X-Total-Count'));
116 this.users = users;
117 }
118 }
File src/main/webapp/app/admin/user-management/user-management.module.ts added (mode: 100644) (index 0000000..be3e024)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3
4 import { HonlapSharedModule } from 'app/shared/shared.module';
5 import { UserManagementComponent } from './user-management.component';
6 import { UserManagementDetailComponent } from './user-management-detail.component';
7 import { UserManagementUpdateComponent } from './user-management-update.component';
8 import { UserManagementDeleteDialogComponent } from './user-management-delete-dialog.component';
9 import { userManagementRoute } from './user-management.route';
10
11 @NgModule({
12 imports: [HonlapSharedModule, RouterModule.forChild(userManagementRoute)],
13 declarations: [
14 UserManagementComponent,
15 UserManagementDetailComponent,
16 UserManagementUpdateComponent,
17 UserManagementDeleteDialogComponent
18 ],
19 entryComponents: [UserManagementDeleteDialogComponent]
20 })
21 export class UserManagementModule {}
File src/main/webapp/app/admin/user-management/user-management.route.ts added (mode: 100644) (index 0000000..5a5c566)
1 import { Injectable } from '@angular/core';
2 import { Resolve, ActivatedRouteSnapshot, Routes } from '@angular/router';
3 import { Observable, of } from 'rxjs';
4 import { JhiResolvePagingParams } from 'ng-jhipster';
5
6 import { User, IUser } from 'app/core/user/user.model';
7 import { UserService } from 'app/core/user/user.service';
8 import { UserManagementComponent } from './user-management.component';
9 import { UserManagementDetailComponent } from './user-management-detail.component';
10 import { UserManagementUpdateComponent } from './user-management-update.component';
11
12 @Injectable({ providedIn: 'root' })
13 export class UserManagementResolve implements Resolve<IUser> {
14 constructor(private service: UserService) {}
15
16 resolve(route: ActivatedRouteSnapshot): Observable<IUser> {
17 const id = route.params['login'];
18 if (id) {
19 return this.service.find(id);
20 }
21 return of(new User());
22 }
23 }
24
25 export const userManagementRoute: Routes = [
26 {
27 path: '',
28 component: UserManagementComponent,
29 resolve: {
30 pagingParams: JhiResolvePagingParams
31 },
32 data: {
33 defaultSort: 'id,asc'
34 }
35 },
36 {
37 path: ':login/view',
38 component: UserManagementDetailComponent,
39 resolve: {
40 user: UserManagementResolve
41 }
42 },
43 {
44 path: 'new',
45 component: UserManagementUpdateComponent,
46 resolve: {
47 user: UserManagementResolve
48 }
49 },
50 {
51 path: ':login/edit',
52 component: UserManagementUpdateComponent,
53 resolve: {
54 user: UserManagementResolve
55 }
56 }
57 ];
File src/main/webapp/app/app-routing.module.ts added (mode: 100644) (index 0000000..3c06b52)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3 import { errorRoute } from './layouts/error/error.route';
4 import { navbarRoute } from './layouts/navbar/navbar.route';
5 import { DEBUG_INFO_ENABLED } from 'app/app.constants';
6 import { Authority } from 'app/shared/constants/authority.constants';
7
8 import { UserRouteAccessService } from 'app/core/auth/user-route-access-service';
9
10 const LAYOUT_ROUTES = [navbarRoute, ...errorRoute];
11
12 @NgModule({
13 imports: [
14 RouterModule.forRoot(
15 [
16 {
17 path: 'admin',
18 data: {
19 authorities: [Authority.ADMIN]
20 },
21 canActivate: [UserRouteAccessService],
22 loadChildren: () => import('./admin/admin-routing.module').then(m => m.AdminRoutingModule)
23 },
24 {
25 path: 'account',
26 loadChildren: () => import('./account/account.module').then(m => m.AccountModule)
27 },
28 ...LAYOUT_ROUTES
29 ],
30 { enableTracing: DEBUG_INFO_ENABLED }
31 )
32 ],
33 exports: [RouterModule]
34 })
35 export class HonlapAppRoutingModule {}
File src/main/webapp/app/app.constants.ts added (mode: 100644) (index 0000000..4b34b65)
1 // These constants are injected via webpack environment variables.
2 // You can add more variables in webpack.common.js or in profile specific webpack.<dev|prod>.js files.
3 // If you change the values in the webpack config files, you need to re run webpack to update the application
4
5 export const VERSION = process.env.VERSION;
6 export const DEBUG_INFO_ENABLED = Boolean(process.env.DEBUG_INFO_ENABLED);
7 export const SERVER_API_URL = process.env.SERVER_API_URL;
8 export const BUILD_TIMESTAMP = process.env.BUILD_TIMESTAMP;
File src/main/webapp/app/app.main.ts added (mode: 100644) (index 0000000..0573d94)
1 import './polyfills';
2 import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 import { ProdConfig } from './blocks/config/prod.config';
4 import { HonlapAppModule } from './app.module';
5
6 ProdConfig();
7
8 if (module['hot']) {
9 module['hot'].accept();
10 }
11
12 platformBrowserDynamic()
13 .bootstrapModule(HonlapAppModule, { preserveWhitespaces: true })
14 // eslint-disable-next-line no-console
15 .then(() => console.log('Application started'))
16 .catch(err => console.error(err));
File src/main/webapp/app/app.module.ts added (mode: 100644) (index 0000000..6a96676)
1 import { NgModule } from '@angular/core';
2 import { BrowserModule } from '@angular/platform-browser';
3
4 import './vendor';
5 import { HonlapSharedModule } from 'app/shared/shared.module';
6 import { HonlapCoreModule } from 'app/core/core.module';
7 import { HonlapAppRoutingModule } from './app-routing.module';
8 import { HonlapHomeModule } from './home/home.module';
9 import { HonlapEntityModule } from './entities/entity.module';
10 // jhipster-needle-angular-add-module-import JHipster will add new module here
11 import { MainComponent } from './layouts/main/main.component';
12 import { NavbarComponent } from './layouts/navbar/navbar.component';
13 import { FooterComponent } from './layouts/footer/footer.component';
14 import { PageRibbonComponent } from './layouts/profiles/page-ribbon.component';
15 import { ActiveMenuDirective } from './layouts/navbar/active-menu.directive';
16 import { ErrorComponent } from './layouts/error/error.component';
17
18 @NgModule({
19 imports: [
20 BrowserModule,
21 HonlapSharedModule,
22 HonlapCoreModule,
23 HonlapHomeModule,
24 // jhipster-needle-angular-add-module JHipster will add new module here
25 HonlapEntityModule,
26 HonlapAppRoutingModule
27 ],
28 declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
29 bootstrap: [MainComponent]
30 })
31 export class HonlapAppModule {}
File src/main/webapp/app/blocks/config/prod.config.ts added (mode: 100644) (index 0000000..b1ccef1)
1 import { enableProdMode } from '@angular/core';
2 import { DEBUG_INFO_ENABLED } from 'app/app.constants';
3
4 export function ProdConfig(): void {
5 // disable debug data on prod profile to improve performance
6 if (!DEBUG_INFO_ENABLED) {
7 enableProdMode();
8 }
9 }
File src/main/webapp/app/blocks/config/uib-pagination.config.ts added (mode: 100644) (index 0000000..002c5cf)
1 import { Injectable } from '@angular/core';
2 import { NgbPaginationConfig } from '@ng-bootstrap/ng-bootstrap';
3 import { ITEMS_PER_PAGE } from 'app/shared/constants/pagination.constants';
4
5 @Injectable({ providedIn: 'root' })
6 export class PaginationConfig {
7 constructor(config: NgbPaginationConfig) {
8 config.boundaryLinks = true;
9 config.maxSize = 5;
10 config.pageSize = ITEMS_PER_PAGE;
11 config.size = 'sm';
12 }
13 }
File src/main/webapp/app/blocks/interceptor/auth-expired.interceptor.ts added (mode: 100644) (index 0000000..a9fa62b)
1 import { Injectable } from '@angular/core';
2 import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4 import { tap } from 'rxjs/operators';
5 import { Router } from '@angular/router';
6
7 import { LoginService } from 'app/core/login/login.service';
8 import { LoginModalService } from 'app/core/login/login-modal.service';
9 import { StateStorageService } from 'app/core/auth/state-storage.service';
10
11 @Injectable()
12 export class AuthExpiredInterceptor implements HttpInterceptor {
13 constructor(
14 private loginService: LoginService,
15 private loginModalService: LoginModalService,
16 private stateStorageService: StateStorageService,
17 private router: Router
18 ) {}
19
20 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
21 return next.handle(request).pipe(
22 tap(null, (err: HttpErrorResponse) => {
23 if (err.status === 401 && err.url && !err.url.includes('api/account')) {
24 this.stateStorageService.storeUrl(this.router.routerState.snapshot.url);
25 this.loginService.logout();
26 this.router.navigate(['']);
27 this.loginModalService.open();
28 }
29 })
30 );
31 }
32 }
File src/main/webapp/app/blocks/interceptor/auth.interceptor.ts added (mode: 100644) (index 0000000..3dd7aff)
1 import { Injectable } from '@angular/core';
2 import { Observable } from 'rxjs';
3 import { LocalStorageService, SessionStorageService } from 'ngx-webstorage';
4 import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
5
6 import { SERVER_API_URL } from 'app/app.constants';
7
8 @Injectable()
9 export class AuthInterceptor implements HttpInterceptor {
10 constructor(private localStorage: LocalStorageService, private sessionStorage: SessionStorageService) {}
11
12 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
13 if (!request || !request.url || (request.url.startsWith('http') && !(SERVER_API_URL && request.url.startsWith(SERVER_API_URL)))) {
14 return next.handle(request);
15 }
16
17 const token = this.localStorage.retrieve('authenticationToken') || this.sessionStorage.retrieve('authenticationToken');
18 if (token) {
19 request = request.clone({
20 setHeaders: {
21 Authorization: 'Bearer ' + token
22 }
23 });
24 }
25 return next.handle(request);
26 }
27 }
File src/main/webapp/app/blocks/interceptor/errorhandler.interceptor.ts added (mode: 100644) (index 0000000..bc6314e)
1 import { Injectable } from '@angular/core';
2 import { JhiEventManager, JhiEventWithContent } from 'ng-jhipster';
3 import { HttpInterceptor, HttpRequest, HttpErrorResponse, HttpHandler, HttpEvent } from '@angular/common/http';
4 import { Observable } from 'rxjs';
5 import { tap } from 'rxjs/operators';
6
7 @Injectable()
8 export class ErrorHandlerInterceptor implements HttpInterceptor {
9 constructor(private eventManager: JhiEventManager) {}
10
11 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
12 return next.handle(request).pipe(
13 tap(null, (err: HttpErrorResponse) => {
14 if (!(err.status === 401 && (err.message === '' || (err.url && err.url.includes('api/account'))))) {
15 this.eventManager.broadcast(new JhiEventWithContent('honlapApp.httpError', err));
16 }
17 })
18 );
19 }
20 }
File src/main/webapp/app/blocks/interceptor/notification.interceptor.ts added (mode: 100644) (index 0000000..5eb735b)
1 import { JhiAlertService } from 'ng-jhipster';
2 import { HttpInterceptor, HttpRequest, HttpResponse, HttpHandler, HttpEvent } from '@angular/common/http';
3 import { Injectable } from '@angular/core';
4 import { Observable } from 'rxjs';
5 import { tap } from 'rxjs/operators';
6
7 @Injectable()
8 export class NotificationInterceptor implements HttpInterceptor {
9 constructor(private alertService: JhiAlertService) {}
10
11 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
12 return next.handle(request).pipe(
13 tap((event: HttpEvent<any>) => {
14 if (event instanceof HttpResponse) {
15 let alert: string | null = null;
16 let alertParams: string | null = null;
17
18 event.headers.keys().forEach(entry => {
19 if (entry.toLowerCase().endsWith('app-alert')) {
20 alert = event.headers.get(entry);
21 } else if (entry.toLowerCase().endsWith('app-params')) {
22 alertParams = decodeURIComponent(event.headers.get(entry)!.replace(/\+/g, ' '));
23 }
24 });
25
26 if (alert) {
27 this.alertService.success(alert, { param: alertParams });
28 }
29 }
30 })
31 );
32 }
33 }
File src/main/webapp/app/core/auth/account.service.ts added (mode: 100644) (index 0000000..8af48d3)
1 import { Injectable } from '@angular/core';
2 import { Router } from '@angular/router';
3 import { HttpClient } from '@angular/common/http';
4 import { JhiLanguageService } from 'ng-jhipster';
5 import { SessionStorageService } from 'ngx-webstorage';
6 import { Observable, ReplaySubject, of } from 'rxjs';
7 import { shareReplay, tap, catchError } from 'rxjs/operators';
8 import { StateStorageService } from 'app/core/auth/state-storage.service';
9
10 import { SERVER_API_URL } from 'app/app.constants';
11 import { Account } from 'app/core/user/account.model';
12
13 @Injectable({ providedIn: 'root' })
14 export class AccountService {
15 private userIdentity: Account | null = null;
16 private authenticationState = new ReplaySubject<Account | null>(1);
17 private accountCache$?: Observable<Account | null>;
18
19 constructor(
20 private languageService: JhiLanguageService,
21 private sessionStorage: SessionStorageService,
22 private http: HttpClient,
23 private stateStorageService: StateStorageService,
24 private router: Router
25 ) {}
26
27 save(account: Account): Observable<{}> {
28 return this.http.post(SERVER_API_URL + 'api/account', account);
29 }
30
31 authenticate(identity: Account | null): void {
32 this.userIdentity = identity;
33 this.authenticationState.next(this.userIdentity);
34 }
35
36 hasAnyAuthority(authorities: string[] | string): boolean {
37 if (!this.userIdentity || !this.userIdentity.authorities) {
38 return false;
39 }
40 if (!Array.isArray(authorities)) {
41 authorities = [authorities];
42 }
43 return this.userIdentity.authorities.some((authority: string) => authorities.includes(authority));
44 }
45
46 identity(force?: boolean): Observable<Account | null> {
47 if (!this.accountCache$ || force || !this.isAuthenticated()) {
48 this.accountCache$ = this.fetch().pipe(
49 catchError(() => {
50 return of(null);
51 }),
52 tap((account: Account | null) => {
53 this.authenticate(account);
54
55 // After retrieve the account info, the language will be changed to
56 // the user's preferred language configured in the account setting
57 if (account && account.langKey) {
58 const langKey = this.sessionStorage.retrieve('locale') || account.langKey;
59 this.languageService.changeLanguage(langKey);
60 }
61
62 if (account) {
63 this.navigateToStoredUrl();
64 }
65 }),
66 shareReplay()
67 );
68 }
69 return this.accountCache$;
70 }
71
72 isAuthenticated(): boolean {
73 return this.userIdentity !== null;
74 }
75
76 getAuthenticationState(): Observable<Account | null> {
77 return this.authenticationState.asObservable();
78 }
79
80 getImageUrl(): string {
81 return this.userIdentity ? this.userIdentity.imageUrl : '';
82 }
83
84 private fetch(): Observable<Account> {
85 return this.http.get<Account>(SERVER_API_URL + 'api/account');
86 }
87
88 private navigateToStoredUrl(): void {
89 // previousState can be set in the authExpiredInterceptor and in the userRouteAccessService
90 // if login is successful, go to stored previousState and clear previousState
91 const previousUrl = this.stateStorageService.getUrl();
92 if (previousUrl) {
93 this.stateStorageService.clearUrl();
94 this.router.navigateByUrl(previousUrl);
95 }
96 }
97 }
File src/main/webapp/app/core/auth/auth-jwt.service.ts added (mode: 100644) (index 0000000..5fb3e6f)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4 import { map } from 'rxjs/operators';
5 import { LocalStorageService, SessionStorageService } from 'ngx-webstorage';
6
7 import { SERVER_API_URL } from 'app/app.constants';
8 import { Login } from 'app/core/login/login.model';
9
10 type JwtToken = {
11 id_token: string;
12 };
13
14 @Injectable({ providedIn: 'root' })
15 export class AuthServerProvider {
16 constructor(private http: HttpClient, private $localStorage: LocalStorageService, private $sessionStorage: SessionStorageService) {}
17
18 getToken(): string {
19 return this.$localStorage.retrieve('authenticationToken') || this.$sessionStorage.retrieve('authenticationToken') || '';
20 }
21
22 login(credentials: Login): Observable<void> {
23 return this.http
24 .post<JwtToken>(SERVER_API_URL + 'api/authenticate', credentials)
25 .pipe(map(response => this.authenticateSuccess(response, credentials.rememberMe)));
26 }
27
28 logout(): Observable<void> {
29 return new Observable(observer => {
30 this.$localStorage.clear('authenticationToken');
31 this.$sessionStorage.clear('authenticationToken');
32 observer.complete();
33 });
34 }
35
36 private authenticateSuccess(response: JwtToken, rememberMe: boolean): void {
37 const jwt = response.id_token;
38 if (rememberMe) {
39 this.$localStorage.store('authenticationToken', jwt);
40 } else {
41 this.$sessionStorage.store('authenticationToken', jwt);
42 }
43 }
44 }
File src/main/webapp/app/core/auth/csrf.service.ts added (mode: 100644) (index 0000000..d436d88)
1 import { Injectable } from '@angular/core';
2 import { CookieService } from 'ngx-cookie';
3
4 @Injectable({ providedIn: 'root' })
5 export class CSRFService {
6 constructor(private cookieService: CookieService) {}
7
8 getCSRF(name = 'XSRF-TOKEN'): string {
9 return this.cookieService.get(name);
10 }
11 }
File src/main/webapp/app/core/auth/state-storage.service.ts added (mode: 100644) (index 0000000..5d8861d)
1 import { Injectable } from '@angular/core';
2 import { SessionStorageService } from 'ngx-webstorage';
3
4 @Injectable({ providedIn: 'root' })
5 export class StateStorageService {
6 private previousUrlKey = 'previousUrl';
7
8 constructor(private $sessionStorage: SessionStorageService) {}
9
10 storeUrl(url: string): void {
11 this.$sessionStorage.store(this.previousUrlKey, url);
12 }
13
14 getUrl(): string | null | undefined {
15 return this.$sessionStorage.retrieve(this.previousUrlKey);
16 }
17
18 clearUrl(): void {
19 this.$sessionStorage.clear(this.previousUrlKey);
20 }
21 }
File src/main/webapp/app/core/auth/user-route-access-service.ts added (mode: 100644) (index 0000000..30d7b7e)
1 import { Injectable, isDevMode } from '@angular/core';
2 import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
3 import { Observable } from 'rxjs';
4 import { map } from 'rxjs/operators';
5
6 import { AccountService } from 'app/core/auth/account.service';
7 import { LoginModalService } from 'app/core/login/login-modal.service';
8 import { StateStorageService } from './state-storage.service';
9
10 @Injectable({ providedIn: 'root' })
11 export class UserRouteAccessService implements CanActivate {
12 constructor(
13 private router: Router,
14 private loginModalService: LoginModalService,
15 private accountService: AccountService,
16 private stateStorageService: StateStorageService
17 ) {}
18
19 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
20 const authorities = route.data['authorities'];
21 // We need to call the checkLogin / and so the accountService.identity() function, to ensure,
22 // that the client has a principal too, if they already logged in by the server.
23 // This could happen on a page refresh.
24 return this.checkLogin(authorities, state.url);
25 }
26
27 checkLogin(authorities: string[], url: string): Observable<boolean> {
28 return this.accountService.identity().pipe(
29 map(account => {
30 if (!authorities || authorities.length === 0) {
31 return true;
32 }
33
34 if (account) {
35 const hasAnyAuthority = this.accountService.hasAnyAuthority(authorities);
36 if (hasAnyAuthority) {
37 return true;
38 }
39 if (isDevMode()) {
40 console.error('User has not any of required authorities: ', authorities);
41 }
42 this.router.navigate(['accessdenied']);
43 return false;
44 }
45
46 this.stateStorageService.storeUrl(url);
47 this.router.navigate(['']);
48 this.loginModalService.open();
49 return false;
50 })
51 );
52 }
53 }
File src/main/webapp/app/core/core.module.ts added (mode: 100644) (index 0000000..fb93c9d)
1 import { NgModule, LOCALE_ID } from '@angular/core';
2 import { DatePipe, registerLocaleData } from '@angular/common';
3 import { HttpClient, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
4 import { Title } from '@angular/platform-browser';
5 import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
6 import { CookieModule } from 'ngx-cookie';
7 import { TranslateModule, TranslateLoader, MissingTranslationHandler } from '@ngx-translate/core';
8 import { NgxWebstorageModule } from 'ngx-webstorage';
9 import { NgJhipsterModule, translatePartialLoader, missingTranslationHandler, JhiConfigService, JhiLanguageService } from 'ng-jhipster';
10 import locale from '@angular/common/locales/hu';
11
12 import * as moment from 'moment';
13 import { NgbDateAdapter, NgbDatepickerConfig } from '@ng-bootstrap/ng-bootstrap';
14 import { NgbDateMomentAdapter } from 'app/shared/util/datepicker-adapter';
15
16 import { AuthInterceptor } from 'app/blocks/interceptor/auth.interceptor';
17 import { AuthExpiredInterceptor } from 'app/blocks/interceptor/auth-expired.interceptor';
18 import { ErrorHandlerInterceptor } from 'app/blocks/interceptor/errorhandler.interceptor';
19 import { NotificationInterceptor } from 'app/blocks/interceptor/notification.interceptor';
20
21 import { fontAwesomeIcons } from './icons/font-awesome-icons';
22
23 @NgModule({
24 imports: [
25 HttpClientModule,
26 CookieModule.forRoot(),
27 NgxWebstorageModule.forRoot({ prefix: 'auth', separator: '-' }),
28 NgJhipsterModule.forRoot({
29 // set below to true to make alerts look like toast
30 alertAsToast: false,
31 alertTimeout: 5000,
32 i18nEnabled: true,
33 defaultI18nLang: 'hu'
34 }),
35 TranslateModule.forRoot({
36 loader: {
37 provide: TranslateLoader,
38 useFactory: translatePartialLoader,
39 deps: [HttpClient]
40 },
41 missingTranslationHandler: {
42 provide: MissingTranslationHandler,
43 useFactory: missingTranslationHandler,
44 deps: [JhiConfigService]
45 }
46 })
47 ],
48 providers: [
49 Title,
50 {
51 provide: LOCALE_ID,
52 useValue: 'hu'
53 },
54 { provide: NgbDateAdapter, useClass: NgbDateMomentAdapter },
55 DatePipe,
56 {
57 provide: HTTP_INTERCEPTORS,
58 useClass: AuthInterceptor,
59 multi: true
60 },
61 {
62 provide: HTTP_INTERCEPTORS,
63 useClass: AuthExpiredInterceptor,
64 multi: true
65 },
66 {
67 provide: HTTP_INTERCEPTORS,
68 useClass: ErrorHandlerInterceptor,
69 multi: true
70 },
71 {
72 provide: HTTP_INTERCEPTORS,
73 useClass: NotificationInterceptor,
74 multi: true
75 }
76 ]
77 })
78 export class HonlapCoreModule {
79 constructor(iconLibrary: FaIconLibrary, dpConfig: NgbDatepickerConfig, languageService: JhiLanguageService) {
80 registerLocaleData(locale);
81 iconLibrary.addIcons(...fontAwesomeIcons);
82 dpConfig.minDate = { year: moment().year() - 100, month: 1, day: 1 };
83 languageService.init();
84 }
85 }
File src/main/webapp/app/core/icons/font-awesome-icons.ts added (mode: 100644) (index 0000000..2892ed2)
1 import {
2 faUser,
3 faSort,
4 faSortUp,
5 faSortDown,
6 faSync,
7 faEye,
8 faBan,
9 faTimes,
10 faArrowLeft,
11 faSave,
12 faPlus,
13 faPencilAlt,
14 faBars,
15 faThList,
16 faUserPlus,
17 faRoad,
18 faTachometerAlt,
19 faHeart,
20 faList,
21 faBell,
22 faBook,
23 faHdd,
24 faFlag,
25 faWrench,
26 faLock,
27 faCloud,
28 faSignOutAlt,
29 faSignInAlt,
30 faCalendarAlt,
31 faSearch,
32 faTrashAlt,
33 faAsterisk,
34 faTasks,
35 faHome
36 // jhipster-needle-add-icon-import
37 } from '@fortawesome/free-solid-svg-icons';
38
39 export const fontAwesomeIcons = [
40 faUser,
41 faSort,
42 faSortUp,
43 faSortDown,
44 faSync,
45 faEye,
46 faBan,
47 faTimes,
48 faArrowLeft,
49 faSave,
50 faPlus,
51 faPencilAlt,
52 faBars,
53 faHome,
54 faThList,
55 faUserPlus,
56 faRoad,
57 faTachometerAlt,
58 faHeart,
59 faList,
60 faBell,
61 faTasks,
62 faBook,
63 faHdd,
64 faFlag,
65 faWrench,
66 faLock,
67 faCloud,
68 faSignOutAlt,
69 faSignInAlt,
70 faCalendarAlt,
71 faSearch,
72 faTrashAlt,
73 faAsterisk
74 // jhipster-needle-add-icon-import
75 ];
File src/main/webapp/app/core/language/language.constants.ts added (mode: 100644) (index 0000000..ef98095)
1 /*
2 Languages codes are ISO_639-1 codes, see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
3 They are written in English to avoid character encoding issues (not a perfect solution)
4 */
5 export const LANGUAGES: string[] = [
6 'hu',
7 'en'
8 // jhipster-needle-i18n-language-constant - JHipster will add/remove languages in this array
9 ];
File src/main/webapp/app/core/login/login-modal.service.ts added (mode: 100644) (index 0000000..73af6ae)
1 import { Injectable } from '@angular/core';
2 import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
3
4 import { LoginModalComponent } from 'app/shared/login/login.component';
5
6 @Injectable({ providedIn: 'root' })
7 export class LoginModalService {
8 private isOpen = false;
9
10 constructor(private modalService: NgbModal) {}
11
12 open(): void {
13 if (this.isOpen) {
14 return;
15 }
16 this.isOpen = true;
17 const modalRef: NgbModalRef = this.modalService.open(LoginModalComponent);
18 modalRef.result.finally(() => (this.isOpen = false));
19 }
20 }
File src/main/webapp/app/core/login/login.model.ts added (mode: 100644) (index 0000000..422fce9)
1 export class Login {
2 constructor(public username: string, public password: string, public rememberMe: boolean) {}
3 }
File src/main/webapp/app/core/login/login.service.ts added (mode: 100644) (index 0000000..600f4f7)
1 import { Injectable } from '@angular/core';
2 import { Observable } from 'rxjs';
3 import { flatMap } from 'rxjs/operators';
4
5 import { Account } from 'app/core/user/account.model';
6 import { AccountService } from 'app/core/auth/account.service';
7 import { AuthServerProvider } from 'app/core/auth/auth-jwt.service';
8 import { Login } from './login.model';
9
10 @Injectable({ providedIn: 'root' })
11 export class LoginService {
12 constructor(private accountService: AccountService, private authServerProvider: AuthServerProvider) {}
13
14 login(credentials: Login): Observable<Account | null> {
15 return this.authServerProvider.login(credentials).pipe(flatMap(() => this.accountService.identity(true)));
16 }
17
18 logout(): void {
19 this.authServerProvider.logout().subscribe(null, null, () => this.accountService.authenticate(null));
20 }
21 }
File src/main/webapp/app/core/user/account.model.ts added (mode: 100644) (index 0000000..4d2c833)
1 export class Account {
2 constructor(
3 public activated: boolean,
4 public authorities: string[],
5 public email: string,
6 public firstName: string,
7 public langKey: string,
8 public lastName: string,
9 public login: string,
10 public imageUrl: string
11 ) {}
12 }
File src/main/webapp/app/core/user/user.model.ts added (mode: 100644) (index 0000000..585f7ed)
1 export interface IUser {
2 id?: any;
3 login?: string;
4 firstName?: string;
5 lastName?: string;
6 email?: string;
7 activated?: boolean;
8 langKey?: string;
9 authorities?: string[];
10 createdBy?: string;
11 createdDate?: Date;
12 lastModifiedBy?: string;
13 lastModifiedDate?: Date;
14 password?: string;
15 }
16
17 export class User implements IUser {
18 constructor(
19 public id?: any,
20 public login?: string,
21 public firstName?: string,
22 public lastName?: string,
23 public email?: string,
24 public activated?: boolean,
25 public langKey?: string,
26 public authorities?: string[],
27 public createdBy?: string,
28 public createdDate?: Date,
29 public lastModifiedBy?: string,
30 public lastModifiedDate?: Date,
31 public password?: string
32 ) {}
33 }
File src/main/webapp/app/core/user/user.service.ts added (mode: 100644) (index 0000000..b598769)
1 import { Injectable } from '@angular/core';
2 import { HttpClient, HttpResponse } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4
5 import { SERVER_API_URL } from 'app/app.constants';
6 import { createRequestOption, Pagination } from 'app/shared/util/request-util';
7 import { IUser } from './user.model';
8
9 @Injectable({ providedIn: 'root' })
10 export class UserService {
11 public resourceUrl = SERVER_API_URL + 'api/users';
12
13 constructor(private http: HttpClient) {}
14
15 create(user: IUser): Observable<IUser> {
16 return this.http.post<IUser>(this.resourceUrl, user);
17 }
18
19 update(user: IUser): Observable<IUser> {
20 return this.http.put<IUser>(this.resourceUrl, user);
21 }
22
23 find(login: string): Observable<IUser> {
24 return this.http.get<IUser>(`${this.resourceUrl}/${login}`);
25 }
26
27 query(req?: Pagination): Observable<HttpResponse<IUser[]>> {
28 const options = createRequestOption(req);
29 return this.http.get<IUser[]>(this.resourceUrl, { params: options, observe: 'response' });
30 }
31
32 delete(login: string): Observable<{}> {
33 return this.http.delete(`${this.resourceUrl}/${login}`);
34 }
35
36 authorities(): Observable<string[]> {
37 return this.http.get<string[]>(SERVER_API_URL + 'api/users/authorities');
38 }
39 }
File src/main/webapp/app/entities/entity.module.ts added (mode: 100644) (index 0000000..f87e452)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3
4 @NgModule({
5 imports: [
6 RouterModule.forChild([
7 {
8 path: 'piece-of-news',
9 loadChildren: () => import('./piece-of-news/piece-of-news.module').then(m => m.HonlapPieceOfNewsModule)
10 }
11 /* jhipster-needle-add-entity-route - JHipster will add entity modules routes here */
12 ])
13 ]
14 })
15 export class HonlapEntityModule {}
File src/main/webapp/app/entities/piece-of-news/piece-of-news-delete-dialog.component.html added (mode: 100644) (index 0000000..7cb3250)
1 <form *ngIf="pieceOfNews" name="deleteForm" (ngSubmit)="confirmDelete(pieceOfNews?.id!)">
2 <div class="modal-header">
3 <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4>
4
5 <button type="button" class="close" data-dismiss="modal" aria-hidden="true"
6 (click)="cancel()">&times;</button>
7 </div>
8
9 <div class="modal-body">
10 <auth-alert-error></auth-alert-error>
11
12 <p id="auth-delete-pieceOfNews-heading" jhiTranslate="honlapApp.pieceOfNews.delete.question" [translateValues]="{ id: pieceOfNews.id }">Are you sure you want to delete this Piece Of News?</p>
13 </div>
14
15 <div class="modal-footer">
16 <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()">
17 <fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
18 </button>
19
20 <button id="auth-confirm-delete-pieceOfNews" type="submit" class="btn btn-danger">
21 <fa-icon icon="times"></fa-icon>&nbsp;<span jhiTranslate="entity.action.delete">Delete</span>
22 </button>
23 </div>
24 </form>
File src/main/webapp/app/entities/piece-of-news/piece-of-news-delete-dialog.component.ts added (mode: 100644) (index 0000000..e290acb)
1 import { Component } from '@angular/core';
2 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3 import { JhiEventManager } from 'ng-jhipster';
4
5 import { IPieceOfNews } from 'app/shared/model/piece-of-news.model';
6 import { PieceOfNewsService } from './piece-of-news.service';
7
8 @Component({
9 templateUrl: './piece-of-news-delete-dialog.component.html'
10 })
11 export class PieceOfNewsDeleteDialogComponent {
12 pieceOfNews?: IPieceOfNews;
13
14 constructor(
15 protected pieceOfNewsService: PieceOfNewsService,
16 public activeModal: NgbActiveModal,
17 protected eventManager: JhiEventManager
18 ) {}
19
20 cancel(): void {
21 this.activeModal.dismiss();
22 }
23
24 confirmDelete(id: number): void {
25 this.pieceOfNewsService.delete(id).subscribe(() => {
26 this.eventManager.broadcast('pieceOfNewsListModification');
27 this.activeModal.close();
28 });
29 }
30 }
File src/main/webapp/app/entities/piece-of-news/piece-of-news-detail.component.html added (mode: 100644) (index 0000000..6a71a4a)
1 <div class="row justify-content-center">
2 <div class="col-8">
3 <div *ngIf="pieceOfNews">
4 <h2><span jhiTranslate="honlapApp.pieceOfNews.detail.title">Piece Of News</span> {{ pieceOfNews.id }}</h2>
5
6 <hr>
7
8 <auth-alert-error></auth-alert-error>
9
10 <dl class="row-md jh-entity-details">
11 <dt><span jhiTranslate="honlapApp.pieceOfNews.appId">App Id</span></dt>
12 <dd>
13 <span>{{ pieceOfNews.appId }}</span>
14 </dd>
15 <dt><span jhiTranslate="honlapApp.pieceOfNews.newsDate">News Date</span></dt>
16 <dd>
17 <span>{{ pieceOfNews.newsDate }}</span>
18 </dd>
19 <dt><span jhiTranslate="honlapApp.pieceOfNews.headline">Headline</span></dt>
20 <dd>
21 <span>{{ pieceOfNews.headline }}</span>
22 </dd>
23 <dt><span jhiTranslate="honlapApp.pieceOfNews.content">Content</span></dt>
24 <dd>
25 <span>{{ pieceOfNews.content }}</span>
26 </dd>
27 <dt><span jhiTranslate="honlapApp.pieceOfNews.link">Link</span></dt>
28 <dd>
29 <span>{{ pieceOfNews.link }}</span>
30 </dd>
31 <dt><span jhiTranslate="honlapApp.pieceOfNews.publishDate">Publish Date</span></dt>
32 <dd>
33 <span>{{ pieceOfNews.publishDate }}</span>
34 </dd>
35 <dt><span jhiTranslate="honlapApp.pieceOfNews.createdBy">Created By</span></dt>
36 <dd>
37 <span>{{ pieceOfNews.createdBy }}</span>
38 </dd>
39 <dt><span jhiTranslate="honlapApp.pieceOfNews.createdDate">Created Date</span></dt>
40 <dd>
41 <span>{{ pieceOfNews.createdDate }}</span>
42 </dd>
43 <dt><span jhiTranslate="honlapApp.pieceOfNews.lastModifiedBy">Last Modified By</span></dt>
44 <dd>
45 <span>{{ pieceOfNews.lastModifiedBy }}</span>
46 </dd>
47 <dt><span jhiTranslate="honlapApp.pieceOfNews.lastModifiedDate">Last Modified Date</span></dt>
48 <dd>
49 <span>{{ pieceOfNews.lastModifiedDate }}</span>
50 </dd>
51 </dl>
52
53 <button type="submit"
54 (click)="previousState()"
55 class="btn btn-info">
56 <fa-icon icon="arrow-left"></fa-icon>&nbsp;<span jhiTranslate="entity.action.back">Back</span>
57 </button>
58
59 <button type="button"
60 [routerLink]="['/piece-of-news', pieceOfNews.id, 'edit']"
61 class="btn btn-primary">
62 <fa-icon icon="pencil-alt"></fa-icon>&nbsp;<span jhiTranslate="entity.action.edit">Edit</span>
63 </button>
64 </div>
65 </div>
66 </div>
File src/main/webapp/app/entities/piece-of-news/piece-of-news-detail.component.ts added (mode: 100644) (index 0000000..dd811ce)
1 import { Component, OnInit } from '@angular/core';
2 import { ActivatedRoute } from '@angular/router';
3
4 import { IPieceOfNews } from 'app/shared/model/piece-of-news.model';
5
6 @Component({
7 selector: 'auth-piece-of-news-detail',
8 templateUrl: './piece-of-news-detail.component.html'
9 })
10 export class PieceOfNewsDetailComponent implements OnInit {
11 pieceOfNews: IPieceOfNews | null = null;
12
13 constructor(protected activatedRoute: ActivatedRoute) {}
14
15 ngOnInit(): void {
16 this.activatedRoute.data.subscribe(({ pieceOfNews }) => (this.pieceOfNews = pieceOfNews));
17 }
18
19 previousState(): void {
20 window.history.back();
21 }
22 }
File src/main/webapp/app/entities/piece-of-news/piece-of-news-update.component.html added (mode: 100644) (index 0000000..fb873dd)
1 <div class="row justify-content-center">
2 <div class="col-8">
3 <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm">
4 <h2 id="auth-piece-of-news-heading" jhiTranslate="honlapApp.pieceOfNews.home.createOrEditLabel">Create or edit a Piece Of News</h2>
5
6 <div>
7 <auth-alert-error></auth-alert-error>
8
9 <div class="form-group" [hidden]="!editForm.get('id')!.value">
10 <label for="id" jhiTranslate="global.field.id">ID</label>
11 <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly />
12 </div>
13
14 <div class="form-group">
15 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.appId" for="field_appId">App Id</label>
16 <input type="number" class="form-control" name="appId" id="field_appId"
17 formControlName="appId"/>
18 <div *ngIf="editForm.get('appId')!.invalid && (editForm.get('appId')!.dirty || editForm.get('appId')!.touched)">
19 <small class="form-text text-danger"
20 *ngIf="editForm.get('appId')?.errors?.required" jhiTranslate="entity.validation.required">
21 This field is required.
22 </small>
23 <small class="form-text text-danger"
24 [hidden]="!editForm.get('appId')?.errors?.number" jhiTranslate="entity.validation.number">
25 This field should be a number.
26 </small>
27 </div>
28 </div>
29
30 <div class="form-group">
31 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.newsDate" for="field_newsDate">News Date</label>
32 <div class="d-flex">
33 <input id="field_newsDate" type="datetime-local" class="form-control" name="newsDate" formControlName="newsDate" placeholder="YYYY-MM-DD HH:mm"/>
34 </div>
35 <div *ngIf="editForm.get('newsDate')!.invalid && (editForm.get('newsDate')!.dirty || editForm.get('newsDate')!.touched)">
36 <small class="form-text text-danger"
37 *ngIf="editForm.get('newsDate')?.errors?.required" jhiTranslate="entity.validation.required">
38 This field is required.
39 </small>
40 <small class="form-text text-danger"
41 [hidden]="!editForm.get('newsDate')?.errors?.ZonedDateTimelocal" jhiTranslate="entity.validation.ZonedDateTimelocal">
42 This field should be a date and time.
43 </small>
44 </div>
45 </div>
46
47 <div class="form-group">
48 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.headline" for="field_headline">Headline</label>
49 <input type="text" class="form-control" name="headline" id="field_headline"
50 formControlName="headline"/>
51 <div *ngIf="editForm.get('headline')!.invalid && (editForm.get('headline')!.dirty || editForm.get('headline')!.touched)">
52 <small class="form-text text-danger"
53 *ngIf="editForm.get('headline')?.errors?.required" jhiTranslate="entity.validation.required">
54 This field is required.
55 </small>
56 <small class="form-text text-danger"
57 *ngIf="editForm.get('headline')?.errors?.maxlength" jhiTranslate="entity.validation.maxlength" [translateValues]="{ max: 300 }">
58 This field cannot be longer than 300 characters.
59 </small>
60 </div>
61 </div>
62
63 <div class="form-group">
64 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.content" for="field_content">Content</label>
65 <input type="text" class="form-control" name="content" id="field_content"
66 formControlName="content"/>
67 <div *ngIf="editForm.get('content')!.invalid && (editForm.get('content')!.dirty || editForm.get('content')!.touched)">
68 <small class="form-text text-danger"
69 *ngIf="editForm.get('content')?.errors?.required" jhiTranslate="entity.validation.required">
70 This field is required.
71 </small>
72 <small class="form-text text-danger"
73 *ngIf="editForm.get('content')?.errors?.maxlength" jhiTranslate="entity.validation.maxlength" [translateValues]="{ max: 600 }">
74 This field cannot be longer than 600 characters.
75 </small>
76 </div>
77 </div>
78
79 <div class="form-group">
80 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.link" for="field_link">Link</label>
81 <input type="text" class="form-control" name="link" id="field_link"
82 formControlName="link"/>
83 <div *ngIf="editForm.get('link')!.invalid && (editForm.get('link')!.dirty || editForm.get('link')!.touched)">
84 <small class="form-text text-danger"
85 *ngIf="editForm.get('link')?.errors?.required" jhiTranslate="entity.validation.required">
86 This field is required.
87 </small>
88 <small class="form-text text-danger"
89 *ngIf="editForm.get('link')?.errors?.maxlength" jhiTranslate="entity.validation.maxlength" [translateValues]="{ max: 600 }">
90 This field cannot be longer than 600 characters.
91 </small>
92 </div>
93 </div>
94
95 <div class="form-group">
96 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.publishDate" for="field_publishDate">Publish Date</label>
97 <div class="d-flex">
98 <input id="field_publishDate" type="datetime-local" class="form-control" name="publishDate" formControlName="publishDate" placeholder="YYYY-MM-DD HH:mm"/>
99 </div>
100 </div>
101
102 <div class="form-group">
103 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.createdBy" for="field_createdBy">Created By</label>
104 <input type="text" class="form-control" name="createdBy" id="field_createdBy"
105 formControlName="createdBy"/>
106 </div>
107
108 <div class="form-group">
109 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.createdDate" for="field_createdDate">Created Date</label>
110 <div class="d-flex">
111 <input id="field_createdDate" type="datetime-local" class="form-control" name="createdDate" formControlName="createdDate" placeholder="YYYY-MM-DD HH:mm"/>
112 </div>
113 </div>
114
115 <div class="form-group">
116 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.lastModifiedBy" for="field_lastModifiedBy">Last Modified By</label>
117 <input type="text" class="form-control" name="lastModifiedBy" id="field_lastModifiedBy"
118 formControlName="lastModifiedBy"/>
119 </div>
120
121 <div class="form-group">
122 <label class="form-control-label" jhiTranslate="honlapApp.pieceOfNews.lastModifiedDate" for="field_lastModifiedDate">Last Modified Date</label>
123 <div class="d-flex">
124 <input id="field_lastModifiedDate" type="datetime-local" class="form-control" name="lastModifiedDate" formControlName="lastModifiedDate" placeholder="YYYY-MM-DD HH:mm"/>
125 </div>
126 </div>
127 </div>
128
129 <div>
130 <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()">
131 <fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
132 </button>
133
134 <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary">
135 <fa-icon icon="save"></fa-icon>&nbsp;<span jhiTranslate="entity.action.save">Save</span>
136 </button>
137 </div>
138 </form>
139 </div>
140 </div>
File src/main/webapp/app/entities/piece-of-news/piece-of-news-update.component.ts added (mode: 100644) (index 0000000..87bffcf)
1 import { Component, OnInit } from '@angular/core';
2 import { HttpResponse } from '@angular/common/http';
3 // eslint-disable-next-line @typescript-eslint/no-unused-vars
4 import { FormBuilder, Validators } from '@angular/forms';
5 import { ActivatedRoute } from '@angular/router';
6 import { Observable } from 'rxjs';
7 import * as moment from 'moment';
8 import { DATE_TIME_FORMAT } from 'app/shared/constants/input.constants';
9
10 import { IPieceOfNews, PieceOfNews } from 'app/shared/model/piece-of-news.model';
11 import { PieceOfNewsService } from './piece-of-news.service';
12
13 @Component({
14 selector: 'auth-piece-of-news-update',
15 templateUrl: './piece-of-news-update.component.html'
16 })
17 export class PieceOfNewsUpdateComponent implements OnInit {
18 isSaving = false;
19
20 editForm = this.fb.group({
21 id: [],
22 appId: [null, [Validators.required]],
23 newsDate: [null, [Validators.required]],
24 headline: [null, [Validators.required, Validators.maxLength(300)]],
25 content: [null, [Validators.required, Validators.maxLength(600)]],
26 link: [null, [Validators.required, Validators.maxLength(600)]],
27 publishDate: [],
28 createdBy: [],
29 createdDate: [],
30 lastModifiedBy: [],
31 lastModifiedDate: []
32 });
33
34 constructor(protected pieceOfNewsService: PieceOfNewsService, protected activatedRoute: ActivatedRoute, private fb: FormBuilder) {}
35
36 ngOnInit(): void {
37 this.activatedRoute.data.subscribe(({ pieceOfNews }) => {
38 if (!pieceOfNews.id) {
39 const today = moment().startOf('day');
40 pieceOfNews.newsDate = today;
41 pieceOfNews.publishDate = today;
42 pieceOfNews.createdDate = today;
43 pieceOfNews.lastModifiedDate = today;
44 }
45
46 this.updateForm(pieceOfNews);
47 });
48 }
49
50 updateForm(pieceOfNews: IPieceOfNews): void {
51 this.editForm.patchValue({
52 id: pieceOfNews.id,
53 appId: pieceOfNews.appId,
54 newsDate: pieceOfNews.newsDate ? pieceOfNews.newsDate.format(DATE_TIME_FORMAT) : null,
55 headline: pieceOfNews.headline,
56 content: pieceOfNews.content,
57 link: pieceOfNews.link,
58 publishDate: pieceOfNews.publishDate ? pieceOfNews.publishDate.format(DATE_TIME_FORMAT) : null,
59 createdBy: pieceOfNews.createdBy,
60 createdDate: pieceOfNews.createdDate ? pieceOfNews.createdDate.format(DATE_TIME_FORMAT) : null,
61 lastModifiedBy: pieceOfNews.lastModifiedBy,
62 lastModifiedDate: pieceOfNews.lastModifiedDate ? pieceOfNews.lastModifiedDate.format(DATE_TIME_FORMAT) : null
63 });
64 }
65
66 previousState(): void {
67 window.history.back();
68 }
69
70 save(): void {
71 this.isSaving = true;
72 const pieceOfNews = this.createFromForm();
73 if (pieceOfNews.id !== undefined) {
74 this.subscribeToSaveResponse(this.pieceOfNewsService.update(pieceOfNews));
75 } else {
76 this.subscribeToSaveResponse(this.pieceOfNewsService.create(pieceOfNews));
77 }
78 }
79
80 private createFromForm(): IPieceOfNews {
81 return {
82 ...new PieceOfNews(),
83 id: this.editForm.get(['id'])!.value,
84 appId: this.editForm.get(['appId'])!.value,
85 newsDate: this.editForm.get(['newsDate'])!.value ? moment(this.editForm.get(['newsDate'])!.value, DATE_TIME_FORMAT) : undefined,
86 headline: this.editForm.get(['headline'])!.value,
87 content: this.editForm.get(['content'])!.value,
88 link: this.editForm.get(['link'])!.value,
89 publishDate: this.editForm.get(['publishDate'])!.value
90 ? moment(this.editForm.get(['publishDate'])!.value, DATE_TIME_FORMAT)
91 : undefined,
92 createdBy: this.editForm.get(['createdBy'])!.value,
93 createdDate: this.editForm.get(['createdDate'])!.value
94 ? moment(this.editForm.get(['createdDate'])!.value, DATE_TIME_FORMAT)
95 : undefined,
96 lastModifiedBy: this.editForm.get(['lastModifiedBy'])!.value,
97 lastModifiedDate: this.editForm.get(['lastModifiedDate'])!.value
98 ? moment(this.editForm.get(['lastModifiedDate'])!.value, DATE_TIME_FORMAT)
99 : undefined
100 };
101 }
102
103 protected subscribeToSaveResponse(result: Observable<HttpResponse<IPieceOfNews>>): void {
104 result.subscribe(
105 () => this.onSaveSuccess(),
106 () => this.onSaveError()
107 );
108 }
109
110 protected onSaveSuccess(): void {
111 this.isSaving = false;
112 this.previousState();
113 }
114
115 protected onSaveError(): void {
116 this.isSaving = false;
117 }
118 }
File src/main/webapp/app/entities/piece-of-news/piece-of-news.component.html added (mode: 100644) (index 0000000..e48ac08)
1 <div>
2 <h2 id="page-heading">
3 <span jhiTranslate="honlapApp.pieceOfNews.home.title">Piece Of News</span>
4
5 <button id="jh-create-entity" class="btn btn-primary float-right jh-create-entity create-piece-of-news" [routerLink]="['/piece-of-news/new']">
6 <fa-icon icon="plus"></fa-icon>
7 <span jhiTranslate="honlapApp.pieceOfNews.home.createLabel">
8 Create a new Piece Of News
9 </span>
10 </button>
11 </h2>
12
13 <auth-alert-error></auth-alert-error>
14
15 <auth-alert></auth-alert>
16
17 <div class="alert alert-warning" id="no-result" *ngIf="pieceOfNews?.length === 0">
18 <span jhiTranslate="honlapApp.pieceOfNews.home.notFound">No pieceOfNews found</span>
19 </div>
20
21 <div class="table-responsive" id="entities" *ngIf="pieceOfNews?.length > 0">
22 <table class="table table-striped" aria-describedby="page-heading">
23 <thead>
24 <tr jhiSort [(predicate)]="predicate" [(ascending)]="ascending" [callback]="loadPage.bind(this)">
25 <th scope="col" jhiSortBy="id"><span jhiTranslate="global.field.id">ID</span> <fa-icon icon="sort"></fa-icon></th>
26 <th scope="col" jhiSortBy="appId"><span jhiTranslate="honlapApp.pieceOfNews.appId">App Id</span> <fa-icon icon="sort"></fa-icon></th>
27 <th scope="col" jhiSortBy="newsDate"><span jhiTranslate="honlapApp.pieceOfNews.newsDate">News Date</span> <fa-icon icon="sort"></fa-icon></th>
28 <th scope="col" jhiSortBy="headline"><span jhiTranslate="honlapApp.pieceOfNews.headline">Headline</span> <fa-icon icon="sort"></fa-icon></th>
29 <th scope="col" jhiSortBy="content"><span jhiTranslate="honlapApp.pieceOfNews.content">Content</span> <fa-icon icon="sort"></fa-icon></th>
30 <th scope="col" jhiSortBy="link"><span jhiTranslate="honlapApp.pieceOfNews.link">Link</span> <fa-icon icon="sort"></fa-icon></th>
31 <th scope="col" jhiSortBy="publishDate"><span jhiTranslate="honlapApp.pieceOfNews.publishDate">Publish Date</span> <fa-icon icon="sort"></fa-icon></th>
32 <th scope="col" jhiSortBy="createdBy"><span jhiTranslate="honlapApp.pieceOfNews.createdBy">Created By</span> <fa-icon icon="sort"></fa-icon></th>
33 <th scope="col" jhiSortBy="createdDate"><span jhiTranslate="honlapApp.pieceOfNews.createdDate">Created Date</span> <fa-icon icon="sort"></fa-icon></th>
34 <th scope="col" jhiSortBy="lastModifiedBy"><span jhiTranslate="honlapApp.pieceOfNews.lastModifiedBy">Last Modified By</span> <fa-icon icon="sort"></fa-icon></th>
35 <th scope="col" jhiSortBy="lastModifiedDate"><span jhiTranslate="honlapApp.pieceOfNews.lastModifiedDate">Last Modified Date</span> <fa-icon icon="sort"></fa-icon></th>
36 <th scope="col"></th>
37 </tr>
38 </thead>
39 <tbody>
40 <tr *ngFor="let pieceOfNews of pieceOfNews ;trackBy: trackId">
41 <td><a [routerLink]="['/piece-of-news', pieceOfNews.id, 'view']">{{ pieceOfNews.id }}</a></td>
42 <td>{{ pieceOfNews.appId }}</td>
43 <td>{{ pieceOfNews.newsDate | date:'medium' }}</td>
44 <td>{{ pieceOfNews.headline }}</td>
45 <td>{{ pieceOfNews.content }}</td>
46 <td>{{ pieceOfNews.link }}</td>
47 <td>{{ pieceOfNews.publishDate | date:'medium' }}</td>
48 <td>{{ pieceOfNews.createdBy }}</td>
49 <td>{{ pieceOfNews.createdDate | date:'medium' }}</td>
50 <td>{{ pieceOfNews.lastModifiedBy }}</td>
51 <td>{{ pieceOfNews.lastModifiedDate | date:'medium' }}</td>
52 <td class="text-right">
53 <div class="btn-group">
54 <button type="submit"
55 [routerLink]="['/piece-of-news', pieceOfNews.id, 'view']"
56 class="btn btn-info btn-sm">
57 <fa-icon icon="eye"></fa-icon>
58 <span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
59 </button>
60
61 <button type="submit"
62 [routerLink]="['/piece-of-news', pieceOfNews.id, 'edit']"
63 class="btn btn-primary btn-sm">
64 <fa-icon icon="pencil-alt"></fa-icon>
65 <span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
66 </button>
67
68 <button type="submit" (click)="delete(pieceOfNews)"
69 class="btn btn-danger btn-sm">
70 <fa-icon icon="times"></fa-icon>
71 <span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
72 </button>
73 </div>
74 </td>
75 </tr>
76 </tbody>
77 </table>
78 </div>
79
80 <div *ngIf="pieceOfNews?.length > 0">
81 <div class="row justify-content-center">
82 <jhi-item-count [page]="page" [total]="totalItems" [itemsPerPage]="itemsPerPage"></jhi-item-count>
83 </div>
84
85 <div class="row justify-content-center">
86 <ngb-pagination [collectionSize]="totalItems" [(page)]="ngbPaginationPage" [pageSize]="itemsPerPage" [maxSize]="5" [rotate]="true" [boundaryLinks]="true" (pageChange)="loadPage($event)"></ngb-pagination>
87 </div>
88 </div>
89 </div>
File src/main/webapp/app/entities/piece-of-news/piece-of-news.component.ts added (mode: 100644) (index 0000000..c6f927e)
1 import { Component, OnInit, OnDestroy } from '@angular/core';
2 import { HttpHeaders, HttpResponse } from '@angular/common/http';
3 import { ActivatedRoute, Router } from '@angular/router';
4 import { Subscription } from 'rxjs';
5 import { JhiEventManager } from 'ng-jhipster';
6 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
7
8 import { IPieceOfNews } from 'app/shared/model/piece-of-news.model';
9
10 import { ITEMS_PER_PAGE } from 'app/shared/constants/pagination.constants';
11 import { PieceOfNewsService } from './piece-of-news.service';
12 import { PieceOfNewsDeleteDialogComponent } from './piece-of-news-delete-dialog.component';
13
14 @Component({
15 selector: 'auth-piece-of-news',
16 templateUrl: './piece-of-news.component.html'
17 })
18 export class PieceOfNewsComponent implements OnInit, OnDestroy {
19 pieceOfNews?: IPieceOfNews[];
20 eventSubscriber?: Subscription;
21 totalItems = 0;
22 itemsPerPage = ITEMS_PER_PAGE;
23 page!: number;
24 predicate!: string;
25 ascending!: boolean;
26 ngbPaginationPage = 1;
27
28 constructor(
29 protected pieceOfNewsService: PieceOfNewsService,
30 protected activatedRoute: ActivatedRoute,
31 protected router: Router,
32 protected eventManager: JhiEventManager,
33 protected modalService: NgbModal
34 ) {}
35
36 loadPage(page?: number): void {
37 const pageToLoad: number = page || this.page;
38
39 this.pieceOfNewsService
40 .query({
41 page: pageToLoad - 1,
42 size: this.itemsPerPage,
43 sort: this.sort()
44 })
45 .subscribe(
46 (res: HttpResponse<IPieceOfNews[]>) => this.onSuccess(res.body, res.headers, pageToLoad),
47 () => this.onError()
48 );
49 }
50
51 ngOnInit(): void {
52 this.activatedRoute.data.subscribe(data => {
53 this.page = data.pagingParams.page;
54 this.ascending = data.pagingParams.ascending;
55 this.predicate = data.pagingParams.predicate;
56 this.ngbPaginationPage = data.pagingParams.page;
57 this.loadPage();
58 });
59 this.registerChangeInPieceOfNews();
60 }
61
62 ngOnDestroy(): void {
63 if (this.eventSubscriber) {
64 this.eventManager.destroy(this.eventSubscriber);
65 }
66 }
67
68 trackId(index: number, item: IPieceOfNews): number {
69 // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
70 return item.id!;
71 }
72
73 registerChangeInPieceOfNews(): void {
74 this.eventSubscriber = this.eventManager.subscribe('pieceOfNewsListModification', () => this.loadPage());
75 }
76
77 delete(pieceOfNews: IPieceOfNews): void {
78 const modalRef = this.modalService.open(PieceOfNewsDeleteDialogComponent, { size: 'lg', backdrop: 'static' });
79 modalRef.componentInstance.pieceOfNews = pieceOfNews;
80 }
81
82 sort(): string[] {
83 const result = [this.predicate + ',' + (this.ascending ? 'asc' : 'desc')];
84 if (this.predicate !== 'id') {
85 result.push('id');
86 }
87 return result;
88 }
89
90 protected onSuccess(data: IPieceOfNews[] | null, headers: HttpHeaders, page: number): void {
91 this.totalItems = Number(headers.get('X-Total-Count'));
92 this.page = page;
93 this.router.navigate(['/piece-of-news'], {
94 queryParams: {
95 page: this.page,
96 size: this.itemsPerPage,
97 sort: this.predicate + ',' + (this.ascending ? 'asc' : 'desc')
98 }
99 });
100 this.pieceOfNews = data || [];
101 }
102
103 protected onError(): void {
104 this.ngbPaginationPage = this.page;
105 }
106 }
File src/main/webapp/app/entities/piece-of-news/piece-of-news.module.ts added (mode: 100644) (index 0000000..4e90026)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3
4 import { HonlapSharedModule } from 'app/shared/shared.module';
5 import { PieceOfNewsComponent } from './piece-of-news.component';
6 import { PieceOfNewsDetailComponent } from './piece-of-news-detail.component';
7 import { PieceOfNewsUpdateComponent } from './piece-of-news-update.component';
8 import { PieceOfNewsDeleteDialogComponent } from './piece-of-news-delete-dialog.component';
9 import { pieceOfNewsRoute } from './piece-of-news.route';
10
11 @NgModule({
12 imports: [HonlapSharedModule, RouterModule.forChild(pieceOfNewsRoute)],
13 declarations: [PieceOfNewsComponent, PieceOfNewsDetailComponent, PieceOfNewsUpdateComponent, PieceOfNewsDeleteDialogComponent],
14 entryComponents: [PieceOfNewsDeleteDialogComponent]
15 })
16 export class HonlapPieceOfNewsModule {}
File src/main/webapp/app/entities/piece-of-news/piece-of-news.route.ts added (mode: 100644) (index 0000000..fdc8d76)
1 import { Injectable } from '@angular/core';
2 import { HttpResponse } from '@angular/common/http';
3 import { Resolve, ActivatedRouteSnapshot, Routes, Router } from '@angular/router';
4 import { JhiResolvePagingParams } from 'ng-jhipster';
5 import { Observable, of, EMPTY } from 'rxjs';
6 import { flatMap } from 'rxjs/operators';
7
8 import { Authority } from 'app/shared/constants/authority.constants';
9 import { UserRouteAccessService } from 'app/core/auth/user-route-access-service';
10 import { IPieceOfNews, PieceOfNews } from 'app/shared/model/piece-of-news.model';
11 import { PieceOfNewsService } from './piece-of-news.service';
12 import { PieceOfNewsComponent } from './piece-of-news.component';
13 import { PieceOfNewsDetailComponent } from './piece-of-news-detail.component';
14 import { PieceOfNewsUpdateComponent } from './piece-of-news-update.component';
15
16 @Injectable({ providedIn: 'root' })
17 export class PieceOfNewsResolve implements Resolve<IPieceOfNews> {
18 constructor(private service: PieceOfNewsService, private router: Router) {}
19
20 resolve(route: ActivatedRouteSnapshot): Observable<IPieceOfNews> | Observable<never> {
21 const id = route.params['id'];
22 if (id) {
23 return this.service.find(id).pipe(
24 flatMap((pieceOfNews: HttpResponse<PieceOfNews>) => {
25 if (pieceOfNews.body) {
26 return of(pieceOfNews.body);
27 } else {
28 this.router.navigate(['404']);
29 return EMPTY;
30 }
31 })
32 );
33 }
34 return of(new PieceOfNews());
35 }
36 }
37
38 export const pieceOfNewsRoute: Routes = [
39 {
40 path: '',
41 component: PieceOfNewsComponent,
42 resolve: {
43 pagingParams: JhiResolvePagingParams
44 },
45 data: {
46 authorities: [Authority.USER],
47 defaultSort: 'id,asc',
48 pageTitle: 'honlapApp.pieceOfNews.home.title'
49 },
50 canActivate: [UserRouteAccessService]
51 },
52 {
53 path: ':id/view',
54 component: PieceOfNewsDetailComponent,
55 resolve: {
56 pieceOfNews: PieceOfNewsResolve
57 },
58 data: {
59 authorities: [Authority.USER],
60 pageTitle: 'honlapApp.pieceOfNews.home.title'
61 },
62 canActivate: [UserRouteAccessService]
63 },
64 {
65 path: 'new',
66 component: PieceOfNewsUpdateComponent,
67 resolve: {
68 pieceOfNews: PieceOfNewsResolve
69 },
70 data: {
71 authorities: [Authority.USER],
72 pageTitle: 'honlapApp.pieceOfNews.home.title'
73 },
74 canActivate: [UserRouteAccessService]
75 },
76 {
77 path: ':id/edit',
78 component: PieceOfNewsUpdateComponent,
79 resolve: {
80 pieceOfNews: PieceOfNewsResolve
81 },
82 data: {
83 authorities: [Authority.USER],
84 pageTitle: 'honlapApp.pieceOfNews.home.title'
85 },
86 canActivate: [UserRouteAccessService]
87 }
88 ];
File src/main/webapp/app/entities/piece-of-news/piece-of-news.service.ts added (mode: 100644) (index 0000000..3c460b2)
1 import { Injectable } from '@angular/core';
2 import { HttpClient, HttpResponse } from '@angular/common/http';
3 import { Observable } from 'rxjs';
4 import { map } from 'rxjs/operators';
5 import * as moment from 'moment';
6
7 import { SERVER_API_URL } from 'app/app.constants';
8 import { createRequestOption } from 'app/shared/util/request-util';
9 import { IPieceOfNews } from 'app/shared/model/piece-of-news.model';
10
11 type EntityResponseType = HttpResponse<IPieceOfNews>;
12 type EntityArrayResponseType = HttpResponse<IPieceOfNews[]>;
13
14 @Injectable({ providedIn: 'root' })
15 export class PieceOfNewsService {
16 public resourceUrl = SERVER_API_URL + 'api/piece-of-news';
17
18 constructor(protected http: HttpClient) {}
19
20 create(pieceOfNews: IPieceOfNews): Observable<EntityResponseType> {
21 const copy = this.convertDateFromClient(pieceOfNews);
22 return this.http
23 .post<IPieceOfNews>(this.resourceUrl, copy, { observe: 'response' })
24 .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
25 }
26
27 update(pieceOfNews: IPieceOfNews): Observable<EntityResponseType> {
28 const copy = this.convertDateFromClient(pieceOfNews);
29 return this.http
30 .put<IPieceOfNews>(this.resourceUrl, copy, { observe: 'response' })
31 .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
32 }
33
34 find(id: number): Observable<EntityResponseType> {
35 return this.http
36 .get<IPieceOfNews>(`${this.resourceUrl}/${id}`, { observe: 'response' })
37 .pipe(map((res: EntityResponseType) => this.convertDateFromServer(res)));
38 }
39
40 query(req?: any): Observable<EntityArrayResponseType> {
41 const options = createRequestOption(req);
42 return this.http
43 .get<IPieceOfNews[]>(this.resourceUrl, { params: options, observe: 'response' })
44 .pipe(map((res: EntityArrayResponseType) => this.convertDateArrayFromServer(res)));
45 }
46
47 delete(id: number): Observable<HttpResponse<{}>> {
48 return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response' });
49 }
50
51 protected convertDateFromClient(pieceOfNews: IPieceOfNews): IPieceOfNews {
52 const copy: IPieceOfNews = Object.assign({}, pieceOfNews, {
53 newsDate: pieceOfNews.newsDate && pieceOfNews.newsDate.isValid() ? pieceOfNews.newsDate.toJSON() : undefined,
54 publishDate: pieceOfNews.publishDate && pieceOfNews.publishDate.isValid() ? pieceOfNews.publishDate.toJSON() : undefined,
55 createdDate: pieceOfNews.createdDate && pieceOfNews.createdDate.isValid() ? pieceOfNews.createdDate.toJSON() : undefined,
56 lastModifiedDate:
57 pieceOfNews.lastModifiedDate && pieceOfNews.lastModifiedDate.isValid() ? pieceOfNews.lastModifiedDate.toJSON() : undefined
58 });
59 return copy;
60 }
61
62 protected convertDateFromServer(res: EntityResponseType): EntityResponseType {
63 if (res.body) {
64 res.body.newsDate = res.body.newsDate ? moment(res.body.newsDate) : undefined;
65 res.body.publishDate = res.body.publishDate ? moment(res.body.publishDate) : undefined;
66 res.body.createdDate = res.body.createdDate ? moment(res.body.createdDate) : undefined;
67 res.body.lastModifiedDate = res.body.lastModifiedDate ? moment(res.body.lastModifiedDate) : undefined;
68 }
69 return res;
70 }
71
72 protected convertDateArrayFromServer(res: EntityArrayResponseType): EntityArrayResponseType {
73 if (res.body) {
74 res.body.forEach((pieceOfNews: IPieceOfNews) => {
75 pieceOfNews.newsDate = pieceOfNews.newsDate ? moment(pieceOfNews.newsDate) : undefined;
76 pieceOfNews.publishDate = pieceOfNews.publishDate ? moment(pieceOfNews.publishDate) : undefined;
77 pieceOfNews.createdDate = pieceOfNews.createdDate ? moment(pieceOfNews.createdDate) : undefined;
78 pieceOfNews.lastModifiedDate = pieceOfNews.lastModifiedDate ? moment(pieceOfNews.lastModifiedDate) : undefined;
79 });
80 }
81 return res;
82 }
83 }
File src/main/webapp/app/home/home.component.html added (mode: 100644) (index 0000000..0f54094)
1 <div class="row">
2 <div class="col-md-3">
3 <span class="hipster img-fluid rounded"></span>
4 </div>
5
6 <div class="col-md-9">
7 <h1 class="display-4" jhiTranslate="home.title">Welcome, Java Hipster!</h1>
8
9 <p class="lead" jhiTranslate="home.subtitle">This is your homepage</p>
10
11 <div [ngSwitch]="isAuthenticated()">
12 <div class="alert alert-success" *ngSwitchCase="true">
13 <span id="home-logged-message" *ngIf="account" jhiTranslate="home.logged.message"
14 [translateValues]="{ username: account.login }">You are logged in as user "{{ account.login }}".</span>
15 </div>
16
17 <div class="alert alert-warning" *ngSwitchCase="false">
18 <span jhiTranslate="global.messages.info.authenticated.prefix">If you want to </span>
19 <a class="alert-link" (click)="login()" jhiTranslate="global.messages.info.authenticated.link">sign in</a><span jhiTranslate="global.messages.info.authenticated.suffix">, you can try the default accounts:<br/>- Administrator (login="admin" and password="admin") <br/>- User (login="user" and password="user").</span>
20 </div>
21
22 <div class="alert alert-warning" *ngSwitchCase="false">
23 <span jhiTranslate="global.messages.info.register.noaccount">You don't have an account yet?</span>&nbsp;
24 <a class="alert-link" routerLink="account/register" jhiTranslate="global.messages.info.register.link">Register a new account</a>
25 </div>
26 </div>
27
28 <p jhiTranslate="home.question">
29 If you have any question on JHipster:
30 </p>
31
32 <ul>
33 <li><a href="https://www.jhipster.tech/" target="_blank" rel="noopener noreferrer" jhiTranslate="home.link.homepage">JHipster homepage</a></li>
34 <li><a href="http://stackoverflow.com/tags/jhipster/info" target="_blank" rel="noopener noreferrer" jhiTranslate="home.link.stackoverflow">JHipster on Stack Overflow</a></li>
35 <li><a href="https://github.com/jhipster/generator-jhipster/issues?state=open" target="_blank" rel="noopener noreferrer" jhiTranslate="home.link.bugtracker">JHipster bug tracker</a></li>
36 <li><a href="https://gitter.im/jhipster/generator-jhipster" target="_blank" rel="noopener noreferrer" jhiTranslate="home.link.chat">JHipster public chat room</a></li>
37 <li><a href="https://twitter.com/jhipster" target="_blank" rel="noopener noreferrer" jhiTranslate="home.link.follow">follow @jhipster on Twitter</a></li>
38 </ul>
39
40 <p>
41 <span jhiTranslate="home.like">If you like JHipster, don't forget to give us a star on</span> <a href="https://github.com/jhipster/generator-jhipster" target="_blank" rel="noopener noreferrer" jhiTranslate="home.github">GitHub</a>!
42 </p>
43 </div>
44 </div>
File src/main/webapp/app/home/home.component.ts added (mode: 100644) (index 0000000..9ef01af)
1 import { Component, OnInit, OnDestroy } from '@angular/core';
2 import { Subscription } from 'rxjs';
3
4 import { LoginModalService } from 'app/core/login/login-modal.service';
5 import { AccountService } from 'app/core/auth/account.service';
6 import { Account } from 'app/core/user/account.model';
7
8 @Component({
9 selector: 'auth-home',
10 templateUrl: './home.component.html',
11 styleUrls: ['home.scss']
12 })
13 export class HomeComponent implements OnInit, OnDestroy {
14 account: Account | null = null;
15 authSubscription?: Subscription;
16
17 constructor(private accountService: AccountService, private loginModalService: LoginModalService) {}
18
19 ngOnInit(): void {
20 this.authSubscription = this.accountService.getAuthenticationState().subscribe(account => (this.account = account));
21 }
22
23 isAuthenticated(): boolean {
24 return this.accountService.isAuthenticated();
25 }
26
27 login(): void {
28 this.loginModalService.open();
29 }
30
31 ngOnDestroy(): void {
32 if (this.authSubscription) {
33 this.authSubscription.unsubscribe();
34 }
35 }
36 }
File src/main/webapp/app/home/home.module.ts added (mode: 100644) (index 0000000..70efe12)
1 import { NgModule } from '@angular/core';
2 import { RouterModule } from '@angular/router';
3
4 import { HonlapSharedModule } from 'app/shared/shared.module';
5 import { HOME_ROUTE } from './home.route';
6 import { HomeComponent } from './home.component';
7
8 @NgModule({
9 imports: [HonlapSharedModule, RouterModule.forChild([HOME_ROUTE])],
10 declarations: [HomeComponent]
11 })
12 export class HonlapHomeModule {}
File src/main/webapp/app/home/home.route.ts added (mode: 100644) (index 0000000..aefa2b7)
1 import { Route } from '@angular/router';
2
3 import { HomeComponent } from './home.component';
4
5 export const HOME_ROUTE: Route = {
6 path: '',
7 component: HomeComponent,
8 data: {
9 authorities: [],
10 pageTitle: 'home.title'
11 }
12 };
File src/main/webapp/app/home/home.scss added (mode: 100644) (index 0000000..c731f12)
1 /* ==========================================================================
2 Main page styles
3 ========================================================================== */
4
5 .hipster {
6 display: inline-block;
7 width: 347px;
8 height: 497px;
9 background: url('../../content/images/jhipster_family_member_0.svg') no-repeat center top;
10 background-size: contain;
11 }
12
13 /* wait autoprefixer update to allow simple generation of high pixel density media query */
14 @media only screen and (-webkit-min-device-pixel-ratio: 2),
15 only screen and (-moz-min-device-pixel-ratio: 2),
16 only screen and (-o-min-device-pixel-ratio: 2/1),
17 only screen and (min-resolution: 192dpi),
18 only screen and (min-resolution: 2dppx) {
19 .hipster {
20 background: url('../../content/images/jhipster_family_member_0.svg') no-repeat center top;
21 background-size: contain;
22 }
23 }
File src/main/webapp/app/layouts/error/error.component.html added (mode: 100644) (index 0000000..b51ae9d)
1 <div>
2 <div class="row">
3 <div class="col-md-4">
4 <span class="hipster img-fluid rounded"></span>
5 </div>
6
7 <div class="col-md-8">
8 <h1 jhiTranslate="error.title">Error Page!</h1>
9
10 <div *ngIf="errorMessage">
11 <div class="alert alert-danger">{{ errorMessage }}</div>
12 </div>
13 </div>
14 </div>
15 </div>
File src/main/webapp/app/layouts/error/error.component.ts added (mode: 100644) (index 0000000..133a96b)
1 import { Component, OnInit, OnDestroy } from '@angular/core';
2 import { ActivatedRoute } from '@angular/router';
3 import { Subscription } from 'rxjs';
4 import { TranslateService } from '@ngx-translate/core';
5
6 @Component({
7 selector: 'auth-error',
8 templateUrl: './error.component.html'
9 })
10 export class ErrorComponent implements OnInit, OnDestroy {
11 errorMessage?: string;
12 errorKey?: string;
13 langChangeSubscription?: Subscription;
14
15 constructor(private translateService: TranslateService, private route: ActivatedRoute) {}
16
17 ngOnInit(): void {
18 this.route.data.subscribe(routeData => {
19 if (routeData.errorMessage) {
20 this.errorKey = routeData.errorMessage;
21 this.getErrorMessageTranslation();
22 this.langChangeSubscription = this.translateService.onLangChange.subscribe(() => this.getErrorMessageTranslation());
23 }
24 });
25 }
26
27 ngOnDestroy(): void {
28 if (this.langChangeSubscription) {
29 this.langChangeSubscription.unsubscribe();
30 }
31 }
32
33 private getErrorMessageTranslation(): void {
34 this.errorMessage = '';
35 if (this.errorKey) {
36 this.translateService.get(this.errorKey).subscribe(translatedErrorMessage => (this.errorMessage = translatedErrorMessage));
37 }
38 }
39 }
File src/main/webapp/app/layouts/error/error.route.ts added (mode: 100644) (index 0000000..4828cc7)
1 import { Routes } from '@angular/router';
2
3 import { ErrorComponent } from './error.component';
4
5 export const errorRoute: Routes = [
6 {
7 path: 'error',
8 component: ErrorComponent,
9 data: {
10 authorities: [],
11 pageTitle: 'error.title'
12 }
13 },
14 {
15 path: 'accessdenied',
16 component: ErrorComponent,
17 data: {
18 authorities: [],
19 pageTitle: 'error.title',
20 errorMessage: 'error.http.403'
21 }
22 },
23 {
24 path: '404',
25 component: ErrorComponent,
26 data: {
27 authorities: [],
28 pageTitle: 'error.title',
29 errorMessage: 'error.http.404'
30 }
31 },
32 {
33 path: '**',
34 redirectTo: '/404'
35 }
36 ];
File src/main/webapp/app/layouts/footer/footer.component.html added (mode: 100644) (index 0000000..9312ad0)
1 <div class="footer">
2 <p jhiTranslate="footer">This is your footer</p>
3 </div>
File src/main/webapp/app/layouts/footer/footer.component.ts added (mode: 100644) (index 0000000..53c8dde)
1 import { Component } from '@angular/core';
2
3 @Component({
4 selector: 'auth-footer',
5 templateUrl: './footer.component.html'
6 })
7 export class FooterComponent {}
File src/main/webapp/app/layouts/main/main.component.html added (mode: 100644) (index 0000000..fce6a43)
1 <auth-page-ribbon></auth-page-ribbon>
2
3 <div>
4 <router-outlet name="navbar"></router-outlet>
5 </div>
6
7 <div class="container-fluid">
8 <div class="card jh-card">
9 <router-outlet></router-outlet>
10 </div>
11
12 <auth-footer></auth-footer>
13 </div>
File src/main/webapp/app/layouts/main/main.component.ts added (mode: 100644) (index 0000000..3c791eb)
1 import { Component, OnInit, RendererFactory2, Renderer2 } from '@angular/core';
2 import { Title } from '@angular/platform-browser';
3 import { Router, ActivatedRouteSnapshot, NavigationEnd, NavigationError } from '@angular/router';
4 import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
5
6 import { AccountService } from 'app/core/auth/account.service';
7
8 @Component({
9 selector: 'auth-main',
10 templateUrl: './main.component.html'
11 })
12 export class MainComponent implements OnInit {
13 private renderer: Renderer2;
14
15 constructor(
16 private accountService: AccountService,
17 private titleService: Title,
18 private router: Router,
19 private translateService: TranslateService,
20 rootRenderer: RendererFactory2
21 ) {
22 this.renderer = rootRenderer.createRenderer(document.querySelector('html'), null);
23 }
24
25 ngOnInit(): void {
26 // try to log in automatically
27 this.accountService.identity().subscribe();
28
29 this.router.events.subscribe(event => {
30 if (event instanceof NavigationEnd) {
31 this.updateTitle();
32 }
33 if (event instanceof NavigationError && event.error.status === 404) {
34 this.router.navigate(['/404']);
35 }
36 });
37
38 this.translateService.onLangChange.subscribe((langChangeEvent: LangChangeEvent) => {
39 this.updateTitle();
40
41 this.renderer.setAttribute(document.querySelector('html'), 'lang', langChangeEvent.lang);
42 });
43 }
44
45 private getPageTitle(routeSnapshot: ActivatedRouteSnapshot): string {
46 let title: string = routeSnapshot.data && routeSnapshot.data['pageTitle'] ? routeSnapshot.data['pageTitle'] : '';
47 if (routeSnapshot.firstChild) {
48 title = this.getPageTitle(routeSnapshot.firstChild) || title;
49 }
50 return title;
51 }
52
53 private updateTitle(): void {
54 let pageTitle = this.getPageTitle(this.router.routerState.snapshot.root);
55 if (!pageTitle) {
56 pageTitle = 'global.title';
57 }
58 this.translateService.get(pageTitle).subscribe(title => this.titleService.setTitle(title));
59 }
60 }
File src/main/webapp/app/layouts/navbar/active-menu.directive.ts added (mode: 100644) (index 0000000..5915bd8)
1 import { Directive, OnInit, ElementRef, Renderer2, Input } from '@angular/core';
2 import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
3
4 @Directive({
5 selector: '[authActiveMenu]'
6 })
7 export class ActiveMenuDirective implements OnInit {
8 @Input() authActiveMenu?: string;
9
10 constructor(private el: ElementRef, private renderer: Renderer2, private translateService: TranslateService) {}
11
12 ngOnInit(): void {
13 this.translateService.onLangChange.subscribe((event: LangChangeEvent) => {
14 this.updateActiveFlag(event.lang);
15 });
16
17 this.updateActiveFlag(this.translateService.currentLang);
18 }
19
20 updateActiveFlag(selectedLanguage: string): void {
21 if (this.authActiveMenu === selectedLanguage) {
22 this.renderer.addClass(this.el.nativeElement, 'active');
23 } else {
24 this.renderer.removeClass(this.el.nativeElement, 'active');
25 }
26 }
27 }
File src/main/webapp/app/layouts/navbar/navbar.component.html added (mode: 100644) (index 0000000..4375f3f)
1 <nav class="navbar navbar-dark navbar-expand-md bg-dark">
2 <a class="navbar-brand logo" routerLink="/" (click)="collapseNavbar()">
3 <span class="logo-img"></span>
4 <span jhiTranslate="global.title" class="navbar-title">Honlap</span> <span class="navbar-version">{{ version }}</span>
5 </a>
6 <a class="navbar-toggler d-lg-none" href="javascript:void(0);" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation" (click)="toggleNavbar()">
7 <fa-icon icon="bars"></fa-icon>
8 </a>
9 <div class="navbar-collapse collapse" id="navbarResponsive" [ngbCollapse]="isNavbarCollapsed" [ngSwitch]="isAuthenticated()">
10 <ul class="navbar-nav ml-auto">
11 <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
12 <a class="nav-link" routerLink="/" (click)="collapseNavbar()">
13 <span>
14 <fa-icon icon="home"></fa-icon>
15 <span jhiTranslate="global.menu.home">Home</span>
16 </span>
17 </a>
18 </li>
19 <!-- jhipster-needle-add-element-to-menu - JHipster will add new menu items here -->
20 <li *ngSwitchCase="true" ngbDropdown class="nav-item dropdown pointer" display="dynamic" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
21 <a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="entity-menu">
22 <span>
23 <fa-icon icon="th-list"></fa-icon>
24 <span jhiTranslate="global.menu.entities.main">
25 Entities
26 </span>
27 </span>
28 </a>
29 <ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="entity-menu">
30 <li>
31 <a class="dropdown-item" routerLink="piece-of-news" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }" (click)="collapseNavbar()">
32 <fa-icon icon="asterisk" fixedWidth="true"></fa-icon>
33 <span jhiTranslate="global.menu.entities.pieceOfNews">Piece Of News</span>
34 </a>
35 </li>
36 <!-- jhipster-needle-add-entity-to-menu - JHipster will add entities to the menu here -->
37 </ul>
38 </li>
39 <li *authHasAnyAuthority="'ROLE_ADMIN'" ngbDropdown class="nav-item dropdown pointer" display="dynamic" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
40 <a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="admin-menu">
41 <span>
42 <fa-icon icon="user-plus"></fa-icon>
43 <span jhiTranslate="global.menu.admin.main">Administration</span>
44 </span>
45 </a>
46 <ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="admin-menu">
47 <li>
48 <a class="dropdown-item" routerLink="admin/user-management" routerLinkActive="active" (click)="collapseNavbar()">
49 <fa-icon icon="user" fixedWidth="true"></fa-icon>
50 <span jhiTranslate="global.menu.admin.userManagement">User management</span>
51 </a>
52 </li>
53 <li>
54 <a class="dropdown-item" routerLink="admin/metrics" routerLinkActive="active" (click)="collapseNavbar()">
55 <fa-icon icon="tachometer-alt" fixedWidth="true"></fa-icon>
56 <span jhiTranslate="global.menu.admin.metrics">Metrics</span>
57 </a>
58 </li>
59 <li>
60 <a class="dropdown-item" routerLink="admin/health" routerLinkActive="active" (click)="collapseNavbar()">
61 <fa-icon icon="heart" fixedWidth="true"></fa-icon>
62 <span jhiTranslate="global.menu.admin.health">Health</span>
63 </a>
64 </li>
65 <li>
66 <a class="dropdown-item" routerLink="admin/configuration" routerLinkActive="active" (click)="collapseNavbar()">
67 <fa-icon icon="list" fixedWidth="true"></fa-icon>
68 <span jhiTranslate="global.menu.admin.configuration">Configuration</span>
69 </a>
70 </li>
71 <li>
72 <a class="dropdown-item" routerLink="admin/audits" routerLinkActive="active" (click)="collapseNavbar()">
73 <fa-icon icon="bell" fixedWidth="true"></fa-icon>
74 <span jhiTranslate="global.menu.admin.audits">Audits</span>
75 </a>
76 </li>
77 <li>
78 <a class="dropdown-item" routerLink="admin/logs" routerLinkActive="active" (click)="collapseNavbar()">
79 <fa-icon icon="tasks" fixedWidth="true"></fa-icon>
80 <span jhiTranslate="global.menu.admin.logs">Logs</span>
81 </a>
82 </li>
83 <li *ngIf="swaggerEnabled">
84 <a class="dropdown-item" routerLink="admin/docs" routerLinkActive="active" (click)="collapseNavbar()">
85 <fa-icon icon="book" fixedWidth="true"></fa-icon>
86 <span jhiTranslate="global.menu.admin.apidocs">API</span>
87 </a>
88 </li>
89 <!-- jhipster-needle-add-element-to-admin-menu - JHipster will add entities to the admin menu here -->
90 <li *ngIf="!inProduction">
91 <a class="dropdown-item" href='./h2-console' target="_tab" (click)="collapseNavbar()">
92 <fa-icon icon="hdd" fixedWidth="true"></fa-icon>
93 <span jhiTranslate="global.menu.admin.database">Database</span>
94 </a>
95 </li>
96 </ul>
97 </li>
98 <li ngbDropdown class="nav-item dropdown pointer" display="dynamic" *ngIf="languages && languages.length > 1">
99 <a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="languagesnavBarDropdown">
100 <span>
101 <fa-icon icon="flag"></fa-icon>
102 <span jhiTranslate="global.menu.language">Language</span>
103 </span>
104 </a>
105 <ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="languagesnavBarDropdown">
106 <li *ngFor="let language of languages">
107 <a class="dropdown-item" [authActiveMenu]="language" href="javascript:void(0);" (click)="changeLanguage(language);collapseNavbar();">{{ language | findLanguageFromKey }}</a>
108 </li>
109 </ul>
110 </li>
111 <li ngbDropdown class="nav-item dropdown pointer" display="dynamic" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
112 <a class="nav-link dropdown-toggle" ngbDropdownToggle href="javascript:void(0);" id="account-menu">
113 <span *ngIf="!getImageUrl()">
114 <fa-icon icon="user"></fa-icon>
115 <span jhiTranslate="global.menu.account.main">
116 Account
117 </span>
118 </span>
119 <span *ngIf="getImageUrl()">
120 <img [src]="getImageUrl()" class="profile-image rounded-circle" alt="Avatar">
121 </span>
122 </a>
123 <ul class="dropdown-menu" ngbDropdownMenu aria-labelledby="account-menu">
124 <li *ngSwitchCase="true">
125 <a class="dropdown-item" routerLink="account/settings" routerLinkActive="active" (click)="collapseNavbar()">
126 <fa-icon icon="wrench" fixedWidth="true"></fa-icon>
127 <span jhiTranslate="global.menu.account.settings">Settings</span>
128 </a>
129 </li>
130 <li *ngSwitchCase="true">
131 <a class="dropdown-item" routerLink="account/password" routerLinkActive="active" (click)="collapseNavbar()">
132 <fa-icon icon="lock" fixedWidth="true"></fa-icon>
133 <span jhiTranslate="global.menu.account.password">Password</span>
134 </a>
135 </li>
136 <li *ngSwitchCase="true">
137 <a class="dropdown-item" (click)="logout()" id="logout">
138 <fa-icon icon="sign-out-alt" fixedWidth="true"></fa-icon>
139 <span jhiTranslate="global.menu.account.logout">Sign out</span>
140 </a>
141 </li>
142 <li *ngSwitchCase="false">
143 <a class="dropdown-item" (click)="login()" id="login">
144 <fa-icon icon="sign-in-alt" fixedWidth="true"></fa-icon>
145 <span jhiTranslate="global.menu.account.login">Sign in</span>
146 </a>
147 </li>
148 <li *ngSwitchCase="false">
149 <a class="dropdown-item" routerLink="account/register" routerLinkActive="active" (click)="collapseNavbar()">
150 <fa-icon icon="user-plus" fixedWidth="true"></fa-icon>
151 <span jhiTranslate="global.menu.account.register">Register</span>
152 </a>
153 </li>
154 </ul>
155 </li>
156 </ul>
157 </div>
158 </nav>
File src/main/webapp/app/layouts/navbar/navbar.component.ts added (mode: 100644) (index 0000000..93f7f08)
1 import { Component, OnInit } from '@angular/core';
2 import { Router } from '@angular/router';
3 import { JhiLanguageService } from 'ng-jhipster';
4 import { SessionStorageService } from 'ngx-webstorage';
5
6 import { VERSION } from 'app/app.constants';
7 import { LANGUAGES } from 'app/core/language/language.constants';
8 import { AccountService } from 'app/core/auth/account.service';
9 import { LoginModalService } from 'app/core/login/login-modal.service';
10 import { LoginService } from 'app/core/login/login.service';
11 import { ProfileService } from 'app/layouts/profiles/profile.service';
12
13 @Component({
14 selector: 'auth-navbar',
15 templateUrl: './navbar.component.html',
16 styleUrls: ['navbar.scss']
17 })
18 export class NavbarComponent implements OnInit {
19 inProduction?: boolean;
20 isNavbarCollapsed = true;
21 languages = LANGUAGES;
22 swaggerEnabled?: boolean;
23 version: string;
24
25 constructor(
26 private loginService: LoginService,
27 private languageService: JhiLanguageService,
28 private sessionStorage: SessionStorageService,
29 private accountService: AccountService,
30 private loginModalService: LoginModalService,
31 private profileService: ProfileService,
32 private router: Router
33 ) {
34 this.version = VERSION ? (VERSION.toLowerCase().startsWith('v') ? VERSION : 'v' + VERSION) : '';
35 }
36
37 ngOnInit(): void {
38 this.profileService.getProfileInfo().subscribe(profileInfo => {
39 this.inProduction = profileInfo.inProduction;
40 this.swaggerEnabled = profileInfo.swaggerEnabled;
41 });
42 }
43
44 changeLanguage(languageKey: string): void {
45 this.sessionStorage.store('locale', languageKey);
46 this.languageService.changeLanguage(languageKey);
47 }
48
49 collapseNavbar(): void {
50 this.isNavbarCollapsed = true;
51 }
52
53 isAuthenticated(): boolean {
54 return this.accountService.isAuthenticated();
55 }
56
57 login(): void {
58 this.loginModalService.open();
59 }
60
61 logout(): void {
62 this.collapseNavbar();
63 this.loginService.logout();
64 this.router.navigate(['']);
65 }
66
67 toggleNavbar(): void {
68 this.isNavbarCollapsed = !this.isNavbarCollapsed;
69 }
70
71 getImageUrl(): string {
72 return this.isAuthenticated() ? this.accountService.getImageUrl() : '';
73 }
74 }
File src/main/webapp/app/layouts/navbar/navbar.route.ts added (mode: 100644) (index 0000000..3519143)
1 import { Route } from '@angular/router';
2
3 import { NavbarComponent } from './navbar.component';
4
5 export const navbarRoute: Route = {
6 path: '',
7 component: NavbarComponent,
8 outlet: 'navbar'
9 };
File src/main/webapp/app/layouts/navbar/navbar.scss added (mode: 100644) (index 0000000..1ff209b)
1 @import '~bootstrap/scss/functions';
2 @import '~bootstrap/scss/variables';
3
4 /* ==========================================================================
5 Navbar
6 ========================================================================== */
7
8 .navbar-version {
9 font-size: 0.65em;
10 color: $navbar-dark-color;
11 }
12
13 .profile-image {
14 height: 1.75em;
15 width: 1.75em;
16 }
17
18 .navbar {
19 padding: 0.2rem 1rem;
20
21 ul.navbar-nav {
22 .nav-item {
23 margin-left: 0.5em;
24 }
25 }
26
27 a.nav-link {
28 font-weight: 400;
29 }
30 }
31
32 /* ==========================================================================
33 Logo styles
34 ========================================================================== */
35 .logo-img {
36 height: 45px;
37 width: 45px;
38 display: inline-block;
39 vertical-align: middle;
40 background: url('../../../content/images/logo-jhipster.png') no-repeat center center;
41 background-size: contain;
42 }
File src/main/webapp/app/layouts/profiles/page-ribbon.component.ts added (mode: 100644) (index 0000000..66fc245)
1 import { Component, OnInit } from '@angular/core';
2 import { Observable } from 'rxjs';
3 import { map } from 'rxjs/operators';
4 import { ProfileService } from './profile.service';
5
6 @Component({
7 selector: 'auth-page-ribbon',
8 template: `
9 <div class="ribbon" *ngIf="ribbonEnv$ | async as ribbonEnv">
10 <a href="" jhiTranslate="global.ribbon.{{ ribbonEnv }}">{{ ribbonEnv }}</a>
11 </div>
12 `,
13 styleUrls: ['page-ribbon.scss']
14 })
15 export class PageRibbonComponent implements OnInit {
16 ribbonEnv$?: Observable<string | undefined>;
17
18 constructor(private profileService: ProfileService) {}
19
20 ngOnInit(): void {
21 this.ribbonEnv$ = this.profileService.getProfileInfo().pipe(map(profileInfo => profileInfo.ribbonEnv));
22 }
23 }
File src/main/webapp/app/layouts/profiles/page-ribbon.scss added (mode: 100644) (index 0000000..a78f268)
1 /* ==========================================================================
2 Developement Ribbon
3 ========================================================================== */
4 .ribbon {
5 background-color: rgba(170, 0, 0, 0.5);
6 left: -3.5em;
7 -moz-transform: rotate(-45deg);
8 -ms-transform: rotate(-45deg);
9 -o-transform: rotate(-45deg);
10 -webkit-transform: rotate(-45deg);
11 transform: rotate(-45deg);
12 overflow: hidden;
13 position: absolute;
14 top: 40px;
15 white-space: nowrap;
16 width: 15em;
17 z-index: 9999;
18 pointer-events: none;
19 opacity: 0.75;
20 a {
21 color: #fff;
22 display: block;
23 font-weight: 400;
24 margin: 1px 0;
25 padding: 10px 50px;
26 text-align: center;
27 text-decoration: none;
28 text-shadow: 0 0 5px #444;
29 pointer-events: none;
30 }
31 }
File src/main/webapp/app/layouts/profiles/profile-info.model.ts added (mode: 100644) (index 0000000..e7763ee)
1 export interface InfoResponse {
2 'display-ribbon-on-profiles'?: string;
3 git?: any;
4 build?: any;
5 activeProfiles?: string[];
6 }
7
8 export class ProfileInfo {
9 constructor(
10 public activeProfiles?: string[],
11 public ribbonEnv?: string,
12 public inProduction?: boolean,
13 public swaggerEnabled?: boolean
14 ) {}
15 }
File src/main/webapp/app/layouts/profiles/profile.service.ts added (mode: 100644) (index 0000000..f1512d3)
1 import { Injectable } from '@angular/core';
2 import { HttpClient } from '@angular/common/http';
3 import { map, shareReplay } from 'rxjs/operators';
4 import { Observable } from 'rxjs';
5
6 import { SERVER_API_URL } from 'app/app.constants';
7 import { ProfileInfo, InfoResponse } from './profile-info.model';
8
9 @Injectable({ providedIn: 'root' })
10 export class ProfileService {
11 private infoUrl = SERVER_API_URL + 'management/info';
12 private profileInfo$!: Observable<ProfileInfo>;
13
14 constructor(private http: HttpClient) {}
15
16 getProfileInfo(): Observable<ProfileInfo> {
17 if (this.profileInfo$) {
18 return this.profileInfo$;
19 }
20
21 this.profileInfo$ = this.http.get<InfoResponse>(this.infoUrl).pipe(
22 map((response: InfoResponse) => {
23 const profileInfo: ProfileInfo = {
24 activeProfiles: response.activeProfiles,
25 inProduction: response.activeProfiles && response.activeProfiles.includes('prod'),
26 swaggerEnabled: response.activeProfiles && response.activeProfiles.includes('swagger')
27 };
28 if (response.activeProfiles && response['display-ribbon-on-profiles']) {
29 const displayRibbonOnProfiles = response['display-ribbon-on-profiles'].split(',');
30 const ribbonProfiles = displayRibbonOnProfiles.filter(
31 profile => response.activeProfiles && response.activeProfiles.includes(profile)
32 );
33 if (ribbonProfiles.length > 0) {
34 profileInfo.ribbonEnv = ribbonProfiles[0];
35 }
36 }
37 return profileInfo;
38 }),
39 shareReplay()
40 );
41 return this.profileInfo$;
42 }
43 }
File src/main/webapp/app/polyfills.ts added (mode: 100644) (index 0000000..f8a8d65)
1 import 'zone.js/dist/zone';
2 import '@angular/localize/init';
3 require('../manifest.webapp');
File src/main/webapp/app/shared/alert/alert-error.component.ts added (mode: 100644) (index 0000000..712c90a)
1 import { Component, OnDestroy } from '@angular/core';
2 import { HttpErrorResponse } from '@angular/common/http';
3 import { TranslateService } from '@ngx-translate/core';
4 import { JhiEventManager, JhiAlert, JhiAlertService, JhiEventWithContent } from 'ng-jhipster';
5 import { Subscription } from 'rxjs';
6
7 import { AlertError } from './alert-error.model';
8
9 @Component({
10 selector: 'auth-alert-error',
11 template: `
12 <div class="alerts" role="alert">
13 <div *ngFor="let alert of alerts" [ngClass]="setClasses(alert)">
14 <ngb-alert *ngIf="alert && alert.type && alert.msg" [type]="alert.type" (close)="alert.close(alerts)">
15 <pre [innerHTML]="alert.msg"></pre>
16 </ngb-alert>
17 </div>
18 </div>
19 `
20 })
21 export class AlertErrorComponent implements OnDestroy {
22 alerts: JhiAlert[] = [];
23 errorListener: Subscription;
24 httpErrorListener: Subscription;
25
26 constructor(private alertService: JhiAlertService, private eventManager: JhiEventManager, translateService: TranslateService) {
27 this.errorListener = eventManager.subscribe('honlapApp.error', (response: JhiEventWithContent<AlertError>) => {
28 const errorResponse = response.content;
29 this.addErrorAlert(errorResponse.message, errorResponse.key, errorResponse.params);
30 });
31
32 this.httpErrorListener = eventManager.subscribe('honlapApp.httpError', (response: JhiEventWithContent<HttpErrorResponse>) => {
33 const httpErrorResponse = response.content;
34 switch (httpErrorResponse.status) {
35 // connection refused, server not reachable
36 case 0:
37 this.addErrorAlert('Server not reachable', 'error.server.not.reachable');
38 break;
39
40 case 400: {
41 const arr = httpErrorResponse.headers.keys();
42 let errorHeader = null;
43 let entityKey = null;
44 arr.forEach(entry => {
45 if (entry.toLowerCase().endsWith('app-error')) {
46 errorHeader = httpErrorResponse.headers.get(entry);
47 } else if (entry.toLowerCase().endsWith('app-params')) {
48 entityKey = httpErrorResponse.headers.get(entry);
49 }
50 });
51 if (errorHeader) {
52 const entityName = translateService.instant('global.menu.entities.' + entityKey);
53 this.addErrorAlert(errorHeader, errorHeader, { entityName });
54 } else if (httpErrorResponse.error !== '' && httpErrorResponse.error.fieldErrors) {
55 const fieldErrors = httpErrorResponse.error.fieldErrors;
56 for (const fieldError of fieldErrors) {
57 if (['Min', 'Max', 'DecimalMin', 'DecimalMax'].includes(fieldError.message)) {
58 fieldError.message = 'Size';
59 }
60 // convert 'something[14].other[4].id' to 'something[].other[].id' so translations can be written to it
61 const convertedField = fieldError.field.replace(/\[\d*\]/g, '[]');
62 const fieldName = translateService.instant('honlapApp.' + fieldError.objectName + '.' + convertedField);
63 this.addErrorAlert('Error on field "' + fieldName + '"', 'error.' + fieldError.message, { fieldName });
64 }
65 } else if (httpErrorResponse.error !== '' && httpErrorResponse.error.message) {
66 this.addErrorAlert(httpErrorResponse.error.message, httpErrorResponse.error.message, httpErrorResponse.error.params);
67 } else {
68 this.addErrorAlert(httpErrorResponse.error);
69 }
70 break;
71 }
72
73 case 404:
74 this.addErrorAlert('Not found', 'error.url.not.found');
75 break;
76
77 default:
78 if (httpErrorResponse.error !== '' && httpErrorResponse.error.message) {
79 this.addErrorAlert(httpErrorResponse.error.message);
80 } else {
81 this.addErrorAlert(httpErrorResponse.error);
82 }
83 }
84 });
85 }
86
87 setClasses(alert: JhiAlert): { [key: string]: boolean } {
88 const classes = { 'jhi-toast': Boolean(alert.toast) };
89 if (alert.position) {
90 return { ...classes, [alert.position]: true };
91 }
92 return classes;
93 }
94
95 ngOnDestroy(): void {
96 if (this.errorListener) {
97 this.eventManager.destroy(this.errorListener);
98 }
99 if (this.httpErrorListener) {
100 this.eventManager.destroy(this.httpErrorListener);
101 }
102 }
103
104 addErrorAlert(message: string, key?: string, data?: any): void {
105 message = key && key !== null ? key : message;
106
107 const newAlert: JhiAlert = {
108 type: 'danger',
109 msg: message,
110 params: data,
111 timeout: 5000,
112 toast: this.alertService.isToast(),
113 scoped: true
114 };
115
116 this.alerts.push(this.alertService.addAlert(newAlert, this.alerts));
117 }
118 }
File src/main/webapp/app/shared/alert/alert-error.model.ts added (mode: 100644) (index 0000000..e76241a)
1 export class AlertError {
2 constructor(public message: string, public key?: string, public params?: any) {}
3 }
File src/main/webapp/app/shared/alert/alert.component.ts added (mode: 100644) (index 0000000..0f13b15)
1 import { Component, OnDestroy, OnInit } from '@angular/core';
2 import { JhiAlertService, JhiAlert } from 'ng-jhipster';
3
4 @Component({
5 selector: 'auth-alert',
6 template: `
7 <div class="alerts" role="alert">
8 <div *ngFor="let alert of alerts" [ngClass]="setClasses(alert)">
9 <ngb-alert *ngIf="alert && alert.type && alert.msg" [type]="alert.type" (close)="alert.close(alerts)">
10 <pre [innerHTML]="alert.msg"></pre>
11 </ngb-alert>
12 </div>
13 </div>
14 `
15 })
16 export class AlertComponent implements OnInit, OnDestroy {
17 alerts: JhiAlert[] = [];
18
19 constructor(private alertService: JhiAlertService) {}
20
21 ngOnInit(): void {
22 this.alerts = this.alertService.get();
23 }
24
25 setClasses(alert: JhiAlert): { [key: string]: boolean } {
26 const classes = { 'jhi-toast': Boolean(alert.toast) };
27 if (alert.position) {
28 return { ...classes, [alert.position]: true };
29 }
30 return classes;
31 }
32
33 ngOnDestroy(): void {
34 this.alertService.clear();
35 }
36 }
File src/main/webapp/app/shared/auth/has-any-authority.directive.ts added (mode: 100644) (index 0000000..43b97c4)
1 import { Directive, Input, TemplateRef, ViewContainerRef, OnDestroy } from '@angular/core';
2 import { Subscription } from 'rxjs';
3
4 import { AccountService } from 'app/core/auth/account.service';
5
6 /**
7 * @whatItDoes Conditionally includes an HTML element if current user has any
8 * of the authorities passed as the `expression`.
9 *
10 * @howToUse
11 * ```
12 * <some-element *authHasAnyAuthority="'ROLE_ADMIN'">...</some-element>
13 *
14 * <some-element *authHasAnyAuthority="['ROLE_ADMIN', 'ROLE_USER']">...</some-element>
15 * ```
16 */
17 @Directive({
18 selector: '[authHasAnyAuthority]'
19 })
20 export class HasAnyAuthorityDirective implements OnDestroy {
21 private authorities: string[] = [];
22 private authenticationSubscription?: Subscription;
23
24 constructor(private accountService: AccountService, private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef) {}
25
26 @Input()
27 set authHasAnyAuthority(value: string | string[]) {
28 this.authorities = typeof value === 'string' ? [value] : value;
29 this.updateView();
30 // Get notified each time authentication state changes.
31 this.authenticationSubscription = this.accountService.getAuthenticationState().subscribe(() => this.updateView());
32 }
33
34 ngOnDestroy(): void {
35 if (this.authenticationSubscription) {
36 this.authenticationSubscription.unsubscribe();
37 }
38 }
39
40 private updateView(): void {
41 const hasAnyAuthority = this.accountService.hasAnyAuthority(this.authorities);
42 this.viewContainerRef.clear();
43 if (hasAnyAuthority) {
44 this.viewContainerRef.createEmbeddedView(this.templateRef);
45 }
46 }
47 }
File src/main/webapp/app/shared/constants/authority.constants.ts added (mode: 100644) (index 0000000..9f672ce)
1 export enum Authority {
2 ADMIN = 'ROLE_ADMIN',
3 USER = 'ROLE_USER'
4 }
File src/main/webapp/app/shared/constants/error.constants.ts added (mode: 100644) (index 0000000..42d91d9)
1 export const PROBLEM_BASE_URL = 'https://www.jhipster.tech/problem';
2 export const EMAIL_ALREADY_USED_TYPE = PROBLEM_BASE_URL + '/email-already-used';
3 export const LOGIN_ALREADY_USED_TYPE = PROBLEM_BASE_URL + '/login-already-used';
File src/main/webapp/app/shared/constants/input.constants.ts added (mode: 100644) (index 0000000..1e3978a)
1 export const DATE_FORMAT = 'YYYY-MM-DD';
2 export const DATE_TIME_FORMAT = 'YYYY-MM-DDTHH:mm';
File src/main/webapp/app/shared/constants/pagination.constants.ts added (mode: 100644) (index 0000000..a148d45)
1 export const ITEMS_PER_PAGE = 20;
File src/main/webapp/app/shared/language/find-language-from-key.pipe.ts added (mode: 100644) (index 0000000..cb52a3e)
1 import { Pipe, PipeTransform } from '@angular/core';
2
3 @Pipe({ name: 'findLanguageFromKey' })
4 export class FindLanguageFromKeyPipe implements PipeTransform {
5 private languages: { [key: string]: { name: string; rtl?: boolean } } = {
6 en: { name: 'English' },
7 hu: { name: 'Magyar' }
8 // jhipster-needle-i18n-language-key-pipe - JHipster will add/remove languages in this object
9 };
10
11 transform(lang: string): string {
12 return this.languages[lang].name;
13 }
14 }
File src/main/webapp/app/shared/login/login.component.html added (mode: 100644) (index 0000000..dcd23c1)
1 <div class="modal-header">
2 <h4 class="modal-title" jhiTranslate="login.title">Sign in</h4>
3
4 <button aria-label="Close" data-dismiss="modal" class="close" type="button" (click)="activeModal.dismiss('closed')">
5 <span aria-hidden="true">x</span>
6 </button>
7 </div>
8
9 <div class="modal-body">
10 <div class="row justify-content-center">
11 <div class="col-md-8">
12 <div class="alert alert-danger" *ngIf="authenticationError" jhiTranslate="login.messages.error.authentication">
13 <strong>Failed to sign in!</strong> Please check your credentials and try again.
14 </div>
15 </div>
16
17 <div class="col-md-8">
18 <form class="form" role="form" (ngSubmit)="login()" [formGroup]="loginForm">
19 <div class="form-group">
20 <label class="username-label" for="username" jhiTranslate="global.form.username.label">Login</label>
21 <input type="text" class="form-control" name="username" id="username" placeholder="{{ 'global.form.username.placeholder' | translate }}"
22 formControlName="username" #username>
23 </div>
24
25 <div class="form-group">
26 <label for="password" jhiTranslate="login.form.password">Password</label>
27 <input type="password" class="form-control" name="password" id="password" placeholder="{{ 'login.form.password.placeholder' | translate }}"
28 formControlName="password">
29 </div>
30
31 <div class="form-check">
32 <label class="form-check-label" for="rememberMe">
33 <input class="form-check-input" type="checkbox" name="rememberMe" id="rememberMe" formControlName="rememberMe">
34 <span jhiTranslate="login.form.rememberme">Remember me</span>
35 </label>
36 </div>
37
38 <button type="submit" class="btn btn-primary" jhiTranslate="login.form.button">Sign in</button>
39 </form>
40
41 <div class="mt-3 alert alert-warning">
42 <a class="alert-link" (click)="requestResetPassword()" jhiTranslate="login.password.forgot">Did you forget your password?</a>
43 </div>
44
45 <div class="alert alert-warning">
46 <span jhiTranslate="global.messages.info.register.noaccount">You don't have an account yet?</span>
47 <a class="alert-link" (click)="register()" jhiTranslate="global.messages.info.register.link">Register a new account</a>
48 </div>
49 </div>
50 </div>
51 </div>
File src/main/webapp/app/shared/login/login.component.ts added (mode: 100644) (index 0000000..24183ce)
1 import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
2 import { FormBuilder } from '@angular/forms';
3 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
4 import { Router } from '@angular/router';
5
6 import { LoginService } from 'app/core/login/login.service';
7
8 @Component({
9 selector: 'auth-login-modal',
10 templateUrl: './login.component.html'
11 })
12 export class LoginModalComponent implements AfterViewInit {
13 @ViewChild('username', { static: false })
14 username?: ElementRef;
15
16 authenticationError = false;
17
18 loginForm = this.fb.group({
19 username: [''],
20 password: [''],
21 rememberMe: [false]
22 });
23
24 constructor(private loginService: LoginService, private router: Router, public activeModal: NgbActiveModal, private fb: FormBuilder) {}
25
26 ngAfterViewInit(): void {
27 if (this.username) {
28 this.username.nativeElement.focus();
29 }
30 }
31
32 cancel(): void {
33 this.authenticationError = false;
34 this.loginForm.patchValue({
35 username: '',
36 password: ''
37 });
38 this.activeModal.dismiss('cancel');
39 }
40
41 login(): void {
42 this.loginService
43 .login({
44 username: this.loginForm.get('username')!.value,
45 password: this.loginForm.get('password')!.value,
46 rememberMe: this.loginForm.get('rememberMe')!.value
47 })
48 .subscribe(
49 () => {
50 this.authenticationError = false;
51 this.activeModal.close();
52 if (
53 this.router.url === '/account/register' ||
54 this.router.url.startsWith('/account/activate') ||
55 this.router.url.startsWith('/account/reset/')
56 ) {
57 this.router.navigate(['']);
58 }
59 },
60 () => (this.authenticationError = true)
61 );
62 }
63
64 register(): void {
65 this.activeModal.dismiss('to state register');
66 this.router.navigate(['/account/register']);
67 }
68
69 requestResetPassword(): void {
70 this.activeModal.dismiss('to state requestReset');
71 this.router.navigate(['/account/reset', 'request']);
72 }
73 }
File src/main/webapp/app/shared/model/piece-of-news.model.ts added (mode: 100644) (index 0000000..b7cef07)
1 import { Moment } from 'moment';
2
3 export interface IPieceOfNews {
4 id?: number;
5 appId?: number;
6 newsDate?: Moment;
7 headline?: string;
8 content?: string;
9 link?: string;
10 publishDate?: Moment;
11 createdBy?: string;
12 createdDate?: Moment;
13 lastModifiedBy?: string;
14 lastModifiedDate?: Moment;
15 }
16
17 export class PieceOfNews implements IPieceOfNews {
18 constructor(
19 public id?: number,
20 public appId?: number,
21 public newsDate?: Moment,
22 public headline?: string,
23 public content?: string,
24 public link?: string,
25 public publishDate?: Moment,
26 public createdBy?: string,
27 public createdDate?: Moment,
28 public lastModifiedBy?: string,
29 public lastModifiedDate?: Moment
30 ) {}
31 }
File src/main/webapp/app/shared/shared-libs.module.ts added (mode: 100644) (index 0000000..609736f)
1 import { NgModule } from '@angular/core';
2 import { CommonModule } from '@angular/common';
3 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4 import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
5 import { NgJhipsterModule } from 'ng-jhipster';
6 import { InfiniteScrollModule } from 'ngx-infinite-scroll';
7 import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
8 import { TranslateModule } from '@ngx-translate/core';
9
10 @NgModule({
11 exports: [
12 FormsModule,
13 CommonModule,
14 NgbModule,
15 NgJhipsterModule,
16 InfiniteScrollModule,
17 FontAwesomeModule,
18 ReactiveFormsModule,
19 TranslateModule
20 ]
21 })
22 export class HonlapSharedLibsModule {}
File src/main/webapp/app/shared/shared.module.ts added (mode: 100644) (index 0000000..2dc0a43)
1 import { NgModule } from '@angular/core';
2 import { HonlapSharedLibsModule } from './shared-libs.module';
3 import { FindLanguageFromKeyPipe } from './language/find-language-from-key.pipe';
4 import { AlertComponent } from './alert/alert.component';
5 import { AlertErrorComponent } from './alert/alert-error.component';
6 import { LoginModalComponent } from './login/login.component';
7 import { HasAnyAuthorityDirective } from './auth/has-any-authority.directive';
8
9 @NgModule({
10 imports: [HonlapSharedLibsModule],
11 declarations: [FindLanguageFromKeyPipe, AlertComponent, AlertErrorComponent, LoginModalComponent, HasAnyAuthorityDirective],
12 entryComponents: [LoginModalComponent],
13 exports: [
14 HonlapSharedLibsModule,
15 FindLanguageFromKeyPipe,
16 AlertComponent,
17 AlertErrorComponent,
18 LoginModalComponent,
19 HasAnyAuthorityDirective
20 ]
21 })
22 export class HonlapSharedModule {}
File src/main/webapp/app/shared/util/datepicker-adapter.ts added (mode: 100644) (index 0000000..027f123)
1 /**
2 * Angular bootstrap Date adapter
3 */
4 import { Injectable } from '@angular/core';
5 import { NgbDateAdapter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
6 import { Moment } from 'moment';
7 import * as moment from 'moment';
8
9 @Injectable()
10 export class NgbDateMomentAdapter extends NgbDateAdapter<Moment> {
11 fromModel(date: Moment): NgbDateStruct {
12 if (date && moment.isMoment(date) && date.isValid()) {
13 return { year: date.year(), month: date.month() + 1, day: date.date() };
14 }
15 // ! can be removed after https://github.com/ng-bootstrap/ng-bootstrap/issues/1544 is resolved
16 return null!;
17 }
18
19 toModel(date: NgbDateStruct): Moment {
20 // ! after null can be removed after https://github.com/ng-bootstrap/ng-bootstrap/issues/1544 is resolved
21 return date ? moment(date.year + '-' + date.month + '-' + date.day, 'YYYY-MM-DD') : null!;
22 }
23 }
File src/main/webapp/app/shared/util/request-util.ts added (mode: 100644) (index 0000000..f839fd6)
1 import { HttpParams } from '@angular/common/http';
2
3 export interface Pagination {
4 page: number;
5 size: number;
6 sort: string[];
7 }
8
9 export interface Search {
10 query: string;
11 }
12
13 export interface SearchWithPagination extends Search, Pagination {}
14
15 export const createRequestOption = (req?: any): HttpParams => {
16 let options: HttpParams = new HttpParams();
17
18 if (req) {
19 Object.keys(req).forEach(key => {
20 if (key !== 'sort') {
21 options = options.set(key, req[key]);
22 }
23 });
24
25 if (req.sort) {
26 req.sort.forEach((val: string) => {
27 options = options.append('sort', val);
28 });
29 }
30 }
31
32 return options;
33 };
File src/main/webapp/app/vendor.ts added (mode: 100644) (index 0000000..a89c6da)
1 /* after changing this file run 'npm run webpack:build' */
2 import '../content/scss/vendor.scss';
File src/main/webapp/content/css/loading.css added (mode: 100644) (index 0000000..b2c6626)
1 @keyframes lds-pacman-1 {
2 0% {
3 -webkit-transform: rotate(0deg);
4 transform: rotate(0deg);
5 }
6 50% {
7 -webkit-transform: rotate(-45deg);
8 transform: rotate(-45deg);
9 }
10 100% {
11 -webkit-transform: rotate(0deg);
12 transform: rotate(0deg);
13 }
14 }
15 @-webkit-keyframes lds-pacman-1 {
16 0% {
17 -webkit-transform: rotate(0deg);
18 transform: rotate(0deg);
19 }
20 50% {
21 -webkit-transform: rotate(-45deg);
22 transform: rotate(-45deg);
23 }
24 100% {
25 -webkit-transform: rotate(0deg);
26 transform: rotate(0deg);
27 }
28 }
29 @keyframes lds-pacman-2 {
30 0% {
31 -webkit-transform: rotate(180deg);
32 transform: rotate(180deg);
33 }
34 50% {
35 -webkit-transform: rotate(225deg);
36 transform: rotate(225deg);
37 }
38 100% {
39 -webkit-transform: rotate(180deg);
40 transform: rotate(180deg);
41 }
42 }
43 @-webkit-keyframes lds-pacman-2 {
44 0% {
45 -webkit-transform: rotate(180deg);
46 transform: rotate(180deg);
47 }
48 50% {
49 -webkit-transform: rotate(225deg);
50 transform: rotate(225deg);
51 }
52 100% {
53 -webkit-transform: rotate(180deg);
54 transform: rotate(180deg);
55 }
56 }
57 @keyframes lds-pacman-3 {
58 0% {
59 -webkit-transform: translate(190px, 0);
60 transform: translate(190px, 0);
61 opacity: 0;
62 }
63 20% {
64 opacity: 1;
65 }
66 100% {
67 -webkit-transform: translate(70px, 0);
68 transform: translate(70px, 0);
69 opacity: 1;
70 }
71 }
72 @-webkit-keyframes lds-pacman-3 {
73 0% {
74 -webkit-transform: translate(190px, 0);
75 transform: translate(190px, 0);
76 opacity: 0;
77 }
78 20% {
79 opacity: 1;
80 }
81 100% {
82 -webkit-transform: translate(70px, 0);
83 transform: translate(70px, 0);
84 opacity: 1;
85 }
86 }
87
88 .app-loading {
89 font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
90 position: relative;
91 display: flex;
92 flex-direction: column;
93 align-items: center;
94 justify-content: center;
95 top: 10em;
96 }
97 .app-loading p {
98 display: block;
99 font-size: 1.17em;
100 margin-inline-start: 0px;
101 margin-inline-end: 0px;
102 font-weight: normal;
103 }
104
105 .app-loading .lds-pacman {
106 position: relative;
107 margin: auto;
108 width: 200px !important;
109 height: 200px !important;
110 -webkit-transform: translate(-100px, -100px) scale(1) translate(100px, 100px);
111 transform: translate(-100px, -100px) scale(1) translate(100px, 100px);
112 }
113 .app-loading .lds-pacman > div:nth-child(2) div {
114 position: absolute;
115 top: 40px;
116 left: 40px;
117 width: 120px;
118 height: 60px;
119 border-radius: 120px 120px 0 0;
120 background: #bbcedd;
121 -webkit-animation: lds-pacman-1 1s linear infinite;
122 animation: lds-pacman-1 1s linear infinite;
123 -webkit-transform-origin: 60px 60px;
124 transform-origin: 60px 60px;
125 }
126 .app-loading .lds-pacman > div:nth-child(2) div:nth-child(2) {
127 -webkit-animation: lds-pacman-2 1s linear infinite;
128 animation: lds-pacman-2 1s linear infinite;
129 }
130 .app-loading .lds-pacman > div:nth-child(1) div {
131 position: absolute;
132 top: 97px;
133 left: -8px;
134 width: 24px;
135 height: 10px;
136 background-image: url('../images/logo-jhipster.png');
137 background-size: contain;
138 -webkit-animation: lds-pacman-3 1s linear infinite;
139 animation: lds-pacman-3 1.5s linear infinite;
140 }
141 .app-loading .lds-pacman > div:nth-child(1) div:nth-child(1) {
142 -webkit-animation-delay: -0.67s;
143 animation-delay: -1s;
144 }
145 .app-loading .lds-pacman > div:nth-child(1) div:nth-child(2) {
146 -webkit-animation-delay: -0.33s;
147 animation-delay: -0.5s;
148 }
149 .app-loading .lds-pacman > div:nth-child(1) div:nth-child(3) {
150 -webkit-animation-delay: 0s;
151 animation-delay: 0s;
152 }
File src/main/webapp/content/images/jhipster_family_member_0.svg added (mode: 100644) (index 0000000..d6df83c)
File src/main/webapp/content/images/jhipster_family_member_0_head-192.png added (mode: 100644) (index 0000000..6d90ab3)
File src/main/webapp/content/images/jhipster_family_member_0_head-256.png added (mode: 100644) (index 0000000..8e99bfe)
File src/main/webapp/content/images/jhipster_family_member_0_head-384.png added (mode: 100644) (index 0000000..c7ca460)
File src/main/webapp/content/images/jhipster_family_member_0_head-512.png added (mode: 100644) (index 0000000..7e0b843)
File src/main/webapp/content/images/jhipster_family_member_1.svg added (mode: 100644) (index 0000000..e3a0f3d)
File src/main/webapp/content/images/jhipster_family_member_1_head-192.png added (mode: 100644) (index 0000000..ac5f2a0)
File src/main/webapp/content/images/jhipster_family_member_1_head-256.png added (mode: 100644) (index 0000000..443822e)
File src/main/webapp/content/images/jhipster_family_member_1_head-384.png added (mode: 100644) (index 0000000..4a5e9fe)
File src/main/webapp/content/images/jhipster_family_member_1_head-512.png added (mode: 100644) (index 0000000..66c625c)
File src/main/webapp/content/images/jhipster_family_member_2.svg added (mode: 100644) (index 0000000..51c6a5a)
File src/main/webapp/content/images/jhipster_family_member_2_head-192.png added (mode: 100644) (index 0000000..24baf78)
File src/main/webapp/content/images/jhipster_family_member_2_head-256.png added (mode: 100644) (index 0000000..7b25f52)
File src/main/webapp/content/images/jhipster_family_member_2_head-384.png added (mode: 100644) (index 0000000..e89e120)
File src/main/webapp/content/images/jhipster_family_member_2_head-512.png added (mode: 100644) (index 0000000..3c0e6cb)
File src/main/webapp/content/images/jhipster_family_member_3.svg added (mode: 100644) (index 0000000..cc0d01f)
File src/main/webapp/content/images/jhipster_family_member_3_head-192.png added (mode: 100644) (index 0000000..b1e4fb3)
File src/main/webapp/content/images/jhipster_family_member_3_head-256.png added (mode: 100644) (index 0000000..aa058c7)
File src/main/webapp/content/images/jhipster_family_member_3_head-384.png added (mode: 100644) (index 0000000..1d10bd5)
File src/main/webapp/content/images/jhipster_family_member_3_head-512.png added (mode: 100644) (index 0000000..e719f1d)
File src/main/webapp/content/images/logo-jhipster.png added (mode: 100644) (index 0000000..6a005bf)
File src/main/webapp/content/scss/_bootstrap-variables.scss added (mode: 100644) (index 0000000..a64158a)
1 /*
2 * Bootstrap overrides https://getbootstrap.com/docs/4.0/getting-started/theming/
3 * All values defined in bootstrap source
4 * https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss can be overwritten here
5 * Make sure not to add !default to values here
6 */
7
8 // Colors:
9 // Grayscale and brand colors for use across Bootstrap.
10
11 $primary: #3e8acc;
12 $success: #28a745;
13 $info: #17a2b8;
14 $warning: #ffc107;
15 $danger: #dc3545;
16
17 // Options:
18 // Quickly modify global styling by enabling or disabling optional features.
19 $enable-rounded: true;
20 $enable-shadows: false;
21 $enable-gradients: false;
22 $enable-transitions: true;
23 $enable-hover-media-query: false;
24 $enable-grid-classes: true;
25 $enable-print-styles: true;
26
27 // Components:
28 // Define common padding and border radius sizes and more.
29
30 $border-radius: 0.15rem;
31 $border-radius-lg: 0.125rem;
32 $border-radius-sm: 0.1rem;
33
34 // Body:
35 // Settings for the `<body>` element.
36
37 $body-bg: #e4e5e6;
38
39 // Typography:
40 // Font, line-height, and color for body text, headings, and more.
41
42 $font-size-base: 1rem;
43
44 $dropdown-link-hover-color: white;
45 $dropdown-link-hover-bg: #343a40;
File src/main/webapp/content/scss/global.scss added (mode: 100644) (index 0000000..543a62c)
1 @import 'bootstrap-variables';
2 @import '~bootstrap/scss/functions';
3 @import '~bootstrap/scss/variables';
4
5 /* ==============================================================
6 Bootstrap tweaks
7 ===============================================================*/
8
9 body,
10 h1,
11 h2,
12 h3,
13 h4 {
14 font-weight: 300;
15 }
16
17 /* Increase contrast of links to get 100% on Lighthouse Accessability Audit. Override this color if you want to change the link color, or use a Bootswatch theme */
18 a {
19 color: #533f03;
20 font-weight: bold;
21 }
22
23 a:hover {
24 color: #533f03;
25 }
26
27 /* override hover color for dropdown-item forced by bootstrap to all a:not([href]):not([tabindex]) elements in _reboot.scss */
28 a:not([href]):not([tabindex]):hover.dropdown-item {
29 color: $dropdown-link-hover-color;
30 }
31
32 /* override .dropdown-item.active background-color on hover */
33 .dropdown-item.active:hover {
34 background-color: mix($dropdown-link-hover-bg, $dropdown-link-active-bg, 50%);
35 }
36
37 a:hover {
38 /* make sure browsers use the pointer cursor for anchors, even with no href */
39 cursor: pointer;
40 }
41
42 .dropdown-item:hover {
43 color: $dropdown-link-hover-color;
44 }
45
46 /* ==========================================================================
47 Browser Upgrade Prompt
48 ========================================================================== */
49 .browserupgrade {
50 margin: 0.2em 0;
51 background: #ccc;
52 color: #000;
53 padding: 0.2em 0;
54 }
55
56 /* ==========================================================================
57 Generic styles
58 ========================================================================== */
59
60 /* Error highlight on input fields */
61 .ng-valid[required],
62 .ng-valid.required {
63 border-left: 5px solid green;
64 }
65
66 .ng-invalid:not(form) {
67 border-left: 5px solid red;
68 }
69
70 /* other generic styles */
71
72 .jh-card {
73 padding: 1.5%;
74 margin-top: 20px;
75 border: none;
76 }
77
78 .error {
79 color: white;
80 background-color: red;
81 }
82
83 .pad {
84 padding: 10px;
85 }
86
87 .w-40 {
88 width: 40% !important;
89 }
90
91 .w-60 {
92 width: 60% !important;
93 }
94
95 .break {
96 white-space: normal;
97 word-break: break-all;
98 }
99
100 .readonly {
101 background-color: #eee;
102 opacity: 1;
103 }
104
105 .footer {
106 border-top: 1px solid rgba(0, 0, 0, 0.125);
107 }
108
109 .hand,
110 [jhisortby] {
111 cursor: pointer;
112 }
113
114 /* ==========================================================================
115 Custom alerts for notification
116 ========================================================================== */
117 .alerts {
118 .alert {
119 text-overflow: ellipsis;
120 pre {
121 background: none;
122 border: none;
123 font: inherit;
124 color: inherit;
125 padding: 0;
126 margin: 0;
127 }
128 .popover pre {
129 font-size: 10px;
130 }
131 }
132 .jhi-toast {
133 position: fixed;
134 width: 100%;
135 &.left {
136 left: 5px;
137 }
138 &.right {
139 right: 5px;
140 }
141 &.top {
142 top: 55px;
143 }
144 &.bottom {
145 bottom: 55px;
146 }
147 }
148 }
149
150 @media screen and (min-width: 480px) {
151 .alerts .jhi-toast {
152 width: 50%;
153 }
154 }
155
156 /* ==========================================================================
157 entity detail page css
158 ========================================================================== */
159 .row.jh-entity-details > {
160 dd {
161 margin-bottom: 15px;
162 }
163 }
164
165 @media screen and (min-width: 768px) {
166 .row.jh-entity-details > {
167 dt {
168 margin-bottom: 15px;
169 }
170 dd {
171 border-bottom: 1px solid #eee;
172 padding-left: 180px;
173 margin-left: 0;
174 }
175 }
176 }
177
178 /* ==========================================================================
179 ui bootstrap tweaks
180 ========================================================================== */
181 .nav,
182 .pagination,
183 .carousel,
184 .panel-title a {
185 cursor: pointer;
186 }
187
188 .thread-dump-modal-lock {
189 max-width: 450px;
190 overflow: hidden;
191 text-overflow: ellipsis;
192 white-space: nowrap;
193 }
194
195 /* jhipster-needle-scss-add-main JHipster will add new css style */
File src/main/webapp/content/scss/vendor.scss added (mode: 100644) (index 0000000..31688d0)
1 /* after changing this file run 'npm run webpack:build' */
2
3 /***************************
4 put Sass variables here:
5 eg $input-color: red;
6 ****************************/
7 // Override Bootstrap variables
8 @import 'bootstrap-variables';
9 // Import Bootstrap source files from node_modules
10 @import '~bootstrap/scss/bootstrap';
11
12 /* jhipster-needle-scss-add-vendor JHipster will add new css style */
File src/main/webapp/favicon.ico added (mode: 100644) (index 0000000..4179874)
File src/main/webapp/i18n/en/activate.json added (mode: 100644) (index 0000000..058bd49)
1 {
2 "activate": {
3 "title": "Activation",
4 "messages": {
5 "success": "<strong>Your user account has been activated.</strong> Please ",
6 "error": "<strong>Your user could not be activated.</strong> Please use the registration form to sign up."
7 }
8 }
9 }
File src/main/webapp/i18n/en/audits.json added (mode: 100644) (index 0000000..8af22b2)
1 {
2 "audits": {
3 "title": "Audits",
4 "filter": {
5 "title": "Filter per date",
6 "from": "from",
7 "to": "to",
8 "button": {
9 "weeks": "Weeks",
10 "today": "today",
11 "clear": "clear",
12 "close": "close"
13 }
14 },
15 "table": {
16 "header": {
17 "principal": "User",
18 "date": "Date",
19 "status": "State",
20 "data": "Extra data"
21 },
22 "data": {
23 "remoteAddress": "Remote Address:"
24 }
25 },
26 "notFound": "No audit found"
27 }
28 }
File src/main/webapp/i18n/en/configuration.json added (mode: 100644) (index 0000000..09c9a1a)
1 {
2 "configuration": {
3 "title": "Configuration",
4 "filter": "Filter (by prefix)",
5 "table": {
6 "prefix": "Prefix",
7 "properties": "Properties"
8 }
9 }
10 }
File src/main/webapp/i18n/en/error.json added (mode: 100644) (index 0000000..d257563)
1 {
2 "error": {
3 "title": "Error page!",
4 "http": {
5 "400": "Bad request.",
6 "403": "You are not authorized to access this page.",
7 "404": "The page does not exist.",
8 "405": "The HTTP verb you used is not supported for this URL.",
9 "500": "Internal server error."
10 },
11 "concurrencyFailure": "Another user modified this data at the same time as you. Your changes were rejected.",
12 "validation": "Validation error on the server."
13 }
14 }
File src/main/webapp/i18n/en/global.json added (mode: 100644) (index 0000000..31905f2)
1 {
2 "global": {
3 "title": "Honlap",
4 "browsehappy": "You are using an <strong>outdated</strong> browser. Please <a href=\"http://browsehappy.com/?locale=en\">upgrade your browser</a> to improve your experience.",
5 "menu": {
6 "home": "Home",
7 "jhipster-needle-menu-add-element": "JHipster will add additional menu entries here (do not translate!)",
8 "entities": {
9 "main": "Entities",
10 "pieceOfNews": "Piece Of News",
11 "jhipster-needle-menu-add-entry": "JHipster will add additional entities here (do not translate!)"
12 },
13 "account": {
14 "main": "Account",
15 "settings": "Settings",
16 "password": "Password",
17 "sessions": "Sessions",
18 "login": "Sign in",
19 "logout": "Sign out",
20 "register": "Register"
21 },
22 "admin": {
23 "main": "Administration",
24 "userManagement": "User management",
25 "tracker": "User tracker",
26 "metrics": "Metrics",
27 "health": "Health",
28 "configuration": "Configuration",
29 "logs": "Logs",
30 "audits": "Audits",
31 "apidocs": "API",
32 "database": "Database",
33 "jhipster-needle-menu-add-admin-element": "JHipster will add additional menu entries here (do not translate!)"
34 },
35 "language": "Language"
36 },
37 "form": {
38 "username.label": "Username",
39 "username.placeholder": "Your username",
40 "currentpassword.label": "Current password",
41 "currentpassword.placeholder": "Current password",
42 "newpassword.label": "New password",
43 "newpassword.placeholder": "New password",
44 "confirmpassword.label": "New password confirmation",
45 "confirmpassword.placeholder": "Confirm the new password",
46 "email.label": "Email",
47 "email.placeholder": "Your email"
48 },
49 "messages": {
50 "info": {
51 "authenticated": {
52 "prefix": "If you want to ",
53 "link": "sign in",
54 "suffix": ", you can try the default accounts:<br/>- Administrator (login=\"admin\" and password=\"admin\") <br/>- User (login=\"user\" and password=\"user\")."
55 },
56 "register": {
57 "noaccount": "You don't have an account yet?",
58 "link": "Register a new account"
59 }
60 },
61 "error": {
62 "dontmatch": "The password and its confirmation do not match!"
63 },
64 "validate": {
65 "newpassword": {
66 "required": "Your password is required.",
67 "minlength": "Your password is required to be at least 4 characters.",
68 "maxlength": "Your password cannot be longer than 50 characters.",
69 "strength": "Password strength:"
70 },
71 "confirmpassword": {
72 "required": "Your confirmation password is required.",
73 "minlength": "Your confirmation password is required to be at least 4 characters.",
74 "maxlength": "Your confirmation password cannot be longer than 50 characters."
75 },
76 "email": {
77 "required": "Your email is required.",
78 "invalid": "Your email is invalid.",
79 "minlength": "Your email is required to be at least 5 characters.",
80 "maxlength": "Your email cannot be longer than 50 characters."
81 }
82 }
83 },
84 "field": {
85 "id": "ID"
86 },
87 "ribbon": {
88 "dev": "Development"
89 },
90 "item-count": "Showing {{first}} - {{second}} of {{total}} items."
91 },
92 "entity": {
93 "action": {
94 "addblob": "Add blob",
95 "addimage": "Add image",
96 "back": "Back",
97 "cancel": "Cancel",
98 "delete": "Delete",
99 "edit": "Edit",
100 "open": "Open",
101 "save": "Save",
102 "view": "View"
103 },
104 "detail": {
105 "field": "Field",
106 "value": "Value"
107 },
108 "delete": {
109 "title": "Confirm delete operation"
110 },
111 "validation": {
112 "required": "This field is required.",
113 "minlength": "This field is required to be at least {{ min }} characters.",
114 "maxlength": "This field cannot be longer than {{ max }} characters.",
115 "min": "This field should be at least {{ min }}.",
116 "max": "This field cannot be more than {{ max }}.",
117 "minbytes": "This field should be at least {{ min }} bytes.",
118 "maxbytes": "This field cannot be more than {{ max }} bytes.",
119 "pattern": "This field should follow pattern for {{ pattern }}.",
120 "number": "This field should be a number.",
121 "datetimelocal": "This field should be a date and time.",
122 "patternLogin": "This field can only contain letters, digits and e-mail addresses."
123 }
124 },
125 "error": {
126 "internalServerError": "Internal server error",
127 "server.not.reachable": "Server not reachable",
128 "url.not.found": "Not found",
129 "NotNull": "Field {{ fieldName }} cannot be empty!",
130 "Size": "Field {{ fieldName }} does not meet min/max size requirements!",
131 "userexists": "Login name already used!",
132 "emailexists": "Email is already in use!",
133 "idexists": "A new {{ entityName }} cannot already have an ID",
134 "idnull": "Invalid ID",
135 "file": {
136 "could.not.extract": "Could not extract file",
137 "not.image": "File was expected to be an image but was found to be \"{{ fileType }}\""
138 }
139 },
140 "footer": "This is your footer"
141 }
File src/main/webapp/i18n/en/health.json added (mode: 100644) (index 0000000..0cbff26)
1 {
2 "health": {
3 "title": "Health Checks",
4 "refresh.button": "Refresh",
5 "stacktrace": "Stacktrace",
6 "details": {
7 "details": "Details",
8 "properties": "Properties",
9 "name": "Name",
10 "value": "Value",
11 "error": "Error"
12 },
13 "indicator": {
14 "diskSpace": "Disk space",
15 "mail": "Email",
16 "ping": "Application",
17 "db": "Database"
18 },
19 "table": {
20 "service": "Service name",
21 "status": "Status"
22 },
23 "status": {
24 "UNKNOWN": "UNKNOWN",
25 "UP": "UP",
26 "DOWN": "DOWN"
27 }
28 }
29 }
File src/main/webapp/i18n/en/home.json added (mode: 100644) (index 0000000..d9fc499)
1 {
2 "home": {
3 "title": "Welcome, Java Hipster!",
4 "subtitle": "This is your homepage",
5 "logged": {
6 "message": "You are logged in as user \"{{username}}\"."
7 },
8 "question": "If you have any question on JHipster:",
9 "link": {
10 "homepage": "JHipster homepage",
11 "stackoverflow": "JHipster on Stack Overflow",
12 "bugtracker": "JHipster bug tracker",
13 "chat": "JHipster public chat room",
14 "follow": "follow @jhipster on Twitter"
15 },
16 "like": "If you like JHipster, don't forget to give us a star on",
17 "github": "GitHub"
18 }
19 }
File src/main/webapp/i18n/en/login.json added (mode: 100644) (index 0000000..4667958)
1 {
2 "login": {
3 "title": "Sign in",
4 "form": {
5 "password": "Password",
6 "password.placeholder": "Your password",
7 "rememberme": "Remember me",
8 "button": "Sign in"
9 },
10 "messages": {
11 "error": {
12 "authentication": "<strong>Failed to sign in!</strong> Please check your credentials and try again."
13 }
14 },
15 "password": {
16 "forgot": "Did you forget your password?"
17 }
18 }
19 }
File src/main/webapp/i18n/en/logs.json added (mode: 100644) (index 0000000..8ee0ba5)
1 {
2 "logs": {
3 "title": "Logs",
4 "nbloggers": "There are {{ total }} loggers.",
5 "filter": "Filter",
6 "table": {
7 "name": "Name",
8 "level": "Level"
9 }
10 }
11 }
File src/main/webapp/i18n/en/metrics.json added (mode: 100644) (index 0000000..c514dee)
1 {
2 "metrics": {
3 "title": "Application Metrics",
4 "refresh.button": "Refresh",
5 "updating": "Updating...",
6 "jvm": {
7 "title": "JVM Metrics",
8 "memory": {
9 "title": "Memory",
10 "total": "Total Memory",
11 "heap": "Heap Memory",
12 "nonheap": "Non-Heap Memory"
13 },
14 "threads": {
15 "title": "Threads",
16 "all": "All",
17 "runnable": "Runnable",
18 "timedwaiting": "Timed waiting",
19 "waiting": "Waiting",
20 "blocked": "Blocked",
21 "dump": {
22 "title": "Threads dump",
23 "id": "Id: ",
24 "blockedtime": "Blocked Time",
25 "blockedcount": "Blocked Count",
26 "waitedtime": "Waited Time",
27 "waitedcount": "Waited Count",
28 "lockname": "Lock name",
29 "stacktrace": "Stacktrace",
30 "show": "Show Stacktrace",
31 "hide": "Hide Stacktrace"
32 }
33 },
34 "gc": {
35 "title": "Garbage collections",
36 "marksweepcount": "Mark Sweep count",
37 "marksweeptime": "Mark Sweep time",
38 "scavengecount": "Scavenge count",
39 "scavengetime": "Scavenge time"
40 },
41 "http": {
42 "title": "HTTP requests (time in millisecond)",
43 "active": "Active requests:",
44 "total": "Total requests:",
45 "table": {
46 "code": "Code",
47 "count": "Count",
48 "mean": "Mean",
49 "average": "Average",
50 "max": "Max"
51 },
52 "code": {
53 "ok": "Ok",
54 "notfound": "Not found",
55 "servererror": "Server Error"
56 }
57 }
58 },
59 "servicesstats": {
60 "title": "Services statistics (time in millisecond)",
61 "table": {
62 "name": "Service name",
63 "count": "Count",
64 "mean": "Mean",
65 "min": "Min",
66 "max": "Max",
67 "p50": "p50",
68 "p75": "p75",
69 "p95": "p95",
70 "p99": "p99"
71 }
72 },
73 "cache": {
74 "title": "Cache statistics",
75 "cachename": "Cache name",
76 "hits": "Cache Hits",
77 "misses": "Cache Misses",
78 "gets": "Cache Gets",
79 "puts": "Cache Puts",
80 "removals": "Cache Removals",
81 "evictions": "Cache Evictions",
82 "hitPercent": "Cache Hit %",
83 "missPercent": "Cache Miss %",
84 "averageGetTime": "Average get time (µs)",
85 "averagePutTime": "Average put time (µs)",
86 "averageRemoveTime": "Average remove time (µs)"
87 },
88 "datasource": {
89 "usage": "Connection Pool Usage",
90 "title": "DataSource statistics (time in millisecond)",
91 "name": "Pool usage",
92 "count": "Count",
93 "mean": "Mean",
94 "min": "Min",
95 "max": "Max",
96 "p50": "p50",
97 "p75": "p75",
98 "p95": "p95",
99 "p99": "p99"
100 }
101 }
102 }
File src/main/webapp/i18n/en/password.json added (mode: 100644) (index 0000000..fc9b6c9)
1 {
2 "password": {
3 "title": "Password for [<strong>{{username}}</strong>]",
4 "form": {
5 "button": "Save"
6 },
7 "messages": {
8 "error": "<strong>An error has occurred!</strong> The password could not be changed.",
9 "success": "<strong>Password changed!</strong>"
10 }
11 }
12 }
File src/main/webapp/i18n/en/pieceOfNews.json added (mode: 100644) (index 0000000..909c22f)
1 {
2 "honlapApp": {
3 "pieceOfNews": {
4 "home": {
5 "title": "Piece Of News",
6 "createLabel": "Create a new Piece Of News",
7 "createOrEditLabel": "Create or edit a Piece Of News",
8 "notFound": "No Piece Of News found"
9 },
10 "created": "A new Piece Of News is created with identifier {{ param }}",
11 "updated": "A Piece Of News is updated with identifier {{ param }}",
12 "deleted": "A Piece Of News is deleted with identifier {{ param }}",
13 "delete": {
14 "question": "Are you sure you want to delete Piece Of News {{ id }}?"
15 },
16 "detail": {
17 "title": "Piece Of News"
18 },
19 "appId": "App Id",
20 "newsDate": "News Date",
21 "headline": "Headline",
22 "content": "Content",
23 "link": "Link",
24 "publishDate": "Publish Date",
25 "createdBy": "Created By",
26 "createdDate": "Created Date",
27 "lastModifiedBy": "Last Modified By",
28 "lastModifiedDate": "Last Modified Date"
29 }
30 }
31 }
File src/main/webapp/i18n/en/register.json added (mode: 100644) (index 0000000..bbd49eb)
1 {
2 "register": {
3 "title": "Registration",
4 "form": {
5 "button": "Register"
6 },
7 "messages": {
8 "validate": {
9 "login": {
10 "required": "Your username is required.",
11 "minlength": "Your username is required to be at least 1 character.",
12 "maxlength": "Your username cannot be longer than 50 characters.",
13 "pattern": "Your username can only contain letters and digits."
14 }
15 },
16 "success": "<strong>Registration saved!</strong> Please check your email for confirmation.",
17 "error": {
18 "fail": "<strong>Registration failed!</strong> Please try again later.",
19 "userexists": "<strong>Login name already registered!</strong> Please choose another one.",
20 "emailexists": "<strong>Email is already in use!</strong> Please choose another one."
21 }
22 }
23 }
24 }
File src/main/webapp/i18n/en/reset.json added (mode: 100644) (index 0000000..4c35e9a)
1 {
2 "reset": {
3 "request": {
4 "title": "Reset your password",
5 "form": {
6 "button": "Reset password"
7 },
8 "messages": {
9 "info": "Enter the email address you used to register",
10 "success": "Check your emails for details on how to reset your password."
11 }
12 },
13 "finish": {
14 "title": "Reset password",
15 "form": {
16 "button": "Validate new password"
17 },
18 "messages": {
19 "info": "Choose a new password",
20 "success": "<strong>Your password has been reset.</strong> Please ",
21 "keymissing": "The reset key is missing.",
22 "error": "Your password couldn't be reset. Remember a password request is only valid for 24 hours."
23 }
24 }
25 }
26 }
File src/main/webapp/i18n/en/sessions.json added (mode: 100644) (index 0000000..38bf44f)
1 {
2 "sessions": {
3 "title": "Active sessions for [<strong>{{username}}</strong>]",
4 "table": {
5 "ipaddress": "IP address",
6 "useragent": "User Agent",
7 "date": "Date",
8 "button": "Invalidate"
9 },
10 "messages": {
11 "success": "<strong>Session invalidated!</strong>",
12 "error": "<strong>An error has occurred!</strong> The session could not be invalidated."
13 }
14 }
15 }
File src/main/webapp/i18n/en/settings.json added (mode: 100644) (index 0000000..508c037)
1 {
2 "settings": {
3 "title": "User settings for [<strong>{{username}}</strong>]",
4 "form": {
5 "firstname": "First Name",
6 "firstname.placeholder": "Your first name",
7 "lastname": "Last Name",
8 "lastname.placeholder": "Your last name",
9 "language": "Language",
10 "button": "Save"
11 },
12 "messages": {
13 "error": {
14 "fail": "<strong>An error has occurred!</strong> Settings could not be saved.",
15 "emailexists": "<strong>Email is already in use!</strong> Please choose another one."
16 },
17 "success": "<strong>Settings saved!</strong>",
18 "validate": {
19 "firstname": {
20 "required": "Your first name is required.",
21 "minlength": "Your first name is required to be at least 1 character",
22 "maxlength": "Your first name cannot be longer than 50 characters"
23 },
24 "lastname": {
25 "required": "Your last name is required.",
26 "minlength": "Your last name is required to be at least 1 character",
27 "maxlength": "Your last name cannot be longer than 50 characters"
28 }
29 }
30 }
31 }
32 }
File src/main/webapp/i18n/en/user-management.json added (mode: 100644) (index 0000000..4923c09)
1 {
2 "userManagement": {
3 "home": {
4 "title": "Users",
5 "createLabel": "Create a new user",
6 "createOrEditLabel": "Create or edit a user"
7 },
8 "created": "A new user is created with identifier {{ param }}",
9 "updated": "A user is updated with identifier {{ param }}",
10 "deleted": "A user is deleted with identifier {{ param }}",
11 "delete": {
12 "question": "Are you sure you want to delete user {{ login }}?"
13 },
14 "detail": {
15 "title": "User"
16 },
17 "login": "Login",
18 "firstName": "First name",
19 "lastName": "Last name",
20 "email": "Email",
21 "activated": "Activated",
22 "deactivated": "Deactivated",
23 "profiles": "Profiles",
24 "langKey": "Language",
25 "createdBy": "Created by",
26 "createdDate": "Created date",
27 "lastModifiedBy": "Modified by",
28 "lastModifiedDate": "Modified date"
29 }
30 }
File src/main/webapp/i18n/hu/activate.json added (mode: 100644) (index 0000000..33ebfa6)
1 {
2 "activate": {
3 "title": "Aktiválás",
4 "messages": {
5 "success": "<strong>A hozzáférése aktiválásra került.</strong> Kérjük ",
6 "error": "<strong>A hozzáférését nem sikerült aktiválni.</strong> Kérjük használja a regisztrációs oldalt, hogy hozzáférést igényeljen."
7 }
8 }
9 }
File src/main/webapp/i18n/hu/audits.json added (mode: 100644) (index 0000000..c2e2f44)
1 {
2 "audits": {
3 "title": "Biztonsági ellenörzés",
4 "filter": {
5 "title": "Dátum szerinti szűrés",
6 "from": "Kezdet",
7 "to": "Vég",
8 "button": {
9 "weeks": "hetek",
10 "today": "ma",
11 "clear": "törlés",
12 "close": "bezárás"
13 }
14 },
15 "table": {
16 "header": {
17 "principal": "Felhasználó",
18 "date": "Dátum",
19 "status": "Állapot",
20 "data": "Extra információ"
21 },
22 "data": {
23 "remoteAddress": "IP cím:"
24 }
25 },
26 "notFound": "No audit found"
27 }
28 }
File src/main/webapp/i18n/hu/configuration.json added (mode: 100644) (index 0000000..ee24680)
1 {
2 "configuration": {
3 "title": "Beállítások",
4 "filter": "Szűrés (prefix alapján)",
5 "table": {
6 "prefix": "Prefix",
7 "properties": "Beállítások"
8 }
9 }
10 }
File src/main/webapp/i18n/hu/error.json added (mode: 100644) (index 0000000..3f5aad1)
1 {
2 "error": {
3 "title": "Hiba!",
4 "http": {
5 "400": "Bad request.",
6 "403": "Nem vagy jogosult ennek a lapnak a megnézésére.",
7 "404": "Az oldal nem létezik.",
8 "405": "The HTTP verb you used is not supported for this URL.",
9 "500": "Internal server error."
10 },
11 "concurrencyFailure": "Another user modified this data at the same time as you. Your changes were rejected.",
12 "validation": "Validation error on the server."
13 }
14 }
File src/main/webapp/i18n/hu/global.json added (mode: 100644) (index 0000000..2dc3e9d)
1 {
2 "global": {
3 "title": "Honlap",
4 "browsehappy": "Ön <strong>elavult</strong> böngészőt használ. Kérjük <a href=\"http://browsehappy.com/?locale=hu\">frissítse böngészőjét</a> hogy javuljon a felhasználói élménye.",
5 "menu": {
6 "home": "Kezdőpont",
7 "jhipster-needle-menu-add-element": "JHipster will add additional menu entries here (do not translate!)",
8 "entities": {
9 "main": "Entitások",
10 "pieceOfNews": "Piece Of News",
11 "jhipster-needle-menu-add-entry": "JHipster will add additional entities here (do not translate!)"
12 },
13 "account": {
14 "main": "Hozzáférés",
15 "settings": "Beállítások",
16 "password": "Jelszó",
17 "sessions": "Munkamenetek",
18 "login": "Hitelesítés",
19 "logout": "Kilépés",
20 "register": "Regisztráció"
21 },
22 "admin": {
23 "main": "Adminisztráció",
24 "userManagement": "Felhasználókezelés",
25 "tracker": "Felhasználó követés",
26 "metrics": "Metrikák",
27 "health": "Akalmazás állapota",
28 "configuration": "Konfiguráció",
29 "logs": "Naplók",
30 "audits": "Nyomkövetés",
31 "apidocs": "API dokumentáció",
32 "database": "Adatbázis",
33 "jhipster-needle-menu-add-admin-element": "JHipster will add additional menu entries here (do not translate!)"
34 },
35 "language": "Nyelvek"
36 },
37 "form": {
38 "username.label": "Azonosító",
39 "username.placeholder": "Az Ön felhasználói neve",
40 "currentpassword.label": "Current password",
41 "currentpassword.placeholder": "Current password",
42 "newpassword.label": "Új jelszó",
43 "newpassword.placeholder": "Új jelszava",
44 "confirmpassword.label": "Új jelszó megerősítése",
45 "confirmpassword.placeholder": "Írja be újra a jelszavát",
46 "email.label": "Email",
47 "email.placeholder": "Az Ön email címe"
48 },
49 "messages": {
50 "info": {
51 "authenticated": {
52 "prefix": "Ha be akar ",
53 "link": "lépni",
54 "suffix": ", kipróbálás céljából használható felhasználók:<br/>- Adminisztrátor (azonosító=\"admin\" és a jelszó=\"admin\") <br/>- Felhasználó (azonosító=\"user\" és jelszó=\"user\")."
55 },
56 "register": {
57 "noaccount": "Nincs még hozzáférése?",
58 "link": "Regisztráljon"
59 }
60 },
61 "error": {
62 "dontmatch": "A jelszó és a jelszó megerősítés nem egyezik meg!"
63 },
64 "validate": {
65 "newpassword": {
66 "required": "A jelszó kötelező.",
67 "minlength": "A jelszó legalább 4 karakterből kell, hogy álljon",
68 "maxlength": "A jelszó nem lehet hosszabb mint 50 karakter",
69 "strength": "A jelszó bonyolultsága:"
70 },
71 "confirmpassword": {
72 "required": "A jelszó megerősítés kötelező.",
73 "minlength": "A jelszó megerősítés legalább 4 betűből kell, hogy álljon",
74 "maxlength": "A jelszó megerősítés nem lehet hosszabb mint 50 betű"
75 },
76 "email": {
77 "required": "Az email cím kötelező.",
78 "invalid": "A megadott email cím nem jó.",
79 "minlength": "Az email cím legalább 5 betüből kell, hogy álljon",
80 "maxlength": "Az email cím nem lehet hosszabb mint 50 betű"
81 }
82 }
83 },
84 "field": {
85 "id": "ID"
86 },
87 "ribbon": {
88 "dev": "Fejlesztői változat"
89 },
90 "item-count": "Showing {{first}} - {{second}} of {{total}} items."
91 },
92 "entity": {
93 "action": {
94 "addblob": "Fájl hozzáadása",
95 "addimage": "Kép hozzáadása",
96 "back": "Vissza",
97 "cancel": "Mégsem",
98 "delete": "Törlés",
99 "edit": "Szerkesztés",
100 "open": "Megnyitás",
101 "save": "Mentés",
102 "view": "Nézet"
103 },
104 "detail": {
105 "field": "Mező",
106 "value": "Érték"
107 },
108 "delete": {
109 "title": "Erősítse meg a törlési szándékát"
110 },
111 "validation": {
112 "required": "Ez a mező kötelező.",
113 "minlength": "Ez a mező legalább {{min}} karaktert kell, hogy tartalmazzon.",
114 "maxlength": "Ez a mező nem lehet hosszabb mint {{max}} karakter.",
115 "min": "Ennek a mezőnek a megengedett minimum értéke {{min}}.",
116 "max": "Ennek a mezőnek a megengedett maximum értéke {{max}}.",
117 "minbytes": "Ennek a mezőnek a megengedett minimum értéke {{min}} bytes.",
118 "maxbytes": "Ennek a mezőnek a megengedett maximum értéke {{max}} bytes.",
119 "pattern": "Ennek a mezőnek meg kell felelni a {{pattern}} mintának.",
120 "number": "Ennek a mezőnek számnak kell lennie.",
121 "datetimelocal": "Ennek a mezőnek dátumnak vagy időpontnak kell lennie."
122 }
123 },
124 "error": {
125 "internalServerError": "Szerver hiba",
126 "server.not.reachable": "A szerver nem elérhető",
127 "url.not.found": "Nem található",
128 "NotNull": "Az {{fieldName}} mező nem lehet üres!",
129 "Size": "A {{fieldName}} mező nem teljesíti a minimum/maximum hossz követelményeket!",
130 "userexists": "Ezzel a felhasználónévvel már regisztráltak!",
131 "emailexists": "Ezzel az email címmel már regisztráltak!",
132 "idexists": "Az új {{entityName}}-nak/nek nem lehet még ID-ja",
133 "idnull": "Invalid ID",
134 "file": {
135 "could.not.extract": "Could not extract file",
136 "not.image": "File was expected to be an image but was found to be \"{{ fileType }}\""
137 }
138 },
139 "footer": "Ez a lábléc."
140 }
File src/main/webapp/i18n/hu/health.json added (mode: 100644) (index 0000000..243aec1)
1 {
2 "health": {
3 "title": "Rendszer ellenőrzések",
4 "refresh.button": "Frissítés",
5 "stacktrace": "Stacktrace",
6 "details": {
7 "details": "Details",
8 "properties": "Properties",
9 "name": "Name",
10 "value": "Value",
11 "error": "Error"
12 },
13 "indicator": {
14 "diskSpace": "Szabad hely a diszken",
15 "mail": "Email",
16 "ping": "Application",
17 "db": "Adatbázis"
18 },
19 "table": {
20 "service": "Szervíz neve",
21 "status": "Státusz"
22 },
23 "status": {
24 "UNKNOWN": "UNKNOWN",
25 "UP": "MŰKÖDIK",
26 "DOWN": "NEM MŰKÖDIK"
27 }
28 }
29 }
File src/main/webapp/i18n/hu/home.json added (mode: 100644) (index 0000000..c407f12)
1 {
2 "home": {
3 "title": "Üdvözöljük, Java Hipster!",
4 "subtitle": "Ez a nyitóképernyőd",
5 "logged": {
6 "message": "Ön \"{{username}}\"-ként lépett be."
7 },
8 "question": "Ha bármi kérdése van a JHipster-ről:",
9 "link": {
10 "homepage": "JHipster honlapja",
11 "stackoverflow": "JHipster a Stack Overflow-n",
12 "bugtracker": "JHipster hibakövető",
13 "chat": "JHipster public chat room",
14 "follow": "lépjen kapcsolatba @jhipster -rel a Twitter-en"
15 },
16 "like": "Ha tetszik a JHipster, ne feledjen csillagot adni a",
17 "github": "GitHub-on"
18 }
19 }
File src/main/webapp/i18n/hu/login.json added (mode: 100644) (index 0000000..8c7b7f3)
1 {
2 "login": {
3 "title": "Hitelesítés",
4 "form": {
5 "password": "Jelszó",
6 "password.placeholder": "Az Ön jelszava",
7 "rememberme": "Automatikus belépés",
8 "button": "Belépés"
9 },
10 "messages": {
11 "error": {
12 "authentication": "<strong>Hitelesítés nem sikerült!</strong> Kérjük ellenörizze, hogy helyesen adta meg nevét és jelszavát, és próbálja újra."
13 }
14 },
15 "password": {
16 "forgot": "Elfelejtette a jelszavát?"
17 }
18 }
19 }
File src/main/webapp/i18n/hu/logs.json added (mode: 100644) (index 0000000..e93fee9)
1 {
2 "logs": {
3 "title": "Naplók",
4 "nbloggers": "{{ total }} naplózó található.",
5 "filter": "Szűrő",
6 "table": {
7 "name": "Név",
8 "level": "Szint"
9 }
10 }
11 }
File src/main/webapp/i18n/hu/metrics.json added (mode: 100644) (index 0000000..7a25dc2)
1 {
2 "metrics": {
3 "title": "Application Metrics",
4 "refresh.button": "Refresh",
5 "updating": "Updating...",
6 "jvm": {
7 "title": "JVM Metrics",
8 "memory": {
9 "title": "Memory",
10 "total": "Total Memory",
11 "heap": "Heap Memory",
12 "nonheap": "Non-Heap Memory"
13 },
14 "threads": {
15 "title": "Threads",
16 "all": "All",
17 "runnable": "Runnable",
18 "timedwaiting": "Timed waiting",
19 "waiting": "Waiting",
20 "blocked": "Blocked",
21 "dump": {
22 "title": "Threads dump",
23 "id": "Id: ",
24 "blockedtime": "Blocked Time",
25 "blockedcount": "Blocked Count",
26 "waitedtime": "Waited Time",
27 "waitedcount": "Waited Count",
28 "lockname": "Lock name",
29 "stacktrace": "Stacktrace",
30 "show": "Show",
31 "hide": "Hide"
32 }
33 },
34 "gc": {
35 "title": "Garbage collections",
36 "marksweepcount": "Mark Sweep count",
37 "marksweeptime": "Mark Sweep time",
38 "scavengecount": "Scavenge count",
39 "scavengetime": "Scavenge time"
40 },
41 "http": {
42 "title": "HTTP requests (events per second)",
43 "active": "Active requests:",
44 "total": "Total requests:",
45 "table": {
46 "code": "Code",
47 "count": "Count",
48 "mean": "Mean",
49 "average": "Average"
50 },
51 "code": {
52 "ok": "Ok",
53 "notfound": "Not found",
54 "servererror": "Server Error"
55 }
56 }
57 },
58 "servicesstats": {
59 "title": "Services statistics (time in millisecond)",
60 "table": {
61 "name": "Service name",
62 "count": "Count",
63 "mean": "Mean",
64 "min": "Min",
65 "max": "Max",
66 "p50": "p50",
67 "p75": "p75",
68 "p95": "p95",
69 "p99": "p99"
70 }
71 },
72 "cache": {
73 "title": "Cache statistics",
74 "cachename": "Cache name",
75 "hits": "Hits",
76 "misses": "Misses",
77 "evictions": "Evictions"
78 },
79 "datasource": {
80 "usage": "Usage",
81 "title": "DataSource statistics (time in millisecond)",
82 "name": "Pool usage",
83 "count": "Count",
84 "mean": "Mean",
85 "min": "Min",
86 "max": "Max",
87 "p50": "p50",
88 "p75": "p75",
89 "p95": "p95",
90 "p99": "p99"
91 }
92 }
93 }
File src/main/webapp/i18n/hu/password.json added (mode: 100644) (index 0000000..9d7f302)
1 {
2 "password": {
3 "title": "Jelszó [<strong>{{username}}</strong>]-nak",
4 "form": {
5 "button": "Mentés"
6 },
7 "messages": {
8 "error": "<strong>Hiba történt!</strong> A jelszót nem sikerült megváltoztatni.",
9 "success": "<strong>A jelszó megváltozott!</strong>"
10 }
11 }
12 }
File src/main/webapp/i18n/hu/pieceOfNews.json added (mode: 100644) (index 0000000..50e7037)
1 {
2 "honlapApp": {
3 "pieceOfNews": {
4 "home": {
5 "title": "PieceOfNews",
6 "createLabel": "Egy új Piece Of News létrehozása",
7 "createOrEditLabel": "Hozzon létre, vagy módosítson Piece Of Newst",
8 "notFound": "No Piece Of News found"
9 },
10 "created": "Egy új Piece Of News lett létrehozva {{ param }} azonosítóval",
11 "updated": "A Piece Of News módosítva lett {{ param }} azonosítóval",
12 "deleted": "A Piece Of News törölve lett {{ param }} azonosítóval",
13 "delete": {
14 "question": "Biztos benne, hogy törölni szeretné az Piece Of Newst {{ id }} azonosítóval?"
15 },
16 "detail": {
17 "title": "Piece Of News"
18 },
19 "appId": "App Id",
20 "newsDate": "News Date",
21 "headline": "Headline",
22 "content": "Content",
23 "link": "Link",
24 "publishDate": "Publish Date",
25 "createdBy": "Created By",
26 "createdDate": "Created Date",
27 "lastModifiedBy": "Last Modified By",
28 "lastModifiedDate": "Last Modified Date"
29 }
30 }
31 }
File src/main/webapp/i18n/hu/register.json added (mode: 100644) (index 0000000..d2ea5ff)
1 {
2 "register": {
3 "title": "Regisztráció",
4 "form": {
5 "button": "Regisztrálás"
6 },
7 "messages": {
8 "validate": {
9 "login": {
10 "required": "A felhasználói azonosító kötelezően kitöltendő.",
11 "minlength": "A felhasználói azonosító legalább 1 betűböl kell, hogy álljon",
12 "maxlength": "A felhasználói azonosító nem lehet több, mint 50 betü",
13 "pattern": "A felhasználói azonosító csak kisbetükből és számokból állhat."
14 }
15 },
16 "success": "<strong>A regisztrációt elmentettük!</strong> Kérjük ellenörizze emailjét, ahova a megerősítő emailt küldtük.",
17 "error": {
18 "fail": "<strong>A regisztráció nem sikerült!</strong> Kérjük próbálj újra később.",
19 "userexists": "<strong>A felhasználói azonosítót már más regisztrálta!</strong> Kérjük, válasszon másikat.",
20 "emailexists": "<strong>Az email cím már használatban van!</strong> Kérjük adjon meg másikat."
21 }
22 }
23 }
24 }
File src/main/webapp/i18n/hu/reset.json added (mode: 100644) (index 0000000..f4d523d)
1 {
2 "reset": {
3 "request": {
4 "title": "Jelszó visszaállítás",
5 "form": {
6 "button": "Jelszó visszaállítás"
7 },
8 "messages": {
9 "info": "Adja meg email címét, amivel regisztrált",
10 "success": "Email címére elküldtük a leírást, hogyan állíthatja vissza jelszavát."
11 }
12 },
13 "finish": {
14 "title": "Jelszó állítás",
15 "form": {
16 "button": "Ellenőrizze új jelszavát"
17 },
18 "messages": {
19 "info": "Válasszon új jelszót",
20 "success": "<strong>Az Ön jelszava meg lett változtatva.</strong> Kérjük ",
21 "keymissing": "A jelszó visszaállító kulcs hiányzik.",
22 "error": "Az Ön jelszavát nem lehetett átállítani. Kérjük vegye figyelembe, hogy a jelszó visszaállító kulcs csak 24 óráig érvényes."
23 }
24 }
25 }
26 }
File src/main/webapp/i18n/hu/sessions.json added (mode: 100644) (index 0000000..5b45f61)
1 {
2 "sessions": {
3 "title": "[<strong>{{username}}</strong>]-hoz tartozó aktív munkamenetek",
4 "table": {
5 "ipaddress": "IP cím",
6 "useragent": "Böngésző típusa",
7 "date": "Dátum",
8 "button": "Kiléptet"
9 },
10 "messages": {
11 "success": "<strong>Munkamenet be lett fejezve!</strong>",
12 "error": "<strong>Hiba történt!</strong> A munkamenetet nem sikerült befejezni."
13 }
14 }
15 }
File src/main/webapp/i18n/hu/settings.json added (mode: 100644) (index 0000000..1d8ce8f)
1 {
2 "settings": {
3 "title": "Felhasználói beállítások [<strong>{{username}}</strong>]-nak",
4 "form": {
5 "firstname": "Keresztnév",
6 "firstname.placeholder": "Az Ön keresztneve",
7 "lastname": "Családnév",
8 "lastname.placeholder": "Az Ön családneve",
9 "language": "Nyelvek",
10 "button": "Mentés"
11 },
12 "messages": {
13 "error": {
14 "fail": "<strong>Hiba történt!</strong> A beállításokat nem sikerült elmenteni.",
15 "emailexists": "<strong>Az email cím már használva van!</strong> Kérjük, válasszon másikat."
16 },
17 "success": "<strong>Beállítások elmentésre kerültek!</strong>",
18 "validate": {
19 "firstname": {
20 "required": "A keresztnév kötelező.",
21 "minlength": "A keresztnév legalább 1 betűböl kell, hogy álljon",
22 "maxlength": "A keresztnév nem lehet több, mint 50 betü"
23 },
24 "lastname": {
25 "required": "A családnév kötelező.",
26 "minlength": "A családnév legalább 1 betűböl kell, hogy álljon",
27 "maxlength": "A családnév nem lehet több, mint 50 betü"
28 }
29 }
30 }
31 }
32 }
File src/main/webapp/i18n/hu/user-management.json added (mode: 100644) (index 0000000..46903e5)
1 {
2 "userManagement": {
3 "home": {
4 "title": "Felhasználók",
5 "createLabel": "Új felhasználó",
6 "createOrEditLabel": "Felhasználó létrehozás vagy módosítás"
7 },
8 "created": "A new user is created with identifier {{ param }}",
9 "updated": "A user is updated with identifier {{ param }}",
10 "deleted": "A user is deleted with identifier {{ param }}",
11 "delete": {
12 "question": "Biztos benne, hogy törölni szeretné az {{ login }} azonosítóval rendelkező felhasználót?"
13 },
14 "detail": {
15 "title": "Felhasználó"
16 },
17 "login": "Azonosító",
18 "firstName": "Keresztnév",
19 "lastName": "Vezetéknév",
20 "email": "Email",
21 "activated": "Aktivált",
22 "deactivated": "Deaktivált",
23 "profiles": "Profil",
24 "langKey": "Nyelv",
25 "createdBy": "Létrehozó",
26 "createdDate": "Létrehozás dátuma",
27 "lastModifiedBy": "Módosította",
28 "lastModifiedDate": "Módosítás dátuma"
29 }
30 }
File src/main/webapp/index.html added (mode: 100644) (index 0000000..b7f91d4)
1 <!doctype html>
2 <html class="no-js" lang="hu" dir="ltr">
3 <head>
4 <base href="/" />
5 <meta charset="utf-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
7 <title>honlap</title>
8 <meta name="description" content="Description for honlap">
9 <meta name="google" content="notranslate">
10 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
11 <meta name="theme-color" content="#000000">
12 <link rel="shortcut icon" href="favicon.ico" />
13 <link rel="manifest" href="manifest.webapp" />
14 <link rel="stylesheet" href="content/css/loading.css">
15 <!-- jhipster-needle-add-resources-to-root - JHipster will add new resources here -->
16 </head>
17 <body>
18 <!--[if lt IE 9]>
19 <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
20 <![endif]-->
21 <auth-main>
22 <div class="app-loading">
23 <div class="lds-css ng-scope">
24 <div class="lds-pacman">
25 <div><div></div><div></div><div></div></div>
26 <div><div></div><div></div><div></div></div>
27 </div>
28 </div>
29 </div>
30 <div class="app-loading">
31 <div id="jhipster-error" style="display:none">
32 <!-- This content is for troubleshooting purpose and will be removed when app renders -->
33 <h1>An error has occurred :-(</h1>
34 <h2>Usual error causes</h2>
35 <ol>
36 <li>You started the application from an IDE and you didn't run <code style="color:red">npm start</code> or <code style="color:red">npm run webpack:build</code>.</li>
37 <li>You had a network error while running <code style="color:red">npm install</code>. If you are behind a corporate proxy, it is likely that this error was caused by your proxy. Have a look at the JHipster error logs, you will probably have the cause of the error.</li>
38 <li>You installed a Node.js version that doesn't work with JHipster: please use an LTS (long-term support) version, as it's the only version we support.</li>
39 </ol>
40 <h2>Building the client side code again</h2>
41 <p>If you want to go fast, run <code style="color:red">./mvnw</code> to build and run everything.</p>
42 <p>If you want to have more control, so you can debug your issue more easily, you should follow the following steps:</p>
43 <ol>
44 <li>Install npm dependencies with the command <code style="color:red">npm install</code></li>
45 <li>Build the client with the command <code style="color:red">npm run webpack:build</code> or <code style="color:red">npm start</code></li>
46 <li>Start the server with <code style="color:red">./mvnw</code> or using your IDE</li>
47 </ol>
48
49 <h2>Getting more help</h2>
50
51 <h3>If you have a question on how to use JHipster</h3>
52 <p>
53 Go to Stack Overflow with the <a href="http://stackoverflow.com/tags/jhipster" target="_blank" rel="noopener noreferrer">"jhipster"</a> tag.
54 </p>
55
56 <h3>If you have a bug or a feature request</h3>
57 <p>
58 First read our <a href="https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contributing guidelines</a>.
59 </p>
60 <p>
61 Then, fill a ticket on our <a href="https://github.com/jhipster/generator-jhipster/issues/new/choose" target="_blank" rel="noopener noreferrer">bug tracker</a>, we'll be happy to resolve your issue!
62 </p>
63
64 <h3>If you want to chat with contributors and other users</h3>
65 <p>
66 Join our chat room on <a href="https://gitter.im/jhipster/generator-jhipster" target="_blank" rel="noopener noreferrer">Gitter.im</a>. Please note that this is a public chat room, and that we expect you to respect other people and write in a correct English language!
67 </p>
68 <!-- end of troubleshooting content -->
69 </div>
70 </div>
71 </auth-main>
72 <noscript>
73 <h1>You must enable javascript to view this page.</h1>
74 </noscript>
75 <script type="text/javascript" language="javascript">
76 // show an error message if the app loading takes more than 5 sec
77 window.onload=function() {
78 setTimeout(showError, 4000);
79 }
80 function showError() {
81 var errorElm = document.getElementById("jhipster-error");
82 if (errorElm && errorElm.style) {
83 errorElm.style.display = "block";
84 }
85 }
86 </script>
87 <!-- uncomment this for adding service worker
88 <script>
89 if ('serviceWorker' in navigator) {
90 window.addEventListener('load', function() {
91 navigator.serviceWorker.register('/service-worker.js')
92 .then(function () {
93 console.log('Service Worker Registered');
94 });
95 });
96 }
97 </script>
98 -->
99 <!-- Google Analytics: uncomment and change UA-XXXXX-X to be your site's ID.
100 <script>
101 (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
102 function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
103 e=o.createElement(i);r=o.getElementsByTagName(i)[0];
104 e.src='//www.google-analytics.com/analytics.js';
105 r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
106 ga('create','UA-XXXXX-X');ga('send','pageview');
107 </script>-->
108 </body>
109 </html>
File src/main/webapp/manifest.webapp added (mode: 100644) (index 0000000..d498844)
1 {
2 "name": "Honlap",
3 "short_name": "Honlap",
4 "icons": [
5 {
6 "src": "./content/images/jhipster_family_member_0_head-192.png",
7 "sizes": "192x192",
8 "type": "image/png"
9 },
10 {
11 "src": "./content/images/jhipster_family_member_0_head-256.png",
12 "sizes": "256x256",
13 "type": "image/png"
14 },
15 {
16 "src": "./content/images/jhipster_family_member_0_head-384.png",
17 "sizes": "384x384",
18 "type": "image/png"
19 },
20 {
21 "src": "./content/images/jhipster_family_member_0_head-512.png",
22 "sizes": "512x512",
23 "type": "image/png"
24 }
25 ],
26 "theme_color": "#000000",
27 "background_color": "#e0e0e0",
28 "start_url": ".",
29 "display": "standalone",
30 "orientation": "portrait"
31 }
File src/main/webapp/robots.txt added (mode: 100644) (index 0000000..7cda274)
1 # robotstxt.org/
2
3 User-agent: *
4 Disallow: /api/account
5 Disallow: /api/account/change-password
6 Disallow: /api/account/sessions
7 Disallow: /api/audits/
8 Disallow: /api/logs/
9 Disallow: /api/users/
10 Disallow: /management/
11 Disallow: /v2/api-docs/
File src/main/webapp/swagger-ui/dist/images/throbber.gif added (mode: 100644) (index 0000000..0639388)
File src/main/webapp/swagger-ui/index.html added (mode: 100644) (index 0000000..ae48d7d)
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>honlap - Swagger UI</title>
6 <link rel="stylesheet" type="text/css" href="./swagger-ui.css">
7 <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32"/>
8 <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16"/>
9 </head>
10
11 <body>
12 <div id="swagger-ui"></div>
13
14 <script src="./swagger-ui-bundle.js"></script>
15 <script src="./swagger-ui-standalone-preset.js"></script>
16 <script src="./axios.min.js"></script>
17
18
19 <script type="text/javascript">
20 window.onload = function () {
21
22
23 var urls = [];
24 axios.get("/swagger-resources").then(function (response) {
25 response.data.forEach(function (resource) {
26 urls.push({"name": resource.name, "url": resource.location});
27 });
28
29 urls.sort(function (a, b) {
30 var x = a.name.toLowerCase(), y = b.name.toLowerCase();
31 return x < y ? -1 : x > y ? 1 : 0;
32 });
33
34 // Build a system
35 var ui = SwaggerUIBundle({
36 urls: urls,
37 dom_id: '#swagger-ui',
38 deepLinking: true,
39 filter: true,
40 layout: "StandaloneLayout",
41 withCredentials: true,
42 presets: [
43 SwaggerUIBundle.presets.apis,
44 SwaggerUIStandalonePreset
45 ],
46 plugins: [
47 SwaggerUIBundle.plugins.DownloadUrl
48 ],
49 requestInterceptor: function (req) {
50 var authToken = JSON.parse(localStorage.getItem("auth-authenticationtoken")
51 || sessionStorage.getItem("auth-authenticationtoken"));
52 if (authToken) {
53 req.headers['Authorization'] = "Bearer " + authToken;
54 }
55 return req;
56 }
57 });
58
59 window.ui = ui
60 });
61
62 };
63 </script>
64 </body>
65 </html>
File src/test/features/gitkeep added (mode: 100644) (index 0000000..e69de29)
File src/test/features/user/user.feature added (mode: 100644) (index 0000000..978b1d4)
1 Feature: User management
2
3 Scenario: Retrieve administrator user
4 When I search user 'admin'
5 Then the user is found
6 And his last name is 'Administrator'
File src/test/java/hu/dns/honlap/ArchTest.java added (mode: 100644) (index 0000000..e887541)
1 package hu.dns.honlap;
2
3 import com.tngtech.archunit.core.domain.JavaClasses;
4 import com.tngtech.archunit.core.importer.ClassFileImporter;
5 import com.tngtech.archunit.core.importer.ImportOption;
6 import org.junit.jupiter.api.Test;
7
8 import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
9
10 class ArchTest {
11
12 @Test
13 void servicesAndRepositoriesShouldNotDependOnWebLayer() {
14
15 JavaClasses importedClasses = new ClassFileImporter()
16 .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
17 .importPackages("hu.dns.honlap");
18
19 noClasses()
20 .that()
21 .resideInAnyPackage("hu.dns.honlap.service..")
22 .or()
23 .resideInAnyPackage("hu.dns.honlap.repository..")
24 .should().dependOnClassesThat()
25 .resideInAnyPackage("..hu.dns.honlap.web..")
26 .because("Services and repositories should not depend on web layer")
27 .check(importedClasses);
28 }
29 }
File src/test/java/hu/dns/honlap/config/NoOpMailConfiguration.java added (mode: 100644) (index 0000000..d89084e)
1 package hu.dns.honlap.config;
2
3 import hu.dns.honlap.service.MailService;
4 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration;
6
7 import static org.mockito.ArgumentMatchers.any;
8 import static org.mockito.Mockito.doNothing;
9 import static org.mockito.Mockito.mock;
10
11 @Configuration
12 public class NoOpMailConfiguration {
13 private final MailService mockMailService;
14
15 public NoOpMailConfiguration() {
16 mockMailService = mock(MailService.class);
17 doNothing().when(mockMailService).sendActivationEmail(any());
18 }
19
20 @Bean
21 public MailService mailService() {
22 return mockMailService;
23 }
24 }
File src/test/java/hu/dns/honlap/config/WebConfigurerTest.java added (mode: 100644) (index 0000000..4e4fd2b)
1 package hu.dns.honlap.config;
2
3 import io.github.jhipster.config.JHipsterConstants;
4 import io.github.jhipster.config.JHipsterProperties;
5 import io.github.jhipster.web.filter.CachingHttpHeadersFilter;
6 import org.h2.server.web.WebServlet;
7 import org.junit.jupiter.api.BeforeEach;
8 import org.junit.jupiter.api.Test;
9 import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
10 import org.springframework.http.HttpHeaders;
11 import org.springframework.mock.env.MockEnvironment;
12 import org.springframework.mock.web.MockServletContext;
13 import org.springframework.test.web.servlet.MockMvc;
14 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
15
16 import javax.servlet.*;
17 import java.io.File;
18 import java.util.*;
19
20 import static org.assertj.core.api.Assertions.assertThat;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyString;
23 import static org.mockito.Mockito.*;
24 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
25 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
26 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
27 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
28
29 /**
30 * Unit tests for the {@link WebConfigurer} class.
31 */
32 public class WebConfigurerTest {
33
34 private WebConfigurer webConfigurer;
35
36 private MockServletContext servletContext;
37
38 private MockEnvironment env;
39
40 private JHipsterProperties props;
41
42 @BeforeEach
43 public void setup() {
44 servletContext = spy(new MockServletContext());
45 doReturn(mock(FilterRegistration.Dynamic.class))
46 .when(servletContext).addFilter(anyString(), any(Filter.class));
47 doReturn(mock(ServletRegistration.Dynamic.class))
48 .when(servletContext).addServlet(anyString(), any(Servlet.class));
49
50 env = new MockEnvironment();
51 props = new JHipsterProperties();
52
53 webConfigurer = new WebConfigurer(env, props);
54 }
55
56 @Test
57 public void testStartUpProdServletContext() throws ServletException {
58 env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION);
59 webConfigurer.onStartup(servletContext);
60
61 verify(servletContext).addFilter(eq("cachingHttpHeadersFilter"), any(CachingHttpHeadersFilter.class));
62 verify(servletContext, never()).addServlet(eq("H2Console"), any(WebServlet.class));
63 }
64
65 @Test
66 public void testStartUpDevServletContext() throws ServletException {
67 env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT);
68 webConfigurer.onStartup(servletContext);
69
70 verify(servletContext, never()).addFilter(eq("cachingHttpHeadersFilter"), any(CachingHttpHeadersFilter.class));
71 verify(servletContext).addServlet(eq("H2Console"), any(WebServlet.class));
72 }
73
74 @Test
75 public void testCustomizeServletContainer() {
76 env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION);
77 UndertowServletWebServerFactory container = new UndertowServletWebServerFactory();
78 webConfigurer.customize(container);
79 assertThat(container.getMimeMappings().get("abs")).isEqualTo("audio/x-mpeg");
80 assertThat(container.getMimeMappings().get("html")).isEqualTo("text/html;charset=utf-8");
81 assertThat(container.getMimeMappings().get("json")).isEqualTo("text/html;charset=utf-8");
82 if (container.getDocumentRoot() != null) {
83 assertThat(container.getDocumentRoot()).isEqualTo(new File("target/classes/static/"));
84 }
85 }
86
87 @Test
88 public void testCorsFilterOnApiPath() throws Exception {
89 props.getCors().setAllowedOrigins(Collections.singletonList("*"));
90 props.getCors().setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
91 props.getCors().setAllowedHeaders(Collections.singletonList("*"));
92 props.getCors().setMaxAge(1800L);
93 props.getCors().setAllowCredentials(true);
94
95 MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController())
96 .addFilters(webConfigurer.corsFilter())
97 .build();
98
99 mockMvc.perform(
100 options("/api/test-cors")
101 .header(HttpHeaders.ORIGIN, "other.domain.com")
102 .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST"))
103 .andExpect(status().isOk())
104 .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "other.domain.com"))
105 .andExpect(header().string(HttpHeaders.VARY, "Origin"))
106 .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,PUT,DELETE"))
107 .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"))
108 .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "1800"));
109
110 mockMvc.perform(
111 get("/api/test-cors")
112 .header(HttpHeaders.ORIGIN, "other.domain.com"))
113 .andExpect(status().isOk())
114 .andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "other.domain.com"));
115 }
116
117 @Test
118 public void testCorsFilterOnOtherPath() throws Exception {
119 props.getCors().setAllowedOrigins(Collections.singletonList("*"));
120 props.getCors().setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
121 props.getCors().setAllowedHeaders(Collections.singletonList("*"));
122 props.getCors().setMaxAge(1800L);
123 props.getCors().setAllowCredentials(true);
124
125 MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController())
126 .addFilters(webConfigurer.corsFilter())
127 .build();
128
129 mockMvc.perform(
130 get("/test/test-cors")
131 .header(HttpHeaders.ORIGIN, "other.domain.com"))
132 .andExpect(status().isOk())
133 .andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
134 }
135
136 @Test
137 public void testCorsFilterDeactivated() throws Exception {
138 props.getCors().setAllowedOrigins(null);
139
140 MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController())
141 .addFilters(webConfigurer.corsFilter())
142 .build();
143
144 mockMvc.perform(
145 get("/api/test-cors")
146 .header(HttpHeaders.ORIGIN, "other.domain.com"))
147 .andExpect(status().isOk())
148 .andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
149 }
150
151 @Test
152 public void testCorsFilterDeactivated2() throws Exception {
153 props.getCors().setAllowedOrigins(new ArrayList<>());
154
155 MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new WebConfigurerTestController())
156 .addFilters(webConfigurer.corsFilter())
157 .build();
158
159 mockMvc.perform(
160 get("/api/test-cors")
161 .header(HttpHeaders.ORIGIN, "other.domain.com"))
162 .andExpect(status().isOk())
163 .andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN));
164 }
165 }
File src/test/java/hu/dns/honlap/config/WebConfigurerTestController.java added (mode: 100644) (index 0000000..bbca64f)
1 package hu.dns.honlap.config;
2
3 import org.springframework.web.bind.annotation.GetMapping;
4 import org.springframework.web.bind.annotation.RestController;
5
6 @RestController
7 public class WebConfigurerTestController {
8
9 @GetMapping("/api/test-cors")
10 public void testCorsOnApiPath() {
11 }
12
13 @GetMapping("/test/test-cors")
14 public void testCorsOnOtherPath() {
15 }
16 }
File src/test/java/hu/dns/honlap/config/timezone/HibernateTimeZoneIT.java added (mode: 100644) (index 0000000..789c929)
1 package hu.dns.honlap.config.timezone;
2
3 import hu.dns.honlap.HonlapApp;
4 import hu.dns.honlap.repository.timezone.DateTimeWrapper;
5 import hu.dns.honlap.repository.timezone.DateTimeWrapperRepository;
6 import org.junit.jupiter.api.BeforeEach;
7 import org.junit.jupiter.api.Test;
8 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.boot.test.context.SpringBootTest;
10 import org.springframework.jdbc.core.JdbcTemplate;
11 import org.springframework.jdbc.support.rowset.SqlRowSet;
12 import org.springframework.transaction.annotation.Transactional;
13
14 import java.time.*;
15 import java.time.format.DateTimeFormatter;
16
17 import static java.lang.String.format;
18 import static org.assertj.core.api.Assertions.assertThat;
19
20 /**
21 * Integration tests for the UTC Hibernate configuration.
22 */
23 @SpringBootTest(classes = HonlapApp.class)
24 public class HibernateTimeZoneIT {
25
26 @Autowired
27 private DateTimeWrapperRepository dateTimeWrapperRepository;
28 @Autowired
29 private JdbcTemplate jdbcTemplate;
30
31 private DateTimeWrapper dateTimeWrapper;
32 private DateTimeFormatter dateTimeFormatter;
33 private DateTimeFormatter timeFormatter;
34 private DateTimeFormatter dateFormatter;
35
36 @BeforeEach
37 public void setup() {
38 dateTimeWrapper = new DateTimeWrapper();
39 dateTimeWrapper.setInstant(Instant.parse("2014-11-12T05:50:00.0Z"));
40 dateTimeWrapper.setLocalDateTime(LocalDateTime.parse("2014-11-12T07:50:00.0"));
41 dateTimeWrapper.setOffsetDateTime(OffsetDateTime.parse("2011-12-14T08:30:00.0Z"));
42 dateTimeWrapper.setZonedDateTime(ZonedDateTime.parse("2011-12-14T08:30:00.0Z"));
43 dateTimeWrapper.setLocalTime(LocalTime.parse("14:30:00"));
44 dateTimeWrapper.setOffsetTime(OffsetTime.parse("14:30:00+02:00"));
45 dateTimeWrapper.setLocalDate(LocalDate.parse("2016-09-10"));
46
47 dateTimeFormatter = DateTimeFormatter
48 .ofPattern("yyyy-MM-dd HH:mm:ss.S")
49 .withZone(ZoneId.of("UTC"));
50
51 timeFormatter = DateTimeFormatter
52 .ofPattern("HH:mm:ss")
53 .withZone(ZoneId.of("UTC"));
54
55 dateFormatter = DateTimeFormatter
56 .ofPattern("yyyy-MM-dd");
57 }
58
59 @Test
60 @Transactional
61 public void storeInstantWithUtcConfigShouldBeStoredOnGMTTimeZone() {
62 dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper);
63
64 String request = generateSqlRequest("instant", dateTimeWrapper.getId());
65 SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request);
66 String expectedValue = dateTimeFormatter.format(dateTimeWrapper.getInstant());
67
68 assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue);
69 }
70
71 @Test
72 @Transactional
73 public void storeLocalDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() {
74 dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper);
75
76 String request = generateSqlRequest("local_date_time", dateTimeWrapper.getId());
77 SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request);
78 String expectedValue = dateTimeWrapper
79 .getLocalDateTime()
80 .atZone(ZoneId.systemDefault())
81 .format(dateTimeFormatter);
82
83 assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue);
84 }
85
86 @Test
87 @Transactional
88 public void storeOffsetDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() {
89 dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper);
90
91 String request = generateSqlRequest("offset_date_time", dateTimeWrapper.getId());
92 SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request);
93 String expectedValue = dateTimeWrapper
94 .getOffsetDateTime()
95 .format(dateTimeFormatter);
96
97 assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue);
98 }
99
100 @Test
101 @Transactional
102 public void storeZoneDateTimeWithUtcConfigShouldBeStoredOnGMTTimeZone() {
103 dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper);
104
105 String request = generateSqlRequest("zoned_date_time", dateTimeWrapper.getId());
106 SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request);
107 String expectedValue = dateTimeWrapper
108 .getZonedDateTime()
109 .format(dateTimeFormatter);
110
111 assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue);
112 }
113
114 @Test
115 @Transactional
116 public void storeLocalTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() {
117 dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper);
118
119 String request = generateSqlRequest("local_time", dateTimeWrapper.getId());
120 SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request);
121 String expectedValue = dateTimeWrapper
122 .getLocalTime()
123 .atDate(LocalDate.of(1970, Month.JANUARY, 1))
124 .atZone(ZoneId.systemDefault())
125 .format(timeFormatter);
126
127 assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue);
128 }
129
130 @Test
131 @Transactional
132 public void storeOffsetTimeWithUtcConfigShouldBeStoredOnGMTTimeZoneAccordingToHis1stJan1970Value() {
133 dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper);
134
135 String request = generateSqlRequest("offset_time", dateTimeWrapper.getId());
136 SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request);
137 String expectedValue = dateTimeWrapper
138 .getOffsetTime()
139 .toLocalTime()
140 .atDate(LocalDate.of(1970, Month.JANUARY, 1))
141 .atZone(ZoneId.systemDefault())
142 .format(timeFormatter);
143
144 assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue);
145 }
146
147 @Test
148 @Transactional
149 public void storeLocalDateWithUtcConfigShouldBeStoredWithoutTransformation() {
150 dateTimeWrapperRepository.saveAndFlush(dateTimeWrapper);
151
152 String request = generateSqlRequest("local_date", dateTimeWrapper.getId());
153 SqlRowSet resultSet = jdbcTemplate.queryForRowSet(request);
154 String expectedValue = dateTimeWrapper
155 .getLocalDate()
156 .format(dateFormatter);
157
158 assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(resultSet, expectedValue);
159 }
160
161 private String generateSqlRequest(String fieldName, long id) {
162 return format("SELECT %s FROM auth_date_time_wrapper where id=%d", fieldName, id);
163 }
164
165 private void assertThatDateStoredValueIsEqualToInsertDateValueOnGMTTimeZone(SqlRowSet sqlRowSet, String expectedValue) {
166 while (sqlRowSet.next()) {
167 String dbValue = sqlRowSet.getString(1);
168
169 assertThat(dbValue).isNotNull();
170 assertThat(dbValue).isEqualTo(expectedValue);
171 }
172 }
173 }
File src/test/java/hu/dns/honlap/cucumber/CucumberContextConfiguration.java added (mode: 100644) (index 0000000..70ca318)
1 package hu.dns.honlap.cucumber;
2
3 import hu.dns.honlap.HonlapApp;
4 import io.cucumber.java.Before;
5 import org.springframework.boot.test.context.SpringBootTest;
6 import org.springframework.test.context.ContextConfiguration;
7 import org.springframework.test.context.web.WebAppConfiguration;
8
9 @SpringBootTest
10 @WebAppConfiguration
11 @ContextConfiguration(classes = HonlapApp.class)
12 public class CucumberContextConfiguration {
13
14 @Before
15 public void setup_cucumber_spring_context() {
16 // Dummy method so cucumber will recognize this class as glue
17 // and use its context configuration.
18 }
19
20 }
File src/test/java/hu/dns/honlap/cucumber/CucumberIT.java added (mode: 100644) (index 0000000..6e70899)
1 package hu.dns.honlap.cucumber;
2
3 import org.junit.runner.RunWith;
4
5 import io.cucumber.junit.CucumberOptions;
6 import io.cucumber.junit.Cucumber;
7
8 @RunWith(Cucumber.class)
9 @CucumberOptions(plugin = "pretty", features = "src/test/features")
10 public class CucumberIT {
11
12 }
File src/test/java/hu/dns/honlap/cucumber/stepdefs/StepDefs.java added (mode: 100644) (index 0000000..bb3b798)
1 package hu.dns.honlap.cucumber.stepdefs;
2
3 import org.springframework.test.web.servlet.ResultActions;
4
5 public abstract class StepDefs {
6
7 protected ResultActions actions;
8
9 }
File src/test/java/hu/dns/honlap/cucumber/stepdefs/UserStepDefs.java added (mode: 100644) (index 0000000..8ef9d20)
1 package hu.dns.honlap.cucumber.stepdefs;
2
3 import io.cucumber.java.Before;
4 import io.cucumber.java.en.Then;
5 import io.cucumber.java.en.When;
6
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.http.MediaType;
9 import org.springframework.test.web.servlet.MockMvc;
10 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
11
12 import hu.dns.honlap.web.rest.UserResource;
13
14 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
15 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
16
17 public class UserStepDefs extends StepDefs {
18
19 @Autowired
20 private UserResource userResource;
21
22 private MockMvc restUserMockMvc;
23
24 @Before
25 public void setup() {
26 this.restUserMockMvc = MockMvcBuilders.standaloneSetup(userResource).build();
27 }
28
29 @When("I search user {string}")
30 public void i_search_user(String userId) throws Throwable {
31 actions = restUserMockMvc.perform(get("/api/users/" + userId)
32 .accept(MediaType.APPLICATION_JSON));
33 }
34
35 @Then("the user is found")
36 public void the_user_is_found() throws Throwable {
37 actions
38 .andExpect(status().isOk())
39 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE));
40 }
41
42 @Then("his last name is {string}")
43 public void his_last_name_is(String lastName) throws Throwable {
44 actions.andExpect(jsonPath("$.lastName").value(lastName));
45 }
46
47 }
File src/test/java/hu/dns/honlap/domain/PieceOfNewsTest.java added (mode: 100644) (index 0000000..17a28d9)
1 package hu.dns.honlap.domain;
2
3 import org.junit.jupiter.api.Test;
4 import static org.assertj.core.api.Assertions.assertThat;
5 import hu.dns.honlap.web.rest.TestUtil;
6
7 public class PieceOfNewsTest {
8
9 @Test
10 public void equalsVerifier() throws Exception {
11 TestUtil.equalsVerifier(PieceOfNews.class);
12 PieceOfNews pieceOfNews1 = new PieceOfNews();
13 pieceOfNews1.setId(1L);
14 PieceOfNews pieceOfNews2 = new PieceOfNews();
15 pieceOfNews2.setId(pieceOfNews1.getId());
16 assertThat(pieceOfNews1).isEqualTo(pieceOfNews2);
17 pieceOfNews2.setId(2L);
18 assertThat(pieceOfNews1).isNotEqualTo(pieceOfNews2);
19 pieceOfNews1.setId(null);
20 assertThat(pieceOfNews1).isNotEqualTo(pieceOfNews2);
21 }
22 }
File src/test/java/hu/dns/honlap/repository/CustomAuditEventRepositoryIT.java added (mode: 100644) (index 0000000..72c0a1b)
1 package hu.dns.honlap.repository;
2
3 import hu.dns.honlap.HonlapApp;
4
5 import hu.dns.honlap.config.Constants;
6 import hu.dns.honlap.config.audit.AuditEventConverter;
7 import hu.dns.honlap.domain.PersistentAuditEvent;
8 import org.junit.jupiter.api.BeforeEach;
9 import org.junit.jupiter.api.Test;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.boot.actuate.audit.AuditEvent;
12 import org.springframework.boot.test.context.SpringBootTest;
13 import org.springframework.mock.web.MockHttpServletRequest;
14 import org.springframework.mock.web.MockHttpSession;
15 import org.springframework.security.web.authentication.WebAuthenticationDetails;
16 import org.springframework.transaction.annotation.Transactional;
17
18 import javax.servlet.http.HttpSession;
19 import java.time.Instant;
20 import java.time.temporal.ChronoUnit;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static hu.dns.honlap.repository.CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH;
27
28 /**
29 * Integration tests for {@link CustomAuditEventRepository}.
30 */
31 @SpringBootTest(classes = HonlapApp.class)
32 @Transactional
33 public class CustomAuditEventRepositoryIT {
34
35 @Autowired
36 private PersistenceAuditEventRepository persistenceAuditEventRepository;
37
38 @Autowired
39 private AuditEventConverter auditEventConverter;
40
41 private CustomAuditEventRepository customAuditEventRepository;
42
43 @BeforeEach
44 public void setup() {
45 customAuditEventRepository = new CustomAuditEventRepository(persistenceAuditEventRepository, auditEventConverter);
46 persistenceAuditEventRepository.deleteAll();
47 Instant oneHourAgo = Instant.now().minusSeconds(3600);
48
49 PersistentAuditEvent testUserEvent = new PersistentAuditEvent();
50 testUserEvent.setPrincipal("test-user");
51 testUserEvent.setAuditEventType("test-type");
52 testUserEvent.setAuditEventDate(oneHourAgo);
53 Map<String, String> data = new HashMap<>();
54 data.put("test-key", "test-value");
55 testUserEvent.setData(data);
56
57 PersistentAuditEvent testOldUserEvent = new PersistentAuditEvent();
58 testOldUserEvent.setPrincipal("test-user");
59 testOldUserEvent.setAuditEventType("test-type");
60 testOldUserEvent.setAuditEventDate(oneHourAgo.minusSeconds(10000));
61
62 PersistentAuditEvent testOtherUserEvent = new PersistentAuditEvent();
63 testOtherUserEvent.setPrincipal("other-test-user");
64 testOtherUserEvent.setAuditEventType("test-type");
65 testOtherUserEvent.setAuditEventDate(oneHourAgo);
66 }
67
68 @Test
69 public void addAuditEvent() {
70 Map<String, Object> data = new HashMap<>();
71 data.put("test-key", "test-value");
72 AuditEvent event = new AuditEvent("test-user", "test-type", data);
73 customAuditEventRepository.add(event);
74 List<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findAll();
75 assertThat(persistentAuditEvents).hasSize(1);
76 PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0);
77 assertThat(persistentAuditEvent.getPrincipal()).isEqualTo(event.getPrincipal());
78 assertThat(persistentAuditEvent.getAuditEventType()).isEqualTo(event.getType());
79 assertThat(persistentAuditEvent.getData()).containsKey("test-key");
80 assertThat(persistentAuditEvent.getData().get("test-key")).isEqualTo("test-value");
81 assertThat(persistentAuditEvent.getAuditEventDate().truncatedTo(ChronoUnit.MILLIS))
82 .isEqualTo(event.getTimestamp().truncatedTo(ChronoUnit.MILLIS));
83 }
84
85 @Test
86 public void addAuditEventTruncateLargeData() {
87 Map<String, Object> data = new HashMap<>();
88 StringBuilder largeData = new StringBuilder();
89 for (int i = 0; i < EVENT_DATA_COLUMN_MAX_LENGTH + 10; i++) {
90 largeData.append("a");
91 }
92 data.put("test-key", largeData);
93 AuditEvent event = new AuditEvent("test-user", "test-type", data);
94 customAuditEventRepository.add(event);
95 List<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findAll();
96 assertThat(persistentAuditEvents).hasSize(1);
97 PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0);
98 assertThat(persistentAuditEvent.getPrincipal()).isEqualTo(event.getPrincipal());
99 assertThat(persistentAuditEvent.getAuditEventType()).isEqualTo(event.getType());
100 assertThat(persistentAuditEvent.getData()).containsKey("test-key");
101 String actualData = persistentAuditEvent.getData().get("test-key");
102 assertThat(actualData.length()).isEqualTo(EVENT_DATA_COLUMN_MAX_LENGTH);
103 assertThat(actualData).isSubstringOf(largeData);
104 assertThat(persistentAuditEvent.getAuditEventDate().truncatedTo(ChronoUnit.MILLIS))
105 .isEqualTo(event.getTimestamp().truncatedTo(ChronoUnit.MILLIS));
106 }
107
108 @Test
109 public void testAddEventWithWebAuthenticationDetails() {
110 HttpSession session = new MockHttpSession(null, "test-session-id");
111 MockHttpServletRequest request = new MockHttpServletRequest();
112 request.setSession(session);
113 request.setRemoteAddr("1.2.3.4");
114 WebAuthenticationDetails details = new WebAuthenticationDetails(request);
115 Map<String, Object> data = new HashMap<>();
116 data.put("test-key", details);
117 AuditEvent event = new AuditEvent("test-user", "test-type", data);
118 customAuditEventRepository.add(event);
119 List<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findAll();
120 assertThat(persistentAuditEvents).hasSize(1);
121 PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0);
122 assertThat(persistentAuditEvent.getData().get("remoteAddress")).isEqualTo("1.2.3.4");
123 assertThat(persistentAuditEvent.getData().get("sessionId")).isEqualTo("test-session-id");
124 }
125
126 @Test
127 public void testAddEventWithNullData() {
128 Map<String, Object> data = new HashMap<>();
129 data.put("test-key", null);
130 AuditEvent event = new AuditEvent("test-user", "test-type", data);
131 customAuditEventRepository.add(event);
132 List<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findAll();
133 assertThat(persistentAuditEvents).hasSize(1);
134 PersistentAuditEvent persistentAuditEvent = persistentAuditEvents.get(0);
135 assertThat(persistentAuditEvent.getData().get("test-key")).isEqualTo("null");
136 }
137
138 @Test
139 public void addAuditEventWithAnonymousUser() {
140 Map<String, Object> data = new HashMap<>();
141 data.put("test-key", "test-value");
142 AuditEvent event = new AuditEvent(Constants.ANONYMOUS_USER, "test-type", data);
143 customAuditEventRepository.add(event);
144 List<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findAll();
145 assertThat(persistentAuditEvents).hasSize(0);
146 }
147
148 @Test
149 public void addAuditEventWithAuthorizationFailureType() {
150 Map<String, Object> data = new HashMap<>();
151 data.put("test-key", "test-value");
152 AuditEvent event = new AuditEvent("test-user", "AUTHORIZATION_FAILURE", data);
153 customAuditEventRepository.add(event);
154 List<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findAll();
155 assertThat(persistentAuditEvents).hasSize(0);
156 }
157
158 }
File src/test/java/hu/dns/honlap/repository/timezone/DateTimeWrapper.java added (mode: 100644) (index 0000000..70442c3)
1 package hu.dns.honlap.repository.timezone;
2
3 import javax.persistence.*;
4 import java.io.Serializable;
5 import java.time.*;
6 import java.util.Objects;
7
8 @Entity
9 @Table(name = "auth_date_time_wrapper")
10 public class DateTimeWrapper implements Serializable {
11
12 private static final long serialVersionUID = 1L;
13
14 @Id
15 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
16 @SequenceGenerator(name = "sequenceGenerator")
17 private Long id;
18
19 @Column(name = "instant")
20 private Instant instant;
21
22 @Column(name = "local_date_time")
23 private LocalDateTime localDateTime;
24
25 @Column(name = "offset_date_time")
26 private OffsetDateTime offsetDateTime;
27
28 @Column(name = "zoned_date_time")
29 private ZonedDateTime zonedDateTime;
30
31 @Column(name = "local_time")
32 private LocalTime localTime;
33
34 @Column(name = "offset_time")
35 private OffsetTime offsetTime;
36
37 @Column(name = "local_date")
38 private LocalDate localDate;
39
40 public Long getId() {
41 return id;
42 }
43
44 public void setId(Long id) {
45 this.id = id;
46 }
47
48 public Instant getInstant() {
49 return instant;
50 }
51
52 public void setInstant(Instant instant) {
53 this.instant = instant;
54 }
55
56 public LocalDateTime getLocalDateTime() {
57 return localDateTime;
58 }
59
60 public void setLocalDateTime(LocalDateTime localDateTime) {
61 this.localDateTime = localDateTime;
62 }
63
64 public OffsetDateTime getOffsetDateTime() {
65 return offsetDateTime;
66 }
67
68 public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
69 this.offsetDateTime = offsetDateTime;
70 }
71
72 public ZonedDateTime getZonedDateTime() {
73 return zonedDateTime;
74 }
75
76 public void setZonedDateTime(ZonedDateTime zonedDateTime) {
77 this.zonedDateTime = zonedDateTime;
78 }
79
80 public LocalTime getLocalTime() {
81 return localTime;
82 }
83
84 public void setLocalTime(LocalTime localTime) {
85 this.localTime = localTime;
86 }
87
88 public OffsetTime getOffsetTime() {
89 return offsetTime;
90 }
91
92 public void setOffsetTime(OffsetTime offsetTime) {
93 this.offsetTime = offsetTime;
94 }
95
96 public LocalDate getLocalDate() {
97 return localDate;
98 }
99
100 public void setLocalDate(LocalDate localDate) {
101 this.localDate = localDate;
102 }
103
104 @Override
105 public boolean equals(Object o) {
106 if (this == o) {
107 return true;
108 }
109 if (o == null || getClass() != o.getClass()) {
110 return false;
111 }
112
113 DateTimeWrapper dateTimeWrapper = (DateTimeWrapper) o;
114 return !(dateTimeWrapper.getId() == null || getId() == null) && Objects.equals(getId(), dateTimeWrapper.getId());
115 }
116
117 @Override
118 public int hashCode() {
119 return Objects.hashCode(getId());
120 }
121
122 @Override
123 public String toString() {
124 return "TimeZoneTest{" +
125 "id=" + id +
126 ", instant=" + instant +
127 ", localDateTime=" + localDateTime +
128 ", offsetDateTime=" + offsetDateTime +
129 ", zonedDateTime=" + zonedDateTime +
130 '}';
131 }
132 }
File src/test/java/hu/dns/honlap/repository/timezone/DateTimeWrapperRepository.java added (mode: 100644) (index 0000000..bead6ba)
1 package hu.dns.honlap.repository.timezone;
2
3 import org.springframework.data.jpa.repository.JpaRepository;
4 import org.springframework.stereotype.Repository;
5
6 /**
7 * Spring Data JPA repository for the {@link DateTimeWrapper} entity.
8 */
9 @Repository
10 public interface DateTimeWrapperRepository extends JpaRepository<DateTimeWrapper, Long> {
11
12 }
File src/test/java/hu/dns/honlap/security/DomainUserDetailsServiceIT.java added (mode: 100644) (index 0000000..589c01d)
1 package hu.dns.honlap.security;
2
3 import hu.dns.honlap.HonlapApp;
4 import hu.dns.honlap.domain.User;
5 import hu.dns.honlap.repository.UserRepository;
6
7 import org.apache.commons.lang3.RandomStringUtils;
8 import org.junit.jupiter.api.BeforeEach;
9 import org.junit.jupiter.api.Test;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.boot.test.context.SpringBootTest;
12 import org.springframework.security.core.userdetails.UserDetails;
13 import org.springframework.security.core.userdetails.UserDetailsService;
14 import org.springframework.transaction.annotation.Transactional;
15
16 import java.util.Locale;
17
18 import static org.assertj.core.api.Assertions.assertThat;
19 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
20
21 /**
22 * Integrations tests for {@link DomainUserDetailsService}.
23 */
24 @SpringBootTest(classes = HonlapApp.class)
25 @Transactional
26 public class DomainUserDetailsServiceIT {
27
28 private static final String USER_ONE_LOGIN = "test-user-one";
29 private static final String USER_ONE_EMAIL = "test-user-one@localhost";
30 private static final String USER_TWO_LOGIN = "test-user-two";
31 private static final String USER_TWO_EMAIL = "test-user-two@localhost";
32 private static final String USER_THREE_LOGIN = "test-user-three";
33 private static final String USER_THREE_EMAIL = "test-user-three@localhost";
34
35 @Autowired
36 private UserRepository userRepository;
37
38 @Autowired
39 private UserDetailsService domainUserDetailsService;
40
41 private User userOne;
42 private User userTwo;
43 private User userThree;
44
45 @BeforeEach
46 public void init() {
47 userOne = new User();
48 userOne.setLogin(USER_ONE_LOGIN);
49 userOne.setPassword(RandomStringUtils.random(60));
50 userOne.setActivated(true);
51 userOne.setEmail(USER_ONE_EMAIL);
52 userOne.setFirstName("userOne");
53 userOne.setLastName("doe");
54 userOne.setLangKey("en");
55 userRepository.save(userOne);
56
57 userTwo = new User();
58 userTwo.setLogin(USER_TWO_LOGIN);
59 userTwo.setPassword(RandomStringUtils.random(60));
60 userTwo.setActivated(true);
61 userTwo.setEmail(USER_TWO_EMAIL);
62 userTwo.setFirstName("userTwo");
63 userTwo.setLastName("doe");
64 userTwo.setLangKey("en");
65 userRepository.save(userTwo);
66
67 userThree = new User();
68 userThree.setLogin(USER_THREE_LOGIN);
69 userThree.setPassword(RandomStringUtils.random(60));
70 userThree.setActivated(false);
71 userThree.setEmail(USER_THREE_EMAIL);
72 userThree.setFirstName("userThree");
73 userThree.setLastName("doe");
74 userThree.setLangKey("en");
75 userRepository.save(userThree);
76 }
77
78 @Test
79 @Transactional
80 public void assertThatUserCanBeFoundByLogin() {
81 UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_ONE_LOGIN);
82 assertThat(userDetails).isNotNull();
83 assertThat(userDetails.getUsername()).isEqualTo(USER_ONE_LOGIN);
84 }
85
86 @Test
87 @Transactional
88 public void assertThatUserCanBeFoundByLoginIgnoreCase() {
89 UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_ONE_LOGIN.toUpperCase(Locale.ENGLISH));
90 assertThat(userDetails).isNotNull();
91 assertThat(userDetails.getUsername()).isEqualTo(USER_ONE_LOGIN);
92 }
93
94 @Test
95 @Transactional
96 public void assertThatUserCanBeFoundByEmail() {
97 UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_TWO_EMAIL);
98 assertThat(userDetails).isNotNull();
99 assertThat(userDetails.getUsername()).isEqualTo(USER_TWO_LOGIN);
100 }
101
102 @Test
103 @Transactional
104 public void assertThatUserCanBeFoundByEmailIgnoreCase() {
105 UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_TWO_EMAIL.toUpperCase(Locale.ENGLISH));
106 assertThat(userDetails).isNotNull();
107 assertThat(userDetails.getUsername()).isEqualTo(USER_TWO_LOGIN);
108 }
109
110 @Test
111 @Transactional
112 public void assertThatEmailIsPrioritizedOverLogin() {
113 UserDetails userDetails = domainUserDetailsService.loadUserByUsername(USER_ONE_EMAIL);
114 assertThat(userDetails).isNotNull();
115 assertThat(userDetails.getUsername()).isEqualTo(USER_ONE_LOGIN);
116 }
117
118 @Test
119 @Transactional
120 public void assertThatUserNotActivatedExceptionIsThrownForNotActivatedUsers() {
121 assertThatExceptionOfType(UserNotActivatedException.class).isThrownBy(
122 () -> domainUserDetailsService.loadUserByUsername(USER_THREE_LOGIN));
123 }
124
125 }
File src/test/java/hu/dns/honlap/security/SecurityUtilsUnitTest.java added (mode: 100644) (index 0000000..9a4ec97)
1 package hu.dns.honlap.security;
2
3 import org.junit.jupiter.api.Test;
4 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
5 import org.springframework.security.core.GrantedAuthority;
6 import org.springframework.security.core.authority.SimpleGrantedAuthority;
7 import org.springframework.security.core.context.SecurityContext;
8 import org.springframework.security.core.context.SecurityContextHolder;
9
10 import java.util.ArrayList;
11 import java.util.Collection;
12 import java.util.Optional;
13
14 import static org.assertj.core.api.Assertions.assertThat;
15
16 /**
17 * Test class for the {@link SecurityUtils} utility class.
18 */
19 public class SecurityUtilsUnitTest {
20
21 @Test
22 public void testGetCurrentUserLogin() {
23 SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
24 securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("admin", "admin"));
25 SecurityContextHolder.setContext(securityContext);
26 Optional<String> login = SecurityUtils.getCurrentUserLogin();
27 assertThat(login).contains("admin");
28 }
29
30 @Test
31 public void testgetCurrentUserJWT() {
32 SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
33 securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("admin", "token"));
34 SecurityContextHolder.setContext(securityContext);
35 Optional<String> jwt = SecurityUtils.getCurrentUserJWT();
36 assertThat(jwt).contains("token");
37 }
38
39 @Test
40 public void testIsAuthenticated() {
41 SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
42 securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("admin", "admin"));
43 SecurityContextHolder.setContext(securityContext);
44 boolean isAuthenticated = SecurityUtils.isAuthenticated();
45 assertThat(isAuthenticated).isTrue();
46 }
47
48 @Test
49 public void testAnonymousIsNotAuthenticated() {
50 SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
51 Collection<GrantedAuthority> authorities = new ArrayList<>();
52 authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
53 securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities));
54 SecurityContextHolder.setContext(securityContext);
55 boolean isAuthenticated = SecurityUtils.isAuthenticated();
56 assertThat(isAuthenticated).isFalse();
57 }
58
59 @Test
60 public void testIsCurrentUserInRole() {
61 SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
62 Collection<GrantedAuthority> authorities = new ArrayList<>();
63 authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.USER));
64 securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("user", "user", authorities));
65 SecurityContextHolder.setContext(securityContext);
66
67 assertThat(SecurityUtils.isCurrentUserInRole(AuthoritiesConstants.USER)).isTrue();
68 assertThat(SecurityUtils.isCurrentUserInRole(AuthoritiesConstants.ADMIN)).isFalse();
69 }
70
71 }
File src/test/java/hu/dns/honlap/security/jwt/JWTFilterTest.java added (mode: 100644) (index 0000000..5782e0a)
1 package hu.dns.honlap.security.jwt;
2
3 import hu.dns.honlap.security.AuthoritiesConstants;
4 import io.github.jhipster.config.JHipsterProperties;
5 import io.jsonwebtoken.io.Decoders;
6 import io.jsonwebtoken.security.Keys;
7
8 import org.junit.jupiter.api.BeforeEach;
9 import org.junit.jupiter.api.Test;
10 import org.springframework.http.HttpStatus;
11 import org.springframework.mock.web.MockFilterChain;
12 import org.springframework.mock.web.MockHttpServletRequest;
13 import org.springframework.mock.web.MockHttpServletResponse;
14 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
15 import org.springframework.security.core.authority.SimpleGrantedAuthority;
16 import org.springframework.security.core.context.SecurityContextHolder;
17 import org.springframework.test.util.ReflectionTestUtils;
18
19 import java.util.Collections;
20
21 import static org.assertj.core.api.Assertions.assertThat;
22
23 public class JWTFilterTest {
24
25 private TokenProvider tokenProvider;
26
27 private JWTFilter jwtFilter;
28
29 @BeforeEach
30 public void setup() {
31 JHipsterProperties jHipsterProperties = new JHipsterProperties();
32 tokenProvider = new TokenProvider(jHipsterProperties);
33 ReflectionTestUtils.setField(tokenProvider, "key",
34 Keys.hmacShaKeyFor(Decoders.BASE64
35 .decode("fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8")));
36
37 ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", 60000);
38 jwtFilter = new JWTFilter(tokenProvider);
39 SecurityContextHolder.getContext().setAuthentication(null);
40 }
41
42 @Test
43 public void testJWTFilter() throws Exception {
44 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
45 "test-user",
46 "test-password",
47 Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.USER))
48 );
49 String jwt = tokenProvider.createToken(authentication, false);
50 MockHttpServletRequest request = new MockHttpServletRequest();
51 request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt);
52 request.setRequestURI("/api/test");
53 MockHttpServletResponse response = new MockHttpServletResponse();
54 MockFilterChain filterChain = new MockFilterChain();
55 jwtFilter.doFilter(request, response, filterChain);
56 assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
57 assertThat(SecurityContextHolder.getContext().getAuthentication().getName()).isEqualTo("test-user");
58 assertThat(SecurityContextHolder.getContext().getAuthentication().getCredentials().toString()).isEqualTo(jwt);
59 }
60
61 @Test
62 public void testJWTFilterInvalidToken() throws Exception {
63 String jwt = "wrong_jwt";
64 MockHttpServletRequest request = new MockHttpServletRequest();
65 request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt);
66 request.setRequestURI("/api/test");
67 MockHttpServletResponse response = new MockHttpServletResponse();
68 MockFilterChain filterChain = new MockFilterChain();
69 jwtFilter.doFilter(request, response, filterChain);
70 assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
71 assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
72 }
73
74 @Test
75 public void testJWTFilterMissingAuthorization() throws Exception {
76 MockHttpServletRequest request = new MockHttpServletRequest();
77 request.setRequestURI("/api/test");
78 MockHttpServletResponse response = new MockHttpServletResponse();
79 MockFilterChain filterChain = new MockFilterChain();
80 jwtFilter.doFilter(request, response, filterChain);
81 assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
82 assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
83 }
84
85 @Test
86 public void testJWTFilterMissingToken() throws Exception {
87 MockHttpServletRequest request = new MockHttpServletRequest();
88 request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Bearer ");
89 request.setRequestURI("/api/test");
90 MockHttpServletResponse response = new MockHttpServletResponse();
91 MockFilterChain filterChain = new MockFilterChain();
92 jwtFilter.doFilter(request, response, filterChain);
93 assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
94 assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
95 }
96
97 @Test
98 public void testJWTFilterWrongScheme() throws Exception {
99 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
100 "test-user",
101 "test-password",
102 Collections.singletonList(new SimpleGrantedAuthority(AuthoritiesConstants.USER))
103 );
104 String jwt = tokenProvider.createToken(authentication, false);
105 MockHttpServletRequest request = new MockHttpServletRequest();
106 request.addHeader(JWTFilter.AUTHORIZATION_HEADER, "Basic " + jwt);
107 request.setRequestURI("/api/test");
108 MockHttpServletResponse response = new MockHttpServletResponse();
109 MockFilterChain filterChain = new MockFilterChain();
110 jwtFilter.doFilter(request, response, filterChain);
111 assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
112 assertThat(SecurityContextHolder.getContext().getAuthentication()).isNull();
113 }
114
115 }
File src/test/java/hu/dns/honlap/security/jwt/TokenProviderTest.java added (mode: 100644) (index 0000000..93157ac)
1 package hu.dns.honlap.security.jwt;
2
3 import hu.dns.honlap.security.AuthoritiesConstants;
4
5 import java.security.Key;
6 import java.util.*;
7
8 import org.junit.jupiter.api.BeforeEach;
9 import org.junit.jupiter.api.Test;
10 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
11 import org.springframework.security.core.Authentication;
12 import org.springframework.security.core.GrantedAuthority;
13 import org.springframework.security.core.authority.SimpleGrantedAuthority;
14 import org.springframework.test.util.ReflectionTestUtils;
15
16 import io.github.jhipster.config.JHipsterProperties;
17 import io.jsonwebtoken.Jwts;
18 import io.jsonwebtoken.SignatureAlgorithm;
19 import io.jsonwebtoken.io.Decoders;
20 import io.jsonwebtoken.security.Keys;
21
22 import static org.assertj.core.api.Assertions.assertThat;
23
24 public class TokenProviderTest {
25
26 private static final long ONE_MINUTE = 60000;
27
28 private Key key;
29 private TokenProvider tokenProvider;
30
31 @BeforeEach
32 public void setup() {
33 tokenProvider = new TokenProvider( new JHipsterProperties());
34 key = Keys.hmacShaKeyFor(Decoders.BASE64
35 .decode("fd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"));
36
37 ReflectionTestUtils.setField(tokenProvider, "key", key);
38 ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", ONE_MINUTE);
39 }
40
41 @Test
42 public void testReturnFalseWhenJWThasInvalidSignature() {
43 boolean isTokenValid = tokenProvider.validateToken(createTokenWithDifferentSignature());
44
45 assertThat(isTokenValid).isEqualTo(false);
46 }
47
48 @Test
49 public void testReturnFalseWhenJWTisMalformed() {
50 Authentication authentication = createAuthentication();
51 String token = tokenProvider.createToken(authentication, false);
52 String invalidToken = token.substring(1);
53 boolean isTokenValid = tokenProvider.validateToken(invalidToken);
54
55 assertThat(isTokenValid).isEqualTo(false);
56 }
57
58 @Test
59 public void testReturnFalseWhenJWTisExpired() {
60 ReflectionTestUtils.setField(tokenProvider, "tokenValidityInMilliseconds", -ONE_MINUTE);
61
62 Authentication authentication = createAuthentication();
63 String token = tokenProvider.createToken(authentication, false);
64
65 boolean isTokenValid = tokenProvider.validateToken(token);
66
67 assertThat(isTokenValid).isEqualTo(false);
68 }
69
70 @Test
71 public void testReturnFalseWhenJWTisUnsupported() {
72 String unsupportedToken = createUnsupportedToken();
73
74 boolean isTokenValid = tokenProvider.validateToken(unsupportedToken);
75
76 assertThat(isTokenValid).isEqualTo(false);
77 }
78
79 @Test
80 public void testReturnFalseWhenJWTisInvalid() {
81 boolean isTokenValid = tokenProvider.validateToken("");
82
83 assertThat(isTokenValid).isEqualTo(false);
84 }
85
86 private Authentication createAuthentication() {
87 Collection<GrantedAuthority> authorities = new ArrayList<>();
88 authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
89 return new UsernamePasswordAuthenticationToken("anonymous", "anonymous", authorities);
90 }
91
92 private String createUnsupportedToken() {
93 return Jwts.builder()
94 .setPayload("payload")
95 .signWith(key, SignatureAlgorithm.HS512)
96 .compact();
97 }
98
99 private String createTokenWithDifferentSignature() {
100 Key otherKey = Keys.hmacShaKeyFor(Decoders.BASE64
101 .decode("Xfd54a45s65fds737b9aafcb3412e07ed99b267f33413274720ddbb7f6c5e64e9f14075f2d7ed041592f0b7657baf8"));
102
103 return Jwts.builder()
104 .setSubject("anonymous")
105 .signWith(otherKey, SignatureAlgorithm.HS512)
106 .setExpiration(new Date(new Date().getTime() + ONE_MINUTE))
107 .compact();
108 }
109 }
File src/test/java/hu/dns/honlap/service/AuditEventServiceIT.java added (mode: 100644) (index 0000000..6ec7776)
1 package hu.dns.honlap.service;
2
3 import hu.dns.honlap.domain.PersistentAuditEvent;
4 import hu.dns.honlap.repository.PersistenceAuditEventRepository;
5 import hu.dns.honlap.HonlapApp;
6 import io.github.jhipster.config.JHipsterProperties;
7 import org.junit.jupiter.api.BeforeEach;
8 import org.junit.jupiter.api.Test;
9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.boot.test.context.SpringBootTest;
11 import org.springframework.transaction.annotation.Transactional;
12 import java.time.Instant;
13 import java.time.temporal.ChronoUnit;
14
15 import static org.assertj.core.api.Assertions.assertThat;
16
17 /**
18 * Integration tests for {@link AuditEventService}.
19 */
20 @SpringBootTest(classes = HonlapApp.class)
21 @Transactional
22 public class AuditEventServiceIT {
23 @Autowired
24 private AuditEventService auditEventService;
25
26 @Autowired
27 private PersistenceAuditEventRepository persistenceAuditEventRepository;
28
29 @Autowired
30 private JHipsterProperties jHipsterProperties;
31
32 private PersistentAuditEvent auditEventOld;
33
34 private PersistentAuditEvent auditEventWithinRetention;
35
36 private PersistentAuditEvent auditEventNew;
37
38 @BeforeEach
39 public void init() {
40 auditEventOld = new PersistentAuditEvent();
41 auditEventOld.setAuditEventDate(Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod() + 1, ChronoUnit.DAYS));
42 auditEventOld.setPrincipal("test-user-old");
43 auditEventOld.setAuditEventType("test-type");
44
45 auditEventWithinRetention = new PersistentAuditEvent();
46 auditEventWithinRetention.setAuditEventDate(Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod() - 1, ChronoUnit.DAYS));
47 auditEventWithinRetention.setPrincipal("test-user-retention");
48 auditEventWithinRetention.setAuditEventType("test-type");
49
50 auditEventNew = new PersistentAuditEvent();
51 auditEventNew.setAuditEventDate(Instant.now());
52 auditEventNew.setPrincipal("test-user-new");
53 auditEventNew.setAuditEventType("test-type");
54 }
55
56 @Test
57 @Transactional
58 public void verifyOldAuditEventsAreDeleted() {
59 persistenceAuditEventRepository.deleteAll();
60 persistenceAuditEventRepository.save(auditEventOld);
61 persistenceAuditEventRepository.save(auditEventWithinRetention);
62 persistenceAuditEventRepository.save(auditEventNew);
63
64 persistenceAuditEventRepository.flush();
65 auditEventService.removeOldAuditEvents();
66 persistenceAuditEventRepository.flush();
67
68 assertThat(persistenceAuditEventRepository.findAll().size()).isEqualTo(2);
69 assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-old")).isEmpty();
70 assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-retention")).isNotEmpty();
71 assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-new")).isNotEmpty();
72 }
73 }
File src/test/java/hu/dns/honlap/service/MailServiceIT.java added (mode: 100644) (index 0000000..1c35ab9)
1 package hu.dns.honlap.service;
2
3 import hu.dns.honlap.config.Constants;
4
5 import hu.dns.honlap.HonlapApp;
6 import hu.dns.honlap.domain.User;
7 import io.github.jhipster.config.JHipsterProperties;
8 import org.junit.jupiter.api.BeforeEach;
9 import org.junit.jupiter.api.Test;
10 import org.mockito.ArgumentCaptor;
11 import org.mockito.Captor;
12 import org.mockito.MockitoAnnotations;
13 import org.mockito.Spy;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.boot.test.context.SpringBootTest;
16 import org.springframework.context.MessageSource;
17 import org.springframework.mail.MailSendException;
18 import org.springframework.mail.javamail.JavaMailSenderImpl;
19 import org.thymeleaf.spring5.SpringTemplateEngine;
20
21 import javax.mail.Multipart;
22 import javax.mail.internet.MimeBodyPart;
23 import javax.mail.internet.MimeMessage;
24 import javax.mail.internet.MimeMultipart;
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.InputStreamReader;
29 import java.net.URI;
30 import java.net.URL;
31 import java.nio.charset.Charset;
32 import java.util.Properties;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35
36 import static org.assertj.core.api.Assertions.*;
37 import static org.mockito.ArgumentMatchers.any;
38 import static org.mockito.Mockito.*;
39
40 /**
41 * Integration tests for {@link MailService}.
42 */
43 @SpringBootTest(classes = HonlapApp.class)
44 public class MailServiceIT {
45
46 private static final String[] languages = {
47 "hu",
48 "en"
49 // jhipster-needle-i18n-language-constant - JHipster will add/remove languages in this array
50 };
51 private static final Pattern PATTERN_LOCALE_3 = Pattern.compile("([a-z]{2})-([a-zA-Z]{4})-([a-z]{2})");
52 private static final Pattern PATTERN_LOCALE_2 = Pattern.compile("([a-z]{2})-([a-z]{2})");
53
54 @Autowired
55 private JHipsterProperties jHipsterProperties;
56
57 @Autowired
58 private MessageSource messageSource;
59
60 @Autowired
61 private SpringTemplateEngine templateEngine;
62
63 @Spy
64 private JavaMailSenderImpl javaMailSender;
65
66 @Captor
67 private ArgumentCaptor<MimeMessage> messageCaptor;
68
69 private MailService mailService;
70
71 @BeforeEach
72 public void setup() {
73 MockitoAnnotations.initMocks(this);
74 doNothing().when(javaMailSender).send(any(MimeMessage.class));
75 mailService = new MailService(jHipsterProperties, javaMailSender, messageSource, templateEngine);
76 }
77
78 @Test
79 public void testSendEmail() throws Exception {
80 mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", false, false);
81 verify(javaMailSender).send(messageCaptor.capture());
82 MimeMessage message = messageCaptor.getValue();
83 assertThat(message.getSubject()).isEqualTo("testSubject");
84 assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com");
85 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
86 assertThat(message.getContent()).isInstanceOf(String.class);
87 assertThat(message.getContent().toString()).isEqualTo("testContent");
88 assertThat(message.getDataHandler().getContentType()).isEqualTo("text/plain; charset=UTF-8");
89 }
90
91 @Test
92 public void testSendHtmlEmail() throws Exception {
93 mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", false, true);
94 verify(javaMailSender).send(messageCaptor.capture());
95 MimeMessage message = messageCaptor.getValue();
96 assertThat(message.getSubject()).isEqualTo("testSubject");
97 assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com");
98 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
99 assertThat(message.getContent()).isInstanceOf(String.class);
100 assertThat(message.getContent().toString()).isEqualTo("testContent");
101 assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8");
102 }
103
104 @Test
105 public void testSendMultipartEmail() throws Exception {
106 mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", true, false);
107 verify(javaMailSender).send(messageCaptor.capture());
108 MimeMessage message = messageCaptor.getValue();
109 MimeMultipart mp = (MimeMultipart) message.getContent();
110 MimeBodyPart part = (MimeBodyPart) ((MimeMultipart) mp.getBodyPart(0).getContent()).getBodyPart(0);
111 ByteArrayOutputStream aos = new ByteArrayOutputStream();
112 part.writeTo(aos);
113 assertThat(message.getSubject()).isEqualTo("testSubject");
114 assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com");
115 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
116 assertThat(message.getContent()).isInstanceOf(Multipart.class);
117 assertThat(aos.toString()).isEqualTo("\r\ntestContent");
118 assertThat(part.getDataHandler().getContentType()).isEqualTo("text/plain; charset=UTF-8");
119 }
120
121 @Test
122 public void testSendMultipartHtmlEmail() throws Exception {
123 mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", true, true);
124 verify(javaMailSender).send(messageCaptor.capture());
125 MimeMessage message = messageCaptor.getValue();
126 MimeMultipart mp = (MimeMultipart) message.getContent();
127 MimeBodyPart part = (MimeBodyPart) ((MimeMultipart) mp.getBodyPart(0).getContent()).getBodyPart(0);
128 ByteArrayOutputStream aos = new ByteArrayOutputStream();
129 part.writeTo(aos);
130 assertThat(message.getSubject()).isEqualTo("testSubject");
131 assertThat(message.getAllRecipients()[0].toString()).isEqualTo("john.doe@example.com");
132 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
133 assertThat(message.getContent()).isInstanceOf(Multipart.class);
134 assertThat(aos.toString()).isEqualTo("\r\ntestContent");
135 assertThat(part.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8");
136 }
137
138 @Test
139 public void testSendEmailFromTemplate() throws Exception {
140 User user = new User();
141 user.setLogin("john");
142 user.setEmail("john.doe@example.com");
143 user.setLangKey("en");
144 mailService.sendEmailFromTemplate(user, "mail/testEmail", "email.test.title");
145 verify(javaMailSender).send(messageCaptor.capture());
146 MimeMessage message = messageCaptor.getValue();
147 assertThat(message.getSubject()).isEqualTo("test title");
148 assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail());
149 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
150 assertThat(message.getContent().toString()).isEqualToNormalizingNewlines("<html>test title, http://127.0.0.1:8080, john</html>\n");
151 assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8");
152 }
153
154 @Test
155 public void testSendActivationEmail() throws Exception {
156 User user = new User();
157 user.setLangKey(Constants.DEFAULT_LANGUAGE);
158 user.setLogin("john");
159 user.setEmail("john.doe@example.com");
160 mailService.sendActivationEmail(user);
161 verify(javaMailSender).send(messageCaptor.capture());
162 MimeMessage message = messageCaptor.getValue();
163 assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail());
164 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
165 assertThat(message.getContent().toString()).isNotEmpty();
166 assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8");
167 }
168
169 @Test
170 public void testCreationEmail() throws Exception {
171 User user = new User();
172 user.setLangKey(Constants.DEFAULT_LANGUAGE);
173 user.setLogin("john");
174 user.setEmail("john.doe@example.com");
175 mailService.sendCreationEmail(user);
176 verify(javaMailSender).send(messageCaptor.capture());
177 MimeMessage message = messageCaptor.getValue();
178 assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail());
179 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
180 assertThat(message.getContent().toString()).isNotEmpty();
181 assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8");
182 }
183
184 @Test
185 public void testSendPasswordResetMail() throws Exception {
186 User user = new User();
187 user.setLangKey(Constants.DEFAULT_LANGUAGE);
188 user.setLogin("john");
189 user.setEmail("john.doe@example.com");
190 mailService.sendPasswordResetMail(user);
191 verify(javaMailSender).send(messageCaptor.capture());
192 MimeMessage message = messageCaptor.getValue();
193 assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail());
194 assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom());
195 assertThat(message.getContent().toString()).isNotEmpty();
196 assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8");
197 }
198
199 @Test
200 public void testSendEmailWithException() {
201 doThrow(MailSendException.class).when(javaMailSender).send(any(MimeMessage.class));
202 try {
203 mailService.sendEmail("john.doe@example.com", "testSubject", "testContent", false, false);
204 } catch (Exception e) {
205 fail("Exception shouldn't have been thrown");
206 }
207 }
208
209 @Test
210 public void testSendLocalizedEmailForAllSupportedLanguages() throws Exception {
211 User user = new User();
212 user.setLogin("john");
213 user.setEmail("john.doe@example.com");
214 for (String langKey : languages) {
215 user.setLangKey(langKey);
216 mailService.sendEmailFromTemplate(user, "mail/testEmail", "email.test.title");
217 verify(javaMailSender, atLeastOnce()).send(messageCaptor.capture());
218 MimeMessage message = messageCaptor.getValue();
219
220 String propertyFilePath = "i18n/messages_" + getJavaLocale(langKey) + ".properties";
221 URL resource = this.getClass().getClassLoader().getResource(propertyFilePath);
222 File file = new File(new URI(resource.getFile()).getPath());
223 Properties properties = new Properties();
224 properties.load(new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")));
225
226 String emailTitle = (String) properties.get("email.test.title");
227 assertThat(message.getSubject()).isEqualTo(emailTitle);
228 assertThat(message.getContent().toString()).isEqualToNormalizingNewlines("<html>" + emailTitle + ", http://127.0.0.1:8080, john</html>\n");
229 }
230 }
231
232 /**
233 * Convert a lang key to the Java locale.
234 */
235 private String getJavaLocale(String langKey) {
236 String javaLangKey = langKey;
237 Matcher matcher2 = PATTERN_LOCALE_2.matcher(langKey);
238 if (matcher2.matches()) {
239 javaLangKey = matcher2.group(1) + "_"+ matcher2.group(2).toUpperCase();
240 }
241 Matcher matcher3 = PATTERN_LOCALE_3.matcher(langKey);
242 if (matcher3.matches()) {
243 javaLangKey = matcher3.group(1) + "_" + matcher3.group(2) + "_" + matcher3.group(3).toUpperCase();
244 }
245 return javaLangKey;
246 }
247 }
File src/test/java/hu/dns/honlap/service/UserServiceIT.java added (mode: 100644) (index 0000000..1af0638)
1 package hu.dns.honlap.service;
2
3 import hu.dns.honlap.HonlapApp;
4 import hu.dns.honlap.config.Constants;
5 import hu.dns.honlap.domain.User;
6 import hu.dns.honlap.repository.UserRepository;
7 import hu.dns.honlap.service.dto.UserDTO;
8
9 import io.github.jhipster.security.RandomUtil;
10
11 import org.apache.commons.lang3.RandomStringUtils;
12 import org.junit.jupiter.api.BeforeEach;
13 import org.junit.jupiter.api.Test;
14 import org.mockito.Mock;
15 import org.springframework.beans.factory.annotation.Autowired;
16 import org.springframework.boot.test.context.SpringBootTest;
17 import org.springframework.data.auditing.AuditingHandler;
18 import org.springframework.data.auditing.DateTimeProvider;
19 import org.springframework.data.domain.Page;
20 import org.springframework.data.domain.PageRequest;
21 import org.springframework.transaction.annotation.Transactional;
22 import java.time.Instant;
23 import java.time.temporal.ChronoUnit;
24 import java.time.LocalDateTime;
25 import java.util.Optional;
26 import java.util.List;
27
28 import static org.assertj.core.api.Assertions.assertThat;
29 import static org.mockito.Mockito.when;
30
31 /**
32 * Integration tests for {@link UserService}.
33 */
34 @SpringBootTest(classes = HonlapApp.class)
35 @Transactional
36 public class UserServiceIT {
37
38 private static final String DEFAULT_LOGIN = "johndoe";
39
40 private static final String DEFAULT_EMAIL = "johndoe@localhost";
41
42 private static final String DEFAULT_FIRSTNAME = "john";
43
44 private static final String DEFAULT_LASTNAME = "doe";
45
46 private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50";
47
48 private static final String DEFAULT_LANGKEY = "dummy";
49
50 @Autowired
51 private UserRepository userRepository;
52
53 @Autowired
54 private UserService userService;
55
56 @Autowired
57 private AuditingHandler auditingHandler;
58
59 @Mock
60 private DateTimeProvider dateTimeProvider;
61
62 private User user;
63
64 @BeforeEach
65 public void init() {
66 user = new User();
67 user.setLogin(DEFAULT_LOGIN);
68 user.setPassword(RandomStringUtils.random(60));
69 user.setActivated(true);
70 user.setEmail(DEFAULT_EMAIL);
71 user.setFirstName(DEFAULT_FIRSTNAME);
72 user.setLastName(DEFAULT_LASTNAME);
73 user.setImageUrl(DEFAULT_IMAGEURL);
74 user.setLangKey(DEFAULT_LANGKEY);
75
76 when(dateTimeProvider.getNow()).thenReturn(Optional.of(LocalDateTime.now()));
77 auditingHandler.setDateTimeProvider(dateTimeProvider);
78 }
79
80 @Test
81 @Transactional
82 public void assertThatUserMustExistToResetPassword() {
83 userRepository.saveAndFlush(user);
84 Optional<User> maybeUser = userService.requestPasswordReset("invalid.login@localhost");
85 assertThat(maybeUser).isNotPresent();
86
87 maybeUser = userService.requestPasswordReset(user.getEmail());
88 assertThat(maybeUser).isPresent();
89 assertThat(maybeUser.orElse(null).getEmail()).isEqualTo(user.getEmail());
90 assertThat(maybeUser.orElse(null).getResetDate()).isNotNull();
91 assertThat(maybeUser.orElse(null).getResetKey()).isNotNull();
92 }
93
94 @Test
95 @Transactional
96 public void assertThatOnlyActivatedUserCanRequestPasswordReset() {
97 user.setActivated(false);
98 userRepository.saveAndFlush(user);
99
100 Optional<User> maybeUser = userService.requestPasswordReset(user.getLogin());
101 assertThat(maybeUser).isNotPresent();
102 userRepository.delete(user);
103 }
104
105 @Test
106 @Transactional
107 public void assertThatResetKeyMustNotBeOlderThan24Hours() {
108 Instant daysAgo = Instant.now().minus(25, ChronoUnit.HOURS);
109 String resetKey = RandomUtil.generateResetKey();
110 user.setActivated(true);
111 user.setResetDate(daysAgo);
112 user.setResetKey(resetKey);
113 userRepository.saveAndFlush(user);
114
115 Optional<User> maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey());
116 assertThat(maybeUser).isNotPresent();
117 userRepository.delete(user);
118 }
119
120 @Test
121 @Transactional
122 public void assertThatResetKeyMustBeValid() {
123 Instant daysAgo = Instant.now().minus(25, ChronoUnit.HOURS);
124 user.setActivated(true);
125 user.setResetDate(daysAgo);
126 user.setResetKey("1234");
127 userRepository.saveAndFlush(user);
128
129 Optional<User> maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey());
130 assertThat(maybeUser).isNotPresent();
131 userRepository.delete(user);
132 }
133
134 @Test
135 @Transactional
136 public void assertThatUserCanResetPassword() {
137 String oldPassword = user.getPassword();
138 Instant daysAgo = Instant.now().minus(2, ChronoUnit.HOURS);
139 String resetKey = RandomUtil.generateResetKey();
140 user.setActivated(true);
141 user.setResetDate(daysAgo);
142 user.setResetKey(resetKey);
143 userRepository.saveAndFlush(user);
144
145 Optional<User> maybeUser = userService.completePasswordReset("johndoe2", user.getResetKey());
146 assertThat(maybeUser).isPresent();
147 assertThat(maybeUser.orElse(null).getResetDate()).isNull();
148 assertThat(maybeUser.orElse(null).getResetKey()).isNull();
149 assertThat(maybeUser.orElse(null).getPassword()).isNotEqualTo(oldPassword);
150
151 userRepository.delete(user);
152 }
153
154 @Test
155 @Transactional
156 public void assertThatNotActivatedUsersWithNotNullActivationKeyCreatedBefore3DaysAreDeleted() {
157 Instant now = Instant.now();
158 when(dateTimeProvider.getNow()).thenReturn(Optional.of(now.minus(4, ChronoUnit.DAYS)));
159 user.setActivated(false);
160 user.setActivationKey(RandomStringUtils.random(20));
161 User dbUser = userRepository.saveAndFlush(user);
162 dbUser.setCreatedDate(now.minus(4, ChronoUnit.DAYS));
163 userRepository.saveAndFlush(user);
164 List<User> users = userRepository.findAllByActivatedIsFalseAndActivationKeyIsNotNullAndCreatedDateBefore(now.minus(3, ChronoUnit.DAYS));
165 assertThat(users).isNotEmpty();
166 userService.removeNotActivatedUsers();
167 users = userRepository.findAllByActivatedIsFalseAndActivationKeyIsNotNullAndCreatedDateBefore(now.minus(3, ChronoUnit.DAYS));
168 assertThat(users).isEmpty();
169 }
170
171 @Test
172 @Transactional
173 public void assertThatNotActivatedUsersWithNullActivationKeyCreatedBefore3DaysAreNotDeleted() {
174 Instant now = Instant.now();
175 when(dateTimeProvider.getNow()).thenReturn(Optional.of(now.minus(4, ChronoUnit.DAYS)));
176 user.setActivated(false);
177 User dbUser = userRepository.saveAndFlush(user);
178 dbUser.setCreatedDate(now.minus(4, ChronoUnit.DAYS));
179 userRepository.saveAndFlush(user);
180 List<User> users = userRepository.findAllByActivatedIsFalseAndActivationKeyIsNotNullAndCreatedDateBefore(now.minus(3, ChronoUnit.DAYS));
181 assertThat(users).isEmpty();
182 userService.removeNotActivatedUsers();
183 Optional<User> maybeDbUser = userRepository.findById(dbUser.getId());
184 assertThat(maybeDbUser).contains(dbUser);
185 }
186
187 @Test
188 @Transactional
189 public void assertThatAnonymousUserIsNotGet() {
190 user.setLogin(Constants.ANONYMOUS_USER);
191 if (!userRepository.findOneByLogin(Constants.ANONYMOUS_USER).isPresent()) {
192 userRepository.saveAndFlush(user);
193 }
194 final PageRequest pageable = PageRequest.of(0, (int) userRepository.count());
195 final Page<UserDTO> allManagedUsers = userService.getAllManagedUsers(pageable);
196 assertThat(allManagedUsers.getContent().stream()
197 .noneMatch(user -> Constants.ANONYMOUS_USER.equals(user.getLogin())))
198 .isTrue();
199 }
200
201 }
File src/test/java/hu/dns/honlap/service/mapper/UserMapperTest.java added (mode: 100644) (index 0000000..8b4fdd9)
1 package hu.dns.honlap.service.mapper;
2
3 import hu.dns.honlap.domain.User;
4 import hu.dns.honlap.service.dto.UserDTO;
5 import org.apache.commons.lang3.RandomStringUtils;
6 import org.junit.jupiter.api.BeforeEach;
7 import org.junit.jupiter.api.Test;
8
9 import java.util.ArrayList;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Set;
13
14 import static org.assertj.core.api.Assertions.assertThat;
15
16 /**
17 * Unit tests for {@link UserMapper}.
18 */
19 public class UserMapperTest {
20
21 private static final String DEFAULT_LOGIN = "johndoe";
22 private static final Long DEFAULT_ID = 1L;
23
24 private UserMapper userMapper;
25 private User user;
26 private UserDTO userDto;
27
28 @BeforeEach
29 public void init() {
30 userMapper = new UserMapper();
31 user = new User();
32 user.setLogin(DEFAULT_LOGIN);
33 user.setPassword(RandomStringUtils.random(60));
34 user.setActivated(true);
35 user.setEmail("johndoe@localhost");
36 user.setFirstName("john");
37 user.setLastName("doe");
38 user.setImageUrl("image_url");
39 user.setLangKey("en");
40
41 userDto = new UserDTO(user);
42 }
43
44 @Test
45 public void usersToUserDTOsShouldMapOnlyNonNullUsers() {
46 List<User> users = new ArrayList<>();
47 users.add(user);
48 users.add(null);
49
50 List<UserDTO> userDTOS = userMapper.usersToUserDTOs(users);
51
52 assertThat(userDTOS).isNotEmpty();
53 assertThat(userDTOS).size().isEqualTo(1);
54 }
55
56 @Test
57 public void userDTOsToUsersShouldMapOnlyNonNullUsers() {
58 List<UserDTO> usersDto = new ArrayList<>();
59 usersDto.add(userDto);
60 usersDto.add(null);
61
62 List<User> users = userMapper.userDTOsToUsers(usersDto);
63
64 assertThat(users).isNotEmpty();
65 assertThat(users).size().isEqualTo(1);
66 }
67
68 @Test
69 public void userDTOsToUsersWithAuthoritiesStringShouldMapToUsersWithAuthoritiesDomain() {
70 Set<String> authoritiesAsString = new HashSet<>();
71 authoritiesAsString.add("ADMIN");
72 userDto.setAuthorities(authoritiesAsString);
73
74 List<UserDTO> usersDto = new ArrayList<>();
75 usersDto.add(userDto);
76
77 List<User> users = userMapper.userDTOsToUsers(usersDto);
78
79 assertThat(users).isNotEmpty();
80 assertThat(users).size().isEqualTo(1);
81 assertThat(users.get(0).getAuthorities()).isNotNull();
82 assertThat(users.get(0).getAuthorities()).isNotEmpty();
83 assertThat(users.get(0).getAuthorities().iterator().next().getName()).isEqualTo("ADMIN");
84 }
85
86 @Test
87 public void userDTOsToUsersMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() {
88 userDto.setAuthorities(null);
89
90 List<UserDTO> usersDto = new ArrayList<>();
91 usersDto.add(userDto);
92
93 List<User> users = userMapper.userDTOsToUsers(usersDto);
94
95 assertThat(users).isNotEmpty();
96 assertThat(users).size().isEqualTo(1);
97 assertThat(users.get(0).getAuthorities()).isNotNull();
98 assertThat(users.get(0).getAuthorities()).isEmpty();
99 }
100
101 @Test
102 public void userDTOToUserMapWithAuthoritiesStringShouldReturnUserWithAuthorities() {
103 Set<String> authoritiesAsString = new HashSet<>();
104 authoritiesAsString.add("ADMIN");
105 userDto.setAuthorities(authoritiesAsString);
106
107 User user = userMapper.userDTOToUser(userDto);
108
109 assertThat(user).isNotNull();
110 assertThat(user.getAuthorities()).isNotNull();
111 assertThat(user.getAuthorities()).isNotEmpty();
112 assertThat(user.getAuthorities().iterator().next().getName()).isEqualTo("ADMIN");
113 }
114
115 @Test
116 public void userDTOToUserMapWithNullAuthoritiesStringShouldReturnUserWithEmptyAuthorities() {
117 userDto.setAuthorities(null);
118
119 User user = userMapper.userDTOToUser(userDto);
120
121 assertThat(user).isNotNull();
122 assertThat(user.getAuthorities()).isNotNull();
123 assertThat(user.getAuthorities()).isEmpty();
124 }
125
126 @Test
127 public void userDTOToUserMapWithNullUserShouldReturnNull() {
128 assertThat(userMapper.userDTOToUser(null)).isNull();
129 }
130
131 @Test
132 public void testUserFromId() {
133 assertThat(userMapper.userFromId(DEFAULT_ID).getId()).isEqualTo(DEFAULT_ID);
134 assertThat(userMapper.userFromId(null)).isNull();
135 }
136 }
File src/test/java/hu/dns/honlap/web/rest/AccountResourceIT.java added (mode: 100644) (index 0000000..865be6e)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.HonlapApp;
4 import hu.dns.honlap.config.Constants;
5 import hu.dns.honlap.domain.Authority;
6 import hu.dns.honlap.domain.User;
7 import hu.dns.honlap.repository.AuthorityRepository;
8 import hu.dns.honlap.repository.UserRepository;
9 import hu.dns.honlap.security.AuthoritiesConstants;
10 import hu.dns.honlap.service.UserService;
11 import hu.dns.honlap.service.dto.PasswordChangeDTO;
12 import hu.dns.honlap.service.dto.UserDTO;
13 import hu.dns.honlap.web.rest.vm.KeyAndPasswordVM;
14 import hu.dns.honlap.web.rest.vm.ManagedUserVM;
15 import org.apache.commons.lang3.RandomStringUtils;
16
17 import org.junit.jupiter.api.BeforeEach;
18 import org.junit.jupiter.api.Test;
19 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
21 import org.springframework.boot.test.context.SpringBootTest;
22 import org.springframework.http.MediaType;
23 import org.springframework.http.converter.HttpMessageConverter;
24 import org.springframework.security.crypto.password.PasswordEncoder;
25 import org.springframework.security.test.context.support.WithMockUser;
26 import org.springframework.test.web.servlet.MockMvc;
27 import org.springframework.transaction.annotation.Transactional;
28
29 import java.time.Instant;
30 import java.util.*;
31
32 import static org.assertj.core.api.Assertions.assertThat;
33 import static hu.dns.honlap.web.rest.AccountResourceIT.TEST_USER_LOGIN;
34 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
35 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
36
37 /**
38 * Integration tests for the {@link AccountResource} REST controller.
39 */
40 @AutoConfigureMockMvc
41 @WithMockUser(value = TEST_USER_LOGIN)
42 @SpringBootTest(classes = HonlapApp.class)
43 public class AccountResourceIT {
44 static final String TEST_USER_LOGIN = "test";
45
46 @Autowired
47 private UserRepository userRepository;
48
49 @Autowired
50 private AuthorityRepository authorityRepository;
51
52 @Autowired
53 private UserService userService;
54
55 @Autowired
56 private PasswordEncoder passwordEncoder;
57
58 @Autowired
59 private MockMvc restAccountMockMvc;
60
61 @Test
62 @WithUnauthenticatedMockUser
63 public void testNonAuthenticatedUser() throws Exception {
64 restAccountMockMvc.perform(get("/api/authenticate")
65 .accept(MediaType.APPLICATION_JSON))
66 .andExpect(status().isOk())
67 .andExpect(content().string(""));
68 }
69
70 @Test
71 public void testAuthenticatedUser() throws Exception {
72 restAccountMockMvc.perform(get("/api/authenticate")
73 .with(request -> {
74 request.setRemoteUser(TEST_USER_LOGIN);
75 return request;
76 })
77 .accept(MediaType.APPLICATION_JSON))
78 .andExpect(status().isOk())
79 .andExpect(content().string(TEST_USER_LOGIN));
80 }
81
82 @Test
83 public void testGetExistingAccount() throws Exception {
84 Set<String> authorities = new HashSet<>();
85 authorities.add(AuthoritiesConstants.ADMIN);
86
87 UserDTO user = new UserDTO();
88 user.setLogin(TEST_USER_LOGIN);
89 user.setFirstName("john");
90 user.setLastName("doe");
91 user.setEmail("john.doe@jhipster.com");
92 user.setImageUrl("http://placehold.it/50x50");
93 user.setLangKey("en");
94 user.setAuthorities(authorities);
95 userService.createUser(user);
96
97 restAccountMockMvc.perform(get("/api/account")
98 .accept(MediaType.APPLICATION_JSON))
99 .andExpect(status().isOk())
100 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
101 .andExpect(jsonPath("$.login").value(TEST_USER_LOGIN))
102 .andExpect(jsonPath("$.firstName").value("john"))
103 .andExpect(jsonPath("$.lastName").value("doe"))
104 .andExpect(jsonPath("$.email").value("john.doe@jhipster.com"))
105 .andExpect(jsonPath("$.imageUrl").value("http://placehold.it/50x50"))
106 .andExpect(jsonPath("$.langKey").value("en"))
107 .andExpect(jsonPath("$.authorities").value(AuthoritiesConstants.ADMIN));
108 }
109
110 @Test
111 public void testGetUnknownAccount() throws Exception {
112 restAccountMockMvc.perform(get("/api/account")
113 .accept(MediaType.APPLICATION_PROBLEM_JSON))
114 .andExpect(status().isInternalServerError());
115 }
116
117 @Test
118 @Transactional
119 public void testRegisterValid() throws Exception {
120 ManagedUserVM validUser = new ManagedUserVM();
121 validUser.setLogin("test-register-valid");
122 validUser.setPassword("password");
123 validUser.setFirstName("Alice");
124 validUser.setLastName("Test");
125 validUser.setEmail("test-register-valid@example.com");
126 validUser.setImageUrl("http://placehold.it/50x50");
127 validUser.setLangKey(Constants.DEFAULT_LANGUAGE);
128 validUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
129 assertThat(userRepository.findOneByLogin("test-register-valid").isPresent()).isFalse();
130
131 restAccountMockMvc.perform(
132 post("/api/register")
133 .contentType(MediaType.APPLICATION_JSON)
134 .content(TestUtil.convertObjectToJsonBytes(validUser)))
135 .andExpect(status().isCreated());
136
137 assertThat(userRepository.findOneByLogin("test-register-valid").isPresent()).isTrue();
138 }
139
140 @Test
141 @Transactional
142 public void testRegisterInvalidLogin() throws Exception {
143 ManagedUserVM invalidUser = new ManagedUserVM();
144 invalidUser.setLogin("funky-log!n");// <-- invalid
145 invalidUser.setPassword("password");
146 invalidUser.setFirstName("Funky");
147 invalidUser.setLastName("One");
148 invalidUser.setEmail("funky@example.com");
149 invalidUser.setActivated(true);
150 invalidUser.setImageUrl("http://placehold.it/50x50");
151 invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE);
152 invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
153
154 restAccountMockMvc.perform(
155 post("/api/register")
156 .contentType(MediaType.APPLICATION_JSON)
157 .content(TestUtil.convertObjectToJsonBytes(invalidUser)))
158 .andExpect(status().isBadRequest());
159
160 Optional<User> user = userRepository.findOneByEmailIgnoreCase("funky@example.com");
161 assertThat(user.isPresent()).isFalse();
162 }
163
164 @Test
165 @Transactional
166 public void testRegisterInvalidEmail() throws Exception {
167 ManagedUserVM invalidUser = new ManagedUserVM();
168 invalidUser.setLogin("bob");
169 invalidUser.setPassword("password");
170 invalidUser.setFirstName("Bob");
171 invalidUser.setLastName("Green");
172 invalidUser.setEmail("invalid");// <-- invalid
173 invalidUser.setActivated(true);
174 invalidUser.setImageUrl("http://placehold.it/50x50");
175 invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE);
176 invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
177
178 restAccountMockMvc.perform(
179 post("/api/register")
180 .contentType(MediaType.APPLICATION_JSON)
181 .content(TestUtil.convertObjectToJsonBytes(invalidUser)))
182 .andExpect(status().isBadRequest());
183
184 Optional<User> user = userRepository.findOneByLogin("bob");
185 assertThat(user.isPresent()).isFalse();
186 }
187
188 @Test
189 @Transactional
190 public void testRegisterInvalidPassword() throws Exception {
191 ManagedUserVM invalidUser = new ManagedUserVM();
192 invalidUser.setLogin("bob");
193 invalidUser.setPassword("123");// password with only 3 digits
194 invalidUser.setFirstName("Bob");
195 invalidUser.setLastName("Green");
196 invalidUser.setEmail("bob@example.com");
197 invalidUser.setActivated(true);
198 invalidUser.setImageUrl("http://placehold.it/50x50");
199 invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE);
200 invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
201
202 restAccountMockMvc.perform(
203 post("/api/register")
204 .contentType(MediaType.APPLICATION_JSON)
205 .content(TestUtil.convertObjectToJsonBytes(invalidUser)))
206 .andExpect(status().isBadRequest());
207
208 Optional<User> user = userRepository.findOneByLogin("bob");
209 assertThat(user.isPresent()).isFalse();
210 }
211
212 @Test
213 @Transactional
214 public void testRegisterNullPassword() throws Exception {
215 ManagedUserVM invalidUser = new ManagedUserVM();
216 invalidUser.setLogin("bob");
217 invalidUser.setPassword(null);// invalid null password
218 invalidUser.setFirstName("Bob");
219 invalidUser.setLastName("Green");
220 invalidUser.setEmail("bob@example.com");
221 invalidUser.setActivated(true);
222 invalidUser.setImageUrl("http://placehold.it/50x50");
223 invalidUser.setLangKey(Constants.DEFAULT_LANGUAGE);
224 invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
225
226 restAccountMockMvc.perform(
227 post("/api/register")
228 .contentType(MediaType.APPLICATION_JSON)
229 .content(TestUtil.convertObjectToJsonBytes(invalidUser)))
230 .andExpect(status().isBadRequest());
231
232 Optional<User> user = userRepository.findOneByLogin("bob");
233 assertThat(user.isPresent()).isFalse();
234 }
235
236 @Test
237 @Transactional
238 public void testRegisterDuplicateLogin() throws Exception {
239 // First registration
240 ManagedUserVM firstUser = new ManagedUserVM();
241 firstUser.setLogin("alice");
242 firstUser.setPassword("password");
243 firstUser.setFirstName("Alice");
244 firstUser.setLastName("Something");
245 firstUser.setEmail("alice@example.com");
246 firstUser.setImageUrl("http://placehold.it/50x50");
247 firstUser.setLangKey(Constants.DEFAULT_LANGUAGE);
248 firstUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
249
250 // Duplicate login, different email
251 ManagedUserVM secondUser = new ManagedUserVM();
252 secondUser.setLogin(firstUser.getLogin());
253 secondUser.setPassword(firstUser.getPassword());
254 secondUser.setFirstName(firstUser.getFirstName());
255 secondUser.setLastName(firstUser.getLastName());
256 secondUser.setEmail("alice2@example.com");
257 secondUser.setImageUrl(firstUser.getImageUrl());
258 secondUser.setLangKey(firstUser.getLangKey());
259 secondUser.setCreatedBy(firstUser.getCreatedBy());
260 secondUser.setCreatedDate(firstUser.getCreatedDate());
261 secondUser.setLastModifiedBy(firstUser.getLastModifiedBy());
262 secondUser.setLastModifiedDate(firstUser.getLastModifiedDate());
263 secondUser.setAuthorities(new HashSet<>(firstUser.getAuthorities()));
264
265 // First user
266 restAccountMockMvc.perform(
267 post("/api/register")
268 .contentType(MediaType.APPLICATION_JSON)
269 .content(TestUtil.convertObjectToJsonBytes(firstUser)))
270 .andExpect(status().isCreated());
271
272 // Second (non activated) user
273 restAccountMockMvc.perform(
274 post("/api/register")
275 .contentType(MediaType.APPLICATION_JSON)
276 .content(TestUtil.convertObjectToJsonBytes(secondUser)))
277 .andExpect(status().isCreated());
278
279 Optional<User> testUser = userRepository.findOneByEmailIgnoreCase("alice2@example.com");
280 assertThat(testUser.isPresent()).isTrue();
281 testUser.get().setActivated(true);
282 userRepository.save(testUser.get());
283
284 // Second (already activated) user
285 restAccountMockMvc.perform(
286 post("/api/register")
287 .contentType(MediaType.APPLICATION_JSON)
288 .content(TestUtil.convertObjectToJsonBytes(secondUser)))
289 .andExpect(status().is4xxClientError());
290 }
291
292 @Test
293 @Transactional
294 public void testRegisterDuplicateEmail() throws Exception {
295 // First user
296 ManagedUserVM firstUser = new ManagedUserVM();
297 firstUser.setLogin("test-register-duplicate-email");
298 firstUser.setPassword("password");
299 firstUser.setFirstName("Alice");
300 firstUser.setLastName("Test");
301 firstUser.setEmail("test-register-duplicate-email@example.com");
302 firstUser.setImageUrl("http://placehold.it/50x50");
303 firstUser.setLangKey(Constants.DEFAULT_LANGUAGE);
304 firstUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
305
306 // Register first user
307 restAccountMockMvc.perform(
308 post("/api/register")
309 .contentType(MediaType.APPLICATION_JSON)
310 .content(TestUtil.convertObjectToJsonBytes(firstUser)))
311 .andExpect(status().isCreated());
312
313 Optional<User> testUser1 = userRepository.findOneByLogin("test-register-duplicate-email");
314 assertThat(testUser1.isPresent()).isTrue();
315
316 // Duplicate email, different login
317 ManagedUserVM secondUser = new ManagedUserVM();
318 secondUser.setLogin("test-register-duplicate-email-2");
319 secondUser.setPassword(firstUser.getPassword());
320 secondUser.setFirstName(firstUser.getFirstName());
321 secondUser.setLastName(firstUser.getLastName());
322 secondUser.setEmail(firstUser.getEmail());
323 secondUser.setImageUrl(firstUser.getImageUrl());
324 secondUser.setLangKey(firstUser.getLangKey());
325 secondUser.setAuthorities(new HashSet<>(firstUser.getAuthorities()));
326
327 // Register second (non activated) user
328 restAccountMockMvc.perform(
329 post("/api/register")
330 .contentType(MediaType.APPLICATION_JSON)
331 .content(TestUtil.convertObjectToJsonBytes(secondUser)))
332 .andExpect(status().isCreated());
333
334 Optional<User> testUser2 = userRepository.findOneByLogin("test-register-duplicate-email");
335 assertThat(testUser2.isPresent()).isFalse();
336
337 Optional<User> testUser3 = userRepository.findOneByLogin("test-register-duplicate-email-2");
338 assertThat(testUser3.isPresent()).isTrue();
339
340 // Duplicate email - with uppercase email address
341 ManagedUserVM userWithUpperCaseEmail = new ManagedUserVM();
342 userWithUpperCaseEmail.setId(firstUser.getId());
343 userWithUpperCaseEmail.setLogin("test-register-duplicate-email-3");
344 userWithUpperCaseEmail.setPassword(firstUser.getPassword());
345 userWithUpperCaseEmail.setFirstName(firstUser.getFirstName());
346 userWithUpperCaseEmail.setLastName(firstUser.getLastName());
347 userWithUpperCaseEmail.setEmail("TEST-register-duplicate-email@example.com");
348 userWithUpperCaseEmail.setImageUrl(firstUser.getImageUrl());
349 userWithUpperCaseEmail.setLangKey(firstUser.getLangKey());
350 userWithUpperCaseEmail.setAuthorities(new HashSet<>(firstUser.getAuthorities()));
351
352 // Register third (not activated) user
353 restAccountMockMvc.perform(
354 post("/api/register")
355 .contentType(MediaType.APPLICATION_JSON)
356 .content(TestUtil.convertObjectToJsonBytes(userWithUpperCaseEmail)))
357 .andExpect(status().isCreated());
358
359 Optional<User> testUser4 = userRepository.findOneByLogin("test-register-duplicate-email-3");
360 assertThat(testUser4.isPresent()).isTrue();
361 assertThat(testUser4.get().getEmail()).isEqualTo("test-register-duplicate-email@example.com");
362
363 testUser4.get().setActivated(true);
364 userService.updateUser((new UserDTO(testUser4.get())));
365
366 // Register 4th (already activated) user
367 restAccountMockMvc.perform(
368 post("/api/register")
369 .contentType(MediaType.APPLICATION_JSON)
370 .content(TestUtil.convertObjectToJsonBytes(secondUser)))
371 .andExpect(status().is4xxClientError());
372 }
373
374 @Test
375 @Transactional
376 public void testRegisterAdminIsIgnored() throws Exception {
377 ManagedUserVM validUser = new ManagedUserVM();
378 validUser.setLogin("badguy");
379 validUser.setPassword("password");
380 validUser.setFirstName("Bad");
381 validUser.setLastName("Guy");
382 validUser.setEmail("badguy@example.com");
383 validUser.setActivated(true);
384 validUser.setImageUrl("http://placehold.it/50x50");
385 validUser.setLangKey(Constants.DEFAULT_LANGUAGE);
386 validUser.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN));
387
388 restAccountMockMvc.perform(
389 post("/api/register")
390 .contentType(MediaType.APPLICATION_JSON)
391 .content(TestUtil.convertObjectToJsonBytes(validUser)))
392 .andExpect(status().isCreated());
393
394 Optional<User> userDup = userRepository.findOneByLogin("badguy");
395 assertThat(userDup.isPresent()).isTrue();
396 assertThat(userDup.get().getAuthorities()).hasSize(1)
397 .containsExactly(authorityRepository.findById(AuthoritiesConstants.USER).get());
398 }
399
400 @Test
401 @Transactional
402 public void testActivateAccount() throws Exception {
403 final String activationKey = "some activation key";
404 User user = new User();
405 user.setLogin("activate-account");
406 user.setEmail("activate-account@example.com");
407 user.setPassword(RandomStringUtils.random(60));
408 user.setActivated(false);
409 user.setActivationKey(activationKey);
410
411 userRepository.saveAndFlush(user);
412
413 restAccountMockMvc.perform(get("/api/activate?key={activationKey}", activationKey))
414 .andExpect(status().isOk());
415
416 user = userRepository.findOneByLogin(user.getLogin()).orElse(null);
417 assertThat(user.getActivated()).isTrue();
418 }
419
420 @Test
421 @Transactional
422 public void testActivateAccountWithWrongKey() throws Exception {
423 restAccountMockMvc.perform(get("/api/activate?key=wrongActivationKey"))
424 .andExpect(status().isInternalServerError());
425 }
426
427 @Test
428 @Transactional
429 @WithMockUser("save-account")
430 public void testSaveAccount() throws Exception {
431 User user = new User();
432 user.setLogin("save-account");
433 user.setEmail("save-account@example.com");
434 user.setPassword(RandomStringUtils.random(60));
435 user.setActivated(true);
436
437 userRepository.saveAndFlush(user);
438
439 UserDTO userDTO = new UserDTO();
440 userDTO.setLogin("not-used");
441 userDTO.setFirstName("firstname");
442 userDTO.setLastName("lastname");
443 userDTO.setEmail("save-account@example.com");
444 userDTO.setActivated(false);
445 userDTO.setImageUrl("http://placehold.it/50x50");
446 userDTO.setLangKey(Constants.DEFAULT_LANGUAGE);
447 userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN));
448
449 restAccountMockMvc.perform(
450 post("/api/account")
451 .contentType(MediaType.APPLICATION_JSON)
452 .content(TestUtil.convertObjectToJsonBytes(userDTO)))
453 .andExpect(status().isOk());
454
455 User updatedUser = userRepository.findOneByLogin(user.getLogin()).orElse(null);
456 assertThat(updatedUser.getFirstName()).isEqualTo(userDTO.getFirstName());
457 assertThat(updatedUser.getLastName()).isEqualTo(userDTO.getLastName());
458 assertThat(updatedUser.getEmail()).isEqualTo(userDTO.getEmail());
459 assertThat(updatedUser.getLangKey()).isEqualTo(userDTO.getLangKey());
460 assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword());
461 assertThat(updatedUser.getImageUrl()).isEqualTo(userDTO.getImageUrl());
462 assertThat(updatedUser.getActivated()).isEqualTo(true);
463 assertThat(updatedUser.getAuthorities()).isEmpty();
464 }
465
466 @Test
467 @Transactional
468 @WithMockUser("save-invalid-email")
469 public void testSaveInvalidEmail() throws Exception {
470 User user = new User();
471 user.setLogin("save-invalid-email");
472 user.setEmail("save-invalid-email@example.com");
473 user.setPassword(RandomStringUtils.random(60));
474 user.setActivated(true);
475
476 userRepository.saveAndFlush(user);
477
478 UserDTO userDTO = new UserDTO();
479 userDTO.setLogin("not-used");
480 userDTO.setFirstName("firstname");
481 userDTO.setLastName("lastname");
482 userDTO.setEmail("invalid email");
483 userDTO.setActivated(false);
484 userDTO.setImageUrl("http://placehold.it/50x50");
485 userDTO.setLangKey(Constants.DEFAULT_LANGUAGE);
486 userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN));
487
488 restAccountMockMvc.perform(
489 post("/api/account")
490 .contentType(MediaType.APPLICATION_JSON)
491 .content(TestUtil.convertObjectToJsonBytes(userDTO)))
492 .andExpect(status().isBadRequest());
493
494 assertThat(userRepository.findOneByEmailIgnoreCase("invalid email")).isNotPresent();
495 }
496
497 @Test
498 @Transactional
499 @WithMockUser("save-existing-email")
500 public void testSaveExistingEmail() throws Exception {
501 User user = new User();
502 user.setLogin("save-existing-email");
503 user.setEmail("save-existing-email@example.com");
504 user.setPassword(RandomStringUtils.random(60));
505 user.setActivated(true);
506
507 userRepository.saveAndFlush(user);
508
509 User anotherUser = new User();
510 anotherUser.setLogin("save-existing-email2");
511 anotherUser.setEmail("save-existing-email2@example.com");
512 anotherUser.setPassword(RandomStringUtils.random(60));
513 anotherUser.setActivated(true);
514
515 userRepository.saveAndFlush(anotherUser);
516
517 UserDTO userDTO = new UserDTO();
518 userDTO.setLogin("not-used");
519 userDTO.setFirstName("firstname");
520 userDTO.setLastName("lastname");
521 userDTO.setEmail("save-existing-email2@example.com");
522 userDTO.setActivated(false);
523 userDTO.setImageUrl("http://placehold.it/50x50");
524 userDTO.setLangKey(Constants.DEFAULT_LANGUAGE);
525 userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN));
526
527 restAccountMockMvc.perform(
528 post("/api/account")
529 .contentType(MediaType.APPLICATION_JSON)
530 .content(TestUtil.convertObjectToJsonBytes(userDTO)))
531 .andExpect(status().isBadRequest());
532
533 User updatedUser = userRepository.findOneByLogin("save-existing-email").orElse(null);
534 assertThat(updatedUser.getEmail()).isEqualTo("save-existing-email@example.com");
535 }
536
537 @Test
538 @Transactional
539 @WithMockUser("save-existing-email-and-login")
540 public void testSaveExistingEmailAndLogin() throws Exception {
541 User user = new User();
542 user.setLogin("save-existing-email-and-login");
543 user.setEmail("save-existing-email-and-login@example.com");
544 user.setPassword(RandomStringUtils.random(60));
545 user.setActivated(true);
546
547 userRepository.saveAndFlush(user);
548
549 UserDTO userDTO = new UserDTO();
550 userDTO.setLogin("not-used");
551 userDTO.setFirstName("firstname");
552 userDTO.setLastName("lastname");
553 userDTO.setEmail("save-existing-email-and-login@example.com");
554 userDTO.setActivated(false);
555 userDTO.setImageUrl("http://placehold.it/50x50");
556 userDTO.setLangKey(Constants.DEFAULT_LANGUAGE);
557 userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN));
558
559 restAccountMockMvc.perform(
560 post("/api/account")
561 .contentType(MediaType.APPLICATION_JSON)
562 .content(TestUtil.convertObjectToJsonBytes(userDTO)))
563 .andExpect(status().isOk());
564
565 User updatedUser = userRepository.findOneByLogin("save-existing-email-and-login").orElse(null);
566 assertThat(updatedUser.getEmail()).isEqualTo("save-existing-email-and-login@example.com");
567 }
568
569 @Test
570 @Transactional
571 @WithMockUser("change-password-wrong-existing-password")
572 public void testChangePasswordWrongExistingPassword() throws Exception {
573 User user = new User();
574 String currentPassword = RandomStringUtils.random(60);
575 user.setPassword(passwordEncoder.encode(currentPassword));
576 user.setLogin("change-password-wrong-existing-password");
577 user.setEmail("change-password-wrong-existing-password@example.com");
578 userRepository.saveAndFlush(user);
579
580 restAccountMockMvc.perform(post("/api/account/change-password")
581 .contentType(MediaType.APPLICATION_JSON)
582 .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO("1"+currentPassword, "new password")))
583 )
584 .andExpect(status().isBadRequest());
585
586 User updatedUser = userRepository.findOneByLogin("change-password-wrong-existing-password").orElse(null);
587 assertThat(passwordEncoder.matches("new password", updatedUser.getPassword())).isFalse();
588 assertThat(passwordEncoder.matches(currentPassword, updatedUser.getPassword())).isTrue();
589 }
590
591 @Test
592 @Transactional
593 @WithMockUser("change-password")
594 public void testChangePassword() throws Exception {
595 User user = new User();
596 String currentPassword = RandomStringUtils.random(60);
597 user.setPassword(passwordEncoder.encode(currentPassword));
598 user.setLogin("change-password");
599 user.setEmail("change-password@example.com");
600 userRepository.saveAndFlush(user);
601
602 restAccountMockMvc.perform(post("/api/account/change-password")
603 .contentType(MediaType.APPLICATION_JSON)
604 .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, "new password")))
605 )
606 .andExpect(status().isOk());
607
608 User updatedUser = userRepository.findOneByLogin("change-password").orElse(null);
609 assertThat(passwordEncoder.matches("new password", updatedUser.getPassword())).isTrue();
610 }
611
612 @Test
613 @Transactional
614 @WithMockUser("change-password-too-small")
615 public void testChangePasswordTooSmall() throws Exception {
616 User user = new User();
617 String currentPassword = RandomStringUtils.random(60);
618 user.setPassword(passwordEncoder.encode(currentPassword));
619 user.setLogin("change-password-too-small");
620 user.setEmail("change-password-too-small@example.com");
621 userRepository.saveAndFlush(user);
622
623 String newPassword = RandomStringUtils.random(ManagedUserVM.PASSWORD_MIN_LENGTH - 1);
624
625 restAccountMockMvc.perform(post("/api/account/change-password")
626 .contentType(MediaType.APPLICATION_JSON)
627 .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, newPassword)))
628 )
629 .andExpect(status().isBadRequest());
630
631 User updatedUser = userRepository.findOneByLogin("change-password-too-small").orElse(null);
632 assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword());
633 }
634
635 @Test
636 @Transactional
637 @WithMockUser("change-password-too-long")
638 public void testChangePasswordTooLong() throws Exception {
639 User user = new User();
640 String currentPassword = RandomStringUtils.random(60);
641 user.setPassword(passwordEncoder.encode(currentPassword));
642 user.setLogin("change-password-too-long");
643 user.setEmail("change-password-too-long@example.com");
644 userRepository.saveAndFlush(user);
645
646 String newPassword = RandomStringUtils.random(ManagedUserVM.PASSWORD_MAX_LENGTH + 1);
647
648 restAccountMockMvc.perform(post("/api/account/change-password")
649 .contentType(MediaType.APPLICATION_JSON)
650 .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, newPassword)))
651 )
652 .andExpect(status().isBadRequest());
653
654 User updatedUser = userRepository.findOneByLogin("change-password-too-long").orElse(null);
655 assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword());
656 }
657
658 @Test
659 @Transactional
660 @WithMockUser("change-password-empty")
661 public void testChangePasswordEmpty() throws Exception {
662 User user = new User();
663 String currentPassword = RandomStringUtils.random(60);
664 user.setPassword(passwordEncoder.encode(currentPassword));
665 user.setLogin("change-password-empty");
666 user.setEmail("change-password-empty@example.com");
667 userRepository.saveAndFlush(user);
668
669 restAccountMockMvc.perform(post("/api/account/change-password")
670 .contentType(MediaType.APPLICATION_JSON)
671 .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, "")))
672 )
673 .andExpect(status().isBadRequest());
674
675 User updatedUser = userRepository.findOneByLogin("change-password-empty").orElse(null);
676 assertThat(updatedUser.getPassword()).isEqualTo(user.getPassword());
677 }
678
679 @Test
680 @Transactional
681 public void testRequestPasswordReset() throws Exception {
682 User user = new User();
683 user.setPassword(RandomStringUtils.random(60));
684 user.setActivated(true);
685 user.setLogin("password-reset");
686 user.setEmail("password-reset@example.com");
687 userRepository.saveAndFlush(user);
688
689 restAccountMockMvc.perform(post("/api/account/reset-password/init")
690 .content("password-reset@example.com")
691 )
692 .andExpect(status().isOk());
693 }
694
695 @Test
696 @Transactional
697 public void testRequestPasswordResetUpperCaseEmail() throws Exception {
698 User user = new User();
699 user.setPassword(RandomStringUtils.random(60));
700 user.setActivated(true);
701 user.setLogin("password-reset");
702 user.setEmail("password-reset@example.com");
703 userRepository.saveAndFlush(user);
704
705 restAccountMockMvc.perform(post("/api/account/reset-password/init")
706 .content("password-reset@EXAMPLE.COM")
707 )
708 .andExpect(status().isOk());
709 }
710
711 @Test
712 public void testRequestPasswordResetWrongEmail() throws Exception {
713 restAccountMockMvc.perform(
714 post("/api/account/reset-password/init")
715 .content("password-reset-wrong-email@example.com"))
716 .andExpect(status().isOk());
717 }
718
719 @Test
720 @Transactional
721 public void testFinishPasswordReset() throws Exception {
722 User user = new User();
723 user.setPassword(RandomStringUtils.random(60));
724 user.setLogin("finish-password-reset");
725 user.setEmail("finish-password-reset@example.com");
726 user.setResetDate(Instant.now().plusSeconds(60));
727 user.setResetKey("reset key");
728 userRepository.saveAndFlush(user);
729
730 KeyAndPasswordVM keyAndPassword = new KeyAndPasswordVM();
731 keyAndPassword.setKey(user.getResetKey());
732 keyAndPassword.setNewPassword("new password");
733
734 restAccountMockMvc.perform(
735 post("/api/account/reset-password/finish")
736 .contentType(MediaType.APPLICATION_JSON)
737 .content(TestUtil.convertObjectToJsonBytes(keyAndPassword)))
738 .andExpect(status().isOk());
739
740 User updatedUser = userRepository.findOneByLogin(user.getLogin()).orElse(null);
741 assertThat(passwordEncoder.matches(keyAndPassword.getNewPassword(), updatedUser.getPassword())).isTrue();
742 }
743
744 @Test
745 @Transactional
746 public void testFinishPasswordResetTooSmall() throws Exception {
747 User user = new User();
748 user.setPassword(RandomStringUtils.random(60));
749 user.setLogin("finish-password-reset-too-small");
750 user.setEmail("finish-password-reset-too-small@example.com");
751 user.setResetDate(Instant.now().plusSeconds(60));
752 user.setResetKey("reset key too small");
753 userRepository.saveAndFlush(user);
754
755 KeyAndPasswordVM keyAndPassword = new KeyAndPasswordVM();
756 keyAndPassword.setKey(user.getResetKey());
757 keyAndPassword.setNewPassword("foo");
758
759 restAccountMockMvc.perform(
760 post("/api/account/reset-password/finish")
761 .contentType(MediaType.APPLICATION_JSON)
762 .content(TestUtil.convertObjectToJsonBytes(keyAndPassword)))
763 .andExpect(status().isBadRequest());
764
765 User updatedUser = userRepository.findOneByLogin(user.getLogin()).orElse(null);
766 assertThat(passwordEncoder.matches(keyAndPassword.getNewPassword(), updatedUser.getPassword())).isFalse();
767 }
768
769 @Test
770 @Transactional
771 public void testFinishPasswordResetWrongKey() throws Exception {
772 KeyAndPasswordVM keyAndPassword = new KeyAndPasswordVM();
773 keyAndPassword.setKey("wrong reset key");
774 keyAndPassword.setNewPassword("new password");
775
776 restAccountMockMvc.perform(
777 post("/api/account/reset-password/finish")
778 .contentType(MediaType.APPLICATION_JSON)
779 .content(TestUtil.convertObjectToJsonBytes(keyAndPassword)))
780 .andExpect(status().isInternalServerError());
781 }
782 }
File src/test/java/hu/dns/honlap/web/rest/AuditResourceIT.java added (mode: 100644) (index 0000000..c44bb84)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.HonlapApp;
4 import io.github.jhipster.config.JHipsterProperties;
5 import hu.dns.honlap.config.audit.AuditEventConverter;
6 import hu.dns.honlap.domain.PersistentAuditEvent;
7 import hu.dns.honlap.repository.PersistenceAuditEventRepository;
8 import hu.dns.honlap.security.AuthoritiesConstants;
9
10 import hu.dns.honlap.service.AuditEventService;
11 import org.junit.jupiter.api.BeforeEach;
12 import org.junit.jupiter.api.Test;
13 import org.mockito.MockitoAnnotations;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.beans.factory.annotation.Qualifier;
16 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
17 import org.springframework.boot.test.context.SpringBootTest;
18 import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
19 import org.springframework.format.support.FormattingConversionService;
20 import org.springframework.http.MediaType;
21 import org.springframework.security.test.context.support.WithMockUser;
22 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
23 import org.springframework.test.web.servlet.MockMvc;
24 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
25 import org.springframework.transaction.annotation.Transactional;
26
27 import java.time.Instant;
28
29 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
30 import static org.hamcrest.Matchers.hasItem;
31 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
32 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
33
34 /**
35 * Integration tests for the {@link AuditResource} REST controller.
36 */
37 @AutoConfigureMockMvc
38 @WithMockUser(authorities = AuthoritiesConstants.ADMIN)
39 @SpringBootTest(classes = HonlapApp.class)
40 @Transactional
41 public class AuditResourceIT {
42
43 private static final String SAMPLE_PRINCIPAL = "SAMPLE_PRINCIPAL";
44 private static final String SAMPLE_TYPE = "SAMPLE_TYPE";
45 private static final Instant SAMPLE_TIMESTAMP = Instant.parse("2015-08-04T10:11:30Z");
46 private static final long SECONDS_PER_DAY = 60 * 60 * 24;
47
48 @Autowired
49 private PersistenceAuditEventRepository auditEventRepository;
50
51 private PersistentAuditEvent auditEvent;
52
53 @Autowired
54 private MockMvc restAuditMockMvc;
55
56 @BeforeEach
57 public void initTest() {
58 auditEventRepository.deleteAll();
59 auditEvent = new PersistentAuditEvent();
60 auditEvent.setAuditEventType(SAMPLE_TYPE);
61 auditEvent.setPrincipal(SAMPLE_PRINCIPAL);
62 auditEvent.setAuditEventDate(SAMPLE_TIMESTAMP);
63 }
64
65 @Test
66 public void getAllAudits() throws Exception {
67 // Initialize the database
68 auditEventRepository.save(auditEvent);
69
70 // Get all the audits
71 restAuditMockMvc.perform(get("/management/audits"))
72 .andExpect(status().isOk())
73 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
74 .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL)));
75 }
76
77 @Test
78 public void getAudit() throws Exception {
79 // Initialize the database
80 auditEventRepository.save(auditEvent);
81
82 // Get the audit
83 restAuditMockMvc.perform(get("/management/audits/{id}", auditEvent.getId()))
84 .andExpect(status().isOk())
85 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
86 .andExpect(jsonPath("$.principal").value(SAMPLE_PRINCIPAL));
87 }
88
89 @Test
90 public void getAuditsByDate() throws Exception {
91 // Initialize the database
92 auditEventRepository.save(auditEvent);
93
94 // Generate dates for selecting audits by date, making sure the period will contain the audit
95 String fromDate = SAMPLE_TIMESTAMP.minusSeconds(SECONDS_PER_DAY).toString().substring(0, 10);
96 String toDate = SAMPLE_TIMESTAMP.plusSeconds(SECONDS_PER_DAY).toString().substring(0, 10);
97
98 // Get the audit
99 restAuditMockMvc.perform(get("/management/audits?fromDate="+fromDate+"&toDate="+toDate))
100 .andExpect(status().isOk())
101 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
102 .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL)));
103 }
104
105 @Test
106 public void getNonExistingAuditsByDate() throws Exception {
107 // Initialize the database
108 auditEventRepository.save(auditEvent);
109
110 // Generate dates for selecting audits by date, making sure the period will not contain the sample audit
111 String fromDate = SAMPLE_TIMESTAMP.minusSeconds(2*SECONDS_PER_DAY).toString().substring(0, 10);
112 String toDate = SAMPLE_TIMESTAMP.minusSeconds(SECONDS_PER_DAY).toString().substring(0, 10);
113
114 // Query audits but expect no results
115 restAuditMockMvc.perform(get("/management/audits?fromDate=" + fromDate + "&toDate=" + toDate))
116 .andExpect(status().isOk())
117 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
118 .andExpect(header().string("X-Total-Count", "0"));
119 }
120
121 @Test
122 public void getNonExistingAudit() throws Exception {
123 // Get the audit
124 restAuditMockMvc.perform(get("/management/audits/{id}", Long.MAX_VALUE))
125 .andExpect(status().isNotFound());
126 }
127
128 @Test
129 @Transactional
130 public void testPersistentAuditEventEquals() throws Exception {
131 TestUtil.equalsVerifier(PersistentAuditEvent.class);
132 PersistentAuditEvent auditEvent1 = new PersistentAuditEvent();
133 auditEvent1.setId(1L);
134 PersistentAuditEvent auditEvent2 = new PersistentAuditEvent();
135 auditEvent2.setId(auditEvent1.getId());
136 assertThat(auditEvent1).isEqualTo(auditEvent2);
137 auditEvent2.setId(2L);
138 assertThat(auditEvent1).isNotEqualTo(auditEvent2);
139 auditEvent1.setId(null);
140 assertThat(auditEvent1).isNotEqualTo(auditEvent2);
141 }
142 }
File src/test/java/hu/dns/honlap/web/rest/ClientForwardControllerTest.java added (mode: 100644) (index 0000000..37037c2)
1 package hu.dns.honlap.web.rest;
2
3 import org.junit.jupiter.api.BeforeEach;
4 import org.junit.jupiter.api.Test;
5 import org.springframework.http.MediaType;
6 import org.springframework.test.web.servlet.MockMvc;
7 import org.springframework.test.web.servlet.ResultActions;
8 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
9 import org.springframework.web.bind.annotation.RequestMapping;
10 import org.springframework.web.bind.annotation.RestController;
11
12 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
13 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
14 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
15 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
16
17 /**
18 * Unit tests for the {@link ClientForwardController} REST controller.
19 */
20 public class ClientForwardControllerTest {
21
22 private MockMvc restMockMvc;
23
24 @BeforeEach
25 public void setup() {
26 ClientForwardController clientForwardController = new ClientForwardController();
27 this.restMockMvc = MockMvcBuilders
28 .standaloneSetup(clientForwardController, new TestController())
29 .build();
30 }
31
32 @Test
33 public void getBackendEndpoint() throws Exception {
34 restMockMvc.perform(get("/test"))
35 .andExpect(status().isOk())
36 .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN_VALUE))
37 .andExpect(content().string("test"));
38 }
39
40 @Test
41 public void getClientEndpoint() throws Exception {
42 ResultActions perform = restMockMvc.perform(get("/non-existant-mapping"));
43 perform
44 .andExpect(status().isOk())
45 .andExpect(forwardedUrl("/"));
46 }
47
48 @Test
49 public void getNestedClientEndpoint() throws Exception {
50 restMockMvc.perform(get("/admin/user-management"))
51 .andExpect(status().isOk())
52 .andExpect(forwardedUrl("/"));
53 }
54
55
56 @RestController
57 public static class TestController {
58
59 @RequestMapping(value = "/test")
60 public String test() {
61 return "test";
62 }
63 }
64 }
File src/test/java/hu/dns/honlap/web/rest/PieceOfNewsResourceIT.java added (mode: 100644) (index 0000000..f43fe2b)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.HonlapApp;
4 import hu.dns.honlap.domain.PieceOfNews;
5 import hu.dns.honlap.repository.PieceOfNewsRepository;
6
7 import org.junit.jupiter.api.BeforeEach;
8 import org.junit.jupiter.api.Test;
9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
11 import org.springframework.boot.test.context.SpringBootTest;
12 import org.springframework.http.MediaType;
13 import org.springframework.security.test.context.support.WithMockUser;
14 import org.springframework.test.web.servlet.MockMvc;
15 import org.springframework.transaction.annotation.Transactional;
16 import javax.persistence.EntityManager;
17 import java.time.Instant;
18 import java.time.temporal.ChronoUnit;
19 import java.util.List;
20
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.hamcrest.Matchers.hasItem;
23 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
24 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
25
26 /**
27 * Integration tests for the {@link PieceOfNewsResource} REST controller.
28 */
29 @SpringBootTest(classes = HonlapApp.class)
30
31 @AutoConfigureMockMvc
32 @WithMockUser
33 public class PieceOfNewsResourceIT {
34
35 private static final Integer DEFAULT_APP_ID = 1;
36 private static final Integer UPDATED_APP_ID = 2;
37
38 private static final Instant DEFAULT_NEWS_DATE = Instant.ofEpochMilli(0L);
39 private static final Instant UPDATED_NEWS_DATE = Instant.now().truncatedTo(ChronoUnit.MILLIS);
40
41 private static final String DEFAULT_HEADLINE = "AAAAAAAAAA";
42 private static final String UPDATED_HEADLINE = "BBBBBBBBBB";
43
44 private static final String DEFAULT_CONTENT = "AAAAAAAAAA";
45 private static final String UPDATED_CONTENT = "BBBBBBBBBB";
46
47 private static final String DEFAULT_LINK = "AAAAAAAAAA";
48 private static final String UPDATED_LINK = "BBBBBBBBBB";
49
50 private static final Instant DEFAULT_PUBLISH_DATE = Instant.ofEpochMilli(0L);
51 private static final Instant UPDATED_PUBLISH_DATE = Instant.now().truncatedTo(ChronoUnit.MILLIS);
52
53 private static final String DEFAULT_CREATED_BY = "AAAAAAAAAA";
54 private static final String UPDATED_CREATED_BY = "BBBBBBBBBB";
55
56 private static final Instant DEFAULT_CREATED_DATE = Instant.ofEpochMilli(0L);
57 private static final Instant UPDATED_CREATED_DATE = Instant.now().truncatedTo(ChronoUnit.MILLIS);
58
59 private static final String DEFAULT_LAST_MODIFIED_BY = "AAAAAAAAAA";
60 private static final String UPDATED_LAST_MODIFIED_BY = "BBBBBBBBBB";
61
62 private static final Instant DEFAULT_LAST_MODIFIED_DATE = Instant.ofEpochMilli(0L);
63 private static final Instant UPDATED_LAST_MODIFIED_DATE = Instant.now().truncatedTo(ChronoUnit.MILLIS);
64
65 @Autowired
66 private PieceOfNewsRepository pieceOfNewsRepository;
67
68 @Autowired
69 private EntityManager em;
70
71 @Autowired
72 private MockMvc restPieceOfNewsMockMvc;
73
74 private PieceOfNews pieceOfNews;
75
76 /**
77 * Create an entity for this test.
78 *
79 * This is a static method, as tests for other entities might also need it,
80 * if they test an entity which requires the current entity.
81 */
82 public static PieceOfNews createEntity(EntityManager em) {
83 PieceOfNews pieceOfNews = new PieceOfNews()
84 .appId(DEFAULT_APP_ID)
85 .newsDate(DEFAULT_NEWS_DATE)
86 .headline(DEFAULT_HEADLINE)
87 .content(DEFAULT_CONTENT)
88 .link(DEFAULT_LINK)
89 .publishDate(DEFAULT_PUBLISH_DATE)
90 .createdBy(DEFAULT_CREATED_BY)
91 .createdDate(DEFAULT_CREATED_DATE)
92 .lastModifiedBy(DEFAULT_LAST_MODIFIED_BY)
93 .lastModifiedDate(DEFAULT_LAST_MODIFIED_DATE);
94 return pieceOfNews;
95 }
96 /**
97 * Create an updated entity for this test.
98 *
99 * This is a static method, as tests for other entities might also need it,
100 * if they test an entity which requires the current entity.
101 */
102 public static PieceOfNews createUpdatedEntity(EntityManager em) {
103 PieceOfNews pieceOfNews = new PieceOfNews()
104 .appId(UPDATED_APP_ID)
105 .newsDate(UPDATED_NEWS_DATE)
106 .headline(UPDATED_HEADLINE)
107 .content(UPDATED_CONTENT)
108 .link(UPDATED_LINK)
109 .publishDate(UPDATED_PUBLISH_DATE)
110 .createdBy(UPDATED_CREATED_BY)
111 .createdDate(UPDATED_CREATED_DATE)
112 .lastModifiedBy(UPDATED_LAST_MODIFIED_BY)
113 .lastModifiedDate(UPDATED_LAST_MODIFIED_DATE);
114 return pieceOfNews;
115 }
116
117 @BeforeEach
118 public void initTest() {
119 pieceOfNews = createEntity(em);
120 }
121
122 @Test
123 @Transactional
124 public void createPieceOfNews() throws Exception {
125 int databaseSizeBeforeCreate = pieceOfNewsRepository.findAll().size();
126
127 // Create the PieceOfNews
128 restPieceOfNewsMockMvc.perform(post("/api/piece-of-news")
129 .contentType(MediaType.APPLICATION_JSON)
130 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
131 .andExpect(status().isCreated());
132
133 // Validate the PieceOfNews in the database
134 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
135 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeCreate + 1);
136 PieceOfNews testPieceOfNews = pieceOfNewsList.get(pieceOfNewsList.size() - 1);
137 assertThat(testPieceOfNews.getAppId()).isEqualTo(DEFAULT_APP_ID);
138 assertThat(testPieceOfNews.getNewsDate()).isEqualTo(DEFAULT_NEWS_DATE);
139 assertThat(testPieceOfNews.getHeadline()).isEqualTo(DEFAULT_HEADLINE);
140 assertThat(testPieceOfNews.getContent()).isEqualTo(DEFAULT_CONTENT);
141 assertThat(testPieceOfNews.getLink()).isEqualTo(DEFAULT_LINK);
142 assertThat(testPieceOfNews.getPublishDate()).isEqualTo(DEFAULT_PUBLISH_DATE);
143 assertThat(testPieceOfNews.getCreatedBy()).isEqualTo(DEFAULT_CREATED_BY);
144 assertThat(testPieceOfNews.getCreatedDate()).isEqualTo(DEFAULT_CREATED_DATE);
145 assertThat(testPieceOfNews.getLastModifiedBy()).isEqualTo(DEFAULT_LAST_MODIFIED_BY);
146 assertThat(testPieceOfNews.getLastModifiedDate()).isEqualTo(DEFAULT_LAST_MODIFIED_DATE);
147 }
148
149 @Test
150 @Transactional
151 public void createPieceOfNewsWithExistingId() throws Exception {
152 int databaseSizeBeforeCreate = pieceOfNewsRepository.findAll().size();
153
154 // Create the PieceOfNews with an existing ID
155 pieceOfNews.setId(1L);
156
157 // An entity with an existing ID cannot be created, so this API call must fail
158 restPieceOfNewsMockMvc.perform(post("/api/piece-of-news")
159 .contentType(MediaType.APPLICATION_JSON)
160 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
161 .andExpect(status().isBadRequest());
162
163 // Validate the PieceOfNews in the database
164 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
165 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeCreate);
166 }
167
168
169 @Test
170 @Transactional
171 public void checkAppIdIsRequired() throws Exception {
172 int databaseSizeBeforeTest = pieceOfNewsRepository.findAll().size();
173 // set the field null
174 pieceOfNews.setAppId(null);
175
176 // Create the PieceOfNews, which fails.
177
178 restPieceOfNewsMockMvc.perform(post("/api/piece-of-news")
179 .contentType(MediaType.APPLICATION_JSON)
180 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
181 .andExpect(status().isBadRequest());
182
183 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
184 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeTest);
185 }
186
187 @Test
188 @Transactional
189 public void checkNewsDateIsRequired() throws Exception {
190 int databaseSizeBeforeTest = pieceOfNewsRepository.findAll().size();
191 // set the field null
192 pieceOfNews.setNewsDate(null);
193
194 // Create the PieceOfNews, which fails.
195
196 restPieceOfNewsMockMvc.perform(post("/api/piece-of-news")
197 .contentType(MediaType.APPLICATION_JSON)
198 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
199 .andExpect(status().isBadRequest());
200
201 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
202 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeTest);
203 }
204
205 @Test
206 @Transactional
207 public void checkHeadlineIsRequired() throws Exception {
208 int databaseSizeBeforeTest = pieceOfNewsRepository.findAll().size();
209 // set the field null
210 pieceOfNews.setHeadline(null);
211
212 // Create the PieceOfNews, which fails.
213
214 restPieceOfNewsMockMvc.perform(post("/api/piece-of-news")
215 .contentType(MediaType.APPLICATION_JSON)
216 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
217 .andExpect(status().isBadRequest());
218
219 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
220 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeTest);
221 }
222
223 @Test
224 @Transactional
225 public void checkContentIsRequired() throws Exception {
226 int databaseSizeBeforeTest = pieceOfNewsRepository.findAll().size();
227 // set the field null
228 pieceOfNews.setContent(null);
229
230 // Create the PieceOfNews, which fails.
231
232 restPieceOfNewsMockMvc.perform(post("/api/piece-of-news")
233 .contentType(MediaType.APPLICATION_JSON)
234 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
235 .andExpect(status().isBadRequest());
236
237 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
238 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeTest);
239 }
240
241 @Test
242 @Transactional
243 public void checkLinkIsRequired() throws Exception {
244 int databaseSizeBeforeTest = pieceOfNewsRepository.findAll().size();
245 // set the field null
246 pieceOfNews.setLink(null);
247
248 // Create the PieceOfNews, which fails.
249
250 restPieceOfNewsMockMvc.perform(post("/api/piece-of-news")
251 .contentType(MediaType.APPLICATION_JSON)
252 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
253 .andExpect(status().isBadRequest());
254
255 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
256 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeTest);
257 }
258
259 @Test
260 @Transactional
261 public void getAllPieceOfNews() throws Exception {
262 // Initialize the database
263 pieceOfNewsRepository.saveAndFlush(pieceOfNews);
264
265 // Get all the pieceOfNewsList
266 restPieceOfNewsMockMvc.perform(get("/api/piece-of-news?sort=id,desc"))
267 .andExpect(status().isOk())
268 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
269 .andExpect(jsonPath("$.[*].id").value(hasItem(pieceOfNews.getId().intValue())))
270 .andExpect(jsonPath("$.[*].appId").value(hasItem(DEFAULT_APP_ID)))
271 .andExpect(jsonPath("$.[*].newsDate").value(hasItem(DEFAULT_NEWS_DATE.toString())))
272 .andExpect(jsonPath("$.[*].headline").value(hasItem(DEFAULT_HEADLINE)))
273 .andExpect(jsonPath("$.[*].content").value(hasItem(DEFAULT_CONTENT)))
274 .andExpect(jsonPath("$.[*].link").value(hasItem(DEFAULT_LINK)))
275 .andExpect(jsonPath("$.[*].publishDate").value(hasItem(DEFAULT_PUBLISH_DATE.toString())))
276 .andExpect(jsonPath("$.[*].createdBy").value(hasItem(DEFAULT_CREATED_BY)))
277 .andExpect(jsonPath("$.[*].createdDate").value(hasItem(DEFAULT_CREATED_DATE.toString())))
278 .andExpect(jsonPath("$.[*].lastModifiedBy").value(hasItem(DEFAULT_LAST_MODIFIED_BY)))
279 .andExpect(jsonPath("$.[*].lastModifiedDate").value(hasItem(DEFAULT_LAST_MODIFIED_DATE.toString())));
280 }
281
282 @Test
283 @Transactional
284 public void getPieceOfNews() throws Exception {
285 // Initialize the database
286 pieceOfNewsRepository.saveAndFlush(pieceOfNews);
287
288 // Get the pieceOfNews
289 restPieceOfNewsMockMvc.perform(get("/api/piece-of-news/{id}", pieceOfNews.getId()))
290 .andExpect(status().isOk())
291 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
292 .andExpect(jsonPath("$.id").value(pieceOfNews.getId().intValue()))
293 .andExpect(jsonPath("$.appId").value(DEFAULT_APP_ID))
294 .andExpect(jsonPath("$.newsDate").value(DEFAULT_NEWS_DATE.toString()))
295 .andExpect(jsonPath("$.headline").value(DEFAULT_HEADLINE))
296 .andExpect(jsonPath("$.content").value(DEFAULT_CONTENT))
297 .andExpect(jsonPath("$.link").value(DEFAULT_LINK))
298 .andExpect(jsonPath("$.publishDate").value(DEFAULT_PUBLISH_DATE.toString()))
299 .andExpect(jsonPath("$.createdBy").value(DEFAULT_CREATED_BY))
300 .andExpect(jsonPath("$.createdDate").value(DEFAULT_CREATED_DATE.toString()))
301 .andExpect(jsonPath("$.lastModifiedBy").value(DEFAULT_LAST_MODIFIED_BY))
302 .andExpect(jsonPath("$.lastModifiedDate").value(DEFAULT_LAST_MODIFIED_DATE.toString()));
303 }
304
305 @Test
306 @Transactional
307 public void getNonExistingPieceOfNews() throws Exception {
308 // Get the pieceOfNews
309 restPieceOfNewsMockMvc.perform(get("/api/piece-of-news/{id}", Long.MAX_VALUE))
310 .andExpect(status().isNotFound());
311 }
312
313 @Test
314 @Transactional
315 public void updatePieceOfNews() throws Exception {
316 // Initialize the database
317 pieceOfNewsRepository.saveAndFlush(pieceOfNews);
318
319 int databaseSizeBeforeUpdate = pieceOfNewsRepository.findAll().size();
320
321 // Update the pieceOfNews
322 PieceOfNews updatedPieceOfNews = pieceOfNewsRepository.findById(pieceOfNews.getId()).get();
323 // Disconnect from session so that the updates on updatedPieceOfNews are not directly saved in db
324 em.detach(updatedPieceOfNews);
325 updatedPieceOfNews
326 .appId(UPDATED_APP_ID)
327 .newsDate(UPDATED_NEWS_DATE)
328 .headline(UPDATED_HEADLINE)
329 .content(UPDATED_CONTENT)
330 .link(UPDATED_LINK)
331 .publishDate(UPDATED_PUBLISH_DATE)
332 .createdBy(UPDATED_CREATED_BY)
333 .createdDate(UPDATED_CREATED_DATE)
334 .lastModifiedBy(UPDATED_LAST_MODIFIED_BY)
335 .lastModifiedDate(UPDATED_LAST_MODIFIED_DATE);
336
337 restPieceOfNewsMockMvc.perform(put("/api/piece-of-news")
338 .contentType(MediaType.APPLICATION_JSON)
339 .content(TestUtil.convertObjectToJsonBytes(updatedPieceOfNews)))
340 .andExpect(status().isOk());
341
342 // Validate the PieceOfNews in the database
343 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
344 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeUpdate);
345 PieceOfNews testPieceOfNews = pieceOfNewsList.get(pieceOfNewsList.size() - 1);
346 assertThat(testPieceOfNews.getAppId()).isEqualTo(UPDATED_APP_ID);
347 assertThat(testPieceOfNews.getNewsDate()).isEqualTo(UPDATED_NEWS_DATE);
348 assertThat(testPieceOfNews.getHeadline()).isEqualTo(UPDATED_HEADLINE);
349 assertThat(testPieceOfNews.getContent()).isEqualTo(UPDATED_CONTENT);
350 assertThat(testPieceOfNews.getLink()).isEqualTo(UPDATED_LINK);
351 assertThat(testPieceOfNews.getPublishDate()).isEqualTo(UPDATED_PUBLISH_DATE);
352 assertThat(testPieceOfNews.getCreatedBy()).isEqualTo(UPDATED_CREATED_BY);
353 assertThat(testPieceOfNews.getCreatedDate()).isEqualTo(UPDATED_CREATED_DATE);
354 assertThat(testPieceOfNews.getLastModifiedBy()).isEqualTo(UPDATED_LAST_MODIFIED_BY);
355 assertThat(testPieceOfNews.getLastModifiedDate()).isEqualTo(UPDATED_LAST_MODIFIED_DATE);
356 }
357
358 @Test
359 @Transactional
360 public void updateNonExistingPieceOfNews() throws Exception {
361 int databaseSizeBeforeUpdate = pieceOfNewsRepository.findAll().size();
362
363 // Create the PieceOfNews
364
365 // If the entity doesn't have an ID, it will throw BadRequestAlertException
366 restPieceOfNewsMockMvc.perform(put("/api/piece-of-news")
367 .contentType(MediaType.APPLICATION_JSON)
368 .content(TestUtil.convertObjectToJsonBytes(pieceOfNews)))
369 .andExpect(status().isBadRequest());
370
371 // Validate the PieceOfNews in the database
372 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
373 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeUpdate);
374 }
375
376 @Test
377 @Transactional
378 public void deletePieceOfNews() throws Exception {
379 // Initialize the database
380 pieceOfNewsRepository.saveAndFlush(pieceOfNews);
381
382 int databaseSizeBeforeDelete = pieceOfNewsRepository.findAll().size();
383
384 // Delete the pieceOfNews
385 restPieceOfNewsMockMvc.perform(delete("/api/piece-of-news/{id}", pieceOfNews.getId())
386 .accept(MediaType.APPLICATION_JSON))
387 .andExpect(status().isNoContent());
388
389 // Validate the database contains one less item
390 List<PieceOfNews> pieceOfNewsList = pieceOfNewsRepository.findAll();
391 assertThat(pieceOfNewsList).hasSize(databaseSizeBeforeDelete - 1);
392 }
393 }
File src/test/java/hu/dns/honlap/web/rest/TestUtil.java added (mode: 100644) (index 0000000..a097a9e)
1 package hu.dns.honlap.web.rest;
2
3 import com.fasterxml.jackson.annotation.JsonInclude;
4 import com.fasterxml.jackson.databind.ObjectMapper;
5 import com.fasterxml.jackson.databind.SerializationFeature;
6 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
7 import org.hamcrest.Description;
8 import org.hamcrest.TypeSafeDiagnosingMatcher;
9 import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
10 import org.springframework.format.support.DefaultFormattingConversionService;
11 import org.springframework.format.support.FormattingConversionService;
12
13 import java.io.IOException;
14 import java.time.ZonedDateTime;
15 import java.time.format.DateTimeParseException;
16 import java.util.List;
17
18 import javax.persistence.EntityManager;
19 import javax.persistence.TypedQuery;
20 import javax.persistence.criteria.CriteriaBuilder;
21 import javax.persistence.criteria.CriteriaQuery;
22 import javax.persistence.criteria.Root;
23
24 import static org.assertj.core.api.Assertions.assertThat;
25
26 /**
27 * Utility class for testing REST controllers.
28 */
29 public final class TestUtil {
30
31 private static final ObjectMapper mapper = createObjectMapper();
32
33 private static ObjectMapper createObjectMapper() {
34 ObjectMapper mapper = new ObjectMapper();
35 mapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
36 mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
37 mapper.registerModule(new JavaTimeModule());
38 return mapper;
39 }
40
41 /**
42 * Convert an object to JSON byte array.
43 *
44 * @param object the object to convert.
45 * @return the JSON byte array.
46 * @throws IOException
47 */
48 public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
49 return mapper.writeValueAsBytes(object);
50 }
51
52 /**
53 * Create a byte array with a specific size filled with specified data.
54 *
55 * @param size the size of the byte array.
56 * @param data the data to put in the byte array.
57 * @return the JSON byte array.
58 */
59 public static byte[] createByteArray(int size, String data) {
60 byte[] byteArray = new byte[size];
61 for (int i = 0; i < size; i++) {
62 byteArray[i] = Byte.parseByte(data, 2);
63 }
64 return byteArray;
65 }
66
67 /**
68 * A matcher that tests that the examined string represents the same instant as the reference datetime.
69 */
70 public static class ZonedDateTimeMatcher extends TypeSafeDiagnosingMatcher<String> {
71
72 private final ZonedDateTime date;
73
74 public ZonedDateTimeMatcher(ZonedDateTime date) {
75 this.date = date;
76 }
77
78 @Override
79 protected boolean matchesSafely(String item, Description mismatchDescription) {
80 try {
81 if (!date.isEqual(ZonedDateTime.parse(item))) {
82 mismatchDescription.appendText("was ").appendValue(item);
83 return false;
84 }
85 return true;
86 } catch (DateTimeParseException e) {
87 mismatchDescription.appendText("was ").appendValue(item)
88 .appendText(", which could not be parsed as a ZonedDateTime");
89 return false;
90 }
91
92 }
93
94 @Override
95 public void describeTo(Description description) {
96 description.appendText("a String representing the same Instant as ").appendValue(date);
97 }
98 }
99
100 /**
101 * Creates a matcher that matches when the examined string represents the same instant as the reference datetime.
102 *
103 * @param date the reference datetime against which the examined string is checked.
104 */
105 public static ZonedDateTimeMatcher sameInstant(ZonedDateTime date) {
106 return new ZonedDateTimeMatcher(date);
107 }
108
109 /**
110 * Verifies the equals/hashcode contract on the domain object.
111 */
112 public static <T> void equalsVerifier(Class<T> clazz) throws Exception {
113 T domainObject1 = clazz.getConstructor().newInstance();
114 assertThat(domainObject1.toString()).isNotNull();
115 assertThat(domainObject1).isEqualTo(domainObject1);
116 assertThat(domainObject1.hashCode()).isEqualTo(domainObject1.hashCode());
117 // Test with an instance of another class
118 Object testOtherObject = new Object();
119 assertThat(domainObject1).isNotEqualTo(testOtherObject);
120 assertThat(domainObject1).isNotEqualTo(null);
121 // Test with an instance of the same class
122 T domainObject2 = clazz.getConstructor().newInstance();
123 assertThat(domainObject1).isNotEqualTo(domainObject2);
124 // HashCodes are equals because the objects are not persisted yet
125 assertThat(domainObject1.hashCode()).isEqualTo(domainObject2.hashCode());
126 }
127
128 /**
129 * Create a {@link FormattingConversionService} which use ISO date format, instead of the localized one.
130 * @return the {@link FormattingConversionService}.
131 */
132 public static FormattingConversionService createFormattingConversionService() {
133 DefaultFormattingConversionService dfcs = new DefaultFormattingConversionService ();
134 DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
135 registrar.setUseIsoFormat(true);
136 registrar.registerFormatters(dfcs);
137 return dfcs;
138 }
139
140 /**
141 * Makes a an executes a query to the EntityManager finding all stored objects.
142 * @param <T> The type of objects to be searched
143 * @param em The instance of the EntityManager
144 * @param clss The class type to be searched
145 * @return A list of all found objects
146 */
147 public static <T> List<T> findAll(EntityManager em, Class<T> clss) {
148 CriteriaBuilder cb = em.getCriteriaBuilder();
149 CriteriaQuery<T> cq = cb.createQuery(clss);
150 Root<T> rootEntry = cq.from(clss);
151 CriteriaQuery<T> all = cq.select(rootEntry);
152 TypedQuery<T> allQuery = em.createQuery(all);
153 return allQuery.getResultList();
154 }
155
156 private TestUtil() {}
157 }
File src/test/java/hu/dns/honlap/web/rest/UserJWTControllerIT.java added (mode: 100644) (index 0000000..2c9d2ae)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.HonlapApp;
4 import hu.dns.honlap.domain.User;
5 import hu.dns.honlap.repository.UserRepository;
6 import hu.dns.honlap.web.rest.vm.LoginVM;
7 import org.junit.jupiter.api.Test;
8 import org.springframework.beans.factory.annotation.Autowired;
9 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
10 import org.springframework.boot.test.context.SpringBootTest;
11 import org.springframework.http.MediaType;
12 import org.springframework.security.crypto.password.PasswordEncoder;
13 import org.springframework.test.web.servlet.MockMvc;
14 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
15 import org.springframework.transaction.annotation.Transactional;
16
17 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
18 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
19 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
20 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
21 import static org.hamcrest.Matchers.nullValue;
22 import static org.hamcrest.Matchers.emptyString;
23 import static org.hamcrest.Matchers.is;
24 import static org.hamcrest.Matchers.not;
25
26 /**
27 * Integration tests for the {@link UserJWTController} REST controller.
28 */
29 @AutoConfigureMockMvc
30 @SpringBootTest(classes = HonlapApp.class)
31 public class UserJWTControllerIT {
32
33 @Autowired
34 private UserRepository userRepository;
35
36 @Autowired
37 private PasswordEncoder passwordEncoder;
38
39 @Autowired
40 private MockMvc mockMvc;
41
42 @Test
43 @Transactional
44 public void testAuthorize() throws Exception {
45 User user = new User();
46 user.setLogin("user-jwt-controller");
47 user.setEmail("user-jwt-controller@example.com");
48 user.setActivated(true);
49 user.setPassword(passwordEncoder.encode("test"));
50
51 userRepository.saveAndFlush(user);
52
53 LoginVM login = new LoginVM();
54 login.setUsername("user-jwt-controller");
55 login.setPassword("test");
56 mockMvc.perform(post("/api/authenticate")
57 .contentType(MediaType.APPLICATION_JSON)
58 .content(TestUtil.convertObjectToJsonBytes(login)))
59 .andExpect(status().isOk())
60 .andExpect(jsonPath("$.id_token").isString())
61 .andExpect(jsonPath("$.id_token").isNotEmpty())
62 .andExpect(header().string("Authorization", not(nullValue())))
63 .andExpect(header().string("Authorization", not(is(emptyString()))));
64 }
65
66 @Test
67 @Transactional
68 public void testAuthorizeWithRememberMe() throws Exception {
69 User user = new User();
70 user.setLogin("user-jwt-controller-remember-me");
71 user.setEmail("user-jwt-controller-remember-me@example.com");
72 user.setActivated(true);
73 user.setPassword(passwordEncoder.encode("test"));
74
75 userRepository.saveAndFlush(user);
76
77 LoginVM login = new LoginVM();
78 login.setUsername("user-jwt-controller-remember-me");
79 login.setPassword("test");
80 login.setRememberMe(true);
81 mockMvc.perform(post("/api/authenticate")
82 .contentType(MediaType.APPLICATION_JSON)
83 .content(TestUtil.convertObjectToJsonBytes(login)))
84 .andExpect(status().isOk())
85 .andExpect(jsonPath("$.id_token").isString())
86 .andExpect(jsonPath("$.id_token").isNotEmpty())
87 .andExpect(header().string("Authorization", not(nullValue())))
88 .andExpect(header().string("Authorization", not(is(emptyString()))));
89 }
90
91 @Test
92 public void testAuthorizeFails() throws Exception {
93 LoginVM login = new LoginVM();
94 login.setUsername("wrong-user");
95 login.setPassword("wrong password");
96 mockMvc.perform(post("/api/authenticate")
97 .contentType(MediaType.APPLICATION_JSON)
98 .content(TestUtil.convertObjectToJsonBytes(login)))
99 .andExpect(status().isUnauthorized())
100 .andExpect(jsonPath("$.id_token").doesNotExist())
101 .andExpect(header().doesNotExist("Authorization"));
102 }
103 }
File src/test/java/hu/dns/honlap/web/rest/UserResourceIT.java added (mode: 100644) (index 0000000..5971462)
1 package hu.dns.honlap.web.rest;
2
3 import hu.dns.honlap.HonlapApp;
4 import hu.dns.honlap.domain.Authority;
5 import hu.dns.honlap.domain.User;
6 import hu.dns.honlap.repository.UserRepository;
7 import hu.dns.honlap.security.AuthoritiesConstants;
8 import hu.dns.honlap.service.dto.UserDTO;
9 import hu.dns.honlap.service.mapper.UserMapper;
10 import hu.dns.honlap.web.rest.vm.ManagedUserVM;
11 import org.apache.commons.lang3.RandomStringUtils;
12 import org.junit.jupiter.api.BeforeEach;
13 import org.junit.jupiter.api.Test;
14 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
16 import org.springframework.boot.test.context.SpringBootTest;
17 import org.springframework.cache.CacheManager;
18 import org.springframework.http.MediaType;
19 import org.springframework.security.test.context.support.WithMockUser;
20 import org.springframework.test.web.servlet.MockMvc;
21 import org.springframework.transaction.annotation.Transactional;
22
23 import javax.persistence.EntityManager;
24 import java.time.Instant;
25 import java.util.*;
26 import java.util.function.Consumer;
27
28 import static org.assertj.core.api.Assertions.assertThat;
29 import static org.hamcrest.Matchers.hasItems;
30 import static org.hamcrest.Matchers.hasItem;
31 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
32 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
33
34 /**
35 * Integration tests for the {@link UserResource} REST controller.
36 */
37 @AutoConfigureMockMvc
38 @WithMockUser(authorities = AuthoritiesConstants.ADMIN)
39 @SpringBootTest(classes = HonlapApp.class)
40 public class UserResourceIT {
41
42 private static final String DEFAULT_LOGIN = "johndoe";
43 private static final String UPDATED_LOGIN = "jhipster";
44
45 private static final Long DEFAULT_ID = 1L;
46
47 private static final String DEFAULT_PASSWORD = "passjohndoe";
48 private static final String UPDATED_PASSWORD = "passjhipster";
49
50 private static final String DEFAULT_EMAIL = "johndoe@localhost";
51 private static final String UPDATED_EMAIL = "jhipster@localhost";
52
53 private static final String DEFAULT_FIRSTNAME = "john";
54 private static final String UPDATED_FIRSTNAME = "jhipsterFirstName";
55
56 private static final String DEFAULT_LASTNAME = "doe";
57 private static final String UPDATED_LASTNAME = "jhipsterLastName";
58
59 private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50";
60 private static final String UPDATED_IMAGEURL = "http://placehold.it/40x40";
61
62 private static final String DEFAULT_LANGKEY = "en";
63 private static final String UPDATED_LANGKEY = "fr";
64
65 @Autowired
66 private UserRepository userRepository;
67
68 @Autowired
69 private UserMapper userMapper;
70
71 @Autowired
72 private EntityManager em;
73
74 @Autowired
75 private CacheManager cacheManager;
76
77 @Autowired
78 private MockMvc restUserMockMvc;
79
80 private User user;
81
82 @BeforeEach
83 public void setup() {
84 cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).clear();
85 cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE).clear();
86 }
87
88 /**
89 * Create a User.
90 *
91 * This is a static method, as tests for other entities might also need it,
92 * if they test an entity which has a required relationship to the User entity.
93 */
94 public static User createEntity(EntityManager em) {
95 User user = new User();
96 user.setLogin(DEFAULT_LOGIN + RandomStringUtils.randomAlphabetic(5));
97 user.setPassword(RandomStringUtils.random(60));
98 user.setActivated(true);
99 user.setEmail(RandomStringUtils.randomAlphabetic(5) + DEFAULT_EMAIL);
100 user.setFirstName(DEFAULT_FIRSTNAME);
101 user.setLastName(DEFAULT_LASTNAME);
102 user.setImageUrl(DEFAULT_IMAGEURL);
103 user.setLangKey(DEFAULT_LANGKEY);
104 return user;
105 }
106
107 @BeforeEach
108 public void initTest() {
109 user = createEntity(em);
110 user.setLogin(DEFAULT_LOGIN);
111 user.setEmail(DEFAULT_EMAIL);
112 }
113
114 @Test
115 @Transactional
116 public void createUser() throws Exception {
117 int databaseSizeBeforeCreate = userRepository.findAll().size();
118
119 // Create the User
120 ManagedUserVM managedUserVM = new ManagedUserVM();
121 managedUserVM.setLogin(DEFAULT_LOGIN);
122 managedUserVM.setPassword(DEFAULT_PASSWORD);
123 managedUserVM.setFirstName(DEFAULT_FIRSTNAME);
124 managedUserVM.setLastName(DEFAULT_LASTNAME);
125 managedUserVM.setEmail(DEFAULT_EMAIL);
126 managedUserVM.setActivated(true);
127 managedUserVM.setImageUrl(DEFAULT_IMAGEURL);
128 managedUserVM.setLangKey(DEFAULT_LANGKEY);
129 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
130
131 restUserMockMvc.perform(post("/api/users")
132 .contentType(MediaType.APPLICATION_JSON)
133 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
134 .andExpect(status().isCreated());
135
136 // Validate the User in the database
137 assertPersistedUsers(users -> {
138 assertThat(users).hasSize(databaseSizeBeforeCreate + 1);
139 User testUser = users.get(users.size() - 1);
140 assertThat(testUser.getLogin()).isEqualTo(DEFAULT_LOGIN);
141 assertThat(testUser.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME);
142 assertThat(testUser.getLastName()).isEqualTo(DEFAULT_LASTNAME);
143 assertThat(testUser.getEmail()).isEqualTo(DEFAULT_EMAIL);
144 assertThat(testUser.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL);
145 assertThat(testUser.getLangKey()).isEqualTo(DEFAULT_LANGKEY);
146 });
147 }
148
149 @Test
150 @Transactional
151 public void createUserWithExistingId() throws Exception {
152 int databaseSizeBeforeCreate = userRepository.findAll().size();
153
154 ManagedUserVM managedUserVM = new ManagedUserVM();
155 managedUserVM.setId(1L);
156 managedUserVM.setLogin(DEFAULT_LOGIN);
157 managedUserVM.setPassword(DEFAULT_PASSWORD);
158 managedUserVM.setFirstName(DEFAULT_FIRSTNAME);
159 managedUserVM.setLastName(DEFAULT_LASTNAME);
160 managedUserVM.setEmail(DEFAULT_EMAIL);
161 managedUserVM.setActivated(true);
162 managedUserVM.setImageUrl(DEFAULT_IMAGEURL);
163 managedUserVM.setLangKey(DEFAULT_LANGKEY);
164 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
165
166 // An entity with an existing ID cannot be created, so this API call must fail
167 restUserMockMvc.perform(post("/api/users")
168 .contentType(MediaType.APPLICATION_JSON)
169 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
170 .andExpect(status().isBadRequest());
171
172 // Validate the User in the database
173 assertPersistedUsers(users -> assertThat(users).hasSize(databaseSizeBeforeCreate));
174 }
175
176 @Test
177 @Transactional
178 public void createUserWithExistingLogin() throws Exception {
179 // Initialize the database
180 userRepository.saveAndFlush(user);
181 int databaseSizeBeforeCreate = userRepository.findAll().size();
182
183 ManagedUserVM managedUserVM = new ManagedUserVM();
184 managedUserVM.setLogin(DEFAULT_LOGIN);// this login should already be used
185 managedUserVM.setPassword(DEFAULT_PASSWORD);
186 managedUserVM.setFirstName(DEFAULT_FIRSTNAME);
187 managedUserVM.setLastName(DEFAULT_LASTNAME);
188 managedUserVM.setEmail("anothermail@localhost");
189 managedUserVM.setActivated(true);
190 managedUserVM.setImageUrl(DEFAULT_IMAGEURL);
191 managedUserVM.setLangKey(DEFAULT_LANGKEY);
192 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
193
194 // Create the User
195 restUserMockMvc.perform(post("/api/users")
196 .contentType(MediaType.APPLICATION_JSON)
197 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
198 .andExpect(status().isBadRequest());
199
200 // Validate the User in the database
201 assertPersistedUsers(users -> assertThat(users).hasSize(databaseSizeBeforeCreate));
202 }
203
204 @Test
205 @Transactional
206 public void createUserWithExistingEmail() throws Exception {
207 // Initialize the database
208 userRepository.saveAndFlush(user);
209 int databaseSizeBeforeCreate = userRepository.findAll().size();
210
211 ManagedUserVM managedUserVM = new ManagedUserVM();
212 managedUserVM.setLogin("anotherlogin");
213 managedUserVM.setPassword(DEFAULT_PASSWORD);
214 managedUserVM.setFirstName(DEFAULT_FIRSTNAME);
215 managedUserVM.setLastName(DEFAULT_LASTNAME);
216 managedUserVM.setEmail(DEFAULT_EMAIL);// this email should already be used
217 managedUserVM.setActivated(true);
218 managedUserVM.setImageUrl(DEFAULT_IMAGEURL);
219 managedUserVM.setLangKey(DEFAULT_LANGKEY);
220 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
221
222 // Create the User
223 restUserMockMvc.perform(post("/api/users")
224 .contentType(MediaType.APPLICATION_JSON)
225 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
226 .andExpect(status().isBadRequest());
227
228 // Validate the User in the database
229 assertPersistedUsers(users -> assertThat(users).hasSize(databaseSizeBeforeCreate));
230 }
231
232 @Test
233 @Transactional
234 public void getAllUsers() throws Exception {
235 // Initialize the database
236 userRepository.saveAndFlush(user);
237
238 // Get all the users
239 restUserMockMvc.perform(get("/api/users?sort=id,desc")
240 .accept(MediaType.APPLICATION_JSON))
241 .andExpect(status().isOk())
242 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
243 .andExpect(jsonPath("$.[*].login").value(hasItem(DEFAULT_LOGIN)))
244 .andExpect(jsonPath("$.[*].firstName").value(hasItem(DEFAULT_FIRSTNAME)))
245 .andExpect(jsonPath("$.[*].lastName").value(hasItem(DEFAULT_LASTNAME)))
246 .andExpect(jsonPath("$.[*].email").value(hasItem(DEFAULT_EMAIL)))
247 .andExpect(jsonPath("$.[*].imageUrl").value(hasItem(DEFAULT_IMAGEURL)))
248 .andExpect(jsonPath("$.[*].langKey").value(hasItem(DEFAULT_LANGKEY)));
249 }
250
251 @Test
252 @Transactional
253 public void getUser() throws Exception {
254 // Initialize the database
255 userRepository.saveAndFlush(user);
256
257 assertThat(cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).get(user.getLogin())).isNull();
258
259 // Get the user
260 restUserMockMvc.perform(get("/api/users/{login}", user.getLogin()))
261 .andExpect(status().isOk())
262 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
263 .andExpect(jsonPath("$.login").value(user.getLogin()))
264 .andExpect(jsonPath("$.firstName").value(DEFAULT_FIRSTNAME))
265 .andExpect(jsonPath("$.lastName").value(DEFAULT_LASTNAME))
266 .andExpect(jsonPath("$.email").value(DEFAULT_EMAIL))
267 .andExpect(jsonPath("$.imageUrl").value(DEFAULT_IMAGEURL))
268 .andExpect(jsonPath("$.langKey").value(DEFAULT_LANGKEY));
269
270 assertThat(cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).get(user.getLogin())).isNotNull();
271 }
272
273 @Test
274 @Transactional
275 public void getNonExistingUser() throws Exception {
276 restUserMockMvc.perform(get("/api/users/unknown"))
277 .andExpect(status().isNotFound());
278 }
279
280 @Test
281 @Transactional
282 public void updateUser() throws Exception {
283 // Initialize the database
284 userRepository.saveAndFlush(user);
285 int databaseSizeBeforeUpdate = userRepository.findAll().size();
286
287 // Update the user
288 User updatedUser = userRepository.findById(user.getId()).get();
289
290 ManagedUserVM managedUserVM = new ManagedUserVM();
291 managedUserVM.setId(updatedUser.getId());
292 managedUserVM.setLogin(updatedUser.getLogin());
293 managedUserVM.setPassword(UPDATED_PASSWORD);
294 managedUserVM.setFirstName(UPDATED_FIRSTNAME);
295 managedUserVM.setLastName(UPDATED_LASTNAME);
296 managedUserVM.setEmail(UPDATED_EMAIL);
297 managedUserVM.setActivated(updatedUser.getActivated());
298 managedUserVM.setImageUrl(UPDATED_IMAGEURL);
299 managedUserVM.setLangKey(UPDATED_LANGKEY);
300 managedUserVM.setCreatedBy(updatedUser.getCreatedBy());
301 managedUserVM.setCreatedDate(updatedUser.getCreatedDate());
302 managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy());
303 managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate());
304 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
305
306 restUserMockMvc.perform(put("/api/users")
307 .contentType(MediaType.APPLICATION_JSON)
308 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
309 .andExpect(status().isOk());
310
311 // Validate the User in the database
312 assertPersistedUsers(users -> {
313 assertThat(users).hasSize(databaseSizeBeforeUpdate);
314 User testUser = users.get(users.size() - 1);
315 assertThat(testUser.getFirstName()).isEqualTo(UPDATED_FIRSTNAME);
316 assertThat(testUser.getLastName()).isEqualTo(UPDATED_LASTNAME);
317 assertThat(testUser.getEmail()).isEqualTo(UPDATED_EMAIL);
318 assertThat(testUser.getImageUrl()).isEqualTo(UPDATED_IMAGEURL);
319 assertThat(testUser.getLangKey()).isEqualTo(UPDATED_LANGKEY);
320 });
321 }
322
323 @Test
324 @Transactional
325 public void updateUserLogin() throws Exception {
326 // Initialize the database
327 userRepository.saveAndFlush(user);
328 int databaseSizeBeforeUpdate = userRepository.findAll().size();
329
330 // Update the user
331 User updatedUser = userRepository.findById(user.getId()).get();
332
333 ManagedUserVM managedUserVM = new ManagedUserVM();
334 managedUserVM.setId(updatedUser.getId());
335 managedUserVM.setLogin(UPDATED_LOGIN);
336 managedUserVM.setPassword(UPDATED_PASSWORD);
337 managedUserVM.setFirstName(UPDATED_FIRSTNAME);
338 managedUserVM.setLastName(UPDATED_LASTNAME);
339 managedUserVM.setEmail(UPDATED_EMAIL);
340 managedUserVM.setActivated(updatedUser.getActivated());
341 managedUserVM.setImageUrl(UPDATED_IMAGEURL);
342 managedUserVM.setLangKey(UPDATED_LANGKEY);
343 managedUserVM.setCreatedBy(updatedUser.getCreatedBy());
344 managedUserVM.setCreatedDate(updatedUser.getCreatedDate());
345 managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy());
346 managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate());
347 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
348
349 restUserMockMvc.perform(put("/api/users")
350 .contentType(MediaType.APPLICATION_JSON)
351 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
352 .andExpect(status().isOk());
353
354 // Validate the User in the database
355 assertPersistedUsers(users -> {
356 assertThat(users).hasSize(databaseSizeBeforeUpdate);
357 User testUser = users.get(users.size() - 1);
358 assertThat(testUser.getLogin()).isEqualTo(UPDATED_LOGIN);
359 assertThat(testUser.getFirstName()).isEqualTo(UPDATED_FIRSTNAME);
360 assertThat(testUser.getLastName()).isEqualTo(UPDATED_LASTNAME);
361 assertThat(testUser.getEmail()).isEqualTo(UPDATED_EMAIL);
362 assertThat(testUser.getImageUrl()).isEqualTo(UPDATED_IMAGEURL);
363 assertThat(testUser.getLangKey()).isEqualTo(UPDATED_LANGKEY);
364 });
365 }
366
367 @Test
368 @Transactional
369 public void updateUserExistingEmail() throws Exception {
370 // Initialize the database with 2 users
371 userRepository.saveAndFlush(user);
372
373 User anotherUser = new User();
374 anotherUser.setLogin("jhipster");
375 anotherUser.setPassword(RandomStringUtils.random(60));
376 anotherUser.setActivated(true);
377 anotherUser.setEmail("jhipster@localhost");
378 anotherUser.setFirstName("java");
379 anotherUser.setLastName("hipster");
380 anotherUser.setImageUrl("");
381 anotherUser.setLangKey("en");
382 userRepository.saveAndFlush(anotherUser);
383
384 // Update the user
385 User updatedUser = userRepository.findById(user.getId()).get();
386
387 ManagedUserVM managedUserVM = new ManagedUserVM();
388 managedUserVM.setId(updatedUser.getId());
389 managedUserVM.setLogin(updatedUser.getLogin());
390 managedUserVM.setPassword(updatedUser.getPassword());
391 managedUserVM.setFirstName(updatedUser.getFirstName());
392 managedUserVM.setLastName(updatedUser.getLastName());
393 managedUserVM.setEmail("jhipster@localhost");// this email should already be used by anotherUser
394 managedUserVM.setActivated(updatedUser.getActivated());
395 managedUserVM.setImageUrl(updatedUser.getImageUrl());
396 managedUserVM.setLangKey(updatedUser.getLangKey());
397 managedUserVM.setCreatedBy(updatedUser.getCreatedBy());
398 managedUserVM.setCreatedDate(updatedUser.getCreatedDate());
399 managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy());
400 managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate());
401 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
402
403 restUserMockMvc.perform(put("/api/users")
404 .contentType(MediaType.APPLICATION_JSON)
405 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
406 .andExpect(status().isBadRequest());
407 }
408
409 @Test
410 @Transactional
411 public void updateUserExistingLogin() throws Exception {
412 // Initialize the database
413 userRepository.saveAndFlush(user);
414
415 User anotherUser = new User();
416 anotherUser.setLogin("jhipster");
417 anotherUser.setPassword(RandomStringUtils.random(60));
418 anotherUser.setActivated(true);
419 anotherUser.setEmail("jhipster@localhost");
420 anotherUser.setFirstName("java");
421 anotherUser.setLastName("hipster");
422 anotherUser.setImageUrl("");
423 anotherUser.setLangKey("en");
424 userRepository.saveAndFlush(anotherUser);
425
426 // Update the user
427 User updatedUser = userRepository.findById(user.getId()).get();
428
429 ManagedUserVM managedUserVM = new ManagedUserVM();
430 managedUserVM.setId(updatedUser.getId());
431 managedUserVM.setLogin("jhipster");// this login should already be used by anotherUser
432 managedUserVM.setPassword(updatedUser.getPassword());
433 managedUserVM.setFirstName(updatedUser.getFirstName());
434 managedUserVM.setLastName(updatedUser.getLastName());
435 managedUserVM.setEmail(updatedUser.getEmail());
436 managedUserVM.setActivated(updatedUser.getActivated());
437 managedUserVM.setImageUrl(updatedUser.getImageUrl());
438 managedUserVM.setLangKey(updatedUser.getLangKey());
439 managedUserVM.setCreatedBy(updatedUser.getCreatedBy());
440 managedUserVM.setCreatedDate(updatedUser.getCreatedDate());
441 managedUserVM.setLastModifiedBy(updatedUser.getLastModifiedBy());
442 managedUserVM.setLastModifiedDate(updatedUser.getLastModifiedDate());
443 managedUserVM.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
444
445 restUserMockMvc.perform(put("/api/users")
446 .contentType(MediaType.APPLICATION_JSON)
447 .content(TestUtil.convertObjectToJsonBytes(managedUserVM)))
448 .andExpect(status().isBadRequest());
449 }
450
451 @Test
452 @Transactional
453 public void deleteUser() throws Exception {
454 // Initialize the database
455 userRepository.saveAndFlush(user);
456 int databaseSizeBeforeDelete = userRepository.findAll().size();
457
458 // Delete the user
459 restUserMockMvc.perform(delete("/api/users/{login}", user.getLogin())
460 .accept(MediaType.APPLICATION_JSON))
461 .andExpect(status().isNoContent());
462
463 assertThat(cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).get(user.getLogin())).isNull();
464
465 // Validate the database is empty
466 assertPersistedUsers(users -> assertThat(users).hasSize(databaseSizeBeforeDelete - 1));
467 }
468
469 @Test
470 @Transactional
471 public void getAllAuthorities() throws Exception {
472 restUserMockMvc.perform(get("/api/users/authorities")
473 .accept(MediaType.APPLICATION_JSON)
474 .contentType(MediaType.APPLICATION_JSON))
475 .andExpect(status().isOk())
476 .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
477 .andExpect(jsonPath("$").isArray())
478 .andExpect(jsonPath("$").value(hasItems(AuthoritiesConstants.USER, AuthoritiesConstants.ADMIN)));
479 }
480
481 @Test
482 @Transactional
483 public void testUserEquals() throws Exception {
484 TestUtil.equalsVerifier(User.class);
485 User user1 = new User();
486 user1.setId(1L);
487 User user2 = new User();
488 user2.setId(user1.getId());
489 assertThat(user1).isEqualTo(user2);
490 user2.setId(2L);
491 assertThat(user1).isNotEqualTo(user2);
492 user1.setId(null);
493 assertThat(user1).isNotEqualTo(user2);
494 }
495
496 @Test
497 public void testUserDTOtoUser() {
498 UserDTO userDTO = new UserDTO();
499 userDTO.setId(DEFAULT_ID);
500 userDTO.setLogin(DEFAULT_LOGIN);
501 userDTO.setFirstName(DEFAULT_FIRSTNAME);
502 userDTO.setLastName(DEFAULT_LASTNAME);
503 userDTO.setEmail(DEFAULT_EMAIL);
504 userDTO.setActivated(true);
505 userDTO.setImageUrl(DEFAULT_IMAGEURL);
506 userDTO.setLangKey(DEFAULT_LANGKEY);
507 userDTO.setCreatedBy(DEFAULT_LOGIN);
508 userDTO.setLastModifiedBy(DEFAULT_LOGIN);
509 userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.USER));
510
511 User user = userMapper.userDTOToUser(userDTO);
512 assertThat(user.getId()).isEqualTo(DEFAULT_ID);
513 assertThat(user.getLogin()).isEqualTo(DEFAULT_LOGIN);
514 assertThat(user.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME);
515 assertThat(user.getLastName()).isEqualTo(DEFAULT_LASTNAME);
516 assertThat(user.getEmail()).isEqualTo(DEFAULT_EMAIL);
517 assertThat(user.getActivated()).isEqualTo(true);
518 assertThat(user.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL);
519 assertThat(user.getLangKey()).isEqualTo(DEFAULT_LANGKEY);
520 assertThat(user.getCreatedBy()).isNull();
521 assertThat(user.getCreatedDate()).isNotNull();
522 assertThat(user.getLastModifiedBy()).isNull();
523 assertThat(user.getLastModifiedDate()).isNotNull();
524 assertThat(user.getAuthorities()).extracting("name").containsExactly(AuthoritiesConstants.USER);
525 }
526
527 @Test
528 public void testUserToUserDTO() {
529 user.setId(DEFAULT_ID);
530 user.setCreatedBy(DEFAULT_LOGIN);
531 user.setCreatedDate(Instant.now());
532 user.setLastModifiedBy(DEFAULT_LOGIN);
533 user.setLastModifiedDate(Instant.now());
534 Set<Authority> authorities = new HashSet<>();
535 Authority authority = new Authority();
536 authority.setName(AuthoritiesConstants.USER);
537 authorities.add(authority);
538 user.setAuthorities(authorities);
539
540 UserDTO userDTO = userMapper.userToUserDTO(user);
541
542 assertThat(userDTO.getId()).isEqualTo(DEFAULT_ID);
543 assertThat(userDTO.getLogin()).isEqualTo(DEFAULT_LOGIN);
544 assertThat(userDTO.getFirstName()).isEqualTo(DEFAULT_FIRSTNAME);
545 assertThat(userDTO.getLastName()).isEqualTo(DEFAULT_LASTNAME);
546 assertThat(userDTO.getEmail()).isEqualTo(DEFAULT_EMAIL);
547 assertThat(userDTO.isActivated()).isEqualTo(true);
548 assertThat(userDTO.getImageUrl()).isEqualTo(DEFAULT_IMAGEURL);
549 assertThat(userDTO.getLangKey()).isEqualTo(DEFAULT_LANGKEY);
550 assertThat(userDTO.getCreatedBy()).isEqualTo(DEFAULT_LOGIN);
551 assertThat(userDTO.getCreatedDate()).isEqualTo(user.getCreatedDate());
552 assertThat(userDTO.getLastModifiedBy()).isEqualTo(DEFAULT_LOGIN);
553 assertThat(userDTO.getLastModifiedDate()).isEqualTo(user.getLastModifiedDate());
554 assertThat(userDTO.getAuthorities()).containsExactly(AuthoritiesConstants.USER);
555 assertThat(userDTO.toString()).isNotNull();
556 }
557
558 @Test
559 public void testAuthorityEquals() {
560 Authority authorityA = new Authority();
561 assertThat(authorityA).isEqualTo(authorityA);
562 assertThat(authorityA).isNotEqualTo(null);
563 assertThat(authorityA).isNotEqualTo(new Object());
564 assertThat(authorityA.hashCode()).isEqualTo(0);
565 assertThat(authorityA.toString()).isNotNull();
566
567 Authority authorityB = new Authority();
568 assertThat(authorityA).isEqualTo(authorityB);
569
570 authorityB.setName(AuthoritiesConstants.ADMIN);
571 assertThat(authorityA).isNotEqualTo(authorityB);
572
573 authorityA.setName(AuthoritiesConstants.USER);
574 assertThat(authorityA).isNotEqualTo(authorityB);
575
576 authorityB.setName(AuthoritiesConstants.USER);
577 assertThat(authorityA).isEqualTo(authorityB);
578 assertThat(authorityA.hashCode()).isEqualTo(authorityB.hashCode());
579 }
580
581 private void assertPersistedUsers(Consumer<List<User>> userAssertion) {
582 userAssertion.accept(userRepository.findAll());
583 }
584 }
File src/test/java/hu/dns/honlap/web/rest/WithUnauthenticatedMockUser.java added (mode: 100644) (index 0000000..6f2fc7c)
1 package hu.dns.honlap.web.rest;
2
3 import org.springframework.security.core.context.SecurityContext;
4 import org.springframework.security.core.context.SecurityContextHolder;
5 import org.springframework.security.test.context.support.WithSecurityContext;
6 import org.springframework.security.test.context.support.WithSecurityContextFactory;
7
8 import java.lang.annotation.ElementType;
9 import java.lang.annotation.Retention;
10 import java.lang.annotation.RetentionPolicy;
11 import java.lang.annotation.Target;
12
13 @Target({ElementType.METHOD, ElementType.TYPE})
14 @Retention(RetentionPolicy.RUNTIME)
15 @WithSecurityContext(factory = WithUnauthenticatedMockUser.Factory.class)
16 public @interface WithUnauthenticatedMockUser {
17
18 class Factory implements WithSecurityContextFactory<WithUnauthenticatedMockUser> {
19 @Override
20 public SecurityContext createSecurityContext(WithUnauthenticatedMockUser annotation) {
21 return SecurityContextHolder.createEmptyContext();
22 }
23 }
24 }
File src/test/java/hu/dns/honlap/web/rest/errors/ExceptionTranslatorIT.java added (mode: 100644) (index 0000000..52ee83b)
1 package hu.dns.honlap.web.rest.errors;
2
3 import hu.dns.honlap.HonlapApp;
4 import org.junit.jupiter.api.Test;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.boot.test.context.SpringBootTest;
7 import org.springframework.security.test.context.support.WithMockUser;
8 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
9 import org.springframework.http.MediaType;
10 import org.springframework.test.web.servlet.MockMvc;
11
12 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
13 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
14 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
15 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
16 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
17
18 /**
19 * Integration tests {@link ExceptionTranslator} controller advice.
20 */
21 @WithMockUser
22 @AutoConfigureMockMvc
23 @SpringBootTest(classes = HonlapApp.class)
24 public class ExceptionTranslatorIT {
25
26 @Autowired
27 private MockMvc mockMvc;
28
29 @Test
30 public void testConcurrencyFailure() throws Exception {
31 mockMvc.perform(get("/api/exception-translator-test/concurrency-failure"))
32 .andExpect(status().isConflict())
33 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
34 .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_CONCURRENCY_FAILURE));
35 }
36
37 @Test
38 public void testMethodArgumentNotValid() throws Exception {
39 mockMvc.perform(post("/api/exception-translator-test/method-argument").content("{}").contentType(MediaType.APPLICATION_JSON))
40 .andExpect(status().isBadRequest())
41 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
42 .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_VALIDATION))
43 .andExpect(jsonPath("$.fieldErrors.[0].objectName").value("test"))
44 .andExpect(jsonPath("$.fieldErrors.[0].field").value("test"))
45 .andExpect(jsonPath("$.fieldErrors.[0].message").value("NotNull"));
46 }
47
48 @Test
49 public void testMissingServletRequestPartException() throws Exception {
50 mockMvc.perform(get("/api/exception-translator-test/missing-servlet-request-part"))
51 .andExpect(status().isBadRequest())
52 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
53 .andExpect(jsonPath("$.message").value("error.http.400"));
54 }
55
56 @Test
57 public void testMissingServletRequestParameterException() throws Exception {
58 mockMvc.perform(get("/api/exception-translator-test/missing-servlet-request-parameter"))
59 .andExpect(status().isBadRequest())
60 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
61 .andExpect(jsonPath("$.message").value("error.http.400"));
62 }
63
64 @Test
65 public void testAccessDenied() throws Exception {
66 mockMvc.perform(get("/api/exception-translator-test/access-denied"))
67 .andExpect(status().isForbidden())
68 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
69 .andExpect(jsonPath("$.message").value("error.http.403"))
70 .andExpect(jsonPath("$.detail").value("test access denied!"));
71 }
72
73 @Test
74 public void testUnauthorized() throws Exception {
75 mockMvc.perform(get("/api/exception-translator-test/unauthorized"))
76 .andExpect(status().isUnauthorized())
77 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
78 .andExpect(jsonPath("$.message").value("error.http.401"))
79 .andExpect(jsonPath("$.path").value("/api/exception-translator-test/unauthorized"))
80 .andExpect(jsonPath("$.detail").value("test authentication failed!"));
81 }
82
83 @Test
84 public void testMethodNotSupported() throws Exception {
85 mockMvc.perform(post("/api/exception-translator-test/access-denied"))
86 .andExpect(status().isMethodNotAllowed())
87 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
88 .andExpect(jsonPath("$.message").value("error.http.405"))
89 .andExpect(jsonPath("$.detail").value("Request method 'POST' not supported"));
90 }
91
92 @Test
93 public void testExceptionWithResponseStatus() throws Exception {
94 mockMvc.perform(get("/api/exception-translator-test/response-status"))
95 .andExpect(status().isBadRequest())
96 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
97 .andExpect(jsonPath("$.message").value("error.http.400"))
98 .andExpect(jsonPath("$.title").value("test response status"));
99 }
100
101 @Test
102 public void testInternalServerError() throws Exception {
103 mockMvc.perform(get("/api/exception-translator-test/internal-server-error"))
104 .andExpect(status().isInternalServerError())
105 .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
106 .andExpect(jsonPath("$.message").value("error.http.500"))
107 .andExpect(jsonPath("$.title").value("Internal Server Error"));
108 }
109
110 }
File src/test/java/hu/dns/honlap/web/rest/errors/ExceptionTranslatorTestController.java added (mode: 100644) (index 0000000..5331e52)
1 package hu.dns.honlap.web.rest.errors;
2
3 import org.springframework.dao.ConcurrencyFailureException;
4 import org.springframework.http.HttpStatus;
5 import org.springframework.security.access.AccessDeniedException;
6 import org.springframework.security.authentication.BadCredentialsException;
7 import org.springframework.web.bind.annotation.*;
8
9 import javax.validation.Valid;
10 import javax.validation.constraints.NotNull;
11
12 @RestController
13 @RequestMapping("/api/exception-translator-test")
14 public class ExceptionTranslatorTestController {
15
16 @GetMapping("/concurrency-failure")
17 public void concurrencyFailure() {
18 throw new ConcurrencyFailureException("test concurrency failure");
19 }
20
21 @PostMapping("/method-argument")
22 public void methodArgument(@Valid @RequestBody TestDTO testDTO) {
23 }
24
25 @GetMapping("/missing-servlet-request-part")
26 public void missingServletRequestPartException(@RequestPart String part) {
27 }
28
29 @GetMapping("/missing-servlet-request-parameter")
30 public void missingServletRequestParameterException(@RequestParam String param) {
31 }
32
33 @GetMapping("/access-denied")
34 public void accessdenied() {
35 throw new AccessDeniedException("test access denied!");
36 }
37
38 @GetMapping("/unauthorized")
39 public void unauthorized() {
40 throw new BadCredentialsException("test authentication failed!");
41 }
42
43 @GetMapping("/response-status")
44 public void exceptionWithResponseStatus() {
45 throw new TestResponseStatusException();
46 }
47
48 @GetMapping("/internal-server-error")
49 public void internalServerError() {
50 throw new RuntimeException();
51 }
52
53 public static class TestDTO {
54
55 @NotNull
56 private String test;
57
58 public String getTest() {
59 return test;
60 }
61
62 public void setTest(String test) {
63 this.test = test;
64 }
65 }
66
67 @ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "test response status")
68 @SuppressWarnings("serial")
69 public static class TestResponseStatusException extends RuntimeException {
70 }
71
72 }
File src/test/javascript/e2e/account/account.spec.ts added (mode: 100644) (index 0000000..a16236b)
1 import { browser, element, by, ExpectedConditions as ec } from 'protractor';
2
3 import { NavBarPage, SignInPage, PasswordPage, SettingsPage } from '../page-objects/jhi-page-objects';
4
5 const expect = chai.expect;
6
7 describe('account', () => {
8 let navBarPage: NavBarPage;
9 let signInPage: SignInPage;
10 let passwordPage: PasswordPage;
11 let settingsPage: SettingsPage;
12
13 before(async () => {
14 await browser.get('/');
15 navBarPage = new NavBarPage(true);
16 });
17
18 it('should fail to login with bad password', async () => {
19 const expect1 = 'home.title';
20 const value1 = await element(by.css('h1')).getAttribute('jhiTranslate');
21 expect(value1).to.eq(expect1);
22 signInPage = await navBarPage.getSignInPage();
23 await signInPage.autoSignInUsing('admin', 'foo');
24
25 const expect2 = 'login.messages.error.authentication';
26 const value2 = await element(by.css('.alert-danger')).getAttribute('jhiTranslate');
27 expect(value2).to.eq(expect2);
28 });
29
30 it('should login successfully with admin account', async () => {
31 await browser.get('/');
32 signInPage = await navBarPage.getSignInPage();
33
34 const expect1 = 'global.form.username.label';
35 const value1 = await element(by.className('username-label')).getAttribute('jhiTranslate');
36 expect(value1).to.eq(expect1);
37 await signInPage.autoSignInUsing('admin', 'admin');
38
39 const expect2 = 'home.logged.message';
40 await browser.wait(ec.visibilityOf(element(by.id('home-logged-message'))));
41 const value2 = await element(by.id('home-logged-message')).getAttribute('jhiTranslate');
42 expect(value2).to.eq(expect2);
43 });
44
45 it('should be able to update settings', async () => {
46 settingsPage = await navBarPage.getSettingsPage();
47
48 const expect1 = 'settings.title';
49 const value1 = await settingsPage.getTitle();
50 expect(value1).to.eq(expect1);
51 await settingsPage.save();
52
53 const expect2 = 'settings.messages.success';
54 const alert = element(by.css('.alert-success'));
55 const value2 = await alert.getAttribute('jhiTranslate');
56 expect(value2).to.eq(expect2);
57 });
58
59 it('should fail to update password when using incorrect current password', async () => {
60 passwordPage = await navBarPage.getPasswordPage();
61
62 expect(await passwordPage.getTitle()).to.eq('password.title');
63
64 await passwordPage.setCurrentPassword('wrong_current_password');
65 await passwordPage.setPassword('new_password');
66 await passwordPage.setConfirmPassword('new_password');
67 await passwordPage.save();
68
69 const expect2 = 'password.messages.error';
70 const alert = element(by.css('.alert-danger'));
71 const value2 = await alert.getAttribute('jhiTranslate');
72 expect(value2).to.eq(expect2);
73 settingsPage = await navBarPage.getSettingsPage();
74 });
75
76 it('should be able to update password', async () => {
77 passwordPage = await navBarPage.getPasswordPage();
78
79 expect(await passwordPage.getTitle()).to.eq('password.title');
80
81 await passwordPage.setCurrentPassword('admin');
82 await passwordPage.setPassword('newpassword');
83 await passwordPage.setConfirmPassword('newpassword');
84 await passwordPage.save();
85
86 const successMsg = 'password.messages.success';
87 const alert = element(by.css('.alert-success'));
88 const alertValue = await alert.getAttribute('jhiTranslate');
89 expect(alertValue).to.eq(successMsg);
90 await navBarPage.autoSignOut();
91 await navBarPage.goToSignInPage();
92 await signInPage.autoSignInUsing('admin', 'newpassword');
93
94 // change back to default
95 await navBarPage.goToPasswordMenu();
96 await passwordPage.setCurrentPassword('newpassword');
97 await passwordPage.setPassword('admin');
98 await passwordPage.setConfirmPassword('admin');
99 await passwordPage.save();
100
101 // wait for success message
102 const alertValue2 = await alert.getAttribute('jhiTranslate');
103 expect(alertValue2).to.eq(successMsg);
104 });
105
106 it('should navigate to 404 not found error page on non existing route and show user own navbar if valid authentication exists', async () => {
107 // don't sign out and refresh page with non existing route
108 await browser.get('/this-is-link-to-non-existing-page');
109
110 // should navigate to 404 not found page
111 const url = await browser.getCurrentUrl();
112 expect(url).to.endWith('404');
113
114 // as user is admin then should show admin menu to user
115 await navBarPage.clickOnAdminMenu();
116 });
117
118 after(async () => {
119 await navBarPage.autoSignOut();
120 });
121 });
File src/test/javascript/e2e/admin/administration.spec.ts added (mode: 100644) (index 0000000..5a65663)
1 import { browser, element, by, ExpectedConditions as ec } from 'protractor';
2
3 import { NavBarPage, SignInPage } from '../page-objects/jhi-page-objects';
4
5 const expect = chai.expect;
6
7 describe('administration', () => {
8 let navBarPage: NavBarPage;
9 let signInPage: SignInPage;
10
11 before(async () => {
12 await browser.get('/');
13 navBarPage = new NavBarPage(true);
14 signInPage = await navBarPage.getSignInPage();
15 await signInPage.autoSignInUsing('admin', 'admin');
16 await browser.wait(ec.visibilityOf(navBarPage.adminMenu), 5000);
17 });
18
19 beforeEach(async () => {
20 await navBarPage.clickOnAdminMenu();
21 });
22
23 it('should load user management', async () => {
24 await navBarPage.clickOnAdmin('user-management');
25 const expect1 = 'userManagement.home.title';
26 const value1 = await element(by.id('user-management-page-heading')).getAttribute('jhiTranslate');
27 expect(value1).to.eq(expect1);
28 });
29
30 it('should load metrics', async () => {
31 await navBarPage.clickOnAdmin('metrics');
32 const expect1 = 'metrics.title';
33 const value1 = await element(by.id('metrics-page-heading')).getAttribute('jhiTranslate');
34 expect(value1).to.eq(expect1);
35 });
36
37 it('should load health', async () => {
38 await navBarPage.clickOnAdmin('health');
39 const expect1 = 'health.title';
40 const value1 = await element(by.id('health-page-heading')).getAttribute('jhiTranslate');
41 expect(value1).to.eq(expect1);
42 });
43
44 it('should load configuration', async () => {
45 await navBarPage.clickOnAdmin('configuration');
46 await browser.sleep(500);
47 const expect1 = 'configuration.title';
48 const value1 = await element(by.id('configuration-page-heading')).getAttribute('jhiTranslate');
49 expect(value1).to.eq(expect1);
50 });
51
52 it('should load audits', async () => {
53 await navBarPage.clickOnAdmin('audits');
54 await browser.sleep(500);
55 const expect1 = 'audits.title';
56 const value1 = await element(by.id('audits-page-heading')).getAttribute('jhiTranslate');
57 expect(value1).to.eq(expect1);
58 });
59
60 it('should load logs', async () => {
61 await navBarPage.clickOnAdmin('logs');
62 await browser.sleep(500);
63 const expect1 = 'logs.title';
64 const value1 = await element(by.id('logs-page-heading')).getAttribute('jhiTranslate');
65 expect(value1).to.eq(expect1);
66 });
67
68 after(async () => {
69 await navBarPage.autoSignOut();
70 });
71 });
File src/test/javascript/e2e/entities/piece-of-news/piece-of-news.page-object.ts added (mode: 100644) (index 0000000..3695094)
1 import { element, by, ElementFinder } from 'protractor';
2
3 export class PieceOfNewsComponentsPage {
4 createButton = element(by.id('jh-create-entity'));
5 deleteButtons = element.all(by.css('auth-piece-of-news div table .btn-danger'));
6 title = element.all(by.css('auth-piece-of-news div h2#page-heading span')).first();
7 noResult = element(by.id('no-result'));
8 entities = element(by.id('entities'));
9
10 async clickOnCreateButton(): Promise<void> {
11 await this.createButton.click();
12 }
13
14 async clickOnLastDeleteButton(): Promise<void> {
15 await this.deleteButtons.last().click();
16 }
17
18 async countDeleteButtons(): Promise<number> {
19 return this.deleteButtons.count();
20 }
21
22 async getTitle(): Promise<string> {
23 return this.title.getAttribute('jhiTranslate');
24 }
25 }
26
27 export class PieceOfNewsUpdatePage {
28 pageTitle = element(by.id('auth-piece-of-news-heading'));
29 saveButton = element(by.id('save-entity'));
30 cancelButton = element(by.id('cancel-save'));
31
32 appIdInput = element(by.id('field_appId'));
33 newsDateInput = element(by.id('field_newsDate'));
34 headlineInput = element(by.id('field_headline'));
35 contentInput = element(by.id('field_content'));
36 linkInput = element(by.id('field_link'));
37 publishDateInput = element(by.id('field_publishDate'));
38 createdByInput = element(by.id('field_createdBy'));
39 createdDateInput = element(by.id('field_createdDate'));
40 lastModifiedByInput = element(by.id('field_lastModifiedBy'));
41 lastModifiedDateInput = element(by.id('field_lastModifiedDate'));
42
43 async getPageTitle(): Promise<string> {
44 return this.pageTitle.getAttribute('jhiTranslate');
45 }
46
47 async setAppIdInput(appId: string): Promise<void> {
48 await this.appIdInput.sendKeys(appId);
49 }
50
51 async getAppIdInput(): Promise<string> {
52 return await this.appIdInput.getAttribute('value');
53 }
54
55 async setNewsDateInput(newsDate: string): Promise<void> {
56 await this.newsDateInput.sendKeys(newsDate);
57 }
58
59 async getNewsDateInput(): Promise<string> {
60 return await this.newsDateInput.getAttribute('value');
61 }
62
63 async setHeadlineInput(headline: string): Promise<void> {
64 await this.headlineInput.sendKeys(headline);
65 }
66
67 async getHeadlineInput(): Promise<string> {
68 return await this.headlineInput.getAttribute('value');
69 }
70
71 async setContentInput(content: string): Promise<void> {
72 await this.contentInput.sendKeys(content);
73 }
74
75 async getContentInput(): Promise<string> {
76 return await this.contentInput.getAttribute('value');
77 }
78
79 async setLinkInput(link: string): Promise<void> {
80 await this.linkInput.sendKeys(link);
81 }
82
83 async getLinkInput(): Promise<string> {
84 return await this.linkInput.getAttribute('value');
85 }
86
87 async setPublishDateInput(publishDate: string): Promise<void> {
88 await this.publishDateInput.sendKeys(publishDate);
89 }
90
91 async getPublishDateInput(): Promise<string> {
92 return await this.publishDateInput.getAttribute('value');
93 }
94
95 async setCreatedByInput(createdBy: string): Promise<void> {
96 await this.createdByInput.sendKeys(createdBy);
97 }
98
99 async getCreatedByInput(): Promise<string> {
100 return await this.createdByInput.getAttribute('value');
101 }
102
103 async setCreatedDateInput(createdDate: string): Promise<void> {
104 await this.createdDateInput.sendKeys(createdDate);
105 }
106
107 async getCreatedDateInput(): Promise<string> {
108 return await this.createdDateInput.getAttribute('value');
109 }
110
111 async setLastModifiedByInput(lastModifiedBy: string): Promise<void> {
112 await this.lastModifiedByInput.sendKeys(lastModifiedBy);
113 }
114
115 async getLastModifiedByInput(): Promise<string> {
116 return await this.lastModifiedByInput.getAttribute('value');
117 }
118
119 async setLastModifiedDateInput(lastModifiedDate: string): Promise<void> {
120 await this.lastModifiedDateInput.sendKeys(lastModifiedDate);
121 }
122
123 async getLastModifiedDateInput(): Promise<string> {
124 return await this.lastModifiedDateInput.getAttribute('value');
125 }
126
127 async save(): Promise<void> {
128 await this.saveButton.click();
129 }
130
131 async cancel(): Promise<void> {
132 await this.cancelButton.click();
133 }
134
135 getSaveButton(): ElementFinder {
136 return this.saveButton;
137 }
138 }
139
140 export class PieceOfNewsDeleteDialog {
141 private dialogTitle = element(by.id('auth-delete-pieceOfNews-heading'));
142 private confirmButton = element(by.id('auth-confirm-delete-pieceOfNews'));
143
144 async getDialogTitle(): Promise<string> {
145 return this.dialogTitle.getAttribute('jhiTranslate');
146 }
147
148 async clickOnConfirmButton(): Promise<void> {
149 await this.confirmButton.click();
150 }
151 }
File src/test/javascript/e2e/entities/piece-of-news/piece-of-news.spec.ts added (mode: 100644) (index 0000000..81f32d7)
1 import { browser, ExpectedConditions as ec, protractor, promise } from 'protractor';
2 import { NavBarPage, SignInPage } from '../../page-objects/jhi-page-objects';
3
4 import { PieceOfNewsComponentsPage, PieceOfNewsDeleteDialog, PieceOfNewsUpdatePage } from './piece-of-news.page-object';
5
6 const expect = chai.expect;
7
8 describe('PieceOfNews e2e test', () => {
9 let navBarPage: NavBarPage;
10 let signInPage: SignInPage;
11 let pieceOfNewsComponentsPage: PieceOfNewsComponentsPage;
12 let pieceOfNewsUpdatePage: PieceOfNewsUpdatePage;
13 let pieceOfNewsDeleteDialog: PieceOfNewsDeleteDialog;
14
15 before(async () => {
16 await browser.get('/');
17 navBarPage = new NavBarPage();
18 signInPage = await navBarPage.getSignInPage();
19 await signInPage.autoSignInUsing('admin', 'admin');
20 await browser.wait(ec.visibilityOf(navBarPage.entityMenu), 5000);
21 });
22
23 it('should load PieceOfNews', async () => {
24 await navBarPage.goToEntity('piece-of-news');
25 pieceOfNewsComponentsPage = new PieceOfNewsComponentsPage();
26 await browser.wait(ec.visibilityOf(pieceOfNewsComponentsPage.title), 5000);
27 expect(await pieceOfNewsComponentsPage.getTitle()).to.eq('honlapApp.pieceOfNews.home.title');
28 await browser.wait(
29 ec.or(ec.visibilityOf(pieceOfNewsComponentsPage.entities), ec.visibilityOf(pieceOfNewsComponentsPage.noResult)),
30 1000
31 );
32 });
33
34 it('should load create PieceOfNews page', async () => {
35 await pieceOfNewsComponentsPage.clickOnCreateButton();
36 pieceOfNewsUpdatePage = new PieceOfNewsUpdatePage();
37 expect(await pieceOfNewsUpdatePage.getPageTitle()).to.eq('honlapApp.pieceOfNews.home.createOrEditLabel');
38 await pieceOfNewsUpdatePage.cancel();
39 });
40
41 it('should create and save PieceOfNews', async () => {
42 const nbButtonsBeforeCreate = await pieceOfNewsComponentsPage.countDeleteButtons();
43
44 await pieceOfNewsComponentsPage.clickOnCreateButton();
45
46 await promise.all([
47 pieceOfNewsUpdatePage.setAppIdInput('5'),
48 pieceOfNewsUpdatePage.setNewsDateInput('01/01/2001' + protractor.Key.TAB + '02:30AM'),
49 pieceOfNewsUpdatePage.setHeadlineInput('headline'),
50 pieceOfNewsUpdatePage.setContentInput('content'),
51 pieceOfNewsUpdatePage.setLinkInput('link'),
52 pieceOfNewsUpdatePage.setPublishDateInput('01/01/2001' + protractor.Key.TAB + '02:30AM'),
53 pieceOfNewsUpdatePage.setCreatedByInput('createdBy'),
54 pieceOfNewsUpdatePage.setCreatedDateInput('01/01/2001' + protractor.Key.TAB + '02:30AM'),
55 pieceOfNewsUpdatePage.setLastModifiedByInput('lastModifiedBy'),
56 pieceOfNewsUpdatePage.setLastModifiedDateInput('01/01/2001' + protractor.Key.TAB + '02:30AM')
57 ]);
58
59 expect(await pieceOfNewsUpdatePage.getAppIdInput()).to.eq('5', 'Expected appId value to be equals to 5');
60 expect(await pieceOfNewsUpdatePage.getNewsDateInput()).to.contain(
61 '2001-01-01T02:30',
62 'Expected newsDate value to be equals to 2000-12-31'
63 );
64 expect(await pieceOfNewsUpdatePage.getHeadlineInput()).to.eq('headline', 'Expected Headline value to be equals to headline');
65 expect(await pieceOfNewsUpdatePage.getContentInput()).to.eq('content', 'Expected Content value to be equals to content');
66 expect(await pieceOfNewsUpdatePage.getLinkInput()).to.eq('link', 'Expected Link value to be equals to link');
67 expect(await pieceOfNewsUpdatePage.getPublishDateInput()).to.contain(
68 '2001-01-01T02:30',
69 'Expected publishDate value to be equals to 2000-12-31'
70 );
71 expect(await pieceOfNewsUpdatePage.getCreatedByInput()).to.eq('createdBy', 'Expected CreatedBy value to be equals to createdBy');
72 expect(await pieceOfNewsUpdatePage.getCreatedDateInput()).to.contain(
73 '2001-01-01T02:30',
74 'Expected createdDate value to be equals to 2000-12-31'
75 );
76 expect(await pieceOfNewsUpdatePage.getLastModifiedByInput()).to.eq(
77 'lastModifiedBy',
78 'Expected LastModifiedBy value to be equals to lastModifiedBy'
79 );
80 expect(await pieceOfNewsUpdatePage.getLastModifiedDateInput()).to.contain(
81 '2001-01-01T02:30',
82 'Expected lastModifiedDate value to be equals to 2000-12-31'
83 );
84
85 await pieceOfNewsUpdatePage.save();
86 expect(await pieceOfNewsUpdatePage.getSaveButton().isPresent(), 'Expected save button disappear').to.be.false;
87
88 expect(await pieceOfNewsComponentsPage.countDeleteButtons()).to.eq(nbButtonsBeforeCreate + 1, 'Expected one more entry in the table');
89 });
90
91 it('should delete last PieceOfNews', async () => {
92 const nbButtonsBeforeDelete = await pieceOfNewsComponentsPage.countDeleteButtons();
93 await pieceOfNewsComponentsPage.clickOnLastDeleteButton();
94
95 pieceOfNewsDeleteDialog = new PieceOfNewsDeleteDialog();
96 expect(await pieceOfNewsDeleteDialog.getDialogTitle()).to.eq('honlapApp.pieceOfNews.delete.question');
97 await pieceOfNewsDeleteDialog.clickOnConfirmButton();
98
99 expect(await pieceOfNewsComponentsPage.countDeleteButtons()).to.eq(nbButtonsBeforeDelete - 1);
100 });
101
102 after(async () => {
103 await navBarPage.autoSignOut();
104 });
105 });
File src/test/javascript/e2e/page-objects/jhi-page-objects.ts added (mode: 100644) (index 0000000..cbfa50c)
1 import { element, by, ElementFinder } from 'protractor';
2
3 /* eslint @typescript-eslint/no-use-before-define: 0 */
4 export class NavBarPage {
5 entityMenu = element(by.id('entity-menu'));
6 accountMenu = element(by.id('account-menu'));
7 adminMenu!: ElementFinder;
8 signIn = element(by.id('login'));
9 register = element(by.css('[routerLink="account/register"]'));
10 signOut = element(by.id('logout'));
11 passwordMenu = element(by.css('[routerLink="account/password"]'));
12 settingsMenu = element(by.css('[routerLink="account/settings"]'));
13
14 constructor(asAdmin?: Boolean) {
15 if (asAdmin) {
16 this.adminMenu = element(by.id('admin-menu'));
17 }
18 }
19
20 async clickOnEntityMenu(): Promise<void> {
21 await this.entityMenu.click();
22 }
23
24 async clickOnAccountMenu(): Promise<void> {
25 await this.accountMenu.click();
26 }
27
28 async clickOnAdminMenu(): Promise<void> {
29 await this.adminMenu.click();
30 }
31
32 async clickOnSignIn(): Promise<void> {
33 await this.signIn.click();
34 }
35
36 async clickOnRegister(): Promise<void> {
37 await this.signIn.click();
38 }
39
40 async clickOnSignOut(): Promise<void> {
41 await this.signOut.click();
42 }
43
44 async clickOnPasswordMenu(): Promise<void> {
45 await this.passwordMenu.click();
46 }
47
48 async clickOnSettingsMenu(): Promise<void> {
49 await this.settingsMenu.click();
50 }
51
52 async clickOnEntity(entityName: string): Promise<void> {
53 await element(by.css('[routerLink="' + entityName + '"]')).click();
54 }
55
56 async clickOnAdmin(entityName: string): Promise<void> {
57 await element(by.css('[routerLink="admin/' + entityName + '"]')).click();
58 }
59
60 async getSignInPage(): Promise<SignInPage> {
61 await this.clickOnAccountMenu();
62 await this.clickOnSignIn();
63 return new SignInPage();
64 }
65
66 async getPasswordPage(): Promise<PasswordPage> {
67 await this.clickOnAccountMenu();
68 await this.clickOnPasswordMenu();
69 return new PasswordPage();
70 }
71
72 async getSettingsPage(): Promise<SettingsPage> {
73 await this.clickOnAccountMenu();
74 await this.clickOnSettingsMenu();
75 return new SettingsPage();
76 }
77
78 async goToEntity(entityName: string): Promise<void> {
79 await this.clickOnEntityMenu();
80 await this.clickOnEntity(entityName);
81 }
82
83 async goToSignInPage(): Promise<void> {
84 await this.clickOnAccountMenu();
85 await this.clickOnSignIn();
86 }
87
88 async goToPasswordMenu(): Promise<void> {
89 await this.clickOnAccountMenu();
90 await this.clickOnPasswordMenu();
91 }
92
93 async autoSignOut(): Promise<void> {
94 await this.clickOnAccountMenu();
95 await this.clickOnSignOut();
96 }
97 }
98
99 export class SignInPage {
100 username = element(by.id('username'));
101 password = element(by.id('password'));
102 loginButton = element(by.css('button[type=submit]'));
103
104 async setUserName(username: string): Promise<void> {
105 await this.username.sendKeys(username);
106 }
107
108 async getUserName(): Promise<string> {
109 return this.username.getAttribute('value');
110 }
111
112 async clearUserName(): Promise<void> {
113 await this.username.clear();
114 }
115
116 async setPassword(password: string): Promise<void> {
117 await this.password.sendKeys(password);
118 }
119
120 async getPassword(): Promise<string> {
121 return this.password.getAttribute('value');
122 }
123
124 async clearPassword(): Promise<void> {
125 await this.password.clear();
126 }
127
128 async autoSignInUsing(username: string, password: string): Promise<void> {
129 await this.setUserName(username);
130 await this.setPassword(password);
131 await this.login();
132 }
133
134 async login(): Promise<void> {
135 await this.loginButton.click();
136 }
137 }
138
139 export class PasswordPage {
140 currentPassword = element(by.id('currentPassword'));
141 password = element(by.id('newPassword'));
142 confirmPassword = element(by.id('confirmPassword'));
143 saveButton = element(by.css('button[type=submit]'));
144 title = element.all(by.css('h2')).first();
145
146 async setCurrentPassword(password: string): Promise<void> {
147 await this.currentPassword.sendKeys(password);
148 }
149
150 async setPassword(password: string): Promise<void> {
151 await this.password.sendKeys(password);
152 }
153
154 async getPassword(): Promise<string> {
155 return this.password.getAttribute('value');
156 }
157
158 async clearPassword(): Promise<void> {
159 await this.password.clear();
160 }
161
162 async setConfirmPassword(confirmPassword: string): Promise<void> {
163 await this.confirmPassword.sendKeys(confirmPassword);
164 }
165
166 async getConfirmPassword(): Promise<string> {
167 return this.confirmPassword.getAttribute('value');
168 }
169
170 async clearConfirmPassword(): Promise<void> {
171 await this.confirmPassword.clear();
172 }
173
174 async getTitle(): Promise<string> {
175 return this.title.getAttribute('jhiTranslate');
176 }
177
178 async save(): Promise<void> {
179 await this.saveButton.click();
180 }
181 }
182
183 export class SettingsPage {
184 firstName = element(by.id('firstName'));
185 lastName = element(by.id('lastName'));
186 email = element(by.id('email'));
187 saveButton = element(by.css('button[type=submit]'));
188 title = element.all(by.css('h2')).first();
189
190 async setFirstName(firstName: string): Promise<void> {
191 await this.firstName.sendKeys(firstName);
192 }
193
194 async getFirstName(): Promise<string> {
195 return this.firstName.getAttribute('value');
196 }
197
198 async clearFirstName(): Promise<void> {
199 await this.firstName.clear();
200 }
201
202 async setLastName(lastName: string): Promise<void> {
203 await this.lastName.sendKeys(lastName);
204 }
205
206 async getLastName(): Promise<string> {
207 return this.lastName.getAttribute('value');
208 }
209
210 async clearLastName(): Promise<void> {
211 await this.lastName.clear();
212 }
213
214 async setEmail(email: string): Promise<void> {
215 await this.email.sendKeys(email);
216 }
217
218 async getEmail(): Promise<string> {
219 return this.email.getAttribute('value');
220 }
221
222 async clearEmail(): Promise<void> {
223 await this.email.clear();
224 }
225
226 async getTitle(): Promise<string> {
227 return this.title.getAttribute('jhiTranslate');
228 }
229
230 async save(): Promise<void> {
231 await this.saveButton.click();
232 }
233 }
File src/test/javascript/jest-global-mocks.ts added (mode: 100644) (index 0000000..a802d1b)
1 Object.defineProperty(window, 'getComputedStyle', {
2 value: () => ['-webkit-appearance']
3 });
File src/test/javascript/jest.conf.js added (mode: 100644) (index 0000000..91d9d5f)
1 const tsconfig = require('../../../tsconfig.json');
2
3 module.exports = {
4 preset: 'jest-preset-angular',
5 setupFiles: ['jest-date-mock'],
6 setupFilesAfterEnv: ['<rootDir>/src/test/javascript/jest.ts'],
7 cacheDirectory: '<rootDir>/target/jest-cache',
8 coverageDirectory: '<rootDir>/target/test-results/',
9 globals: {
10 'ts-jest': {
11 stringifyContentPathRegex: '\\.html$',
12 tsConfig: '<rootDir>/tsconfig.json',
13 astTransformers: ['jest-preset-angular/build/InlineFilesTransformer', 'jest-preset-angular/build/StripStylesTransformer']
14 }
15 },
16 coveragePathIgnorePatterns: [
17 '<rootDir>/src/test/javascript'
18 ],
19 moduleNameMapper: mapTypescriptAliasToJestAlias(),
20 reporters: [
21 'default',
22 [ 'jest-junit', { outputDirectory: './target/test-results/', outputName: 'TESTS-results-jest.xml' } ]
23 ],
24 testResultsProcessor: 'jest-sonar-reporter',
25 transformIgnorePatterns: ['node_modules/'],
26 testMatch: ['<rootDir>/src/test/javascript/spec/**/@(*.)@(spec.ts)'],
27 rootDir: '../../../',
28 testURL: 'http://localhost/'
29 };
30
31 function mapTypescriptAliasToJestAlias(alias = {}) {
32 const jestAliases = { ...alias };
33 if (!tsconfig.compilerOptions.paths) {
34 return jestAliases;
35 }
36 Object.entries(tsconfig.compilerOptions.paths)
37 .filter(([key, value]) => {
38 // use Typescript alias in Jest only if this has value
39 if (value.length) {
40 return true;
41 }
42 return false;
43 })
44 .map(([key, value]) => {
45 // if Typescript alias ends with /* then in Jest:
46 // - alias key must end with /(.*)
47 // - alias value must end with /$1
48 const regexToReplace = /(.*)\/\*$/;
49 const aliasKey = key.replace(regexToReplace, '$1/(.*)');
50 const aliasValue = value[0].replace(regexToReplace, '$1/$$1');
51 return [aliasKey, `<rootDir>/${aliasValue}`];
52 })
53 .reduce((aliases, [key, value]) => {
54 aliases[key] = value;
55 return aliases;
56 }, jestAliases);
57 return jestAliases;
58 }
File src/test/javascript/jest.ts added (mode: 100644) (index 0000000..904329f)
1 import 'jest-preset-angular';
2 import './jest-global-mocks';
File src/test/javascript/protractor.conf.js added (mode: 100644) (index 0000000..faed3b3)
1 exports.config = {
2 allScriptsTimeout: 20000,
3
4 specs: [
5 './e2e/account/**/*.spec.ts',
6 './e2e/admin/**/*.spec.ts',
7 './e2e/entities/**/*.spec.ts',
8 /* jhipster-needle-add-protractor-tests - JHipster will add protractors tests here */
9 ],
10
11 capabilities: {
12 browserName: 'chrome',
13 chromeOptions: {
14 args: process.env.JHI_E2E_HEADLESS
15 ? [ "--headless", "--disable-gpu", "--window-size=800,600" ]
16 : [ "--disable-gpu", "--window-size=800,600" ]
17 }
18 },
19
20 directConnect: true,
21
22 baseUrl: 'http://localhost:8080/',
23
24 framework: 'mocha',
25
26 SELENIUM_PROMISE_MANAGER: false,
27
28 mochaOpts: {
29 reporter: 'spec',
30 slow: 3000,
31 ui: 'bdd',
32 timeout: 720000
33 },
34
35 beforeLaunch: function() {
36 require('ts-node').register({
37 project: 'tsconfig.e2e.json'
38 });
39 },
40
41 onPrepare: function() {
42 browser.driver.manage().window().setSize(1280, 1024);
43 // Disable animations
44 // @ts-ignore
45 browser.executeScript('document.body.className += " notransition";');
46 const chai = require('chai');
47 const chaiAsPromised = require('chai-as-promised');
48 chai.use(chaiAsPromised);
49 const chaiString = require('chai-string');
50 chai.use(chaiString);
51 // @ts-ignore
52 global.chai = chai;
53 },
54
55 useAllAngular2AppRoots: true
56 };
File src/test/javascript/spec/app/account/activate/activate.component.spec.ts added (mode: 100644) (index 0000000..82c5195)
1 import { TestBed, async, tick, fakeAsync, inject } from '@angular/core/testing';
2 import { ActivatedRoute } from '@angular/router';
3 import { of, throwError } from 'rxjs';
4
5 import { HonlapTestModule } from '../../../test.module';
6 import { MockActivatedRoute } from '../../../helpers/mock-route.service';
7 import { ActivateService } from 'app/account/activate/activate.service';
8 import { ActivateComponent } from 'app/account/activate/activate.component';
9
10 describe('Component Tests', () => {
11 describe('ActivateComponent', () => {
12 let comp: ActivateComponent;
13
14 beforeEach(async(() => {
15 TestBed.configureTestingModule({
16 imports: [HonlapTestModule],
17 declarations: [ActivateComponent],
18 providers: [
19 {
20 provide: ActivatedRoute,
21 useValue: new MockActivatedRoute({ key: 'ABC123' })
22 }
23 ]
24 })
25 .overrideTemplate(ActivateComponent, '')
26 .compileComponents();
27 }));
28
29 beforeEach(() => {
30 const fixture = TestBed.createComponent(ActivateComponent);
31 comp = fixture.componentInstance;
32 });
33
34 it('calls activate.get with the key from params', inject(
35 [ActivateService],
36 fakeAsync((service: ActivateService) => {
37 spyOn(service, 'get').and.returnValue(of());
38
39 comp.ngOnInit();
40 tick();
41
42 expect(service.get).toHaveBeenCalledWith('ABC123');
43 })
44 ));
45
46 it('should set set success to true upon successful activation', inject(
47 [ActivateService],
48 fakeAsync((service: ActivateService) => {
49 spyOn(service, 'get').and.returnValue(of({}));
50
51 comp.ngOnInit();
52 tick();
53
54 expect(comp.error).toBe(false);
55 expect(comp.success).toBe(true);
56 })
57 ));
58
59 it('should set set error to true upon activation failure', inject(
60 [ActivateService],
61 fakeAsync((service: ActivateService) => {
62 spyOn(service, 'get').and.returnValue(throwError('ERROR'));
63
64 comp.ngOnInit();
65 tick();
66
67 expect(comp.error).toBe(true);
68 expect(comp.success).toBe(false);
69 })
70 ));
71 });
72 });
File src/test/javascript/spec/app/account/password-reset/finish/password-reset-finish.component.spec.ts added (mode: 100644) (index 0000000..2185aaf)
1 import { ElementRef } from '@angular/core';
2 import { ComponentFixture, TestBed, inject, tick, fakeAsync } from '@angular/core/testing';
3 import { FormBuilder } from '@angular/forms';
4 import { ActivatedRoute } from '@angular/router';
5 import { of, throwError } from 'rxjs';
6
7 import { HonlapTestModule } from '../../../../test.module';
8 import { PasswordResetFinishComponent } from 'app/account/password-reset/finish/password-reset-finish.component';
9 import { PasswordResetFinishService } from 'app/account/password-reset/finish/password-reset-finish.service';
10 import { MockActivatedRoute } from '../../../../helpers/mock-route.service';
11
12 describe('Component Tests', () => {
13 describe('PasswordResetFinishComponent', () => {
14 let fixture: ComponentFixture<PasswordResetFinishComponent>;
15 let comp: PasswordResetFinishComponent;
16
17 beforeEach(() => {
18 fixture = TestBed.configureTestingModule({
19 imports: [HonlapTestModule],
20 declarations: [PasswordResetFinishComponent],
21 providers: [
22 FormBuilder,
23 {
24 provide: ActivatedRoute,
25 useValue: new MockActivatedRoute({ key: 'XYZPDQ' })
26 }
27 ]
28 })
29 .overrideTemplate(PasswordResetFinishComponent, '')
30 .createComponent(PasswordResetFinishComponent);
31 });
32
33 beforeEach(() => {
34 fixture = TestBed.createComponent(PasswordResetFinishComponent);
35 comp = fixture.componentInstance;
36 comp.ngOnInit();
37 });
38
39 it('should define its initial state', () => {
40 expect(comp.initialized).toBe(true);
41 expect(comp.key).toEqual('XYZPDQ');
42 });
43
44 it('sets focus after the view has been initialized', () => {
45 const node = {
46 focus(): void {}
47 };
48 comp.newPassword = new ElementRef(node);
49 spyOn(node, 'focus');
50
51 comp.ngAfterViewInit();
52
53 expect(node.focus).toHaveBeenCalled();
54 });
55
56 it('should ensure the two passwords entered match', () => {
57 comp.passwordForm.patchValue({
58 newPassword: 'password',
59 confirmPassword: 'non-matching'
60 });
61
62 comp.finishReset();
63
64 expect(comp.doNotMatch).toBe(true);
65 });
66
67 it('should update success to true after resetting password', inject(
68 [PasswordResetFinishService],
69 fakeAsync((service: PasswordResetFinishService) => {
70 spyOn(service, 'save').and.returnValue(of({}));
71 comp.passwordForm.patchValue({
72 newPassword: 'password',
73 confirmPassword: 'password'
74 });
75
76 comp.finishReset();
77 tick();
78
79 expect(service.save).toHaveBeenCalledWith('XYZPDQ', 'password');
80 expect(comp.success).toBe(true);
81 })
82 ));
83
84 it('should notify of generic error', inject(
85 [PasswordResetFinishService],
86 fakeAsync((service: PasswordResetFinishService) => {
87 spyOn(service, 'save').and.returnValue(throwError('ERROR'));
88 comp.passwordForm.patchValue({
89 newPassword: 'password',
90 confirmPassword: 'password'
91 });
92
93 comp.finishReset();
94 tick();
95
96 expect(service.save).toHaveBeenCalledWith('XYZPDQ', 'password');
97 expect(comp.success).toBe(false);
98 expect(comp.error).toBe(true);
99 })
100 ));
101 });
102 });
File src/test/javascript/spec/app/account/password-reset/init/password-reset-init.component.spec.ts added (mode: 100644) (index 0000000..5d281b5)
1 import { ElementRef } from '@angular/core';
2 import { ComponentFixture, TestBed, inject } from '@angular/core/testing';
3 import { FormBuilder } from '@angular/forms';
4 import { of, throwError } from 'rxjs';
5
6 import { HonlapTestModule } from '../../../../test.module';
7 import { PasswordResetInitComponent } from 'app/account/password-reset/init/password-reset-init.component';
8 import { PasswordResetInitService } from 'app/account/password-reset/init/password-reset-init.service';
9
10 describe('Component Tests', () => {
11 describe('PasswordResetInitComponent', () => {
12 let fixture: ComponentFixture<PasswordResetInitComponent>;
13 let comp: PasswordResetInitComponent;
14
15 beforeEach(() => {
16 fixture = TestBed.configureTestingModule({
17 imports: [HonlapTestModule],
18 declarations: [PasswordResetInitComponent],
19 providers: [FormBuilder]
20 })
21 .overrideTemplate(PasswordResetInitComponent, '')
22 .createComponent(PasswordResetInitComponent);
23 comp = fixture.componentInstance;
24 });
25
26 it('sets focus after the view has been initialized', () => {
27 const node = {
28 focus(): void {}
29 };
30 comp.email = new ElementRef(node);
31 spyOn(node, 'focus');
32
33 comp.ngAfterViewInit();
34
35 expect(node.focus).toHaveBeenCalled();
36 });
37
38 it('notifies of success upon successful requestReset', inject([PasswordResetInitService], (service: PasswordResetInitService) => {
39 spyOn(service, 'save').and.returnValue(of({}));
40 comp.resetRequestForm.patchValue({
41 email: 'user@domain.com'
42 });
43
44 comp.requestReset();
45
46 expect(service.save).toHaveBeenCalledWith('user@domain.com');
47 expect(comp.success).toBe(true);
48 }));
49
50 it('no notification of success upon error response', inject([PasswordResetInitService], (service: PasswordResetInitService) => {
51 spyOn(service, 'save').and.returnValue(
52 throwError({
53 status: 503,
54 data: 'something else'
55 })
56 );
57 comp.resetRequestForm.patchValue({
58 email: 'user@domain.com'
59 });
60 comp.requestReset();
61
62 expect(service.save).toHaveBeenCalledWith('user@domain.com');
63 expect(comp.success).toBe(false);
64 }));
65 });
66 });
File src/test/javascript/spec/app/account/password/password-strength-bar.component.spec.ts added (mode: 100644) (index 0000000..ff1297e)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2
3 import { PasswordStrengthBarComponent } from 'app/account/password/password-strength-bar.component';
4
5 describe('Component Tests', () => {
6 describe('PasswordStrengthBarComponent', () => {
7 let comp: PasswordStrengthBarComponent;
8 let fixture: ComponentFixture<PasswordStrengthBarComponent>;
9
10 beforeEach(async(() => {
11 TestBed.configureTestingModule({
12 declarations: [PasswordStrengthBarComponent]
13 })
14 .overrideTemplate(PasswordStrengthBarComponent, '')
15 .compileComponents();
16 }));
17
18 beforeEach(() => {
19 fixture = TestBed.createComponent(PasswordStrengthBarComponent);
20 comp = fixture.componentInstance;
21 });
22
23 describe('PasswordStrengthBarComponents', () => {
24 it('should initialize with default values', () => {
25 expect(comp.measureStrength('')).toBe(0);
26 expect(comp.colors).toEqual(['#F00', '#F90', '#FF0', '#9F0', '#0F0']);
27 expect(comp.getColor(0).idx).toBe(1);
28 expect(comp.getColor(0).color).toBe(comp.colors[0]);
29 });
30
31 it('should increase strength upon password value change', () => {
32 expect(comp.measureStrength('')).toBe(0);
33 expect(comp.measureStrength('aa')).toBeGreaterThanOrEqual(comp.measureStrength(''));
34 expect(comp.measureStrength('aa^6')).toBeGreaterThanOrEqual(comp.measureStrength('aa'));
35 expect(comp.measureStrength('Aa090(**)')).toBeGreaterThanOrEqual(comp.measureStrength('aa^6'));
36 expect(comp.measureStrength('Aa090(**)+-07365')).toBeGreaterThanOrEqual(comp.measureStrength('Aa090(**)'));
37 });
38
39 it('should change the color based on strength', () => {
40 expect(comp.getColor(0).color).toBe(comp.colors[0]);
41 expect(comp.getColor(11).color).toBe(comp.colors[1]);
42 expect(comp.getColor(22).color).toBe(comp.colors[2]);
43 expect(comp.getColor(33).color).toBe(comp.colors[3]);
44 expect(comp.getColor(44).color).toBe(comp.colors[4]);
45 });
46 });
47 });
48 });
File src/test/javascript/spec/app/account/password/password.component.spec.ts added (mode: 100644) (index 0000000..385f8eb)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { HttpResponse } from '@angular/common/http';
3 import { FormBuilder } from '@angular/forms';
4 import { of, throwError } from 'rxjs';
5
6 import { HonlapTestModule } from '../../../test.module';
7 import { PasswordComponent } from 'app/account/password/password.component';
8 import { PasswordService } from 'app/account/password/password.service';
9
10 describe('Component Tests', () => {
11 describe('PasswordComponent', () => {
12 let comp: PasswordComponent;
13 let fixture: ComponentFixture<PasswordComponent>;
14 let service: PasswordService;
15
16 beforeEach(async(() => {
17 TestBed.configureTestingModule({
18 imports: [HonlapTestModule],
19 declarations: [PasswordComponent],
20 providers: [FormBuilder]
21 })
22 .overrideTemplate(PasswordComponent, '')
23 .compileComponents();
24 }));
25
26 beforeEach(() => {
27 fixture = TestBed.createComponent(PasswordComponent);
28 comp = fixture.componentInstance;
29 service = fixture.debugElement.injector.get(PasswordService);
30 });
31
32 it('should show error if passwords do not match', () => {
33 // GIVEN
34 comp.passwordForm.patchValue({
35 newPassword: 'password1',
36 confirmPassword: 'password2'
37 });
38 // WHEN
39 comp.changePassword();
40 // THEN
41 expect(comp.doNotMatch).toBe(true);
42 expect(comp.error).toBe(false);
43 expect(comp.success).toBe(false);
44 });
45
46 it('should call Auth.changePassword when passwords match', () => {
47 // GIVEN
48 const passwordValues = {
49 currentPassword: 'oldPassword',
50 newPassword: 'myPassword'
51 };
52
53 spyOn(service, 'save').and.returnValue(of(new HttpResponse({ body: true })));
54
55 comp.passwordForm.patchValue({
56 currentPassword: passwordValues.currentPassword,
57 newPassword: passwordValues.newPassword,
58 confirmPassword: passwordValues.newPassword
59 });
60
61 // WHEN
62 comp.changePassword();
63
64 // THEN
65 expect(service.save).toHaveBeenCalledWith(passwordValues.newPassword, passwordValues.currentPassword);
66 });
67
68 it('should set success to true upon success', () => {
69 // GIVEN
70 spyOn(service, 'save').and.returnValue(of(new HttpResponse({ body: true })));
71 comp.passwordForm.patchValue({
72 newPassword: 'myPassword',
73 confirmPassword: 'myPassword'
74 });
75
76 // WHEN
77 comp.changePassword();
78
79 // THEN
80 expect(comp.doNotMatch).toBe(false);
81 expect(comp.error).toBe(false);
82 expect(comp.success).toBe(true);
83 });
84
85 it('should notify of error if change password fails', () => {
86 // GIVEN
87 spyOn(service, 'save').and.returnValue(throwError('ERROR'));
88 comp.passwordForm.patchValue({
89 newPassword: 'myPassword',
90 confirmPassword: 'myPassword'
91 });
92
93 // WHEN
94 comp.changePassword();
95
96 // THEN
97 expect(comp.doNotMatch).toBe(false);
98 expect(comp.success).toBe(false);
99 expect(comp.error).toBe(true);
100 });
101 });
102 });
File src/test/javascript/spec/app/account/register/register.component.spec.ts added (mode: 100644) (index 0000000..65b06e5)
1 import { ComponentFixture, TestBed, async, inject, tick, fakeAsync } from '@angular/core/testing';
2 import { FormBuilder } from '@angular/forms';
3 import { of, throwError } from 'rxjs';
4 import { JhiLanguageService } from 'ng-jhipster';
5
6 import { MockLanguageService } from '../../../helpers/mock-language.service';
7 import { HonlapTestModule } from '../../../test.module';
8 import { EMAIL_ALREADY_USED_TYPE, LOGIN_ALREADY_USED_TYPE } from 'app/shared/constants/error.constants';
9 import { RegisterService } from 'app/account/register/register.service';
10 import { RegisterComponent } from 'app/account/register/register.component';
11
12 describe('Component Tests', () => {
13 describe('RegisterComponent', () => {
14 let fixture: ComponentFixture<RegisterComponent>;
15 let comp: RegisterComponent;
16
17 beforeEach(async(() => {
18 TestBed.configureTestingModule({
19 imports: [HonlapTestModule],
20 declarations: [RegisterComponent],
21 providers: [FormBuilder]
22 })
23 .overrideTemplate(RegisterComponent, '')
24 .compileComponents();
25 }));
26
27 beforeEach(() => {
28 fixture = TestBed.createComponent(RegisterComponent);
29 comp = fixture.componentInstance;
30 });
31
32 it('should ensure the two passwords entered match', () => {
33 comp.registerForm.patchValue({
34 password: 'password',
35 confirmPassword: 'non-matching'
36 });
37
38 comp.register();
39
40 expect(comp.doNotMatch).toBe(true);
41 });
42
43 it('should update success to true after creating an account', inject(
44 [RegisterService, JhiLanguageService],
45 fakeAsync((service: RegisterService, mockTranslate: MockLanguageService) => {
46 spyOn(service, 'save').and.returnValue(of({}));
47 comp.registerForm.patchValue({
48 password: 'password',
49 confirmPassword: 'password'
50 });
51
52 comp.register();
53 tick();
54
55 expect(service.save).toHaveBeenCalledWith({
56 email: '',
57 password: 'password',
58 login: '',
59 langKey: 'hu'
60 });
61 expect(comp.success).toBe(true);
62 expect(mockTranslate.getCurrentLanguageSpy).toHaveBeenCalled();
63 expect(comp.errorUserExists).toBe(false);
64 expect(comp.errorEmailExists).toBe(false);
65 expect(comp.error).toBe(false);
66 })
67 ));
68
69 it('should notify of user existence upon 400/login already in use', inject(
70 [RegisterService],
71 fakeAsync((service: RegisterService) => {
72 spyOn(service, 'save').and.returnValue(
73 throwError({
74 status: 400,
75 error: { type: LOGIN_ALREADY_USED_TYPE }
76 })
77 );
78 comp.registerForm.patchValue({
79 password: 'password',
80 confirmPassword: 'password'
81 });
82
83 comp.register();
84 tick();
85
86 expect(comp.errorUserExists).toBe(true);
87 expect(comp.errorEmailExists).toBe(false);
88 expect(comp.error).toBe(false);
89 })
90 ));
91
92 it('should notify of email existence upon 400/email address already in use', inject(
93 [RegisterService],
94 fakeAsync((service: RegisterService) => {
95 spyOn(service, 'save').and.returnValue(
96 throwError({
97 status: 400,
98 error: { type: EMAIL_ALREADY_USED_TYPE }
99 })
100 );
101 comp.registerForm.patchValue({
102 password: 'password',
103 confirmPassword: 'password'
104 });
105
106 comp.register();
107 tick();
108
109 expect(comp.errorEmailExists).toBe(true);
110 expect(comp.errorUserExists).toBe(false);
111 expect(comp.error).toBe(false);
112 })
113 ));
114
115 it('should notify of generic error', inject(
116 [RegisterService],
117 fakeAsync((service: RegisterService) => {
118 spyOn(service, 'save').and.returnValue(
119 throwError({
120 status: 503
121 })
122 );
123 comp.registerForm.patchValue({
124 password: 'password',
125 confirmPassword: 'password'
126 });
127
128 comp.register();
129 tick();
130
131 expect(comp.errorUserExists).toBe(false);
132 expect(comp.errorEmailExists).toBe(false);
133 expect(comp.error).toBe(true);
134 })
135 ));
136 });
137 });
File src/test/javascript/spec/app/account/settings/settings.component.spec.ts added (mode: 100644) (index 0000000..bd2f61d)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { FormBuilder } from '@angular/forms';
3 import { throwError, of } from 'rxjs';
4
5 import { HonlapTestModule } from '../../../test.module';
6 import { AccountService } from 'app/core/auth/account.service';
7 import { Account } from 'app/core/user/account.model';
8 import { SettingsComponent } from 'app/account/settings/settings.component';
9 import { MockAccountService } from '../../../helpers/mock-account.service';
10
11 describe('Component Tests', () => {
12 describe('SettingsComponent', () => {
13 let comp: SettingsComponent;
14 let fixture: ComponentFixture<SettingsComponent>;
15 let mockAuth: MockAccountService;
16 const accountValues: Account = {
17 firstName: 'John',
18 lastName: 'Doe',
19 activated: true,
20 email: 'john.doe@mail.com',
21 langKey: 'hu',
22 login: 'john',
23 authorities: [],
24 imageUrl: ''
25 };
26
27 beforeEach(async(() => {
28 TestBed.configureTestingModule({
29 imports: [HonlapTestModule],
30 declarations: [SettingsComponent],
31 providers: [FormBuilder]
32 })
33 .overrideTemplate(SettingsComponent, '')
34 .compileComponents();
35 }));
36
37 beforeEach(() => {
38 fixture = TestBed.createComponent(SettingsComponent);
39 comp = fixture.componentInstance;
40 mockAuth = TestBed.get(AccountService);
41 mockAuth.setIdentityResponse(accountValues);
42 });
43
44 it('should send the current identity upon save', () => {
45 // GIVEN
46 mockAuth.saveSpy.and.returnValue(of({}));
47 const settingsFormValues = {
48 firstName: 'John',
49 lastName: 'Doe',
50 email: 'john.doe@mail.com',
51 langKey: 'hu'
52 };
53
54 // WHEN
55 comp.ngOnInit();
56 comp.save();
57
58 // THEN
59 expect(mockAuth.identitySpy).toHaveBeenCalled();
60 expect(mockAuth.saveSpy).toHaveBeenCalledWith(accountValues);
61 expect(mockAuth.authenticateSpy).toHaveBeenCalledWith(accountValues);
62 expect(comp.settingsForm.value).toEqual(settingsFormValues);
63 });
64
65 it('should notify of success upon successful save', () => {
66 // GIVEN
67 mockAuth.saveSpy.and.returnValue(of({}));
68
69 // WHEN
70 comp.ngOnInit();
71 comp.save();
72
73 // THEN
74 expect(comp.success).toBe(true);
75 });
76
77 it('should notify of error upon failed save', () => {
78 // GIVEN
79 mockAuth.saveSpy.and.returnValue(throwError('ERROR'));
80
81 // WHEN
82 comp.ngOnInit();
83 comp.save();
84
85 // THEN
86 expect(comp.success).toBe(false);
87 });
88 });
89 });
File src/test/javascript/spec/app/admin/audits/audits.component.spec.ts added (mode: 100644) (index 0000000..8ebf759)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { HttpHeaders, HttpResponse } from '@angular/common/http';
3 import { of } from 'rxjs';
4 import { advanceTo } from 'jest-date-mock';
5
6 import { HonlapTestModule } from '../../../test.module';
7 import { AuditsComponent } from 'app/admin/audits/audits.component';
8 import { AuditsService } from 'app/admin/audits/audits.service';
9 import { Audit } from 'app/admin/audits/audit.model';
10 import { ITEMS_PER_PAGE } from 'app/shared/constants/pagination.constants';
11
12 function build2DigitsDatePart(datePart: number): string {
13 return `0${datePart}`.slice(-2);
14 }
15
16 function getDate(isToday = true): string {
17 let date: Date = new Date();
18 if (isToday) {
19 // Today + 1 day - needed if the current day must be included
20 date.setDate(date.getDate() + 1);
21 } else {
22 // get last month
23 if (date.getMonth() === 0) {
24 date = new Date(date.getFullYear() - 1, 11, date.getDate());
25 } else {
26 date = new Date(date.getFullYear(), date.getMonth() - 1, date.getDate());
27 }
28 }
29 const monthString = build2DigitsDatePart(date.getMonth() + 1);
30 const dateString = build2DigitsDatePart(date.getDate());
31 return `${date.getFullYear()}-${monthString}-${dateString}`;
32 }
33
34 describe('Component Tests', () => {
35 describe('AuditsComponent', () => {
36 let comp: AuditsComponent;
37 let fixture: ComponentFixture<AuditsComponent>;
38 let service: AuditsService;
39
40 beforeEach(async(() => {
41 TestBed.configureTestingModule({
42 imports: [HonlapTestModule],
43 declarations: [AuditsComponent],
44 providers: [AuditsService]
45 })
46 .overrideTemplate(AuditsComponent, '')
47 .compileComponents();
48 }));
49
50 beforeEach(() => {
51 fixture = TestBed.createComponent(AuditsComponent);
52 comp = fixture.componentInstance;
53 service = fixture.debugElement.injector.get(AuditsService);
54 });
55
56 describe('today function', () => {
57 it('should set toDate to current date', () => {
58 comp.ngOnInit();
59 expect(comp.toDate).toBe(getDate());
60 });
61
62 it('if current day is last day of month then should set toDate to first day of next month', () => {
63 advanceTo(new Date(2019, 0, 31, 0, 0, 0));
64 comp.ngOnInit();
65 expect(comp.toDate).toBe('2019-02-01');
66 });
67
68 it('if current day is not last day of month then should set toDate to next day of current month', () => {
69 advanceTo(new Date(2019, 0, 27, 0, 0, 0));
70 comp.ngOnInit();
71 expect(comp.toDate).toBe('2019-01-28');
72 });
73 });
74
75 describe('previousMonth function', () => {
76 it('should set fromDate to previous month', () => {
77 comp.ngOnInit();
78 expect(comp.fromDate).toBe(getDate(false));
79 });
80
81 it('if current month is January then should set fromDate to previous year last month', () => {
82 advanceTo(new Date(2019, 0, 20, 0, 0, 0));
83 comp.ngOnInit();
84 expect(comp.fromDate).toBe('2018-12-20');
85 });
86
87 it('if current month is not January then should set fromDate to current year previous month', () => {
88 advanceTo(new Date(2019, 1, 20, 0, 0, 0));
89 comp.ngOnInit();
90 expect(comp.fromDate).toBe('2019-01-20');
91 });
92 });
93
94 describe('By default, on init', () => {
95 it('should set all default values correctly', () => {
96 fixture.detectChanges();
97 expect(comp.toDate).toBe(getDate());
98 expect(comp.fromDate).toBe(getDate(false));
99 expect(comp.itemsPerPage).toBe(ITEMS_PER_PAGE);
100 expect(comp.page).toBe(10);
101 expect(comp.ascending).toBe(false);
102 expect(comp.predicate).toBe('id');
103 });
104 });
105
106 describe('OnInit', () => {
107 it('Should call load all on init', () => {
108 // GIVEN
109 const headers = new HttpHeaders().append('X-Total-Count', '1');
110 const audit = new Audit({ remoteAddress: '127.0.0.1', sessionId: '123' }, 'user', '20140101', 'AUTHENTICATION_SUCCESS');
111 spyOn(service, 'query').and.returnValue(
112 of(
113 new HttpResponse({
114 body: [audit],
115 headers
116 })
117 )
118 );
119
120 // WHEN
121 comp.ngOnInit();
122
123 // THEN
124 expect(service.query).toHaveBeenCalled();
125 expect(comp.audits && comp.audits[0]).toEqual(jasmine.objectContaining(audit));
126 expect(comp.totalItems).toBe(1);
127 });
128 });
129
130 describe('Create sort object', () => {
131 beforeEach(() => {
132 comp.toDate = getDate();
133 comp.fromDate = getDate(false);
134 spyOn(service, 'query').and.returnValue(of(new HttpResponse({ body: null })));
135 });
136
137 it('Should sort only by id asc', () => {
138 // GIVEN
139 comp.predicate = 'id';
140 comp.ascending = false;
141
142 // WHEN
143 comp.transition();
144
145 // THEN
146 expect(service.query).toBeCalledWith(
147 expect.objectContaining({
148 sort: ['id,desc']
149 })
150 );
151 });
152
153 it('Should sort by timestamp asc then by id', () => {
154 // GIVEN
155 comp.predicate = 'timestamp';
156 comp.ascending = true;
157
158 // WHEN
159 comp.transition();
160
161 // THEN
162 expect(service.query).toBeCalledWith(
163 expect.objectContaining({
164 sort: ['timestamp,asc', 'id']
165 })
166 );
167 });
168 });
169
170 describe('loadPage', () => {
171 beforeEach(() => {
172 comp.toDate = getDate();
173 comp.fromDate = getDate(false);
174 comp.previousPage = 1;
175 spyOn(comp, 'transition');
176 });
177
178 it('Should not reload page already shown', () => {
179 // WHEN
180 comp.loadPage(1);
181
182 // THEN
183 expect(comp.transition).not.toBeCalled();
184 });
185
186 it('Should load new page', () => {
187 // WHEN
188 comp.loadPage(2);
189
190 // THEN
191 expect(comp.previousPage).toBe(2);
192 expect(comp.transition).toBeCalled();
193 });
194 });
195
196 describe('transition', () => {
197 beforeEach(() => {
198 spyOn(service, 'query').and.returnValue(of(new HttpResponse({ body: null })));
199 });
200
201 it('Should not query data if fromDate and toDate are empty', () => {
202 // WHEN
203 comp.transition();
204
205 // THEN
206 expect(comp.canLoad()).toBe(false);
207 expect(service.query).not.toBeCalled();
208 });
209
210 it('Should query data if fromDate and toDate are not empty', () => {
211 // GIVEN
212 comp.toDate = getDate();
213 comp.fromDate = getDate(false);
214
215 // WHEN
216 comp.transition();
217
218 // THEN
219 expect(comp.canLoad()).toBe(true);
220 expect(service.query).toBeCalled();
221 });
222 });
223 });
224 });
File src/test/javascript/spec/app/admin/audits/audits.service.spec.ts added (mode: 100644) (index 0000000..d5073e2)
1 import { TestBed } from '@angular/core/testing';
2 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3 import { HttpResponse, HttpErrorResponse } from '@angular/common/http';
4
5 import { AuditsService, AuditsQuery } from 'app/admin/audits/audits.service';
6 import { Audit } from 'app/admin/audits/audit.model';
7 import { SERVER_API_URL } from 'app/app.constants';
8
9 describe('Service Tests', () => {
10 describe('Audits Service', () => {
11 let service: AuditsService;
12 let httpMock: HttpTestingController;
13 const fakeRequest: AuditsQuery = { page: 0, size: 0, sort: [], fromDate: '', toDate: '' };
14
15 beforeEach(() => {
16 TestBed.configureTestingModule({
17 imports: [HttpClientTestingModule]
18 });
19
20 service = TestBed.get(AuditsService);
21 httpMock = TestBed.get(HttpTestingController);
22 });
23
24 afterEach(() => {
25 httpMock.verify();
26 });
27
28 describe('Service methods', () => {
29 it('should call correct URL', () => {
30 service.query(fakeRequest).subscribe();
31
32 const req = httpMock.expectOne({ method: 'GET' });
33 const resourceUrl = SERVER_API_URL + 'management/audits';
34 expect(req.request.url).toEqual(resourceUrl);
35 });
36
37 it('should return Audits', () => {
38 let expectedResult: HttpResponse<Audit[]> = new HttpResponse({ body: [] });
39 const audit = new Audit({ remoteAddress: '127.0.0.1', sessionId: '123' }, 'user', '20140101', 'AUTHENTICATION_SUCCESS');
40
41 service.query(fakeRequest).subscribe(received => {
42 expectedResult = received;
43 });
44
45 const req = httpMock.expectOne({ method: 'GET' });
46 req.flush([audit]);
47 let audits: Audit[] = [];
48 if (expectedResult.body !== null) {
49 audits = expectedResult.body;
50 }
51 expect(audits.length).toBe(1);
52 expect(audits[0]).toEqual(audit);
53 });
54
55 it('should propagate not found response', () => {
56 let expectedResult = 0;
57 service.query(fakeRequest).subscribe(null, (error: HttpErrorResponse) => {
58 expectedResult = error.status;
59 });
60
61 const req = httpMock.expectOne({ method: 'GET' });
62 req.flush('Invalid request parameters', {
63 status: 404,
64 statusText: 'Bad Request'
65 });
66 expect(expectedResult).toEqual(404);
67 });
68 });
69 });
70 });
File src/test/javascript/spec/app/admin/configuration/configuration.component.spec.ts added (mode: 100644) (index 0000000..ed4eb8e)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { of } from 'rxjs';
3
4 import { HonlapTestModule } from '../../../test.module';
5 import { ConfigurationComponent } from 'app/admin/configuration/configuration.component';
6 import { ConfigurationService, Bean, PropertySource } from 'app/admin/configuration/configuration.service';
7
8 describe('Component Tests', () => {
9 describe('ConfigurationComponent', () => {
10 let comp: ConfigurationComponent;
11 let fixture: ComponentFixture<ConfigurationComponent>;
12 let service: ConfigurationService;
13
14 beforeEach(async(() => {
15 TestBed.configureTestingModule({
16 imports: [HonlapTestModule],
17 declarations: [ConfigurationComponent],
18 providers: [ConfigurationService]
19 })
20 .overrideTemplate(ConfigurationComponent, '')
21 .compileComponents();
22 }));
23
24 beforeEach(() => {
25 fixture = TestBed.createComponent(ConfigurationComponent);
26 comp = fixture.componentInstance;
27 service = fixture.debugElement.injector.get(ConfigurationService);
28 });
29
30 describe('OnInit', () => {
31 it('Should call load all on init', () => {
32 // GIVEN
33 const beans: Bean[] = [
34 {
35 prefix: 'jhipster',
36 properties: {
37 clientApp: {
38 name: 'jhipsterApp'
39 }
40 }
41 }
42 ];
43 const propertySources: PropertySource[] = [
44 {
45 name: 'server.ports',
46 properties: {
47 'local.server.port': {
48 value: '8080'
49 }
50 }
51 }
52 ];
53 spyOn(service, 'getBeans').and.returnValue(of(beans));
54 spyOn(service, 'getPropertySources').and.returnValue(of(propertySources));
55
56 // WHEN
57 comp.ngOnInit();
58
59 // THEN
60 expect(service.getBeans).toHaveBeenCalled();
61 expect(service.getPropertySources).toHaveBeenCalled();
62 expect(comp.allBeans).toEqual(beans);
63 expect(comp.beans).toEqual(beans);
64 expect(comp.propertySources).toEqual(propertySources);
65 });
66 });
67 });
68 });
File src/test/javascript/spec/app/admin/configuration/configuration.service.spec.ts added (mode: 100644) (index 0000000..2715a8f)
1 import { TestBed } from '@angular/core/testing';
2 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3
4 import { ConfigurationService, ConfigProps, Env, Bean, PropertySource } from 'app/admin/configuration/configuration.service';
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 describe('Service Tests', () => {
8 describe('Logs Service', () => {
9 let service: ConfigurationService;
10 let httpMock: HttpTestingController;
11 let expectedResult: Bean[] | PropertySource[] | null;
12
13 beforeEach(() => {
14 TestBed.configureTestingModule({
15 imports: [HttpClientTestingModule]
16 });
17
18 expectedResult = null;
19 service = TestBed.get(ConfigurationService);
20 httpMock = TestBed.get(HttpTestingController);
21 });
22
23 afterEach(() => {
24 httpMock.verify();
25 });
26
27 describe('Service methods', () => {
28 it('should call correct URL', () => {
29 service.getBeans().subscribe();
30
31 const req = httpMock.expectOne({ method: 'GET' });
32 const resourceUrl = SERVER_API_URL + 'management/configprops';
33 expect(req.request.url).toEqual(resourceUrl);
34 });
35
36 it('should get the config', () => {
37 const bean: Bean = {
38 prefix: 'jhipster',
39 properties: {
40 clientApp: {
41 name: 'jhipsterApp'
42 }
43 }
44 };
45 const configProps: ConfigProps = {
46 contexts: {
47 jhipster: {
48 beans: {
49 'io.github.jhipster.config.JHipsterProperties': bean
50 }
51 }
52 }
53 };
54 service.getBeans().subscribe(received => (expectedResult = received));
55
56 const req = httpMock.expectOne({ method: 'GET' });
57 req.flush(configProps);
58 expect(expectedResult).toEqual([bean]);
59 });
60
61 it('should get the env', () => {
62 const propertySources: PropertySource[] = [
63 {
64 name: 'server.ports',
65 properties: {
66 'local.server.port': {
67 value: '8080'
68 }
69 }
70 }
71 ];
72 const env: Env = { propertySources };
73 service.getPropertySources().subscribe(received => (expectedResult = received));
74
75 const req = httpMock.expectOne({ method: 'GET' });
76 req.flush(env);
77 expect(expectedResult).toEqual(propertySources);
78 });
79 });
80 });
81 });
File src/test/javascript/spec/app/admin/health/health.component.spec.ts added (mode: 100644) (index 0000000..2131dba)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { HttpErrorResponse } from '@angular/common/http';
3 import { of, throwError } from 'rxjs';
4
5 import { HonlapTestModule } from '../../../test.module';
6 import { HealthComponent } from 'app/admin/health/health.component';
7 import { HealthService, Health } from 'app/admin/health/health.service';
8
9 describe('Component Tests', () => {
10 describe('HealthComponent', () => {
11 let comp: HealthComponent;
12 let fixture: ComponentFixture<HealthComponent>;
13 let service: HealthService;
14
15 beforeEach(async(() => {
16 TestBed.configureTestingModule({
17 imports: [HonlapTestModule],
18 declarations: [HealthComponent]
19 })
20 .overrideTemplate(HealthComponent, '')
21 .compileComponents();
22 }));
23
24 beforeEach(() => {
25 fixture = TestBed.createComponent(HealthComponent);
26 comp = fixture.componentInstance;
27 service = fixture.debugElement.injector.get(HealthService);
28 });
29
30 describe('getBadgeClass', () => {
31 it('should get badge class', () => {
32 const upBadgeClass = comp.getBadgeClass('UP');
33 const downBadgeClass = comp.getBadgeClass('DOWN');
34 expect(upBadgeClass).toEqual('badge-success');
35 expect(downBadgeClass).toEqual('badge-danger');
36 });
37 });
38
39 describe('refresh', () => {
40 it('should call refresh on init', () => {
41 // GIVEN
42 const health: Health = { status: 'UP', components: { mail: { status: 'UP', details: 'mailDetails' } } };
43 spyOn(service, 'checkHealth').and.returnValue(of(health));
44
45 // WHEN
46 comp.ngOnInit();
47
48 // THEN
49 expect(service.checkHealth).toHaveBeenCalled();
50 expect(comp.health).toEqual(health);
51 });
52
53 it('should handle a 503 on refreshing health data', () => {
54 // GIVEN
55 const health: Health = { status: 'DOWN', components: { mail: { status: 'DOWN', details: 'mailDetails' } } };
56 spyOn(service, 'checkHealth').and.returnValue(throwError(new HttpErrorResponse({ status: 503, error: health })));
57
58 // WHEN
59 comp.refresh();
60
61 // THEN
62 expect(service.checkHealth).toHaveBeenCalled();
63 expect(comp.health).toEqual(health);
64 });
65 });
66 });
67 });
File src/test/javascript/spec/app/admin/logs/logs.component.spec.ts added (mode: 100644) (index 0000000..ccb0ed7)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { of } from 'rxjs';
3
4 import { HonlapTestModule } from '../../../test.module';
5 import { LogsComponent } from 'app/admin/logs/logs.component';
6 import { LogsService } from 'app/admin/logs/logs.service';
7 import { Log } from 'app/admin/logs/log.model';
8
9 describe('Component Tests', () => {
10 describe('LogsComponent', () => {
11 let comp: LogsComponent;
12 let fixture: ComponentFixture<LogsComponent>;
13 let service: LogsService;
14
15 beforeEach(async(() => {
16 TestBed.configureTestingModule({
17 imports: [HonlapTestModule],
18 declarations: [LogsComponent],
19 providers: [LogsService]
20 })
21 .overrideTemplate(LogsComponent, '')
22 .compileComponents();
23 }));
24
25 beforeEach(() => {
26 fixture = TestBed.createComponent(LogsComponent);
27 comp = fixture.componentInstance;
28 service = fixture.debugElement.injector.get(LogsService);
29 });
30
31 describe('OnInit', () => {
32 it('should set all default values correctly', () => {
33 expect(comp.filter).toBe('');
34 expect(comp.orderProp).toBe('name');
35 expect(comp.reverse).toBe(false);
36 });
37
38 it('Should call load all on init', () => {
39 // GIVEN
40 const log = new Log('main', 'WARN');
41 spyOn(service, 'findAll').and.returnValue(
42 of({
43 loggers: {
44 main: {
45 effectiveLevel: 'WARN'
46 }
47 }
48 })
49 );
50
51 // WHEN
52 comp.ngOnInit();
53
54 // THEN
55 expect(service.findAll).toHaveBeenCalled();
56 expect(comp.loggers && comp.loggers[0]).toEqual(jasmine.objectContaining(log));
57 });
58 });
59
60 describe('change log level', () => {
61 it('should change log level correctly', () => {
62 // GIVEN
63 const log = new Log('main', 'ERROR');
64 spyOn(service, 'changeLevel').and.returnValue(of({}));
65 spyOn(service, 'findAll').and.returnValue(
66 of({
67 loggers: {
68 main: {
69 effectiveLevel: 'ERROR'
70 }
71 }
72 })
73 );
74
75 // WHEN
76 comp.changeLevel('main', 'ERROR');
77
78 // THEN
79 expect(service.changeLevel).toHaveBeenCalled();
80 expect(service.findAll).toHaveBeenCalled();
81 expect(comp.loggers && comp.loggers[0]).toEqual(jasmine.objectContaining(log));
82 });
83 });
84 });
85 });
File src/test/javascript/spec/app/admin/logs/logs.service.spec.ts added (mode: 100644) (index 0000000..bccec0d)
1 import { TestBed } from '@angular/core/testing';
2 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3
4 import { LogsService } from 'app/admin/logs/logs.service';
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 describe('Service Tests', () => {
8 describe('Logs Service', () => {
9 let service: LogsService;
10 let httpMock: HttpTestingController;
11
12 beforeEach(() => {
13 TestBed.configureTestingModule({
14 imports: [HttpClientTestingModule]
15 });
16
17 service = TestBed.get(LogsService);
18 httpMock = TestBed.get(HttpTestingController);
19 });
20
21 afterEach(() => {
22 httpMock.verify();
23 });
24
25 describe('Service methods', () => {
26 it('should call correct URL', () => {
27 service.findAll().subscribe();
28
29 const req = httpMock.expectOne({ method: 'GET' });
30 const resourceUrl = SERVER_API_URL + 'management/loggers';
31 expect(req.request.url).toEqual(resourceUrl);
32 });
33
34 it('should change log level', () => {
35 service.changeLevel('main', 'ERROR').subscribe();
36
37 const req = httpMock.expectOne({ method: 'POST' });
38 const resourceUrl = SERVER_API_URL + 'management/loggers/main';
39 expect(req.request.url).toEqual(resourceUrl);
40 expect(req.request.body).toEqual({ configuredLevel: 'ERROR' });
41 });
42 });
43 });
44 });
File src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts added (mode: 100644) (index 0000000..c17b8f7)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { of } from 'rxjs';
3
4 import { HonlapTestModule } from '../../../test.module';
5 import { MetricsComponent } from 'app/admin/metrics/metrics.component';
6 import { MetricsService } from 'app/admin/metrics/metrics.service';
7
8 describe('Component Tests', () => {
9 describe('MetricsComponent', () => {
10 let comp: MetricsComponent;
11 let fixture: ComponentFixture<MetricsComponent>;
12 let service: MetricsService;
13
14 beforeEach(async(() => {
15 TestBed.configureTestingModule({
16 imports: [HonlapTestModule],
17 declarations: [MetricsComponent]
18 })
19 .overrideTemplate(MetricsComponent, '')
20 .compileComponents();
21 }));
22
23 beforeEach(() => {
24 fixture = TestBed.createComponent(MetricsComponent);
25 comp = fixture.componentInstance;
26 service = fixture.debugElement.injector.get(MetricsService);
27 });
28
29 describe('refresh', () => {
30 it('should call refresh on init', () => {
31 // GIVEN
32 const response = {
33 timers: {
34 service: 'test',
35 unrelatedKey: 'test'
36 },
37 gauges: {
38 'jcache.statistics': {
39 value: 2
40 },
41 unrelatedKey: 'test'
42 }
43 };
44 spyOn(service, 'getMetrics').and.returnValue(of(response));
45
46 // WHEN
47 comp.ngOnInit();
48
49 // THEN
50 expect(service.getMetrics).toHaveBeenCalled();
51 });
52 });
53 });
54 });
File src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts added (mode: 100644) (index 0000000..c86b4af)
1 import { TestBed } from '@angular/core/testing';
2 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3
4 import { MetricsService, Metrics, ThreadDump } from 'app/admin/metrics/metrics.service';
5 import { SERVER_API_URL } from 'app/app.constants';
6
7 describe('Service Tests', () => {
8 describe('Logs Service', () => {
9 let service: MetricsService;
10 let httpMock: HttpTestingController;
11
12 beforeEach(() => {
13 TestBed.configureTestingModule({
14 imports: [HttpClientTestingModule]
15 });
16 service = TestBed.get(MetricsService);
17 httpMock = TestBed.get(HttpTestingController);
18 });
19
20 afterEach(() => {
21 httpMock.verify();
22 });
23
24 describe('Service methods', () => {
25 it('should call correct URL', () => {
26 service.getMetrics().subscribe();
27
28 const req = httpMock.expectOne({ method: 'GET' });
29 const resourceUrl = SERVER_API_URL + 'management/jhimetrics';
30 expect(req.request.url).toEqual(resourceUrl);
31 });
32
33 it('should return Metrics', () => {
34 let expectedResult: Metrics | null = null;
35 const metrics: Metrics = {
36 jvm: {},
37 'http.server.requests': {},
38 cache: {},
39 services: {},
40 databases: {},
41 garbageCollector: {},
42 processMetrics: {}
43 };
44
45 service.getMetrics().subscribe(received => {
46 expectedResult = received;
47 });
48
49 const req = httpMock.expectOne({ method: 'GET' });
50 req.flush(metrics);
51 expect(expectedResult).toEqual(metrics);
52 });
53
54 it('should return Thread Dump', () => {
55 let expectedResult: ThreadDump | null = null;
56 const dump: ThreadDump = { threads: [{ name: 'test1', threadState: 'RUNNABLE' }] };
57
58 service.threadDump().subscribe(received => {
59 expectedResult = received;
60 });
61
62 const req = httpMock.expectOne({ method: 'GET' });
63 req.flush(dump);
64 expect(expectedResult).toEqual(dump);
65 });
66 });
67 });
68 });
File src/test/javascript/spec/app/admin/user-management/user-management-delete-dialog.component.spec.ts added (mode: 100644) (index 0000000..1f04e99)
1 import { ComponentFixture, TestBed, async, inject, fakeAsync, tick } from '@angular/core/testing';
2 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3 import { of } from 'rxjs';
4 import { JhiEventManager } from 'ng-jhipster';
5
6 import { HonlapTestModule } from '../../../test.module';
7 import { MockEventManager } from '../../../helpers/mock-event-manager.service';
8 import { MockActiveModal } from '../../../helpers/mock-active-modal.service';
9 import { UserManagementDeleteDialogComponent } from 'app/admin/user-management/user-management-delete-dialog.component';
10 import { UserService } from 'app/core/user/user.service';
11
12 describe('Component Tests', () => {
13 describe('User Management Delete Component', () => {
14 let comp: UserManagementDeleteDialogComponent;
15 let fixture: ComponentFixture<UserManagementDeleteDialogComponent>;
16 let service: UserService;
17 let mockEventManager: MockEventManager;
18 let mockActiveModal: MockActiveModal;
19
20 beforeEach(async(() => {
21 TestBed.configureTestingModule({
22 imports: [HonlapTestModule],
23 declarations: [UserManagementDeleteDialogComponent]
24 })
25 .overrideTemplate(UserManagementDeleteDialogComponent, '')
26 .compileComponents();
27 }));
28
29 beforeEach(() => {
30 fixture = TestBed.createComponent(UserManagementDeleteDialogComponent);
31 comp = fixture.componentInstance;
32 service = fixture.debugElement.injector.get(UserService);
33 mockEventManager = TestBed.get(JhiEventManager);
34 mockActiveModal = TestBed.get(NgbActiveModal);
35 });
36
37 describe('confirmDelete', () => {
38 it('Should call delete service on confirmDelete', inject(
39 [],
40 fakeAsync(() => {
41 // GIVEN
42 spyOn(service, 'delete').and.returnValue(of({}));
43
44 // WHEN
45 comp.confirmDelete('user');
46 tick();
47
48 // THEN
49 expect(service.delete).toHaveBeenCalledWith('user');
50 expect(mockActiveModal.closeSpy).toHaveBeenCalled();
51 expect(mockEventManager.broadcastSpy).toHaveBeenCalled();
52 })
53 ));
54 });
55 });
56 });
File src/test/javascript/spec/app/admin/user-management/user-management-detail.component.spec.ts added (mode: 100644) (index 0000000..55b3a53)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { ActivatedRoute } from '@angular/router';
3 import { of } from 'rxjs';
4
5 import { Authority } from 'app/shared/constants/authority.constants';
6 import { HonlapTestModule } from '../../../test.module';
7 import { UserManagementDetailComponent } from 'app/admin/user-management/user-management-detail.component';
8 import { User } from 'app/core/user/user.model';
9
10 describe('Component Tests', () => {
11 describe('User Management Detail Component', () => {
12 let comp: UserManagementDetailComponent;
13 let fixture: ComponentFixture<UserManagementDetailComponent>;
14 const route: ActivatedRoute = ({
15 data: of({ user: new User(1, 'user', 'first', 'last', 'first@last.com', true, 'en', [Authority.USER], 'admin') })
16 } as any) as ActivatedRoute;
17
18 beforeEach(async(() => {
19 TestBed.configureTestingModule({
20 imports: [HonlapTestModule],
21 declarations: [UserManagementDetailComponent],
22 providers: [
23 {
24 provide: ActivatedRoute,
25 useValue: route
26 }
27 ]
28 })
29 .overrideTemplate(UserManagementDetailComponent, '')
30 .compileComponents();
31 }));
32
33 beforeEach(() => {
34 fixture = TestBed.createComponent(UserManagementDetailComponent);
35 comp = fixture.componentInstance;
36 });
37
38 describe('OnInit', () => {
39 it('Should call load all on init', () => {
40 // GIVEN
41
42 // WHEN
43 comp.ngOnInit();
44
45 // THEN
46 expect(comp.user).toEqual(
47 jasmine.objectContaining({
48 id: 1,
49 login: 'user',
50 firstName: 'first',
51 lastName: 'last',
52 email: 'first@last.com',
53 activated: true,
54 langKey: 'en',
55 authorities: [Authority.USER],
56 createdBy: 'admin'
57 })
58 );
59 });
60 });
61 });
62 });
File src/test/javascript/spec/app/admin/user-management/user-management-update.component.spec.ts added (mode: 100644) (index 0000000..84520c1)
1 import { ComponentFixture, TestBed, async, inject, fakeAsync, tick } from '@angular/core/testing';
2 import { HttpResponse } from '@angular/common/http';
3 import { FormBuilder } from '@angular/forms';
4 import { ActivatedRoute } from '@angular/router';
5 import { of } from 'rxjs';
6
7 import { Authority } from 'app/shared/constants/authority.constants';
8 import { HonlapTestModule } from '../../../test.module';
9 import { UserManagementUpdateComponent } from 'app/admin/user-management/user-management-update.component';
10 import { UserService } from 'app/core/user/user.service';
11 import { User } from 'app/core/user/user.model';
12
13 describe('Component Tests', () => {
14 describe('User Management Update Component', () => {
15 let comp: UserManagementUpdateComponent;
16 let fixture: ComponentFixture<UserManagementUpdateComponent>;
17 let service: UserService;
18 const route: ActivatedRoute = ({
19 data: of({ user: new User(1, 'user', 'first', 'last', 'first@last.com', true, 'en', [Authority.USER], 'admin') })
20 } as any) as ActivatedRoute;
21
22 beforeEach(async(() => {
23 TestBed.configureTestingModule({
24 imports: [HonlapTestModule],
25 declarations: [UserManagementUpdateComponent],
26 providers: [
27 FormBuilder,
28 {
29 provide: ActivatedRoute,
30 useValue: route
31 }
32 ]
33 })
34 .overrideTemplate(UserManagementUpdateComponent, '')
35 .compileComponents();
36 }));
37
38 beforeEach(() => {
39 fixture = TestBed.createComponent(UserManagementUpdateComponent);
40 comp = fixture.componentInstance;
41 service = fixture.debugElement.injector.get(UserService);
42 });
43
44 describe('OnInit', () => {
45 it('Should load authorities and language on init', inject(
46 [],
47 fakeAsync(() => {
48 // GIVEN
49 spyOn(service, 'authorities').and.returnValue(of(['USER']));
50
51 // WHEN
52 comp.ngOnInit();
53
54 // THEN
55 expect(service.authorities).toHaveBeenCalled();
56 expect(comp.authorities).toEqual(['USER']);
57 })
58 ));
59 });
60
61 describe('save', () => {
62 it('Should call update service on save for existing user', inject(
63 [],
64 fakeAsync(() => {
65 // GIVEN
66 const entity = new User(123);
67 spyOn(service, 'update').and.returnValue(
68 of(
69 new HttpResponse({
70 body: entity
71 })
72 )
73 );
74 comp.user = entity;
75 comp.editForm.patchValue({ id: entity.id });
76 // WHEN
77 comp.save();
78 tick(); // simulate async
79
80 // THEN
81 expect(service.update).toHaveBeenCalledWith(entity);
82 expect(comp.isSaving).toEqual(false);
83 })
84 ));
85
86 it('Should call create service on save for new user', inject(
87 [],
88 fakeAsync(() => {
89 // GIVEN
90 const entity = new User();
91 spyOn(service, 'create').and.returnValue(of(new HttpResponse({ body: entity })));
92 comp.user = entity;
93 // WHEN
94 comp.save();
95 tick(); // simulate async
96
97 // THEN
98 expect(service.create).toHaveBeenCalledWith(entity);
99 expect(comp.isSaving).toEqual(false);
100 })
101 ));
102 });
103 });
104 });
File src/test/javascript/spec/app/admin/user-management/user-management.component.spec.ts added (mode: 100644) (index 0000000..76eb140)
1 import { ComponentFixture, TestBed, async, inject, fakeAsync, tick } from '@angular/core/testing';
2 import { HttpHeaders, HttpResponse } from '@angular/common/http';
3 import { of } from 'rxjs';
4
5 import { HonlapTestModule } from '../../../test.module';
6 import { UserManagementComponent } from 'app/admin/user-management/user-management.component';
7 import { UserService } from 'app/core/user/user.service';
8 import { User } from 'app/core/user/user.model';
9
10 describe('Component Tests', () => {
11 describe('User Management Component', () => {
12 let comp: UserManagementComponent;
13 let fixture: ComponentFixture<UserManagementComponent>;
14 let service: UserService;
15
16 beforeEach(async(() => {
17 TestBed.configureTestingModule({
18 imports: [HonlapTestModule],
19 declarations: [UserManagementComponent]
20 })
21 .overrideTemplate(UserManagementComponent, '')
22 .compileComponents();
23 }));
24
25 beforeEach(() => {
26 fixture = TestBed.createComponent(UserManagementComponent);
27 comp = fixture.componentInstance;
28 service = fixture.debugElement.injector.get(UserService);
29 });
30
31 describe('OnInit', () => {
32 it('Should call load all on init', inject(
33 [],
34 fakeAsync(() => {
35 // GIVEN
36 const headers = new HttpHeaders().append('link', 'link;link');
37 spyOn(service, 'query').and.returnValue(
38 of(
39 new HttpResponse({
40 body: [new User(123)],
41 headers
42 })
43 )
44 );
45
46 // WHEN
47 comp.ngOnInit();
48 tick(); // simulate async
49
50 // THEN
51 expect(service.query).toHaveBeenCalled();
52 expect(comp.users && comp.users[0]).toEqual(jasmine.objectContaining({ id: 123 }));
53 })
54 ));
55 });
56
57 describe('setActive', () => {
58 it('Should update user and call load all', inject(
59 [],
60 fakeAsync(() => {
61 // GIVEN
62 const headers = new HttpHeaders().append('link', 'link;link');
63 const user = new User(123);
64 spyOn(service, 'query').and.returnValue(
65 of(
66 new HttpResponse({
67 body: [user],
68 headers
69 })
70 )
71 );
72 spyOn(service, 'update').and.returnValue(of(new HttpResponse({ status: 200 })));
73
74 // WHEN
75 comp.setActive(user, true);
76 tick(); // simulate async
77
78 // THEN
79 expect(service.update).toHaveBeenCalledWith({ ...user, activated: true });
80 expect(service.query).toHaveBeenCalled();
81 expect(comp.users && comp.users[0]).toEqual(jasmine.objectContaining({ id: 123 }));
82 })
83 ));
84 });
85 });
86 });
File src/test/javascript/spec/app/core/user/account.service.spec.ts added (mode: 100644) (index 0000000..f5e1167)
1 import { Router } from '@angular/router';
2 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3 import { TestBed } from '@angular/core/testing';
4 import { JhiDateUtils, JhiLanguageService } from 'ng-jhipster';
5 import { NgxWebstorageModule } from 'ngx-webstorage';
6
7 import { SERVER_API_URL } from 'app/app.constants';
8 import { AccountService } from 'app/core/auth/account.service';
9 import { Account } from 'app/core/user/account.model';
10 import { Authority } from 'app/shared/constants/authority.constants';
11 import { StateStorageService } from 'app/core/auth/state-storage.service';
12 import { MockLanguageService } from '../../../helpers/mock-language.service';
13 import { MockRouter } from '../../../helpers/mock-route.service';
14 import { MockStateStorageService } from '../../../helpers/mock-state-storage.service';
15
16 function accountWithAuthorities(authorities: string[]): Account {
17 return {
18 activated: true,
19 authorities,
20 email: '',
21 firstName: '',
22 langKey: '',
23 lastName: '',
24 login: '',
25 imageUrl: ''
26 };
27 }
28
29 describe('Service Tests', () => {
30 describe('Account Service', () => {
31 let service: AccountService;
32 let httpMock: HttpTestingController;
33 let storageService: MockStateStorageService;
34 let router: MockRouter;
35
36 beforeEach(() => {
37 TestBed.configureTestingModule({
38 imports: [HttpClientTestingModule, NgxWebstorageModule.forRoot()],
39 providers: [
40 JhiDateUtils,
41 {
42 provide: JhiLanguageService,
43 useClass: MockLanguageService
44 },
45 {
46 provide: StateStorageService,
47 useClass: MockStateStorageService
48 },
49 {
50 provide: Router,
51 useClass: MockRouter
52 }
53 ]
54 });
55
56 service = TestBed.get(AccountService);
57 httpMock = TestBed.get(HttpTestingController);
58 storageService = TestBed.get(StateStorageService);
59 router = TestBed.get(Router);
60 });
61
62 afterEach(() => {
63 httpMock.verify();
64 });
65
66 describe('authenticate', () => {
67 it('authenticationState should emit null if input is null', () => {
68 // GIVEN
69 let userIdentity: Account | null = accountWithAuthorities([]);
70 service.getAuthenticationState().subscribe(account => (userIdentity = account));
71
72 // WHEN
73 service.authenticate(null);
74
75 // THEN
76 expect(userIdentity).toBeNull();
77 expect(service.isAuthenticated()).toBe(false);
78 });
79
80 it('authenticationState should emit the same account as was in input parameter', () => {
81 // GIVEN
82 const expectedResult = accountWithAuthorities([]);
83 let userIdentity: Account | null = null;
84 service.getAuthenticationState().subscribe(account => (userIdentity = account));
85
86 // WHEN
87 service.authenticate(expectedResult);
88
89 // THEN
90 expect(userIdentity).toEqual(expectedResult);
91 expect(service.isAuthenticated()).toBe(true);
92 });
93 });
94
95 describe('identity', () => {
96 it('should call /account if user is undefined', () => {
97 service.identity().subscribe();
98 const req = httpMock.expectOne({ method: 'GET' });
99 const resourceUrl = SERVER_API_URL + 'api/account';
100
101 expect(req.request.url).toEqual(`${resourceUrl}`);
102 });
103
104 it('should call /account only once if not logged out after first authentication and should call /account again if user has logged out', () => {
105 // Given the user is authenticated
106 service.identity().subscribe();
107 httpMock.expectOne({ method: 'GET' }).flush({});
108
109 // When I call
110 service.identity().subscribe();
111
112 // Then there is no second request
113 httpMock.expectNone({ method: 'GET' });
114
115 // When I log out
116 service.authenticate(null);
117 // and then call
118 service.identity().subscribe();
119
120 // Then there is a new request
121 httpMock.expectOne({ method: 'GET' });
122 });
123
124 describe('navigateToStoredUrl', () => {
125 it('should navigate to the previous stored url post successful authentication', () => {
126 // GIVEN
127 storageService.setResponse('admin/users?page=0');
128
129 // WHEN
130 service.identity().subscribe();
131 httpMock.expectOne({ method: 'GET' }).flush({});
132
133 // THEN
134 expect(storageService.getUrlSpy).toHaveBeenCalledTimes(1);
135 expect(storageService.clearUrlSpy).toHaveBeenCalledTimes(1);
136 expect(router.navigateByUrlSpy).toHaveBeenCalledWith('admin/users?page=0');
137 });
138
139 it('should not navigate to the previous stored url when authentication fails', () => {
140 // WHEN
141 service.identity().subscribe();
142 httpMock.expectOne({ method: 'GET' }).error(new ErrorEvent(''));
143
144 // THEN
145 expect(storageService.getUrlSpy).not.toHaveBeenCalled();
146 expect(storageService.clearUrlSpy).not.toHaveBeenCalled();
147 expect(router.navigateByUrlSpy).not.toHaveBeenCalled();
148 });
149
150 it('should not navigate to the previous stored url when no such url exists post successful authentication', () => {
151 // GIVEN
152 storageService.setResponse(null);
153
154 // WHEN
155 service.identity().subscribe();
156 httpMock.expectOne({ method: 'GET' }).flush({});
157
158 // THEN
159 expect(storageService.getUrlSpy).toHaveBeenCalledTimes(1);
160 expect(storageService.clearUrlSpy).not.toHaveBeenCalled();
161 expect(router.navigateByUrlSpy).not.toHaveBeenCalled();
162 });
163 });
164 });
165
166 describe('hasAnyAuthority', () => {
167 describe('hasAnyAuthority string parameter', () => {
168 it('should return false if user is not logged', () => {
169 const hasAuthority = service.hasAnyAuthority(Authority.USER);
170 expect(hasAuthority).toBe(false);
171 });
172
173 it('should return false if user is logged and has not authority', () => {
174 service.authenticate(accountWithAuthorities([Authority.USER]));
175
176 const hasAuthority = service.hasAnyAuthority(Authority.ADMIN);
177
178 expect(hasAuthority).toBe(false);
179 });
180
181 it('should return true if user is logged and has authority', () => {
182 service.authenticate(accountWithAuthorities([Authority.USER]));
183
184 const hasAuthority = service.hasAnyAuthority(Authority.USER);
185
186 expect(hasAuthority).toBe(true);
187 });
188 });
189
190 describe('hasAnyAuthority array parameter', () => {
191 it('should return false if user is not logged', () => {
192 const hasAuthority = service.hasAnyAuthority([Authority.USER]);
193 expect(hasAuthority).toBeFalsy();
194 });
195
196 it('should return false if user is logged and has not authority', () => {
197 service.authenticate(accountWithAuthorities([Authority.USER]));
198
199 const hasAuthority = service.hasAnyAuthority([Authority.ADMIN]);
200
201 expect(hasAuthority).toBe(false);
202 });
203
204 it('should return true if user is logged and has authority', () => {
205 service.authenticate(accountWithAuthorities([Authority.USER]));
206
207 const hasAuthority = service.hasAnyAuthority([Authority.USER, Authority.ADMIN]);
208
209 expect(hasAuthority).toBe(true);
210 });
211 });
212 });
213 });
214 });
File src/test/javascript/spec/app/core/user/user.service.spec.ts added (mode: 100644) (index 0000000..2811acb)
1 import { TestBed } from '@angular/core/testing';
2 import { HttpErrorResponse } from '@angular/common/http';
3 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
4 import { JhiDateUtils } from 'ng-jhipster';
5
6 import { Authority } from 'app/shared/constants/authority.constants';
7 import { UserService } from 'app/core/user/user.service';
8 import { User } from 'app/core/user/user.model';
9 import { SERVER_API_URL } from 'app/app.constants';
10
11 describe('Service Tests', () => {
12 describe('User Service', () => {
13 let service: UserService;
14 let httpMock: HttpTestingController;
15
16 beforeEach(() => {
17 TestBed.configureTestingModule({
18 imports: [HttpClientTestingModule],
19 providers: [JhiDateUtils]
20 });
21
22 service = TestBed.get(UserService);
23 httpMock = TestBed.get(HttpTestingController);
24 });
25
26 afterEach(() => {
27 httpMock.verify();
28 });
29
30 describe('Service methods', () => {
31 it('should call correct URL', () => {
32 service.find('user').subscribe();
33
34 const req = httpMock.expectOne({ method: 'GET' });
35 const resourceUrl = SERVER_API_URL + 'api/users';
36 expect(req.request.url).toEqual(`${resourceUrl}/user`);
37 });
38
39 it('should return User', () => {
40 let expectedResult: string | undefined;
41
42 service.find('user').subscribe(received => {
43 expectedResult = received.login;
44 });
45
46 const req = httpMock.expectOne({ method: 'GET' });
47 req.flush(new User(1, 'user'));
48 expect(expectedResult).toEqual('user');
49 });
50
51 it('should return Authorities', () => {
52 let expectedResult: string[] = [];
53
54 service.authorities().subscribe(authorities => {
55 expectedResult = authorities;
56 });
57 const req = httpMock.expectOne({ method: 'GET' });
58
59 req.flush([Authority.USER, Authority.ADMIN]);
60 expect(expectedResult).toEqual([Authority.USER, Authority.ADMIN]);
61 });
62
63 it('should propagate not found response', () => {
64 let expectedResult = 0;
65
66 service.find('user').subscribe(null, (error: HttpErrorResponse) => {
67 expectedResult = error.status;
68 });
69
70 const req = httpMock.expectOne({ method: 'GET' });
71 req.flush('Invalid request parameters', {
72 status: 404,
73 statusText: 'Bad Request'
74 });
75 expect(expectedResult).toEqual(404);
76 });
77 });
78 });
79 });
File src/test/javascript/spec/app/entities/piece-of-news/piece-of-news-delete-dialog.component.spec.ts added (mode: 100644) (index 0000000..63a0850)
1 import { ComponentFixture, TestBed, inject, fakeAsync, tick } from '@angular/core/testing';
2 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3 import { of } from 'rxjs';
4 import { JhiEventManager } from 'ng-jhipster';
5
6 import { HonlapTestModule } from '../../../test.module';
7 import { MockEventManager } from '../../../helpers/mock-event-manager.service';
8 import { MockActiveModal } from '../../../helpers/mock-active-modal.service';
9 import { PieceOfNewsDeleteDialogComponent } from 'app/entities/piece-of-news/piece-of-news-delete-dialog.component';
10 import { PieceOfNewsService } from 'app/entities/piece-of-news/piece-of-news.service';
11
12 describe('Component Tests', () => {
13 describe('PieceOfNews Management Delete Component', () => {
14 let comp: PieceOfNewsDeleteDialogComponent;
15 let fixture: ComponentFixture<PieceOfNewsDeleteDialogComponent>;
16 let service: PieceOfNewsService;
17 let mockEventManager: MockEventManager;
18 let mockActiveModal: MockActiveModal;
19
20 beforeEach(() => {
21 TestBed.configureTestingModule({
22 imports: [HonlapTestModule],
23 declarations: [PieceOfNewsDeleteDialogComponent]
24 })
25 .overrideTemplate(PieceOfNewsDeleteDialogComponent, '')
26 .compileComponents();
27 fixture = TestBed.createComponent(PieceOfNewsDeleteDialogComponent);
28 comp = fixture.componentInstance;
29 service = fixture.debugElement.injector.get(PieceOfNewsService);
30 mockEventManager = TestBed.get(JhiEventManager);
31 mockActiveModal = TestBed.get(NgbActiveModal);
32 });
33
34 describe('confirmDelete', () => {
35 it('Should call delete service on confirmDelete', inject(
36 [],
37 fakeAsync(() => {
38 // GIVEN
39 spyOn(service, 'delete').and.returnValue(of({}));
40
41 // WHEN
42 comp.confirmDelete(123);
43 tick();
44
45 // THEN
46 expect(service.delete).toHaveBeenCalledWith(123);
47 expect(mockActiveModal.closeSpy).toHaveBeenCalled();
48 expect(mockEventManager.broadcastSpy).toHaveBeenCalled();
49 })
50 ));
51
52 it('Should not call delete service on clear', () => {
53 // GIVEN
54 spyOn(service, 'delete');
55
56 // WHEN
57 comp.cancel();
58
59 // THEN
60 expect(service.delete).not.toHaveBeenCalled();
61 expect(mockActiveModal.dismissSpy).toHaveBeenCalled();
62 });
63 });
64 });
65 });
File src/test/javascript/spec/app/entities/piece-of-news/piece-of-news-detail.component.spec.ts added (mode: 100644) (index 0000000..c123358)
1 import { ComponentFixture, TestBed } from '@angular/core/testing';
2 import { ActivatedRoute } from '@angular/router';
3 import { of } from 'rxjs';
4
5 import { HonlapTestModule } from '../../../test.module';
6 import { PieceOfNewsDetailComponent } from 'app/entities/piece-of-news/piece-of-news-detail.component';
7 import { PieceOfNews } from 'app/shared/model/piece-of-news.model';
8
9 describe('Component Tests', () => {
10 describe('PieceOfNews Management Detail Component', () => {
11 let comp: PieceOfNewsDetailComponent;
12 let fixture: ComponentFixture<PieceOfNewsDetailComponent>;
13 const route = ({ data: of({ pieceOfNews: new PieceOfNews(123) }) } as any) as ActivatedRoute;
14
15 beforeEach(() => {
16 TestBed.configureTestingModule({
17 imports: [HonlapTestModule],
18 declarations: [PieceOfNewsDetailComponent],
19 providers: [{ provide: ActivatedRoute, useValue: route }]
20 })
21 .overrideTemplate(PieceOfNewsDetailComponent, '')
22 .compileComponents();
23 fixture = TestBed.createComponent(PieceOfNewsDetailComponent);
24 comp = fixture.componentInstance;
25 });
26
27 describe('OnInit', () => {
28 it('Should load pieceOfNews on init', () => {
29 // WHEN
30 comp.ngOnInit();
31
32 // THEN
33 expect(comp.pieceOfNews).toEqual(jasmine.objectContaining({ id: 123 }));
34 });
35 });
36 });
37 });
File src/test/javascript/spec/app/entities/piece-of-news/piece-of-news-update.component.spec.ts added (mode: 100644) (index 0000000..997fc7a)
1 import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
2 import { HttpResponse } from '@angular/common/http';
3 import { FormBuilder } from '@angular/forms';
4 import { of } from 'rxjs';
5
6 import { HonlapTestModule } from '../../../test.module';
7 import { PieceOfNewsUpdateComponent } from 'app/entities/piece-of-news/piece-of-news-update.component';
8 import { PieceOfNewsService } from 'app/entities/piece-of-news/piece-of-news.service';
9 import { PieceOfNews } from 'app/shared/model/piece-of-news.model';
10
11 describe('Component Tests', () => {
12 describe('PieceOfNews Management Update Component', () => {
13 let comp: PieceOfNewsUpdateComponent;
14 let fixture: ComponentFixture<PieceOfNewsUpdateComponent>;
15 let service: PieceOfNewsService;
16
17 beforeEach(() => {
18 TestBed.configureTestingModule({
19 imports: [HonlapTestModule],
20 declarations: [PieceOfNewsUpdateComponent],
21 providers: [FormBuilder]
22 })
23 .overrideTemplate(PieceOfNewsUpdateComponent, '')
24 .compileComponents();
25
26 fixture = TestBed.createComponent(PieceOfNewsUpdateComponent);
27 comp = fixture.componentInstance;
28 service = fixture.debugElement.injector.get(PieceOfNewsService);
29 });
30
31 describe('save', () => {
32 it('Should call update service on save for existing entity', fakeAsync(() => {
33 // GIVEN
34 const entity = new PieceOfNews(123);
35 spyOn(service, 'update').and.returnValue(of(new HttpResponse({ body: entity })));
36 comp.updateForm(entity);
37 // WHEN
38 comp.save();
39 tick(); // simulate async
40
41 // THEN
42 expect(service.update).toHaveBeenCalledWith(entity);
43 expect(comp.isSaving).toEqual(false);
44 }));
45
46 it('Should call create service on save for new entity', fakeAsync(() => {
47 // GIVEN
48 const entity = new PieceOfNews();
49 spyOn(service, 'create').and.returnValue(of(new HttpResponse({ body: entity })));
50 comp.updateForm(entity);
51 // WHEN
52 comp.save();
53 tick(); // simulate async
54
55 // THEN
56 expect(service.create).toHaveBeenCalledWith(entity);
57 expect(comp.isSaving).toEqual(false);
58 }));
59 });
60 });
61 });
File src/test/javascript/spec/app/entities/piece-of-news/piece-of-news.component.spec.ts added (mode: 100644) (index 0000000..f33ba9c)
1 import { ComponentFixture, TestBed } from '@angular/core/testing';
2 import { of } from 'rxjs';
3 import { HttpHeaders, HttpResponse } from '@angular/common/http';
4 import { ActivatedRoute, Data } from '@angular/router';
5
6 import { HonlapTestModule } from '../../../test.module';
7 import { PieceOfNewsComponent } from 'app/entities/piece-of-news/piece-of-news.component';
8 import { PieceOfNewsService } from 'app/entities/piece-of-news/piece-of-news.service';
9 import { PieceOfNews } from 'app/shared/model/piece-of-news.model';
10
11 describe('Component Tests', () => {
12 describe('PieceOfNews Management Component', () => {
13 let comp: PieceOfNewsComponent;
14 let fixture: ComponentFixture<PieceOfNewsComponent>;
15 let service: PieceOfNewsService;
16
17 beforeEach(() => {
18 TestBed.configureTestingModule({
19 imports: [HonlapTestModule],
20 declarations: [PieceOfNewsComponent],
21 providers: [
22 {
23 provide: ActivatedRoute,
24 useValue: {
25 data: {
26 subscribe: (fn: (value: Data) => void) =>
27 fn({
28 pagingParams: {
29 predicate: 'id',
30 reverse: false,
31 page: 0
32 }
33 })
34 }
35 }
36 }
37 ]
38 })
39 .overrideTemplate(PieceOfNewsComponent, '')
40 .compileComponents();
41
42 fixture = TestBed.createComponent(PieceOfNewsComponent);
43 comp = fixture.componentInstance;
44 service = fixture.debugElement.injector.get(PieceOfNewsService);
45 });
46
47 it('Should call load all on init', () => {
48 // GIVEN
49 const headers = new HttpHeaders().append('link', 'link;link');
50 spyOn(service, 'query').and.returnValue(
51 of(
52 new HttpResponse({
53 body: [new PieceOfNews(123)],
54 headers
55 })
56 )
57 );
58
59 // WHEN
60 comp.ngOnInit();
61
62 // THEN
63 expect(service.query).toHaveBeenCalled();
64 expect(comp.pieceOfNews && comp.pieceOfNews[0]).toEqual(jasmine.objectContaining({ id: 123 }));
65 });
66
67 it('should load a page', () => {
68 // GIVEN
69 const headers = new HttpHeaders().append('link', 'link;link');
70 spyOn(service, 'query').and.returnValue(
71 of(
72 new HttpResponse({
73 body: [new PieceOfNews(123)],
74 headers
75 })
76 )
77 );
78
79 // WHEN
80 comp.loadPage(1);
81
82 // THEN
83 expect(service.query).toHaveBeenCalled();
84 expect(comp.pieceOfNews && comp.pieceOfNews[0]).toEqual(jasmine.objectContaining({ id: 123 }));
85 });
86
87 it('should calculate the sort attribute for an id', () => {
88 // WHEN
89 comp.ngOnInit();
90 const result = comp.sort();
91
92 // THEN
93 expect(result).toEqual(['id,desc']);
94 });
95
96 it('should calculate the sort attribute for a non-id attribute', () => {
97 // INIT
98 comp.ngOnInit();
99
100 // GIVEN
101 comp.predicate = 'name';
102
103 // WHEN
104 const result = comp.sort();
105
106 // THEN
107 expect(result).toEqual(['name,desc', 'id']);
108 });
109 });
110 });
File src/test/javascript/spec/app/entities/piece-of-news/piece-of-news.service.spec.ts added (mode: 100644) (index 0000000..544d208)
1 import { TestBed, getTestBed } from '@angular/core/testing';
2 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
3 import * as moment from 'moment';
4 import { DATE_TIME_FORMAT } from 'app/shared/constants/input.constants';
5 import { PieceOfNewsService } from 'app/entities/piece-of-news/piece-of-news.service';
6 import { IPieceOfNews, PieceOfNews } from 'app/shared/model/piece-of-news.model';
7
8 describe('Service Tests', () => {
9 describe('PieceOfNews Service', () => {
10 let injector: TestBed;
11 let service: PieceOfNewsService;
12 let httpMock: HttpTestingController;
13 let elemDefault: IPieceOfNews;
14 let expectedResult: IPieceOfNews | IPieceOfNews[] | boolean | null;
15 let currentDate: moment.Moment;
16
17 beforeEach(() => {
18 TestBed.configureTestingModule({
19 imports: [HttpClientTestingModule]
20 });
21 expectedResult = null;
22 injector = getTestBed();
23 service = injector.get(PieceOfNewsService);
24 httpMock = injector.get(HttpTestingController);
25 currentDate = moment();
26
27 elemDefault = new PieceOfNews(
28 0,
29 0,
30 currentDate,
31 'AAAAAAA',
32 'AAAAAAA',
33 'AAAAAAA',
34 currentDate,
35 'AAAAAAA',
36 currentDate,
37 'AAAAAAA',
38 currentDate
39 );
40 });
41
42 describe('Service methods', () => {
43 it('should find an element', () => {
44 const returnedFromService = Object.assign(
45 {
46 newsDate: currentDate.format(DATE_TIME_FORMAT),
47 publishDate: currentDate.format(DATE_TIME_FORMAT),
48 createdDate: currentDate.format(DATE_TIME_FORMAT),
49 lastModifiedDate: currentDate.format(DATE_TIME_FORMAT)
50 },
51 elemDefault
52 );
53
54 service.find(123).subscribe(resp => (expectedResult = resp.body));
55
56 const req = httpMock.expectOne({ method: 'GET' });
57 req.flush(returnedFromService);
58 expect(expectedResult).toMatchObject(elemDefault);
59 });
60
61 it('should create a PieceOfNews', () => {
62 const returnedFromService = Object.assign(
63 {
64 id: 0,
65 newsDate: currentDate.format(DATE_TIME_FORMAT),
66 publishDate: currentDate.format(DATE_TIME_FORMAT),
67 createdDate: currentDate.format(DATE_TIME_FORMAT),
68 lastModifiedDate: currentDate.format(DATE_TIME_FORMAT)
69 },
70 elemDefault
71 );
72
73 const expected = Object.assign(
74 {
75 newsDate: currentDate,
76 publishDate: currentDate,
77 createdDate: currentDate,
78 lastModifiedDate: currentDate
79 },
80 returnedFromService
81 );
82
83 service.create(new PieceOfNews()).subscribe(resp => (expectedResult = resp.body));
84
85 const req = httpMock.expectOne({ method: 'POST' });
86 req.flush(returnedFromService);
87 expect(expectedResult).toMatchObject(expected);
88 });
89
90 it('should update a PieceOfNews', () => {
91 const returnedFromService = Object.assign(
92 {
93 appId: 1,
94 newsDate: currentDate.format(DATE_TIME_FORMAT),
95 headline: 'BBBBBB',
96 content: 'BBBBBB',
97 link: 'BBBBBB',
98 publishDate: currentDate.format(DATE_TIME_FORMAT),
99 createdBy: 'BBBBBB',
100 createdDate: currentDate.format(DATE_TIME_FORMAT),
101 lastModifiedBy: 'BBBBBB',
102 lastModifiedDate: currentDate.format(DATE_TIME_FORMAT)
103 },
104 elemDefault
105 );
106
107 const expected = Object.assign(
108 {
109 newsDate: currentDate,
110 publishDate: currentDate,
111 createdDate: currentDate,
112 lastModifiedDate: currentDate
113 },
114 returnedFromService
115 );
116
117 service.update(expected).subscribe(resp => (expectedResult = resp.body));
118
119 const req = httpMock.expectOne({ method: 'PUT' });
120 req.flush(returnedFromService);
121 expect(expectedResult).toMatchObject(expected);
122 });
123
124 it('should return a list of PieceOfNews', () => {
125 const returnedFromService = Object.assign(
126 {
127 appId: 1,
128 newsDate: currentDate.format(DATE_TIME_FORMAT),
129 headline: 'BBBBBB',
130 content: 'BBBBBB',
131 link: 'BBBBBB',
132 publishDate: currentDate.format(DATE_TIME_FORMAT),
133 createdBy: 'BBBBBB',
134 createdDate: currentDate.format(DATE_TIME_FORMAT),
135 lastModifiedBy: 'BBBBBB',
136 lastModifiedDate: currentDate.format(DATE_TIME_FORMAT)
137 },
138 elemDefault
139 );
140
141 const expected = Object.assign(
142 {
143 newsDate: currentDate,
144 publishDate: currentDate,
145 createdDate: currentDate,
146 lastModifiedDate: currentDate
147 },
148 returnedFromService
149 );
150
151 service.query().subscribe(resp => (expectedResult = resp.body));
152
153 const req = httpMock.expectOne({ method: 'GET' });
154 req.flush([returnedFromService]);
155 httpMock.verify();
156 expect(expectedResult).toContainEqual(expected);
157 });
158
159 it('should delete a PieceOfNews', () => {
160 service.delete(123).subscribe(resp => (expectedResult = resp.ok));
161
162 const req = httpMock.expectOne({ method: 'DELETE' });
163 req.flush({ status: 200 });
164 expect(expectedResult);
165 });
166 });
167
168 afterEach(() => {
169 httpMock.verify();
170 });
171 });
172 });
File src/test/javascript/spec/app/layouts/main/main.component.spec.ts added (mode: 100644) (index 0000000..1c30205)
1 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 import { Router, RouterEvent, NavigationEnd } from '@angular/router';
3 import { Title } from '@angular/platform-browser';
4 import { Subject, of } from 'rxjs';
5 import { TranslateModule, TranslateService, LangChangeEvent } from '@ngx-translate/core';
6
7 import { MainComponent } from 'app/layouts/main/main.component';
8 import { HonlapTestModule } from '../../../test.module';
9 import { MockRouter } from '../../../helpers/mock-route.service';
10
11 describe('Component Tests', () => {
12 describe('MainComponent', () => {
13 let comp: MainComponent;
14 let fixture: ComponentFixture<MainComponent>;
15 let router: MockRouter;
16 const routerEventsSubject = new Subject<RouterEvent>();
17 let titleService: Title;
18 let translateService: TranslateService;
19
20 beforeEach(async(() => {
21 TestBed.configureTestingModule({
22 imports: [HonlapTestModule, TranslateModule.forRoot()],
23 declarations: [MainComponent],
24 providers: [Title]
25 })
26 .overrideTemplate(MainComponent, '')
27 .compileComponents();
28 }));
29
30 beforeEach(() => {
31 fixture = TestBed.createComponent(MainComponent);
32 comp = fixture.componentInstance;
33 router = TestBed.get(Router);
34 router.setEvents(routerEventsSubject.asObservable());
35 titleService = TestBed.get(Title);
36 translateService = TestBed.get(TranslateService);
37 });
38
39 describe('page title', () => {
40 let routerState: any;
41 const defaultPageTitle = 'global.title';
42 const parentRoutePageTitle = 'parentTitle';
43 const childRoutePageTitle = 'childTitle';
44 const navigationEnd = new NavigationEnd(1, '', '');
45 const langChangeEvent: LangChangeEvent = { lang: 'hu', translations: null };
46
47 beforeEach(() => {
48 routerState = { snapshot: { root: {} } };
49 router.setRouterState(routerState);
50 spyOn(translateService, 'get').and.callFake((key: string) => {
51 return of(key + ' translated');
52 });
53 translateService.currentLang = 'hu';
54 spyOn(titleService, 'setTitle');
55 comp.ngOnInit();
56 });
57
58 describe('navigation end', () => {
59 it('should set page title to default title if pageTitle is missing on routes', () => {
60 // WHEN
61 routerEventsSubject.next(navigationEnd);
62
63 // THEN
64 expect(translateService.get).toHaveBeenCalledWith(defaultPageTitle);
65 expect(titleService.setTitle).toHaveBeenCalledWith(defaultPageTitle + ' translated');
66 });
67
68 it('should set page title to root route pageTitle if there is no child routes', () => {
69 // GIVEN
70 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
71
72 // WHEN
73 routerEventsSubject.next(navigationEnd);
74
75 // THEN
76 expect(translateService.get).toHaveBeenCalledWith(parentRoutePageTitle);
77 expect(titleService.setTitle).toHaveBeenCalledWith(parentRoutePageTitle + ' translated');
78 });
79
80 it('should set page title to child route pageTitle if child routes exist and pageTitle is set for child route', () => {
81 // GIVEN
82 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
83 routerState.snapshot.root.firstChild = { data: { pageTitle: childRoutePageTitle } };
84
85 // WHEN
86 routerEventsSubject.next(navigationEnd);
87
88 // THEN
89 expect(translateService.get).toHaveBeenCalledWith(childRoutePageTitle);
90 expect(titleService.setTitle).toHaveBeenCalledWith(childRoutePageTitle + ' translated');
91 });
92
93 it('should set page title to parent route pageTitle if child routes exists but pageTitle is not set for child route data', () => {
94 // GIVEN
95 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
96 routerState.snapshot.root.firstChild = { data: {} };
97
98 // WHEN
99 routerEventsSubject.next(navigationEnd);
100
101 // THEN
102 expect(translateService.get).toHaveBeenCalledWith(parentRoutePageTitle);
103 expect(titleService.setTitle).toHaveBeenCalledWith(parentRoutePageTitle + ' translated');
104 });
105
106 it('should set page title to parent route pageTitle if child routes exists but data is not set for child route', () => {
107 // GIVEN
108 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
109 routerState.snapshot.root.firstChild = {};
110
111 // WHEN
112 routerEventsSubject.next(navigationEnd);
113
114 // THEN
115 expect(translateService.get).toHaveBeenCalledWith(parentRoutePageTitle);
116 expect(titleService.setTitle).toHaveBeenCalledWith(parentRoutePageTitle + ' translated');
117 });
118 });
119
120 describe('language change', () => {
121 it('should set page title to default title if pageTitle is missing on routes', () => {
122 // WHEN
123 translateService.onLangChange.emit(langChangeEvent);
124
125 // THEN
126 expect(translateService.get).toHaveBeenCalledWith(defaultPageTitle);
127 expect(titleService.setTitle).toHaveBeenCalledWith(defaultPageTitle + ' translated');
128 });
129
130 it('should set page title to root route pageTitle if there is no child routes', () => {
131 // GIVEN
132 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
133
134 // WHEN
135 translateService.onLangChange.emit(langChangeEvent);
136
137 // THEN
138 expect(translateService.get).toHaveBeenCalledWith(parentRoutePageTitle);
139 expect(titleService.setTitle).toHaveBeenCalledWith(parentRoutePageTitle + ' translated');
140 });
141
142 it('should set page title to child route pageTitle if child routes exist and pageTitle is set for child route', () => {
143 // GIVEN
144 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
145 routerState.snapshot.root.firstChild = { data: { pageTitle: childRoutePageTitle } };
146
147 // WHEN
148 translateService.onLangChange.emit(langChangeEvent);
149
150 // THEN
151 expect(translateService.get).toHaveBeenCalledWith(childRoutePageTitle);
152 expect(titleService.setTitle).toHaveBeenCalledWith(childRoutePageTitle + ' translated');
153 });
154
155 it('should set page title to parent route pageTitle if child routes exists but pageTitle is not set for child route data', () => {
156 // GIVEN
157 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
158 routerState.snapshot.root.firstChild = { data: {} };
159
160 // WHEN
161 translateService.onLangChange.emit(langChangeEvent);
162
163 // THEN
164 expect(translateService.get).toHaveBeenCalledWith(parentRoutePageTitle);
165 expect(titleService.setTitle).toHaveBeenCalledWith(parentRoutePageTitle + ' translated');
166 });
167
168 it('should set page title to parent route pageTitle if child routes exists but data is not set for child route', () => {
169 // GIVEN
170 routerState.snapshot.root.data = { pageTitle: parentRoutePageTitle };
171 routerState.snapshot.root.firstChild = {};
172
173 // WHEN
174 translateService.onLangChange.emit(langChangeEvent);
175
176 // THEN
177 expect(translateService.get).toHaveBeenCalledWith(parentRoutePageTitle);
178 expect(titleService.setTitle).toHaveBeenCalledWith(parentRoutePageTitle + ' translated');
179 });
180 });
181 });
182 });
183 });
File src/test/javascript/spec/app/shared/alert/alert-error.component.spec.ts added (mode: 100644) (index 0000000..10ef85f)
1 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
2 import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
3 import { JhiAlertService, JhiEventManager } from 'ng-jhipster';
4 import { TranslateModule } from '@ngx-translate/core';
5
6 import { HonlapTestModule } from '../../../test.module';
7 import { AlertErrorComponent } from 'app/shared/alert/alert-error.component';
8 import { MockAlertService } from '../../../helpers/mock-alert.service';
9
10 describe('Component Tests', () => {
11 describe('Alert Error Component', () => {
12 let comp: AlertErrorComponent;
13 let fixture: ComponentFixture<AlertErrorComponent>;
14 let eventManager: JhiEventManager;
15
16 beforeEach(async(() => {
17 TestBed.configureTestingModule({
18 imports: [HonlapTestModule, TranslateModule.forRoot()],
19 declarations: [AlertErrorComponent],
20 providers: [
21 JhiEventManager,
22 {
23 provide: JhiAlertService,
24 useClass: MockAlertService
25 }
26 ]
27 })
28 .overrideTemplate(AlertErrorComponent, '')
29 .compileComponents();
30 }));
31
32 beforeEach(() => {
33 fixture = TestBed.createComponent(AlertErrorComponent);
34 comp = fixture.componentInstance;
35 eventManager = fixture.debugElement.injector.get(JhiEventManager);
36 });
37
38 describe('Error Handling', () => {
39 it('Should display an alert on status 0', () => {
40 // GIVEN
41 eventManager.broadcast({ name: 'honlapApp.httpError', content: { status: 0 } });
42 // THEN
43 expect(comp.alerts.length).toBe(1);
44 expect(comp.alerts[0].msg).toBe('error.server.not.reachable');
45 });
46
47 it('Should display an alert on status 404', () => {
48 // GIVEN
49 eventManager.broadcast({ name: 'honlapApp.httpError', content: { status: 404 } });
50 // THEN
51 expect(comp.alerts.length).toBe(1);
52 expect(comp.alerts[0].msg).toBe('error.url.not.found');
53 });
54
55 it('Should display an alert on generic error', () => {
56 // GIVEN
57 eventManager.broadcast({ name: 'honlapApp.httpError', content: { error: { message: 'Error Message' } } });
58 eventManager.broadcast({ name: 'honlapApp.httpError', content: { error: 'Second Error Message' } });
59 // THEN
60 expect(comp.alerts.length).toBe(2);
61 expect(comp.alerts[0].msg).toBe('Error Message');
62 expect(comp.alerts[1].msg).toBe('Second Error Message');
63 });
64
65 it('Should display an alert on status 400 for generic error', () => {
66 // GIVEN
67 const response = new HttpErrorResponse({
68 url: 'http://localhost:8080/api/foos',
69 headers: new HttpHeaders(),
70 status: 400,
71 statusText: 'Bad Request',
72 error: {
73 type: 'https://www.jhipster.tech/problem/constraint-violation',
74 title: 'Bad Request',
75 status: 400,
76 path: '/api/foos',
77 message: 'error.validation'
78 }
79 });
80 eventManager.broadcast({ name: 'honlapApp.httpError', content: response });
81 // THEN
82 expect(comp.alerts.length).toBe(1);
83 expect(comp.alerts[0].msg).toBe('error.validation');
84 });
85
86 it('Should display an alert on status 400 for generic error without message', () => {
87 // GIVEN
88 const response = new HttpErrorResponse({
89 url: 'http://localhost:8080/api/foos',
90 headers: new HttpHeaders(),
91 status: 400,
92 error: 'Bad Request'
93 });
94 eventManager.broadcast({ name: 'honlapApp.httpError', content: response });
95 // THEN
96 expect(comp.alerts.length).toBe(1);
97 expect(comp.alerts[0].msg).toBe('Bad Request');
98 });
99
100 it('Should display an alert on status 400 for invalid parameters', () => {
101 // GIVEN
102 const response = new HttpErrorResponse({
103 url: 'http://localhost:8080/api/foos',
104 headers: new HttpHeaders(),
105 status: 400,
106 statusText: 'Bad Request',
107 error: {
108 type: 'https://www.jhipster.tech/problem/constraint-violation',
109 title: 'Method argument not valid',
110 status: 400,
111 path: '/api/foos',
112 message: 'error.validation',
113 fieldErrors: [{ objectName: 'foo', field: 'minField', message: 'Min' }]
114 }
115 });
116 eventManager.broadcast({ name: 'honlapApp.httpError', content: response });
117 // THEN
118 expect(comp.alerts.length).toBe(1);
119 expect(comp.alerts[0].msg).toBe('error.Size');
120 });
121
122 it('Should display an alert on status 400 for error headers', () => {
123 // GIVEN
124 const response = new HttpErrorResponse({
125 url: 'http://localhost:8080/api/foos',
126 headers: new HttpHeaders().append('app-error', 'Error Message').append('app-params', 'foo'),
127 status: 400,
128 statusText: 'Bad Request',
129 error: {
130 status: 400,
131 message: 'error.validation'
132 }
133 });
134 eventManager.broadcast({ name: 'honlapApp.httpError', content: response });
135 // THEN
136 expect(comp.alerts.length).toBe(1);
137 expect(comp.alerts[0].msg).toBe('Error Message');
138 });
139 });
140 });
141 });
File src/test/javascript/spec/app/shared/login/login.component.spec.ts added (mode: 100644) (index 0000000..b5606a6)
1 import { ComponentFixture, TestBed, async, inject, fakeAsync, tick } from '@angular/core/testing';
2 import { FormBuilder } from '@angular/forms';
3 import { Router } from '@angular/router';
4 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
5
6 import { LoginService } from 'app/core/login/login.service';
7 import { LoginModalComponent } from 'app/shared/login/login.component';
8 import { HonlapTestModule } from '../../../test.module';
9 import { MockLoginService } from '../../../helpers/mock-login.service';
10 import { MockRouter } from '../../../helpers/mock-route.service';
11 import { MockActiveModal } from '../../../helpers/mock-active-modal.service';
12
13 describe('Component Tests', () => {
14 describe('LoginComponent', () => {
15 let comp: LoginModalComponent;
16 let fixture: ComponentFixture<LoginModalComponent>;
17 let mockLoginService: MockLoginService;
18 let mockRouter: MockRouter;
19 let mockActiveModal: MockActiveModal;
20
21 beforeEach(async(() => {
22 TestBed.configureTestingModule({
23 imports: [HonlapTestModule],
24 declarations: [LoginModalComponent],
25 providers: [
26 FormBuilder,
27 {
28 provide: LoginService,
29 useClass: MockLoginService
30 }
31 ]
32 })
33 .overrideTemplate(LoginModalComponent, '')
34 .compileComponents();
35 }));
36
37 beforeEach(() => {
38 fixture = TestBed.createComponent(LoginModalComponent);
39 comp = fixture.componentInstance;
40 mockLoginService = TestBed.get(LoginService);
41 mockRouter = TestBed.get(Router);
42 mockActiveModal = TestBed.get(NgbActiveModal);
43 });
44
45 it('should authenticate the user', inject(
46 [],
47 fakeAsync(() => {
48 // GIVEN
49 const credentials = {
50 username: 'admin',
51 password: 'admin',
52 rememberMe: true
53 };
54
55 comp.loginForm.patchValue({
56 username: 'admin',
57 password: 'admin',
58 rememberMe: true
59 });
60 mockLoginService.setResponse({});
61 mockRouter.url = '/admin/metrics';
62
63 // WHEN/
64 comp.login();
65 tick(); // simulate async
66
67 // THEN
68 expect(comp.authenticationError).toEqual(false);
69 expect(mockActiveModal.closeSpy).toHaveBeenCalled();
70 expect(mockLoginService.loginSpy).toHaveBeenCalledWith(credentials);
71 })
72 ));
73
74 it('should empty the credentials upon cancel', () => {
75 // GIVEN
76 comp.loginForm.patchValue({
77 username: 'admin',
78 password: 'admin'
79 });
80
81 const expected = {
82 username: '',
83 password: '',
84 rememberMe: false
85 };
86
87 // WHEN
88 comp.cancel();
89
90 // THEN
91 expect(comp.authenticationError).toEqual(false);
92 expect(comp.loginForm.get('username')!.value).toEqual(expected.username);
93 expect(comp.loginForm.get('password')!.value).toEqual(expected.password);
94 expect(comp.loginForm.get('rememberMe')!.value).toEqual(expected.rememberMe);
95 expect(mockActiveModal.dismissSpy).toHaveBeenCalledWith('cancel');
96 });
97
98 it('should redirect user when register', () => {
99 // WHEN
100 comp.register();
101
102 // THEN
103 expect(mockActiveModal.dismissSpy).toHaveBeenCalledWith('to state register');
104 expect(mockRouter.navigateSpy).toHaveBeenCalledWith(['/account/register']);
105 });
106
107 it('should redirect user when request password', () => {
108 // WHEN
109 comp.requestResetPassword();
110
111 // THEN
112 expect(mockActiveModal.dismissSpy).toHaveBeenCalledWith('to state requestReset');
113 expect(mockRouter.navigateSpy).toHaveBeenCalledWith(['/account/reset', 'request']);
114 });
115 });
116 });
File src/test/javascript/spec/helpers/mock-account.service.ts added (mode: 100644) (index 0000000..a01ceed)
1 import Spy = jasmine.Spy;
2 import { of } from 'rxjs';
3
4 import { SpyObject } from './spyobject';
5 import { AccountService } from 'app/core/auth/account.service';
6 import { Account } from 'app/core/user/account.model';
7
8 export class MockAccountService extends SpyObject {
9 getSpy: Spy;
10 saveSpy: Spy;
11 authenticateSpy: Spy;
12 identitySpy: Spy;
13 getAuthenticationStateSpy: Spy;
14
15 constructor() {
16 super(AccountService);
17
18 this.getSpy = this.spy('get').andReturn(this);
19 this.saveSpy = this.spy('save').andReturn(this);
20 this.authenticateSpy = this.spy('authenticate').andReturn(this);
21 this.identitySpy = this.spy('identity').andReturn(of(null));
22 this.getAuthenticationStateSpy = this.spy('getAuthenticationState').andReturn(of(null));
23 }
24
25 setIdentityResponse(account: Account | null): void {
26 this.identitySpy = this.spy('identity').andReturn(of(account));
27 this.getAuthenticationStateSpy = this.spy('getAuthenticationState').andReturn(of(account));
28 }
29 }
File src/test/javascript/spec/helpers/mock-active-modal.service.ts added (mode: 100644) (index 0000000..bd32d74)
1 import Spy = jasmine.Spy;
2 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3
4 import { SpyObject } from './spyobject';
5
6 export class MockActiveModal extends SpyObject {
7 dismissSpy: Spy;
8 closeSpy: Spy;
9
10 constructor() {
11 super(NgbActiveModal);
12 this.dismissSpy = this.spy('dismiss').andReturn(this);
13 this.closeSpy = this.spy('close').andReturn(this);
14 }
15 }
File src/test/javascript/spec/helpers/mock-alert.service.ts added (mode: 100644) (index 0000000..2bf7724)
1 import { JhiAlertService, JhiAlert } from 'ng-jhipster';
2
3 import { SpyObject } from './spyobject';
4
5 export class MockAlertService extends SpyObject {
6 constructor() {
7 super(JhiAlertService);
8 }
9
10 addAlert(alertOptions: JhiAlert): JhiAlert {
11 return alertOptions;
12 }
13 }
File src/test/javascript/spec/helpers/mock-event-manager.service.ts added (mode: 100644) (index 0000000..4a8f56a)
1 import Spy = jasmine.Spy;
2 import { JhiEventManager } from 'ng-jhipster';
3
4 import { SpyObject } from './spyobject';
5
6 export class MockEventManager extends SpyObject {
7 broadcastSpy: Spy;
8
9 constructor() {
10 super(JhiEventManager);
11 this.broadcastSpy = this.spy('broadcast').andReturn(this);
12 }
13 }
File src/test/javascript/spec/helpers/mock-language.service.ts added (mode: 100644) (index 0000000..0c53be6)
1 import Spy = jasmine.Spy;
2 import { JhiLanguageService } from 'ng-jhipster';
3
4 import { SpyObject } from './spyobject';
5
6 export class MockLanguageService extends SpyObject {
7 getCurrentLanguageSpy: Spy;
8
9 constructor() {
10 super(JhiLanguageService);
11
12 this.getCurrentLanguageSpy = this.spy('getCurrentLanguage').andReturn('hu');
13 }
14 }
File src/test/javascript/spec/helpers/mock-login.service.ts added (mode: 100644) (index 0000000..a75a800)
1 import Spy = jasmine.Spy;
2 import { of } from 'rxjs';
3
4 import { SpyObject } from './spyobject';
5 import { LoginService } from 'app/core/login/login.service';
6
7 export class MockLoginService extends SpyObject {
8 loginSpy: Spy;
9 logoutSpy: Spy;
10 registerSpy: Spy;
11 requestResetPasswordSpy: Spy;
12 cancelSpy: Spy;
13
14 constructor() {
15 super(LoginService);
16
17 this.loginSpy = this.spy('login').andReturn(of({}));
18 this.logoutSpy = this.spy('logout').andReturn(this);
19 this.registerSpy = this.spy('register').andReturn(this);
20 this.requestResetPasswordSpy = this.spy('requestResetPassword').andReturn(this);
21 this.cancelSpy = this.spy('cancel').andReturn(this);
22 }
23
24 setResponse(json: any): void {
25 this.loginSpy = this.spy('login').andReturn(of(json));
26 }
27 }
File src/test/javascript/spec/helpers/mock-route.service.ts added (mode: 100644) (index 0000000..a2dd6d8)
1 import Spy = jasmine.Spy;
2 import { ActivatedRoute, Router, RouterEvent } from '@angular/router';
3 import { Observable, of } from 'rxjs';
4
5 import { SpyObject } from './spyobject';
6
7 export class MockActivatedRoute extends ActivatedRoute {
8 constructor(parameters?: any) {
9 super();
10 this.queryParams = of(parameters);
11 this.params = of(parameters);
12 this.data = of({
13 ...parameters,
14 pagingParams: {
15 page: 10,
16 ascending: false,
17 predicate: 'id'
18 }
19 });
20 }
21 }
22
23 export class MockRouter extends SpyObject {
24 navigateSpy: Spy;
25 navigateByUrlSpy: Spy;
26 events: Observable<RouterEvent> | null = null;
27 routerState: any;
28 url = '';
29
30 constructor() {
31 super(Router);
32 this.navigateSpy = this.spy('navigate');
33 this.navigateByUrlSpy = this.spy('navigateByUrl');
34 }
35
36 setEvents(events: Observable<RouterEvent>): void {
37 this.events = events;
38 }
39
40 setRouterState(routerState: any): void {
41 this.routerState = routerState;
42 }
43 }
File src/test/javascript/spec/helpers/mock-state-storage.service.ts added (mode: 100644) (index 0000000..1a23343)
1 import Spy = jasmine.Spy;
2
3 import { SpyObject } from './spyobject';
4 import { StateStorageService } from 'app/core/auth/state-storage.service';
5
6 export class MockStateStorageService extends SpyObject {
7 getUrlSpy: Spy;
8 storeUrlSpy: Spy;
9 clearUrlSpy: Spy;
10
11 constructor() {
12 super(StateStorageService);
13 this.getUrlSpy = this.spy('getUrl').andReturn(null);
14 this.storeUrlSpy = this.spy('storeUrl').andReturn(this);
15 this.clearUrlSpy = this.spy('clearUrl').andReturn(this);
16 }
17
18 setResponse(previousUrl: string | null): void {
19 this.getUrlSpy = this.spy('getUrl').andReturn(previousUrl);
20 }
21 }
File src/test/javascript/spec/helpers/spyobject.ts added (mode: 100644) (index 0000000..eeb221a)
1 export interface GuinessCompatibleSpy extends jasmine.Spy {
2 /** By chaining the spy with and.returnValue, all calls to the function will return a specific
3 * value. */
4 andReturn(val: any): GuinessCompatibleSpy;
5 /** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied
6 * function. */
7 andCallFake(fn: Function): GuinessCompatibleSpy;
8 /** removes all recorded calls */
9 reset(): void;
10 }
11
12 export class SpyObject {
13 constructor(type?: any) {
14 if (type) {
15 Object.keys(type.prototype).forEach(prop => {
16 let m = null;
17 try {
18 m = type.prototype[prop];
19 } catch (e) {
20 // As we are creating spys for abstract classes,
21 // these classes might have getters that throw when they are accessed.
22 // As we are only auto creating spys for methods, this
23 // should not matter.
24 }
25 if (typeof m === 'function') {
26 this.spy(prop);
27 }
28 });
29 }
30 }
31
32 spy(name: string): GuinessCompatibleSpy {
33 if (!this[name]) {
34 this[name] = this.createGuinnessCompatibleSpy(name);
35 }
36 return this[name];
37 }
38
39 private createGuinnessCompatibleSpy(name: string): GuinessCompatibleSpy {
40 const newSpy: GuinessCompatibleSpy = jasmine.createSpy(name) as any;
41 newSpy.andCallFake = newSpy.and.callFake as any;
42 newSpy.andReturn = newSpy.and.returnValue as any;
43 newSpy.reset = newSpy.calls.reset as any;
44 // revisit return null here (previously needed for rtts_assert).
45 newSpy.and.returnValue(null);
46 return newSpy;
47 }
48 }
File src/test/javascript/spec/test.module.ts added (mode: 100644) (index 0000000..601e364)
1 import { DatePipe } from '@angular/common';
2 import { ActivatedRoute, Router } from '@angular/router';
3 import { NgModule } from '@angular/core';
4 import { HttpClientTestingModule } from '@angular/common/http/testing';
5 import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
6 import { JhiLanguageService, JhiDataUtils, JhiDateUtils, JhiEventManager, JhiAlertService, JhiParseLinks } from 'ng-jhipster';
7
8 import { MockLanguageService } from './helpers/mock-language.service';
9 import { AccountService } from 'app/core/auth/account.service';
10 import { LoginModalService } from 'app/core/login/login-modal.service';
11 import { MockAccountService } from './helpers/mock-account.service';
12 import { MockActivatedRoute, MockRouter } from './helpers/mock-route.service';
13 import { MockActiveModal } from './helpers/mock-active-modal.service';
14 import { MockEventManager } from './helpers/mock-event-manager.service';
15
16 @NgModule({
17 providers: [
18 DatePipe,
19 JhiDataUtils,
20 JhiDateUtils,
21 JhiParseLinks,
22 {
23 provide: JhiLanguageService,
24 useClass: MockLanguageService
25 },
26 {
27 provide: JhiEventManager,
28 useClass: MockEventManager
29 },
30 {
31 provide: NgbActiveModal,
32 useClass: MockActiveModal
33 },
34 {
35 provide: ActivatedRoute,
36 useValue: new MockActivatedRoute({ id: 123 })
37 },
38 {
39 provide: Router,
40 useClass: MockRouter
41 },
42 {
43 provide: AccountService,
44 useClass: MockAccountService
45 },
46 {
47 provide: LoginModalService,
48 useValue: null
49 },
50 {
51 provide: JhiAlertService,
52 useValue: null
53 },
54 {
55 provide: NgbModal,
56 useValue: null
57 }
58 ],
59 imports: [HttpClientTestingModule]
60 })
61 export class HonlapTestModule {}
File src/test/resources/config/application.yml added (mode: 100644) (index 0000000..a6606ba)
1 # ===================================================================
2 # Spring Boot configuration.
3 #
4 # This configuration is used for unit/integration tests.
5 #
6 # More information on profiles: https://www.jhipster.tech/profiles/
7 # More information on configuration properties: https://www.jhipster.tech/common-application-properties/
8 # ===================================================================
9
10 # ===================================================================
11 # Standard Spring Boot properties.
12 # Full reference is available at:
13 # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
14 # ===================================================================
15
16 spring:
17 application:
18 name: honlap
19 datasource:
20 type: com.zaxxer.hikari.HikariDataSource
21 url: jdbc:h2:mem:honlap;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
22 name:
23 username:
24 password:
25 hikari:
26 auto-commit: false
27 jackson:
28 serialization:
29 write-durations-as-timestamps: false
30 jpa:
31 database-platform: io.github.jhipster.domain.util.FixedH2Dialect
32 open-in-view: false
33 show-sql: false
34 hibernate:
35 ddl-auto: none
36 naming:
37 physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
38 implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
39 properties:
40 hibernate.id.new_generator_mappings: true
41 hibernate.connection.provider_disables_autocommit: true
42 hibernate.cache.use_second_level_cache: false
43 hibernate.cache.use_query_cache: false
44 hibernate.generate_statistics: false
45 hibernate.hbm2ddl.auto: validate
46 hibernate.jdbc.time_zone: UTC
47 liquibase:
48 contexts: test
49 mail:
50 host: localhost
51 main:
52 allow-bean-definition-overriding: true
53 messages:
54 basename: i18n/messages
55 mvc:
56 favicon:
57 enabled: false
58 task:
59 execution:
60 thread-name-prefix: honlap-task-
61 pool:
62 core-size: 1
63 max-size: 50
64 queue-capacity: 10000
65 scheduling:
66 thread-name-prefix: honlap-scheduling-
67 pool:
68 size: 1
69 thymeleaf:
70 mode: HTML
71
72 server:
73 port: 10344
74 address: localhost
75
76 # ===================================================================
77 # JHipster specific properties
78 #
79 # Full reference is available at: https://www.jhipster.tech/common-application-properties/
80 # ===================================================================
81
82 jhipster:
83 clientApp:
84 name: 'honlapApp'
85 logging:
86 # To test json console appender
87 use-json-format: true # By default, logs are in Json format
88 logstash:
89 enabled: false
90 host: localhost
91 port: 5000
92 queue-size: 512
93 mail:
94 from: test@localhost
95 base-url: http://127.0.0.1:8080
96 security:
97 authentication:
98 jwt:
99 # This token must be encoded using Base64 (you can type `echo 'secret-key'|base64` on your command line)
100 base64-secret: ZmYxOTYwOGZiYTY1OTJiMTQ3MDNhNGJiNTM3ZWMxN2U1ZTVjODdlMDhmZmNkMGRhYTQxY2ZiMGQzM2Q0ZTNmYzc2YjNjMzU5ZmVkZDgzZDc3OTYxZDMzNzdiNzc3MmVkYjA0NDFkOGIxMTI0MjRiNTMzYzRkNzFkMTJiYWE4Y2Y=
101 # Token is valid 24 hours
102 token-validity-in-seconds: 86400
103 metrics:
104 logs: # Reports metrics in the logs
105 enabled: true
106 report-frequency: 60 # in seconds
107
108 # ===================================================================
109 # Application specific properties
110 # Add your own application properties here, see the ApplicationProperties class
111 # to have type-safe configuration, like in the JHipsterProperties above
112 #
113 # More documentation is available at:
114 # https://www.jhipster.tech/common-application-properties/
115 # ===================================================================
116
117 # application:
File src/test/resources/i18n/messages_en.properties added (mode: 100644) (index 0000000..334cb4a)
1 email.test.title=test title
2 # Value used for English locale unit test in MailServiceIT
3 # as this file is loaded instead of real file
4 email.activation.title=honlap account activation
File src/test/resources/i18n/messages_hu.properties added (mode: 100644) (index 0000000..e971453)
1 email.test.title=hozzáférés aktiválása.
File src/test/resources/logback.xml added (mode: 100644) (index 0000000..d0ec607)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration>
3
4 <configuration scan="true">
5 <include resource="org/springframework/boot/logging/logback/base.xml"/>
6
7 <logger name="hu.dns.honlap" level="INFO"/>
8
9 <logger name="io.github.jhipster" level="WARN"/>
10
11 <logger name="javax.activation" level="WARN"/>
12 <logger name="javax.mail" level="WARN"/>
13 <logger name="javax.xml.bind" level="WARN"/>
14 <logger name="ch.qos.logback" level="WARN"/>
15 <logger name="com.ryantenney" level="WARN"/>
16 <logger name="com.sun" level="WARN"/>
17 <logger name="com.zaxxer" level="WARN"/>
18 <logger name="io.undertow" level="WARN"/>
19 <logger name="io.undertow.websockets.jsr" level="ERROR"/>
20 <logger name="org.ehcache" level="WARN"/>
21 <logger name="org.apache" level="WARN"/>
22 <logger name="org.apache.catalina.startup.DigesterFactory" level="OFF"/>
23 <logger name="org.bson" level="WARN"/>
24 <logger name="org.hibernate.validator" level="WARN"/>
25 <logger name="org.hibernate" level="WARN"/>
26 <logger name="org.hibernate.ejb.HibernatePersistence" level="OFF"/>
27 <logger name="org.postgresql.jdbc" level="WARN"/>
28 <logger name="org.springframework" level="WARN"/>
29 <logger name="org.springframework.web" level="WARN"/>
30 <logger name="org.springframework.security" level="WARN"/>
31 <logger name="org.springframework.cache" level="WARN"/>
32 <logger name="org.thymeleaf" level="WARN"/>
33 <logger name="org.xnio" level="WARN"/>
34 <logger name="springfox" level="WARN"/>
35 <logger name="sun.rmi" level="WARN"/>
36 <logger name="liquibase" level="WARN"/>
37 <logger name="LiquibaseSchemaResolver" level="INFO"/>
38 <logger name="sun.rmi.transport" level="WARN"/>
39
40 <root>
41 <level>WARN</level>
42 <appender-ref ref="CONSOLE"/>
43 </root>
44
45 </configuration>
File src/test/resources/templates/mail/testEmail.html added (mode: 100644) (index 0000000..a4ca16a)
1 <html xmlns:th="http://www.thymeleaf.org" th:text="|#{email.test.title}, ${baseUrl}, ${user.login}|"></html>
File tsconfig.app.json added (mode: 100644) (index 0000000..6aeff43)
1 {
2 "extends": "./tsconfig.json",
3 "files": ["src/main/webapp/app/app.main.ts"]
4 }
File tsconfig.e2e.json added (mode: 100644) (index 0000000..2c7b284)
1 {
2 "extends": "./tsconfig.json",
3 "compilerOptions": {
4 "module": "commonjs"
5 }
6 }
File tsconfig.json added (mode: 100644) (index 0000000..3f31512)
1 {
2 "compilerOptions": {
3 "target": "es6",
4 "module": "esnext",
5 "moduleResolution": "node",
6 "sourceMap": true,
7 "emitDecoratorMetadata": true,
8 "experimentalDecorators": true,
9 "removeComments": false,
10 "strict": true,
11 "noImplicitReturns": true,
12 "noFallthroughCasesInSwitch": true,
13 "suppressImplicitAnyIndexErrors": true,
14 "skipLibCheck": true,
15 "outDir": "target/classes/static/app",
16 "lib": ["es7", "dom"],
17 "baseUrl": "./",
18 "paths": {
19 "app/*": ["src/main/webapp/app/*"]
20 },
21 "importHelpers": true
22 },
23 "angularCompilerOptions": {
24 "genDir": "target/classes/aot",
25 "fullTemplateTypeCheck": true,
26 "preserveWhitespaces": true
27 }
28 }
File tslint.json added (mode: 100644) (index 0000000..9319baf)
1 {
2 "rulesDirectory": ["node_modules/codelyzer"],
3 "rules": {
4 "directive-selector": [true, "attribute", "auth", "camelCase"],
5 "component-selector": [true, "element", "auth", "kebab-case"],
6 "no-inputs-metadata-property": true,
7 "no-outputs-metadata-property": true,
8 "no-host-metadata-property": true,
9 "no-input-rename": true,
10 "no-output-rename": true,
11 "use-lifecycle-interface": true,
12 "use-pipe-transform-interface": false,
13 "component-class-suffix": true,
14 "directive-class-suffix": true,
15 "typedef": [true, "call-signature"]
16 }
17 }
File webpack/logo-jhipster.png added (mode: 100644) (index 0000000..e301aa9)
File webpack/utils.js added (mode: 100644) (index 0000000..10aefd4)
1 const path = require('path');
2
3 const tsconfig = require('../tsconfig.json');
4
5 module.exports = {
6 root,
7 mapTypescriptAliasToWebpackAlias
8 };
9
10 const _root = path.resolve(__dirname, '..');
11
12 function root(args) {
13 args = Array.prototype.slice.call(arguments, 0);
14 return path.join.apply(path, [_root].concat(args));
15 }
16
17 function mapTypescriptAliasToWebpackAlias(alias = {}) {
18 const webpackAliases = { ...alias };
19 if (!tsconfig.compilerOptions.paths) {
20 return webpackAliases;
21 }
22 Object.entries(tsconfig.compilerOptions.paths)
23 .filter(([key, value]) => {
24 // use Typescript alias in Webpack only if this has value
25 return Boolean(value.length);
26 })
27 .map(([key, value]) => {
28 // if Typescript alias ends with /* then remove this for Webpack
29 const regexToReplace = /\/\*$/;
30 const aliasKey = key.replace(regexToReplace, '');
31 const aliasValue = value[0].replace(regexToReplace, '');
32 return [aliasKey, root(aliasValue)];
33 })
34 .reduce((aliases, [key, value]) => {
35 aliases[key] = value;
36 return aliases;
37 }, webpackAliases);
38 return webpackAliases;
39 }
File webpack/webpack.common.js added (mode: 100644) (index 0000000..3efcbf3)
1 const webpack = require('webpack');
2 const { BaseHrefWebpackPlugin } = require('base-href-webpack-plugin');
3 const CopyWebpackPlugin = require('copy-webpack-plugin');
4 const HtmlWebpackPlugin = require('html-webpack-plugin');
5 const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
6 const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin");
7
8 const utils = require('./utils.js');
9
10 module.exports = (options) => ({
11 resolve: {
12 extensions: ['.ts', '.js'],
13 modules: ['node_modules'],
14 mainFields: [ 'es2015', 'browser', 'module', 'main'],
15 alias: utils.mapTypescriptAliasToWebpackAlias()
16 },
17 stats: {
18 children: false
19 },
20 module: {
21 rules: [
22 {
23 test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
24 loader: '@ngtools/webpack'
25 },
26 {
27 test: /\.html$/,
28 loader: 'html-loader',
29 options: {
30 minimize: true,
31 caseSensitive: true,
32 removeAttributeQuotes:false,
33 minifyJS:false,
34 minifyCSS:false
35 },
36 exclude: /(src\/main\/webapp\/index.html)/
37 },
38 {
39 test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
40 loader: 'file-loader',
41 options: {
42 digest: 'hex',
43 hash: 'sha512',
44 // For fixing src attr of image
45 // See https://github.com/jhipster/generator-jhipster/issues/11209
46 name: 'content/[hash].[ext]',
47 esModule: false
48 }
49 },
50 {
51 test: /manifest.webapp$/,
52 loader: 'file-loader',
53 options: {
54 name: 'manifest.webapp'
55 }
56 },
57 // Ignore warnings about System.import in Angular
58 { test: /[\/\\]@angular[\/\\].+\.js$/, parser: { system: true } },
59 ]
60 },
61 plugins: [
62 new webpack.DefinePlugin({
63 'process.env': {
64 NODE_ENV: `'${options.env}'`,
65 BUILD_TIMESTAMP: `'${new Date().getTime()}'`,
66 // APP_VERSION is passed as an environment variable from the Gradle / Maven build tasks.
67 VERSION: `'${process.env.hasOwnProperty('APP_VERSION') ? process.env.APP_VERSION : 'DEV'}'`,
68 DEBUG_INFO_ENABLED: options.env === 'development',
69 // The root URL for API calls, ending with a '/' - for example: `"https://www.jhipster.tech:8081/myservice/"`.
70 // If this URL is left empty (""), then it will be relative to the current context.
71 // If you use an API server, in `prod` mode, you will need to enable CORS
72 // (see the `jhipster.cors` common JHipster property in the `application-*.yml` configurations)
73 SERVER_API_URL: `''`
74 }
75 }),
76 new CopyWebpackPlugin([
77 { from: './node_modules/swagger-ui-dist/*.{js,css,html,png}', to: 'swagger-ui', flatten: true, ignore: ['index.html'] },
78 { from: './node_modules/axios/dist/axios.min.js', to: 'swagger-ui' },
79 { from: './src/main/webapp/swagger-ui/', to: 'swagger-ui' },
80 { from: './src/main/webapp/content/', to: 'content' },
81 { from: './src/main/webapp/favicon.ico', to: 'favicon.ico' },
82 { from: './src/main/webapp/manifest.webapp', to: 'manifest.webapp' },
83 // jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array
84 { from: './src/main/webapp/robots.txt', to: 'robots.txt' }
85 ]),
86 new MergeJsonWebpackPlugin({
87 output: {
88 groupBy: [
89 { pattern: "./src/main/webapp/i18n/hu/*.json", fileName: "./i18n/hu.json" },
90 { pattern: "./src/main/webapp/i18n/en/*.json", fileName: "./i18n/en.json" }
91 // jhipster-needle-i18n-language-webpack - JHipster will add/remove languages in this array
92 ]
93 }
94 }),
95 new HtmlWebpackPlugin({
96 template: './src/main/webapp/index.html',
97 chunks: ['polyfills', 'main', 'global'],
98 chunksSortMode: 'manual',
99 inject: 'body'
100 }),
101 new BaseHrefWebpackPlugin({ baseHref: '/' }),
102 new AngularCompilerPlugin({
103 mainPath: utils.root('src/main/webapp/app/app.main.ts'),
104 tsConfigPath: utils.root('tsconfig.app.json'),
105 sourceMap: true
106 })
107 ]
108 });
File webpack/webpack.dev.js added (mode: 100644) (index 0000000..0fb31af)
1 const webpack = require('webpack');
2 const writeFilePlugin = require('write-file-webpack-plugin');
3 const webpackMerge = require('webpack-merge');
4 const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
5 const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
6 const SimpleProgressWebpackPlugin = require('simple-progress-webpack-plugin');
7 const WebpackNotifierPlugin = require('webpack-notifier');
8 const path = require('path');
9 const sass = require('sass');
10
11 const utils = require('./utils.js');
12 const commonConfig = require('./webpack.common.js');
13
14 const ENV = 'development';
15
16 module.exports = (options) => webpackMerge(commonConfig({ env: ENV }), {
17 devtool: 'eval-source-map',
18 devServer: {
19 contentBase: './target/classes/static/',
20 proxy: [{
21 context: [
22 '/api',
23 '/services',
24 '/management',
25 '/swagger-resources',
26 '/v2/api-docs',
27 '/h2-console',
28 '/auth'
29 ],
30 target: `http${options.tls ? 's' : ''}://localhost:8080`,
31 secure: false,
32 changeOrigin: options.tls
33 }],
34 stats: options.stats,
35 watchOptions: {
36 ignored: /node_modules/
37 },
38 https: options.tls,
39 historyApiFallback: true
40 },
41 entry: {
42 global: './src/main/webapp/content/scss/global.scss',
43 main: './src/main/webapp/app/app.main'
44 },
45 output: {
46 path: utils.root('target/classes/static/'),
47 filename: 'app/[name].bundle.js',
48 chunkFilename: 'app/[id].chunk.js'
49 },
50 module: {
51 rules: [{
52 test: /\.(j|t)s$/,
53 enforce: 'pre',
54 loader: 'eslint-loader',
55 exclude: /node_modules/
56 },
57 {
58 test: /\.scss$/,
59 use: ['to-string-loader', 'css-loader', 'postcss-loader', {
60 loader: 'sass-loader',
61 options: { implementation: sass }
62 }],
63 exclude: /(vendor\.scss|global\.scss)/
64 },
65 {
66 test: /(vendor\.scss|global\.scss)/,
67 use: ['style-loader', 'css-loader', 'postcss-loader', {
68 loader: 'sass-loader',
69 options: { implementation: sass }
70 }]
71 }]
72 },
73 stats: process.env.JHI_DISABLE_WEBPACK_LOGS ? 'none' : options.stats,
74 plugins: [
75 process.env.JHI_DISABLE_WEBPACK_LOGS
76 ? null
77 : new SimpleProgressWebpackPlugin({
78 format: options.stats === 'minimal' ? 'compact' : 'expanded'
79 }),
80 new FriendlyErrorsWebpackPlugin(),
81 new BrowserSyncPlugin({
82 https: options.tls,
83 host: 'localhost',
84 port: 9000,
85 proxy: {
86 target: `http${options.tls ? 's' : ''}://localhost:9060`,
87 proxyOptions: {
88 changeOrigin: false //pass the Host header to the backend unchanged https://github.com/Browsersync/browser-sync/issues/430
89 }
90 },
91 socket: {
92 clients: {
93 heartbeatTimeout: 60000
94 }
95 }
96 /*
97 ,ghostMode: { // uncomment this part to disable BrowserSync ghostMode; https://github.com/jhipster/generator-jhipster/issues/11116
98 clicks: false,
99 location: false,
100 forms: false,
101 scroll: false
102 } */
103 }, {
104 reload: false
105 }),
106 new webpack.ContextReplacementPlugin(
107 /angular(\\|\/)core(\\|\/)/,
108 path.resolve(__dirname, './src/main/webapp/')
109 ),
110 new writeFilePlugin(),
111 new webpack.WatchIgnorePlugin([
112 utils.root('src/test'),
113 ]),
114 new WebpackNotifierPlugin({
115 title: 'JHipster',
116 contentImage: path.join(__dirname, 'logo-jhipster.png')
117 })
118 ].filter(Boolean),
119 mode: 'development'
120 });
File webpack/webpack.prod.js added (mode: 100644) (index 0000000..c2d3477)
1 const webpack = require('webpack');
2 const webpackMerge = require('webpack-merge');
3 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4 const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
5 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
6 const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
7 const TerserPlugin = require('terser-webpack-plugin');
8 const WorkboxPlugin = require('workbox-webpack-plugin');
9 const path = require('path');
10
11 const utils = require('./utils.js');
12 const commonConfig = require('./webpack.common.js');
13
14 const ENV = 'production';
15 const sass = require('sass');
16
17 module.exports = webpackMerge(commonConfig({ env: ENV }), {
18 // Enable source maps. Please note that this will slow down the build.
19 // You have to enable it in Terser config below and in tsconfig.json as well
20 // devtool: 'source-map',
21 entry: {
22 global: './src/main/webapp/content/scss/global.scss',
23 main: './src/main/webapp/app/app.main'
24 },
25 output: {
26 path: utils.root('target/classes/static/'),
27 filename: 'app/[name].[hash].bundle.js',
28 chunkFilename: 'app/[id].[hash].chunk.js'
29 },
30 module: {
31 rules: [
32 {
33 test: /\.scss$/,
34 use: ['to-string-loader', 'css-loader', 'postcss-loader', {
35 loader: 'sass-loader',
36 options: { implementation: sass }
37 }],
38 exclude: /(vendor\.scss|global\.scss)/
39 },
40 {
41 test: /(vendor\.scss|global\.scss)/,
42 use: [
43 {
44 loader: MiniCssExtractPlugin.loader,
45 options: {
46 publicPath: '../'
47 }
48 },
49 'css-loader',
50 'postcss-loader',
51 {
52 loader: 'sass-loader',
53 options: { implementation: sass }
54 }
55 ]
56 },
57 {
58 test: /\.css$/,
59 use: ['to-string-loader', 'css-loader'],
60 exclude: /(vendor\.css|global\.css)/
61 },
62 {
63 test: /(vendor\.css|global\.css)/,
64 use: [
65 {
66 loader: MiniCssExtractPlugin.loader,
67 options: {
68 publicPath: '../'
69 }
70 },
71 'css-loader',
72 'postcss-loader'
73 ]
74 }]
75 },
76 optimization: {
77 runtimeChunk: false,
78 minimizer: [
79 new TerserPlugin({
80 parallel: true,
81 cache: true,
82 // sourceMap: true, // Enable source maps. Please note that this will slow down the build
83 terserOptions: {
84 ecma: 6,
85 ie8: false,
86 toplevel: true,
87 module: true,
88 compress: {
89 dead_code: true,
90 warnings: false,
91 properties: true,
92 drop_debugger: true,
93 conditionals: true,
94 booleans: true,
95 loops: true,
96 unused: true,
97 toplevel: true,
98 if_return: true,
99 inline: true,
100 join_vars: true,
101 ecma: 6,
102 module: true
103 },
104 output: {
105 comments: false,
106 beautify: false,
107 indent_level: 2,
108 ecma: 6
109 },
110 mangle: {
111 module: true,
112 toplevel: true
113 }
114 }
115 }),
116 new OptimizeCSSAssetsPlugin({})
117 ]
118 },
119 plugins: [
120 new MiniCssExtractPlugin({
121 // Options similar to the same options in webpackOptions.output
122 // both options are optional
123 filename: 'content/[name].[contenthash].css',
124 chunkFilename: 'content/[id].css'
125 }),
126 new MomentLocalesPlugin({
127 localesToKeep: [
128 'hu',
129 'en'
130 // jhipster-needle-i18n-language-moment-webpack - JHipster will add/remove languages in this array
131 ]
132 }),
133 new BundleAnalyzerPlugin({
134 analyzerMode: 'static',
135 openAnalyzer: false,
136 // Webpack statistics in target folder
137 reportFilename: '../stats.html'
138 }),
139 new webpack.LoaderOptionsPlugin({
140 minimize: true,
141 debug: false
142 }),
143 new WorkboxPlugin.GenerateSW({
144 clientsClaim: true,
145 skipWaiting: true,
146 exclude: [/swagger-ui/]
147 })
148 ],
149 mode: 'production'
150 });
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/dns/honlap

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/dns/honlap

Clone this repository using git:
git clone git://git.rocketgit.com/user/dns/honlap

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main