├── .gitignore ├── README.md ├── docker-compose.yml ├── sar-1.png ├── sar-2.png ├── sar-3.png ├── sar-4.png ├── sar-5.png ├── sar-6.png ├── sar-test-1.png ├── sar-test-2.png ├── sar-test-3.png ├── spring-angular-registration ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── wissensalt │ │ │ └── test │ │ │ └── sar │ │ │ ├── SpringAngularRegistrationApplication.java │ │ │ ├── auditrail │ │ │ ├── AAuditTrail.java │ │ │ └── AppAuditorAware.java │ │ │ ├── config │ │ │ ├── BasicAuthEntryPoint.java │ │ │ ├── CorsFilter.java │ │ │ └── SecurityConfig.java │ │ │ ├── dao │ │ │ ├── IRoleDAO.java │ │ │ └── IUserDAO.java │ │ │ ├── dto │ │ │ ├── RequestLoginDTO.java │ │ │ ├── RequestRegistrationDTO.java │ │ │ ├── ResponseAPIErrorDTO.java │ │ │ ├── ResponseData.java │ │ │ └── ResponseValidationDTO.java │ │ │ ├── endpoint │ │ │ ├── IAuthEndPoint.java │ │ │ ├── IDashboardEndPoint.java │ │ │ ├── IRegistrationEndPoint.java │ │ │ └── impl │ │ │ │ ├── AuthEndPointImpl.java │ │ │ │ ├── DashboardEndPointException.java │ │ │ │ └── RegistrationEndPointImpl.java │ │ │ ├── exception │ │ │ ├── DAOException.java │ │ │ ├── EndPointException.java │ │ │ └── ServiceException.java │ │ │ ├── mapper │ │ │ └── UserMapper.java │ │ │ ├── model │ │ │ ├── Role.java │ │ │ ├── User.java │ │ │ └── base │ │ │ │ ├── ABaseAuditTrail.java │ │ │ │ ├── ASimpleAuditTrail.java │ │ │ │ ├── BaseMasterDATA.java │ │ │ │ └── ISingleKeyDATA.java │ │ │ ├── service │ │ │ ├── IAuthenticationService.java │ │ │ ├── IRegistrationService.java │ │ │ └── impl │ │ │ │ ├── AuthenticationServiceImpl.java │ │ │ │ ├── CustomUserDetailService.java │ │ │ │ └── RegistrationServiceImpl.java │ │ │ ├── statval │ │ │ └── ISarConstant.java │ │ │ ├── util │ │ │ ├── APIErrorBuilder.java │ │ │ ├── CookieUtil.java │ │ │ └── DateUtil.java │ │ │ └── validation │ │ │ ├── GeneralValidation.java │ │ │ ├── IRequestValidator.java │ │ │ └── RegistrationValidator.java │ └── resources │ │ ├── application.yml │ │ ├── logback-spring.xml │ │ └── schema.sql │ └── test │ └── java │ └── com │ └── wissensalt │ └── test │ └── sar │ └── SpringAngularRegistrationApplicationTests.java └── web-angular-registration ├── .editorconfig ├── README.md ├── angular.json ├── e2e ├── protractor.conf.js ├── src │ ├── app.e2e-spec.ts │ └── app.po.ts └── tsconfig.e2e.json ├── package-lock.json ├── package.json ├── proxy.json ├── src ├── app │ ├── app-routing.module.ts │ ├── app.component.css │ ├── app.component.html │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── client │ │ ├── login-client.service.spec.ts │ │ ├── login-client.service.ts │ │ ├── registration-client.service.spec.ts │ │ └── registration-client.service.ts │ ├── dashboard │ │ ├── dashboard.component.css │ │ ├── dashboard.component.html │ │ ├── dashboard.component.spec.ts │ │ └── dashboard.component.ts │ ├── dto │ │ ├── request-login.spec.ts │ │ ├── request-login.ts │ │ ├── request-registration.spec.ts │ │ ├── request-registration.ts │ │ ├── response-data.spec.ts │ │ ├── response-data.ts │ │ ├── response-error.spec.ts │ │ └── response-error.ts │ ├── login-form │ │ ├── login-form.component.css │ │ ├── login-form.component.html │ │ ├── login-form.component.spec.ts │ │ └── login-form.component.ts │ ├── registration-form │ │ ├── registration-form.component.css │ │ ├── registration-form.component.html │ │ ├── registration-form.component.spec.ts │ │ └── registration-form.component.ts │ └── security │ │ ├── auth-guard.spec.ts │ │ └── auth-guard.ts ├── assets │ └── .gitkeep ├── browserslist ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── karma.conf.js ├── main.ts ├── polyfills.ts ├── styles.css ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── tslint.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | spring-angular-registration/.gitignore 2 | spring-angular-registration/.mvn/ 3 | spring-angular-registration/mvnw 4 | spring-angular-registration/mvnw.cmd 5 | web-angular-registration/node_modules/ 6 | 7 | .idea/ 8 | **/target/ 9 | **.log 10 | **.iml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # springboot-angular-registration 2 | A Simple Registration and Login Page using SpringBoot and Angular. This repository contains two project **spring-angular-registration** for backend and **web-angular-registration** for the frontend. 3 | 4 | ### Technologies ! 5 | WEB : 6 | - Angular 7 CLI 7 | - Bootstrap 8 | - Karma 9 | - Jasmine 10 | 11 | API : 12 | - Spring Web 13 | - Spring Security 14 | - JPA 15 | - PostgreSQL 16 | - Spring Test 17 | 18 | # Steps to run the project 19 | - Create DB and Restore file **schema.sql** 20 | - Run Backend **spring-angular-registration** and make sure there is no Error 21 | - Run Frontend **web-angular-registration** 22 | 23 | # How To Build And Run : spring-angular-registration (backend) 24 | - Open file : spring-angular-registration/src/main/resources/application.yml 25 | - Suppose you are running on local environment, change property spring.profiles.active : into local 26 | - Open file spring-angular-registration/src/main/resources/application-local.yml 27 | - Change property log.file.path : depend on your local storage 28 | - Change property db.name, db.host, db.port, db.username, db.password depend on your local configuration 29 | - Compile : 30 | ```sh 31 | $ mvn clean package 32 | ``` 33 | - or directly Run : 34 | ```sh 35 | $ mvn spring-boot:run 36 | ``` 37 | 38 | # How To Build And Run : web-angular-registration (frontend) 39 | - Install dependencies : 40 | ```sh 41 | $ npm install 42 | ``` 43 | - If everything installed properly , run : 44 | ```sh 45 | $ ng serve 46 | ``` 47 | - Open browser and go to http://localhost:4200 48 | - port 4200 is default, you can change with command --port to change the port 49 | 50 | ![sar-1.png](sar-1.png) 51 | ![sar-2.png](sar-2.png) 52 | ![sar-3.png](sar-3.png) 53 | ![sar-4.png](sar-4.png) 54 | ![sar-5.png](sar-5.png) 55 | ![sar-6.png](sar-6.png) 56 | 57 | # How To Run Unit Testing : web-angular-registration (frontend) 58 | - Run : 59 | ```sh 60 | $ ng test 61 | ``` 62 | 63 | ![sar-test-1.png](sar-test-1.png) 64 | ![sar-test-2.png](sar-test-2.png) 65 | 66 | # How To Run Unit Testing : spring-angular-registration (backend) 67 | - Run : 68 | ```sh 69 | $ mvn clean package 70 | ``` 71 | 72 | ![sar-test-3.png](sar-test-3.png) 73 | 74 | #### *Username for Login is Email and Password is FirstName -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | services: 3 | db: 4 | image: postgres:9-alpine 5 | container_name: sar_db 6 | ports: 7 | - "5432:5432" 8 | environment: 9 | - POSTGRES_USERNAME=postgres 10 | - POSTGRES_PASSWORD=pgadmin 11 | - POSTGRES_DB=sar_db -------------------------------------------------------------------------------- /sar-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-1.png -------------------------------------------------------------------------------- /sar-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-2.png -------------------------------------------------------------------------------- /sar-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-3.png -------------------------------------------------------------------------------- /sar-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-4.png -------------------------------------------------------------------------------- /sar-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-5.png -------------------------------------------------------------------------------- /sar-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-6.png -------------------------------------------------------------------------------- /sar-test-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-test-1.png -------------------------------------------------------------------------------- /sar-test-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-test-2.png -------------------------------------------------------------------------------- /sar-test-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/sar-test-3.png -------------------------------------------------------------------------------- /spring-angular-registration/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.3.RELEASE 9 | 10 | 11 | com.wissensalt.test 12 | spring-angular-registration 13 | 0.0.1-SNAPSHOT 14 | spring-angular-registration 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | javax.validation 24 | validation-api 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-jpa 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-security 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-web 38 | 39 | 40 | 41 | org.postgresql 42 | postgresql 43 | runtime 44 | 45 | 46 | org.projectlombok 47 | lombok 48 | true 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-test 53 | test 54 | 55 | 56 | org.springframework.security 57 | spring-security-test 58 | test 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-maven-plugin 67 | 68 | 69 | 70 | 71 | 72 | 73 | spring-snapshots 74 | Spring Snapshots 75 | https://repo.spring.io/snapshot 76 | 77 | true 78 | 79 | 80 | 81 | spring-milestones 82 | Spring Milestones 83 | https://repo.spring.io/milestone 84 | 85 | 86 | 87 | 88 | spring-snapshots 89 | Spring Snapshots 90 | https://repo.spring.io/snapshot 91 | 92 | true 93 | 94 | 95 | 96 | spring-milestones 97 | Spring Milestones 98 | https://repo.spring.io/milestone 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/SpringAngularRegistrationApplication.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringAngularRegistrationApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringAngularRegistrationApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/auditrail/AAuditTrail.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.auditrail; 2 | 3 | import com.wissensalt.test.sar.model.base.ABaseAuditTrail; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 8 | 9 | import javax.persistence.EntityListeners; 10 | import javax.persistence.MappedSuperclass; 11 | import javax.persistence.Transient; 12 | 13 | @MappedSuperclass 14 | @EntityListeners(AuditingEntityListener.class) 15 | public abstract class AAuditTrail extends ABaseAuditTrail { 16 | /** 17 | * 18 | * 19 | */ 20 | private static final long serialVersionUID = -5401587542468260575L; 21 | 22 | @Getter(AccessLevel.NONE) 23 | @Setter(AccessLevel.NONE) 24 | @Transient 25 | private AppAuditorAware auditorAware; 26 | 27 | public AAuditTrail() { 28 | auditorAware = new AppAuditorAware(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/auditrail/AppAuditorAware.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.auditrail; 2 | 3 | import org.springframework.data.domain.AuditorAware; 4 | import org.springframework.security.core.context.SecurityContextHolder; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.io.Serializable; 8 | import java.util.Optional; 9 | 10 | /** 11 | * Created on 2/27/19. 12 | * 13 | * @author Achmad Fauzi 14 | */ 15 | @Component 16 | public class AppAuditorAware implements AuditorAware, Serializable { 17 | /** 18 | * 19 | * 20 | */ 21 | private static final long serialVersionUID = 3916619591736957909L; 22 | 23 | @Override 24 | public Optional getCurrentAuditor() { 25 | String userName; 26 | try{ 27 | userName = SecurityContextHolder.getContext().getAuthentication().getName(); 28 | }catch (Exception e) { 29 | userName = "PUBLIC_USER"; 30 | } 31 | 32 | return Optional.of(userName); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/config/BasicAuthEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.config; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.servlet.ServletException; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | import java.io.PrintWriter; 12 | 13 | /** 14 | * Created on 4/28/18. 15 | * 16 | * @author Achmad Fauzi 17 | */ 18 | @Component 19 | public class BasicAuthEntryPoint extends BasicAuthenticationEntryPoint { 20 | 21 | @Override 22 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { 23 | response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName()); 24 | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 25 | PrintWriter writer = response.getWriter(); 26 | writer.println("HTTP STATUS 401 - "+ authException.getMessage()); 27 | } 28 | 29 | @Override 30 | public void afterPropertiesSet() throws Exception { 31 | setRealmName("SECURED-BASIC-REALM"); 32 | super.afterPropertiesSet(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/config/CorsFilter.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.config; 2 | 3 | import org.springframework.web.filter.GenericFilterBean; 4 | 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.ServletRequest; 8 | import javax.servlet.ServletResponse; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | 12 | /** 13 | * Created on 5/11/18. 14 | * 15 | * @author Achmad Fauzi 16 | */ 17 | public class CorsFilter extends GenericFilterBean { 18 | @Override 19 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 20 | HttpServletResponse response = (HttpServletResponse) servletResponse; 21 | response.setHeader("Access-Control-Allow-Origin", "*"); 22 | response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE"); 23 | response.setHeader("Access-Control-Max-Age", "3600"); 24 | response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Content-Length, X-Requested-With"); 25 | filterChain.doFilter(servletRequest, servletResponse); 26 | } 27 | } -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.config; 2 | 3 | import com.wissensalt.test.sar.service.impl.CustomUserDetailService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 11 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 13 | import org.springframework.security.crypto.password.PasswordEncoder; 14 | import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; 15 | import org.springframework.web.cors.CorsConfiguration; 16 | import org.springframework.web.cors.CorsConfigurationSource; 17 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 18 | 19 | import java.util.Arrays; 20 | 21 | import static com.wissensalt.test.sar.statval.ISarConstant.RoleName.ADMIN; 22 | 23 | /** 24 | * Created on 4/27/18. 25 | * 26 | * @author Achmad Fauzi 27 | */ 28 | @Configuration 29 | @EnableWebSecurity 30 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 31 | 32 | @Autowired 33 | private BasicAuthEntryPoint basicAuthEntryPoint; 34 | 35 | @Bean 36 | public PasswordEncoder passwordEncoder () { 37 | return new BCryptPasswordEncoder(); 38 | } 39 | 40 | @Autowired 41 | private CustomUserDetailService customUserDetailService; 42 | 43 | @Override 44 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 45 | auth 46 | .authenticationProvider(authenticationProvider()); 47 | } 48 | 49 | @Bean 50 | public DaoAuthenticationProvider authenticationProvider() { 51 | DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); 52 | provider.setUserDetailsService(customUserDetailService); 53 | provider.setPasswordEncoder(passwordEncoder()); 54 | return provider; 55 | } 56 | 57 | @Override 58 | protected void configure(HttpSecurity http) throws Exception { 59 | http 60 | .authorizeRequests() 61 | .antMatchers("/registration/*").permitAll() 62 | .antMatchers("/auth/*").permitAll() 63 | .antMatchers("/api/*").hasRole(ADMIN) 64 | .anyRequest().authenticated() 65 | .and() 66 | .httpBasic().authenticationEntryPoint(basicAuthEntryPoint) 67 | .and() 68 | .csrf().disable(); 69 | 70 | 71 | http.addFilterAfter(new CorsFilter(), BasicAuthenticationFilter.class); 72 | } 73 | 74 | @Bean 75 | CorsConfigurationSource corsConfigurationSource() 76 | { 77 | CorsConfiguration configuration = new CorsConfiguration(); 78 | configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200")); 79 | configuration.setAllowedMethods(Arrays.asList("GET", "POST")); 80 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 81 | source.registerCorsConfiguration("/**", configuration); 82 | return source; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/dao/IRoleDAO.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.dao; 2 | 3 | import com.wissensalt.test.sar.exception.DAOException; 4 | import com.wissensalt.test.sar.model.Role; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * Created on 5/8/19. 9 | * 10 | * @author Achmad Fauzi 11 | */ 12 | public interface IRoleDAO extends JpaRepository { 13 | 14 | Role findByName(String p_Name) throws DAOException; 15 | 16 | Role findByCode(String p_Code) throws DAOException; 17 | } 18 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/dao/IUserDAO.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.dao; 2 | 3 | import com.wissensalt.test.sar.exception.DAOException; 4 | import com.wissensalt.test.sar.model.User; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * Created on 5/8/19. 9 | * 10 | * @author Achmad Fauzi 11 | */ 12 | public interface IUserDAO extends JpaRepository { 13 | 14 | User findByMobileNumber(String p_MobileNumber) throws DAOException; 15 | 16 | User findByEmail(String p_Email) throws DAOException; 17 | 18 | User findByCodeAndStatus(String p_Code, Boolean p_Status)throws DAOException; 19 | 20 | User findByCodeOrEmail(String p_Code, String p_Email) throws DAOException; 21 | } 22 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/dto/RequestLoginDTO.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Created on 6/6/18. 10 | * 11 | * @author Achmad Fauzi 12 | */ 13 | @Getter 14 | @Setter 15 | public class RequestLoginDTO implements Serializable{ 16 | /** 17 | * 18 | * 19 | */ 20 | private static final long serialVersionUID = -3717873746249151313L; 21 | 22 | private String userName; 23 | private String password; 24 | } 25 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/dto/RequestRegistrationDTO.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Created on 5/8/19. 10 | * 11 | * @author Achmad Fauzi 12 | */ 13 | @Getter 14 | @Setter 15 | public class RequestRegistrationDTO implements Serializable { 16 | /** 17 | * 18 | * 19 | */ 20 | private static final long serialVersionUID = 3198880434676247053L; 21 | private String mobileNumber; 22 | private String firstName; 23 | private String lastName; 24 | private String dob; 25 | private Integer gender; 26 | private String email; 27 | } 28 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/dto/ResponseAPIErrorDTO.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | /** 12 | * Created on 5/8/19. 13 | * 14 | * @author Achmad Fauzi 15 | */ 16 | @Setter 17 | @Getter 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class ResponseAPIErrorDTO implements Serializable { 21 | /** 22 | * 23 | * 24 | */ 25 | private static final long serialVersionUID = -2021006695807894437L; 26 | private Date timestamp; 27 | private Integer status; 28 | private String exception; 29 | private String message; 30 | private String path; 31 | private String error; 32 | } 33 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/dto/ResponseData.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * Created on 5/8/19. 12 | * 13 | * @author Achmad Fauzi 14 | */ 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | @Getter 18 | @Setter 19 | public class ResponseData implements Serializable { 20 | /** 21 | * 22 | * 23 | */ 24 | private static final long serialVersionUID = -8524185686815426024L; 25 | private String responseCode; 26 | private String responseMsg; 27 | } 28 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/dto/ResponseValidationDTO.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.dto; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Created on 5/8/19. 10 | * 11 | * @author Achmad Fauzi 12 | */ 13 | @Getter 14 | @Setter 15 | public class ResponseValidationDTO implements Serializable { 16 | /** 17 | * 18 | * 19 | */ 20 | private static final long serialVersionUID = -5800369745118333312L; 21 | private Boolean isValid; 22 | private String message; 23 | } 24 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/endpoint/IAuthEndPoint.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.endpoint; 2 | 3 | import com.wissensalt.test.sar.dto.ResponseData; 4 | import com.wissensalt.test.sar.exception.EndPointException; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestBody; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | /** 13 | * Created on 5/9/19. 14 | * 15 | * @author Achmad Fauzi 16 | */ 17 | @RequestMapping("/auth") 18 | public interface IAuthEndPoint { 19 | 20 | @PostMapping("/logout") 21 | ResponseData logout(HttpServletRequest p_Request, HttpServletResponse p_Response) throws EndPointException; 22 | 23 | @PostMapping("/login") 24 | RESPONSE_DTO login(@RequestBody LOGIN_DATA login_data, HttpServletResponse p_Response, HttpServletRequest p_Request) throws EndPointException; 25 | } -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/endpoint/IDashboardEndPoint.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.endpoint; 2 | 3 | import com.wissensalt.test.sar.exception.EndPointException; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | 7 | import java.security.Principal; 8 | 9 | import static com.wissensalt.test.sar.statval.ISarConstant.Path.DASHBOARD; 10 | 11 | /** 12 | * Created on 5/9/19. 13 | * 14 | * @author Achmad Fauzi 15 | */ 16 | @RequestMapping(DASHBOARD) 17 | public interface IDashboardEndPoint { 18 | 19 | ResponseEntity display(Principal p_Principal) throws EndPointException; 20 | } 21 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/endpoint/IRegistrationEndPoint.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.endpoint; 2 | 3 | import com.wissensalt.test.sar.dto.RequestRegistrationDTO; 4 | import com.wissensalt.test.sar.exception.EndPointException; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.web.bind.annotation.RequestBody; 7 | 8 | /** 9 | * Created on 5/8/19. 10 | * 11 | * @author Achmad Fauzi 12 | */ 13 | public interface IRegistrationEndPoint { 14 | 15 | ResponseEntity register(@RequestBody RequestRegistrationDTO p_Request) throws EndPointException; 16 | } 17 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/endpoint/impl/AuthEndPointImpl.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.endpoint.impl; 2 | 3 | import com.wissensalt.test.sar.dto.RequestLoginDTO; 4 | import com.wissensalt.test.sar.dto.ResponseData; 5 | import com.wissensalt.test.sar.endpoint.IAuthEndPoint; 6 | import com.wissensalt.test.sar.exception.EndPointException; 7 | import com.wissensalt.test.sar.exception.ServiceException; 8 | import com.wissensalt.test.sar.model.User; 9 | import com.wissensalt.test.sar.service.IAuthenticationService; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 14 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider; 15 | import org.springframework.security.core.Authentication; 16 | import org.springframework.security.core.context.SecurityContextHolder; 17 | import org.springframework.web.bind.annotation.RequestBody; 18 | import org.springframework.web.bind.annotation.RestController; 19 | 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | 23 | /** 24 | * Created on 5/9/19. 25 | * 26 | * @author Achmad Fauzi 27 | */ 28 | @RestController 29 | public class AuthEndPointImpl implements IAuthEndPoint { 30 | @Autowired 31 | private DaoAuthenticationProvider authenticationManager; 32 | 33 | @Autowired 34 | private IAuthenticationService authenticationService; 35 | 36 | private static final Logger LOGGER = LoggerFactory.getLogger(AuthEndPointImpl.class); 37 | 38 | @Override 39 | public ResponseData logout(HttpServletRequest p_Request, HttpServletResponse p_Response) throws EndPointException { 40 | ResponseData result = new ResponseData("500", "Logout Failed"); 41 | Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 42 | if (auth != null){ 43 | authenticationService.logout(p_Request, p_Response, auth); 44 | LOGGER.info("Logout Successful"); 45 | try { 46 | authenticationService.updateStatusLoggedOut(auth.getName()); 47 | } catch (ServiceException e) { 48 | LOGGER.error("Error Update Status Logged Out {}", e.toString()); 49 | } 50 | result = new ResponseData("200", "Logout Success"); 51 | }else { 52 | LOGGER.error("Logout Failed"); 53 | } 54 | return result; 55 | } 56 | 57 | @Override 58 | public ResponseData login(@RequestBody RequestLoginDTO p_RequestLoginDTO, HttpServletResponse p_HttpServletResponse, HttpServletRequest p_Request) throws EndPointException { 59 | ResponseData result = new ResponseData("500", "Login Failed"); 60 | if (p_RequestLoginDTO.getPassword() != null && p_RequestLoginDTO.getUserName() != null) { 61 | User userDetails = null; 62 | try { 63 | userDetails = authenticationService.login(p_RequestLoginDTO.getUserName()); 64 | } catch (ServiceException e) { 65 | LOGGER.error("Error Login {}", e.toString()); 66 | } 67 | if (userDetails != null) { 68 | Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(p_RequestLoginDTO.getUserName(), p_RequestLoginDTO.getPassword())); 69 | if (authentication.isAuthenticated()) { 70 | try { 71 | authenticationService.updateStatusLoggedIn(userDetails); 72 | } catch (ServiceException e) { 73 | LOGGER.error("Error update status logged in : {}", e.toString()); 74 | } 75 | SecurityContextHolder.getContext().setAuthentication(authentication); 76 | result = new ResponseData("200", "Login Success"); 77 | } 78 | }else { 79 | LOGGER.info("User Not Found"); 80 | result = new ResponseData("500", "User Not Exist"); 81 | } 82 | }else { 83 | LOGGER.error("Missing Login Body Request"); 84 | } 85 | return result; 86 | } 87 | } -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/endpoint/impl/DashboardEndPointException.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.endpoint.impl; 2 | 3 | import com.wissensalt.test.sar.dto.ResponseData; 4 | import com.wissensalt.test.sar.endpoint.IDashboardEndPoint; 5 | import com.wissensalt.test.sar.exception.EndPointException; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import java.security.Principal; 10 | 11 | /** 12 | * Created on 5/9/19. 13 | * 14 | * @author Achmad Fauzi 15 | */ 16 | @RestController 17 | public class DashboardEndPointException implements IDashboardEndPoint { 18 | @Override 19 | public ResponseEntity display(Principal p_Principal) throws EndPointException { 20 | return ResponseEntity.ok(new ResponseData("200", p_Principal.getName())); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/endpoint/impl/RegistrationEndPointImpl.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.endpoint.impl; 2 | 3 | import com.wissensalt.test.sar.dto.RequestRegistrationDTO; 4 | import com.wissensalt.test.sar.endpoint.IRegistrationEndPoint; 5 | import com.wissensalt.test.sar.exception.EndPointException; 6 | import com.wissensalt.test.sar.exception.ServiceException; 7 | import com.wissensalt.test.sar.service.IRegistrationService; 8 | import com.wissensalt.test.sar.statval.ISarConstant; 9 | import com.wissensalt.test.sar.util.APIErrorBuilder; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.http.HttpStatus; 14 | import org.springframework.http.ResponseEntity; 15 | import org.springframework.web.bind.annotation.PostMapping; 16 | import org.springframework.web.bind.annotation.RequestBody; 17 | import org.springframework.web.bind.annotation.RequestMapping; 18 | import org.springframework.web.bind.annotation.RestController; 19 | 20 | import static com.wissensalt.test.sar.statval.ISarConstant.Path.REGISTER; 21 | 22 | /** 23 | * Created on 5/8/19. 24 | * 25 | * @author Achmad Fauzi 26 | */ 27 | @RestController 28 | @RequestMapping(ISarConstant.Path.REGISTRATION) 29 | public class RegistrationEndPointImpl implements IRegistrationEndPoint { 30 | 31 | @Autowired private IRegistrationService registrationService; 32 | private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationEndPointImpl.class); 33 | 34 | @PostMapping(ISarConstant.Path.REGISTER) 35 | @Override 36 | public ResponseEntity register(@RequestBody RequestRegistrationDTO p_Request) throws EndPointException { 37 | try { 38 | return registrationService.register(p_Request); 39 | } catch (ServiceException e) { 40 | LOGGER.error("Error conduct register : {}", e.toString()); 41 | return new ResponseEntity<>(APIErrorBuilder.internalServerError(RegistrationEndPointImpl.class, "Error Register Process : "+e.getMessage(), ISarConstant.Path.REGISTRATION.concat(REGISTER)), HttpStatus.INTERNAL_SERVER_ERROR); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/exception/DAOException.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.exception; 2 | 3 | /** 4 | * Created on 5/8/19. 5 | * 6 | * @author Achmad Fauzi 7 | */ 8 | public class DAOException extends Exception { 9 | /** 10 | * 11 | * 12 | */ 13 | private static final long serialVersionUID = 2682641418110879822L; 14 | 15 | public DAOException(String message) { 16 | super(message); 17 | } 18 | 19 | public DAOException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/exception/EndPointException.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.exception; 2 | 3 | /** 4 | * Created on 5/8/19. 5 | * 6 | * @author Achmad Fauzi 7 | */ 8 | public class EndPointException extends Exception { 9 | /** 10 | * 11 | * 12 | */ 13 | private static final long serialVersionUID = -3606509494328908116L; 14 | 15 | public EndPointException(String message) { 16 | super(message); 17 | } 18 | 19 | public EndPointException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/exception/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.exception; 2 | 3 | /** 4 | * Created on 5/8/19. 5 | * 6 | * @author Achmad Fauzi 7 | */ 8 | public class ServiceException extends Exception { 9 | /** 10 | * 11 | * 12 | */ 13 | private static final long serialVersionUID = 3882661372718700763L; 14 | 15 | public ServiceException(String message) { 16 | super(message); 17 | } 18 | 19 | public ServiceException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.mapper; 2 | 3 | import com.wissensalt.test.sar.dao.IRoleDAO; 4 | import com.wissensalt.test.sar.dto.RequestRegistrationDTO; 5 | import com.wissensalt.test.sar.exception.DAOException; 6 | import com.wissensalt.test.sar.model.Role; 7 | import com.wissensalt.test.sar.model.User; 8 | import com.wissensalt.test.sar.util.DateUtil; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.core.convert.converter.Converter; 13 | import org.springframework.security.crypto.password.PasswordEncoder; 14 | import org.springframework.stereotype.Service; 15 | 16 | import java.text.ParseException; 17 | import java.util.Date; 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | import static com.wissensalt.test.sar.statval.ISarConstant.RoleCode.ADMIN; 22 | 23 | /** 24 | * Created on 5/8/19. 25 | * 26 | * @author Achmad Fauzi 27 | */ 28 | @Service 29 | public class UserMapper implements Converter { 30 | 31 | @Autowired private IRoleDAO roleDAO; 32 | @Autowired private PasswordEncoder passwordEncoder; 33 | private static Date CURRENT_DATE = new Date(); 34 | private static final Logger LOGGER = LoggerFactory.getLogger(UserMapper.class); 35 | 36 | /** 37 | *
    38 | *
  1. 39 | * User will be set as ADMIN by Default 40 | *
  2. 41 | *
  3. 42 | * Password will be equal with first name 43 | *
  4. 44 | *
