├── .editorconfig ├── .gitattributes ├── .gitignore ├── .huskyrc ├── .jhipster ├── BloodPressure.json ├── Points.json ├── Preferences.json └── Weigth.json ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .prettierignore ├── .prettierrc ├── .yo-rc.json ├── 21-points.jh ├── Procfile ├── README.md ├── mvnw ├── mvnw.cmd ├── package-lock.json ├── package.json ├── pom.xml ├── postcss.config.js ├── src ├── main │ ├── docker │ │ ├── .dockerignore │ │ ├── Dockerfile │ │ ├── app.yml │ │ ├── elasticsearch.yml │ │ ├── entrypoint.sh │ │ ├── mysql.yml │ │ └── sonar.yml │ ├── java │ │ └── com │ │ │ └── robmelfi │ │ │ └── health │ │ │ ├── ApplicationWebXml.java │ │ │ ├── TwentyOnePointsReactApp.java │ │ │ ├── aop │ │ │ └── logging │ │ │ │ └── LoggingAspect.java │ │ │ ├── config │ │ │ ├── ApplicationProperties.java │ │ │ ├── AsyncConfiguration.java │ │ │ ├── CacheConfiguration.java │ │ │ ├── CloudDatabaseConfiguration.java │ │ │ ├── Constants.java │ │ │ ├── DatabaseConfiguration.java │ │ │ ├── DateTimeFormatConfiguration.java │ │ │ ├── DefaultProfileUtil.java │ │ │ ├── ElasticsearchConfiguration.java │ │ │ ├── JacksonConfiguration.java │ │ │ ├── LiquibaseConfiguration.java │ │ │ ├── LocaleConfiguration.java │ │ │ ├── LoggingAspectConfiguration.java │ │ │ ├── LoggingConfiguration.java │ │ │ ├── MetricsConfiguration.java │ │ │ ├── SecurityConfiguration.java │ │ │ ├── WebConfigurer.java │ │ │ ├── audit │ │ │ │ ├── AuditEventConverter.java │ │ │ │ └── package-info.java │ │ │ └── package-info.java │ │ │ ├── domain │ │ │ ├── AbstractAuditingEntity.java │ │ │ ├── Authority.java │ │ │ ├── BloodPressure.java │ │ │ ├── PersistentAuditEvent.java │ │ │ ├── Points.java │ │ │ ├── Preferences.java │ │ │ ├── User.java │ │ │ ├── Weigth.java │ │ │ ├── enumeration │ │ │ │ └── Units.java │ │ │ └── package-info.java │ │ │ ├── repository │ │ │ ├── AuthorityRepository.java │ │ │ ├── BloodPressureRepository.java │ │ │ ├── CustomAuditEventRepository.java │ │ │ ├── PersistenceAuditEventRepository.java │ │ │ ├── PointsRepository.java │ │ │ ├── PreferencesRepository.java │ │ │ ├── UserRepository.java │ │ │ ├── WeigthRepository.java │ │ │ ├── package-info.java │ │ │ └── search │ │ │ │ ├── BloodPressureSearchRepository.java │ │ │ │ ├── PointsSearchRepository.java │ │ │ │ ├── PreferencesSearchRepository.java │ │ │ │ ├── UserSearchRepository.java │ │ │ │ ├── WeigthSearchRepository.java │ │ │ │ └── package-info.java │ │ │ ├── security │ │ │ ├── AuthoritiesConstants.java │ │ │ ├── DomainUserDetailsService.java │ │ │ ├── SecurityUtils.java │ │ │ ├── SpringSecurityAuditorAware.java │ │ │ ├── UserNotActivatedException.java │ │ │ ├── jwt │ │ │ │ ├── JWTConfigurer.java │ │ │ │ ├── JWTFilter.java │ │ │ │ └── TokenProvider.java │ │ │ └── package-info.java │ │ │ ├── service │ │ │ ├── AuditEventService.java │ │ │ ├── BloodPressureService.java │ │ │ ├── MailService.java │ │ │ ├── PointsService.java │ │ │ ├── PreferencesService.java │ │ │ ├── UserService.java │ │ │ ├── WeigthService.java │ │ │ ├── dto │ │ │ │ ├── BloodPressureByPeriodDTO.java │ │ │ │ ├── BloodPressureDTO.java │ │ │ │ ├── PasswordChangeDTO.java │ │ │ │ ├── PointsDTO.java │ │ │ │ ├── PointsPerMonthDTO.java │ │ │ │ ├── PointsPerWeekDTO.java │ │ │ │ ├── PreferencesDTO.java │ │ │ │ ├── UserDTO.java │ │ │ │ ├── WeigthByPeriodDTO.java │ │ │ │ ├── WeigthDTO.java │ │ │ │ └── package-info.java │ │ │ ├── mapper │ │ │ │ ├── BloodPressureMapper.java │ │ │ │ ├── EntityMapper.java │ │ │ │ ├── PointsMapper.java │ │ │ │ ├── PreferencesMapper.java │ │ │ │ ├── UserMapper.java │ │ │ │ ├── WeigthMapper.java │ │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ └── util │ │ │ │ └── RandomUtil.java │ │ │ └── web │ │ │ └── rest │ │ │ ├── AccountResource.java │ │ │ ├── AuditResource.java │ │ │ ├── BloodPressureResource.java │ │ │ ├── LogsResource.java │ │ │ ├── PointsResource.java │ │ │ ├── PreferencesResource.java │ │ │ ├── UserJWTController.java │ │ │ ├── UserResource.java │ │ │ ├── WeigthResource.java │ │ │ ├── errors │ │ │ ├── BadRequestAlertException.java │ │ │ ├── CustomParameterizedException.java │ │ │ ├── EmailAlreadyUsedException.java │ │ │ ├── EmailNotFoundException.java │ │ │ ├── ErrorConstants.java │ │ │ ├── ExceptionTranslator.java │ │ │ ├── FieldErrorVM.java │ │ │ ├── InternalServerErrorException.java │ │ │ ├── InvalidPasswordException.java │ │ │ ├── LoginAlreadyUsedException.java │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ ├── util │ │ │ ├── HeaderUtil.java │ │ │ └── PaginationUtil.java │ │ │ └── vm │ │ │ ├── KeyAndPasswordVM.java │ │ │ ├── LoggerVM.java │ │ │ ├── LoginVM.java │ │ │ ├── ManagedUserVM.java │ │ │ └── package-info.java │ ├── jib │ │ └── entrypoint.sh │ ├── resources │ │ ├── .h2.server.properties │ │ ├── banner.txt │ │ ├── config │ │ │ ├── application-dev.yml │ │ │ ├── application-heroku.yml │ │ │ ├── application-prod.yml │ │ │ ├── application-tls.yml │ │ │ ├── application.yml │ │ │ ├── bootstrap-heroku.yml │ │ │ ├── liquibase │ │ │ │ ├── authorities.csv │ │ │ │ ├── changelog │ │ │ │ │ ├── 00000000000000_initial_schema.xml │ │ │ │ │ ├── 20181012140436_added_entity_Points.xml │ │ │ │ │ ├── 20181012140436_added_entity_constraints_Points.xml │ │ │ │ │ ├── 20181012140437_added_entity_Weigth.xml │ │ │ │ │ ├── 20181012140437_added_entity_constraints_Weigth.xml │ │ │ │ │ ├── 20181012140438_added_entity_BloodPressure.xml │ │ │ │ │ ├── 20181012140438_added_entity_constraints_BloodPressure.xml │ │ │ │ │ ├── 20181012140439_added_entity_Preferences.xml │ │ │ │ │ └── 20181012140439_added_entity_constraints_Preferences.xml │ │ │ │ ├── master.xml │ │ │ │ ├── users.csv │ │ │ │ └── users_authorities.csv │ │ │ └── tls │ │ │ │ └── keystore.p12 │ │ ├── i18n │ │ │ └── messages.properties │ │ ├── logback-spring.xml │ │ └── templates │ │ │ ├── error.html │ │ │ └── mail │ │ │ ├── activationEmail.html │ │ │ ├── creationEmail.html │ │ │ └── passwordResetEmail.html │ └── webapp │ │ ├── 404.html │ │ ├── app │ │ ├── _bootstrap-variables.scss │ │ ├── app.scss │ │ ├── app.tsx │ │ ├── config │ │ │ ├── axios-interceptor.ts │ │ │ ├── constants.ts │ │ │ ├── devtools.tsx │ │ │ ├── error-middleware.ts │ │ │ ├── icon-loader.ts │ │ │ ├── logger-middleware.ts │ │ │ ├── notification-middleware.ts │ │ │ └── store.ts │ │ ├── entities │ │ │ ├── blood-pressure │ │ │ │ ├── blood-pressure-delete-dialog.tsx │ │ │ │ ├── blood-pressure-detail.tsx │ │ │ │ ├── blood-pressure-home.tsx │ │ │ │ ├── blood-pressure-update.tsx │ │ │ │ ├── blood-pressure.reducer.ts │ │ │ │ ├── blood-pressure.tsx │ │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ ├── points │ │ │ │ ├── index.tsx │ │ │ │ ├── point.scss │ │ │ │ ├── points-delete-dialog.tsx │ │ │ │ ├── points-detail.tsx │ │ │ │ ├── points-home.tsx │ │ │ │ ├── points-update.tsx │ │ │ │ ├── points.reducer.ts │ │ │ │ └── points.tsx │ │ │ ├── preferences │ │ │ │ ├── index.tsx │ │ │ │ ├── preferences-delete-dialog.tsx │ │ │ │ ├── preferences-detail.tsx │ │ │ │ ├── preferences-update.tsx │ │ │ │ ├── preferences.reducer.ts │ │ │ │ └── preferences.tsx │ │ │ └── weigth │ │ │ │ ├── index.tsx │ │ │ │ ├── weigth-delete-dialog.tsx │ │ │ │ ├── weigth-detail.tsx │ │ │ │ ├── weigth-home.tsx │ │ │ │ ├── weigth-update.tsx │ │ │ │ ├── weigth.reducer.ts │ │ │ │ └── weigth.tsx │ │ ├── index.tsx │ │ ├── modules │ │ │ ├── about │ │ │ │ ├── about.scss │ │ │ │ └── about.tsx │ │ │ ├── account │ │ │ │ ├── activate │ │ │ │ │ ├── activate.reducer.ts │ │ │ │ │ └── activate.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── password-reset │ │ │ │ │ ├── finish │ │ │ │ │ │ └── password-reset-finish.tsx │ │ │ │ │ ├── init │ │ │ │ │ │ └── password-reset-init.tsx │ │ │ │ │ └── password-reset.reducer.ts │ │ │ │ ├── password │ │ │ │ │ ├── password.reducer.ts │ │ │ │ │ └── password.tsx │ │ │ │ ├── register │ │ │ │ │ ├── register.reducer.ts │ │ │ │ │ └── register.tsx │ │ │ │ └── settings │ │ │ │ │ ├── settings.reducer.ts │ │ │ │ │ └── settings.tsx │ │ │ ├── administration │ │ │ │ ├── administration.reducer.ts │ │ │ │ ├── audits │ │ │ │ │ └── audits.tsx │ │ │ │ ├── configuration │ │ │ │ │ └── configuration.tsx │ │ │ │ ├── docs │ │ │ │ │ └── docs.tsx │ │ │ │ ├── health │ │ │ │ │ ├── health-modal.tsx │ │ │ │ │ └── health.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── logs │ │ │ │ │ └── logs.tsx │ │ │ │ ├── metrics │ │ │ │ │ ├── metrics-modal.tsx │ │ │ │ │ ├── metrics.tsx │ │ │ │ │ └── thread-item.tsx │ │ │ │ └── user-management │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── user-management-delete-dialog.tsx │ │ │ │ │ ├── user-management-detail.tsx │ │ │ │ │ ├── user-management-update.tsx │ │ │ │ │ ├── user-management.reducer.ts │ │ │ │ │ └── user-management.tsx │ │ │ ├── history │ │ │ │ ├── CustomToolbar.js │ │ │ │ ├── history.scss │ │ │ │ └── history.tsx │ │ │ ├── home │ │ │ │ ├── home.scss │ │ │ │ └── home.tsx │ │ │ └── login │ │ │ │ ├── login-modal.tsx │ │ │ │ ├── login.tsx │ │ │ │ └── logout.tsx │ │ ├── routes.tsx │ │ ├── shared │ │ │ ├── auth │ │ │ │ └── private-route.tsx │ │ │ ├── error │ │ │ │ ├── error-boundary-route.tsx │ │ │ │ └── error-boundary.tsx │ │ │ ├── layout │ │ │ │ ├── footer │ │ │ │ │ ├── footer.scss │ │ │ │ │ └── footer.tsx │ │ │ │ ├── header │ │ │ │ │ ├── header-components.tsx │ │ │ │ │ ├── header.scss │ │ │ │ │ ├── header.tsx │ │ │ │ │ └── menus │ │ │ │ │ │ ├── account.tsx │ │ │ │ │ │ ├── admin.tsx │ │ │ │ │ │ ├── entities.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ └── password │ │ │ │ │ ├── password-strength-bar.scss │ │ │ │ │ └── password-strength-bar.tsx │ │ │ ├── model │ │ │ │ ├── blood-pressure-chart.tsx │ │ │ │ ├── blood-pressure.model.ts │ │ │ │ ├── points-this-week.model.ts │ │ │ │ ├── points.model.ts │ │ │ │ ├── preferences.model.ts │ │ │ │ ├── user.model.ts │ │ │ │ ├── weigth-chart.tsx │ │ │ │ └── weigth.model.ts │ │ │ ├── reducers │ │ │ │ ├── action-type.util.ts │ │ │ │ ├── application-profile.ts │ │ │ │ ├── authentication.ts │ │ │ │ └── index.ts │ │ │ └── util │ │ │ │ ├── date-utils.ts │ │ │ │ ├── entity-utils.ts │ │ │ │ ├── pagination.constants.ts │ │ │ │ └── url-utils.ts │ │ └── typings.d.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── manifest.webapp │ │ ├── robots.txt │ │ ├── static │ │ └── images │ │ │ ├── 21-points-logo.png │ │ │ ├── hipster.png │ │ │ ├── hipster192.png │ │ │ ├── hipster256.png │ │ │ ├── hipster2x.png │ │ │ ├── hipster384.png │ │ │ ├── hipster512.png │ │ │ ├── logo-21-points.png │ │ │ ├── logo-jhipster-react.svg │ │ │ └── logo-jhipster.png │ │ └── swagger-ui │ │ ├── dist │ │ └── images │ │ │ └── throbber.gif │ │ └── index.html └── test │ ├── java │ └── com │ │ └── robmelfi │ │ └── health │ │ ├── config │ │ ├── WebConfigurerTest.java │ │ └── WebConfigurerTestController.java │ │ ├── repository │ │ ├── CustomAuditEventRepositoryIntTest.java │ │ └── search │ │ │ ├── BloodPressureSearchRepositoryMockConfiguration.java │ │ │ ├── PointsSearchRepositoryMockConfiguration.java │ │ │ ├── PreferencesSearchRepositoryMockConfiguration.java │ │ │ ├── UserSearchRepositoryMockConfiguration.java │ │ │ └── WeigthSearchRepositoryMockConfiguration.java │ │ ├── security │ │ ├── DomainUserDetailsServiceIntTest.java │ │ ├── SecurityUtilsUnitTest.java │ │ └── jwt │ │ │ ├── JWTFilterTest.java │ │ │ └── TokenProviderTest.java │ │ ├── service │ │ ├── MailServiceIntTest.java │ │ └── UserServiceIntTest.java │ │ └── web │ │ └── rest │ │ ├── AccountResourceIntTest.java │ │ ├── AuditResourceIntTest.java │ │ ├── BloodPressureResourceIntTest.java │ │ ├── LogsResourceIntTest.java │ │ ├── PointsResourceIntTest.java │ │ ├── PreferencesResourceIntTest.java │ │ ├── TestUtil.java │ │ ├── UserJWTControllerIntTest.java │ │ ├── UserResourceIntTest.java │ │ ├── WeigthResourceIntTest.java │ │ ├── errors │ │ ├── ExceptionTranslatorIntTest.java │ │ └── ExceptionTranslatorTestController.java │ │ └── util │ │ └── PaginationUtilUnitTest.java │ ├── javascript │ ├── e2e │ │ ├── entities │ │ │ ├── blood-pressure │ │ │ │ ├── blood-pressure-update.page-object.ts │ │ │ │ ├── blood-pressure.page-object.ts │ │ │ │ └── blood-pressure.spec.ts │ │ │ ├── points │ │ │ │ ├── points-update.page-object.ts │ │ │ │ ├── points.page-object.ts │ │ │ │ └── points.spec.ts │ │ │ ├── preferences │ │ │ │ ├── preferences-update.page-object.ts │ │ │ │ ├── preferences.page-object.ts │ │ │ │ └── preferences.spec.ts │ │ │ └── weigth │ │ │ │ ├── weigth-update.page-object.ts │ │ │ │ ├── weigth.page-object.ts │ │ │ │ └── weigth.spec.ts │ │ ├── modules │ │ │ ├── account │ │ │ │ └── account.spec.ts │ │ │ └── administration │ │ │ │ └── administration.spec.ts │ │ ├── page-objects │ │ │ ├── base-component.ts │ │ │ ├── navbar-page.ts │ │ │ ├── password-page.ts │ │ │ ├── register-page.ts │ │ │ ├── settings-page.ts │ │ │ └── signin-page.ts │ │ └── util │ │ │ └── utils.ts │ ├── jest.conf.js │ ├── protractor.conf.js │ └── spec │ │ ├── app │ │ ├── config │ │ │ ├── axios-interceptor.spec.ts │ │ │ └── notification-middleware.spec.ts │ │ ├── entities │ │ │ ├── blood-pressure │ │ │ │ └── blood-pressure-reducer.spec.ts │ │ │ ├── points │ │ │ │ └── points-reducer.spec.ts │ │ │ ├── preferences │ │ │ │ └── preferences-reducer.spec.ts │ │ │ └── weigth │ │ │ │ └── weigth-reducer.spec.ts │ │ ├── modules │ │ │ ├── account │ │ │ │ ├── activate │ │ │ │ │ └── activate.reducer.spec.ts │ │ │ │ ├── password │ │ │ │ │ └── password.reducer.spec.ts │ │ │ │ ├── register │ │ │ │ │ └── register.reducer.spec.ts │ │ │ │ └── settings │ │ │ │ │ └── settings.reducer.spec.ts │ │ │ └── administration │ │ │ │ ├── administration.reducer.spec.ts │ │ │ │ └── user-management │ │ │ │ └── user-management.reducer.spec.ts │ │ ├── shared │ │ │ ├── auth │ │ │ │ └── private-route.spec.tsx │ │ │ ├── error │ │ │ │ ├── error-boundary-route.spec.tsx │ │ │ │ └── error-boundary.spec.tsx │ │ │ ├── layout │ │ │ │ └── header │ │ │ │ │ ├── header.spec.tsx │ │ │ │ │ └── menus │ │ │ │ │ └── account.spec.tsx │ │ │ ├── reducers │ │ │ │ ├── application-profile.spec.ts │ │ │ │ └── authentication.spec.ts │ │ │ └── util │ │ │ │ └── entity-utils.spec.ts │ │ └── utils.ts │ │ ├── enzyme-setup.ts │ │ └── storage-mock.ts │ └── resources │ ├── config │ └── application.yml │ ├── i18n │ └── messages_en.properties │ ├── logback.xml │ └── templates │ └── mail │ └── testEmail.html ├── tsconfig.e2e.json ├── tsconfig.json ├── tsconfig.test.json ├── tslint.json └── webpack ├── logo-jhipster.png ├── utils.js ├── webpack.common.js ├── webpack.dev.js └── webpack.prod.js /.editorconfig: -------------------------------------------------------------------------------- 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 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 4 12 | max_line_length = 180 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.{ts,tsx,js,jsx,json,css,scss,sql,ejs}] 21 | indent_style = space 22 | indent_size = 2 23 | 24 | [*.md] 25 | trim_trailing_whitespace = false 26 | -------------------------------------------------------------------------------- /.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.jhipster/BloodPressure.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BloodPressure", 3 | "fields": [ 4 | { 5 | "fieldName": "timestamp", 6 | "fieldType": "ZonedDateTime", 7 | "fieldValidateRules": [ 8 | "required" 9 | ] 10 | }, 11 | { 12 | "fieldName": "systolic", 13 | "fieldType": "Integer", 14 | "fieldValidateRules": [ 15 | "required" 16 | ] 17 | }, 18 | { 19 | "fieldName": "diastolic", 20 | "fieldType": "Integer", 21 | "fieldValidateRules": [ 22 | "required" 23 | ] 24 | } 25 | ], 26 | "relationships": [ 27 | { 28 | "relationshipType": "many-to-one", 29 | "relationshipValidateRules": "required", 30 | "relationshipName": "user", 31 | "otherEntityName": "user", 32 | "otherEntityField": "login" 33 | } 34 | ], 35 | "changelogDate": "20181012140438", 36 | "entityTableName": "blood_pressure", 37 | "dto": "mapstruct", 38 | "pagination": "infinite-scroll", 39 | "service": "serviceClass", 40 | "jpaMetamodelFiltering": false, 41 | "fluentMethods": true, 42 | "clientRootFolder": "", 43 | "applications": "*" 44 | } -------------------------------------------------------------------------------- /.jhipster/Points.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Points", 3 | "fields": [ 4 | { 5 | "fieldName": "date", 6 | "fieldType": "LocalDate", 7 | "fieldValidateRules": [ 8 | "required" 9 | ] 10 | }, 11 | { 12 | "fieldName": "excercise", 13 | "fieldType": "Integer" 14 | }, 15 | { 16 | "fieldName": "meals", 17 | "fieldType": "Integer" 18 | }, 19 | { 20 | "fieldName": "alcohol", 21 | "fieldType": "Integer" 22 | }, 23 | { 24 | "fieldName": "notes", 25 | "fieldType": "String", 26 | "fieldValidateRules": [ 27 | "maxlength" 28 | ], 29 | "fieldValidateRulesMaxlength": 140 30 | } 31 | ], 32 | "relationships": [ 33 | { 34 | "relationshipType": "many-to-one", 35 | "relationshipValidateRules": "required", 36 | "relationshipName": "user", 37 | "otherEntityName": "user", 38 | "otherEntityField": "login" 39 | } 40 | ], 41 | "changelogDate": "20181012140436", 42 | "entityTableName": "points", 43 | "dto": "mapstruct", 44 | "pagination": "pagination", 45 | "service": "serviceClass", 46 | "jpaMetamodelFiltering": false, 47 | "fluentMethods": true, 48 | "clientRootFolder": "", 49 | "applications": "*" 50 | } -------------------------------------------------------------------------------- /.jhipster/Preferences.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Preferences", 3 | "fields": [ 4 | { 5 | "fieldName": "weeklyGoal", 6 | "fieldType": "Integer", 7 | "fieldValidateRules": [ 8 | "required", 9 | "min", 10 | "max" 11 | ], 12 | "fieldValidateRulesMin": 10, 13 | "fieldValidateRulesMax": 21 14 | }, 15 | { 16 | "fieldName": "weightUnits", 17 | "fieldType": "Units", 18 | "fieldValues": "KG,LB", 19 | "fieldValidateRules": [ 20 | "required" 21 | ] 22 | } 23 | ], 24 | "relationships": [ 25 | { 26 | "relationshipType": "one-to-one", 27 | "relationshipName": "user", 28 | "otherEntityName": "user", 29 | "otherEntityField": "login", 30 | "ownerSide": true, 31 | "otherEntityRelationshipName": "preferences" 32 | } 33 | ], 34 | "changelogDate": "20181012140439", 35 | "entityTableName": "preferences", 36 | "dto": "mapstruct", 37 | "pagination": "no", 38 | "service": "serviceClass", 39 | "jpaMetamodelFiltering": false, 40 | "fluentMethods": true, 41 | "clientRootFolder": "", 42 | "applications": "*" 43 | } -------------------------------------------------------------------------------- /.jhipster/Weigth.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Weigth", 3 | "fields": [ 4 | { 5 | "fieldName": "timestamp", 6 | "fieldType": "ZonedDateTime", 7 | "fieldValidateRules": [ 8 | "required" 9 | ] 10 | }, 11 | { 12 | "fieldName": "weight", 13 | "fieldType": "Double", 14 | "fieldValidateRules": [ 15 | "required" 16 | ] 17 | } 18 | ], 19 | "relationships": [ 20 | { 21 | "relationshipType": "many-to-one", 22 | "relationshipValidateRules": "required", 23 | "relationshipName": "user", 24 | "otherEntityName": "user", 25 | "otherEntityField": "login" 26 | } 27 | ], 28 | "changelogDate": "20181012140437", 29 | "entityTableName": "weigth", 30 | "dto": "mapstruct", 31 | "pagination": "infinite-scroll", 32 | "service": "serviceClass", 33 | "jpaMetamodelFiltering": false, 34 | "fluentMethods": true, 35 | "clientRootFolder": "", 36 | "applications": "*" 37 | } -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robmelfi/21-points-react/a310a2762d7ddab3440588dbe3dcb22c338823ed/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | target 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-jhipster": { 3 | "promptValues": { 4 | "packageName": "com.robmelfi.health" 5 | }, 6 | "jhipsterVersion": "5.4.1", 7 | "applicationType": "monolith", 8 | "baseName": "TwentyOnePointsReact", 9 | "packageName": "com.robmelfi.health", 10 | "packageFolder": "com/robmelfi/health", 11 | "serverPort": "8080", 12 | "authenticationType": "jwt", 13 | "cacheProvider": "ehcache", 14 | "enableHibernateCache": true, 15 | "websocket": false, 16 | "databaseType": "sql", 17 | "devDatabaseType": "h2Disk", 18 | "prodDatabaseType": "mysql", 19 | "searchEngine": "elasticsearch", 20 | "messageBroker": false, 21 | "serviceDiscoveryType": false, 22 | "buildTool": "maven", 23 | "enableSwaggerCodegen": false, 24 | "jwtSecretKey": "MjExZTE1MjEzMzQwM2JiMmU2ZjgzOWE3YzFhMjAxZjA2NTUxZDQ1N2MzYzI1ZjE0ZTRhMjExZWEyYjI3YmE5OThhNzYzNTNlNzhhMDE1YzRiNGYwZDNkMGE1ZjViNzQ0MTU1ZWJiMmM5ZjY1NDVkOTg3ZDg0OTNkMzNmYTBkYTk=", 25 | "clientFramework": "react", 26 | "useSass": true, 27 | "clientPackageManager": "npm", 28 | "testFrameworks": [ 29 | "protractor" 30 | ], 31 | "jhiPrefix": "jhi", 32 | "enableTranslation": false, 33 | "herokuAppName": "twentyone-points-react", 34 | "herokuDeployType": "git" 35 | } 36 | } -------------------------------------------------------------------------------- /21-points.jh: -------------------------------------------------------------------------------- 1 | 2 | entity Points { 3 | date LocalDate required 4 | excercise Integer 5 | meals Integer 6 | alcohol Integer 7 | notes String maxlength(140) 8 | } 9 | 10 | entity Weigth { 11 | timestamp ZonedDateTime required 12 | weight Double required 13 | } 14 | 15 | entity BloodPressure { 16 | timestamp ZonedDateTime required 17 | systolic Integer required 18 | diastolic Integer required 19 | } 20 | 21 | enum Units { 22 | KG, LB 23 | } 24 | 25 | entity Preferences { 26 | weeklyGoal Integer required min(10) max(21) 27 | weightUnits Units required 28 | } 29 | 30 | relationship OneToOne { 31 | Preferences { user(login) } to User 32 | } 33 | 34 | relationship ManyToOne { 35 | Points { user(login) required } to User 36 | Weigth { user(login) required } to User 37 | BloodPressure { user(login) required } to User 38 | } 39 | 40 | dto * with mapstruct 41 | service * with serviceClass 42 | paginate Points with pagination 43 | paginate BloodPressure, Weigth with infinite-scroll 44 | 45 | 46 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: java $JAVA_OPTS -Xmx256m -jar target/*.war --spring.profiles.active=prod,heroku,no-liquibase --server.port=$PORT 2 | release: cp -R src/main/resources/config config && ./mvnw liquibase:update -Pheroku 3 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [] 3 | }; 4 | -------------------------------------------------------------------------------- /src/main/docker/.dockerignore: -------------------------------------------------------------------------------- 1 | # https://docs.docker.com/engine/reference/builder/#dockerignore-file 2 | classes/ 3 | generated-sources/ 4 | generated-test-sources/ 5 | h2db/ 6 | maven-archiver/ 7 | maven-status/ 8 | reports/ 9 | surefire-reports/ 10 | test-classes/ 11 | test-results/ 12 | www/ 13 | !*.jar 14 | !*.war 15 | -------------------------------------------------------------------------------- /src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | 3 | ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \ 4 | JHIPSTER_SLEEP=0 \ 5 | JAVA_OPTS="" 6 | 7 | # Add a jhipster user to run our application so that it doesn't need to run as root 8 | RUN adduser -D -s /bin/sh jhipster 9 | WORKDIR /home/jhipster 10 | 11 | ADD entrypoint.sh entrypoint.sh 12 | RUN chmod 755 entrypoint.sh && chown jhipster:jhipster entrypoint.sh 13 | USER jhipster 14 | 15 | ENTRYPOINT ["./entrypoint.sh"] 16 | 17 | EXPOSE 8080 18 | 19 | ADD *.war app.war 20 | 21 | -------------------------------------------------------------------------------- /src/main/docker/app.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | twentyonepointsreact-app: 4 | image: twentyonepointsreact 5 | environment: 6 | # - _JAVA_OPTIONS=-Xmx512m -Xms256m 7 | - SPRING_PROFILES_ACTIVE=prod,swagger 8 | - SPRING_DATASOURCE_URL=jdbc:mysql://twentyonepointsreact-mysql:3306/twentyonepointsreact?useUnicode=true&characterEncoding=utf8&useSSL=false 9 | - JHIPSTER_SLEEP=10 # gives time for the database to boot before the application 10 | - SPRING_DATA_JEST_URI=http://twentyonepointsreact-elasticsearch:9200 11 | ports: 12 | - 8080:8080 13 | twentyonepointsreact-mysql: 14 | extends: 15 | file: mysql.yml 16 | service: twentyonepointsreact-mysql 17 | twentyonepointsreact-elasticsearch: 18 | extends: 19 | file: elasticsearch.yml 20 | service: twentyonepointsreact-elasticsearch 21 | -------------------------------------------------------------------------------- /src/main/docker/elasticsearch.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | twentyonepointsreact-elasticsearch: 4 | image: elasticsearch:5.6.5 5 | # volumes: 6 | # - ~/volumes/jhipster/TwentyOnePointsReact/elasticsearch/:/usr/share/elasticsearch/data/ 7 | ports: 8 | - 9200:9200 9 | - 9300:9300 10 | command: -Enetwork.host=0.0.0.0 -Ediscovery.type=single-node 11 | environment: 12 | - "ES_JAVA_OPTS=-Xms512m -Xmx512m" 13 | -------------------------------------------------------------------------------- /src/main/docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP} 4 | exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar "${HOME}/app.war" "$@" 5 | -------------------------------------------------------------------------------- /src/main/docker/mysql.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | twentyonepointsreact-mysql: 4 | image: mysql:5.7.20 5 | # volumes: 6 | # - ~/volumes/jhipster/TwentyOnePointsReact/mysql/:/var/lib/mysql/ 7 | environment: 8 | - MYSQL_USER=root 9 | - MYSQL_ALLOW_EMPTY_PASSWORD=yes 10 | - MYSQL_DATABASE=twentyonepointsreact 11 | ports: 12 | - 3306:3306 13 | command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8mb4 --explicit_defaults_for_timestamp 14 | -------------------------------------------------------------------------------- /src/main/docker/sonar.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | twentyonepointsreact-sonar: 4 | image: sonarqube:7.1-alpine 5 | ports: 6 | - 9001:9000 7 | - 9092:9092 8 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/ApplicationWebXml.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health; 2 | 3 | import com.robmelfi.health.config.DefaultProfileUtil; 4 | import org.springframework.boot.builder.SpringApplicationBuilder; 5 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 6 | 7 | /** 8 | * This is a helper Java class that provides an alternative to creating a web.xml. 9 | * This will be invoked only when the application is deployed to a Servlet container like Tomcat, JBoss etc. 10 | */ 11 | public class ApplicationWebXml extends SpringBootServletInitializer { 12 | 13 | @Override 14 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 15 | /** 16 | * set a default to use when no profile is configured. 17 | */ 18 | DefaultProfileUtil.addDefaultProfile(application.application()); 19 | return application.sources(TwentyOnePointsReactApp.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/ApplicationProperties.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.config; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * Properties specific to Twenty One Points React. 7 | *

