├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .huskyrc ├── .jhipster ├── CustomerDetails.json ├── PaymentCache.json ├── Product.json ├── ProductCategory.json ├── ProductOrder.json └── ShoppingCart.json ├── .lintstagedrc.js ├── .prettierignore ├── .prettierrc ├── .yo-rc.json ├── Procfile ├── README.md ├── app.jdl ├── app.png ├── build.gradle ├── checkstyle.xml ├── e-commerce-app-blog.md ├── gradle.properties ├── gradle ├── docker.gradle ├── heroku.gradle ├── profile_dev.gradle ├── profile_prod.gradle ├── sonar.gradle ├── war.gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── zipkin.gradle ├── gradlew ├── gradlew.bat ├── package-lock.json ├── package.json ├── postcss.config.js ├── settings.gradle ├── sonar-project.properties ├── src ├── main │ ├── docker │ │ ├── app.yml │ │ ├── grafana │ │ │ └── provisioning │ │ │ │ ├── dashboards │ │ │ │ ├── JVM.json │ │ │ │ └── dashboard.yml │ │ │ │ └── datasources │ │ │ │ └── datasource.yml │ │ ├── monitoring.yml │ │ ├── mysql.yml │ │ ├── prometheus │ │ │ └── prometheus.yml │ │ └── sonar.yml │ ├── generated │ │ └── com │ │ │ └── adyen │ │ │ └── demo │ │ │ └── store │ │ │ └── domain │ │ │ ├── AbstractAuditingEntity_.java │ │ │ ├── Authority_.java │ │ │ ├── CustomerDetails_.java │ │ │ ├── PersistentAuditEvent_.java │ │ │ ├── ProductCategory_.java │ │ │ ├── ProductOrder_.java │ │ │ ├── Product_.java │ │ │ ├── ShoppingCart_.java │ │ │ └── User_.java │ ├── java │ │ └── com │ │ │ └── adyen │ │ │ └── demo │ │ │ └── store │ │ │ ├── ApplicationWebXml.java │ │ │ ├── StoreApp.java │ │ │ ├── aop │ │ │ └── logging │ │ │ │ └── LoggingAspect.java │ │ │ ├── config │ │ │ ├── ApplicationProperties.java │ │ │ ├── AsyncConfiguration.java │ │ │ ├── CacheConfiguration.java │ │ │ ├── CloudDatabaseConfiguration.java │ │ │ ├── Constants.java │ │ │ ├── DatabaseConfiguration.java │ │ │ ├── DateTimeFormatConfiguration.java │ │ │ ├── JacksonConfiguration.java │ │ │ ├── LiquibaseConfiguration.java │ │ │ ├── LocaleConfiguration.java │ │ │ ├── LoggingAspectConfiguration.java │ │ │ ├── LoggingConfiguration.java │ │ │ ├── SecurityConfiguration.java │ │ │ ├── WebConfigurer.java │ │ │ ├── audit │ │ │ │ ├── AuditEventConverter.java │ │ │ │ └── package-info.java │ │ │ └── package-info.java │ │ │ ├── domain │ │ │ ├── AbstractAuditingEntity.java │ │ │ ├── Authority.java │ │ │ ├── CustomerDetails.java │ │ │ ├── PaymentCache.java │ │ │ ├── PersistentAuditEvent.java │ │ │ ├── Product.java │ │ │ ├── ProductCategory.java │ │ │ ├── ProductOrder.java │ │ │ ├── ShoppingCart.java │ │ │ ├── User.java │ │ │ ├── enumeration │ │ │ │ ├── Gender.java │ │ │ │ ├── OrderStatus.java │ │ │ │ ├── PaymentMethod.java │ │ │ │ └── Size.java │ │ │ └── package-info.java │ │ │ ├── repository │ │ │ ├── AuthorityRepository.java │ │ │ ├── CustomAuditEventRepository.java │ │ │ ├── CustomerDetailsRepository.java │ │ │ ├── PaymentCacheRepository.java │ │ │ ├── PersistenceAuditEventRepository.java │ │ │ ├── ProductCategoryRepository.java │ │ │ ├── ProductOrderRepository.java │ │ │ ├── ProductRepository.java │ │ │ ├── ShoppingCartRepository.java │ │ │ ├── UserRepository.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 │ │ │ ├── CustomerDetailsService.java │ │ │ ├── EmailAlreadyUsedException.java │ │ │ ├── InvalidPasswordException.java │ │ │ ├── MailService.java │ │ │ ├── PaymentCacheService.java │ │ │ ├── ProductCategoryService.java │ │ │ ├── ProductOrderService.java │ │ │ ├── ProductService.java │ │ │ ├── ShoppingCartService.java │ │ │ ├── UserService.java │ │ │ ├── UsernameAlreadyUsedException.java │ │ │ ├── dto │ │ │ │ ├── PasswordChangeDTO.java │ │ │ │ ├── UserDTO.java │ │ │ │ └── package-info.java │ │ │ ├── mapper │ │ │ │ ├── UserMapper.java │ │ │ │ └── package-info.java │ │ │ └── package-info.java │ │ │ └── web │ │ │ └── rest │ │ │ ├── AccountResource.java │ │ │ ├── AuditResource.java │ │ │ ├── CheckoutResource.java │ │ │ ├── ClientForwardController.java │ │ │ ├── CustomerDetailsResource.java │ │ │ ├── ProductCategoryResource.java │ │ │ ├── ProductOrderResource.java │ │ │ ├── ProductResource.java │ │ │ ├── ShoppingCartResource.java │ │ │ ├── UserJWTController.java │ │ │ ├── UserResource.java │ │ │ ├── WebhookResource.java │ │ │ ├── errors │ │ │ ├── BadRequestAlertException.java │ │ │ ├── EmailAlreadyUsedException.java │ │ │ ├── EntityNotFoundException.java │ │ │ ├── ErrorConstants.java │ │ │ ├── ExceptionTranslator.java │ │ │ ├── FieldErrorVM.java │ │ │ ├── InvalidPasswordException.java │ │ │ ├── LoginAlreadyUsedException.java │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ └── vm │ │ │ ├── CheckoutPaymentsActionVM.java │ │ │ ├── KeyAndPasswordVM.java │ │ │ ├── LoginVM.java │ │ │ ├── ManagedUserVM.java │ │ │ ├── PaymentRedirectVM.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 │ │ │ │ ├── changelog │ │ │ │ │ ├── 00000000000000_initial_schema.xml │ │ │ │ │ ├── 20200424080100_added_entity_Product.xml │ │ │ │ │ ├── 20200424080100_added_entity_constraints_Product.xml │ │ │ │ │ ├── 20200424080200_added_entity_ProductCategory.xml │ │ │ │ │ ├── 20200424080300_added_entity_CustomerDetails.xml │ │ │ │ │ ├── 20200424080300_added_entity_constraints_CustomerDetails.xml │ │ │ │ │ ├── 20200424080400_added_entity_ShoppingCart.xml │ │ │ │ │ ├── 20200424080400_added_entity_constraints_ShoppingCart.xml │ │ │ │ │ ├── 20200424080500_added_entity_ProductOrder.xml │ │ │ │ │ ├── 20200424080500_added_entity_constraints_ProductOrder.xml │ │ │ │ │ ├── 20201218114000_added_entity_PaymentCache.xml │ │ │ │ │ └── 20201218114000_added_entity_constraints_PaymentCache.xml │ │ │ │ ├── data │ │ │ │ │ ├── authority.csv │ │ │ │ │ ├── user.csv │ │ │ │ │ └── user_authority.csv │ │ │ │ ├── fake-data │ │ │ │ │ ├── blob │ │ │ │ │ │ ├── shirt1.jpg │ │ │ │ │ │ ├── shirt2.jpg │ │ │ │ │ │ └── shirt3.jpg │ │ │ │ │ ├── customer_details.csv │ │ │ │ │ ├── product.csv │ │ │ │ │ └── product_category.csv │ │ │ │ └── master.xml │ │ │ └── tls │ │ │ │ └── keystore.p12 │ │ ├── i18n │ │ │ └── messages.properties │ │ ├── logback-spring.xml │ │ └── templates │ │ │ ├── error.html │ │ │ └── mail │ │ │ ├── activationEmail.html │ │ │ ├── creationEmail.html │ │ │ └── passwordResetEmail.html │ └── webapp │ │ ├── 404.html │ │ ├── WEB-INF │ │ └── web.xml │ │ ├── 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 │ │ │ ├── customer-details │ │ │ │ ├── customer-details-delete-dialog.tsx │ │ │ │ ├── customer-details-detail.tsx │ │ │ │ ├── customer-details-update.tsx │ │ │ │ ├── customer-details.reducer.ts │ │ │ │ ├── customer-details.tsx │ │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ ├── product-category │ │ │ │ ├── index.tsx │ │ │ │ ├── product-category-delete-dialog.tsx │ │ │ │ ├── product-category-detail.tsx │ │ │ │ ├── product-category-update.tsx │ │ │ │ ├── product-category.reducer.ts │ │ │ │ └── product-category.tsx │ │ │ ├── product-order │ │ │ │ ├── index.tsx │ │ │ │ ├── product-order-delete-dialog.tsx │ │ │ │ ├── product-order-detail.tsx │ │ │ │ ├── product-order-update.tsx │ │ │ │ ├── product-order.reducer.ts │ │ │ │ └── product-order.tsx │ │ │ ├── product │ │ │ │ ├── index.tsx │ │ │ │ ├── product-delete-dialog.tsx │ │ │ │ ├── product-detail.tsx │ │ │ │ ├── product-update.tsx │ │ │ │ ├── product.reducer.ts │ │ │ │ └── product.tsx │ │ │ └── shopping-cart │ │ │ │ ├── index.tsx │ │ │ │ ├── shopping-cart-delete-dialog.tsx │ │ │ │ ├── shopping-cart-detail.tsx │ │ │ │ ├── shopping-cart-update.tsx │ │ │ │ ├── shopping-cart.reducer.ts │ │ │ │ └── shopping-cart.tsx │ │ ├── index.tsx │ │ ├── modules │ │ │ ├── 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.scss │ │ │ │ │ └── docs.tsx │ │ │ │ ├── health │ │ │ │ │ ├── health-modal.tsx │ │ │ │ │ └── health.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── logs │ │ │ │ │ └── logs.tsx │ │ │ │ ├── metrics │ │ │ │ │ └── metrics.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 │ │ │ ├── cart │ │ │ │ └── cart.tsx │ │ │ ├── checkout │ │ │ │ ├── checkout-status.tsx │ │ │ │ ├── checkout.reducer.ts │ │ │ │ ├── checkout.scss │ │ │ │ └── checkout.tsx │ │ │ ├── home │ │ │ │ ├── home.scss │ │ │ │ └── home.tsx │ │ │ ├── login │ │ │ │ ├── login-modal.tsx │ │ │ │ ├── login.tsx │ │ │ │ └── logout.tsx │ │ │ └── orders │ │ │ │ └── orders.tsx │ │ ├── routes.tsx │ │ ├── shared │ │ │ ├── auth │ │ │ │ └── private-route.tsx │ │ │ ├── error │ │ │ │ ├── error-boundary-route.tsx │ │ │ │ ├── error-boundary.tsx │ │ │ │ └── page-not-found.tsx │ │ │ ├── layout │ │ │ │ ├── footer │ │ │ │ │ ├── footer.scss │ │ │ │ │ └── footer.tsx │ │ │ │ ├── header │ │ │ │ │ ├── header-components.tsx │ │ │ │ │ ├── header.scss │ │ │ │ │ └── header.tsx │ │ │ │ ├── menus │ │ │ │ │ ├── account.tsx │ │ │ │ │ ├── admin.tsx │ │ │ │ │ ├── entities.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── menu-components.tsx │ │ │ │ │ └── menu-item.tsx │ │ │ │ └── password │ │ │ │ │ ├── password-strength-bar.scss │ │ │ │ │ └── password-strength-bar.tsx │ │ │ ├── model │ │ │ │ ├── customer-details.model.ts │ │ │ │ ├── enumerations │ │ │ │ │ ├── gender.model.ts │ │ │ │ │ ├── order-status.model.ts │ │ │ │ │ ├── payment-method.model.ts │ │ │ │ │ └── size.model.ts │ │ │ │ ├── product-category.model.ts │ │ │ │ ├── product-order.model.ts │ │ │ │ ├── product.model.ts │ │ │ │ ├── shopping-cart.model.ts │ │ │ │ └── user.model.ts │ │ │ ├── reducers │ │ │ │ ├── action-type.util.ts │ │ │ │ ├── application-profile.ts │ │ │ │ ├── authentication.ts │ │ │ │ └── index.ts │ │ │ └── util │ │ │ │ ├── date-utils.ts │ │ │ │ ├── entity-utils.ts │ │ │ │ └── pagination.constants.ts │ │ └── typings.d.ts │ │ ├── content │ │ ├── css │ │ │ └── loading.css │ │ └── images │ │ │ ├── failed.svg │ │ │ ├── logo-jhipster.png │ │ │ ├── logo.svg │ │ │ ├── success.svg │ │ │ └── thank-you.svg │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── manifest.webapp │ │ ├── robots.txt │ │ └── swagger-ui │ │ ├── dist │ │ └── images │ │ │ └── throbber.gif │ │ └── index.html └── test │ ├── java │ └── com │ │ └── adyen │ │ └── demo │ │ └── store │ │ ├── ArchTest.java │ │ ├── config │ │ ├── NoOpMailConfiguration.java │ │ ├── WebConfigurerTest.java │ │ ├── WebConfigurerTestController.java │ │ └── timezone │ │ │ └── HibernateTimeZoneIT.java │ │ ├── domain │ │ ├── CustomerDetailsTest.java │ │ ├── PaymentCacheTest.java │ │ ├── ProductCategoryTest.java │ │ ├── ProductOrderTest.java │ │ ├── ProductTest.java │ │ └── ShoppingCartTest.java │ │ ├── repository │ │ ├── CustomAuditEventRepositoryIT.java │ │ └── timezone │ │ │ ├── DateTimeWrapper.java │ │ │ └── DateTimeWrapperRepository.java │ │ ├── security │ │ ├── DomainUserDetailsServiceIT.java │ │ ├── SecurityUtilsUnitTest.java │ │ └── jwt │ │ │ ├── JWTFilterTest.java │ │ │ └── TokenProviderTest.java │ │ ├── service │ │ ├── AuditEventServiceIT.java │ │ ├── MailServiceIT.java │ │ ├── UserServiceIT.java │ │ └── mapper │ │ │ └── UserMapperTest.java │ │ └── web │ │ └── rest │ │ ├── AccountResourceIT.java │ │ ├── AuditResourceIT.java │ │ ├── ClientForwardControllerTest.java │ │ ├── CustomerDetailsResourceIT.java │ │ ├── ProductCategoryResourceIT.java │ │ ├── ProductOrderResourceIT.java │ │ ├── ProductResourceIT.java │ │ ├── ShoppingCartResourceIT.java │ │ ├── TestUtil.java │ │ ├── UserJWTControllerIT.java │ │ ├── UserResourceIT.java │ │ ├── WithUnauthenticatedMockUser.java │ │ └── errors │ │ ├── ExceptionTranslatorIT.java │ │ └── ExceptionTranslatorTestController.java │ ├── javascript │ ├── jest.conf.js │ └── spec │ │ ├── app │ │ ├── config │ │ │ ├── axios-interceptor.spec.ts │ │ │ └── notification-middleware.spec.ts │ │ ├── entities │ │ │ ├── customer-details │ │ │ │ └── customer-details-reducer.spec.ts │ │ │ ├── product-category │ │ │ │ └── product-category-reducer.spec.ts │ │ │ ├── product-order │ │ │ │ └── product-order-reducer.spec.ts │ │ │ ├── product │ │ │ │ └── product-reducer.spec.ts │ │ │ └── shopping-cart │ │ │ │ └── shopping-cart-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 │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ │ └── header.spec.tsx.snap │ │ │ │ │ └── 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.json ├── tsconfig.test.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 | # We recommend you to keep these unchanged 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | # Change these settings to your own preference 16 | indent_style = space 17 | indent_size = 4 18 | 19 | [*.{ts,tsx,js,jsx,json,css,scss,yml}] 20 | indent_size = 2 21 | 22 | [*.md] 23 | trim_trailing_whitespace = false 24 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | src/main/docker/ 3 | src/test/javascript/protractor.conf.js 4 | src/test/javascript/jest.conf.js 5 | webpack/ 6 | target/ 7 | build/ 8 | node/ 9 | postcss.config.js 10 | src/main/webapp/content/js/adyen.js 11 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["jhipster-react"], 3 | "parserOptions": { 4 | "project": "./tsconfig.json" 5 | }, 6 | "rules": {} 7 | } 8 | -------------------------------------------------------------------------------- /.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.jhipster/CustomerDetails.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CustomerDetails", 3 | "fields": [ 4 | { 5 | "fieldName": "gender", 6 | "fieldType": "Gender", 7 | "fieldValues": "MALE,FEMALE,OTHER", 8 | "fieldValidateRules": [ 9 | "required" 10 | ] 11 | }, 12 | { 13 | "fieldName": "phone", 14 | "fieldType": "String", 15 | "fieldValidateRules": [ 16 | "required" 17 | ] 18 | }, 19 | { 20 | "fieldName": "addressLine1", 21 | "fieldType": "String", 22 | "fieldValidateRules": [ 23 | "required" 24 | ] 25 | }, 26 | { 27 | "fieldName": "addressLine2", 28 | "fieldType": "String" 29 | }, 30 | { 31 | "fieldName": "city", 32 | "fieldType": "String", 33 | "fieldValidateRules": [ 34 | "required" 35 | ] 36 | }, 37 | { 38 | "fieldName": "country", 39 | "fieldType": "String", 40 | "fieldValidateRules": [ 41 | "required" 42 | ] 43 | } 44 | ], 45 | "relationships": [ 46 | { 47 | "relationshipType": "one-to-one", 48 | "otherEntityName": "user", 49 | "otherEntityRelationshipName": "customerDetails", 50 | "relationshipValidateRules": "required", 51 | "relationshipName": "user", 52 | "otherEntityField": "login", 53 | "ownerSide": true 54 | }, 55 | { 56 | "relationshipType": "one-to-many", 57 | "otherEntityName": "shoppingCart", 58 | "otherEntityRelationshipName": "customerDetails", 59 | "relationshipName": "cart" 60 | } 61 | ], 62 | "changelogDate": "20200424080300", 63 | "entityTableName": "customer_details", 64 | "dto": "no", 65 | "pagination": "pagination", 66 | "service": "serviceClass", 67 | "jpaMetamodelFiltering": false, 68 | "fluentMethods": true, 69 | "readOnly": false, 70 | "embedded": false, 71 | "clientRootFolder": "", 72 | "applications": [ 73 | "store" 74 | ] 75 | } -------------------------------------------------------------------------------- /.jhipster/PaymentCache.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PaymentCache", 3 | "fields": [ 4 | { 5 | "fieldName": "orderRef", 6 | "fieldType": "String", 7 | "fieldValidateRules": [ 8 | "required" 9 | ] 10 | }, 11 | { 12 | "fieldName": "originalHost", 13 | "fieldType": "String" 14 | }, 15 | { 16 | "fieldName": "paymentData", 17 | "fieldType": "String" 18 | }, 19 | { 20 | "fieldName": "paymentType", 21 | "fieldType": "String" 22 | } 23 | ], 24 | "relationships": [ 25 | { 26 | "relationshipType": "many-to-one", 27 | "otherEntityName": "user", 28 | "otherEntityRelationshipName": "paymentCache", 29 | "relationshipValidateRules": "required", 30 | "relationshipName": "user", 31 | "otherEntityField": "login" 32 | } 33 | ], 34 | "changelogDate": "20201218114000", 35 | "entityTableName": "payment_cache", 36 | "dto": "no", 37 | "pagination": "no", 38 | "service": "serviceClass", 39 | "jpaMetamodelFiltering": false, 40 | "fluentMethods": true, 41 | "readOnly": false, 42 | "embedded": false, 43 | "clientRootFolder": "", 44 | "applications": [ 45 | "store" 46 | ] 47 | } -------------------------------------------------------------------------------- /.jhipster/Product.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Product", 3 | "fields": [ 4 | { 5 | "fieldName": "name", 6 | "fieldType": "String", 7 | "fieldValidateRules": [ 8 | "required" 9 | ] 10 | }, 11 | { 12 | "fieldName": "description", 13 | "fieldType": "String" 14 | }, 15 | { 16 | "fieldName": "price", 17 | "fieldType": "BigDecimal", 18 | "fieldValidateRules": [ 19 | "required", 20 | "min" 21 | ], 22 | "fieldValidateRulesMin": "0" 23 | }, 24 | { 25 | "fieldName": "size", 26 | "fieldType": "Size", 27 | "fieldValues": "S,M,L,XL,XXL", 28 | "fieldValidateRules": [ 29 | "required" 30 | ] 31 | }, 32 | { 33 | "fieldName": "image", 34 | "fieldType": "byte[]", 35 | "fieldTypeBlobContent": "image" 36 | } 37 | ], 38 | "relationships": [ 39 | { 40 | "relationshipType": "many-to-one", 41 | "otherEntityName": "productCategory", 42 | "otherEntityRelationshipName": "product", 43 | "relationshipValidateRules": "required", 44 | "relationshipName": "productCategory", 45 | "otherEntityField": "name" 46 | } 47 | ], 48 | "changelogDate": "20200424080100", 49 | "javadoc": "Product sold by the Online store", 50 | "entityTableName": "product", 51 | "dto": "no", 52 | "pagination": "pagination", 53 | "service": "serviceClass", 54 | "jpaMetamodelFiltering": false, 55 | "fluentMethods": true, 56 | "readOnly": false, 57 | "embedded": false, 58 | "clientRootFolder": "", 59 | "applications": [ 60 | "store" 61 | ] 62 | } -------------------------------------------------------------------------------- /.jhipster/ProductCategory.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ProductCategory", 3 | "fields": [ 4 | { 5 | "fieldName": "name", 6 | "fieldType": "String", 7 | "fieldValidateRules": [ 8 | "required" 9 | ] 10 | }, 11 | { 12 | "fieldName": "description", 13 | "fieldType": "String" 14 | } 15 | ], 16 | "relationships": [ 17 | { 18 | "relationshipType": "one-to-many", 19 | "otherEntityName": "product", 20 | "otherEntityRelationshipName": "productCategory", 21 | "relationshipName": "product" 22 | } 23 | ], 24 | "changelogDate": "20200424080200", 25 | "entityTableName": "product_category", 26 | "dto": "no", 27 | "pagination": "pagination", 28 | "service": "serviceClass", 29 | "jpaMetamodelFiltering": false, 30 | "fluentMethods": true, 31 | "readOnly": false, 32 | "embedded": false, 33 | "clientRootFolder": "", 34 | "applications": [ 35 | "store" 36 | ] 37 | } -------------------------------------------------------------------------------- /.jhipster/ProductOrder.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ProductOrder", 3 | "fields": [ 4 | { 5 | "fieldName": "quantity", 6 | "fieldType": "Integer", 7 | "fieldValidateRules": [ 8 | "required", 9 | "min" 10 | ], 11 | "fieldValidateRulesMin": "0" 12 | }, 13 | { 14 | "fieldName": "totalPrice", 15 | "fieldType": "BigDecimal", 16 | "fieldValidateRules": [ 17 | "required", 18 | "min" 19 | ], 20 | "fieldValidateRulesMin": "0" 21 | } 22 | ], 23 | "relationships": [ 24 | { 25 | "relationshipType": "many-to-one", 26 | "otherEntityName": "product", 27 | "otherEntityRelationshipName": "productOrder", 28 | "relationshipValidateRules": "required", 29 | "relationshipName": "product", 30 | "otherEntityField": "name" 31 | }, 32 | { 33 | "relationshipType": "many-to-one", 34 | "otherEntityName": "shoppingCart", 35 | "otherEntityRelationshipName": "order", 36 | "relationshipValidateRules": "required", 37 | "relationshipName": "cart", 38 | "otherEntityField": "id" 39 | } 40 | ], 41 | "changelogDate": "20200424080500", 42 | "entityTableName": "product_order", 43 | "dto": "no", 44 | "pagination": "no", 45 | "service": "serviceClass", 46 | "jpaMetamodelFiltering": false, 47 | "fluentMethods": true, 48 | "readOnly": false, 49 | "embedded": false, 50 | "clientRootFolder": "", 51 | "applications": [ 52 | "store" 53 | ] 54 | } -------------------------------------------------------------------------------- /.lintstagedrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | '{,src/**/}*.{md,json,ts,css,scss,yml}': ['prettier --write', 'git add'] 3 | }; 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | target 3 | package-lock.json 4 | .git 5 | -------------------------------------------------------------------------------- /.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 | 14 | # java rules: 15 | overrides: 16 | - files: "*.java" 17 | options: 18 | tabWidth: 4 19 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-jhipster": { 3 | "authenticationType": "jwt", 4 | "cacheProvider": "ehcache", 5 | "clientFramework": "react", 6 | "serverPort": "8080", 7 | "serviceDiscoveryType": false, 8 | "skipUserManagement": false, 9 | "baseName": "store", 10 | "buildTool": "gradle", 11 | "databaseType": "sql", 12 | "devDatabaseType": "h2Disk", 13 | "enableHibernateCache": true, 14 | "enableSwaggerCodegen": false, 15 | "enableTranslation": false, 16 | "jhiPrefix": "jhi", 17 | "languages": ["en", "fr"], 18 | "messageBroker": false, 19 | "nativeLanguage": "en", 20 | "prodDatabaseType": "mysql", 21 | "searchEngine": false, 22 | "skipClient": false, 23 | "testFrameworks": [], 24 | "websocket": false, 25 | "packageName": "com.adyen.demo.store", 26 | "packageFolder": "com/adyen/demo/store", 27 | "useSass": true, 28 | "jhipsterVersion": "6.8.0", 29 | "creationTimestamp": 1608565320758, 30 | "skipServer": false, 31 | "clientPackageManager": "npm", 32 | "clientTheme": "none", 33 | "clientThemeVariant": "", 34 | "applicationType": "monolith", 35 | "jwtSecretKey": "NTMyMGZkYWMzYTVmOWMwMWUwOWNhYjllYzM0MTg2ZDZmNzZmMWZhNjcwYjc2ODA2ZGZjMGJlYTc4YzM3YzczMTFiNjBlYjczMWM4NDM3NTM0N2RkOTNiMWJmOWE4YTUxOTkzMzQ0Zjc2MTNmN2U4NjMyZGMzYjRiNzUwZTI2OTA=", 36 | "embeddableLaunchScript": false, 37 | "entitySuffix": "", 38 | "dtoSuffix": "DTO", 39 | "otherModules": [], 40 | "blueprints": [], 41 | "herokuAppName": "adyen-demo-store", 42 | "herokuDeployType": "jar" 43 | }, 44 | "entities": ["Product", "ProductCategory", "CustomerDetails", "ShoppingCart", "ProductOrder", "PaymentCache"] 45 | } 46 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: java $JAVA_OPTS -Xmx256m -jar build/libs/*.jar --spring.profiles.active=prod,heroku --server.port=$PORT 2 | -------------------------------------------------------------------------------- /app.jdl: -------------------------------------------------------------------------------- 1 | application { 2 | config { 3 | baseName store 4 | packageName com.adyen.demo.store 5 | authenticationType jwt 6 | prodDatabaseType mysql 7 | buildTool gradle 8 | clientFramework react 9 | useSass true 10 | enableTranslation false 11 | } 12 | entities * 13 | } 14 | 15 | 16 | /** Product sold by the Online store */ 17 | entity Product { 18 | name String required 19 | description String 20 | price BigDecimal required min(0) 21 | size Size required 22 | image ImageBlob 23 | } 24 | 25 | enum Size { 26 | S, M, L, XL, XXL 27 | } 28 | 29 | entity ProductCategory { 30 | name String required 31 | description String 32 | } 33 | 34 | entity CustomerDetails { 35 | gender Gender required 36 | phone String required 37 | addressLine1 String required 38 | addressLine2 String 39 | city String required 40 | country String required 41 | } 42 | 43 | enum Gender { 44 | MALE, FEMALE, OTHER 45 | } 46 | 47 | entity ShoppingCart { 48 | placedDate Instant required 49 | status OrderStatus required 50 | totalPrice BigDecimal required min(0) 51 | paymentMethod PaymentMethod required 52 | paymentReference String 53 | paymentModificationReference String 54 | } 55 | 56 | enum OrderStatus { 57 | COMPLETED, PAID, PENDING, CANCELLED, REFUNDED 58 | } 59 | 60 | enum PaymentMethod { 61 | CREDIT_CARD(scheme), IDEAL(ideal) 62 | } 63 | 64 | entity ProductOrder { 65 | quantity Integer required min(0) 66 | totalPrice BigDecimal required min(0) 67 | } 68 | 69 | entity PaymentCache { 70 | orderRef String required 71 | originalHost String 72 | paymentData String 73 | paymentType String 74 | } 75 | 76 | relationship ManyToOne { 77 | PaymentCache{user(login) required} to User 78 | } 79 | 80 | relationship OneToOne { 81 | CustomerDetails{user(login) required} to User 82 | } 83 | 84 | relationship ManyToOne { 85 | ProductOrder{product(name) required} to Product 86 | } 87 | 88 | relationship OneToMany { 89 | CustomerDetails{cart} to ShoppingCart{customerDetails required}, 90 | ShoppingCart{order} to ProductOrder{cart required}, 91 | ProductCategory{product} to Product{productCategory(name) required} 92 | } 93 | 94 | service * with serviceClass 95 | paginate Product, CustomerDetails, ProductCategory with pagination 96 | -------------------------------------------------------------------------------- /app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/app.png -------------------------------------------------------------------------------- /checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /gradle/docker.gradle: -------------------------------------------------------------------------------- 1 | jib { 2 | from { 3 | image = "adoptopenjdk:11-jre-hotspot" 4 | } 5 | to { 6 | image = "store:latest" 7 | } 8 | container { 9 | entrypoint = ["bash", "-c", "/entrypoint.sh"] 10 | ports = ["8080"] 11 | environment = [ 12 | SPRING_OUTPUT_ANSI_ENABLED: "ALWAYS", 13 | JHIPSTER_SLEEP: "0" 14 | ] 15 | creationTime = "USE_CURRENT_TIMESTAMP" 16 | } 17 | extraDirectories { 18 | paths = file("src/main/jib") 19 | permissions = ["/entrypoint.sh": "755"] 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /gradle/heroku.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.heroku.sdk.heroku-gradle" 2 | 3 | heroku { 4 | appName = "adyen-demo-store" 5 | buildpacks = ["heroku/jvm"] 6 | } 7 | -------------------------------------------------------------------------------- /gradle/profile_dev.gradle: -------------------------------------------------------------------------------- 1 | configurations { 2 | developmentOnly 3 | runtimeClasspath { 4 | extendsFrom developmentOnly 5 | } 6 | } 7 | 8 | dependencies { 9 | developmentOnly "org.springframework.boot:spring-boot-devtools" 10 | implementation "com.h2database:h2" 11 | } 12 | 13 | def profiles = "dev" 14 | if (project.hasProperty("no-liquibase")) { 15 | profiles += ",no-liquibase" 16 | } 17 | if (project.hasProperty("tls")) { 18 | profiles += ",tls" 19 | } 20 | 21 | springBoot { 22 | buildInfo { 23 | properties { 24 | time = null 25 | } 26 | } 27 | } 28 | 29 | bootRun { 30 | args = [] 31 | } 32 | 33 | task webpack(type: NpmTask) { 34 | inputs.files("package-lock.json") 35 | inputs.files("build.gradle") 36 | inputs.dir("src/main/webapp/") 37 | 38 | def webpackDevFiles = fileTree("webpack//") 39 | webpackDevFiles.exclude("webpack.prod.js") 40 | inputs.files(webpackDevFiles) 41 | 42 | outputs.dir("build/resources/main/static/") 43 | 44 | dependsOn npmInstall 45 | args = ["run", "webpack:build"] 46 | environment = [APP_VERSION: project.version] 47 | } 48 | 49 | processResources { 50 | inputs.property('version', version) 51 | inputs.property('springProfiles', profiles) 52 | filesMatching("**/application.yml") { 53 | filter { 54 | it.replace("#project.version#", version) 55 | } 56 | filter { 57 | it.replace("#spring.profiles.active#", profiles) 58 | } 59 | } 60 | } 61 | 62 | processResources.dependsOn webpack 63 | bootJar.dependsOn processResources 64 | -------------------------------------------------------------------------------- /gradle/profile_prod.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | testImplementation "com.h2database:h2" 3 | } 4 | 5 | def profiles = "prod" 6 | if (project.hasProperty("no-liquibase")) { 7 | profiles += ",no-liquibase" 8 | } 9 | 10 | if (project.hasProperty("swagger")) { 11 | profiles += ",swagger" 12 | } 13 | 14 | springBoot { 15 | buildInfo() 16 | } 17 | 18 | bootRun { 19 | args = [] 20 | } 21 | 22 | task webpack_test(type: NpmTask, dependsOn: "npmInstall") { 23 | args = ["run", "webpack:test"] 24 | } 25 | 26 | task webpack(type: NpmTask, dependsOn: "npmInstall") { 27 | args = ["run", "webpack:prod"] 28 | environment = [APP_VERSION: project.version] 29 | } 30 | 31 | processResources { 32 | inputs.property('version', version) 33 | inputs.property('springProfiles', profiles) 34 | filesMatching("**/application.yml") { 35 | filter { 36 | it.replace("#project.version#", version) 37 | } 38 | filter { 39 | it.replace("#spring.profiles.active#", profiles) 40 | } 41 | } 42 | } 43 | 44 | test.dependsOn webpack_test 45 | processResources.dependsOn webpack 46 | bootJar.dependsOn processResources 47 | -------------------------------------------------------------------------------- /gradle/sonar.gradle: -------------------------------------------------------------------------------- 1 | jacoco { 2 | toolVersion = "0.8.5" 3 | } 4 | 5 | jacocoTestReport { 6 | executionData tasks.withType(Test) 7 | classDirectories.from = files(sourceSets.main.output.classesDirs) 8 | sourceDirectories.from = files(sourceSets.main.java.srcDirs) 9 | 10 | reports { 11 | xml.enabled = true 12 | } 13 | } 14 | 15 | file("sonar-project.properties").withReader { 16 | Properties sonarProperties = new Properties() 17 | sonarProperties.load(it) 18 | 19 | sonarProperties.each { key, value -> 20 | sonarqube { 21 | properties { 22 | property key, value 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gradle/war.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "war" 2 | 3 | bootWar { 4 | mainClassName = "com.adyen.demo.store.StoreApp" 5 | includes = ["WEB-INF/**", "META-INF/**"] 6 | webXml = file("${project.rootDir}/src/main/webapp/WEB-INF/web.xml") 7 | } 8 | 9 | war { 10 | webAppDirName = "build/resources/main/static/" 11 | webXml = file("${project.rootDir}/src/main/webapp/WEB-INF/web.xml") 12 | enabled = true 13 | archiveExtension = "war.original" 14 | includes = ["WEB-INF/**", "META-INF/**"] 15 | 16 | } 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradle/zipkin.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation "org.springframework.cloud:spring-cloud-starter-zipkin" 3 | } 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('autoprefixer') 4 | ] 5 | }; 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | 2 | pluginManagement { 3 | plugins { 4 | id 'org.springframework.boot' version "${spring_boot_version}" 5 | id 'com.google.cloud.tools.jib' version "${jib_plugin_version}" 6 | id 'com.gorylenko.gradle-git-properties' version "${git_properties_plugin_version}" 7 | id 'com.github.node-gradle.node' version "${gradle_node_plugin_version}" 8 | id 'org.liquibase.gradle' version "${liquibase_plugin_version}" 9 | id 'org.sonarqube' version "${sonarqube_plugin_version}" 10 | id 'net.ltgt.apt-eclipse' version "${apt_plugin_version}" 11 | id 'net.ltgt.apt-idea' version "${apt_plugin_version}" 12 | id 'net.ltgt.apt' version "${apt_plugin_version}" 13 | id "io.spring.nohttp" version "${spring_no_http_plugin_version}" 14 | } 15 | } 16 | 17 | rootProject.name = "store" 18 | -------------------------------------------------------------------------------- /src/main/docker/app.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | store-app: 4 | image: store 5 | environment: 6 | - _JAVA_OPTIONS=-Xmx512m -Xms256m 7 | - SPRING_PROFILES_ACTIVE=prod,swagger 8 | - MANAGEMENT_METRICS_EXPORT_PROMETHEUS_ENABLED=true 9 | - SPRING_DATASOURCE_URL=jdbc:mysql://store-mysql:3306/store?useUnicode=true&characterEncoding=utf8&useSSL=false&createDatabaseIfNotExist=true 10 | - JHIPSTER_SLEEP=30 # gives time for other services to boot before the application 11 | ports: 12 | - 8080:8080 13 | store-mysql: 14 | extends: 15 | file: mysql.yml 16 | service: store-mysql 17 | -------------------------------------------------------------------------------- /src/main/docker/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: true 10 | options: 11 | path: /etc/grafana/provisioning/dashboards 12 | -------------------------------------------------------------------------------- /src/main/docker/grafana/provisioning/datasources/datasource.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | # list of datasources that should be deleted from the database 4 | deleteDatasources: 5 | - name: Prometheus 6 | orgId: 1 7 | 8 | # list of datasources to insert/update depending 9 | # whats available in the database 10 | datasources: 11 | # name of the datasource. Required 12 | - name: Prometheus 13 | # datasource type. Required 14 | type: prometheus 15 | # access mode. direct or proxy. Required 16 | access: proxy 17 | # org id. will default to orgId 1 if not specified 18 | orgId: 1 19 | # url 20 | # On MacOS, replace localhost by host.docker.internal 21 | url: http://localhost:9090 22 | # database password, if used 23 | password: 24 | # database user, if used 25 | user: 26 | # database name, if used 27 | database: 28 | # enable/disable basic auth 29 | basicAuth: false 30 | # basic auth username 31 | basicAuthUser: admin 32 | # basic auth password 33 | basicAuthPassword: admin 34 | # enable/disable with credentials headers 35 | withCredentials: 36 | # mark as default datasource. Max one per org 37 | isDefault: true 38 | # fields that will be converted to json and stored in json_data 39 | jsonData: 40 | graphiteVersion: '1.1' 41 | tlsAuth: false 42 | tlsAuthWithCACert: false 43 | # json object of data that will be encrypted. 44 | secureJsonData: 45 | tlsCACert: '...' 46 | tlsClientCert: '...' 47 | tlsClientKey: '...' 48 | version: 1 49 | # allow users to edit datasources from the UI. 50 | editable: true 51 | -------------------------------------------------------------------------------- /src/main/docker/monitoring.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | store-prometheus: 4 | image: prom/prometheus:v2.16.0 5 | volumes: 6 | - ./prometheus/:/etc/prometheus/ 7 | command: 8 | - '--config.file=/etc/prometheus/prometheus.yml' 9 | ports: 10 | - 9090:9090 11 | # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and 12 | # grafana/provisioning/datasources/datasource.yml 13 | network_mode: 'host' # to test locally running service 14 | store-grafana: 15 | image: grafana/grafana:6.6.2 16 | volumes: 17 | - ./grafana/provisioning/:/etc/grafana/provisioning/ 18 | environment: 19 | - GF_SECURITY_ADMIN_PASSWORD=admin 20 | - GF_USERS_ALLOW_SIGN_UP=false 21 | - GF_INSTALL_PLUGINS=grafana-piechart-panel 22 | ports: 23 | - 3000:3000 24 | # On MacOS, remove next line and replace localhost by host.docker.internal in prometheus/prometheus.yml and 25 | # grafana/provisioning/datasources/datasource.yml 26 | network_mode: 'host' # to test locally running service 27 | -------------------------------------------------------------------------------- /src/main/docker/mysql.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | store-mysql: 4 | image: mysql:8.0.19 5 | # volumes: 6 | # - ~/volumes/jhipster/store/mysql/:/var/lib/mysql/ 7 | environment: 8 | - MYSQL_USER=root 9 | - MYSQL_ALLOW_EMPTY_PASSWORD=yes 10 | - MYSQL_DATABASE=store 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/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | # Sample global config for monitoring JHipster applications 2 | global: 3 | scrape_interval: 15s # By default, scrape targets every 15 seconds. 4 | evaluation_interval: 15s # By default, scrape targets every 15 seconds. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Attach these labels to any time series or alerts when communicating with 8 | # external systems (federation, remote storage, Alertmanager). 9 | external_labels: 10 | monitor: 'jhipster' 11 | 12 | # A scrape configuration containing exactly one endpoint to scrape: 13 | # Here it's Prometheus itself. 14 | scrape_configs: 15 | # The job name is added as a label `job=` to any timeseries scraped from this config. 16 | - job_name: 'prometheus' 17 | 18 | # Override the global default and scrape targets from this job every 5 seconds. 19 | scrape_interval: 5s 20 | 21 | # scheme defaults to 'http' enable https in case your application is server via https 22 | #scheme: https 23 | # basic auth is not needed by default. See https://www.jhipster.tech/monitoring/#configuring-metrics-forwarding for details 24 | #basic_auth: 25 | # username: admin 26 | # password: admin 27 | metrics_path: /management/prometheus 28 | static_configs: 29 | - targets: 30 | # On MacOS, replace localhost by host.docker.internal 31 | - localhost:8080 32 | -------------------------------------------------------------------------------- /src/main/docker/sonar.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | store-sonar: 4 | image: sonarqube:8.2-community 5 | ports: 6 | - 9001:9000 7 | - 9092:9092 8 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/AbstractAuditingEntity_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import java.time.Instant; 4 | import javax.annotation.Generated; 5 | import javax.persistence.metamodel.SingularAttribute; 6 | import javax.persistence.metamodel.StaticMetamodel; 7 | 8 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 9 | @StaticMetamodel(AbstractAuditingEntity.class) 10 | public abstract class AbstractAuditingEntity_ { 11 | 12 | public static volatile SingularAttribute createdDate; 13 | public static volatile SingularAttribute createdBy; 14 | public static volatile SingularAttribute lastModifiedDate; 15 | public static volatile SingularAttribute lastModifiedBy; 16 | 17 | public static final String CREATED_DATE = "createdDate"; 18 | public static final String CREATED_BY = "createdBy"; 19 | public static final String LAST_MODIFIED_DATE = "lastModifiedDate"; 20 | public static final String LAST_MODIFIED_BY = "lastModifiedBy"; 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/Authority_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import javax.annotation.Generated; 4 | import javax.persistence.metamodel.SingularAttribute; 5 | import javax.persistence.metamodel.StaticMetamodel; 6 | 7 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 8 | @StaticMetamodel(Authority.class) 9 | public abstract class Authority_ { 10 | 11 | public static volatile SingularAttribute name; 12 | 13 | public static final String NAME = "name"; 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/CustomerDetails_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import com.adyen.demo.store.domain.enumeration.Gender; 4 | import javax.annotation.Generated; 5 | import javax.persistence.metamodel.SetAttribute; 6 | import javax.persistence.metamodel.SingularAttribute; 7 | import javax.persistence.metamodel.StaticMetamodel; 8 | 9 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 10 | @StaticMetamodel(CustomerDetails.class) 11 | public abstract class CustomerDetails_ { 12 | 13 | public static volatile SingularAttribute country; 14 | public static volatile SetAttribute carts; 15 | public static volatile SingularAttribute gender; 16 | public static volatile SingularAttribute phone; 17 | public static volatile SingularAttribute city; 18 | public static volatile SingularAttribute addressLine1; 19 | public static volatile SingularAttribute addressLine2; 20 | public static volatile SingularAttribute id; 21 | public static volatile SingularAttribute user; 22 | 23 | public static final String COUNTRY = "country"; 24 | public static final String CARTS = "carts"; 25 | public static final String GENDER = "gender"; 26 | public static final String PHONE = "phone"; 27 | public static final String CITY = "city"; 28 | public static final String ADDRESS_LINE1 = "addressLine1"; 29 | public static final String ADDRESS_LINE2 = "addressLine2"; 30 | public static final String ID = "id"; 31 | public static final String USER = "user"; 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/PersistentAuditEvent_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import java.time.Instant; 4 | import javax.annotation.Generated; 5 | import javax.persistence.metamodel.MapAttribute; 6 | import javax.persistence.metamodel.SingularAttribute; 7 | import javax.persistence.metamodel.StaticMetamodel; 8 | 9 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 10 | @StaticMetamodel(PersistentAuditEvent.class) 11 | public abstract class PersistentAuditEvent_ { 12 | 13 | public static volatile SingularAttribute principal; 14 | public static volatile SingularAttribute auditEventDate; 15 | public static volatile MapAttribute data; 16 | public static volatile SingularAttribute id; 17 | public static volatile SingularAttribute auditEventType; 18 | 19 | public static final String PRINCIPAL = "principal"; 20 | public static final String AUDIT_EVENT_DATE = "auditEventDate"; 21 | public static final String DATA = "data"; 22 | public static final String ID = "id"; 23 | public static final String AUDIT_EVENT_TYPE = "auditEventType"; 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/ProductCategory_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import javax.annotation.Generated; 4 | import javax.persistence.metamodel.SetAttribute; 5 | import javax.persistence.metamodel.SingularAttribute; 6 | import javax.persistence.metamodel.StaticMetamodel; 7 | 8 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 9 | @StaticMetamodel(ProductCategory.class) 10 | public abstract class ProductCategory_ { 11 | 12 | public static volatile SingularAttribute name; 13 | public static volatile SingularAttribute description; 14 | public static volatile SingularAttribute id; 15 | public static volatile SetAttribute products; 16 | 17 | public static final String NAME = "name"; 18 | public static final String DESCRIPTION = "description"; 19 | public static final String ID = "id"; 20 | public static final String PRODUCTS = "products"; 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/ProductOrder_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import java.math.BigDecimal; 4 | import javax.annotation.Generated; 5 | import javax.persistence.metamodel.SingularAttribute; 6 | import javax.persistence.metamodel.StaticMetamodel; 7 | 8 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 9 | @StaticMetamodel(ProductOrder.class) 10 | public abstract class ProductOrder_ { 11 | 12 | public static volatile SingularAttribute product; 13 | public static volatile SingularAttribute quantity; 14 | public static volatile SingularAttribute totalPrice; 15 | public static volatile SingularAttribute id; 16 | public static volatile SingularAttribute cart; 17 | 18 | public static final String PRODUCT = "product"; 19 | public static final String QUANTITY = "quantity"; 20 | public static final String TOTAL_PRICE = "totalPrice"; 21 | public static final String ID = "id"; 22 | public static final String CART = "cart"; 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/Product_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import com.adyen.demo.store.domain.enumeration.Size; 4 | import java.math.BigDecimal; 5 | import javax.annotation.Generated; 6 | import javax.persistence.metamodel.SingularAttribute; 7 | import javax.persistence.metamodel.StaticMetamodel; 8 | 9 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 10 | @StaticMetamodel(Product.class) 11 | public abstract class Product_ { 12 | 13 | public static volatile SingularAttribute image; 14 | public static volatile SingularAttribute size; 15 | public static volatile SingularAttribute price; 16 | public static volatile SingularAttribute imageContentType; 17 | public static volatile SingularAttribute name; 18 | public static volatile SingularAttribute description; 19 | public static volatile SingularAttribute id; 20 | public static volatile SingularAttribute productCategory; 21 | 22 | public static final String IMAGE = "image"; 23 | public static final String SIZE = "size"; 24 | public static final String PRICE = "price"; 25 | public static final String IMAGE_CONTENT_TYPE = "imageContentType"; 26 | public static final String NAME = "name"; 27 | public static final String DESCRIPTION = "description"; 28 | public static final String ID = "id"; 29 | public static final String PRODUCT_CATEGORY = "productCategory"; 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/ShoppingCart_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import com.adyen.demo.store.domain.enumeration.OrderStatus; 4 | import com.adyen.demo.store.domain.enumeration.PaymentMethod; 5 | import java.math.BigDecimal; 6 | import java.time.Instant; 7 | import javax.annotation.Generated; 8 | import javax.persistence.metamodel.SetAttribute; 9 | import javax.persistence.metamodel.SingularAttribute; 10 | import javax.persistence.metamodel.StaticMetamodel; 11 | 12 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 13 | @StaticMetamodel(ShoppingCart.class) 14 | public abstract class ShoppingCart_ { 15 | 16 | public static volatile SingularAttribute totalPrice; 17 | public static volatile SingularAttribute paymentReference; 18 | public static volatile SingularAttribute paymentMethod; 19 | public static volatile SetAttribute orders; 20 | public static volatile SingularAttribute id; 21 | public static volatile SingularAttribute customerDetails; 22 | public static volatile SingularAttribute placedDate; 23 | public static volatile SingularAttribute status; 24 | 25 | public static final String TOTAL_PRICE = "totalPrice"; 26 | public static final String PAYMENT_REFERENCE = "paymentReference"; 27 | public static final String PAYMENT_METHOD = "paymentMethod"; 28 | public static final String ORDERS = "orders"; 29 | public static final String ID = "id"; 30 | public static final String CUSTOMER_DETAILS = "customerDetails"; 31 | public static final String PLACED_DATE = "placedDate"; 32 | public static final String STATUS = "status"; 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/generated/com/adyen/demo/store/domain/User_.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import java.time.Instant; 4 | import javax.annotation.Generated; 5 | import javax.persistence.metamodel.SetAttribute; 6 | import javax.persistence.metamodel.SingularAttribute; 7 | import javax.persistence.metamodel.StaticMetamodel; 8 | 9 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 10 | @StaticMetamodel(User.class) 11 | public abstract class User_ extends com.adyen.demo.store.domain.AbstractAuditingEntity_ { 12 | 13 | public static volatile SingularAttribute lastName; 14 | public static volatile SingularAttribute resetDate; 15 | public static volatile SingularAttribute login; 16 | public static volatile SingularAttribute activationKey; 17 | public static volatile SingularAttribute resetKey; 18 | public static volatile SetAttribute authorities; 19 | public static volatile SingularAttribute firstName; 20 | public static volatile SingularAttribute password; 21 | public static volatile SingularAttribute langKey; 22 | public static volatile SingularAttribute imageUrl; 23 | public static volatile SingularAttribute id; 24 | public static volatile SingularAttribute email; 25 | public static volatile SingularAttribute activated; 26 | 27 | public static final String LAST_NAME = "lastName"; 28 | public static final String RESET_DATE = "resetDate"; 29 | public static final String LOGIN = "login"; 30 | public static final String ACTIVATION_KEY = "activationKey"; 31 | public static final String RESET_KEY = "resetKey"; 32 | public static final String AUTHORITIES = "authorities"; 33 | public static final String FIRST_NAME = "firstName"; 34 | public static final String PASSWORD = "password"; 35 | public static final String LANG_KEY = "langKey"; 36 | public static final String IMAGE_URL = "imageUrl"; 37 | public static final String ID = "id"; 38 | public static final String EMAIL = "email"; 39 | public static final String ACTIVATED = "activated"; 40 | 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/ApplicationWebXml.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store; 2 | 3 | import io.github.jhipster.config.DefaultProfileUtil; 4 | 5 | import org.springframework.boot.builder.SpringApplicationBuilder; 6 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; 7 | 8 | /** 9 | * This is a helper Java class that provides an alternative to creating a {@code web.xml}. 10 | * This will be invoked only when the application is deployed to a Servlet container like Tomcat, JBoss etc. 11 | */ 12 | public class ApplicationWebXml extends SpringBootServletInitializer { 13 | 14 | @Override 15 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 16 | // set a default to use when no profile is configured. 17 | DefaultProfileUtil.addDefaultProfile(application.application()); 18 | return application.sources(StoreApp.class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/ApplicationProperties.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * Properties specific to Store. 7 | *