45 | * @param source 46 | * @return 47 | */ 48 | @Override 49 | public User convert(RequestRegistrationDTO source) { 50 | User user = new User(); 51 | user.setCode(source.getEmail()); 52 | user.setName(source.getFirstName().concat(" ").concat(source.getLastName())); 53 | user.setStatus(true); 54 | user.setFirstName(source.getFirstName()); 55 | user.setLastName(source.getLastName()); 56 | user.setMobileNumber(source.getMobileNumber()); 57 | try { 58 | user.setDateOfBirth(DateUtil.BirthDateFormatter.parse(source.getDob())); 59 | } catch (ParseException e) { 60 | LOGGER.warn("Date is not in valid format {}", e.toString()); 61 | } 62 | user.setGender(source.getGender()); 63 | user.setEmail(source.getEmail()); 64 | user.setPassword(passwordEncoder.encode(user.getFirstName())); 65 | user.setEnabled(true); 66 | user.setExpiredDate(DateUtil.addNYearToDate(1, CURRENT_DATE)); 67 | user.setCredentialsExpiredDate(DateUtil.addNYearToDate(1, CURRENT_DATE)); 68 | user.setNonLocked(true); 69 | 70 | Role role = null; 71 | try { 72 | role = roleDAO.findByCode(ADMIN); 73 | } catch (DAOException e) { 74 | LOGGER.error("Error find Role By Name {} : {}", ADMIN, e.toString()); 75 | } 76 | Set roles = new HashSet<>(); 77 | if (role != null) { 78 | roles.add(role); 79 | } 80 | user.setRoles(roles); 81 | return user; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/model/Role.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import com.wissensalt.test.sar.auditrail.AAuditTrail; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import org.hibernate.annotations.Where; 8 | 9 | import javax.persistence.*; 10 | import java.util.HashSet; 11 | import java.util.Set; 12 | 13 | /** 14 | * Created on 5/8/19. 15 | * 16 | * @author Achmad Fauzi 17 | */ 18 | @Where(clause = "status=true") 19 | @Getter 20 | @Setter 21 | @Entity 22 | @Table(name = "sec_role") 23 | public class Role extends AAuditTrail { 24 | /** 25 | * 26 | * 27 | */ 28 | private static final long serialVersionUID = 5906359157470193026L; 29 | 30 | @JsonIgnore 31 | @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "roles") 32 | private Set users = new HashSet<>(); 33 | } 34 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/model/User.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.model; 2 | 3 | import com.wissensalt.test.sar.auditrail.AAuditTrail; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | import lombok.Setter; 8 | import org.hibernate.annotations.Where; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.security.core.GrantedAuthority; 12 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 13 | import org.springframework.security.core.userdetails.UserDetails; 14 | 15 | import javax.persistence.*; 16 | import javax.validation.constraints.Email; 17 | import java.util.Collection; 18 | import java.util.Date; 19 | import java.util.HashSet; 20 | import java.util.Set; 21 | import java.util.stream.Collectors; 22 | 23 | /** 24 | * Created on 5/8/19. 25 | * 26 | * @author Achmad Fauzi 27 | */ 28 | @Where(clause = "status=true") 29 | @Getter 30 | @Setter 31 | @AllArgsConstructor 32 | @NoArgsConstructor 33 | @Entity 34 | @Table(name = "sec_user") 35 | public class User extends AAuditTrail implements UserDetails { 36 | /** 37 | * 38 | * 39 | */ 40 | private static final long serialVersionUID = 1170842867204324354L; 41 | 42 | private static final Logger LOGGER = LoggerFactory.getLogger(User.class); 43 | 44 | private static Date CURRENT_DATE = new Date(); 45 | 46 | @Column(name = "first_name") 47 | private String firstName; 48 | 49 | @Column(name = "last_name") 50 | private String lastName; 51 | 52 | @Column(name = "mobile_number", unique = true, nullable = false) 53 | private String mobileNumber; 54 | 55 | @Temporal(TemporalType.DATE) 56 | @Column(name = "date_of_birth", nullable = false) 57 | private Date dateOfBirth; 58 | 59 | @Email(message = "Email must be valid") 60 | @Column(name = "email", unique = true, nullable = false) 61 | private String email; 62 | 63 | @Column(name = "gender") 64 | private Integer gender; 65 | 66 | @Column(name = "password") 67 | private String password; 68 | 69 | @Column(name = "enabled") 70 | private Boolean enabled; 71 | 72 | @Temporal(TemporalType.TIMESTAMP) 73 | @Column(name = "expired_date") 74 | private Date expiredDate; 75 | 76 | @Temporal(TemporalType.TIMESTAMP) 77 | @Column(name = "credentials_expired_date") 78 | private Date credentialsExpiredDate; 79 | 80 | @Column(name = "account_non_locked") 81 | private Boolean nonLocked; 82 | 83 | @Column(name = "login_status") 84 | private Boolean loginStatus; 85 | 86 | @Temporal(TemporalType.TIMESTAMP) 87 | @Column(name = "last_login") 88 | private Date lastLogin; 89 | 90 | @ManyToMany( 91 | fetch = FetchType.EAGER, 92 | cascade = CascadeType.ALL 93 | ) 94 | @JoinTable( 95 | name = "link_user_role", 96 | joinColumns = {@JoinColumn( 97 | name = "user_id", 98 | referencedColumnName = "id" 99 | )}, 100 | inverseJoinColumns = {@JoinColumn( 101 | name = "role_id", 102 | referencedColumnName = "id" 103 | )} 104 | ) 105 | private Set roles = new HashSet<>(); 106 | 107 | @Override 108 | public Collection getAuthorities() { 109 | for (Role role : getRoles()) { 110 | LOGGER.debug(role.getName()); 111 | } 112 | return getRoles().stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList()); 113 | } 114 | 115 | @Override 116 | public String getUsername() { 117 | return this.getCode(); 118 | } 119 | 120 | @Override 121 | public boolean isAccountNonExpired() { 122 | return this.getExpiredDate().compareTo(CURRENT_DATE) > 0; 123 | } 124 | 125 | @Override 126 | public boolean isAccountNonLocked() { 127 | return this.getNonLocked(); 128 | } 129 | 130 | @Override 131 | public boolean isCredentialsNonExpired() { 132 | return this.getCredentialsExpiredDate().compareTo(CURRENT_DATE) > 0; 133 | } 134 | 135 | @Override 136 | public boolean isEnabled() { 137 | return this.getEnabled(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/model/base/ABaseAuditTrail.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.model.base; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import org.springframework.data.annotation.CreatedBy; 6 | import org.springframework.data.annotation.CreatedDate; 7 | import org.springframework.data.annotation.LastModifiedBy; 8 | import org.springframework.data.annotation.LastModifiedDate; 9 | 10 | import javax.persistence.Column; 11 | import javax.persistence.MappedSuperclass; 12 | import javax.validation.constraints.Size; 13 | import java.util.Date; 14 | 15 | /** 16 | * Created on 2/27/19. 17 | * 18 | * @author Achmad Fauzi 19 | */ 20 | @Getter 21 | @Setter 22 | @MappedSuperclass 23 | public abstract class ABaseAuditTrail extends BaseMasterDATA { 24 | /** 25 | * 26 | * 27 | */ 28 | private static final long serialVersionUID = -4888747591156741211L; 29 | 30 | @CreatedBy 31 | @Column(name= "created_by", length=150) 32 | @Size(max = 150) 33 | protected String createdBy; 34 | 35 | @CreatedDate 36 | @Column(name = "created_on", nullable = false, updatable = false) 37 | protected Date createdOn; 38 | 39 | @LastModifiedBy 40 | @Column(name = "updated_by", length = 150) 41 | protected String modifiedBy; 42 | 43 | @LastModifiedDate 44 | @Column(name = "updated_on") 45 | protected Date modifiedOn; 46 | } -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/model/base/ASimpleAuditTrail.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.model.base; 2 | 3 | import com.wissensalt.test.sar.auditrail.AppAuditorAware; 4 | import lombok.AccessLevel; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 8 | 9 | import javax.persistence.EntityListeners; 10 | import javax.persistence.MappedSuperclass; 11 | import javax.persistence.Transient; 12 | 13 | /** 14 | * Created on 2/27/19. 15 | * 16 | * @author Achmad Fauzi 17 | */ 18 | @MappedSuperclass 19 | @EntityListeners(AuditingEntityListener.class) 20 | public abstract class ASimpleAuditTrail extends BaseMasterDATA { 21 | /** 22 | * 23 | * 24 | */ 25 | private static final long serialVersionUID = -5338452813229316294L; 26 | 27 | @Getter(AccessLevel.NONE) 28 | @Setter(AccessLevel.NONE) 29 | @Transient 30 | private AppAuditorAware auditorAware; 31 | 32 | public ASimpleAuditTrail() { 33 | auditorAware = new AppAuditorAware(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/model/base/BaseMasterDATA.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.model.base; 2 | 3 | /** 4 | * Created on 2/27/19. 5 | * 6 | * @author Achmad Fauzi 7 | */ 8 | 9 | import lombok.Getter; 10 | import lombok.Setter; 11 | 12 | import javax.persistence.*; 13 | import javax.validation.constraints.NotNull; 14 | import javax.validation.constraints.Size; 15 | import java.io.Serializable; 16 | 17 | /** 18 | * 19 | * @author Achmad Fauzi 20 | * @param 21 | */ 22 | @Getter 23 | @Setter 24 | @MappedSuperclass 25 | public class BaseMasterDATA implements ISingleKeyDATA, Serializable { 26 | /** 27 | * 28 | * 29 | */ 30 | private static final long serialVersionUID = -81861420500108351L; 31 | 32 | @Id 33 | @GeneratedValue(strategy= GenerationType.IDENTITY) 34 | @Column(name= "id", nullable = false) 35 | private KEY id; 36 | 37 | @Column(name = "code", length = 50, unique = true, nullable = false) 38 | @NotNull(message = "Code Field of Entity is Required") 39 | @Size(max = 50) 40 | private String code; 41 | 42 | @Size(max = 50) 43 | @NotNull(message = "Name Field of Entity is Required") 44 | @Column(name = "name", length = 50) 45 | private String name; 46 | 47 | @Column(name= "status", nullable = false) 48 | protected Boolean status; 49 | 50 | @Size(max = 256) 51 | @Column(name= "remarks", length=256) 52 | protected String remarks; 53 | 54 | @Override 55 | public KEY getId() { 56 | return id; 57 | } 58 | } -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/model/base/ISingleKeyDATA.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.model.base; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Created on 2/27/19. 7 | * 8 | * @author Achmad Fauzi 9 | */ 10 | public interface ISingleKeyDATA { 11 | 12 | public KEY getId(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/service/IAuthenticationService.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.service; 2 | 3 | import com.wissensalt.test.sar.exception.ServiceException; 4 | import com.wissensalt.test.sar.model.User; 5 | import org.springframework.security.web.authentication.logout.LogoutHandler; 6 | 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | /** 10 | * Created on 5/17/18. 11 | * 12 | * @author Achmad Fauzi 13 | */ 14 | public interface IAuthenticationService extends LogoutHandler { 15 | 16 | User login(String p_UserName) throws ServiceException; 17 | 18 | void updateStatusLoggedIn(User p_User) throws ServiceException; 19 | 20 | void updateStatusLoggedOut(String p_UserName) throws ServiceException; 21 | 22 | void logoutJwt(HttpServletResponse httpServletResponse, String p_CookieName) throws ServiceException; 23 | } 24 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/service/IRegistrationService.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.service; 2 | 3 | import com.wissensalt.test.sar.dto.RequestRegistrationDTO; 4 | import com.wissensalt.test.sar.exception.ServiceException; 5 | import org.springframework.http.ResponseEntity; 6 | 7 | /** 8 | * Created on 5/8/19. 9 | * 10 | * @author Achmad Fauzi 11 | */ 12 | public interface IRegistrationService { 13 | 14 | ResponseEntity register(RequestRegistrationDTO p_Request) throws ServiceException; 15 | } 16 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/service/impl/AuthenticationServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.service.impl; 2 | 3 | import com.wissensalt.test.sar.dao.IUserDAO; 4 | import com.wissensalt.test.sar.exception.DAOException; 5 | import com.wissensalt.test.sar.exception.ServiceException; 6 | import com.wissensalt.test.sar.model.User; 7 | import com.wissensalt.test.sar.service.IAuthenticationService; 8 | import com.wissensalt.test.sar.util.CookieUtil; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.security.core.Authentication; 13 | import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; 14 | import org.springframework.stereotype.Service; 15 | 16 | import javax.servlet.http.HttpServletRequest; 17 | import javax.servlet.http.HttpServletResponse; 18 | import java.util.Date; 19 | 20 | /** 21 | * Created on 5/17/18. 22 | * 23 | * @author Achmad Fauzi 24 | */ 25 | @Service 26 | public class AuthenticationServiceImpl implements IAuthenticationService { 27 | 28 | @Autowired 29 | private IUserDAO userDAO; 30 | 31 | private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationServiceImpl.class); 32 | 33 | @Override 34 | public User login(String p_UserName) throws ServiceException { 35 | User user = null; 36 | try { 37 | user = userDAO.findByCodeOrEmail(p_UserName, p_UserName); 38 | } catch (DAOException e) { 39 | LOGGER.error("Error Searching User By UserName or PhoneNumber of Email {}", e.toString()); 40 | } 41 | if(user != null) { 42 | LOGGER.debug("User Found : {}", user.getCode()); 43 | return user; 44 | }else { 45 | LOGGER.warn("User Not Found"); 46 | return null; 47 | } 48 | } 49 | 50 | @Override 51 | public void updateStatusLoggedIn(User p_User) throws ServiceException { 52 | p_User.setLastLogin(new Date()); 53 | p_User.setLoginStatus(Boolean.TRUE); 54 | userDAO.save(p_User); 55 | } 56 | 57 | @Override 58 | public void updateStatusLoggedOut(String p_UserName) throws ServiceException { 59 | User p_User = null; 60 | try { 61 | p_User = userDAO.findByCodeAndStatus(p_UserName, true); 62 | } catch (DAOException e) { 63 | LOGGER.error("Error Searching User {} : {}", p_UserName, e.toString()); 64 | } 65 | if (p_User != null) { 66 | p_User.setLoginStatus(Boolean.FALSE); 67 | userDAO.save(p_User); 68 | }else { 69 | LOGGER.error("Error Updating Status Logout"); 70 | } 71 | } 72 | 73 | @Override 74 | public void logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) { 75 | CookieUtil.clearBasicAuth(httpServletRequest, httpServletResponse, authentication); 76 | new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, authentication); 77 | } 78 | 79 | @Override 80 | public void logoutJwt(HttpServletResponse httpServletResponse, String p_CookieName) throws ServiceException { 81 | CookieUtil.clear(httpServletResponse, p_CookieName); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/service/impl/CustomUserDetailService.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.service.impl; 2 | 3 | import com.wissensalt.test.sar.dao.IUserDAO; 4 | import com.wissensalt.test.sar.exception.DAOException; 5 | import com.wissensalt.test.sar.model.User; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 12 | import org.springframework.stereotype.Service; 13 | 14 | /** 15 | * Created on 5/2/18. 16 | * 17 | * @author Achmad Fauzi 18 | */ 19 | @Service 20 | public class CustomUserDetailService implements UserDetailsService { 21 | 22 | @Autowired 23 | private IUserDAO userDAO; 24 | 25 | private static final Logger LOGGER = LoggerFactory.getLogger(CustomUserDetailService.class); 26 | 27 | @Override 28 | public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { 29 | User user; 30 | try { 31 | user = userDAO.findByCodeAndStatus(s, true); 32 | } catch (DAOException e) { 33 | LOGGER.error("error find user by code {} : {}", s, e.toString()); 34 | throw new UsernameNotFoundException("User Name not Found"); 35 | } 36 | return user; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/service/impl/RegistrationServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.service.impl; 2 | 3 | import com.wissensalt.test.sar.dao.IUserDAO; 4 | import com.wissensalt.test.sar.dto.RequestRegistrationDTO; 5 | import com.wissensalt.test.sar.dto.ResponseData; 6 | import com.wissensalt.test.sar.dto.ResponseValidationDTO; 7 | import com.wissensalt.test.sar.mapper.UserMapper; 8 | import com.wissensalt.test.sar.service.IRegistrationService; 9 | import com.wissensalt.test.sar.statval.ISarConstant; 10 | import com.wissensalt.test.sar.statval.ISarConstant.Bean; 11 | import com.wissensalt.test.sar.util.APIErrorBuilder; 12 | import com.wissensalt.test.sar.validation.IRequestValidator; 13 | import org.hibernate.service.spi.ServiceException; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.beans.factory.annotation.Qualifier; 18 | import org.springframework.http.HttpStatus; 19 | import org.springframework.http.ResponseEntity; 20 | import org.springframework.stereotype.Service; 21 | import org.springframework.transaction.annotation.Isolation; 22 | import org.springframework.transaction.annotation.Transactional; 23 | 24 | import static com.wissensalt.test.sar.statval.ISarConstant.Path.REGISTER; 25 | 26 | /** 27 | * Created on 5/8/19. 28 | * 29 | * @author Achmad Fauzi 30 | */ 31 | @Service 32 | public class RegistrationServiceImpl implements IRegistrationService { 33 | 34 | @Autowired private IUserDAO userDAO; 35 | @Autowired private UserMapper userMapper; 36 | @Autowired @Qualifier(Bean.REGISTRATION_VALIDATOR) private IRequestValidator registrationValidator; 37 | private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationServiceImpl.class); 38 | 39 | @Transactional(isolation = Isolation.READ_COMMITTED) 40 | @Override 41 | public ResponseEntity register(RequestRegistrationDTO p_Request) throws ServiceException { 42 | ResponseEntity response; 43 | ResponseValidationDTO responseValidation = registrationValidator.validate(p_Request); 44 | if (responseValidation.getIsValid()) { 45 | userDAO.save(userMapper.convert(p_Request)); 46 | response = ResponseEntity.ok(new ResponseData("200", "Success Register User")); 47 | }else { 48 | LOGGER.error("Request is not Valid {}", responseValidation.getMessage()); 49 | response = new ResponseEntity<>(APIErrorBuilder.badRequest(RegistrationServiceImpl.class, responseValidation.getMessage(), ISarConstant.Path.REGISTRATION.concat(REGISTER)), HttpStatus.BAD_REQUEST); 50 | } 51 | return response; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/statval/ISarConstant.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.statval; 2 | 3 | /** 4 | * Created on 5/8/19. 5 | * 6 | * @author Achmad Fauzi 7 | */ 8 | public interface ISarConstant { 9 | 10 | interface Bean { 11 | String REGISTRATION_VALIDATOR = "bean-registration-validator"; 12 | } 13 | 14 | interface Path { 15 | String REGISTRATION = "/registration"; 16 | String LOGIN = "/login"; 17 | String REGISTER = "/register"; 18 | String DASHBOARD = "/api/dashboard"; 19 | } 20 | 21 | interface RoleCode { 22 | String ADMIN = "ROLE_ADMIN"; 23 | } 24 | 25 | interface RoleName { 26 | String ADMIN = "ADMIN"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/util/APIErrorBuilder.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.util; 2 | 3 | import com.wissensalt.test.sar.dto.ResponseAPIErrorDTO; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * Created on 5/8/19. 9 | * 10 | * @author Achmad Fauzi 11 | */ 12 | public class APIErrorBuilder { 13 | 14 | private static final Integer NOT_FOUND_STATUS = 404; 15 | private static final Integer INTERNAL_SERVER_ERROR = 500; 16 | private static final Integer BAD_REQUEST = 400; 17 | private static final Integer CONFLICT = 409; 18 | private static final Integer GONE = 401; 19 | 20 | public static ResponseAPIErrorDTO notFound(Class p_Exception, String p_Message, String p_Path) { 21 | return new ResponseAPIErrorDTO( 22 | new Date(), 23 | NOT_FOUND_STATUS, 24 | p_Exception.getCanonicalName(), 25 | p_Message, 26 | p_Path, 27 | "Not Found" 28 | ); 29 | } 30 | 31 | 32 | public static ResponseAPIErrorDTO conflict(Class p_Exception, String p_Message, String p_Path) { 33 | return new ResponseAPIErrorDTO( 34 | new Date(), 35 | CONFLICT, 36 | p_Exception.getCanonicalName(), 37 | p_Message, 38 | p_Path, 39 | "Conflict" 40 | ); 41 | } 42 | 43 | public static ResponseAPIErrorDTO internalServerError(Class p_Exception, String p_Message, String p_Path) { 44 | return new ResponseAPIErrorDTO( 45 | new Date(), 46 | INTERNAL_SERVER_ERROR, 47 | p_Exception.getCanonicalName(), 48 | p_Message, 49 | p_Path, 50 | "Internal Server Error" 51 | ); 52 | } 53 | 54 | public static ResponseAPIErrorDTO badRequest(Class p_Exception, String p_Message, String p_Path) { 55 | return new ResponseAPIErrorDTO( 56 | new Date(), 57 | BAD_REQUEST, 58 | p_Exception.getCanonicalName(), 59 | p_Message, 60 | p_Path, 61 | "Bad Request" 62 | ); 63 | } 64 | 65 | public static ResponseAPIErrorDTO gone(Class p_Exception, String p_Message, String p_Path) { 66 | return new ResponseAPIErrorDTO( 67 | new Date(), 68 | GONE, 69 | p_Exception.getCanonicalName(), 70 | p_Message, 71 | p_Path, 72 | "Gone" 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/util/CookieUtil.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.util; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.security.core.Authentication; 6 | import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler; 7 | import org.springframework.web.util.WebUtils; 8 | 9 | import javax.servlet.http.Cookie; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | /** 14 | * Created on 7/9/18. 15 | * 16 | * @author Achmad Fauzi 17 | */ 18 | public class CookieUtil { 19 | 20 | private static final Logger LOGGER = LoggerFactory.getLogger(CookieUtil.class); 21 | 22 | public static void create(HttpServletResponse httpServletResponse, String name, String value, Boolean secure, Integer maxAge, String domain) { 23 | Cookie cookie = new Cookie(name, value); 24 | cookie.setSecure(secure); 25 | cookie.setMaxAge(maxAge); 26 | cookie.setDomain(domain); 27 | cookie.setPath("/"); 28 | httpServletResponse.addCookie(cookie); 29 | } 30 | 31 | public static void clear(HttpServletResponse httpServletResponse, String cookieName) { 32 | Cookie cookie = new Cookie(cookieName, null); 33 | cookie.setPath("/"); 34 | cookie.setMaxAge(0); 35 | httpServletResponse.addCookie(cookie); 36 | } 37 | 38 | public static void clearBasicAuth(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) { 39 | String JAVA_COOKIE_SESSION = "JSESSIONID"; 40 | if (httpServletRequest.getCookies() != null) { 41 | for(Cookie cookie : httpServletRequest.getCookies()) { 42 | if(cookie.getName().equals(JAVA_COOKIE_SESSION)) { 43 | cookie.setMaxAge(0); 44 | cookie.setPath(httpServletRequest.getContextPath()); 45 | httpServletResponse.addCookie(cookie); 46 | //Clear the other cookie 47 | Cookie cookieWithSlash = (Cookie) cookie.clone(); 48 | cookieWithSlash.setPath(httpServletRequest.getContextPath() + "/"); 49 | httpServletResponse.addCookie(cookieWithSlash); 50 | } 51 | } 52 | new CookieClearingLogoutHandler(JAVA_COOKIE_SESSION).logout(httpServletRequest, httpServletResponse, authentication); 53 | } else { 54 | LOGGER.info("Cookie is Empty, Cancel Process Clearing Cookie"); 55 | } 56 | } 57 | 58 | public static String getValue(HttpServletRequest httpServletRequest, String name) { 59 | Cookie cookie = WebUtils.getCookie(httpServletRequest, name); 60 | return cookie != null ? cookie.getValue() : null; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/util/DateUtil.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.util; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Calendar; 5 | import java.util.Date; 6 | 7 | /** 8 | * Created on 5/8/19. 9 | * 10 | * @author Achmad Fauzi 11 | */ 12 | public class DateUtil { 13 | 14 | public static SimpleDateFormat BirthDateFormatter = new SimpleDateFormat("dd-MM-yyyy"); 15 | 16 | public static Date addNYearToDate(int n, Date p_PrevDate) { 17 | Calendar c = Calendar.getInstance(); 18 | c.setTime(p_PrevDate); 19 | c.add(Calendar.YEAR, n); 20 | return c.getTime(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/validation/GeneralValidation.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.validation; 2 | 3 | /** 4 | * Created on 5/8/19. 5 | * 6 | * @author Achmad Fauzi 7 | */ 8 | public class GeneralValidation { 9 | /** 10 | * Validate Email 11 | * @param email String 12 | * @return boolean 13 | */ 14 | public static boolean isValidEmail(String email){ 15 | String emailPattern = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+"; 16 | email = email.trim(); 17 | return email.matches(emailPattern) && email.length() > 0; 18 | } 19 | 20 | /** 21 | * Validate if a String is a Phone Number 22 | * @param phoneNumber String 23 | * @return boolean 24 | */ 25 | public static boolean isValidPhoneNumber(String phoneNumber){ 26 | // String phoneNumberPattern = "^([0-9\\(\\)\\/\\+ \\-]*)$"; 27 | String phoneNumberPattern = "^08[0-9]{9,}$"; 28 | phoneNumber = phoneNumber.trim(); 29 | return phoneNumber.matches( phoneNumberPattern ) && phoneNumber.length() > 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/validation/IRequestValidator.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.validation; 2 | 3 | import com.wissensalt.test.sar.dto.ResponseValidationDTO; 4 | 5 | /** 6 | * Created on 5/8/19. 7 | * 8 | * @author Achmad Fauzi 9 | * @param 10 | */ 11 | public interface IRequestValidator { 12 | 13 | ResponseValidationDTO validate(REQUEST_DTO p_Request); 14 | } 15 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/java/com/wissensalt/test/sar/validation/RegistrationValidator.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar.validation; 2 | 3 | import com.wissensalt.test.sar.dao.IUserDAO; 4 | import com.wissensalt.test.sar.dto.RequestRegistrationDTO; 5 | import com.wissensalt.test.sar.dto.ResponseValidationDTO; 6 | import com.wissensalt.test.sar.exception.DAOException; 7 | import com.wissensalt.test.sar.model.User; 8 | import com.wissensalt.test.sar.statval.ISarConstant.Bean; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.beans.factory.annotation.Qualifier; 13 | import org.springframework.stereotype.Service; 14 | 15 | /** 16 | * Created on 5/8/19. 17 | * 18 | * @author Achmad Fauzi 19 | */ 20 | @Service 21 | @Qualifier(value = Bean.REGISTRATION_VALIDATOR) 22 | public class RegistrationValidator implements IRequestValidator { 23 | 24 | @Autowired private IUserDAO userDAO; 25 | private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationValidator.class); 26 | 27 | @Override 28 | public ResponseValidationDTO validate(RequestRegistrationDTO p_Request) { 29 | ResponseValidationDTO result = new ResponseValidationDTO(); 30 | result.setIsValid(false); 31 | if (p_Request.getMobileNumber() != null && p_Request.getMobileNumber().length() > 0) { 32 | if (GeneralValidation.isValidPhoneNumber(p_Request.getMobileNumber())) { 33 | User user = null; 34 | try { 35 | user = userDAO.findByMobileNumber(p_Request.getMobileNumber()); 36 | } catch (DAOException e) { 37 | LOGGER.error("Error searching user by mobile number {} : {}", p_Request.getMobileNumber(), e.toString()); 38 | } 39 | if (user == null) { 40 | if (p_Request.getFirstName() != null && p_Request.getFirstName().length() > 0) { 41 | if (p_Request.getLastName() != null && p_Request.getFirstName().length() > 0) { 42 | if (p_Request.getEmail() != null && p_Request.getEmail().length()> 0) { 43 | if (GeneralValidation.isValidEmail(p_Request.getEmail())) { 44 | try { 45 | user = userDAO.findByEmail(p_Request.getEmail()); 46 | } catch (DAOException e) { 47 | LOGGER.error("Error find User By Email {} : {}", p_Request.getEmail(), e.toString()); 48 | } 49 | if (user == null) { 50 | result.setIsValid(true); 51 | }else { 52 | result.setMessage("User with email "+p_Request.getEmail()+" has already exist"); 53 | } 54 | }else { 55 | result.setMessage("Email must be in valid format"); 56 | } 57 | }else { 58 | result.setMessage("Email can not be null & length must be > 0"); 59 | } 60 | }else { 61 | result.setMessage("Last Name can not be null & length must be > 0"); 62 | } 63 | }else { 64 | result.setMessage("First Name can not be null & length must be > 0"); 65 | } 66 | }else { 67 | result.setMessage("User with Phone Number "+p_Request.getMobileNumber()+" is exist"); 68 | } 69 | }else { 70 | result.setMessage("Phone Number must be in valid Indonesia format"); 71 | } 72 | }else { 73 | result.setMessage("Mobile Phone can not be null & length must be > 0"); 74 | } 75 | return result; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | #============================================================================ 2 | # SERVER 3 | #============================================================================ 4 | server: 5 | port: 8081 6 | tomcat: 7 | max-threads: 500 8 | connection-timeout: 30000 #in milisecond 9 | # servlet: 10 | # context-path : /sar 11 | 12 | #============================================================================ 13 | # SPRING 14 | #============================================================================ 15 | spring: 16 | profiles: 17 | active: local 18 | application: 19 | name : spring-angular-registration 20 | datasource: 21 | initialization-mode: always 22 | driver-class-name : org.postgresql.Driver 23 | url : jdbc:postgresql://localhost:5432/sar_db 24 | username : postgres 25 | password : pgadmin 26 | hikari: 27 | minimumIdle: 1 28 | maximumPoolSize: 5 29 | idleTimeout: 30000 30 | poolName: sar-connection-pooling 31 | maxLifetime: 2000000 32 | connectionTimeout: 60000 33 | jpa: 34 | show-sql: false 35 | properties: 36 | hibernate: 37 | jdbc: 38 | lob: 39 | non_contextual_creation: true 40 | naming_strategy : org.hibernate.cfg.EJB3NamingStrategy 41 | dialect: org.hibernate.dialect.PostgreSQL9Dialect 42 | ddl-auto: validate # Hibernate ddl auto (create, create-drop, validate, update) 43 | hibernate: 44 | ddl-auto: none 45 | #============================================================================ 46 | # LOGGER 47 | #============================================================================ 48 | logging: 49 | config: classpath:logback-spring.xml 50 | file : ${log.file.path} 51 | level: 52 | com.wissensalt.test.sar : DEBUG 53 | # org.springframework.security : DEBUG 54 | 55 | #============================================================================ 56 | # LOG FILE PATH 57 | #============================================================================ 58 | log : 59 | file : 60 | path : ./sar.log -------------------------------------------------------------------------------- /spring-angular-registration/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SPRING-ANGULAR-REGISTRATION | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | SPRING-ANGULAR-REGISTRATION | %d{dd-MM-yyyy} %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 18 | 19 | ${LOG_FILE} 20 | 21 | 22 | ${LOG_FILE}.%i 23 | 1 24 | 50 25 | 26 | 27 | 29 | 100MB 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /spring-angular-registration/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | -- Table: public.sec_user 2 | 3 | -- DROP TABLE public.sec_user; 4 | 5 | CREATE TABLE public.sec_user 6 | ( 7 | id bigserial, 8 | code character varying(50), 9 | name character varying(150), 10 | first_name character varying(50), 11 | last_name character varying(50), 12 | mobile_number character varying(13), 13 | date_of_birth timestamp without time zone, 14 | email character varying(256), 15 | remarks character varying(256), 16 | status boolean, 17 | created_by character varying(50), 18 | created_on timestamp without time zone, 19 | updated_by character varying(50), 20 | updated_on timestamp without time zone, 21 | password character varying(256), 22 | enabled boolean, 23 | expired_date timestamp without time zone, 24 | account_non_locked boolean, 25 | login_status boolean, 26 | last_login timestamp without time zone, 27 | credentials_expired_date timestamp without time zone, 28 | gender smallint, 29 | CONSTRAINT pk_user PRIMARY KEY (id), 30 | CONSTRAINT unique_code_user UNIQUE (code) 31 | ); 32 | 33 | -- Table: public.sec_role 34 | 35 | -- DROP TABLE public.sec_role; 36 | 37 | CREATE TABLE public.sec_role 38 | ( 39 | id bigserial, 40 | code character varying(50), 41 | name character varying(150), 42 | remarks character varying(256), 43 | status boolean, 44 | created_by character varying(50), 45 | created_on timestamp without time zone, 46 | updated_by character varying(50), 47 | updated_on timestamp without time zone, 48 | CONSTRAINT pk_role PRIMARY KEY (id), 49 | CONSTRAINT unique_role UNIQUE (code) 50 | ); 51 | 52 | 53 | -- Table: public.link_user_role 54 | 55 | -- DROP TABLE public.link_user_role; 56 | 57 | CREATE TABLE public.link_user_role 58 | ( 59 | user_id bigint, 60 | role_id bigint, 61 | CONSTRAINT fk_role_id FOREIGN KEY (role_id) 62 | REFERENCES public.sec_role (id) MATCH SIMPLE 63 | ON UPDATE NO ACTION ON DELETE NO ACTION, 64 | CONSTRAINT role_id FOREIGN KEY (user_id) 65 | REFERENCES public.sec_user (id) MATCH SIMPLE 66 | ON UPDATE NO ACTION ON DELETE NO ACTION 67 | ) 68 | 69 | -------------------------------------------------------------------------------- /spring-angular-registration/src/test/java/com/wissensalt/test/sar/SpringAngularRegistrationApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.wissensalt.test.sar; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.wissensalt.test.sar.dto.RequestRegistrationDTO; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.http.MediaType; 11 | import org.springframework.test.annotation.Rollback; 12 | import org.springframework.test.context.junit4.SpringRunner; 13 | import org.springframework.test.web.servlet.MockMvc; 14 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 15 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 16 | import org.springframework.transaction.annotation.Transactional; 17 | import org.springframework.web.context.WebApplicationContext; 18 | 19 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 20 | 21 | 22 | @RunWith(SpringRunner.class) 23 | @SpringBootTest 24 | @Transactional 25 | public class SpringAngularRegistrationApplicationTests { 26 | 27 | @Autowired 28 | private WebApplicationContext webApplicationContext; 29 | 30 | private MockMvc mockMvc; 31 | 32 | private ObjectMapper mapper = new ObjectMapper(); 33 | 34 | @Before 35 | public void setUp() { 36 | mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); 37 | } 38 | 39 | @Test 40 | @Rollback(true) 41 | public void testRegisterUser() throws Exception { 42 | RequestRegistrationDTO requestRegistrationDTO = new RequestRegistrationDTO(); 43 | requestRegistrationDTO.setMobileNumber("081294533212"); 44 | requestRegistrationDTO.setFirstName("David"); 45 | requestRegistrationDTO.setLastName("Guetta"); 46 | requestRegistrationDTO.setGender(1); 47 | requestRegistrationDTO.setDob("12-12-1990"); 48 | requestRegistrationDTO.setEmail("guetta@gmail.com"); 49 | 50 | String inputJson = mapper.writeValueAsString(requestRegistrationDTO); 51 | mockMvc.perform( 52 | MockMvcRequestBuilders 53 | .post("/registration/register") 54 | .contentType(MediaType.APPLICATION_JSON) 55 | .accept(MediaType.APPLICATION_JSON) 56 | .content(inputJson)) 57 | .andExpect(status().isOk()); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /web-angular-registration/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /web-angular-registration/README.md: -------------------------------------------------------------------------------- 1 | # WebAngularRegistration 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.3.9. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | -------------------------------------------------------------------------------- /web-angular-registration/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "web-angular-registration": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": {}, 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "dist/web-angular-registration", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "src/tsconfig.app.json", 21 | "assets": [ 22 | "src/favicon.ico", 23 | "src/assets" 24 | ], 25 | "styles": [ 26 | "src/styles.css", 27 | "node_modules/bootstrap/dist/css/bootstrap.min.css" 28 | ], 29 | "scripts": [], 30 | "es5BrowserSupport": true 31 | }, 32 | "configurations": { 33 | "production": { 34 | "fileReplacements": [ 35 | { 36 | "replace": "src/environments/environment.ts", 37 | "with": "src/environments/environment.prod.ts" 38 | } 39 | ], 40 | "optimization": true, 41 | "outputHashing": "all", 42 | "sourceMap": false, 43 | "extractCss": true, 44 | "namedChunks": false, 45 | "aot": true, 46 | "extractLicenses": true, 47 | "vendorChunk": false, 48 | "buildOptimizer": true, 49 | "budgets": [ 50 | { 51 | "type": "initial", 52 | "maximumWarning": "2mb", 53 | "maximumError": "5mb" 54 | } 55 | ] 56 | } 57 | } 58 | }, 59 | "serve": { 60 | "builder": "@angular-devkit/build-angular:dev-server", 61 | "options": { 62 | "browserTarget": "web-angular-registration:build" 63 | }, 64 | "configurations": { 65 | "production": { 66 | "browserTarget": "web-angular-registration:build:production" 67 | } 68 | } 69 | }, 70 | "extract-i18n": { 71 | "builder": "@angular-devkit/build-angular:extract-i18n", 72 | "options": { 73 | "browserTarget": "web-angular-registration:build" 74 | } 75 | }, 76 | "test": { 77 | "builder": "@angular-devkit/build-angular:karma", 78 | "options": { 79 | "main": "src/test.ts", 80 | "polyfills": "src/polyfills.ts", 81 | "tsConfig": "src/tsconfig.spec.json", 82 | "karmaConfig": "src/karma.conf.js", 83 | "styles": [ 84 | "src/styles.css" 85 | ], 86 | "scripts": [], 87 | "assets": [ 88 | "src/favicon.ico", 89 | "src/assets" 90 | ] 91 | } 92 | }, 93 | "lint": { 94 | "builder": "@angular-devkit/build-angular:tslint", 95 | "options": { 96 | "tsConfig": [ 97 | "src/tsconfig.app.json", 98 | "src/tsconfig.spec.json" 99 | ], 100 | "exclude": [ 101 | "**/node_modules/**" 102 | ] 103 | } 104 | } 105 | } 106 | }, 107 | "web-angular-registration-e2e": { 108 | "root": "e2e/", 109 | "projectType": "application", 110 | "prefix": "", 111 | "architect": { 112 | "e2e": { 113 | "builder": "@angular-devkit/build-angular:protractor", 114 | "options": { 115 | "protractorConfig": "e2e/protractor.conf.js", 116 | "devServerTarget": "web-angular-registration:serve" 117 | }, 118 | "configurations": { 119 | "production": { 120 | "devServerTarget": "web-angular-registration:serve:production" 121 | } 122 | } 123 | }, 124 | "lint": { 125 | "builder": "@angular-devkit/build-angular:tslint", 126 | "options": { 127 | "tsConfig": "e2e/tsconfig.e2e.json", 128 | "exclude": [ 129 | "**/node_modules/**" 130 | ] 131 | } 132 | } 133 | } 134 | } 135 | }, 136 | "defaultProject": "web-angular-registration" 137 | } -------------------------------------------------------------------------------- /web-angular-registration/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /web-angular-registration/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('Welcome to web-angular-registration!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /web-angular-registration/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /web-angular-registration/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /web-angular-registration/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-angular-registration", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "^7.2.15", 15 | "@angular/cdk": "^7.3.7", 16 | "@angular/common": "~7.2.0", 17 | "@angular/compiler": "~7.2.0", 18 | "@angular/core": "~7.2.0", 19 | "@angular/forms": "~7.2.0", 20 | "@angular/material": "^7.3.7", 21 | "@angular/platform-browser": "~7.2.0", 22 | "@angular/platform-browser-dynamic": "~7.2.0", 23 | "@angular/router": "~7.2.0", 24 | "@ng-bootstrap/ng-bootstrap": "^4.1.2", 25 | "bootstrap": "^3.3.7", 26 | "core-js": "^2.5.4", 27 | "rxjs": "~6.3.3", 28 | "sweetalert2": "^8.10.7", 29 | "tslib": "^1.9.0", 30 | "zone.js": "~0.8.26" 31 | }, 32 | "devDependencies": { 33 | "@angular-devkit/build-angular": "~0.13.0", 34 | "@angular/cli": "~7.3.9", 35 | "@angular/compiler-cli": "~7.2.0", 36 | "@angular/language-service": "~7.2.0", 37 | "@types/jasmine": "~2.8.8", 38 | "@types/jasminewd2": "~2.0.3", 39 | "@types/node": "~8.9.4", 40 | "codelyzer": "~4.5.0", 41 | "https-proxy-agent": "^2.2.1", 42 | "jasmine-core": "~2.99.1", 43 | "jasmine-spec-reporter": "~4.2.1", 44 | "karma": "~4.0.0", 45 | "karma-chrome-launcher": "~2.2.0", 46 | "karma-coverage-istanbul-reporter": "~2.0.1", 47 | "karma-jasmine": "~1.1.2", 48 | "karma-jasmine-html-reporter": "^0.2.2", 49 | "protractor": "~5.4.0", 50 | "ts-node": "~7.0.0", 51 | "tslint": "~5.11.0", 52 | "typescript": "~3.2.2" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /web-angular-registration/proxy.json: -------------------------------------------------------------------------------- 1 | { 2 | "/registration/*": { 3 | "target": "http://localhost:8081", 4 | "secure": "false", 5 | "logLevel": "debug", 6 | "changeOrigin": true 7 | } 8 | } -------------------------------------------------------------------------------- /web-angular-registration/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { RegistrationFormComponent } from './registration-form/registration-form.component'; 4 | import { LoginFormComponent } from './login-form/login-form.component'; 5 | import { DashboardComponent } from './dashboard/dashboard.component'; 6 | import { AuthGuard } from './security/auth-guard'; 7 | 8 | const routes: Routes = [ 9 | { 10 | path:'', 11 | component:RegistrationFormComponent 12 | }, 13 | { 14 | path:'login', 15 | component:LoginFormComponent 16 | }, 17 | { 18 | path:'dashboard', 19 | component:DashboardComponent, 20 | canActivate: [AuthGuard] 21 | } 22 | ]; 23 | 24 | @NgModule({ 25 | imports: [RouterModule.forRoot(routes)], 26 | exports: [RouterModule] 27 | }) 28 | export class AppRoutingModule { } 29 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/web-angular-registration/src/app/app.component.css -------------------------------------------------------------------------------- /web-angular-registration/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 |
Footer
16 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async(() => { 7 | TestBed.configureTestingModule({ 8 | imports: [ 9 | RouterTestingModule 10 | ], 11 | declarations: [ 12 | AppComponent 13 | ], 14 | }).compileComponents(); 15 | })); 16 | 17 | it('should create the app', () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.debugElement.componentInstance; 20 | expect(app).toBeTruthy(); 21 | }); 22 | 23 | it(`should have as title 'WebAngularRegistration'`, () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | const app = fixture.debugElement.componentInstance; 26 | expect(app.title).toEqual('web-angular-registration'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'web-angular-registration'; 10 | } 11 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppRoutingModule } from './app-routing.module'; 5 | import { AppComponent } from './app.component'; 6 | // import { RouterModule, Routes } from '@angular/router'; 7 | import { RegistrationFormComponent } from './registration-form/registration-form.component'; 8 | import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; 9 | import {MatButtonModule} from '@angular/material'; 10 | import {MatCardModule} from '@angular/material/card'; 11 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 12 | import { LoginFormComponent } from './login-form/login-form.component'; 13 | 14 | // HttpClient module for RESTful API 15 | import { HttpClientModule } from '@angular/common/http'; 16 | import { DashboardComponent } from './dashboard/dashboard.component'; 17 | import { AuthGuard } from './security/auth-guard'; 18 | 19 | 20 | @NgModule({ 21 | declarations: [ 22 | AppComponent, 23 | RegistrationFormComponent, 24 | LoginFormComponent, 25 | DashboardComponent 26 | ], 27 | imports: [ 28 | HttpClientModule, 29 | BrowserModule, 30 | AppRoutingModule, 31 | BrowserAnimationsModule, 32 | MatButtonModule, 33 | MatCardModule, 34 | FormsModule, ReactiveFormsModule 35 | ], 36 | exports: [MatButtonModule,MatCardModule], 37 | providers: [AuthGuard], 38 | //HttpClientModule, , RegistrationClientService, LoginClientService 39 | bootstrap: [AppComponent] 40 | }) 41 | export class AppModule { } 42 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/client/login-client.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing' 3 | import { LoginClientService } from './login-client.service'; 4 | import { HttpClient } from '@angular/common/http'; 5 | 6 | describe('LoginClientService', () => { 7 | let httpClient : HttpClient; 8 | let httpTestingController : HttpTestingController; 9 | beforeEach(() => TestBed.configureTestingModule({ 10 | imports : [HttpClientTestingModule] 11 | })); 12 | 13 | beforeEach(() =>{ 14 | httpClient = TestBed.get(HttpClient); 15 | httpTestingController = TestBed.get(HttpTestingController); 16 | }); 17 | 18 | it('should be created', inject([LoginClientService], (service: LoginClientService) => { 19 | expect(service).toBeTruthy(); 20 | })); 21 | }); 22 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/client/login-client.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpHeaders, HttpClient } from '@angular/common/http'; 3 | import { ResponseData } from '../dto/response-data'; 4 | import { Observable, throwError } from 'rxjs'; 5 | import { retry, catchError, mapTo, tap } from 'rxjs/operators'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class LoginClientService { 11 | 12 | private baseUrl = "http://localhost:8081"; 13 | private loginUrl = "/auth/login"; 14 | 15 | constructor( 16 | private http: HttpClient 17 | ) { } 18 | 19 | httpOptions = { 20 | headers: new HttpHeaders( 21 | { 22 | 'Content-Type' : 'application/json' 23 | } 24 | ) 25 | } 26 | 27 | login(requestLoginDTO): Observable { 28 | return this.http.post( 29 | this.baseUrl+this.loginUrl, 30 | JSON.stringify(requestLoginDTO), 31 | this.httpOptions 32 | ).pipe( 33 | retry(1), 34 | catchError(this.handleError) 35 | ) 36 | } 37 | 38 | handleError(error) { 39 | let errorMessage = `Error Code: ${error.status} - ${error.error.error} \nMessage: ${error.error.message}`; 40 | window.alert(errorMessage); 41 | return throwError(errorMessage); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/client/registration-client.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing' 3 | import { LoginClientService } from './login-client.service'; 4 | import { HttpClient } from '@angular/common/http'; 5 | import { RegistrationClientService } from './registration-client.service'; 6 | 7 | describe('RegistrationClientService', () => { 8 | let httpClient : HttpClient; 9 | let httpTestingController : HttpTestingController; 10 | 11 | beforeEach(() => TestBed.configureTestingModule({ 12 | imports : [HttpClientTestingModule] 13 | })); 14 | 15 | beforeEach(() =>{ 16 | httpClient = TestBed.get(HttpClient); 17 | httpTestingController = TestBed.get(HttpTestingController); 18 | }); 19 | 20 | it('should be created', inject([RegistrationClientService], (service: LoginClientService) => { 21 | expect(service).toBeTruthy(); 22 | })); 23 | }); 24 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/client/registration-client.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpHeaders, HttpClient, HttpErrorResponse } from '@angular/common/http'; 3 | import { RequestRegistration } from '../dto/request-registration'; 4 | import { ResponseData } from '../dto/response-data'; 5 | import { Observable, throwError } from 'rxjs'; 6 | import { retry, catchError } from 'rxjs/operators'; 7 | import { ResponseError } from '../dto/response-error'; 8 | 9 | const httpOptions = { 10 | headers: new HttpHeaders( 11 | { 12 | 'Content-Type' : 'application/json' 13 | } 14 | ) 15 | } 16 | 17 | @Injectable({ 18 | providedIn: 'root' 19 | }) 20 | export class RegistrationClientService { 21 | 22 | baseUrl = "http://localhost:8081"; 23 | registrationUrl = "/registration/register" 24 | constructor( 25 | private http: HttpClient 26 | ) { } 27 | 28 | register(requestRegistrationDTO: RequestRegistration): Observable { 29 | return this.http.post( 30 | this.baseUrl+this.registrationUrl, 31 | requestRegistrationDTO, 32 | httpOptions 33 | ).pipe( 34 | retry(1), 35 | catchError(this.handleError) 36 | ) 37 | } 38 | 39 | handleError(error) { 40 | let errorMessage = `Error Code: ${error.status} - ${error.error.error} \nMessage: ${error.error.message}`; 41 | window.alert(errorMessage); 42 | return throwError(errorMessage); 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dashboard/dashboard.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/web-angular-registration/src/app/dashboard/dashboard.component.css -------------------------------------------------------------------------------- /web-angular-registration/src/app/dashboard/dashboard.component.html: -------------------------------------------------------------------------------- 1 |
2 |

Welcome {{ userName }}!

3 | 4 |
5 |
6 | 7 |
8 |
9 |
-------------------------------------------------------------------------------- /web-angular-registration/src/app/dashboard/dashboard.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { DashboardComponent } from './dashboard.component'; 4 | 5 | describe('DashboardComponent', () => { 6 | let component: DashboardComponent; 7 | let fixture: ComponentFixture; 8 | 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | imports: [RouterTestingModule], 13 | declarations: [ DashboardComponent ] 14 | }) 15 | .compileComponents(); 16 | })); 17 | 18 | beforeEach(() => { 19 | fixture = TestBed.createComponent(DashboardComponent); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it('should create', () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dashboard/dashboard.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | 4 | @Component({ 5 | selector: 'app-dashboard', 6 | templateUrl: './dashboard.component.html', 7 | styleUrls: ['./dashboard.component.css'] 8 | }) 9 | export class DashboardComponent implements OnInit { 10 | 11 | userName : any; 12 | constructor(private router: Router) { } 13 | 14 | ngOnInit() { 15 | this.userName = localStorage.getItem("userName"); 16 | } 17 | 18 | logout() { 19 | localStorage.removeItem("isLoggedIn"); 20 | localStorage.removeItem("userName"); 21 | this.router.navigate(["/login"]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/request-login.spec.ts: -------------------------------------------------------------------------------- 1 | import { RequestLogin } from './request-login'; 2 | 3 | describe('RequestLogin', () => { 4 | it('should create an instance', () => { 5 | expect(new RequestLogin()).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/request-login.ts: -------------------------------------------------------------------------------- 1 | export class RequestLogin { 2 | userName : string; 3 | password : string; 4 | 5 | public setUserName(p_UserName : string) { 6 | this.userName = p_UserName; 7 | } 8 | 9 | public getUserName() : string { 10 | return this.userName; 11 | } 12 | 13 | public setPassword(p_Password : string) { 14 | this.password = p_Password; 15 | } 16 | 17 | public getPassword() : string { 18 | return this.password; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/request-registration.spec.ts: -------------------------------------------------------------------------------- 1 | import { RequestRegistration } from './request-registration'; 2 | 3 | describe('RequestRegistration', () => { 4 | it('should create an instance', () => { 5 | expect(new RequestRegistration()).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/request-registration.ts: -------------------------------------------------------------------------------- 1 | export class RequestRegistration { 2 | private mobileNumber : string; 3 | private firstName : string; 4 | private lastName : string; 5 | private dob : string; 6 | private gender : number; 7 | private email : string; 8 | 9 | public setMobileNumber(p_MobileNumber: string){ 10 | this.mobileNumber = p_MobileNumber; 11 | } 12 | 13 | public getMobileNumber() : string { 14 | return this.mobileNumber; 15 | } 16 | 17 | public setFirstName(p_FirstName: string) { 18 | this.firstName = p_FirstName; 19 | } 20 | 21 | public getFirstName() : string { 22 | return this.firstName; 23 | } 24 | 25 | public setLastName(p_LastName : string) { 26 | this.lastName = p_LastName; 27 | } 28 | 29 | public getLastName() : string { 30 | return this.lastName; 31 | } 32 | 33 | public setDob(p_Dob : string) { 34 | this.dob = p_Dob; 35 | } 36 | 37 | public getDob() : string { 38 | return this.dob; 39 | } 40 | 41 | public setGender(p_Gender : number) { 42 | this.gender = p_Gender; 43 | } 44 | 45 | public getGender() : number { 46 | return this.gender; 47 | } 48 | 49 | public setEmail(p_Email : string) { 50 | this.email = p_Email; 51 | } 52 | 53 | public getEmail() : string { 54 | return this.email; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/response-data.spec.ts: -------------------------------------------------------------------------------- 1 | import { ResponseData } from './response-data'; 2 | 3 | describe('ResponseData', () => { 4 | it('should create an instance', () => { 5 | expect(new ResponseData()).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/response-data.ts: -------------------------------------------------------------------------------- 1 | export class ResponseData { 2 | responseCode : string; 3 | responseMsg : string; 4 | } 5 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/response-error.spec.ts: -------------------------------------------------------------------------------- 1 | import { ResponseError } from './response-error'; 2 | 3 | describe('ResponseError', () => { 4 | it('should create an instance', () => { 5 | expect(new ResponseError()).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/dto/response-error.ts: -------------------------------------------------------------------------------- 1 | export class ResponseError { 2 | timestamp : Date; 3 | status : number; 4 | exception : string; 5 | message : string; 6 | path : string; 7 | error : string; 8 | } 9 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/login-form/login-form.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/web-angular-registration/src/app/login-form/login-form.component.css -------------------------------------------------------------------------------- /web-angular-registration/src/app/login-form/login-form.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 16 |
17 |
-------------------------------------------------------------------------------- /web-angular-registration/src/app/login-form/login-form.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing' 3 | import { HttpClient } from '@angular/common/http'; 4 | import { LoginFormComponent } from './login-form.component'; 5 | import { ReactiveFormsModule } from '@angular/forms'; 6 | import { RouterTestingModule } from '@angular/router/testing'; 7 | 8 | describe('LoginFormComponent', () => { 9 | let component: LoginFormComponent; 10 | let fixture: ComponentFixture; 11 | 12 | let httpClient : HttpClient; 13 | let httpTestingController : HttpTestingController; 14 | 15 | 16 | beforeEach(async(() => { 17 | TestBed.configureTestingModule({ 18 | imports : [ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule], 19 | declarations: [ LoginFormComponent ] 20 | }) 21 | .compileComponents(); 22 | })); 23 | 24 | beforeEach(() => { 25 | fixture = TestBed.createComponent(LoginFormComponent); 26 | component = fixture.componentInstance; 27 | fixture.detectChanges(); 28 | 29 | httpClient = TestBed.get(HttpClient); 30 | httpTestingController = TestBed.get(HttpTestingController); 31 | }); 32 | 33 | it('should create', () => { 34 | expect(component).toBeTruthy(); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/login-form/login-form.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { FormGroup, FormControl, Validators } from '@angular/forms'; 3 | import { RequestLogin } from '../dto/request-login'; 4 | import { LoginClientService } from '../client/login-client.service'; 5 | import { ResponseData } from '../dto/response-data'; 6 | import { Router } from '@angular/router'; 7 | 8 | @Component({ 9 | selector: 'app-login-form', 10 | templateUrl: './login-form.component.html', 11 | styleUrls: ['./login-form.component.css'] 12 | }) 13 | export class LoginFormComponent implements OnInit { 14 | 15 | loginForm : FormGroup; 16 | private submitted = false; 17 | private loginData : RequestLogin; 18 | 19 | constructor( 20 | public loginClient : LoginClientService, 21 | public router: Router 22 | ) { } 23 | 24 | ngOnInit() { 25 | this.loginForm = new FormGroup({ 26 | userName : new FormControl('', [Validators.required, Validators.email]), 27 | password : new FormControl('', Validators.required), 28 | }) 29 | } 30 | 31 | login() { 32 | this.submitted = true; 33 | if (this.loginForm.invalid) { 34 | return; 35 | }else { 36 | this.loginData = new RequestLogin(); 37 | this.loginData.setUserName(this.loginForm.get('userName').value) 38 | this.loginData.setPassword(this.loginForm.get('password').value) 39 | 40 | this.loginClient.login(this.loginData).subscribe((data: ResponseData) => { 41 | console.log("RESPONSE DATA "+JSON.stringify(data)) 42 | if (data.responseCode == '200') { 43 | localStorage.setItem("isLoggedIn", "true"); 44 | localStorage.setItem("userName", this.loginData.getUserName()); 45 | this.router.navigate(["/dashboard"]); 46 | } 47 | window.alert(data.responseMsg); 48 | }), error => { 49 | console.log("An Error Occured "+error); 50 | }; 51 | } 52 | } 53 | 54 | clearPass(){ 55 | this.loginForm.get('password').setValue(''); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/registration-form/registration-form.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/web-angular-registration/src/app/registration-form/registration-form.component.css -------------------------------------------------------------------------------- /web-angular-registration/src/app/registration-form/registration-form.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Registration

5 |
6 | 7 |
8 |
9 |
Mobile Number is required
10 |
Please Enter Valid Indonesian 11 | Phone Number
12 |
13 |
14 |
First Name is required
15 |
16 |
17 |
Last Name is required
18 |
19 |
20 |
Email is required
21 |
Please Enter Valid Email Format
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 | 39 | 40 | 48 | 56 | 64 | 65 |
41 |
42 | 46 |
47 |
49 |
50 | 54 |
55 |
57 |
58 | 62 |
63 |
66 | 69 | 72 |
73 | 74 |
75 | 77 |
78 |
79 |
80 | 81 |
82 |
83 |
84 |
85 |
-------------------------------------------------------------------------------- /web-angular-registration/src/app/registration-form/registration-form.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing'; 2 | import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing' 3 | import { HttpClient } from '@angular/common/http'; 4 | import { RegistrationFormComponent } from './registration-form.component'; 5 | import { ReactiveFormsModule } from '@angular/forms'; 6 | import { LoginFormComponent } from '../login-form/login-form.component'; 7 | 8 | describe('RegistrationFormComponent', () => { 9 | let component: RegistrationFormComponent; 10 | let fixture: ComponentFixture; 11 | 12 | let httpClient : HttpClient; 13 | let httpTestingController : HttpTestingController; 14 | 15 | beforeEach(async(() => { 16 | TestBed.configureTestingModule({ 17 | imports : [ReactiveFormsModule, HttpClientTestingModule], 18 | declarations: [ RegistrationFormComponent, LoginFormComponent ] 19 | }) 20 | .compileComponents(); 21 | })); 22 | 23 | beforeEach(() => { 24 | fixture = TestBed.createComponent(RegistrationFormComponent); 25 | component = fixture.componentInstance; 26 | fixture.detectChanges(); 27 | 28 | httpClient = TestBed.get(HttpClient); 29 | httpTestingController = TestBed.get(HttpTestingController); 30 | }); 31 | 32 | it('should create', () => { 33 | expect(component).toBeTruthy(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/registration-form/registration-form.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | import { FormGroup, FormControl, Validators } from '@angular/forms'; 3 | import { RegistrationClientService } from '../client/registration-client.service'; 4 | import { RequestRegistration } from '../dto/request-registration'; 5 | import { ResponseData } from '../dto/response-data'; 6 | 7 | @Component({ 8 | selector: 'app-registration-form', 9 | templateUrl: './registration-form.component.html', 10 | styleUrls: ['./registration-form.component.css'] 11 | }) 12 | export class RegistrationFormComponent implements OnInit { 13 | 14 | visible = false; 15 | day = []; 16 | month=[]; 17 | year=[]; 18 | buttonRegister= true; 19 | registrationForm: FormGroup; 20 | submitted = false; 21 | 22 | private registrationData : RequestRegistration; 23 | 24 | constructor( 25 | public registrationClient : RegistrationClientService 26 | ) { 27 | } 28 | 29 | 30 | dayMonthContent(){ 31 | for(let a=0;a<31;a++){ 32 | this.day.push(a+1); 33 | if(a<12){ 34 | this.month.push(a+1); 35 | } 36 | } 37 | } 38 | 39 | yearContent(){ 40 | for(let a=2019;a>=1990;a--){ 41 | this.year.push(a); 42 | } 43 | } 44 | 45 | enableForm(enable : boolean){ 46 | if (enable) { 47 | this.registrationForm.get('mobileNumber').enable(); 48 | this.registrationForm.get('firstName').enable(); 49 | this.registrationForm.get('lastName').enable(); 50 | this.registrationForm.get('email').enable(); 51 | this.registrationForm.get('day').enable(); 52 | this.registrationForm.get('month').enable(); 53 | this.registrationForm.get('year').enable(); 54 | this.registrationForm.get('gender').enable(); 55 | this.buttonRegister = true; 56 | }else { 57 | this.registrationForm.get('mobileNumber').disable(); 58 | this.registrationForm.get('firstName').disable(); 59 | this.registrationForm.get('lastName').disable(); 60 | this.registrationForm.get('email').disable(); 61 | this.registrationForm.get('day').disable(); 62 | this.registrationForm.get('month').disable(); 63 | this.registrationForm.get('year').disable(); 64 | this.registrationForm.get('gender').disable(); 65 | this.buttonRegister = false; 66 | } 67 | } 68 | 69 | register(){ 70 | this.submitted = true; 71 | if (this.registrationForm.invalid) { 72 | return; 73 | }else { 74 | this.registrationData = new RequestRegistration(); 75 | this.registrationData.setMobileNumber(this.registrationForm.get('mobileNumber').value); 76 | this.registrationData.setFirstName(this.registrationForm.get('firstName').value); 77 | this.registrationData.setLastName(this.registrationForm.get('lastName').value); 78 | this.registrationData.setDob( 79 | this.registrationForm.get('day').value + '-' + 80 | this.registrationForm.get('month').value + '-' + 81 | this.registrationForm.get('year').value 82 | ); 83 | this.registrationData.setGender(this.registrationForm.get('gender').value); 84 | this.registrationData.setEmail(this.registrationForm.get('email').value); 85 | 86 | this.registrationClient.register(this.registrationData).subscribe((data: ResponseData) => { 87 | console.log("RESPONSE DATA "+JSON.stringify(data)) 88 | if (data.responseCode=='200') { 89 | window.alert(data.responseMsg); 90 | this.visible = true; 91 | this.enableForm(false); 92 | }else { 93 | this.enableForm(true); 94 | } 95 | }), error => { 96 | console.log("An Error Occured "+error); 97 | }; 98 | } 99 | } 100 | 101 | ngOnInit() { 102 | this.registrationForm = new FormGroup({ 103 | mobileNumber : new FormControl('',[Validators.required, Validators.pattern('^08[0-9]{9,}$')]), 104 | firstName: new FormControl('', [Validators.required]), 105 | lastName: new FormControl('', [Validators.required]), 106 | email:new FormControl('', [Validators.required, Validators.email]), 107 | day: new FormControl('day'), 108 | month: new FormControl('month'), 109 | year: new FormControl('year'), 110 | gender: new FormControl('1') 111 | }) 112 | 113 | this.dayMonthContent(); 114 | this.yearContent(); 115 | } 116 | 117 | setSubmitted(submitted : boolean) { 118 | this.submitted = submitted; 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/security/auth-guard.spec.ts: -------------------------------------------------------------------------------- 1 | import { AuthGuard } from './auth-guard'; 2 | 3 | describe('AuthGuard', () => { 4 | it('should create an instance', () => { 5 | expect(new AuthGuard(null)).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /web-angular-registration/src/app/security/auth-guard.ts: -------------------------------------------------------------------------------- 1 | import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Router } from '@angular/router'; 2 | import { Injectable } from '@angular/core'; 3 | import { Observable } from 'rxjs'; 4 | import { LoginClientService } from '../client/login-client.service'; 5 | 6 | @Injectable({providedIn: 'root'}) 7 | export class AuthGuard implements CanActivate{ 8 | 9 | constructor(private router: Router) { } 10 | 11 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { 12 | if (localStorage.getItem("isLoggedIn") == 'true') { 13 | return true; 14 | }else { 15 | this.router.navigate(["/login"]); 16 | return false; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /web-angular-registration/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/web-angular-registration/src/assets/.gitkeep -------------------------------------------------------------------------------- /web-angular-registration/src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # 5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed 6 | 7 | > 0.5% 8 | last 2 versions 9 | Firefox ESR 10 | not dead 11 | not IE 9-11 -------------------------------------------------------------------------------- /web-angular-registration/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /web-angular-registration/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /web-angular-registration/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wissensalt/springboot-angular-registration/ffef4dabbd104a0319f6f7e5ff2fd49228dd3b36/web-angular-registration/src/favicon.ico -------------------------------------------------------------------------------- /web-angular-registration/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebAngularRegistration 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /web-angular-registration/src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage/web-angular-registration'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /web-angular-registration/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /web-angular-registration/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags.ts'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /web-angular-registration/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | .footer { 3 | position: fixed; 4 | left: 0; 5 | bottom: 0; 6 | width: 100%; 7 | background-color: red; 8 | color: white; 9 | text-align: center; 10 | } -------------------------------------------------------------------------------- /web-angular-registration/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /web-angular-registration/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "exclude": [ 8 | "test.ts", 9 | "**/*.spec.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /web-angular-registration/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts", 12 | "polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /web-angular-registration/src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /web-angular-registration/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "module": "es2015", 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "importHelpers": true, 13 | "target": "es5", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /web-angular-registration/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rulesDirectory": [ 4 | "codelyzer" 5 | ], 6 | "rules": { 7 | "array-type": false, 8 | "arrow-parens": false, 9 | "deprecation": { 10 | "severity": "warn" 11 | }, 12 | "import-blacklist": [ 13 | true, 14 | "rxjs/Rx" 15 | ], 16 | "interface-name": false, 17 | "max-classes-per-file": false, 18 | "max-line-length": [ 19 | true, 20 | 140 21 | ], 22 | "member-access": false, 23 | "member-ordering": [ 24 | true, 25 | { 26 | "order": [ 27 | "static-field", 28 | "instance-field", 29 | "static-method", 30 | "instance-method" 31 | ] 32 | } 33 | ], 34 | "no-consecutive-blank-lines": false, 35 | "no-console": [ 36 | true, 37 | "debug", 38 | "info", 39 | "time", 40 | "timeEnd", 41 | "trace" 42 | ], 43 | "no-empty": false, 44 | "no-inferrable-types": [ 45 | true, 46 | "ignore-params" 47 | ], 48 | "no-non-null-assertion": true, 49 | "no-redundant-jsdoc": true, 50 | "no-switch-case-fall-through": true, 51 | "no-use-before-declare": true, 52 | "no-var-requires": false, 53 | "object-literal-key-quotes": [ 54 | true, 55 | "as-needed" 56 | ], 57 | "object-literal-sort-keys": false, 58 | "ordered-imports": false, 59 | "quotemark": [ 60 | true, 61 | "single" 62 | ], 63 | "trailing-comma": false, 64 | "no-output-on-prefix": true, 65 | "use-input-property-decorator": true, 66 | "use-output-property-decorator": true, 67 | "use-host-property-decorator": true, 68 | "no-input-rename": true, 69 | "no-output-rename": true, 70 | "use-life-cycle-interface": true, 71 | "use-pipe-transform-interface": true, 72 | "component-class-suffix": true, 73 | "directive-class-suffix": true 74 | } 75 | } 76 | --------------------------------------------------------------------------------