8 | * Properties are configured in the 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 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/CloudDatabaseConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | 12 | @Configuration 13 | @Profile(JHipsterConstants.SPRING_PROFILE_CLOUD) 14 | public class CloudDatabaseConfiguration extends AbstractCloudConfig { 15 | 16 | private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class); 17 | 18 | @Bean 19 | public DataSource dataSource() { 20 | log.info("Configuring JDBC datasource from a cloud provider"); 21 | return connectionFactory().dataSource(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/Constants.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 ANONYMOUS_USER = "anonymoususer"; 13 | public static final String DEFAULT_LANGUAGE = "en"; 14 | 15 | private Constants() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/DatabaseConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; 11 | 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("com.robmelfi.health.repository") 20 | @EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware") 21 | @EnableTransactionManagement 22 | @EnableElasticsearchRepositories("com.robmelfi.health.repository.search") 23 | public class DatabaseConfiguration { 24 | 25 | private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class); 26 | 27 | 28 | /** 29 | * Open the TCP port for the H2 database, so it is available remotely. 30 | * 31 | * @return the H2 database TCP server 32 | * @throws SQLException if the server failed to start 33 | */ 34 | @Bean(initMethod = "start", destroyMethod = "stop") 35 | @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) 36 | public Object h2TCPServer() throws SQLException { 37 | log.debug("Starting H2 database"); 38 | return H2ConfigurationHelper.createServer(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/DateTimeFormatConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/DefaultProfileUtil.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.config; 2 | 3 | import io.github.jhipster.config.JHipsterConstants; 4 | 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.core.env.Environment; 7 | 8 | import java.util.*; 9 | 10 | /** 11 | * Utility class to load a Spring profile to be used as default 12 | * when there is no spring.profiles.active set in the environment or as command line argument. 13 | * If the value is not available in application.yml then dev profile will be used as default. 14 | */ 15 | public final class DefaultProfileUtil { 16 | 17 | private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default"; 18 | 19 | private DefaultProfileUtil() { 20 | } 21 | 22 | /** 23 | * Set a default to use when no profile is configured. 24 | * 25 | * @param app the Spring application 26 | */ 27 | public static void addDefaultProfile(SpringApplication app) { 28 | Map defProperties = new HashMap<>(); 29 | /* 30 | * The default profile to use when no other profiles are defined 31 | * This cannot be set in the application.yml file. 32 | * See https://github.com/spring-projects/spring-boot/issues/1219 33 | */ 34 | defProperties.put(SPRING_PROFILE_DEFAULT, JHipsterConstants.SPRING_PROFILE_DEVELOPMENT); 35 | app.setDefaultProperties(defProperties); 36 | } 37 | 38 | /** 39 | * Get the profiles that are applied else get default profiles. 40 | * 41 | * @param env spring environment 42 | * @return profiles 43 | */ 44 | public static String[] getActiveProfiles(Environment env) { 45 | String[] profiles = env.getActiveProfiles(); 46 | if (profiles.length == 0) { 47 | return env.getDefaultProfiles(); 48 | } 49 | return profiles; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/JacksonConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | /* 32 | * Support for Hibernate types in Jackson. 33 | */ 34 | @Bean 35 | public Hibernate5Module hibernate5Module() { 36 | return new Hibernate5Module(); 37 | } 38 | 39 | /* 40 | * Jackson Afterburner module to speed up serialization/deserialization. 41 | */ 42 | @Bean 43 | public AfterburnerModule afterburnerModule() { 44 | return new AfterburnerModule(); 45 | } 46 | 47 | /* 48 | * Module for serialization/deserialization of RFC7807 Problem. 49 | */ 50 | @Bean 51 | ProblemModule problemModule() { 52 | return new ProblemModule(); 53 | } 54 | 55 | /* 56 | * Module for serialization/deserialization of ConstraintViolationProblem. 57 | */ 58 | @Bean 59 | ConstraintViolationProblemModule constraintViolationProblemModule() { 60 | return new ConstraintViolationProblemModule(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/LocaleConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/LoggingAspectConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.config; 2 | 3 | import com.robmelfi.health.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 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/audit/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Audit specific code. 3 | */ 4 | package com.robmelfi.health.config.audit; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/config/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Framework configuration files. 3 | */ 4 | package com.robmelfi.health.config; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/domain/Authority.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | 13 | /** 14 | * An authority (a security role) used by Spring Security. 15 | */ 16 | @Entity 17 | @Table(name = "jhi_authority") 18 | @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 19 | public class Authority implements Serializable { 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | @NotNull 24 | @Size(max = 50) 25 | @Id 26 | @Column(length = 50) 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | @Override 38 | public boolean equals(Object o) { 39 | if (this == o) { 40 | return true; 41 | } 42 | if (o == null || getClass() != o.getClass()) { 43 | return false; 44 | } 45 | 46 | Authority authority = (Authority) o; 47 | 48 | return !(name != null ? !name.equals(authority.name) : authority.name != null); 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | return name != null ? name.hashCode() : 0; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | return "Authority{" + 59 | "name='" + name + '\'' + 60 | "}"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/domain/PersistentAuditEvent.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 = "jhi_persistent_audit_event") 17 | public class PersistentAuditEvent implements Serializable { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | @Column(name = "event_id") 24 | private Long id; 25 | 26 | @NotNull 27 | @Column(nullable = false) 28 | private String principal; 29 | 30 | @Column(name = "event_date") 31 | private Instant auditEventDate; 32 | 33 | @Column(name = "event_type") 34 | private String auditEventType; 35 | 36 | @ElementCollection 37 | @MapKeyColumn(name = "name") 38 | @Column(name = "value") 39 | @CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id")) 40 | private Map data = new HashMap<>(); 41 | 42 | public Long getId() { 43 | return id; 44 | } 45 | 46 | public void setId(Long id) { 47 | this.id = id; 48 | } 49 | 50 | public String getPrincipal() { 51 | return principal; 52 | } 53 | 54 | public void setPrincipal(String principal) { 55 | this.principal = principal; 56 | } 57 | 58 | public Instant getAuditEventDate() { 59 | return auditEventDate; 60 | } 61 | 62 | public void setAuditEventDate(Instant auditEventDate) { 63 | this.auditEventDate = auditEventDate; 64 | } 65 | 66 | public String getAuditEventType() { 67 | return auditEventType; 68 | } 69 | 70 | public void setAuditEventType(String auditEventType) { 71 | this.auditEventType = auditEventType; 72 | } 73 | 74 | public Map getData() { 75 | return data; 76 | } 77 | 78 | public void setData(Map data) { 79 | this.data = data; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/domain/enumeration/Units.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.domain.enumeration; 2 | 3 | /** 4 | * The Units enumeration. 5 | */ 6 | public enum Units { 7 | KG, LB 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/domain/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JPA domain objects. 3 | */ 4 | package com.robmelfi.health.domain; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/AuthorityRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository; 2 | 3 | import com.robmelfi.health.domain.Authority; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * Spring Data JPA repository for the Authority entity. 9 | */ 10 | public interface AuthorityRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/BloodPressureRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository; 2 | 3 | import com.robmelfi.health.domain.BloodPressure; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.*; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.time.ZonedDateTime; 10 | import java.util.List; 11 | 12 | /** 13 | * Spring Data repository for the BloodPressure entity. 14 | */ 15 | @SuppressWarnings("unused") 16 | @Repository 17 | public interface BloodPressureRepository extends JpaRepository { 18 | 19 | @Query("select blood_pressure from BloodPressure blood_pressure where blood_pressure.user.login = ?#{principal.username} order by blood_pressure.timestamp desc") 20 | Page findByUserIsCurrentUser(Pageable pageable); 21 | 22 | Page findAllByOrderByTimestampDesc(Pageable pageable); 23 | 24 | List findAllByTimestampBetweenOrderByTimestampDesc(ZonedDateTime firstDate, ZonedDateTime secondDate); 25 | 26 | List findAllByTimestampBetweenAndUserLoginOrderByTimestampDesc(ZonedDateTime firstDate, ZonedDateTime secondDate, String login); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/PersistenceAuditEventRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository; 2 | 3 | import com.robmelfi.health.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 PersistentAuditEvent entity. 13 | */ 14 | public interface PersistenceAuditEventRepository extends JpaRepository { 15 | 16 | List findByPrincipal(String principal); 17 | 18 | List findByAuditEventDateAfter(Instant after); 19 | 20 | List findByPrincipalAndAuditEventDateAfter(String principal, Instant after); 21 | 22 | List findByPrincipalAndAuditEventDateAfterAndAuditEventType(String principal, Instant after, String type); 23 | 24 | Page findAllByAuditEventDateBetween(Instant fromDate, Instant toDate, Pageable pageable); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/PointsRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository; 2 | 3 | import com.robmelfi.health.domain.Points; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.*; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | /** 13 | * Spring Data repository for the Points entity. 14 | */ 15 | @SuppressWarnings("unused") 16 | @Repository 17 | public interface PointsRepository extends JpaRepository { 18 | 19 | @Query("select points from Points points where points.user.login = ?#{principal.username} order by points.date desc") 20 | Page findByUserIsCurrentUser(Pageable pageable); 21 | 22 | Page findAllByOrderByDateDesc(Pageable pageable); 23 | 24 | List findAllByDateBetweenAndUserLogin(LocalDate fierstDate, LocalDate secondDate, String user); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/PreferencesRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository; 2 | 3 | import com.robmelfi.health.domain.Preferences; 4 | import org.springframework.data.jpa.repository.*; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.Optional; 8 | 9 | 10 | /** 11 | * Spring Data repository for the Preferences entity. 12 | */ 13 | @SuppressWarnings("unused") 14 | @Repository 15 | public interface PreferencesRepository extends JpaRepository { 16 | Optional findOneByUserLogin(String login); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository; 2 | 3 | import com.robmelfi.health.domain.User; 4 | 5 | import org.springframework.cache.annotation.Cacheable; 6 | import org.springframework.data.domain.Page; 7 | import org.springframework.data.domain.Pageable; 8 | import org.springframework.data.jpa.repository.EntityGraph; 9 | import org.springframework.data.jpa.repository.JpaRepository; 10 | import org.springframework.stereotype.Repository; 11 | import java.util.List; 12 | import java.util.Optional; 13 | import java.time.Instant; 14 | 15 | /** 16 | * Spring Data JPA repository for the User entity. 17 | */ 18 | @Repository 19 | public interface UserRepository extends JpaRepository { 20 | 21 | String USERS_BY_LOGIN_CACHE = "usersByLogin"; 22 | 23 | String USERS_BY_EMAIL_CACHE = "usersByEmail"; 24 | 25 | Optional findOneByActivationKey(String activationKey); 26 | 27 | List findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime); 28 | 29 | Optional findOneByResetKey(String resetKey); 30 | 31 | Optional findOneByEmailIgnoreCase(String email); 32 | 33 | Optional findOneByLogin(String login); 34 | 35 | @EntityGraph(attributePaths = "authorities") 36 | Optional findOneWithAuthoritiesById(Long id); 37 | 38 | @EntityGraph(attributePaths = "authorities") 39 | @Cacheable(cacheNames = USERS_BY_LOGIN_CACHE) 40 | Optional findOneWithAuthoritiesByLogin(String login); 41 | 42 | @EntityGraph(attributePaths = "authorities") 43 | @Cacheable(cacheNames = USERS_BY_EMAIL_CACHE) 44 | Optional findOneWithAuthoritiesByEmail(String email); 45 | 46 | Page findAllByLoginNot(Pageable pageable, String login); 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/WeigthRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository; 2 | 3 | import com.robmelfi.health.domain.Weigth; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.*; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.time.ZonedDateTime; 10 | import java.util.List; 11 | 12 | /** 13 | * Spring Data repository for the Weigth entity. 14 | */ 15 | @SuppressWarnings("unused") 16 | @Repository 17 | public interface WeigthRepository extends JpaRepository { 18 | 19 | @Query("select weigth from Weigth weigth where weigth.user.login = ?#{principal.username} order by weight.timestamp desc") 20 | Page findByUserIsCurrentUser(Pageable pageable); 21 | 22 | Page findAllByOrderByTimestampDesc(Pageable pageable); 23 | 24 | List findAllByTimestampBetweenOrderByTimestampDesc(ZonedDateTime firstDate, ZonedDateTime secondDate); 25 | 26 | List findAllByTimestampBetweenAndUserLoginOrderByTimestampDesc(ZonedDateTime firstDate, ZonedDateTime secondDate, String login); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Data JPA repositories. 3 | */ 4 | package com.robmelfi.health.repository; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/search/BloodPressureSearchRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository.search; 2 | 3 | import com.robmelfi.health.domain.BloodPressure; 4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 | 6 | /** 7 | * Spring Data Elasticsearch repository for the BloodPressure entity. 8 | */ 9 | public interface BloodPressureSearchRepository extends ElasticsearchRepository { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/search/PointsSearchRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository.search; 2 | 3 | import com.robmelfi.health.domain.Points; 4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 | 6 | /** 7 | * Spring Data Elasticsearch repository for the Points entity. 8 | */ 9 | public interface PointsSearchRepository extends ElasticsearchRepository { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/search/PreferencesSearchRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository.search; 2 | 3 | import com.robmelfi.health.domain.Preferences; 4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 | 6 | /** 7 | * Spring Data Elasticsearch repository for the Preferences entity. 8 | */ 9 | public interface PreferencesSearchRepository extends ElasticsearchRepository { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/search/UserSearchRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository.search; 2 | 3 | import com.robmelfi.health.domain.User; 4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 | 6 | /** 7 | * Spring Data Elasticsearch repository for the User entity. 8 | */ 9 | public interface UserSearchRepository extends ElasticsearchRepository { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/search/WeigthSearchRepository.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.repository.search; 2 | 3 | import com.robmelfi.health.domain.Weigth; 4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 5 | 6 | /** 7 | * Spring Data Elasticsearch repository for the Weigth entity. 8 | */ 9 | public interface WeigthSearchRepository extends ElasticsearchRepository { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/repository/search/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Data Elasticsearch repositories. 3 | */ 4 | package com.robmelfi.health.repository.search; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/security/AuthoritiesConstants.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/security/SpringSecurityAuditorAware.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.security; 2 | 3 | import com.robmelfi.health.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 AuditorAware based on Spring Security. 12 | */ 13 | @Component 14 | public class SpringSecurityAuditorAware implements AuditorAware { 15 | 16 | @Override 17 | public Optional getCurrentAuditor() { 18 | return Optional.of(SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM_ACCOUNT)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/security/UserNotActivatedException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/security/jwt/JWTConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 { 9 | 10 | private TokenProvider tokenProvider; 11 | 12 | public JWTConfigurer(TokenProvider tokenProvider) { 13 | this.tokenProvider = tokenProvider; 14 | } 15 | 16 | @Override 17 | public void configure(HttpSecurity http) throws Exception { 18 | JWTFilter customFilter = new JWTFilter(tokenProvider); 19 | http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/security/jwt/JWTFilter.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 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, bearerToken.length()); 45 | } 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/security/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Security configuration. 3 | */ 4 | package com.robmelfi.health.security; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/AuditEventService.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service; 2 | 3 | import com.robmelfi.health.config.audit.AuditEventConverter; 4 | import com.robmelfi.health.repository.PersistenceAuditEventRepository; 5 | import org.springframework.boot.actuate.audit.AuditEvent; 6 | import org.springframework.data.domain.Page; 7 | import org.springframework.data.domain.Pageable; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import java.time.Instant; 12 | import java.util.Optional; 13 | 14 | /** 15 | * Service for managing audit events. 16 | *

17 | * This is the default implementation to support SpringBoot Actuator AuditEventRepository 18 | */ 19 | @Service 20 | @Transactional 21 | public class AuditEventService { 22 | 23 | private final PersistenceAuditEventRepository persistenceAuditEventRepository; 24 | 25 | private final AuditEventConverter auditEventConverter; 26 | 27 | public AuditEventService( 28 | PersistenceAuditEventRepository persistenceAuditEventRepository, 29 | AuditEventConverter auditEventConverter) { 30 | 31 | this.persistenceAuditEventRepository = persistenceAuditEventRepository; 32 | this.auditEventConverter = auditEventConverter; 33 | } 34 | 35 | public Page findAll(Pageable pageable) { 36 | return persistenceAuditEventRepository.findAll(pageable) 37 | .map(auditEventConverter::convertToAuditEvent); 38 | } 39 | 40 | public Page findByDates(Instant fromDate, Instant toDate, Pageable pageable) { 41 | return persistenceAuditEventRepository.findAllByAuditEventDateBetween(fromDate, toDate, pageable) 42 | .map(auditEventConverter::convertToAuditEvent); 43 | } 44 | 45 | public Optional find(Long id) { 46 | return Optional.ofNullable(persistenceAuditEventRepository.findById(id)) 47 | .filter(Optional::isPresent) 48 | .map(Optional::get) 49 | .map(auditEventConverter::convertToAuditEvent); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/dto/BloodPressureByPeriodDTO.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.dto; 2 | 3 | import com.robmelfi.health.domain.BloodPressure; 4 | 5 | import java.util.List; 6 | 7 | public class BloodPressureByPeriodDTO { 8 | private String period; 9 | private List readings; 10 | 11 | public BloodPressureByPeriodDTO(String period, List readings) { 12 | this.period = period; 13 | this.readings = readings; 14 | } 15 | 16 | public String getPeriod() { 17 | return period; 18 | } 19 | 20 | public void setPeriod(String period) { 21 | this.period = period; 22 | } 23 | 24 | public List getReadings() { 25 | return readings; 26 | } 27 | 28 | public void setReadings(List readings) { 29 | this.readings = readings; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "BloodPressureByPeriod{" + 35 | "period='" + period + '\'' + 36 | ", readings=" + readings + 37 | '}'; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/dto/PasswordChangeDTO.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/dto/PointsPerMonthDTO.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.dto; 2 | 3 | import com.robmelfi.health.domain.Points; 4 | 5 | import java.time.YearMonth; 6 | import java.util.List; 7 | 8 | public class PointsPerMonthDTO { 9 | private YearMonth month; 10 | private List points; 11 | 12 | public PointsPerMonthDTO(YearMonth yearWithMonth, List points) { 13 | this.month = yearWithMonth; 14 | this.points = points; 15 | } 16 | 17 | public YearMonth getMonth() { 18 | return month; 19 | } 20 | 21 | public void setMonth(YearMonth month) { 22 | this.month = month; 23 | } 24 | 25 | public List getPoints() { 26 | return points; 27 | } 28 | 29 | public void setPoints(List points) { 30 | this.points = points; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return "PointsPerMonth{" + 36 | "month=" + month + 37 | ", points=" + points + 38 | '}'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/dto/PointsPerWeekDTO.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.dto; 2 | 3 | import java.time.LocalDate; 4 | 5 | public class PointsPerWeekDTO { 6 | private LocalDate week; 7 | private Integer points; 8 | 9 | public PointsPerWeekDTO(LocalDate week, Integer points) { 10 | this.week = week; 11 | this.points = points; 12 | } 13 | 14 | public LocalDate getWeek() { 15 | return week; 16 | } 17 | 18 | public void setWeek(LocalDate week) { 19 | this.week = week; 20 | } 21 | 22 | public Integer getPoints() { 23 | return points; 24 | } 25 | 26 | public void setPoints(Integer points) { 27 | this.points = points; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "PointsThisWeek{" + 33 | "points=" + points + 34 | ", week=" + week + 35 | "}"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/dto/WeigthByPeriodDTO.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.dto; 2 | 3 | import com.robmelfi.health.domain.Weigth; 4 | 5 | import java.util.List; 6 | 7 | public class WeigthByPeriodDTO { 8 | private String period; 9 | private List weighIns; 10 | 11 | public WeigthByPeriodDTO(String period, List weighIns) { 12 | this.period = period; 13 | this.weighIns = weighIns; 14 | } 15 | 16 | public String getPeriod() { 17 | return period; 18 | } 19 | 20 | public void setPeriod(String period) { 21 | this.period = period; 22 | } 23 | 24 | public List getWeighIns() { 25 | return weighIns; 26 | } 27 | 28 | public void setWeighIns(List weighIns) { 29 | this.weighIns = weighIns; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "WeightByPeriod{" + 35 | "period='" + period + '\'' + 36 | ", weighIns=" + weighIns + 37 | '}'; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/dto/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Data Transfer Objects. 3 | */ 4 | package com.robmelfi.health.service.dto; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/mapper/BloodPressureMapper.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.mapper; 2 | 3 | import com.robmelfi.health.domain.*; 4 | import com.robmelfi.health.service.dto.BloodPressureDTO; 5 | 6 | import org.mapstruct.*; 7 | 8 | /** 9 | * Mapper for the entity BloodPressure and its DTO BloodPressureDTO. 10 | */ 11 | @Mapper(componentModel = "spring", uses = {UserMapper.class}) 12 | public interface BloodPressureMapper extends EntityMapper { 13 | 14 | @Mapping(source = "user.id", target = "userId") 15 | @Mapping(source = "user.login", target = "userLogin") 16 | BloodPressureDTO toDto(BloodPressure bloodPressure); 17 | 18 | @Mapping(source = "userId", target = "user") 19 | BloodPressure toEntity(BloodPressureDTO bloodPressureDTO); 20 | 21 | default BloodPressure fromId(Long id) { 22 | if (id == null) { 23 | return null; 24 | } 25 | BloodPressure bloodPressure = new BloodPressure(); 26 | bloodPressure.setId(id); 27 | return bloodPressure; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/mapper/EntityMapper.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.mapper; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Contract for a generic dto to entity mapper. 7 | * 8 | * @param - DTO type parameter. 9 | * @param - Entity type parameter. 10 | */ 11 | 12 | public interface EntityMapper { 13 | 14 | E toEntity(D dto); 15 | 16 | D toDto(E entity); 17 | 18 | List toEntity(List dtoList); 19 | 20 | List toDto(List entityList); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/mapper/PointsMapper.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.mapper; 2 | 3 | import com.robmelfi.health.domain.*; 4 | import com.robmelfi.health.service.dto.PointsDTO; 5 | 6 | import org.mapstruct.*; 7 | 8 | /** 9 | * Mapper for the entity Points and its DTO PointsDTO. 10 | */ 11 | @Mapper(componentModel = "spring", uses = {UserMapper.class}) 12 | public interface PointsMapper extends EntityMapper { 13 | 14 | @Mapping(source = "user.id", target = "userId") 15 | @Mapping(source = "user.login", target = "userLogin") 16 | PointsDTO toDto(Points points); 17 | 18 | @Mapping(source = "userId", target = "user") 19 | Points toEntity(PointsDTO pointsDTO); 20 | 21 | default Points fromId(Long id) { 22 | if (id == null) { 23 | return null; 24 | } 25 | Points points = new Points(); 26 | points.setId(id); 27 | return points; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/mapper/PreferencesMapper.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.mapper; 2 | 3 | import com.robmelfi.health.domain.*; 4 | import com.robmelfi.health.service.dto.PreferencesDTO; 5 | 6 | import org.mapstruct.*; 7 | 8 | /** 9 | * Mapper for the entity Preferences and its DTO PreferencesDTO. 10 | */ 11 | @Mapper(componentModel = "spring", uses = {UserMapper.class}) 12 | public interface PreferencesMapper extends EntityMapper { 13 | 14 | @Mapping(source = "user.id", target = "userId") 15 | @Mapping(source = "user.login", target = "userLogin") 16 | PreferencesDTO toDto(Preferences preferences); 17 | 18 | @Mapping(source = "userId", target = "user") 19 | Preferences toEntity(PreferencesDTO preferencesDTO); 20 | 21 | default Preferences fromId(Long id) { 22 | if (id == null) { 23 | return null; 24 | } 25 | Preferences preferences = new Preferences(); 26 | preferences.setId(id); 27 | return preferences; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/mapper/WeigthMapper.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.mapper; 2 | 3 | import com.robmelfi.health.domain.*; 4 | import com.robmelfi.health.service.dto.WeigthDTO; 5 | 6 | import org.mapstruct.*; 7 | 8 | /** 9 | * Mapper for the entity Weigth and its DTO WeigthDTO. 10 | */ 11 | @Mapper(componentModel = "spring", uses = {UserMapper.class}) 12 | public interface WeigthMapper extends EntityMapper { 13 | 14 | @Mapping(source = "user.id", target = "userId") 15 | @Mapping(source = "user.login", target = "userLogin") 16 | WeigthDTO toDto(Weigth weigth); 17 | 18 | @Mapping(source = "userId", target = "user") 19 | Weigth toEntity(WeigthDTO weigthDTO); 20 | 21 | default Weigth fromId(Long id) { 22 | if (id == null) { 23 | return null; 24 | } 25 | Weigth weigth = new Weigth(); 26 | weigth.setId(id); 27 | return weigth; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/mapper/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MapStruct mappers for mapping domain objects and Data Transfer Objects. 3 | */ 4 | package com.robmelfi.health.service.mapper; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Service layer beans. 3 | */ 4 | package com.robmelfi.health.service; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/service/util/RandomUtil.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.service.util; 2 | 3 | import org.apache.commons.lang3.RandomStringUtils; 4 | 5 | import java.security.SecureRandom; 6 | 7 | /** 8 | * Utility class for generating random Strings. 9 | */ 10 | public final class RandomUtil { 11 | private static final SecureRandom SECURE_RANDOM = new SecureRandom(); 12 | 13 | private static final int DEF_COUNT = 20; 14 | 15 | static { 16 | SECURE_RANDOM.nextBytes(new byte[64]); 17 | } 18 | 19 | private RandomUtil() { 20 | } 21 | 22 | private static String generateRandomAlphanumericString() { 23 | return RandomStringUtils.random(DEF_COUNT, 0, 0, true, true, null, SECURE_RANDOM); 24 | } 25 | 26 | /** 27 | * Generate a password. 28 | * 29 | * @return the generated password 30 | */ 31 | public static String generatePassword() { 32 | return generateRandomAlphanumericString(); 33 | } 34 | 35 | /** 36 | * Generate an activation key. 37 | * 38 | * @return the generated activation key 39 | */ 40 | public static String generateActivationKey() { 41 | return generateRandomAlphanumericString(); 42 | } 43 | 44 | /** 45 | * Generate a reset key. 46 | * 47 | * @return the generated reset key 48 | */ 49 | public static String generateResetKey() { 50 | return generateRandomAlphanumericString(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/LogsResource.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.web.rest; 2 | 3 | import com.robmelfi.health.web.rest.vm.LoggerVM; 4 | 5 | import ch.qos.logback.classic.Level; 6 | import ch.qos.logback.classic.LoggerContext; 7 | import com.codahale.metrics.annotation.Timed; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * Controller for view and managing Log Level at runtime. 17 | */ 18 | @RestController 19 | @RequestMapping("/management") 20 | public class LogsResource { 21 | 22 | @GetMapping("/logs") 23 | @Timed 24 | public List getList() { 25 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 26 | return context.getLoggerList() 27 | .stream() 28 | .map(LoggerVM::new) 29 | .collect(Collectors.toList()); 30 | } 31 | 32 | @PutMapping("/logs") 33 | @ResponseStatus(HttpStatus.NO_CONTENT) 34 | @Timed 35 | public void changeLevel(@RequestBody LoggerVM jsonLogger) { 36 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 37 | context.getLogger(jsonLogger.getName()).setLevel(Level.valueOf(jsonLogger.getLevel())); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/BadRequestAlertException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 getAlertParameters(String entityName, String errorKey) { 37 | Map parameters = new HashMap<>(); 38 | parameters.put("message", "error." + errorKey); 39 | parameters.put("params", entityName); 40 | return parameters; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/CustomParameterizedException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.web.rest.errors; 2 | 3 | import org.zalando.problem.AbstractThrowableProblem; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | import static org.zalando.problem.Status.BAD_REQUEST; 9 | 10 | /** 11 | * Custom, parameterized exception, which can be translated on the client side. 12 | * For example: 13 | * 14 | *

15 |  * throw new CustomParameterizedException("myCustomError", "hello", "world");
16 |  * 
17 | * 18 | * Can be translated with: 19 | * 20 | *
21 |  * "error.myCustomError" :  "The server says {{param0}} to {{param1}}"
22 |  * 
23 | */ 24 | public class CustomParameterizedException extends AbstractThrowableProblem { 25 | 26 | private static final long serialVersionUID = 1L; 27 | 28 | private static final String PARAM = "param"; 29 | 30 | public CustomParameterizedException(String message, String... params) { 31 | this(message, toParamMap(params)); 32 | } 33 | 34 | public CustomParameterizedException(String message, Map paramMap) { 35 | super(ErrorConstants.PARAMETERIZED_TYPE, "Parameterized Exception", BAD_REQUEST, null, null, null, toProblemParameters(message, paramMap)); 36 | } 37 | 38 | public static Map toParamMap(String... params) { 39 | Map paramMap = new HashMap<>(); 40 | if (params != null && params.length > 0) { 41 | for (int i = 0; i < params.length; i++) { 42 | paramMap.put(PARAM + i, params[i]); 43 | } 44 | } 45 | return paramMap; 46 | } 47 | 48 | public static Map toProblemParameters(String message, Map paramMap) { 49 | Map parameters = new HashMap<>(); 50 | parameters.put("message", message); 51 | parameters.put("params", paramMap); 52 | return parameters; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/EmailAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/EmailNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.web.rest.errors; 2 | 3 | import org.zalando.problem.AbstractThrowableProblem; 4 | import org.zalando.problem.Status; 5 | 6 | public class EmailNotFoundException extends AbstractThrowableProblem { 7 | 8 | private static final long serialVersionUID = 1L; 9 | 10 | public EmailNotFoundException() { 11 | super(ErrorConstants.EMAIL_NOT_FOUND_TYPE, "Email address not registered", Status.BAD_REQUEST); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/ErrorConstants.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 PARAMETERIZED_TYPE = URI.create(PROBLEM_BASE_URL + "/parameterized"); 13 | public static final URI ENTITY_NOT_FOUND_TYPE = URI.create(PROBLEM_BASE_URL + "/entity-not-found"); 14 | public static final URI INVALID_PASSWORD_TYPE = URI.create(PROBLEM_BASE_URL + "/invalid-password"); 15 | public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used"); 16 | public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used"); 17 | public static final URI EMAIL_NOT_FOUND_TYPE = URI.create(PROBLEM_BASE_URL + "/email-not-found"); 18 | 19 | private ErrorConstants() { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/FieldErrorVM.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/InternalServerErrorException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.web.rest.errors; 2 | 3 | import org.zalando.problem.AbstractThrowableProblem; 4 | import org.zalando.problem.Status; 5 | 6 | /** 7 | * Simple exception with a message, that returns an Internal Server Error code. 8 | */ 9 | public class InternalServerErrorException extends AbstractThrowableProblem { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | public InternalServerErrorException(String message) { 14 | super(ErrorConstants.DEFAULT_TYPE, message, Status.INTERNAL_SERVER_ERROR); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/InvalidPasswordException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/LoginAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/errors/package-info.java: -------------------------------------------------------------------------------- 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 com.robmelfi.health.web.rest.errors; 7 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring MVC REST controllers. 3 | */ 4 | package com.robmelfi.health.web.rest; 5 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/util/HeaderUtil.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.web.rest.util; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.http.HttpHeaders; 6 | 7 | /** 8 | * Utility class for HTTP headers creation. 9 | */ 10 | public final class HeaderUtil { 11 | 12 | private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class); 13 | 14 | private static final String APPLICATION_NAME = "twentyOnePointsReactApp"; 15 | 16 | private HeaderUtil() { 17 | } 18 | 19 | public static HttpHeaders createAlert(String message, String param) { 20 | HttpHeaders headers = new HttpHeaders(); 21 | headers.add("X-" + APPLICATION_NAME + "-alert", message); 22 | headers.add("X-" + APPLICATION_NAME + "-params", param); 23 | return headers; 24 | } 25 | 26 | public static HttpHeaders createEntityCreationAlert(String entityName, String param) { 27 | return createAlert("A new " + entityName + " is created with identifier " + param, param); 28 | } 29 | 30 | public static HttpHeaders createEntityUpdateAlert(String entityName, String param) { 31 | return createAlert("A " + entityName + " is updated with identifier " + param, param); 32 | } 33 | 34 | public static HttpHeaders createEntityDeletionAlert(String entityName, String param) { 35 | return createAlert("A " + entityName + " is deleted with identifier " + param, param); 36 | } 37 | 38 | public static HttpHeaders createFailureAlert(String entityName, String errorKey, String defaultMessage) { 39 | log.error("Entity processing failed, {}", defaultMessage); 40 | HttpHeaders headers = new HttpHeaders(); 41 | headers.add("X-" + APPLICATION_NAME + "-error", defaultMessage); 42 | headers.add("X-" + APPLICATION_NAME + "-params", entityName); 43 | return headers; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/vm/KeyAndPasswordVM.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/vm/LoggerVM.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.web.rest.vm; 2 | 3 | import ch.qos.logback.classic.Logger; 4 | 5 | /** 6 | * View Model object for storing a Logback logger. 7 | */ 8 | public class LoggerVM { 9 | 10 | private String name; 11 | 12 | private String level; 13 | 14 | public LoggerVM(Logger logger) { 15 | this.name = logger.getName(); 16 | this.level = logger.getEffectiveLevel().toString(); 17 | } 18 | 19 | public LoggerVM() { 20 | // Empty public constructor used by Jackson. 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public String getLevel() { 32 | return level; 33 | } 34 | 35 | public void setLevel(String level) { 36 | this.level = level; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "LoggerVM{" + 42 | "name='" + name + '\'' + 43 | ", level='" + level + '\'' + 44 | '}'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/vm/LoginVM.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.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 = ManagedUserVM.PASSWORD_MIN_LENGTH, max = ManagedUserVM.PASSWORD_MAX_LENGTH) 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 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/vm/ManagedUserVM.java: -------------------------------------------------------------------------------- 1 | package com.robmelfi.health.web.rest.vm; 2 | 3 | import com.robmelfi.health.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{" + 33 | "} " + super.toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/robmelfi/health/web/rest/vm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * View Models used by Spring MVC REST controllers. 3 | */ 4 | package com.robmelfi.health.web.rest.vm; 5 | -------------------------------------------------------------------------------- /src/main/jib/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP} 4 | exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -cp /app/resources/:/app/classes/:/app/libs/* "com.robmelfi.health.TwentyOnePointsReactApp" "$@" 5 | -------------------------------------------------------------------------------- /src/main/resources/.h2.server.properties: -------------------------------------------------------------------------------- 1 | #H2 Server Properties 2 | 0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./target/h2db/db/twentyonepointsreact|TwentyOnePointsReact 3 | webAllowOthers=true 4 | webPort=8082 5 | webSSL=false 6 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ${AnsiColor.GREEN} ██╗${AnsiColor.BLUE} ██╗ ██╗ ████████╗ ███████╗ ██████╗ ████████╗ ████████╗ ███████╗ 3 | ${AnsiColor.GREEN} ██║${AnsiColor.BLUE} ██║ ██║ ╚══██╔══╝ ██╔═══██╗ ██╔════╝ ╚══██╔══╝ ██╔═════╝ ██╔═══██╗ 4 | ${AnsiColor.GREEN} ██║${AnsiColor.BLUE} ████████║ ██║ ███████╔╝ ╚█████╗ ██║ ██████╗ ███████╔╝ 5 | ${AnsiColor.GREEN}██╗ ██║${AnsiColor.BLUE} ██╔═══██║ ██║ ██╔════╝ ╚═══██╗ ██║ ██╔═══╝ ██╔══██║ 6 | ${AnsiColor.GREEN}╚██████╔╝${AnsiColor.BLUE} ██║ ██║ ████████╗ ██║ ██████╔╝ ██║ ████████╗ ██║ ╚██╗ 7 | ${AnsiColor.GREEN} ╚═════╝ ${AnsiColor.BLUE} ╚═╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═╝ 8 | 9 | ${AnsiColor.BRIGHT_BLUE}:: JHipster 🤓 :: Running Spring Boot ${spring-boot.version} :: 10 | :: https://www.jhipster.tech ::${AnsiColor.DEFAULT} 11 | -------------------------------------------------------------------------------- /src/main/resources/config/application-heroku.yml: -------------------------------------------------------------------------------- 1 | # =================================================================== 2 | # Spring Boot configuration for the "heroku" profile. 3 | # 4 | # This configuration overrides the application.yml file. 5 | # =================================================================== 6 | 7 | # =================================================================== 8 | # Standard Spring Boot properties. 9 | # Full reference is available at: 10 | # http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html 11 | # =================================================================== 12 | 13 | eureka: 14 | instance: 15 | hostname: twentyone-points-react-dev.herokuapp.com 16 | non-secure-port: 80 17 | prefer-ip-address: false 18 | client: 19 | service-url: 20 | defaultZone: ${JHIPSTER_REGISTRY_URL}/eureka/ 21 | 22 | spring: 23 | datasource: 24 | type: com.zaxxer.hikari.HikariDataSource 25 | url: ${JDBC_DATABASE_URL} 26 | username: ${JDBC_DATABASE_USERNAME} 27 | password: ${JDBC_DATABASE_PASSWORD} 28 | hikari: 29 | maximumPoolSize: 8 30 | data: 31 | jest: 32 | uri: ${BONSAI_URL} 33 | -------------------------------------------------------------------------------- /src/main/resources/config/application-tls.yml: -------------------------------------------------------------------------------- 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 | jhipster: 17 | http: 18 | version: V_2_0 19 | -------------------------------------------------------------------------------- /src/main/resources/config/bootstrap-heroku.yml: -------------------------------------------------------------------------------- 1 | # =================================================================== 2 | # Spring Cloud Config bootstrap configuration for the "heroku" profile 3 | # =================================================================== 4 | 5 | spring: 6 | cloud: 7 | config: 8 | fail-fast: true 9 | uri: ${JHIPSTER_REGISTRY_URL}/config 10 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/authorities.csv: -------------------------------------------------------------------------------- 1 | name 2 | ROLE_ADMIN 3 | ROLE_USER 4 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20181012140436_added_entity_constraints_Points.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20181012140437_added_entity_Weigth.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20181012140437_added_entity_constraints_Weigth.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20181012140438_added_entity_BloodPressure.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20181012140438_added_entity_constraints_BloodPressure.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20181012140439_added_entity_Preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20181012140439_added_entity_constraints_Preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/master.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/users.csv: -------------------------------------------------------------------------------- 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;en;system;system 3 | 2;anonymoususer;$2a$10$j8S5d7Sr7.8VTOYNviDPOeWX8KcYILUVJBsYV83Y5NtECayypx9lO;Anonymous;User;anonymous@localhost;;true;en;system;system 4 | 3;admin;$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC;Administrator;Administrator;admin@localhost;;true;en;system;system 5 | 4;user;$2a$10$VEjxo0jq2YG9Rbk2HmX9S.k1uZBGYUHdUcid3g/vfiEl7lwWgOH/K;User;User;user@localhost;;true;en;system;system 6 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/users_authorities.csv: -------------------------------------------------------------------------------- 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 7 | -------------------------------------------------------------------------------- /src/main/resources/config/tls/keystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robmelfi/21-points-react/a310a2762d7ddab3440588dbe3dcb22c338823ed/src/main/resources/config/tls/keystore.p12 -------------------------------------------------------------------------------- /src/main/resources/i18n/messages.properties: -------------------------------------------------------------------------------- 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=21-Points Health Account Activation 9 | email.activation.greeting=Dear {0} 10 | email.activation.text1=Your 21-Points Health account has been created, please click on the URL below to activate it: 11 | email.activation.text2=Regards, 12 | email.signature=21-Points Health 13 | 14 | # Creation email 15 | email.creation.text1=Your 21-Points Health account has been created, please click on the URL below to access it: 16 | 17 | # Reset email 18 | email.reset.title=21-Points Health Password Reset 19 | email.reset.greeting=Dear {0} 20 | email.reset.text1=For your 21-Points Health account a password reset was requested, please click on the URL below to reset it: 21 | email.reset.text2=Regards, 22 | -------------------------------------------------------------------------------- /src/main/resources/templates/mail/activationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21-Points Health activation 5 | 6 | 7 | 8 | 9 |

10 | Dear 11 |

12 |

13 | Your JHipster account has been created, please click on the URL below to activate it: 14 |

15 |

16 | Activation Link 18 |

19 |

20 | Regards, 21 |
22 | JHipster. 23 |

24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/resources/templates/mail/creationEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster creation 5 | 6 | 7 | 8 | 9 |

10 | Dear 11 |

12 |

13 | Your JHipster account has been created, please click on the URL below to access it: 14 |

15 |

16 | 17 | Login link 19 | 20 |

21 |

22 | Regards, 23 |
24 | JHipster. 25 |

26 | 27 | 28 | -------------------------------------------------------------------------------- /src/main/resources/templates/mail/passwordResetEmail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JHipster password reset 5 | 6 | 7 | 8 | 9 |

10 | Dear 11 |

12 |

13 | For your JHipster account a password reset was requested, please click on the URL below to reset it: 14 |

15 |

16 | Login link 18 |

19 |

20 | Regards, 21 |
22 | JHipster. 23 |

24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/webapp/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found 6 | 7 | 8 | 55 | 56 | 57 |

Page Not Found

58 |

Sorry, but the page you were trying to view does not exist.

59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/webapp/app/_bootstrap-variables.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Bootstrap overrides https://v4-alpha.getbootstrap.com/getting-started/options/ 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 | // Options: 9 | // Quickly modify global styling by enabling or disabling optional features. 10 | $enable-rounded: true; 11 | $enable-shadows: false; 12 | $enable-gradients: false; 13 | $enable-transitions: true; 14 | $enable-hover-media-query: false; 15 | $enable-grid-classes: true; 16 | $enable-print-styles: true; 17 | 18 | // Components: 19 | // Define common padding and border radius sizes and more. 20 | 21 | $border-radius: 0.15rem; 22 | $border-radius-lg: 0.125rem; 23 | $border-radius-sm: 0.1rem; 24 | 25 | // Body: 26 | // Settings for the `` element. 27 | 28 | $body-bg: #fff; 29 | $primary-color: #009688; 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/axios-interceptor.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { getBasePath, Storage } from 'react-jhipster'; 3 | 4 | import { SERVER_API_URL } from 'app/config/constants'; 5 | 6 | const TIMEOUT = 1000000; // 10000 7 | const setupAxiosInterceptors = onUnauthenticated => { 8 | const onRequestSuccess = config => { 9 | const token = Storage.local.get('jhi-authenticationToken') || Storage.session.get('jhi-authenticationToken'); 10 | if (token) { 11 | config.headers.Authorization = `Bearer ${token}`; 12 | } 13 | config.timeout = TIMEOUT; 14 | config.url = `${SERVER_API_URL}${config.url}`; 15 | return config; 16 | }; 17 | const onResponseSuccess = response => response; 18 | const onResponseError = err => { 19 | const status = err.status || err.response.status; 20 | if (status === 403 || status === 401) { 21 | onUnauthenticated(); 22 | } 23 | return Promise.reject(err); 24 | }; 25 | axios.interceptors.request.use(onRequestSuccess); 26 | axios.interceptors.response.use(onResponseSuccess, onResponseError); 27 | }; 28 | 29 | export default setupAxiosInterceptors; 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/constants.ts: -------------------------------------------------------------------------------- 1 | const config = { 2 | VERSION: process.env.VERSION 3 | }; 4 | 5 | export default config; 6 | 7 | export const SERVER_API_URL = process.env.SERVER_API_URL; 8 | 9 | export const AUTHORITIES = { 10 | ADMIN: 'ROLE_ADMIN', 11 | USER: 'ROLE_USER' 12 | }; 13 | 14 | export const messages = { 15 | DATA_ERROR_ALERT: 'Internal Error' 16 | }; 17 | 18 | export const APP_DATE_FORMAT = 'DD/MM/YY HH:mm'; 19 | export const APP_TIMESTAMP_FORMAT = 'DD/MM/YY HH:mm:ss'; 20 | export const APP_LOCAL_DATE_FORMAT = 'DD/MM/YYYY'; 21 | export const APP_LOCAL_DATETIME_FORMAT = 'YYYY-MM-DDThh:mm'; 22 | export const APP_WHOLE_NUMBER_FORMAT = '0,0'; 23 | export const APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT = '0,0.[00]'; 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/devtools.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createDevTools } from 'redux-devtools'; 3 | import LogMonitor from 'redux-devtools-log-monitor'; 4 | import DockMonitor from 'redux-devtools-dock-monitor'; 5 | // You can toggle visibility of devTools with ctrl + H 6 | // and change their position with ctrl + Q 7 | export default createDevTools( 8 | 9 | 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/error-middleware.ts: -------------------------------------------------------------------------------- 1 | import { isPromise } from 'react-jhipster'; 2 | 3 | const getErrorMessage = errorData => { 4 | let message = errorData.message; 5 | if (errorData.fieldErrors) { 6 | errorData.fieldErrors.forEach(fErr => { 7 | message += `\nfield: ${fErr.field}, Object: ${fErr.objectName}, message: ${fErr.message}\n`; 8 | }); 9 | } 10 | return message; 11 | }; 12 | 13 | export default () => next => action => { 14 | // If not a promise, continue on 15 | if (!isPromise(action.payload)) { 16 | return next(action); 17 | } 18 | 19 | /** 20 | * 21 | * The error middleware serves to dispatch the initial pending promise to 22 | * the promise middleware, but adds a `catch`. 23 | * It need not run in production 24 | */ 25 | if (process.env.NODE_ENV === 'development') { 26 | // Dispatch initial pending promise, but catch any errors 27 | return next(action).catch(error => { 28 | console.error(`${action.type} caught at middleware with reason: ${JSON.stringify(error.message)}.`); 29 | if (error && error.response && error.response.data) { 30 | const message = getErrorMessage(error.response.data); 31 | console.error(`Actual cause: ${message}`); 32 | } 33 | 34 | return Promise.reject(error); 35 | }); 36 | } 37 | return next(action); 38 | }; 39 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/logger-middleware.ts: -------------------------------------------------------------------------------- 1 | export default () => next => action => { 2 | if (process.env.NODE_ENV !== 'production') { 3 | const { type, payload, meta } = action; 4 | 5 | console.groupCollapsed(type); 6 | // tslint:disable-next-line 7 | console.log('Payload:', payload); 8 | // tslint:disable-next-line 9 | console.log('Meta:', meta); 10 | console.groupEnd(); 11 | } 12 | 13 | return next(action); 14 | }; 15 | -------------------------------------------------------------------------------- /src/main/webapp/app/config/store.ts: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware, compose } from 'redux'; 2 | import promiseMiddleware from 'redux-promise-middleware'; 3 | import thunkMiddleware from 'redux-thunk'; 4 | import reducer, { IRootState } from 'app/shared/reducers'; 5 | import DevTools from './devtools'; 6 | import errorMiddleware from './error-middleware'; 7 | import notificationMiddleware from './notification-middleware'; 8 | import loggerMiddleware from './logger-middleware'; 9 | import { loadingBarMiddleware } from 'react-redux-loading-bar'; 10 | 11 | const defaultMiddlewares = [ 12 | thunkMiddleware, 13 | errorMiddleware, 14 | notificationMiddleware, 15 | promiseMiddleware(), 16 | loadingBarMiddleware(), 17 | loggerMiddleware 18 | ]; 19 | const composedMiddlewares = middlewares => 20 | process.env.NODE_ENV === 'development' 21 | ? compose( 22 | applyMiddleware(...defaultMiddlewares, ...middlewares), 23 | DevTools.instrument() 24 | ) 25 | : compose(applyMiddleware(...defaultMiddlewares, ...middlewares)); 26 | 27 | const initialize = (initialState?: IRootState, middlewares = []) => createStore(reducer, initialState, composedMiddlewares(middlewares)); 28 | 29 | export default initialize; 30 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/blood-pressure/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch } from 'react-router-dom'; 3 | 4 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route'; 5 | 6 | import BloodPressure from './blood-pressure'; 7 | import BloodPressureDetail from './blood-pressure-detail'; 8 | import BloodPressureUpdate from './blood-pressure-update'; 9 | import BloodPressureDeleteDialog from './blood-pressure-delete-dialog'; 10 | 11 | const Routes = ({ match }) => ( 12 | <> 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | 23 | export default Routes; 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch } from 'react-router-dom'; 3 | 4 | // tslint:disable-next-line:no-unused-variable 5 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route'; 6 | 7 | import Points from './points'; 8 | import Weigth from './weigth'; 9 | import BloodPressure from './blood-pressure'; 10 | import Preferences from './preferences'; 11 | /* jhipster-needle-add-route-import - JHipster will add routes here */ 12 | 13 | const Routes = ({ match }) => ( 14 |
15 | 16 | {/* prettier-ignore */} 17 | 18 | 19 | 20 | 21 | {/* jhipster-needle-add-route-path - JHipster will routes here */} 22 | 23 |
24 | ); 25 | 26 | export default Routes; 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/points/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch } from 'react-router-dom'; 3 | 4 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route'; 5 | 6 | import Points from './points'; 7 | import PointsDetail from './points-detail'; 8 | import PointsUpdate from './points-update'; 9 | import PointsDeleteDialog from './points-delete-dialog'; 10 | 11 | const Routes = ({ match }) => ( 12 | <> 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | 23 | export default Routes; 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/points/point.scss: -------------------------------------------------------------------------------- 1 | .truncate { 2 | width: 180px; 3 | white-space: nowrap; 4 | overflow: hidden; 5 | text-overflow: ellipsis; 6 | cursor: pointer; 7 | 8 | &.cal-day-notes { 9 | width: 150px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/points/points-home.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | import { Row, Col, Alert, Progress } from 'reactstrap'; 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import moment from 'moment'; 7 | 8 | const pointsHome = props => ( 9 |
10 | 11 | 12 |

Points for the week of {moment(props.pointsThisWeek.week).format('ll')}

13 |

Points for {moment(props.pointsThisWeek.week).format('ll')}

14 | 15 | 16 | 17 | Add Points 18 | 19 | 20 |
21 | 22 | 23 | 27 | { !props.pointsThisWeek.points && No points yet this week, better get moving!} 28 | 29 | 30 |
31 | ); 32 | 33 | export default pointsHome; 34 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/preferences/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch } from 'react-router-dom'; 3 | 4 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route'; 5 | 6 | import Preferences from './preferences'; 7 | import PreferencesDetail from './preferences-detail'; 8 | import PreferencesUpdate from './preferences-update'; 9 | import PreferencesDeleteDialog from './preferences-delete-dialog'; 10 | 11 | const Routes = ({ match }) => ( 12 | <> 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | 23 | export default Routes; 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/weigth/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch } from 'react-router-dom'; 3 | 4 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route'; 5 | 6 | import Weigth from './weigth'; 7 | import WeigthDetail from './weigth-detail'; 8 | import WeigthUpdate from './weigth-update'; 9 | import WeigthDeleteDialog from './weigth-delete-dialog'; 10 | 11 | const Routes = ({ match }) => ( 12 | <> 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | 23 | export default Routes; 24 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/weigth/weigth-home.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, Area, AreaChart } from 'recharts'; 4 | 5 | import { Row, Col, Alert, Progress } from 'reactstrap'; 6 | 7 | import { IWeigthChart } from 'app/shared/model/weigth-chart'; 8 | 9 | export interface IWeigthHomeProp { 10 | weigthChart: IWeigthChart; 11 | } 12 | 13 | class WeigthHome extends Component { 14 | 15 | render () { 16 | 17 | let graph = No blood pressure readings found. [TO DO: graph]; 18 | 19 | if (this.props.weigthChart.data.length !== 0) { 20 | graph = ( 21 | 22 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | ); 35 | } 36 | 37 | return ( 38 |
39 | 40 | 41 |

Weight:

42 | 43 | 44 | 45 | Add Weight 46 | 47 | 48 |
49 | 50 | 51 | {graph} 52 | 53 | 54 |
55 | ); 56 | } 57 | } 58 | 59 | export default WeigthHome; 60 | -------------------------------------------------------------------------------- /src/main/webapp/app/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Provider } from 'react-redux'; 4 | import { bindActionCreators } from 'redux'; 5 | import { AppContainer } from 'react-hot-loader'; 6 | 7 | import DevTools from './config/devtools'; 8 | import initStore from './config/store'; 9 | import setupAxiosInterceptors from './config/axios-interceptor'; 10 | import { clearAuthentication } from './shared/reducers/authentication'; 11 | import ErrorBoundary from './shared/error/error-boundary'; 12 | import AppComponent from './app'; 13 | import { loadIcons } from './config/icon-loader'; 14 | 15 | const devTools = process.env.NODE_ENV === 'development' ? : null; 16 | 17 | const store = initStore(); 18 | 19 | const actions = bindActionCreators({ clearAuthentication }, store.dispatch); 20 | setupAxiosInterceptors(() => actions.clearAuthentication('login.error.unauthorized')); 21 | 22 | loadIcons(); 23 | 24 | const rootEl = document.getElementById('root'); 25 | 26 | const render = Component => 27 | ReactDOM.render( 28 | 29 | 30 | 31 |
32 | {/* If this slows down the app in dev disable it and enable when required */} 33 | {devTools} 34 | 35 |
36 |
37 |
38 |
, 39 | rootEl 40 | ); 41 | 42 | render(AppComponent); 43 | 44 | // This is quite unstable 45 | // if (module.hot) { 46 | // module.hot.accept('./app', () => { 47 | // const NextApp = require<{ default: typeof AppComponent }>('./app').default; 48 | // render(NextApp); 49 | // }); 50 | // } 51 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/about/about.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robmelfi/21-points-react/a310a2762d7ddab3440588dbe3dcb22c338823ed/src/main/webapp/app/modules/about/about.scss -------------------------------------------------------------------------------- /src/main/webapp/app/modules/account/activate/activate.reducer.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | import { REQUEST, SUCCESS, FAILURE } from 'app/shared/reducers/action-type.util'; 4 | 5 | export const ACTION_TYPES = { 6 | ACTIVATE_ACCOUNT: 'activate/ACTIVATE_ACCOUNT', 7 | RESET: 'activate/RESET' 8 | }; 9 | 10 | const initialState = { 11 | activationSuccess: false, 12 | activationFailure: false 13 | }; 14 | 15 | export type ActivateState = Readonly; 16 | 17 | // Reducer 18 | export default (state: ActivateState = initialState, action): ActivateState => { 19 | switch (action.type) { 20 | case REQUEST(ACTION_TYPES.ACTIVATE_ACCOUNT): 21 | return { 22 | ...state 23 | }; 24 | case FAILURE(ACTION_TYPES.ACTIVATE_ACCOUNT): 25 | return { 26 | ...state, 27 | activationFailure: true 28 | }; 29 | case SUCCESS(ACTION_TYPES.ACTIVATE_ACCOUNT): 30 | return { 31 | ...state, 32 | activationSuccess: true 33 | }; 34 | case ACTION_TYPES.RESET: 35 | return { 36 | ...initialState 37 | }; 38 | default: 39 | return state; 40 | } 41 | }; 42 | 43 | // Actions 44 | export const activateAction = key => ({ 45 | type: ACTION_TYPES.ACTIVATE_ACCOUNT, 46 | payload: axios.get('api/activate?key=' + key) 47 | }); 48 | 49 | export const reset = () => ({ 50 | type: ACTION_TYPES.RESET 51 | }); 52 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/account/activate/activate.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { Link, RouteComponentProps } from 'react-router-dom'; 4 | import { Row, Col, Alert } from 'reactstrap'; 5 | import { getUrlParameter } from 'react-jhipster'; 6 | 7 | import { IRootState } from 'app/shared/reducers'; 8 | import { activateAction, reset } from './activate.reducer'; 9 | 10 | const successAlert = ( 11 | 12 | Your user account has been activated. Please 13 | 14 | sign in 15 | . 16 | 17 | ); 18 | 19 | const failureAlert = ( 20 | 21 | Your user could not be activated. Please use the registration form to sign up. 22 | 23 | ); 24 | 25 | export interface IActivateProps extends StateProps, DispatchProps, RouteComponentProps<{ key: any }> {} 26 | 27 | export class ActivatePage extends React.Component { 28 | componentWillUnmount() { 29 | this.props.reset(); 30 | } 31 | 32 | componentDidMount() { 33 | const key = getUrlParameter('key', this.props.location.search); 34 | this.props.activateAction(key); 35 | } 36 | 37 | render() { 38 | const { activationSuccess, activationFailure } = this.props; 39 | 40 | return ( 41 |
42 | 43 | 44 |

Activation

45 | {activationSuccess ? successAlert : undefined} 46 | {activationFailure ? failureAlert : undefined} 47 | 48 |
49 |
50 | ); 51 | } 52 | } 53 | 54 | const mapStateToProps = ({ activate }: IRootState) => ({ 55 | activationSuccess: activate.activationSuccess, 56 | activationFailure: activate.activationFailure 57 | }); 58 | 59 | const mapDispatchToProps = { activateAction, reset }; 60 | 61 | type StateProps = ReturnType; 62 | type DispatchProps = typeof mapDispatchToProps; 63 | 64 | export default connect( 65 | mapStateToProps, 66 | mapDispatchToProps 67 | )(ActivatePage); 68 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/account/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route'; 4 | 5 | import Settings from './settings/settings'; 6 | import Password from './password/password'; 7 | 8 | const Routes = ({ match }) => ( 9 |
10 | 11 | 12 |
13 | ); 14 | 15 | export default Routes; 16 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/account/password-reset/init/password-reset-init.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { connect } from 'react-redux'; 4 | import { AvForm, AvField } from 'availity-reactstrap-validation'; 5 | import { Button, Alert, Col, Row } from 'reactstrap'; 6 | 7 | import { IRootState } from 'app/shared/reducers'; 8 | import { handlePasswordResetInit, reset } from '../password-reset.reducer'; 9 | 10 | export type IPasswordResetInitProps = DispatchProps; 11 | 12 | export class PasswordResetInit extends React.Component { 13 | componentWillUnmount() { 14 | this.props.reset(); 15 | } 16 | 17 | handleValidSubmit = (event, values) => { 18 | this.props.handlePasswordResetInit(values.email); 19 | event.preventDefault(); 20 | }; 21 | 22 | render() { 23 | return ( 24 |
25 | 26 | 27 |

Reset your password

28 | 29 |

Enter the email address you used to register

30 |
31 | 32 | 43 | 46 | 47 | 48 |
49 |
50 | ); 51 | } 52 | } 53 | 54 | const mapDispatchToProps = { handlePasswordResetInit, reset }; 55 | 56 | type DispatchProps = typeof mapDispatchToProps; 57 | 58 | export default connect( 59 | null, 60 | mapDispatchToProps 61 | )(PasswordResetInit); 62 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/account/password/password.reducer.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | import { REQUEST, SUCCESS, FAILURE } from 'app/shared/reducers/action-type.util'; 4 | 5 | export const ACTION_TYPES = { 6 | UPDATE_PASSWORD: 'account/UPDATE_PASSWORD', 7 | RESET: 'account/RESET' 8 | }; 9 | 10 | const initialState = { 11 | loading: false, 12 | errorMessage: null, 13 | updateSuccess: false, 14 | updateFailure: false 15 | }; 16 | 17 | export type PasswordState = Readonly; 18 | 19 | // Reducer 20 | export default (state: PasswordState = initialState, action): PasswordState => { 21 | switch (action.type) { 22 | case REQUEST(ACTION_TYPES.UPDATE_PASSWORD): 23 | return { 24 | ...initialState, 25 | errorMessage: null, 26 | updateSuccess: false, 27 | loading: true 28 | }; 29 | case FAILURE(ACTION_TYPES.UPDATE_PASSWORD): 30 | return { 31 | ...initialState, 32 | loading: false, 33 | updateSuccess: false, 34 | updateFailure: true 35 | }; 36 | case SUCCESS(ACTION_TYPES.UPDATE_PASSWORD): 37 | return { 38 | ...initialState, 39 | loading: false, 40 | updateSuccess: true, 41 | updateFailure: false 42 | }; 43 | case ACTION_TYPES.RESET: 44 | return { 45 | ...initialState 46 | }; 47 | default: 48 | return state; 49 | } 50 | }; 51 | 52 | // Actions 53 | const apiUrl = 'api/account'; 54 | 55 | export const savePassword = (currentPassword, newPassword) => ({ 56 | type: ACTION_TYPES.UPDATE_PASSWORD, 57 | payload: axios.post(`${apiUrl}/change-password`, { currentPassword, newPassword }), 58 | meta: { 59 | successMessage: 'Password changed!', 60 | errorMessage: 'An error has occurred! The password could not be changed.' 61 | } 62 | }); 63 | 64 | export const reset = () => ({ 65 | type: ACTION_TYPES.RESET 66 | }); 67 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/account/register/register.reducer.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | import { REQUEST, SUCCESS, FAILURE } from 'app/shared/reducers/action-type.util'; 4 | 5 | export const ACTION_TYPES = { 6 | CREATE_ACCOUNT: 'register/CREATE_ACCOUNT', 7 | RESET: 'register/RESET' 8 | }; 9 | 10 | const initialState = { 11 | loading: false, 12 | registrationSuccess: false, 13 | registrationFailure: false, 14 | errorMessage: null 15 | }; 16 | 17 | export type RegisterState = Readonly; 18 | 19 | // Reducer 20 | export default (state: RegisterState = initialState, action): RegisterState => { 21 | switch (action.type) { 22 | case REQUEST(ACTION_TYPES.CREATE_ACCOUNT): 23 | return { 24 | ...state, 25 | loading: true 26 | }; 27 | case FAILURE(ACTION_TYPES.CREATE_ACCOUNT): 28 | return { 29 | ...initialState, 30 | registrationFailure: true, 31 | errorMessage: action.payload.response.data.errorKey 32 | }; 33 | case SUCCESS(ACTION_TYPES.CREATE_ACCOUNT): 34 | return { 35 | ...initialState, 36 | registrationSuccess: true 37 | }; 38 | case ACTION_TYPES.RESET: 39 | return { 40 | ...initialState 41 | }; 42 | default: 43 | return state; 44 | } 45 | }; 46 | 47 | // Actions 48 | export const handleRegister = (login, email, password, langKey = 'en') => ({ 49 | type: ACTION_TYPES.CREATE_ACCOUNT, 50 | payload: axios.post('api/register', { login, email, password, langKey }), 51 | meta: { 52 | successMessage: 'Registration saved! Please check your email for confirmation.' 53 | } 54 | }); 55 | 56 | export const reset = () => ({ 57 | type: ACTION_TYPES.RESET 58 | }); 59 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/account/settings/settings.reducer.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | import { REQUEST, SUCCESS, FAILURE } from 'app/shared/reducers/action-type.util'; 4 | import { getSession } from 'app/shared/reducers/authentication'; 5 | 6 | export const ACTION_TYPES = { 7 | UPDATE_ACCOUNT: 'account/UPDATE_ACCOUNT', 8 | RESET: 'account/RESET' 9 | }; 10 | 11 | const initialState = { 12 | loading: false, 13 | errorMessage: null, 14 | updateSuccess: false, 15 | updateFailure: false 16 | }; 17 | 18 | export type SettingsState = Readonly; 19 | 20 | // Reducer 21 | export default (state: SettingsState = initialState, action): SettingsState => { 22 | switch (action.type) { 23 | case REQUEST(ACTION_TYPES.UPDATE_ACCOUNT): 24 | return { 25 | ...state, 26 | errorMessage: null, 27 | updateSuccess: false, 28 | loading: true 29 | }; 30 | case FAILURE(ACTION_TYPES.UPDATE_ACCOUNT): 31 | return { 32 | ...state, 33 | loading: false, 34 | updateSuccess: false, 35 | updateFailure: true 36 | }; 37 | case SUCCESS(ACTION_TYPES.UPDATE_ACCOUNT): 38 | return { 39 | ...state, 40 | loading: false, 41 | updateSuccess: true, 42 | updateFailure: false 43 | }; 44 | case ACTION_TYPES.RESET: 45 | return { 46 | ...initialState 47 | }; 48 | default: 49 | return state; 50 | } 51 | }; 52 | 53 | // Actions 54 | const apiUrl = 'api/account'; 55 | 56 | export const saveAccountSettings = account => async dispatch => { 57 | await dispatch({ 58 | type: ACTION_TYPES.UPDATE_ACCOUNT, 59 | payload: axios.post(apiUrl, account), 60 | meta: { 61 | successMessage: 'Settings saved!' 62 | } 63 | }); 64 | dispatch(getSession()); 65 | }; 66 | 67 | export const reset = () => ({ 68 | type: ACTION_TYPES.RESET 69 | }); 70 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/administration/docs/docs.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const DocsPage = () => ( 4 |
5 |