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 |
8 |
9 | );
10 |
11 | export default DocsPage;
12 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/administration/health/health-modal.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Table, Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
3 |
4 | const formatDiskSpaceOutput = rawValue => {
5 | // Should display storage space in an human readable unit
6 | const val = rawValue / 1073741824;
7 | if (val > 1) {
8 | // Value
9 | return val.toFixed(2) + ' GB';
10 | } else {
11 | return (rawValue / 1048576).toFixed(2) + ' MB';
12 | }
13 | };
14 |
15 | const HealthModal = ({ handleClose, healthObject, showModal }) => {
16 | const data = healthObject.details || {};
17 | return (
18 |
19 | {healthObject.name}
20 |
21 |
22 |
23 |
24 | Name |
25 | Value |
26 |
27 |
28 |
29 | {Object.keys(data).map((key, index) => (
30 |
31 | {key} |
32 | {healthObject.name === 'diskSpace' ? formatDiskSpaceOutput(data[key]) : JSON.stringify(data[key])} |
33 |
34 | ))}
35 |
36 |
37 |
38 |
39 |
42 |
43 |
44 | );
45 | };
46 |
47 | export default HealthModal;
48 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/administration/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route';
4 | import UserManagement from './user-management';
5 | import Logs from './logs/logs';
6 | import Health from './health/health';
7 | import Metrics from './metrics/metrics';
8 | import Configuration from './configuration/configuration';
9 | import Audits from './audits/audits';
10 | import Docs from './docs/docs';
11 |
12 | const Routes = ({ match }) => (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | );
23 |
24 | export default Routes;
25 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/administration/user-management/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 | import UserManagement from './user-management';
6 | import UserManagementDetail from './user-management-detail';
7 | import UserManagementUpdate from './user-management-update';
8 | import UserManagementDeleteDialog from './user-management-delete-dialog';
9 |
10 | const Routes = ({ match }) => (
11 | <>
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | >
20 | );
21 |
22 | export default Routes;
23 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/administration/user-management/user-management-delete-dialog.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 | import { connect } from 'react-redux';
3 | import { RouteComponentProps } from 'react-router-dom';
4 | import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
5 |
6 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
7 |
8 | import { getUser, deleteUser } from './user-management.reducer';
9 | import { IRootState } from 'app/shared/reducers';
10 |
11 | export interface IUserManagementDeleteDialogProps extends StateProps, DispatchProps, RouteComponentProps<{ login: string }> {}
12 |
13 | export const UserManagementDeleteDialog = (props: IUserManagementDeleteDialogProps) => {
14 | useEffect(() => {
15 | props.getUser(props.match.params.login);
16 | }, []);
17 |
18 | const handleClose = event => {
19 | event.stopPropagation();
20 | props.history.push('/admin/user-management');
21 | };
22 |
23 | const confirmDelete = event => {
24 | props.deleteUser(props.user.login);
25 | handleClose(event);
26 | };
27 |
28 | const { user } = props;
29 |
30 | return (
31 |
32 | Confirm delete operation
33 | Are you sure you want to delete this User?
34 |
35 |
39 |
43 |
44 |
45 | );
46 | };
47 |
48 | const mapStateToProps = (storeState: IRootState) => ({
49 | user: storeState.userManagement.user
50 | });
51 |
52 | const mapDispatchToProps = { getUser, deleteUser };
53 |
54 | type StateProps = ReturnType;
55 | type DispatchProps = typeof mapDispatchToProps;
56 |
57 | export default connect(mapStateToProps, mapDispatchToProps)(UserManagementDeleteDialog);
58 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/checkout/checkout-status.tsx:
--------------------------------------------------------------------------------
1 | import './checkout.scss';
2 |
3 | import React from 'react';
4 | import { Link, useParams, useLocation } from 'react-router-dom';
5 | import { Button } from 'reactstrap';
6 |
7 | export const Message = ({ type, reason }) => {
8 | let msg: JSX.Element, img: string;
9 | switch (type) {
10 | case 'pending':
11 | msg = Your order has been received! Payment completion pending.;
12 | img = 'success';
13 | break;
14 | case 'failed':
15 | msg = The payment was refused. Please try a different payment method or card.;
16 | img = 'failed';
17 | break;
18 | case 'error':
19 | msg = (
20 |
21 | Error! Reason: {reason || 'Internal error'}, refer to
22 | Response handling.
23 |
24 | );
25 | img = 'failed';
26 | break;
27 | default:
28 | msg = Your order has been successfully placed.;
29 | img = 'success';
30 | }
31 |
32 | return (
33 | <>
34 |
35 | {['failed', 'error'].includes(type) ? null : }
36 | {msg}
37 | >
38 | );
39 | };
40 |
41 | export default () => {
42 | const { type } = useParams<{ type: string }>();
43 | const query = new URLSearchParams(useLocation().search);
44 | const reason = query ? query.get('reason') : '';
45 |
46 | return (
47 |
48 |
49 |
50 |
53 |
54 |
55 | );
56 | };
57 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/checkout/checkout.scss:
--------------------------------------------------------------------------------
1 |
2 | .status-container {
3 | .status {
4 | text-align: center;
5 | .status-image {
6 | display: inline-block;
7 | width: 100%;
8 | height: 120px;
9 | &.failed{
10 | background: url('../../../content/images/failed.svg') no-repeat center top;
11 | }
12 | &.success{
13 | background: url('../../../content/images/success.svg') no-repeat center top;
14 | }
15 | &.thank-you{
16 | background: url('../../../content/images/thank-you.svg') no-repeat center top;
17 | }
18 | background-size: contain;
19 | }
20 |
21 | .status-message {
22 | text-align: center;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/home/home.scss:
--------------------------------------------------------------------------------
1 | /* ==========================================================================
2 | Main page styles
3 | ========================================================================== */
4 | .sort-btns .fa-sort {
5 | position: relative;
6 | top: 4px;
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/login/login.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { connect } from 'react-redux';
3 | import { Redirect, RouteComponentProps } from 'react-router-dom';
4 |
5 | import { IRootState } from 'app/shared/reducers';
6 | import { login } from 'app/shared/reducers/authentication';
7 | import LoginModal from './login-modal';
8 |
9 | export interface ILoginProps extends StateProps, DispatchProps, RouteComponentProps<{}> {}
10 |
11 | export const Login = (props: ILoginProps) => {
12 | const [showModal, setShowModal] = useState(props.showModal);
13 |
14 | useEffect(() => {
15 | setShowModal(true);
16 | }, []);
17 |
18 | const handleLogin = (username, password, rememberMe = false) => props.login(username, password, rememberMe);
19 |
20 | const handleClose = () => {
21 | setShowModal(false);
22 | props.history.push('/');
23 | };
24 |
25 | const { location, isAuthenticated } = props;
26 | const { from } = (location.state as any) || { from: { pathname: '/', search: location.search } };
27 | if (isAuthenticated) {
28 | return ;
29 | }
30 | return ;
31 | };
32 |
33 | const mapStateToProps = ({ authentication }: IRootState) => ({
34 | isAuthenticated: authentication.isAuthenticated,
35 | loginError: authentication.loginError,
36 | showModal: authentication.showModalLogin
37 | });
38 |
39 | const mapDispatchToProps = { login };
40 |
41 | type StateProps = ReturnType;
42 | type DispatchProps = typeof mapDispatchToProps;
43 |
44 | export default connect(mapStateToProps, mapDispatchToProps)(Login);
45 |
--------------------------------------------------------------------------------
/src/main/webapp/app/modules/login/logout.tsx:
--------------------------------------------------------------------------------
1 | import React, { useLayoutEffect } from 'react';
2 | import { connect } from 'react-redux';
3 |
4 | import { IRootState } from 'app/shared/reducers';
5 | import { logout } from 'app/shared/reducers/authentication';
6 |
7 | export interface ILogoutProps extends StateProps, DispatchProps {
8 | idToken: string;
9 | logoutUrl: string;
10 | }
11 |
12 | export const Logout = (props: ILogoutProps) => {
13 | useLayoutEffect(() => {
14 | props.logout();
15 | const logoutUrl = props.logoutUrl;
16 | if (logoutUrl) {
17 | // if Keycloak, logoutUrl has protocol/openid-connect in it
18 | window.location.href = logoutUrl.includes('/protocol')
19 | ? logoutUrl + '?redirect_uri=' + window.location.origin
20 | : logoutUrl + '?id_token_hint=' + props.idToken + '&post_logout_redirect_uri=' + window.location.origin;
21 | }
22 | });
23 |
24 | return (
25 |
26 |
Logged out successfully!
27 |
28 | );
29 | };
30 |
31 | const mapStateToProps = (storeState: IRootState) => ({
32 | logoutUrl: storeState.authentication.logoutUrl,
33 | idToken: storeState.authentication.idToken
34 | });
35 |
36 | const mapDispatchToProps = { logout };
37 |
38 | type StateProps = ReturnType;
39 | type DispatchProps = typeof mapDispatchToProps;
40 |
41 | export default connect(mapStateToProps, mapDispatchToProps)(Logout);
42 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/error/error-boundary-route.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Route, RouteProps } from 'react-router-dom';
3 | import ErrorBoundary from 'app/shared/error/error-boundary';
4 |
5 | export const ErrorBoundaryRoute = ({ component: Component, ...rest }: RouteProps) => {
6 | const encloseInErrorBoundary = props => (
7 |
8 |
9 |
10 | );
11 |
12 | if (!Component) throw new Error(`A component needs to be specified for path ${(rest as any).path}`);
13 |
14 | return ;
15 | };
16 |
17 | export default ErrorBoundaryRoute;
18 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/error/error-boundary.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | interface IErrorBoundaryProps {
4 | readonly children: JSX.Element | JSX.Element[];
5 | }
6 |
7 | interface IErrorBoundaryState {
8 | readonly error: any;
9 | readonly errorInfo: any;
10 | }
11 |
12 | class ErrorBoundary extends React.Component {
13 | readonly state: IErrorBoundaryState = { error: undefined, errorInfo: undefined };
14 |
15 | componentDidCatch(error, errorInfo) {
16 | this.setState({
17 | error,
18 | errorInfo
19 | });
20 | }
21 |
22 | render() {
23 | const { error, errorInfo } = this.state;
24 | if (errorInfo) {
25 | const errorDetails =
26 | process.env.NODE_ENV === 'development' ? (
27 |
28 | {error && error.toString()}
29 |
30 | {errorInfo.componentStack}
31 |
32 | ) : (
33 | undefined
34 | );
35 | return (
36 |
37 |
An unexpected error has occurred.
38 | {errorDetails}
39 |
40 | );
41 | }
42 | return this.props.children;
43 | }
44 | }
45 |
46 | export default ErrorBoundary;
47 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/error/page-not-found.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { Row, Col, Alert } from 'reactstrap';
4 |
5 | class PageNotFound extends React.Component {
6 | render() {
7 | return (
8 |
9 |
The page does not exist.
10 |
11 | );
12 | }
13 | }
14 |
15 | export default PageNotFound;
16 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/footer/footer.scss:
--------------------------------------------------------------------------------
1 | .footer {
2 | height: 50px;
3 | }
4 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/footer/footer.tsx:
--------------------------------------------------------------------------------
1 | import './footer.scss';
2 |
3 | import React from 'react';
4 |
5 | import { Col, Row } from 'reactstrap';
6 |
7 | const Footer = props => (
8 |
9 |
10 |
11 |
12 | You can find the source code of this application on{' '}
13 |
14 | Github
15 |
16 |
17 |
18 |
19 |
20 | );
21 |
22 | export default Footer;
23 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/header/header-components.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { NavItem, NavLink, NavbarBrand } from 'reactstrap';
4 | import { NavLink as Link } from 'react-router-dom';
5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6 |
7 | import appConfig from 'app/config/constants';
8 |
9 | export const BrandIcon = props => (
10 |
11 |

12 |
13 | );
14 |
15 | export const Brand = props => (
16 |
17 |
18 | Demo Store
19 | {appConfig.VERSION}
20 |
21 | );
22 |
23 | export const Home = props => (
24 |
25 |
26 |
27 | Home
28 |
29 |
30 | );
31 |
32 | export const Cart = props => (
33 |
34 |
35 |
36 | My Cart
37 |
38 |
39 | );
40 |
41 | export const Orders = props => (
42 |
43 |
44 |
45 | My Orders
46 |
47 |
48 | );
49 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/header/header.tsx:
--------------------------------------------------------------------------------
1 | import './header.scss';
2 |
3 | import React, { useState } from 'react';
4 |
5 | import { Navbar, Nav, NavbarToggler, Collapse } from 'reactstrap';
6 |
7 | import LoadingBar from 'react-redux-loading-bar';
8 |
9 | import { Home, Brand, Cart, Orders } from './header-components';
10 | import { AdminMenu, EntitiesMenu, AccountMenu } from '../menus';
11 |
12 | export interface IHeaderProps {
13 | isAuthenticated: boolean;
14 | isAdmin: boolean;
15 | ribbonEnv: string;
16 | isInProduction: boolean;
17 | isSwaggerEnabled: boolean;
18 | }
19 |
20 | const Header = (props: IHeaderProps) => {
21 | const [menuOpen, setMenuOpen] = useState(false);
22 |
23 | const renderDevRibbon = () =>
24 | props.isInProduction === false ? (
25 |
28 | ) : null;
29 |
30 | const toggleMenu = () => setMenuOpen(!menuOpen);
31 |
32 | /* jhipster-needle-add-element-to-menu - JHipster will add new menu items here */
33 |
34 | return (
35 |
55 | );
56 | };
57 |
58 | export default Header;
59 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/menus/account.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import MenuItem from 'app/shared/layout/menus/menu-item';
3 | import { DropdownItem } from 'reactstrap';
4 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5 | import { NavLink as Link } from 'react-router-dom';
6 |
7 | import { NavDropdown } from './menu-components';
8 |
9 | const accountMenuItemsAuthenticated = (
10 | <>
11 |
14 |
17 |
20 | >
21 | );
22 |
23 | const accountMenuItems = (
24 | <>
25 |
28 |
31 | >
32 | );
33 |
34 | export const AccountMenu = ({ isAuthenticated = false }) => (
35 |
38 | );
39 |
40 | export default AccountMenu;
41 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/menus/admin.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import MenuItem from 'app/shared/layout/menus/menu-item';
3 | import { DropdownItem } from 'reactstrap';
4 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5 | import { NavLink as Link } from 'react-router-dom';
6 | import { NavDropdown } from './menu-components';
7 |
8 | const adminMenuItems = (
9 | <>
10 |
13 |
16 |
19 |
22 |
25 | {/* jhipster-needle-add-element-to-admin-menu - JHipster will add entities to the admin menu here */}
26 |
29 | >
30 | );
31 |
32 | const swaggerItem = (
33 |
36 | );
37 |
38 | const databaseItem = (
39 |
40 | Database
41 |
42 | );
43 |
44 | export const AdminMenu = ({ showSwagger, showDatabase }) => (
45 |
51 | );
52 |
53 | export default AdminMenu;
54 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/menus/entities.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import MenuItem from 'app/shared/layout/menus/menu-item';
3 | import { DropdownItem } from 'reactstrap';
4 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5 |
6 | import { NavLink as Link } from 'react-router-dom';
7 | import { NavDropdown } from './menu-components';
8 |
9 | export const EntitiesMenu = props => (
10 |
28 | );
29 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/menus/index.ts:
--------------------------------------------------------------------------------
1 | export * from './account';
2 | export * from './admin';
3 | export * from './entities';
4 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/menus/menu-components.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { UncontrolledDropdown, DropdownToggle, DropdownMenu } from 'reactstrap';
4 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5 |
6 | export const NavDropdown = props => (
7 |
8 |
9 |
10 | {props.name}
11 |
12 |
13 | {props.children}
14 |
15 |
16 | );
17 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/menus/menu-item.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { DropdownItem } from 'reactstrap';
3 | import { NavLink as Link } from 'react-router-dom';
4 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5 | import { IconProp } from '@fortawesome/fontawesome-svg-core';
6 |
7 | export interface IMenuItem {
8 | icon: IconProp;
9 | to: string;
10 | id?: string;
11 | }
12 |
13 | export default class MenuItem extends React.Component {
14 | render() {
15 | const { to, icon, id, children } = this.props;
16 |
17 | return (
18 |
19 | {children}
20 |
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/password/password-strength-bar.scss:
--------------------------------------------------------------------------------
1 | /* ==========================================================================
2 | start Password strength bar style
3 | ========================================================================== */
4 | ul#strength {
5 | display: inline;
6 | list-style: none;
7 | margin: 0;
8 | margin-left: 15px;
9 | padding: 0;
10 | vertical-align: 2px;
11 | }
12 |
13 | .point {
14 | background: #ddd;
15 | border-radius: 2px;
16 | display: inline-block;
17 | height: 5px;
18 | margin-right: 1px;
19 | width: 20px;
20 | &:last-child {
21 | margin: 0 !important;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/layout/password/password-strength-bar.tsx:
--------------------------------------------------------------------------------
1 | import './password-strength-bar.scss';
2 |
3 | import React from 'react';
4 |
5 | export interface IPasswordStrengthBarProps {
6 | password: string;
7 | }
8 |
9 | export const PasswordStrengthBar = ({ password }: IPasswordStrengthBarProps) => {
10 | const colors = ['#F00', '#F90', '#FF0', '#9F0', '#0F0'];
11 |
12 | const measureStrength = (p: string): number => {
13 | let force = 0;
14 | const regex = /[$-/:-?{-~!"^_`[\]]/g;
15 | const flags = {
16 | lowerLetters: /[a-z]+/.test(p),
17 | upperLetters: /[A-Z]+/.test(p),
18 | numbers: /[0-9]+/.test(p),
19 | symbols: regex.test(p)
20 | };
21 |
22 | const passedMatches = Object.values(flags).filter((isMatchedFlag: boolean) => !!isMatchedFlag).length;
23 |
24 | force += 2 * p.length + (p.length >= 10 ? 1 : 0);
25 | force += passedMatches * 10;
26 |
27 | // penalty (short password)
28 | force = p.length <= 6 ? Math.min(force, 10) : force;
29 |
30 | // penalty (poor variety of characters)
31 | force = passedMatches === 1 ? Math.min(force, 10) : force;
32 | force = passedMatches === 2 ? Math.min(force, 20) : force;
33 | force = passedMatches === 3 ? Math.min(force, 40) : force;
34 |
35 | return force;
36 | };
37 |
38 | const getColor = (s: number): any => {
39 | let idx = 0;
40 | if (s <= 10) {
41 | idx = 0;
42 | } else if (s <= 20) {
43 | idx = 1;
44 | } else if (s <= 30) {
45 | idx = 2;
46 | } else if (s <= 40) {
47 | idx = 3;
48 | } else {
49 | idx = 4;
50 | }
51 | return { idx: idx + 1, col: colors[idx] };
52 | };
53 |
54 | const getPoints = force => {
55 | const pts = [] as any[];
56 | for (let i = 0; i < 5; i++) {
57 | pts.push();
58 | }
59 | return pts;
60 | };
61 |
62 | const strength = getColor(measureStrength(password));
63 | const points = getPoints(strength);
64 |
65 | return (
66 |
67 |
Password strength:
68 |
69 |
70 | );
71 | };
72 |
73 | export default PasswordStrengthBar;
74 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/customer-details.model.ts:
--------------------------------------------------------------------------------
1 | import { IUser } from 'app/shared/model/user.model';
2 | import { IShoppingCart } from 'app/shared/model/shopping-cart.model';
3 | import { Gender } from 'app/shared/model/enumerations/gender.model';
4 |
5 | export interface ICustomerDetails {
6 | id?: number;
7 | gender?: Gender;
8 | phone?: string;
9 | addressLine1?: string;
10 | addressLine2?: string;
11 | city?: string;
12 | country?: string;
13 | user?: IUser;
14 | carts?: IShoppingCart[];
15 | }
16 |
17 | export const defaultValue: Readonly = {};
18 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/enumerations/gender.model.ts:
--------------------------------------------------------------------------------
1 | export const enum Gender {
2 | MALE = 'MALE',
3 | FEMALE = 'FEMALE',
4 | OTHER = 'OTHER'
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/enumerations/order-status.model.ts:
--------------------------------------------------------------------------------
1 | export const enum OrderStatus {
2 | REFUND_INITIATED = 'REFUND_INITIATED',
3 | REFUND_FAILED = 'REFUND_FAILED',
4 | PAID = 'PAID',
5 | PENDING = 'PENDING',
6 | OPEN = 'OPEN',
7 | CANCELLED = 'CANCELLED',
8 | REFUNDED = 'REFUNDED'
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/enumerations/payment-method.model.ts:
--------------------------------------------------------------------------------
1 | export const enum PaymentMethod {
2 | CREDIT_CARD = 'CREDIT_CARD',
3 | IDEAL = 'IDEAL'
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/enumerations/size.model.ts:
--------------------------------------------------------------------------------
1 | export const enum Size {
2 | S = 'S',
3 | M = 'M',
4 | L = 'L',
5 | XL = 'XL',
6 | XXL = 'XXL'
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/product-category.model.ts:
--------------------------------------------------------------------------------
1 | import { IProduct } from 'app/shared/model/product.model';
2 |
3 | export interface IProductCategory {
4 | id?: number;
5 | name?: string;
6 | description?: string;
7 | products?: IProduct[];
8 | }
9 |
10 | export const defaultValue: Readonly = {};
11 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/product-order.model.ts:
--------------------------------------------------------------------------------
1 | import { IProduct } from 'app/shared/model/product.model';
2 | import { IShoppingCart } from 'app/shared/model/shopping-cart.model';
3 |
4 | export interface IProductOrder {
5 | id?: number;
6 | quantity?: number;
7 | totalPrice?: number;
8 | product?: IProduct;
9 | cart?: IShoppingCart;
10 | }
11 |
12 | export const defaultValue: Readonly = {};
13 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/product.model.ts:
--------------------------------------------------------------------------------
1 | import { IProductCategory } from 'app/shared/model/product-category.model';
2 | import { Size } from 'app/shared/model/enumerations/size.model';
3 |
4 | export interface IProduct {
5 | id?: number;
6 | name?: string;
7 | description?: string;
8 | price?: number;
9 | size?: Size;
10 | imageContentType?: string;
11 | image?: any;
12 | productCategory?: IProductCategory;
13 | }
14 |
15 | export const defaultValue: Readonly = {};
16 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/shopping-cart.model.ts:
--------------------------------------------------------------------------------
1 | import { Moment } from 'moment';
2 | import { IProductOrder } from 'app/shared/model/product-order.model';
3 | import { ICustomerDetails } from 'app/shared/model/customer-details.model';
4 | import { OrderStatus } from 'app/shared/model/enumerations/order-status.model';
5 | import { PaymentMethod } from 'app/shared/model/enumerations/payment-method.model';
6 |
7 | export interface IShoppingCart {
8 | id?: number;
9 | placedDate?: Moment;
10 | status?: OrderStatus;
11 | totalPrice?: number;
12 | paymentMethod?: PaymentMethod;
13 | paymentReference?: string;
14 | paymentModificationReference?: string;
15 | orders?: IProductOrder[];
16 | customerDetails?: ICustomerDetails;
17 | }
18 |
19 | export const defaultValue: Readonly = {};
20 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/model/user.model.ts:
--------------------------------------------------------------------------------
1 | export interface IUser {
2 | id?: any;
3 | login?: string;
4 | firstName?: string;
5 | lastName?: string;
6 | email?: string;
7 | activated?: boolean;
8 | langKey?: string;
9 | authorities?: any[];
10 | createdBy?: string;
11 | createdDate?: Date | null;
12 | lastModifiedBy?: string;
13 | lastModifiedDate?: Date | null;
14 | password?: string;
15 | }
16 |
17 | export const defaultValue: Readonly = {
18 | id: '',
19 | login: '',
20 | firstName: '',
21 | lastName: '',
22 | email: '',
23 | activated: true,
24 | langKey: '',
25 | authorities: [],
26 | createdBy: '',
27 | createdDate: null,
28 | lastModifiedBy: '',
29 | lastModifiedDate: null,
30 | password: ''
31 | };
32 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/reducers/action-type.util.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Appends REQUEST async action type
3 | */
4 |
5 | export const REQUEST = actionType => `${actionType}_PENDING`;
6 |
7 | /**
8 | * Appends SUCCESS async action type
9 | */
10 |
11 | export const SUCCESS = actionType => `${actionType}_FULFILLED`;
12 |
13 | /**
14 | * Appends FAILURE async action type
15 | */
16 |
17 | export const FAILURE = actionType => `${actionType}_REJECTED`;
18 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/reducers/application-profile.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { SUCCESS } from 'app/shared/reducers/action-type.util';
4 |
5 | export const ACTION_TYPES = {
6 | GET_PROFILE: 'applicationProfile/GET_PROFILE'
7 | };
8 |
9 | const initialState = {
10 | ribbonEnv: '',
11 | inProduction: true,
12 | isSwaggerEnabled: false
13 | };
14 |
15 | export type ApplicationProfileState = Readonly;
16 |
17 | export default (state: ApplicationProfileState = initialState, action): ApplicationProfileState => {
18 | switch (action.type) {
19 | case SUCCESS(ACTION_TYPES.GET_PROFILE): {
20 | const { data } = action.payload;
21 | return {
22 | ...state,
23 | ribbonEnv: data['display-ribbon-on-profiles'],
24 | inProduction: data.activeProfiles.includes('prod'),
25 | isSwaggerEnabled: data.activeProfiles.includes('swagger')
26 | };
27 | }
28 | default:
29 | return state;
30 | }
31 | };
32 |
33 | export const getProfile = () => ({
34 | type: ACTION_TYPES.GET_PROFILE,
35 | payload: axios.get('management/info')
36 | });
37 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/util/date-utils.ts:
--------------------------------------------------------------------------------
1 | import moment from 'moment';
2 |
3 | import { APP_LOCAL_DATETIME_FORMAT, APP_LOCAL_DATETIME_FORMAT_Z } from 'app/config/constants';
4 |
5 | export const convertDateTimeFromServer = date => (date ? moment(date).format(APP_LOCAL_DATETIME_FORMAT) : null);
6 |
7 | export const convertDateTimeToServer = date => (date ? moment(date, APP_LOCAL_DATETIME_FORMAT_Z).toDate() : null);
8 |
9 | export const displayDefaultDateTime = () =>
10 | moment()
11 | .startOf('day')
12 | .format(APP_LOCAL_DATETIME_FORMAT);
13 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/util/entity-utils.ts:
--------------------------------------------------------------------------------
1 | import pick from 'lodash/pick';
2 |
3 | /**
4 | * Removes fields with an 'id' field that equals ''.
5 | * This function was created to prevent entities to be sent to
6 | * the server with relationship fields with empty an empty id and thus
7 | * resulting in a 500.
8 | *
9 | * @param entity Object to clean.
10 | */
11 | export const cleanEntity = entity => {
12 | const keysToKeep = Object.keys(entity).filter(k => !(entity[k] instanceof Object) || (entity[k]['id'] !== '' && entity[k]['id'] !== -1));
13 |
14 | return pick(entity, keysToKeep);
15 | };
16 |
17 | /**
18 | * Simply map a list of element to a list a object with the element as id.
19 | *
20 | * @param idList Elements to map.
21 | * @returns The list of objects with mapped ids.
22 | */
23 | export const mapIdList = (idList: ReadonlyArray) =>
24 | idList.filter((entityId: any) => entityId !== '').map((entityId: any) => ({ id: entityId }));
25 |
--------------------------------------------------------------------------------
/src/main/webapp/app/shared/util/pagination.constants.ts:
--------------------------------------------------------------------------------
1 | export const ITEMS_PER_PAGE = 20;
2 |
--------------------------------------------------------------------------------
/src/main/webapp/app/typings.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.json' {
2 | const value: any;
3 | export default value;
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/webapp/content/images/failed.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/main/webapp/content/images/logo-jhipster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/src/main/webapp/content/images/logo-jhipster.png
--------------------------------------------------------------------------------
/src/main/webapp/content/images/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/main/webapp/content/images/success.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/main/webapp/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/src/main/webapp/favicon.ico
--------------------------------------------------------------------------------
/src/main/webapp/manifest.webapp:
--------------------------------------------------------------------------------
1 | {
2 | "name": "store",
3 | "short_name": "store",
4 | "icons": [
5 | {
6 | "src": "./content/images/logo.svg",
7 | "sizes": "192x192",
8 | "type": "image/svg"
9 | }
10 | ],
11 | "theme_color": "#000000",
12 | "background_color": "#e0e0e0",
13 | "start_url": ".",
14 | "display": "standalone",
15 | "orientation": "portrait"
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/webapp/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 | Disallow: /api/account
5 | Disallow: /api/account/change-password
6 | Disallow: /api/account/sessions
7 | Disallow: /api/audits/
8 | Disallow: /api/logs/
9 | Disallow: /api/users/
10 | Disallow: /management/
11 | Disallow: /v2/api-docs/
12 |
--------------------------------------------------------------------------------
/src/main/webapp/swagger-ui/dist/images/throbber.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RameshMF/adyen-java-react-ecommerce-example/f7ced3d3ac93b562aa5b6b8da05ce37e11431a4d/src/main/webapp/swagger-ui/dist/images/throbber.gif
--------------------------------------------------------------------------------
/src/main/webapp/swagger-ui/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | store - Swagger UI
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/ArchTest.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store;
2 |
3 | import com.tngtech.archunit.core.domain.JavaClasses;
4 | import com.tngtech.archunit.core.importer.ClassFileImporter;
5 | import com.tngtech.archunit.core.importer.ImportOption;
6 | import org.junit.jupiter.api.Test;
7 |
8 | import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
9 |
10 | class ArchTest {
11 |
12 | @Test
13 | void servicesAndRepositoriesShouldNotDependOnWebLayer() {
14 |
15 | JavaClasses importedClasses = new ClassFileImporter()
16 | .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
17 | .importPackages("com.adyen.demo.store");
18 |
19 | noClasses()
20 | .that()
21 | .resideInAnyPackage("com.adyen.demo.store.service..")
22 | .or()
23 | .resideInAnyPackage("com.adyen.demo.store.repository..")
24 | .should().dependOnClassesThat()
25 | .resideInAnyPackage("..com.adyen.demo.store.web..")
26 | .because("Services and repositories should not depend on web layer")
27 | .check(importedClasses);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/config/NoOpMailConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.config;
2 |
3 | import com.adyen.demo.store.service.MailService;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | import static org.mockito.ArgumentMatchers.any;
8 | import static org.mockito.Mockito.doNothing;
9 | import static org.mockito.Mockito.mock;
10 |
11 | @Configuration
12 | public class NoOpMailConfiguration {
13 | private final MailService mockMailService;
14 |
15 | public NoOpMailConfiguration() {
16 | mockMailService = mock(MailService.class);
17 | doNothing().when(mockMailService).sendActivationEmail(any());
18 | }
19 |
20 | @Bean
21 | public MailService mailService() {
22 | return mockMailService;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/config/WebConfigurerTestController.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.config;
2 |
3 | import org.springframework.web.bind.annotation.GetMapping;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | @RestController
7 | public class WebConfigurerTestController {
8 |
9 | @GetMapping("/api/test-cors")
10 | public void testCorsOnApiPath() {
11 | }
12 |
13 | @GetMapping("/test/test-cors")
14 | public void testCorsOnOtherPath() {
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/domain/CustomerDetailsTest.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.domain;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.assertj.core.api.Assertions.assertThat;
5 | import com.adyen.demo.store.web.rest.TestUtil;
6 |
7 | public class CustomerDetailsTest {
8 |
9 | @Test
10 | public void equalsVerifier() throws Exception {
11 | TestUtil.equalsVerifier(CustomerDetails.class);
12 | CustomerDetails customerDetails1 = new CustomerDetails();
13 | customerDetails1.setId(1L);
14 | CustomerDetails customerDetails2 = new CustomerDetails();
15 | customerDetails2.setId(customerDetails1.getId());
16 | assertThat(customerDetails1).isEqualTo(customerDetails2);
17 | customerDetails2.setId(2L);
18 | assertThat(customerDetails1).isNotEqualTo(customerDetails2);
19 | customerDetails1.setId(null);
20 | assertThat(customerDetails1).isNotEqualTo(customerDetails2);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/domain/PaymentCacheTest.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.domain;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.assertj.core.api.Assertions.assertThat;
5 | import com.adyen.demo.store.web.rest.TestUtil;
6 |
7 | public class PaymentCacheTest {
8 |
9 | @Test
10 | public void equalsVerifier() throws Exception {
11 | TestUtil.equalsVerifier(PaymentCache.class);
12 | PaymentCache paymentCache1 = new PaymentCache();
13 | paymentCache1.setId(1L);
14 | PaymentCache paymentCache2 = new PaymentCache();
15 | paymentCache2.setId(paymentCache1.getId());
16 | assertThat(paymentCache1).isEqualTo(paymentCache2);
17 | paymentCache2.setId(2L);
18 | assertThat(paymentCache1).isNotEqualTo(paymentCache2);
19 | paymentCache1.setId(null);
20 | assertThat(paymentCache1).isNotEqualTo(paymentCache2);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/domain/ProductCategoryTest.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.domain;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.assertj.core.api.Assertions.assertThat;
5 | import com.adyen.demo.store.web.rest.TestUtil;
6 |
7 | public class ProductCategoryTest {
8 |
9 | @Test
10 | public void equalsVerifier() throws Exception {
11 | TestUtil.equalsVerifier(ProductCategory.class);
12 | ProductCategory productCategory1 = new ProductCategory();
13 | productCategory1.setId(1L);
14 | ProductCategory productCategory2 = new ProductCategory();
15 | productCategory2.setId(productCategory1.getId());
16 | assertThat(productCategory1).isEqualTo(productCategory2);
17 | productCategory2.setId(2L);
18 | assertThat(productCategory1).isNotEqualTo(productCategory2);
19 | productCategory1.setId(null);
20 | assertThat(productCategory1).isNotEqualTo(productCategory2);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/domain/ProductOrderTest.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.domain;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.assertj.core.api.Assertions.assertThat;
5 | import com.adyen.demo.store.web.rest.TestUtil;
6 |
7 | public class ProductOrderTest {
8 |
9 | @Test
10 | public void equalsVerifier() throws Exception {
11 | TestUtil.equalsVerifier(ProductOrder.class);
12 | ProductOrder productOrder1 = new ProductOrder();
13 | productOrder1.setId(1L);
14 | ProductOrder productOrder2 = new ProductOrder();
15 | productOrder2.setId(productOrder1.getId());
16 | assertThat(productOrder1).isEqualTo(productOrder2);
17 | productOrder2.setId(2L);
18 | assertThat(productOrder1).isNotEqualTo(productOrder2);
19 | productOrder1.setId(null);
20 | assertThat(productOrder1).isNotEqualTo(productOrder2);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/domain/ProductTest.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.domain;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.assertj.core.api.Assertions.assertThat;
5 | import com.adyen.demo.store.web.rest.TestUtil;
6 |
7 | public class ProductTest {
8 |
9 | @Test
10 | public void equalsVerifier() throws Exception {
11 | TestUtil.equalsVerifier(Product.class);
12 | Product product1 = new Product();
13 | product1.setId(1L);
14 | Product product2 = new Product();
15 | product2.setId(product1.getId());
16 | assertThat(product1).isEqualTo(product2);
17 | product2.setId(2L);
18 | assertThat(product1).isNotEqualTo(product2);
19 | product1.setId(null);
20 | assertThat(product1).isNotEqualTo(product2);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/domain/ShoppingCartTest.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.domain;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.assertj.core.api.Assertions.assertThat;
5 | import com.adyen.demo.store.web.rest.TestUtil;
6 |
7 | public class ShoppingCartTest {
8 |
9 | @Test
10 | public void equalsVerifier() throws Exception {
11 | TestUtil.equalsVerifier(ShoppingCart.class);
12 | ShoppingCart shoppingCart1 = new ShoppingCart();
13 | shoppingCart1.setId(1L);
14 | ShoppingCart shoppingCart2 = new ShoppingCart();
15 | shoppingCart2.setId(shoppingCart1.getId());
16 | assertThat(shoppingCart1).isEqualTo(shoppingCart2);
17 | shoppingCart2.setId(2L);
18 | assertThat(shoppingCart1).isNotEqualTo(shoppingCart2);
19 | shoppingCart1.setId(null);
20 | assertThat(shoppingCart1).isNotEqualTo(shoppingCart2);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/repository/timezone/DateTimeWrapperRepository.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.repository.timezone;
2 |
3 | import org.springframework.data.jpa.repository.JpaRepository;
4 | import org.springframework.stereotype.Repository;
5 |
6 | /**
7 | * Spring Data JPA repository for the {@link DateTimeWrapper} entity.
8 | */
9 | @Repository
10 | public interface DateTimeWrapperRepository extends JpaRepository {
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/test/java/com/adyen/demo/store/web/rest/WithUnauthenticatedMockUser.java:
--------------------------------------------------------------------------------
1 | package com.adyen.demo.store.web.rest;
2 |
3 | import org.springframework.security.core.context.SecurityContext;
4 | import org.springframework.security.core.context.SecurityContextHolder;
5 | import org.springframework.security.test.context.support.WithSecurityContext;
6 | import org.springframework.security.test.context.support.WithSecurityContextFactory;
7 |
8 | import java.lang.annotation.ElementType;
9 | import java.lang.annotation.Retention;
10 | import java.lang.annotation.RetentionPolicy;
11 | import java.lang.annotation.Target;
12 |
13 | @Target({ElementType.METHOD, ElementType.TYPE})
14 | @Retention(RetentionPolicy.RUNTIME)
15 | @WithSecurityContext(factory = WithUnauthenticatedMockUser.Factory.class)
16 | public @interface WithUnauthenticatedMockUser {
17 |
18 | class Factory implements WithSecurityContextFactory {
19 | @Override
20 | public SecurityContext createSecurityContext(WithUnauthenticatedMockUser annotation) {
21 | return SecurityContextHolder.createEmptyContext();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/app/config/axios-interceptor.spec.ts:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import sinon from 'sinon';
3 |
4 | import setupAxiosInterceptors from 'app/config/axios-interceptor';
5 |
6 | describe('Axios Interceptor', () => {
7 | describe('setupAxiosInterceptors', () => {
8 | const client = axios;
9 | const onUnauthenticated = sinon.spy();
10 | setupAxiosInterceptors(onUnauthenticated);
11 |
12 | it('onRequestSuccess is called on fulfilled request', () => {
13 | expect((client.interceptors.request as any).handlers[0].fulfilled({ data: 'foo', url: '/test' })).toMatchObject({
14 | data: 'foo'
15 | });
16 | });
17 | it('onResponseSuccess is called on fulfilled response', () => {
18 | expect((client.interceptors.response as any).handlers[0].fulfilled({ data: 'foo' })).toEqual({ data: 'foo' });
19 | });
20 | it('onResponseError is called on rejected response', () => {
21 | (client.interceptors.response as any).handlers[0].rejected({
22 | response: {
23 | statusText: 'NotFound',
24 | status: 403,
25 | data: { message: 'Page not found' }
26 | }
27 | });
28 | expect(onUnauthenticated.calledOnce).toBe(true);
29 | });
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/app/shared/error/error-boundary-route.spec.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Route } from 'react-router-dom';
3 | import { shallow, mount } from 'enzyme';
4 |
5 | import ErrorBoundaryRoute from 'app/shared/error/error-boundary-route';
6 |
7 | const ErrorComp = () => {
8 | throw new Error('test');
9 | };
10 |
11 | describe('error-boundary-route component', () => {
12 | beforeEach(() => {
13 | // ignore console and jsdom errors
14 | jest.spyOn((window as any)._virtualConsole, 'emit').mockImplementation(() => false);
15 | jest.spyOn((window as any).console, 'error').mockImplementation(() => false);
16 | });
17 |
18 | // All tests will go here
19 | it('Should throw error when no component is provided', () => {
20 | expect(() => shallow()).toThrow(Error);
21 | });
22 |
23 | it('Should render fallback component when an uncaught error is thrown from component', () => {
24 | const route = shallow();
25 | const renderedRoute = route.find(Route);
26 | expect(renderedRoute.length).toEqual(1);
27 | expect(renderedRoute.props().path).toEqual('/');
28 | expect(renderedRoute.props().render).toBeDefined();
29 | const renderFn: Function = renderedRoute.props().render;
30 | const comp = mount(
31 | renderFn({
32 | location: '/'
33 | })
34 | );
35 | expect(comp.length).toEqual(1);
36 | expect(comp.html()).toEqual('An unexpected error has occurred.
');
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/app/shared/error/error-boundary.spec.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow, mount } from 'enzyme';
3 |
4 | import ErrorBoundary from 'app/shared/error/error-boundary';
5 |
6 | const ErrorComp = () => {
7 | throw new Error('test');
8 | };
9 |
10 | describe('error component', () => {
11 | beforeEach(() => {
12 | // ignore console and jsdom errors
13 | jest.spyOn((window as any)._virtualConsole, 'emit').mockImplementation(() => false);
14 | jest.spyOn((window as any).console, 'error').mockImplementation(() => false);
15 | });
16 |
17 | it('Should throw an error when componnet is not enclosed in Error Boundary', () => {
18 | expect(() => shallow()).toThrow(Error);
19 | });
20 |
21 | it('Should call Error Boundary componentDidCatch method', () => {
22 | const spy = jest.spyOn(ErrorBoundary.prototype, 'componentDidCatch');
23 | mount(
24 |
25 |
26 |
27 | );
28 | expect(spy).toHaveBeenCalled();
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/app/shared/layout/menus/account.spec.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow } from 'enzyme';
3 |
4 | import { NavDropdown } from 'app/shared/layout/menus/menu-components';
5 | import { AccountMenu } from 'app/shared/layout/menus';
6 |
7 | describe('AccountMenu', () => {
8 | let mountedWrapper;
9 |
10 | const authenticatedWrapper = () => {
11 | if (!mountedWrapper) {
12 | mountedWrapper = shallow();
13 | }
14 | return mountedWrapper;
15 | };
16 | const guestWrapper = () => {
17 | if (!mountedWrapper) {
18 | mountedWrapper = shallow();
19 | }
20 | return mountedWrapper;
21 | };
22 |
23 | beforeEach(() => {
24 | mountedWrapper = undefined;
25 | });
26 |
27 | // All tests will go here
28 |
29 | it('Renders a authenticated AccountMenu component', () => {
30 | const dropdown = authenticatedWrapper().find(NavDropdown);
31 | expect(dropdown).toHaveLength(1);
32 | expect(dropdown.find({ to: '/login' })).toHaveLength(0);
33 | expect(dropdown.find({ to: '/logout' })).toHaveLength(1);
34 | });
35 |
36 | it('Renders a guest AccountMenu component', () => {
37 | const dropdown = guestWrapper().find(NavDropdown);
38 | expect(dropdown).toHaveLength(1);
39 | expect(dropdown.find({ to: '/login' })).toHaveLength(1);
40 | expect(dropdown.find({ to: '/logout' })).toHaveLength(0);
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/app/shared/util/entity-utils.spec.ts:
--------------------------------------------------------------------------------
1 | import { cleanEntity, mapIdList } from 'app/shared/util/entity-utils';
2 |
3 | describe('Entity utils', () => {
4 | describe('cleanEntity', () => {
5 | it('should not remove fields with an id', () => {
6 | const entityA = {
7 | a: {
8 | id: 5
9 | }
10 | };
11 | const entityB = {
12 | a: {
13 | id: '5'
14 | }
15 | };
16 |
17 | expect(cleanEntity({ ...entityA })).toEqual(entityA);
18 | expect(cleanEntity({ ...entityB })).toEqual(entityB);
19 | });
20 |
21 | it('should remove fields with an empty id', () => {
22 | const entity = {
23 | a: {
24 | id: ''
25 | }
26 | };
27 |
28 | expect(cleanEntity({ ...entity })).toEqual({});
29 | });
30 |
31 | it('should not remove fields that are not objects', () => {
32 | const entity = {
33 | a: '',
34 | b: 5,
35 | c: [],
36 | d: '5'
37 | };
38 |
39 | expect(cleanEntity({ ...entity })).toEqual(entity);
40 | });
41 | });
42 |
43 | describe('mapIdList', () => {
44 | it("should map ids no matter the element's type", () => {
45 | const ids = ['jhipster', '', 1, { key: 'value' }];
46 |
47 | expect(mapIdList(ids)).toEqual([{ id: 'jhipster' }, { id: 1 }, { id: { key: 'value' } }]);
48 | });
49 |
50 | it('should return an empty array', () => {
51 | const ids = [];
52 |
53 | expect(mapIdList(ids)).toEqual([]);
54 | });
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/app/utils.ts:
--------------------------------------------------------------------------------
1 | // A dirty way to remove functions and undefined from an object for comparison
2 | export const cleanupObj = obj => JSON.parse(JSON.stringify(obj));
3 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/enzyme-setup.ts:
--------------------------------------------------------------------------------
1 | import { configure } from 'enzyme';
2 | import Adapter from 'enzyme-adapter-react-16';
3 |
4 | // React 16 Enzyme adapter
5 | configure({ adapter: new Adapter() });
6 |
--------------------------------------------------------------------------------
/src/test/javascript/spec/storage-mock.ts:
--------------------------------------------------------------------------------
1 | const StorageMock = () => {
2 | let storage = {};
3 | return {
4 | getItem: key => (key in storage ? storage[key] : null),
5 | setItem: (key, value) => (storage[key] = value || ''),
6 | removeItem: key => delete storage[key],
7 | clear: () => (storage = {})
8 | };
9 | };
10 |
11 | Object.defineProperty(window, 'localStorage', {
12 | value: StorageMock()
13 | });
14 |
15 | Object.defineProperty(window, 'sessionStorage', {
16 | value: StorageMock()
17 | });
18 |
--------------------------------------------------------------------------------
/src/test/resources/i18n/messages_en.properties:
--------------------------------------------------------------------------------
1 | email.test.title=test title
2 |
--------------------------------------------------------------------------------
/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
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 | WARN
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/test/resources/templates/mail/testEmail.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es6",
5 | "module": "esnext",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "removeComments": false,
11 | "noImplicitAny": false,
12 | "suppressImplicitAnyIndexErrors": true,
13 | "outDir": "build/resources/main/static/app",
14 | "lib": ["es2015", "es2017", "dom"],
15 | "types": ["webpack-env", "jest"],
16 | "allowJs": true,
17 | "checkJs": false,
18 | "baseUrl": "./",
19 | "paths": {
20 | "app/*": ["src/main/webapp/app/*"]
21 | },
22 | "importHelpers": true,
23 | "esModuleInterop": true,
24 | "allowSyntheticDefaultImports": true
25 | },
26 | "include": ["src/main/webapp/app", "src/test/javascript/spec"],
27 | "exclude": ["node_modules"]
28 | }
29 |
--------------------------------------------------------------------------------
/tsconfig.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig",
3 | "compilerOptions": {
4 | "module": "commonjs",
5 | "allowSyntheticDefaultImports": false
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/webpack/utils.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const tsconfig = require('../tsconfig.json');
4 |
5 | module.exports = {
6 | root,
7 | mapTypescriptAliasToWebpackAlias
8 | };
9 |
10 | const _root = path.resolve(__dirname, '..');
11 |
12 | function root(args) {
13 | args = Array.prototype.slice.call(arguments, 0);
14 | return path.join.apply(path, [_root].concat(args));
15 | }
16 |
17 | function mapTypescriptAliasToWebpackAlias(alias = {}) {
18 | const webpackAliases = { ...alias };
19 | if (!tsconfig.compilerOptions.paths) {
20 | return webpackAliases;
21 | }
22 | Object.entries(tsconfig.compilerOptions.paths)
23 | .filter(([key, value]) => {
24 | // use Typescript alias in Webpack only if this has value
25 | return !!value.length;
26 | })
27 | .map(([key, value]) => {
28 | // if Typescript alias ends with /* then remove this for Webpack
29 | const regexToReplace = /\/\*$/;
30 | const aliasKey = key.replace(regexToReplace, '');
31 | const aliasValue = value[0].replace(regexToReplace, '');
32 | return [aliasKey, root(aliasValue)];
33 | })
34 | .reduce((aliases, [key, value]) => {
35 | aliases[key] = value;
36 | return aliases;
37 | }, webpackAliases);
38 | return webpackAliases;
39 | }
40 |
--------------------------------------------------------------------------------