8 | * Properties are configured in the {@code application.yml} file. 9 | * See {@link io.github.jhipster.config.JHipsterProperties} for a good example. 10 | */ 11 | @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) 12 | public class ApplicationProperties { 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/AsyncConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | import io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 7 | import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; 8 | import org.springframework.boot.autoconfigure.task.TaskExecutionProperties; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.scheduling.annotation.AsyncConfigurer; 12 | import org.springframework.scheduling.annotation.EnableAsync; 13 | import org.springframework.scheduling.annotation.EnableScheduling; 14 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 15 | 16 | import java.util.concurrent.Executor; 17 | 18 | @Configuration 19 | @EnableAsync 20 | @EnableScheduling 21 | public class AsyncConfiguration implements AsyncConfigurer { 22 | 23 | private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class); 24 | 25 | private final TaskExecutionProperties taskExecutionProperties; 26 | 27 | public AsyncConfiguration(TaskExecutionProperties taskExecutionProperties) { 28 | this.taskExecutionProperties = taskExecutionProperties; 29 | } 30 | 31 | @Override 32 | @Bean(name = "taskExecutor") 33 | public Executor getAsyncExecutor() { 34 | log.debug("Creating Async Task Executor"); 35 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 36 | executor.setCorePoolSize(taskExecutionProperties.getPool().getCoreSize()); 37 | executor.setMaxPoolSize(taskExecutionProperties.getPool().getMaxSize()); 38 | executor.setQueueCapacity(taskExecutionProperties.getPool().getQueueCapacity()); 39 | executor.setThreadNamePrefix(taskExecutionProperties.getThreadNamePrefix()); 40 | return new ExceptionHandlingAsyncTaskExecutor(executor); 41 | } 42 | 43 | @Override 44 | public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 45 | return new SimpleAsyncUncaughtExceptionHandler(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/CloudDatabaseConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | import io.github.jhipster.config.JHipsterConstants; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.cloud.config.java.AbstractCloudConfig; 8 | import org.springframework.context.annotation.*; 9 | 10 | import javax.sql.DataSource; 11 | import org.springframework.boot.context.properties.ConfigurationProperties; 12 | 13 | 14 | @Configuration 15 | @Profile(JHipsterConstants.SPRING_PROFILE_CLOUD) 16 | public class CloudDatabaseConfiguration extends AbstractCloudConfig { 17 | 18 | private final Logger log = LoggerFactory.getLogger(CloudDatabaseConfiguration.class); 19 | 20 | private static final String CLOUD_CONFIGURATION_HIKARI_PREFIX = "spring.datasource.hikari"; 21 | 22 | @Bean 23 | @ConfigurationProperties(CLOUD_CONFIGURATION_HIKARI_PREFIX) 24 | public DataSource dataSource() { 25 | log.info("Configuring JDBC datasource from a cloud provider"); 26 | return connectionFactory().dataSource(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/Constants.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | /** 4 | * Application constants. 5 | */ 6 | public final class Constants { 7 | 8 | // Regex for acceptable logins 9 | public static final String LOGIN_REGEX = "^[_.@A-Za-z0-9-]*$"; 10 | 11 | public static final String SYSTEM_ACCOUNT = "system"; 12 | public static final String DEFAULT_LANGUAGE = "en"; 13 | public static final String ANONYMOUS_USER = "anonymoususer"; 14 | 15 | private Constants() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/DatabaseConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | import io.github.jhipster.config.JHipsterConstants; 4 | import io.github.jhipster.config.h2.H2ConfigurationHelper; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.Profile; 10 | 11 | import org.springframework.core.env.Environment; 12 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 13 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 14 | import org.springframework.transaction.annotation.EnableTransactionManagement; 15 | 16 | import java.sql.SQLException; 17 | 18 | @Configuration 19 | @EnableJpaRepositories("com.adyen.demo.store.repository") 20 | @EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware") 21 | @EnableTransactionManagement 22 | public class DatabaseConfiguration { 23 | 24 | private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class); 25 | 26 | private final Environment env; 27 | 28 | public DatabaseConfiguration(Environment env) { 29 | this.env = env; 30 | } 31 | 32 | /** 33 | * Open the TCP port for the H2 database, so it is available remotely. 34 | * 35 | * @return the H2 database TCP server. 36 | * @throws SQLException if the server failed to start. 37 | */ 38 | @Bean(initMethod = "start", destroyMethod = "stop") 39 | @Profile(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) 40 | public Object h2TCPServer() throws SQLException { 41 | String port = getValidPortForH2(); 42 | log.debug("H2 database is available on port {}", port); 43 | return H2ConfigurationHelper.createServer(port); 44 | } 45 | 46 | private String getValidPortForH2() { 47 | int port = Integer.parseInt(env.getProperty("server.port")); 48 | if (port < 10000) { 49 | port = 10000 + port; 50 | } else { 51 | if (port < 63536) { 52 | port = port + 2000; 53 | } else { 54 | port = port - 2000; 55 | } 56 | } 57 | return String.valueOf(port); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/DateTimeFormatConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/config/JacksonConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; 4 | import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; 5 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 6 | import com.fasterxml.jackson.module.afterburner.AfterburnerModule; 7 | 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.zalando.problem.ProblemModule; 11 | import org.zalando.problem.violations.ConstraintViolationProblemModule; 12 | 13 | @Configuration 14 | public class JacksonConfiguration { 15 | 16 | /** 17 | * Support for Java date and time API. 18 | * @return the corresponding Jackson module. 19 | */ 20 | @Bean 21 | public JavaTimeModule javaTimeModule() { 22 | return new JavaTimeModule(); 23 | } 24 | 25 | @Bean 26 | public Jdk8Module jdk8TimeModule() { 27 | return new Jdk8Module(); 28 | } 29 | 30 | /* 31 | * Support for Hibernate types in Jackson. 32 | */ 33 | @Bean 34 | public Hibernate5Module hibernate5Module() { 35 | return new Hibernate5Module(); 36 | } 37 | 38 | /* 39 | * Jackson Afterburner module to speed up serialization/deserialization. 40 | */ 41 | @Bean 42 | public AfterburnerModule afterburnerModule() { 43 | return new AfterburnerModule(); 44 | } 45 | 46 | /* 47 | * Module for serialization/deserialization of RFC7807 Problem. 48 | */ 49 | @Bean 50 | ProblemModule problemModule() { 51 | return new ProblemModule(); 52 | } 53 | 54 | /* 55 | * Module for serialization/deserialization of ConstraintViolationProblem. 56 | */ 57 | @Bean 58 | ConstraintViolationProblemModule constraintViolationProblemModule() { 59 | return new ConstraintViolationProblemModule(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/LocaleConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/config/LoggingAspectConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | import com.adyen.demo.store.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/adyen/demo/store/config/LoggingConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.config; 2 | 3 | import ch.qos.logback.classic.LoggerContext; 4 | import com.fasterxml.jackson.core.JsonProcessingException; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import io.github.jhipster.config.JHipsterProperties; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | import static io.github.jhipster.config.logging.LoggingUtils.*; 15 | 16 | /* 17 | * Configures the console and Logstash log appenders from the app properties 18 | */ 19 | @Configuration 20 | public class LoggingConfiguration { 21 | 22 | public LoggingConfiguration(@Value("${spring.application.name}") String appName, 23 | @Value("${server.port}") String serverPort, 24 | JHipsterProperties jHipsterProperties, 25 | ObjectMapper mapper) throws JsonProcessingException { 26 | 27 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 28 | 29 | Map map = new HashMap<>(); 30 | map.put("app_name", appName); 31 | map.put("app_port", serverPort); 32 | String customFields = mapper.writeValueAsString(map); 33 | 34 | JHipsterProperties.Logging loggingProperties = jHipsterProperties.getLogging(); 35 | JHipsterProperties.Logging.Logstash logstashProperties = loggingProperties.getLogstash(); 36 | 37 | if (loggingProperties.isUseJsonFormat()) { 38 | addJsonConsoleAppender(context, customFields); 39 | } 40 | if (logstashProperties.isEnabled()) { 41 | addLogstashTcpSocketAppender(context, customFields, logstashProperties); 42 | } 43 | if (loggingProperties.isUseJsonFormat() || logstashProperties.isEnabled()) { 44 | addContextListener(context, customFields, loggingProperties); 45 | } 46 | if (jHipsterProperties.getMetrics().getLogs().isEnabled()) { 47 | setMetricsMarkerLogbackFilter(context, loggingProperties.isUseJsonFormat()); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/audit/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Audit specific code. 3 | */ 4 | package com.adyen.demo.store.config.audit; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/config/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Framework configuration files. 3 | */ 4 | package com.adyen.demo.store.config; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/domain/Authority.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain; 2 | 3 | import org.hibernate.annotations.Cache; 4 | import org.hibernate.annotations.CacheConcurrencyStrategy; 5 | import javax.persistence.Entity; 6 | import javax.persistence.Id; 7 | import javax.persistence.Table; 8 | import javax.persistence.Column; 9 | import javax.validation.constraints.NotNull; 10 | import javax.validation.constraints.Size; 11 | import java.io.Serializable; 12 | import java.util.Objects; 13 | 14 | /** 15 | * An authority (a security role) used by Spring Security. 16 | */ 17 | @Entity 18 | @Table(name = "jhi_authority") 19 | @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 20 | public class Authority implements Serializable { 21 | 22 | private static final long serialVersionUID = 1L; 23 | 24 | @NotNull 25 | @Size(max = 50) 26 | @Id 27 | @Column(length = 50) 28 | private String name; 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) { 41 | return true; 42 | } 43 | if (!(o instanceof Authority)) { 44 | return false; 45 | } 46 | return Objects.equals(name, ((Authority) o).name); 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | return Objects.hashCode(name); 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return "Authority{" + 57 | "name='" + name + '\'' + 58 | "}"; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/domain/enumeration/Gender.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain.enumeration; 2 | 3 | /** 4 | * The Gender enumeration. 5 | */ 6 | public enum Gender { 7 | MALE, FEMALE, OTHER 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/domain/enumeration/OrderStatus.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain.enumeration; 2 | 3 | /** 4 | * The OrderStatus enumeration. 5 | */ 6 | public enum OrderStatus { 7 | REFUND_INITIATED, REFUND_FAILED, PAID, PENDING, OPEN, CANCELLED, REFUNDED 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/domain/enumeration/PaymentMethod.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain.enumeration; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * The PaymentMethod enumeration. 8 | */ 9 | public enum PaymentMethod { 10 | CREDIT_CARD("scheme"), IDEAL("ideal"); 11 | 12 | public final String label; 13 | 14 | private static final Map BY_LABEL = new HashMap<>(); 15 | 16 | static { 17 | for (PaymentMethod e : values()) { 18 | BY_LABEL.put(e.label, e); 19 | } 20 | } 21 | 22 | PaymentMethod(final String label) { 23 | this.label = label; 24 | } 25 | 26 | public static PaymentMethod fromLabel(String label) { 27 | return BY_LABEL.get(label); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/domain/enumeration/Size.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.domain.enumeration; 2 | 3 | /** 4 | * The Size enumeration. 5 | */ 6 | public enum Size { 7 | S, M, L, XL, XXL 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/domain/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * JPA domain objects. 3 | */ 4 | package com.adyen.demo.store.domain; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/AuthorityRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import com.adyen.demo.store.domain.Authority; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * Spring Data JPA repository for the {@link Authority} entity. 9 | */ 10 | public interface AuthorityRepository extends JpaRepository { 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/CustomerDetailsRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import java.util.Optional; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | import com.adyen.demo.store.domain.CustomerDetails; 7 | 8 | /** 9 | * Spring Data repository for the CustomerDetails entity. 10 | */ 11 | @SuppressWarnings("unused") 12 | @Repository 13 | public interface CustomerDetailsRepository extends JpaRepository { 14 | Optional findOneByUserLogin(String login); 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/PaymentCacheRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.Query; 7 | import org.springframework.stereotype.Repository; 8 | import com.adyen.demo.store.domain.PaymentCache; 9 | 10 | /** 11 | * Spring Data repository for the PaymentCache entity. 12 | */ 13 | @SuppressWarnings("unused") 14 | @Repository 15 | public interface PaymentCacheRepository extends JpaRepository { 16 | 17 | @Query("select paymentCache from PaymentCache paymentCache where paymentCache.user.login = ?#{principal.username}") 18 | List findByUserIsCurrentUser(); 19 | 20 | Optional findOneByOrderRef(String orderRef); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/PersistenceAuditEventRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import com.adyen.demo.store.domain.PersistentAuditEvent; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | 8 | import java.time.Instant; 9 | import java.util.List; 10 | 11 | /** 12 | * Spring Data JPA repository for the {@link PersistentAuditEvent} entity. 13 | */ 14 | public interface PersistenceAuditEventRepository extends JpaRepository { 15 | 16 | List findByPrincipal(String principal); 17 | 18 | List findByPrincipalAndAuditEventDateAfterAndAuditEventType(String principal, Instant after, String type); 19 | 20 | Page findAllByAuditEventDateBetween(Instant fromDate, Instant toDate, Pageable pageable); 21 | 22 | List findByAuditEventDateBefore(Instant before); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/ProductCategoryRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import com.adyen.demo.store.domain.ProductCategory; 4 | 5 | import org.springframework.data.jpa.repository.*; 6 | import org.springframework.stereotype.Repository; 7 | 8 | /** 9 | * Spring Data repository for the ProductCategory entity. 10 | */ 11 | @SuppressWarnings("unused") 12 | @Repository 13 | public interface ProductCategoryRepository extends JpaRepository { 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/ProductOrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import com.adyen.demo.store.domain.ProductOrder; 4 | 5 | import org.springframework.data.jpa.repository.*; 6 | import org.springframework.stereotype.Repository; 7 | 8 | /** 9 | * Spring Data repository for the ProductOrder entity. 10 | */ 11 | @SuppressWarnings("unused") 12 | @Repository 13 | public interface ProductOrderRepository extends JpaRepository { 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import com.adyen.demo.store.domain.Product; 4 | 5 | import org.springframework.data.jpa.repository.*; 6 | import org.springframework.stereotype.Repository; 7 | 8 | /** 9 | * Spring Data repository for the Product entity. 10 | */ 11 | @SuppressWarnings("unused") 12 | @Repository 13 | public interface ProductRepository extends JpaRepository { 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/ShoppingCartRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import java.util.List; 4 | import java.util.Optional; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.stereotype.Repository; 7 | import com.adyen.demo.store.domain.ShoppingCart; 8 | import com.adyen.demo.store.domain.enumeration.OrderStatus; 9 | 10 | /** 11 | * Spring Data repository for the ShoppingCart entity. 12 | */ 13 | @SuppressWarnings("unused") 14 | @Repository 15 | public interface ShoppingCartRepository extends JpaRepository { 16 | 17 | Optional findFirstByCustomerDetailsUserLoginAndStatusOrderByIdAsc(String login, OrderStatus orderStatus); 18 | 19 | List findAllByCustomerDetailsUserLoginAndStatusNot(String user, OrderStatus orderStatus); 20 | 21 | Optional findOneByPaymentModificationReference(String paymentRef); 22 | 23 | Optional findOneByPaymentReference(String paymentRef); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.repository; 2 | 3 | import com.adyen.demo.store.domain.User; 4 | 5 | import org.springframework.cache.annotation.Cacheable; 6 | import org.springframework.data.domain.Page; 7 | 8 | import org.springframework.data.domain.Pageable; 9 | import org.springframework.data.jpa.repository.EntityGraph; 10 | import org.springframework.data.jpa.repository.JpaRepository; 11 | import org.springframework.stereotype.Repository; 12 | 13 | import java.util.List; 14 | import java.util.Optional; 15 | import java.time.Instant; 16 | 17 | /** 18 | * Spring Data JPA repository for the {@link User} entity. 19 | */ 20 | @Repository 21 | public interface UserRepository extends JpaRepository { 22 | 23 | String USERS_BY_LOGIN_CACHE = "usersByLogin"; 24 | 25 | String USERS_BY_EMAIL_CACHE = "usersByEmail"; 26 | 27 | Optional findOneByActivationKey(String activationKey); 28 | 29 | List findAllByActivatedIsFalseAndActivationKeyIsNotNullAndCreatedDateBefore(Instant dateTime); 30 | 31 | Optional findOneByResetKey(String resetKey); 32 | 33 | Optional findOneByEmailIgnoreCase(String email); 34 | 35 | Optional findOneByLogin(String login); 36 | 37 | 38 | 39 | @EntityGraph(attributePaths = "authorities") 40 | Optional findOneWithAuthoritiesById(Long id); 41 | 42 | @EntityGraph(attributePaths = "authorities") 43 | @Cacheable(cacheNames = USERS_BY_LOGIN_CACHE) 44 | Optional findOneWithAuthoritiesByLogin(String login); 45 | 46 | @EntityGraph(attributePaths = "authorities") 47 | @Cacheable(cacheNames = USERS_BY_EMAIL_CACHE) 48 | Optional findOneWithAuthoritiesByEmailIgnoreCase(String email); 49 | 50 | Page findAllByLoginNot(Pageable pageable, String login); 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/repository/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Data JPA repositories. 3 | */ 4 | package com.adyen.demo.store.repository; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/security/AuthoritiesConstants.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/security/SpringSecurityAuditorAware.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.security; 2 | 3 | import com.adyen.demo.store.config.Constants; 4 | 5 | import java.util.Optional; 6 | 7 | import org.springframework.data.domain.AuditorAware; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * Implementation of {@link AuditorAware} based on Spring Security. 12 | */ 13 | @Component 14 | public class SpringSecurityAuditorAware implements AuditorAware { 15 | 16 | @Override 17 | public Optional getCurrentAuditor() { 18 | return Optional.of(SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM_ACCOUNT)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/security/UserNotActivatedException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/security/jwt/JWTConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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 final TokenProvider tokenProvider; 11 | 12 | public JWTConfigurer(TokenProvider tokenProvider) { 13 | this.tokenProvider = tokenProvider; 14 | } 15 | 16 | @Override 17 | public void configure(HttpSecurity http) { 18 | JWTFilter customFilter = new JWTFilter(tokenProvider); 19 | http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/security/jwt/JWTFilter.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.security.jwt; 2 | 3 | import org.springframework.security.core.Authentication; 4 | import org.springframework.security.core.context.SecurityContextHolder; 5 | import org.springframework.util.StringUtils; 6 | import org.springframework.web.filter.GenericFilterBean; 7 | 8 | import javax.servlet.FilterChain; 9 | import javax.servlet.ServletException; 10 | import javax.servlet.ServletRequest; 11 | import javax.servlet.ServletResponse; 12 | import javax.servlet.http.HttpServletRequest; 13 | import java.io.IOException; 14 | 15 | /** 16 | * Filters incoming requests and installs a Spring Security principal if a header corresponding to a valid user is 17 | * found. 18 | */ 19 | public class JWTFilter extends GenericFilterBean { 20 | 21 | public static final String AUTHORIZATION_HEADER = "Authorization"; 22 | 23 | private final TokenProvider tokenProvider; 24 | 25 | public JWTFilter(TokenProvider tokenProvider) { 26 | this.tokenProvider = tokenProvider; 27 | } 28 | 29 | @Override 30 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 31 | throws IOException, ServletException { 32 | HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; 33 | String jwt = resolveToken(httpServletRequest); 34 | if (StringUtils.hasText(jwt) && this.tokenProvider.validateToken(jwt)) { 35 | Authentication authentication = this.tokenProvider.getAuthentication(jwt); 36 | SecurityContextHolder.getContext().setAuthentication(authentication); 37 | } 38 | filterChain.doFilter(servletRequest, servletResponse); 39 | } 40 | 41 | private String resolveToken(HttpServletRequest request) { 42 | String bearerToken = request.getHeader(AUTHORIZATION_HEADER); 43 | if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { 44 | return bearerToken.substring(7); 45 | } 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/security/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring Security configuration. 3 | */ 4 | package com.adyen.demo.store.security; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/service/EmailAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.service; 2 | 3 | public class EmailAlreadyUsedException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public EmailAlreadyUsedException() { 8 | super("Email is already in use!"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/service/InvalidPasswordException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.service; 2 | 3 | public class InvalidPasswordException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public InvalidPasswordException() { 8 | super("Incorrect password"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/service/ProductService.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.service; 2 | 3 | import com.adyen.demo.store.domain.Product; 4 | import com.adyen.demo.store.repository.ProductRepository; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import org.springframework.data.domain.Page; 9 | import org.springframework.data.domain.Pageable; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | import java.util.Optional; 14 | 15 | /** 16 | * Service Implementation for managing {@link Product}. 17 | */ 18 | @Service 19 | @Transactional 20 | public class ProductService { 21 | 22 | private final Logger log = LoggerFactory.getLogger(ProductService.class); 23 | 24 | private final ProductRepository productRepository; 25 | 26 | public ProductService(ProductRepository productRepository) { 27 | this.productRepository = productRepository; 28 | } 29 | 30 | /** 31 | * Save a product. 32 | * 33 | * @param product the entity to save. 34 | * @return the persisted entity. 35 | */ 36 | public Product save(Product product) { 37 | log.debug("Request to save Product : {}", product); 38 | return productRepository.save(product); 39 | } 40 | 41 | /** 42 | * Get all the products. 43 | * 44 | * @param pageable the pagination information. 45 | * @return the list of entities. 46 | */ 47 | @Transactional(readOnly = true) 48 | public Page findAll(Pageable pageable) { 49 | log.debug("Request to get all Products"); 50 | return productRepository.findAll(pageable); 51 | } 52 | 53 | /** 54 | * Get one product by id. 55 | * 56 | * @param id the id of the entity. 57 | * @return the entity. 58 | */ 59 | @Transactional(readOnly = true) 60 | public Optional findOne(Long id) { 61 | log.debug("Request to get Product : {}", id); 62 | return productRepository.findById(id); 63 | } 64 | 65 | /** 66 | * Delete the product by id. 67 | * 68 | * @param id the id of the entity. 69 | */ 70 | public void delete(Long id) { 71 | log.debug("Request to delete Product : {}", id); 72 | productRepository.deleteById(id); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/service/UsernameAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.service; 2 | 3 | public class UsernameAlreadyUsedException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public UsernameAlreadyUsedException() { 8 | super("Login name already used!"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/service/dto/PasswordChangeDTO.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/service/dto/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Data Transfer Objects. 3 | */ 4 | package com.adyen.demo.store.service.dto; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/service/mapper/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MapStruct mappers for mapping domain objects and Data Transfer Objects. 3 | */ 4 | package com.adyen.demo.store.service.mapper; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/service/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Service layer beans. 3 | */ 4 | package com.adyen.demo.store.service; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/ClientForwardController.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.web.rest; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | 6 | @Controller 7 | public class ClientForwardController { 8 | 9 | /** 10 | * Forwards any unmapped paths (except those containing a period) to the client {@code index.html}. 11 | * @return forward to client {@code index.html}. 12 | */ 13 | @GetMapping(value = "/**/{path:[^\\.]*}") 14 | public String forward() { 15 | return "forward:/"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/errors/BadRequestAlertException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/web/rest/errors/EmailAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/web/rest/errors/EntityNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.web.rest.errors; 2 | 3 | import org.zalando.problem.AbstractThrowableProblem; 4 | import org.zalando.problem.Status; 5 | 6 | public class EntityNotFoundException extends AbstractThrowableProblem { 7 | 8 | private static final long serialVersionUID = 1L; 9 | 10 | public EntityNotFoundException(String entityName) { 11 | super(ErrorConstants.ENTITY_NOT_FOUND, entityName + " not found", Status.NOT_FOUND); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/errors/ErrorConstants.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.web.rest.errors; 2 | 3 | import java.net.URI; 4 | 5 | public final class ErrorConstants { 6 | 7 | public static final String ERR_CONCURRENCY_FAILURE = "error.concurrencyFailure"; 8 | public static final String ERR_VALIDATION = "error.validation"; 9 | public static final String PROBLEM_BASE_URL = "https://www.jhipster.tech/problem"; 10 | public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message"); 11 | public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation"); 12 | public static final URI INVALID_PASSWORD_TYPE = URI.create(PROBLEM_BASE_URL + "/invalid-password"); 13 | public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used"); 14 | public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used"); 15 | public static final URI ENTITY_NOT_FOUND = URI.create(PROBLEM_BASE_URL + "/entity-not-found"); 16 | 17 | private ErrorConstants() { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/errors/FieldErrorVM.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/web/rest/errors/InvalidPasswordException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/web/rest/errors/LoginAlreadyUsedException.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/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.adyen.demo.store.web.rest.errors; 7 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Spring MVC REST controllers. 3 | */ 4 | package com.adyen.demo.store.web.rest; 5 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/vm/KeyAndPasswordVM.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.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/adyen/demo/store/web/rest/vm/LoginVM.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.web.rest.vm; 2 | 3 | import javax.validation.constraints.NotNull; 4 | import javax.validation.constraints.Size; 5 | 6 | /** 7 | * View Model object for storing a user's credentials. 8 | */ 9 | public class LoginVM { 10 | 11 | @NotNull 12 | @Size(min = 1, max = 50) 13 | private String username; 14 | 15 | @NotNull 16 | @Size(min = 4, max = 100) 17 | private String password; 18 | 19 | private Boolean rememberMe; 20 | 21 | public String getUsername() { 22 | return username; 23 | } 24 | 25 | public void setUsername(String username) { 26 | this.username = username; 27 | } 28 | 29 | public String getPassword() { 30 | return password; 31 | } 32 | 33 | public void setPassword(String password) { 34 | this.password = password; 35 | } 36 | 37 | public Boolean isRememberMe() { 38 | return rememberMe; 39 | } 40 | 41 | public void setRememberMe(Boolean rememberMe) { 42 | this.rememberMe = rememberMe; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "LoginVM{" + 48 | "username='" + username + '\'' + 49 | ", rememberMe=" + rememberMe + 50 | '}'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/vm/ManagedUserVM.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.web.rest.vm; 2 | 3 | import com.adyen.demo.store.service.dto.UserDTO; 4 | import javax.validation.constraints.Size; 5 | 6 | /** 7 | * View Model extending the UserDTO, which is meant to be used in the user management UI. 8 | */ 9 | public class ManagedUserVM extends UserDTO { 10 | 11 | public static final int PASSWORD_MIN_LENGTH = 4; 12 | 13 | public static final int PASSWORD_MAX_LENGTH = 100; 14 | 15 | @Size(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH) 16 | private String password; 17 | 18 | public ManagedUserVM() { 19 | // Empty constructor needed for Jackson. 20 | } 21 | 22 | public String getPassword() { 23 | return password; 24 | } 25 | 26 | public void setPassword(String password) { 27 | this.password = password; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "ManagedUserVM{" + super.toString() + "} "; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/vm/PaymentRedirectVM.java: -------------------------------------------------------------------------------- 1 | package com.adyen.demo.store.web.rest.vm; 2 | 3 | public class PaymentRedirectVM { 4 | private String paRes; 5 | private String MD; 6 | 7 | public String getPaRes() { 8 | return paRes; 9 | } 10 | 11 | public PaymentRedirectVM setPaRes(final String paRes) { 12 | this.paRes = paRes; 13 | return this; 14 | } 15 | 16 | public String getMD() { 17 | return MD; 18 | } 19 | 20 | public PaymentRedirectVM setMD(final String MD) { 21 | this.MD = MD; 22 | return this; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return "PaymentRedirectVM{" + 28 | "paRes='" + paRes + '\'' + 29 | ", MD='" + MD + '\'' + 30 | '}'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/adyen/demo/store/web/rest/vm/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * View Models used by Spring MVC REST controllers. 3 | */ 4 | package com.adyen.demo.store.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} -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -cp /app/resources/:/app/classes/:/app/libs/* "com.adyen.demo.store.StoreApp" "$@" 5 | -------------------------------------------------------------------------------- /src/main/resources/.h2.server.properties: -------------------------------------------------------------------------------- 1 | #H2 Server Properties 2 | 0=JHipster H2 (Disk)|org.h2.Driver|jdbc\:h2\:file\:./build/h2db/db/store|store 3 | webAllowOthers=true 4 | webPort=8082 5 | webSSL=false 6 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | ${AnsiColor.GREEN} ██╗${AnsiColor.CYAN} ██╗ ██╗ ████████╗ ███████╗ ██████╗ ████████╗ ████████╗ ███████╗ 3 | ${AnsiColor.GREEN} ██║${AnsiColor.CYAN} ██║ ██║ ╚══██╔══╝ ██╔═══██╗ ██╔════╝ ╚══██╔══╝ ██╔═════╝ ██╔═══██╗ 4 | ${AnsiColor.GREEN} ██║${AnsiColor.CYAN} ████████║ ██║ ███████╔╝ ╚█████╗ ██║ ██████╗ ███████╔╝ 5 | ${AnsiColor.GREEN}██╗ ██║${AnsiColor.CYAN} ██╔═══██║ ██║ ██╔════╝ ╚═══██╗ ██║ ██╔═══╝ ██╔══██║ 6 | ${AnsiColor.GREEN}╚██████╔╝${AnsiColor.CYAN} ██║ ██║ ████████╗ ██║ ██████╔╝ ██║ ████████╗ ██║ ╚██╗ 7 | ${AnsiColor.GREEN} ╚═════╝ ${AnsiColor.CYAN} ╚═╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══════╝ ╚═╝ ╚═╝ 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: adyen-demo-store.herokuapp.com 16 | non-secure-port: 80 17 | prefer-ip-address: false 18 | 19 | spring: 20 | datasource: 21 | type: com.zaxxer.hikari.HikariDataSource 22 | url: ${JDBC_DATABASE_URL} 23 | username: ${JDBC_DATABASE_USERNAME} 24 | password: ${JDBC_DATABASE_PASSWORD} 25 | hikari: 26 | maximumPoolSize: 8 27 | liquibase: 28 | # Remove 'faker' if you do not want the sample data to be loaded automatically 29 | contexts: prod, faker 30 | -------------------------------------------------------------------------------- /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 | ciphers: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 17 | enabled-protocols: TLSv1.2 18 | http2: 19 | enabled: true 20 | -------------------------------------------------------------------------------- /src/main/resources/config/bootstrap-heroku.yml: -------------------------------------------------------------------------------- 1 | # =================================================================== 2 | # Spring Cloud Config bootstrap configuration for the "heroku" profile 3 | # =================================================================== 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20200424080100_added_entity_constraints_Product.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20200424080300_added_entity_constraints_CustomerDetails.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20200424080400_added_entity_constraints_ShoppingCart.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20200424080500_added_entity_ProductOrder.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 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/20200424080500_added_entity_constraints_ProductOrder.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/changelog/20201218114000_added_entity_PaymentCache.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 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/20201218114000_added_entity_constraints_PaymentCache.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/data/authority.csv: -------------------------------------------------------------------------------- 1 | name 2 | ROLE_ADMIN 3 | ROLE_USER 4 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/data/user.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 | 5;webhook;$2a$10$gSAhZrxMllrbgj/kkK9UceBPpChGWJA7SYIb1Mqo.n5aNLq1/oRrC;Webhook User;User;webhook-user@localhost;;true;en;system;system 7 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/data/user_authority.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 | 5;ROLE_USER 8 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/blob/shirt1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/src/main/resources/config/liquibase/fake-data/blob/shirt1.jpg -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/blob/shirt2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/src/main/resources/config/liquibase/fake-data/blob/shirt2.jpg -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/blob/shirt3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/src/main/resources/config/liquibase/fake-data/blob/shirt3.jpg -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/customer_details.csv: -------------------------------------------------------------------------------- 1 | id;gender;phone;address_line_1;address_line_2;city;country;user_id 2 | 1;MALE;+31 657657008;150 Larensweg;;Hilversum;Netherlands;3 3 | 2;FEMALE;+31 657657009;Londonstraat 4;;Utrecht;Netherlands;4 4 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/product.csv: -------------------------------------------------------------------------------- 1 | id;name;description;price;size;image;image_content_type;product_category_id 2 | 1;JHipster T-Shirt;T-Shirt with JHipster logo;12;S;../fake-data/blob/shirt3.jpg;image/png;1 3 | 2;JHipster T-Shirt;T-Shirt with JHipster logo;15;M;../fake-data/blob/shirt3.jpg;image/png;1 4 | 3;JHipster T-Shirt;T-Shirt with JHipster logo;18;L;../fake-data/blob/shirt3.jpg;image/png;1 5 | 4;Special Spring T-Shirt;T-Shirt with Spring logo;20;XL;../fake-data/blob/shirt3.jpg;image/png;1 6 | 5;Special Spring T-Shirt;T-Shirt with Spring logo;20;S;../fake-data/blob/shirt2.jpg;image/png;5 7 | 6;Special Spring T-Shirt;T-Shirt with Spring logo;22;M;../fake-data/blob/shirt2.jpg;image/png;5 8 | 7;Special Spring T-Shirt;T-Shirt with Spring logo;25;L;../fake-data/blob/shirt2.jpg;image/png;5 9 | 8;Special Spring T-Shirt;T-Shirt with Spring logo;20;S;../fake-data/blob/shirt1.jpg;image/png;6 10 | 9;Special Spring T-Shirt;T-Shirt with Spring logo;22;M;../fake-data/blob/shirt1.jpg;image/png;6 11 | 10;Special Spring T-Shirt;T-Shirt with Spring logo;25;L;../fake-data/blob/shirt1.jpg;image/png;6 12 | -------------------------------------------------------------------------------- /src/main/resources/config/liquibase/fake-data/product_category.csv: -------------------------------------------------------------------------------- 1 | id;name;description 2 | 1;T-shirt;Unisex T-Shirts 3 | 2;Men's Jeans;Branded jeans for men 4 | 3;Women's Jeans;Branded jeans for women 5 | 4;Top;Women's top 6 | 5;Summer collection women;Special summer collection for women 7 | 6;Summer collection men;Special summer collection for men 8 | 7;Trousers;Formal trousers 9 | 8;Sports;Sports wear 10 | 9;Beach wear;Beach wear for men & women 11 | 10;Suits;Suits for men 12 | -------------------------------------------------------------------------------- /src/main/resources/config/tls/keystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/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=store account activation is required 9 | email.activation.greeting=Dear {0} 10 | email.activation.text1=Your store account has been created, please click on the URL below to activate it: 11 | email.activation.text2=Regards, 12 | email.signature=store Team. 13 | 14 | # Creation email 15 | email.creation.text1=Your store account has been created, please click on the URL below to access it: 16 | 17 | # Reset email 18 | email.reset.title=store password reset 19 | email.reset.greeting=Dear {0} 20 | email.reset.text1=For your store 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 | JHipster 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 | Login link 18 |

19 |

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

24 | 25 | 26 | -------------------------------------------------------------------------------- /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/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | html 10 | text/html;charset=utf-8 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /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: #e4e5e6; 29 | -------------------------------------------------------------------------------- /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 = 1 * 60 * 1000; 7 | axios.defaults.timeout = TIMEOUT; 8 | axios.defaults.baseURL = SERVER_API_URL; 9 | 10 | const setupAxiosInterceptors = onUnauthenticated => { 11 | const onRequestSuccess = config => { 12 | const token = Storage.local.get('jhi-authenticationToken') || Storage.session.get('jhi-authenticationToken'); 13 | if (token) { 14 | config.headers.Authorization = `Bearer ${token}`; 15 | } 16 | return config; 17 | }; 18 | const onResponseSuccess = response => response; 19 | const onResponseError = err => { 20 | const status = err.status || (err.response ? err.response.status : 0); 21 | if (status === 403 || status === 401) { 22 | onUnauthenticated(); 23 | } 24 | return Promise.reject(err); 25 | }; 26 | axios.interceptors.request.use(onRequestSuccess); 27 | axios.interceptors.response.use(onResponseSuccess, onResponseError); 28 | }; 29 | 30 | export default setupAxiosInterceptors; 31 | -------------------------------------------------------------------------------- /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_LOCAL_DATETIME_FORMAT_Z = 'YYYY-MM-DDTHH:mm Z'; 23 | export const APP_WHOLE_NUMBER_FORMAT = '0,0'; 24 | export const APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT = '0,0.[00]'; 25 | -------------------------------------------------------------------------------- /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 | /* eslint no-console: off */ 2 | export default () => next => action => { 3 | if (process.env.NODE_ENV !== 'production') { 4 | const { type, payload, meta } = action; 5 | 6 | console.groupCollapsed(type); 7 | console.log('Payload:', payload); 8 | console.log('Meta:', meta); 9 | console.groupEnd(); 10 | } 11 | 12 | return next(action); 13 | }; 14 | -------------------------------------------------------------------------------- /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(applyMiddleware(...defaultMiddlewares, ...middlewares), DevTools.instrument()) 22 | : compose(applyMiddleware(...defaultMiddlewares, ...middlewares)); 23 | 24 | const initialize = (initialState?: IRootState, middlewares = []) => createStore(reducer, initialState, composedMiddlewares(middlewares)); 25 | 26 | export default initialize; 27 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/customer-details/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 CustomerDetails from './customer-details'; 7 | import CustomerDetailsDetail from './customer-details-detail'; 8 | import CustomerDetailsUpdate from './customer-details-update'; 9 | import CustomerDetailsDeleteDialog from './customer-details-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 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 5 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route'; 6 | 7 | import Product from './product'; 8 | import ProductCategory from './product-category'; 9 | import CustomerDetails from './customer-details'; 10 | import ShoppingCart from './shopping-cart'; 11 | import ProductOrder from './product-order'; 12 | /* jhipster-needle-add-route-import - JHipster will add routes here */ 13 | 14 | const Routes = ({ match }) => ( 15 |
16 | 17 | {/* prettier-ignore */} 18 | 19 | 20 | 21 | 22 | 23 | {/* jhipster-needle-add-route-path - JHipster will add routes here */} 24 | 25 |
26 | ); 27 | 28 | export default Routes; 29 | -------------------------------------------------------------------------------- /src/main/webapp/app/entities/product-category/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 ProductCategory from './product-category'; 7 | import ProductCategoryDetail from './product-category-detail'; 8 | import ProductCategoryUpdate from './product-category-update'; 9 | import ProductCategoryDeleteDialog from './product-category-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/product-order/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 ProductOrder from './product-order'; 7 | import ProductOrderDetail from './product-order-detail'; 8 | import ProductOrderUpdate from './product-order-update'; 9 | import ProductOrderDeleteDialog from './product-order-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/product/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 Product from './product'; 7 | import ProductDetail from './product-detail'; 8 | import ProductUpdate from './product-update'; 9 | import ProductDeleteDialog from './product-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/shopping-cart/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 ShoppingCart from './shopping-cart'; 7 | import ShoppingCartDetail from './shopping-cart-detail'; 8 | import ShoppingCartUpdate from './shopping-cart-update'; 9 | import ShoppingCartDeleteDialog from './shopping-cart-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/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 | 6 | import DevTools from './config/devtools'; 7 | import initStore from './config/store'; 8 | import setupAxiosInterceptors from './config/axios-interceptor'; 9 | import { clearAuthentication } from './shared/reducers/authentication'; 10 | import ErrorBoundary from './shared/error/error-boundary'; 11 | import AppComponent from './app'; 12 | import { loadIcons } from './config/icon-loader'; 13 | 14 | const devTools = process.env.NODE_ENV === 'development' ? : null; 15 | 16 | const store = initStore(); 17 | 18 | const actions = bindActionCreators({ clearAuthentication }, store.dispatch); 19 | setupAxiosInterceptors(() => actions.clearAuthentication('login.error.unauthorized')); 20 | 21 | loadIcons(); 22 | 23 | const rootEl = document.getElementById('root'); 24 | 25 | const render = Component => 26 | // eslint-disable-next-line react/no-render-return-value 27 | ReactDOM.render( 28 | 29 | 30 |
31 | {/* If this slows down the app in dev disable it and enable when required */} 32 | {devTools} 33 | 34 |
35 |
36 |
, 37 | rootEl 38 | ); 39 | 40 | render(AppComponent); 41 | -------------------------------------------------------------------------------- /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, { useEffect } 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 | 20 | const failureAlert = ( 21 | 22 | Your user could not be activated. Please use the registration form to sign up. 23 | 24 | ); 25 | 26 | export interface IActivateProps extends StateProps, DispatchProps, RouteComponentProps<{ key: any }> {} 27 | 28 | export const ActivatePage = (props: IActivateProps) => { 29 | useEffect(() => { 30 | const key = getUrlParameter('key', props.location.search); 31 | props.activateAction(key); 32 | return () => { 33 | props.reset(); 34 | }; 35 | }, []); 36 | 37 | return ( 38 |
39 | 40 | 41 |

Activation

42 | {props.activationSuccess ? successAlert : undefined} 43 | {props.activationFailure ? failureAlert : undefined} 44 | 45 |
46 |
47 | ); 48 | }; 49 | 50 | const mapStateToProps = ({ activate }: IRootState) => ({ 51 | activationSuccess: activate.activationSuccess, 52 | activationFailure: activate.activationFailure 53 | }); 54 | 55 | const mapDispatchToProps = { activateAction, reset }; 56 | 57 | type StateProps = ReturnType; 58 | type DispatchProps = typeof mapDispatchToProps; 59 | 60 | export default connect(mapStateToProps, mapDispatchToProps)(ActivatePage); 61 | -------------------------------------------------------------------------------- /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(null, mapDispatchToProps)(PasswordResetInit); 59 | -------------------------------------------------------------------------------- /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 = (values, langKey = 'en') => ({ 49 | type: ACTION_TYPES.CREATE_ACCOUNT, 50 | payload: axios.post('api/register', { 51 | ...values, 52 | login: values.username, 53 | password: values.firstPassword, 54 | langKey 55 | }), 56 | meta: { 57 | successMessage: 'Registration saved! Please check your email for confirmation.' 58 | } 59 | }); 60 | 61 | export const reset = () => ({ 62 | type: ACTION_TYPES.RESET 63 | }); 64 | -------------------------------------------------------------------------------- /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 | 65 | await dispatch(getSession()); 66 | }; 67 | 68 | export const reset = () => ({ 69 | type: ACTION_TYPES.RESET 70 | }); 71 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/administration/docs/docs.scss: -------------------------------------------------------------------------------- 1 | iframe { 2 | background: white; 3 | } 4 | -------------------------------------------------------------------------------- /src/main/webapp/app/modules/administration/docs/docs.tsx: -------------------------------------------------------------------------------- 1 | import './docs.scss'; 2 | 3 | import React from 'react'; 4 | 5 | const DocsPage = () => ( 6 |
7 |