QPAT commited on
Commit
d9026b5
·
1 Parent(s): 75ee1b5

Fix folder structure of frontend

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. pom.xml +7 -2
  2. src/main/java/com/attendenceSystem/constant/Routes.java +13 -0
  3. src/main/java/com/attendenceSystem/exception/GlobalExceptionHandler.java +41 -0
  4. src/main/java/com/attendenceSystem/exception/custom/BadRequestException.java +7 -0
  5. src/main/java/com/attendenceSystem/exception/custom/ResourceNotFoundException.java +7 -0
  6. src/main/java/com/attendenceSystem/module/log/dto/request/AuditLogRequest.java +14 -0
  7. src/main/java/com/attendenceSystem/module/log/dto/response/AuditLogResponse.java +18 -0
  8. src/main/java/com/attendenceSystem/module/log/entity/AuditLog.java +58 -0
  9. src/main/java/com/attendenceSystem/module/log/entity/converter/LogActionConverter.java +21 -0
  10. src/main/java/com/attendenceSystem/module/log/entity/converter/LogEntityTypeConverter.java +21 -0
  11. src/main/java/com/attendenceSystem/module/log/entity/enums/LogAction.java +31 -0
  12. src/main/java/com/attendenceSystem/module/log/entity/enums/LogEntityType.java +20 -0
  13. src/main/java/com/attendenceSystem/module/log/mapper/request/AuditLogRequestMapping.java +5 -0
  14. src/main/java/com/attendenceSystem/module/log/mapper/response/AuditLogResponseMapper.java +20 -0
  15. src/main/java/com/attendenceSystem/module/log/repository/AuditLogRepository.java +13 -0
  16. src/main/java/com/attendenceSystem/module/log/service/AuditLogService.java +13 -0
  17. src/main/java/com/attendenceSystem/module/log/service/impl/AuditLogServiceImpl.java +40 -0
  18. src/main/java/com/attendenceSystem/module/user/controller/AuthController.java +25 -0
  19. src/main/java/com/attendenceSystem/module/user/dto/request/LoginRequest.java +13 -0
  20. src/main/java/com/attendenceSystem/module/user/dto/request/RegisterRequest.java +37 -0
  21. src/main/java/com/attendenceSystem/module/user/dto/response/UserResponse.java +14 -0
  22. src/main/java/com/attendenceSystem/{user → module/user}/entity/User.java +24 -14
  23. src/main/java/com/attendenceSystem/module/user/entity/converter/RoleConverter.java +20 -0
  24. src/main/java/com/attendenceSystem/{user → module/user}/entity/enums/Role.java +1 -1
  25. src/main/java/com/attendenceSystem/module/user/mapper/request/RegisterRequestMapper.java +19 -0
  26. src/main/java/com/attendenceSystem/{user → module/user}/mapper/response/UserResponseMapper.java +7 -17
  27. src/main/java/com/attendenceSystem/module/user/repository/UserRepository.java +24 -0
  28. src/main/java/com/attendenceSystem/module/user/service/AuthService.java +12 -0
  29. src/main/java/com/attendenceSystem/module/user/service/UserService.java +12 -0
  30. src/main/java/com/attendenceSystem/module/user/service/impl/AuthServiceImpl.java +72 -0
  31. src/main/java/com/attendenceSystem/module/user/service/impl/UserServiceImpl.java +43 -0
  32. src/main/java/com/attendenceSystem/security/ActiveUserFilter.java +67 -0
  33. src/main/java/com/attendenceSystem/security/ForceChangePasswordInterceptor.java +41 -0
  34. src/main/java/com/attendenceSystem/security/SecurityConfig.java +60 -0
  35. src/main/java/com/attendenceSystem/user/dto/request/LoginRequest.java +0 -20
  36. src/main/java/com/attendenceSystem/user/dto/request/RegisterRequest.java +0 -38
  37. src/main/java/com/attendenceSystem/user/dto/response/UserResponse.java +0 -17
  38. src/main/java/com/attendenceSystem/user/entity/converter/RoleConverter.java +0 -15
  39. src/main/java/com/attendenceSystem/user/mapper/request/LoginRequestMapper.java +0 -5
  40. src/main/java/com/attendenceSystem/user/mapper/request/RegisterRequestMapper.java +0 -5
  41. src/main/java/com/attendenceSystem/user/repository/UserRepository.java +0 -11
  42. src/main/java/com/attendenceSystem/user/service/UserService.java +0 -15
  43. src/main/java/com/attendenceSystem/user/service/impl/UserServiceImpl.java +0 -65
  44. src/main/java/com/attendenceSystem/validator/PasswordMatchValidator.java +5 -5
  45. src/main/resources/application.properties +19 -8
  46. src/main/resources/templates/cms/{auths → auth}/login.html +0 -0
  47. src/main/resources/templates/cms/{auths → auth}/register.html +0 -0
  48. src/main/resources/templates/cms/{auths → auth}/verify-otp.html +0 -0
  49. src/main/resources/templates/cms/{documents → document}/document-create.html +0 -0
  50. src/main/resources/templates/cms/{documents → document}/document-detail.html +0 -0
pom.xml CHANGED
@@ -1,6 +1,7 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 
4
  <modelVersion>4.0.0</modelVersion>
5
  <parent>
6
  <groupId>org.springframework.boot</groupId>
@@ -34,6 +35,10 @@
34
  <groupId>org.springframework.boot</groupId>
35
  <artifactId>spring-boot-starter-data-jpa</artifactId>
36
  </dependency> -->
 
 
 
 
37
  <dependency>
38
  <groupId>org.springframework.boot</groupId>
39
  <artifactId>spring-boot-starter-validation</artifactId>
 
1
  <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5
  <modelVersion>4.0.0</modelVersion>
6
  <parent>
7
  <groupId>org.springframework.boot</groupId>
 
35
  <groupId>org.springframework.boot</groupId>
36
  <artifactId>spring-boot-starter-data-jpa</artifactId>
37
  </dependency> -->
38
+ <dependency>
39
+ <groupId>org.mariadb.jdbc</groupId>
40
+ <artifactId>mariadb-java-client</artifactId>
41
+ </dependency>
42
  <dependency>
43
  <groupId>org.springframework.boot</groupId>
44
  <artifactId>spring-boot-starter-validation</artifactId>
src/main/java/com/attendenceSystem/constant/Routes.java ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.constant;
2
+
3
+ import lombok.AccessLevel;
4
+ import lombok.NoArgsConstructor;
5
+
6
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
7
+ public final class Routes {
8
+ public static final class Auth {
9
+ public static final String ROOT = "/auth";
10
+ public static final String LOGIN = "/login";
11
+ public static final String REGISTER = "/register";
12
+ }
13
+ }
src/main/java/com/attendenceSystem/exception/GlobalExceptionHandler.java ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // package com.attendenceSystem.exception;
2
+
3
+ // import org.springframework.http.HttpStatus;
4
+ // import org.springframework.security.access.AccessDeniedException;
5
+ // import org.springframework.web.bind.annotation.ControllerAdvice;
6
+ // import org.springframework.web.bind.annotation.ExceptionHandler;
7
+ // import org.springframework.web.bind.annotation.ResponseStatus;
8
+
9
+ // import com.attendenceSystem.exception.custom.BadRequestException;
10
+ // import com.attendenceSystem.exception.custom.ResourceNotFoundException;
11
+
12
+ // @ControllerAdvice
13
+ // public class GlobalExceptionHandler {
14
+ // @ExceptionHandler(ResourceNotFoundException.class)
15
+ // @ResponseStatus(HttpStatus.NOT_FOUND)
16
+ // public String notFound() {
17
+ // return "error/404";
18
+ // }
19
+
20
+ // @ExceptionHandler(AccessDeniedException.class)
21
+ // @ResponseStatus(HttpStatus.FORBIDDEN)
22
+ // public String forbidden() {
23
+ // return "error/403";
24
+ // }
25
+
26
+ // @ExceptionHandler(BadRequestException.class)
27
+ // @ResponseStatus(HttpStatus.BAD_REQUEST)
28
+ // public String badRequest() {
29
+ // return "error/400";
30
+ // }
31
+
32
+ // @ExceptionHandler(Exception.class)
33
+ // @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
34
+ // public String internalServerError(Exception ex) {
35
+
36
+ // ex.printStackTrace();
37
+
38
+ // return "error/500";
39
+ // }
40
+
41
+ // }
src/main/java/com/attendenceSystem/exception/custom/BadRequestException.java ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.exception.custom;
2
+
3
+ public class BadRequestException extends RuntimeException{
4
+ public BadRequestException(String message){
5
+ super(message);
6
+ }
7
+ }
src/main/java/com/attendenceSystem/exception/custom/ResourceNotFoundException.java ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.exception.custom;
2
+
3
+ public class ResourceNotFoundException extends RuntimeException{
4
+ public ResourceNotFoundException(String message){
5
+ super(message);
6
+ }
7
+ }
src/main/java/com/attendenceSystem/module/log/dto/request/AuditLogRequest.java ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.dto.request;
2
+
3
+ import com.attendenceSystem.module.log.entity.enums.LogAction;
4
+ import com.attendenceSystem.module.log.entity.enums.LogEntityType;
5
+ import com.attendenceSystem.module.user.entity.User;
6
+
7
+ public record AuditLogRequest(
8
+ User user,
9
+ LogEntityType logEntityType,
10
+ Long entityId,
11
+ LogAction action,
12
+ String description) {
13
+
14
+ }
src/main/java/com/attendenceSystem/module/log/dto/response/AuditLogResponse.java ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.dto.response;
2
+
3
+ import com.attendenceSystem.module.log.entity.enums.LogAction;
4
+ import com.attendenceSystem.module.log.entity.enums.LogEntityType;
5
+
6
+ import lombok.Builder;
7
+
8
+ @Builder
9
+ public record AuditLogResponse(
10
+ Long id,
11
+ Long userId,
12
+ String username,
13
+ LogEntityType entityType,
14
+ Long entityId,
15
+ LogAction action,
16
+ String description,
17
+ String createdAt) {
18
+ }
src/main/java/com/attendenceSystem/module/log/entity/AuditLog.java ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.entity;
2
+
3
+ import java.time.Instant;
4
+
5
+ import org.hibernate.annotations.CreationTimestamp;
6
+
7
+ import com.attendenceSystem.module.log.entity.enums.LogAction;
8
+ import com.attendenceSystem.module.log.entity.enums.LogEntityType;
9
+ import com.attendenceSystem.module.user.entity.User;
10
+
11
+ import jakarta.persistence.Column;
12
+ import jakarta.persistence.Entity;
13
+ import jakarta.persistence.FetchType;
14
+ import jakarta.persistence.GeneratedValue;
15
+ import jakarta.persistence.GenerationType;
16
+ import jakarta.persistence.Id;
17
+ import jakarta.persistence.JoinColumn;
18
+ import jakarta.persistence.ManyToOne;
19
+ import jakarta.persistence.Table;
20
+ import lombok.AllArgsConstructor;
21
+ import lombok.Builder;
22
+ import lombok.Getter;
23
+ import lombok.NoArgsConstructor;
24
+ import lombok.Setter;
25
+
26
+ @Entity
27
+ @Table(name = "audit_logs")
28
+ @Getter
29
+ @Setter
30
+ @NoArgsConstructor
31
+ @AllArgsConstructor
32
+ @Builder
33
+ public class AuditLog {
34
+
35
+ @Id
36
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
37
+ private Long id;
38
+
39
+ @Column(name = "entity_id")
40
+ private Long entityId;
41
+
42
+ @Column(name = "entity_type", nullable = false)
43
+ private LogEntityType entityType;
44
+
45
+ @Column(name = "action", nullable = false)
46
+ private LogAction action;
47
+
48
+ @Column(name = "description", columnDefinition = "LONGTEXT")
49
+ private String description;
50
+
51
+ @CreationTimestamp
52
+ @Column(name = "created_at", updatable = false)
53
+ private Instant createdAt;
54
+
55
+ @ManyToOne(fetch = FetchType.LAZY)
56
+ @JoinColumn(name = "user_id", updatable = false)
57
+ private User user;
58
+ }
src/main/java/com/attendenceSystem/module/log/entity/converter/LogActionConverter.java ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.entity.converter;
2
+
3
+ import com.attendenceSystem.module.log.entity.enums.LogAction;
4
+
5
+ import jakarta.persistence.AttributeConverter;
6
+ import jakarta.persistence.Converter;
7
+
8
+ @Converter(autoApply = true)
9
+ public class LogActionConverter implements AttributeConverter<LogAction, Long> {
10
+
11
+ @Override
12
+ public Long convertToDatabaseColumn(LogAction attribute) {
13
+ return attribute == null ? null : attribute.getCode();
14
+ }
15
+
16
+ @Override
17
+ public LogAction convertToEntityAttribute(Long dbData) {
18
+ return dbData == null ? null : LogAction.fromValue(dbData);
19
+ }
20
+
21
+ }
src/main/java/com/attendenceSystem/module/log/entity/converter/LogEntityTypeConverter.java ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.entity.converter;
2
+
3
+ import com.attendenceSystem.module.log.entity.enums.LogEntityType;
4
+
5
+ import jakarta.persistence.AttributeConverter;
6
+ import jakarta.persistence.Converter;
7
+
8
+ @Converter(autoApply = true)
9
+ public class LogEntityTypeConverter implements AttributeConverter<LogEntityType, Long>{
10
+
11
+ @Override
12
+ public Long convertToDatabaseColumn(LogEntityType attribute) {
13
+ return attribute == null ? null : attribute.getCode();
14
+ }
15
+
16
+ @Override
17
+ public LogEntityType convertToEntityAttribute(Long dbData) {
18
+ return dbData == null ? null : LogEntityType.fromValue(dbData);
19
+ }
20
+
21
+ }
src/main/java/com/attendenceSystem/module/log/entity/enums/LogAction.java ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.entity.enums;
2
+
3
+ import lombok.Getter;
4
+ import lombok.RequiredArgsConstructor;
5
+
6
+ @Getter
7
+ @RequiredArgsConstructor
8
+ public enum LogAction {
9
+ CREATE(1),
10
+ UPDATE(2),
11
+ DELETE(3),
12
+ RESTORE(4),
13
+ APPROVE(5),
14
+ LOCK(6),
15
+ UNLOCK(7),
16
+ CHANGE_PASSWORD(8),
17
+ LOGIN(9),
18
+ LOGOUT(10),
19
+ PROCESS(11);
20
+
21
+ private final long code;
22
+
23
+ public static LogAction fromValue(long code) {
24
+ for (LogAction action : LogAction.values()) {
25
+ if (action.code == code) {
26
+ return action;
27
+ }
28
+ }
29
+ throw new IllegalArgumentException("Không tìm thấy loại hành động: " + code);
30
+ }
31
+ }
src/main/java/com/attendenceSystem/module/log/entity/enums/LogEntityType.java ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.entity.enums;
2
+
3
+ import lombok.Getter;
4
+ import lombok.RequiredArgsConstructor;
5
+
6
+ @Getter
7
+ @RequiredArgsConstructor
8
+ public enum LogEntityType {
9
+ USER(1);
10
+
11
+ private final long code;
12
+ public static LogEntityType fromValue(long code) {
13
+ for (LogEntityType action : LogEntityType.values()) {
14
+ if (action.code == code) {
15
+ return action;
16
+ }
17
+ }
18
+ throw new IllegalArgumentException("Không tìm thấy loại Entity: " + code);
19
+ }
20
+ }
src/main/java/com/attendenceSystem/module/log/mapper/request/AuditLogRequestMapping.java ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.mapper.request;
2
+
3
+ public class AuditLogRequestMapping {
4
+
5
+ }
src/main/java/com/attendenceSystem/module/log/mapper/response/AuditLogResponseMapper.java ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.mapper.response;
2
+
3
+ import com.attendenceSystem.module.log.dto.response.AuditLogResponse;
4
+ import com.attendenceSystem.module.log.entity.AuditLog;
5
+ import com.attendenceSystem.util.TimeUtil;
6
+
7
+ public class AuditLogResponseMapper {
8
+ public static AuditLogResponse fromEntity(AuditLog auditLog) {
9
+ return AuditLogResponse.builder()
10
+ .id(auditLog.getId())
11
+ .userId(auditLog.getUser().getId())
12
+ .username(auditLog.getUser().getUsername())
13
+ .entityType(auditLog.getEntityType())
14
+ .entityId(auditLog.getEntityId())
15
+ .action(auditLog.getAction())
16
+ .description(auditLog.getDescription())
17
+ .createdAt(TimeUtil.formatInstant(auditLog.getCreatedAt(), null))
18
+ .build();
19
+ }
20
+ }
src/main/java/com/attendenceSystem/module/log/repository/AuditLogRepository.java ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.repository;
2
+
3
+ import org.springframework.data.domain.Page;
4
+ import org.springframework.data.domain.Pageable;
5
+ import org.springframework.data.jpa.repository.JpaRepository;
6
+ import org.springframework.stereotype.Repository;
7
+
8
+ import com.attendenceSystem.module.log.entity.AuditLog;
9
+
10
+ @Repository
11
+ public interface AuditLogRepository extends JpaRepository<AuditLog, Long> {
12
+ Page<AuditLog> findAllByOrderByCreatedAtDesc(Pageable pageable);
13
+ }
src/main/java/com/attendenceSystem/module/log/service/AuditLogService.java ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.service;
2
+
3
+ import org.springframework.data.domain.Page;
4
+ import org.springframework.data.domain.Pageable;
5
+
6
+ import com.attendenceSystem.module.log.dto.request.AuditLogRequest;
7
+ import com.attendenceSystem.module.log.dto.response.AuditLogResponse;
8
+
9
+ public interface AuditLogService {
10
+ void log(AuditLogRequest request);
11
+
12
+ Page<AuditLogResponse> getLogs(Pageable pageable);
13
+ }
src/main/java/com/attendenceSystem/module/log/service/impl/AuditLogServiceImpl.java ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.log.service.impl;
2
+
3
+ import org.springframework.data.domain.Page;
4
+ import org.springframework.data.domain.Pageable;
5
+ import org.springframework.transaction.annotation.Transactional;
6
+
7
+ import com.attendenceSystem.module.log.dto.request.AuditLogRequest;
8
+ import com.attendenceSystem.module.log.dto.response.AuditLogResponse;
9
+ import com.attendenceSystem.module.log.entity.AuditLog;
10
+ import com.attendenceSystem.module.log.mapper.response.AuditLogResponseMapper;
11
+ import com.attendenceSystem.module.log.repository.AuditLogRepository;
12
+ import com.attendenceSystem.module.log.service.AuditLogService;
13
+
14
+ import lombok.RequiredArgsConstructor;
15
+
16
+ @RequiredArgsConstructor
17
+ public class AuditLogServiceImpl implements AuditLogService {
18
+ private final AuditLogRepository auditLogRepository;
19
+
20
+ @Transactional
21
+ @Override
22
+ public void log(AuditLogRequest request) {
23
+ AuditLog auditLog = AuditLog.builder()
24
+ .user(request.user())
25
+ .entityType(request.logEntityType())
26
+ .entityId(request.entityId())
27
+ .action(request.action())
28
+ .description(request.description())
29
+ .build();
30
+ auditLogRepository.save(auditLog);
31
+ }
32
+
33
+ @Override
34
+ public Page<AuditLogResponse> getLogs(Pageable pageable) {
35
+ return auditLogRepository
36
+ .findAll(pageable)
37
+ .map(AuditLogResponseMapper::fromEntity);
38
+ }
39
+
40
+ }
src/main/java/com/attendenceSystem/module/user/controller/AuthController.java ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.controller;
2
+
3
+ import org.springframework.stereotype.Controller;
4
+ import org.springframework.web.bind.annotation.RequestMapping;
5
+
6
+ import com.attendenceSystem.constant.Routes;
7
+ import com.attendenceSystem.module.user.service.AuthService;
8
+
9
+ import lombok.RequiredArgsConstructor;
10
+ import org.springframework.web.bind.annotation.GetMapping;
11
+
12
+
13
+
14
+ @Controller
15
+ @RequestMapping(Routes.Auth.ROOT)
16
+ @RequiredArgsConstructor
17
+ public class AuthController {
18
+ private final AuthService authService;
19
+
20
+ @GetMapping(Routes.Auth.REGISTER)
21
+ public String toRegisterPage() {
22
+ return "auth/register";
23
+ }
24
+
25
+ }
src/main/java/com/attendenceSystem/module/user/dto/request/LoginRequest.java ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.dto.request;
2
+
3
+ import jakarta.validation.constraints.NotBlank;
4
+ import jakarta.validation.constraints.Size;
5
+
6
+ public record LoginRequest(
7
+ @NotBlank(message = "Tên đăng nhập hoặc email không được để trống")
8
+ String login,
9
+
10
+ @NotBlank(message = "Mật khẩu không được để trống")
11
+ @Size(min = 8, message = "Mật khẩu phải chứa ít nhất 8 kí tự")
12
+ String password) {
13
+ }
src/main/java/com/attendenceSystem/module/user/dto/request/RegisterRequest.java ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.dto.request;
2
+
3
+ import com.attendenceSystem.annotation.PasswordMatch;
4
+ import com.fasterxml.jackson.annotation.JsonProperty;
5
+
6
+ import jakarta.validation.constraints.Email;
7
+ import jakarta.validation.constraints.NotBlank;
8
+ import jakarta.validation.constraints.Pattern;
9
+ import jakarta.validation.constraints.Size;
10
+
11
+ @PasswordMatch
12
+ public record RegisterRequest(
13
+
14
+ @NotBlank(message = "Tên đăng nhập không được để trống")
15
+ @Size(min = 3, max = 30, message = "Tên đăng nhập phải có độ dài từ 3 đến 30 ký tự")
16
+ @Pattern(regexp = "^[a-zA-Z0-9]+$", message = "Tên đăng nhập không được chứa ký tự đặc biệt")
17
+ String username,
18
+
19
+ @NotBlank(message = "Email không được để trống")
20
+ @Size(max = 255, message = "Email không được vượt quá 255 ký tự")
21
+ @Email(message = "Email không đúng định dạng")
22
+ String email,
23
+
24
+ @NotBlank(message = "Mật khẩu không được để trống")
25
+ @Size(min = 8, message = "Mật khẩu phải chứa ít nhất 8 kí tự")
26
+ String password,
27
+
28
+ @NotBlank(message = "Mật khẩu xác nhận không được để trống")
29
+ @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
30
+ String rePassword,
31
+
32
+ @NotBlank(message = "Họ tên không được để trống")
33
+ @Size(max = 255, message = "Họ tên không được vượt quá 255 ký tự")
34
+ String fullName
35
+
36
+ ) {
37
+ }
src/main/java/com/attendenceSystem/module/user/dto/response/UserResponse.java ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.dto.response;
2
+
3
+ import lombok.Builder;
4
+
5
+ @Builder
6
+ public record UserResponse(
7
+ Long id,
8
+ String username,
9
+ String email,
10
+ String fullName,
11
+ Boolean isActive,
12
+ String role) {
13
+
14
+ }
src/main/java/com/attendenceSystem/{user → module/user}/entity/User.java RENAMED
@@ -1,7 +1,12 @@
1
- package com.attendenceSystem.user.entity;
2
 
3
  import java.time.Instant;
4
 
 
 
 
 
 
5
  import jakarta.persistence.Column;
6
  import jakarta.persistence.Entity;
7
  import jakarta.persistence.GeneratedValue;
@@ -26,22 +31,27 @@ public class User {
26
  @GeneratedValue(strategy = GenerationType.IDENTITY)
27
  @Column(name = "id")
28
  private Long id;
29
- @Column(name = "email")
 
 
30
  private String email;
31
- @Column(name = "password")
32
  private String password;
33
- @Column(name = "full_name")
 
 
 
 
 
34
  private String fullName;
35
- @Column(name = "avatar")
36
- private String avatar;
37
- @Column(name = "role")
38
- private String role;
39
- @Column(name = "status")
40
- private String status;
41
- @Column(name = "created_at")
42
  private Instant createdAt;
43
- @Column(name = "updated_at")
 
44
  private Instant updatedAt;
45
- @Column(name = "deleted")
46
- private Boolean deleted;
 
 
47
  }
 
1
+ package com.attendenceSystem.module.user.entity;
2
 
3
  import java.time.Instant;
4
 
5
+ import org.hibernate.annotations.CreationTimestamp;
6
+ import org.hibernate.annotations.UpdateTimestamp;
7
+
8
+ import com.attendenceSystem.module.user.entity.enums.Role;
9
+
10
  import jakarta.persistence.Column;
11
  import jakarta.persistence.Entity;
12
  import jakarta.persistence.GeneratedValue;
 
31
  @GeneratedValue(strategy = GenerationType.IDENTITY)
32
  @Column(name = "id")
33
  private Long id;
34
+ @Column(name = "username", unique = true, nullable = false, length = 30)
35
+ private String username;
36
+ @Column(name = "email", unique = true, nullable = false, length = 255)
37
  private String email;
38
+ @Column(name = "password", nullable = false, length = 255)
39
  private String password;
40
+ @Column(name = "role", nullable = false)
41
+ private Role role;
42
+ @Column(name = "is_active", nullable = false)
43
+ @Builder.Default
44
+ private boolean isActive = true;
45
+ @Column(name = "full_name", nullable = false, length = 255)
46
  private String fullName;
47
+ @CreationTimestamp
48
+ @Column(name = "created_at", nullable = false, updatable = false)
 
 
 
 
 
49
  private Instant createdAt;
50
+ @UpdateTimestamp
51
+ @Column(name = "updated_at", nullable = false)
52
  private Instant updatedAt;
53
+
54
+ @Column(name = "must_change_password", nullable = false)
55
+ @Builder.Default
56
+ private boolean mustChangePassword = false;
57
  }
src/main/java/com/attendenceSystem/module/user/entity/converter/RoleConverter.java ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.entity.converter;
2
+
3
+ import com.attendenceSystem.module.user.entity.enums.Role;
4
+
5
+ import jakarta.persistence.AttributeConverter;
6
+ import jakarta.persistence.Converter;
7
+
8
+ @Converter(autoApply = true)
9
+ public class RoleConverter implements AttributeConverter<Role, Integer> {
10
+
11
+ @Override
12
+ public Integer convertToDatabaseColumn(Role role) {
13
+ return role == null ? null : role.getValue();
14
+ }
15
+
16
+ @Override
17
+ public Role convertToEntityAttribute(Integer dbData) {
18
+ return dbData == null ? null : Role.fromValue(dbData);
19
+ }
20
+ }
src/main/java/com/attendenceSystem/{user → module/user}/entity/enums/Role.java RENAMED
@@ -1,4 +1,4 @@
1
- package com.attendenceSystem.user.entity.enums;
2
 
3
  import lombok.Getter;
4
  import lombok.RequiredArgsConstructor;
 
1
+ package com.attendenceSystem.module.user.entity.enums;
2
 
3
  import lombok.Getter;
4
  import lombok.RequiredArgsConstructor;
src/main/java/com/attendenceSystem/module/user/mapper/request/RegisterRequestMapper.java ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.mapper.request;
2
+
3
+ import com.attendenceSystem.module.user.dto.request.RegisterRequest;
4
+ import com.attendenceSystem.module.user.entity.User;
5
+
6
+ import lombok.AccessLevel;
7
+ import lombok.NoArgsConstructor;
8
+
9
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
10
+ public final class RegisterRequestMapper {
11
+ public static User toEntity(RegisterRequest request, String hashPassword) {
12
+ return User.builder()
13
+ .username(request.username())
14
+ .email(request.email())
15
+ .password(hashPassword)
16
+ .fullName(request.fullName())
17
+ .build();
18
+ }
19
+ }
src/main/java/com/attendenceSystem/{user → module/user}/mapper/response/UserResponseMapper.java RENAMED
@@ -1,12 +1,11 @@
1
- package com.attendenceSystem.user.mapper.response;
2
 
3
  import java.time.ZoneId;
4
 
5
  import org.springframework.stereotype.Component;
6
 
7
- import com.attendenceSystem.user.dto.response.UserResponse;
8
- import com.attendenceSystem.user.entity.User;
9
- import com.attendenceSystem.util.TimeUtil;
10
 
11
  import lombok.RequiredArgsConstructor;
12
 
@@ -16,23 +15,14 @@ public class UserResponseMapper {
16
 
17
  private final ZoneId applicationZoneId;
18
 
19
- public UserResponse toResponse(User user) {
20
-
21
  return UserResponse.builder()
22
  .id(user.getId())
 
23
  .email(user.getEmail())
24
  .fullName(user.getFullName())
25
- .avatar(user.getAvatar())
26
- .status(user.getStatus())
27
- .createdAt(
28
- TimeUtil.formatInstant(
29
- user.getCreatedAt(),
30
- applicationZoneId))
31
- .updatedAt(
32
- TimeUtil.formatInstant(
33
- user.getUpdatedAt(),
34
- applicationZoneId))
35
- .deleted(user.getDeleted())
36
  .build();
37
  }
38
  }
 
1
+ package com.attendenceSystem.module.user.mapper.response;
2
 
3
  import java.time.ZoneId;
4
 
5
  import org.springframework.stereotype.Component;
6
 
7
+ import com.attendenceSystem.module.user.dto.response.UserResponse;
8
+ import com.attendenceSystem.module.user.entity.User;
 
9
 
10
  import lombok.RequiredArgsConstructor;
11
 
 
15
 
16
  private final ZoneId applicationZoneId;
17
 
18
+ public UserResponse fromEntity(User user) {
 
19
  return UserResponse.builder()
20
  .id(user.getId())
21
+ .username(user.getUsername())
22
  .email(user.getEmail())
23
  .fullName(user.getFullName())
24
+ .isActive(user.isActive())
25
+ .role(user.getRole().name())
 
 
 
 
 
 
 
 
 
26
  .build();
27
  }
28
  }
src/main/java/com/attendenceSystem/module/user/repository/UserRepository.java ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.repository;
2
+
3
+ import java.util.Optional;
4
+
5
+ import org.springframework.data.domain.Page;
6
+ import org.springframework.data.domain.Pageable;
7
+ import org.springframework.data.jpa.repository.JpaRepository;
8
+ import org.springframework.stereotype.Repository;
9
+
10
+ import com.attendenceSystem.module.user.entity.User;
11
+
12
+ @Repository
13
+ public interface UserRepository extends JpaRepository<User, Long> {
14
+ Optional<User> findUserByUsername(String username);
15
+ Optional<User> findUserByEmail(String email);
16
+ boolean existsByUsername(String username);
17
+ boolean existsByEmail(String email);
18
+ Optional<User> findUserByUsernameOrEmail(String username, String email);
19
+ boolean existsByUsernameOrEmail(String username, String email);
20
+ Page<User> findAllByOrderByIdAsc(Pageable pageable);
21
+ long countByIsActiveTrue();
22
+ long countByIsActiveFalse();
23
+ Optional<User> findByUsername(String username);
24
+ }
src/main/java/com/attendenceSystem/module/user/service/AuthService.java ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.service;
2
+
3
+ import com.attendenceSystem.module.user.dto.request.LoginRequest;
4
+ import com.attendenceSystem.module.user.dto.request.RegisterRequest;
5
+ import com.attendenceSystem.module.user.dto.response.UserResponse;
6
+
7
+ public interface AuthService {
8
+ UserResponse login(LoginRequest request);
9
+
10
+ void register(RegisterRequest request);
11
+
12
+ }
src/main/java/com/attendenceSystem/module/user/service/UserService.java ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.service;
2
+
3
+ import org.springframework.data.domain.Page;
4
+ import org.springframework.data.domain.Pageable;
5
+
6
+ import com.attendenceSystem.module.user.dto.response.UserResponse;
7
+
8
+ public interface UserService {
9
+ Page<UserResponse> getAccounts(Pageable pageable);
10
+ UserResponse getById(Long id);
11
+ void deleteUser(Long id);
12
+ }
src/main/java/com/attendenceSystem/module/user/service/impl/AuthServiceImpl.java ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.service.impl;
2
+
3
+ import com.attendenceSystem.module.user.mapper.request.RegisterRequestMapper;
4
+ import com.attendenceSystem.module.user.mapper.response.UserResponseMapper;
5
+ import java.util.Optional;
6
+
7
+ import org.springframework.security.authentication.AuthenticationManager;
8
+ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
9
+ import org.springframework.security.core.Authentication;
10
+ import org.springframework.security.core.context.SecurityContext;
11
+ import org.springframework.security.core.context.SecurityContextHolder;
12
+ import org.springframework.security.crypto.password.PasswordEncoder;
13
+ import org.springframework.stereotype.Service;
14
+ import org.springframework.transaction.annotation.Transactional;
15
+
16
+ import com.attendenceSystem.module.user.dto.request.LoginRequest;
17
+ import com.attendenceSystem.module.user.dto.request.RegisterRequest;
18
+ import com.attendenceSystem.module.user.dto.response.UserResponse;
19
+ import com.attendenceSystem.module.user.entity.User;
20
+ import com.attendenceSystem.module.user.repository.UserRepository;
21
+ import com.attendenceSystem.module.user.service.AuthService;
22
+
23
+ import lombok.RequiredArgsConstructor;
24
+
25
+ @Service
26
+ @RequiredArgsConstructor
27
+ public class AuthServiceImpl implements AuthService {
28
+ private final UserResponseMapper userResponseMapper;
29
+ private final UserRepository userRepository;
30
+ private final AuthenticationManager authenticationManager;
31
+ private final PasswordEncoder passwordEncoder;
32
+
33
+ @Transactional
34
+ @Override
35
+ public void register(RegisterRequest request) {
36
+ if (existsByKeyword(request.username())) {
37
+ throw new IllegalArgumentException("Tên đăng nhập đã tồn tại!");
38
+ }
39
+ if (existsByKeyword(request.email())) {
40
+ throw new IllegalArgumentException("Email này đã được đăng ký!");
41
+ }
42
+ String hashPassword = passwordEncoder.encode(request.password());
43
+ User savedUser = RegisterRequestMapper.toEntity(request, hashPassword);
44
+ userRepository.save(savedUser);
45
+ }
46
+
47
+ @Override
48
+ public UserResponse login(LoginRequest request) {
49
+
50
+ Authentication authentication = authenticationManager.authenticate(
51
+ new UsernamePasswordAuthenticationToken(
52
+ request.login(),
53
+ request.password()));
54
+
55
+ SecurityContext context = SecurityContextHolder.createEmptyContext();
56
+ context.setAuthentication(authentication);
57
+ SecurityContextHolder.setContext(context);
58
+
59
+ User user = findUser(authentication.getName())
60
+ .orElseThrow(() -> new IllegalArgumentException(
61
+ "Tên đăng nhập hoặc mật khẩu không đúng."));
62
+ return userResponseMapper.fromEntity(user);
63
+ }
64
+
65
+ private Optional<User> findUser(String keyword) {
66
+ return userRepository.findUserByUsernameOrEmail(keyword, keyword);
67
+ }
68
+
69
+ private boolean existsByKeyword(String keyword) {
70
+ return userRepository.existsByUsernameOrEmail(keyword, keyword);
71
+ }
72
+ }
src/main/java/com/attendenceSystem/module/user/service/impl/UserServiceImpl.java ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.module.user.service.impl;
2
+
3
+ import org.springframework.data.domain.Page;
4
+ import org.springframework.data.domain.Pageable;
5
+ import org.springframework.stereotype.Service;
6
+ import org.springframework.transaction.annotation.Transactional;
7
+
8
+ import com.attendenceSystem.module.user.dto.response.UserResponse;
9
+ import com.attendenceSystem.module.user.entity.User;
10
+ import com.attendenceSystem.module.user.mapper.response.UserResponseMapper;
11
+ import com.attendenceSystem.module.user.repository.UserRepository;
12
+ import com.attendenceSystem.module.user.service.UserService;
13
+
14
+ import lombok.RequiredArgsConstructor;
15
+
16
+ @Service
17
+ @RequiredArgsConstructor
18
+ public class UserServiceImpl implements UserService {
19
+ private final UserRepository userRepository;
20
+ private final UserResponseMapper userResponseMapper;
21
+
22
+ @Override
23
+ public UserResponse getById(Long id) {
24
+ return userResponseMapper.fromEntity(findById(id));
25
+ }
26
+
27
+ @Transactional
28
+ @Override
29
+ public void deleteUser(Long id) {
30
+ userRepository.delete(findById(id));
31
+ }
32
+
33
+ private User findById(Long id) {
34
+ return userRepository.findById(id)
35
+ .orElseThrow(() -> new IllegalArgumentException("Không tìm thấy người dùng với id: " + id));
36
+ }
37
+
38
+ @Override
39
+ public Page<UserResponse> getAccounts(Pageable pageable) {
40
+ // TODO Auto-generated method stub
41
+ throw new UnsupportedOperationException("Unimplemented method 'getAccounts'");
42
+ }
43
+ }
src/main/java/com/attendenceSystem/security/ActiveUserFilter.java ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // package com.attendenceSystem.security;
2
+
3
+ // import java.io.IOException;
4
+
5
+ // import org.springframework.security.authentication.AnonymousAuthenticationToken;
6
+ // import org.springframework.security.core.Authentication;
7
+ // import org.springframework.security.core.context.SecurityContextHolder;
8
+ // import org.springframework.stereotype.Component;
9
+ // import org.springframework.web.filter.OncePerRequestFilter;
10
+
11
+ // import com.attendenceSystem.constant.Routes;
12
+ // import com.attendenceSystem.entity.User;
13
+ // import com.attendenceSystem.repository.UserRepository;
14
+
15
+ // import jakarta.servlet.FilterChain;
16
+ // import jakarta.servlet.ServletException;
17
+ // import jakarta.servlet.http.HttpServletRequest;
18
+ // import jakarta.servlet.http.HttpServletResponse;
19
+ // import jakarta.servlet.http.HttpSession;
20
+ // import lombok.RequiredArgsConstructor;
21
+
22
+ // @Component
23
+ // @RequiredArgsConstructor
24
+ // public class ActiveUserFilter extends OncePerRequestFilter {
25
+
26
+ // private final UserRepository userRepository;
27
+
28
+ // @Override
29
+ // protected void doFilterInternal(
30
+ // HttpServletRequest request,
31
+ // HttpServletResponse response,
32
+ // FilterChain filterChain)
33
+ // throws ServletException, IOException {
34
+
35
+ // Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
36
+
37
+ // if (authentication != null
38
+ // && authentication.isAuthenticated()
39
+ // && !(authentication instanceof AnonymousAuthenticationToken)) {
40
+
41
+ // String username = authentication.getName();
42
+
43
+ // User user = userRepository.findByUsername(username).orElse(null);
44
+
45
+ // if (user == null || !user.isActive()) {
46
+ // SecurityContextHolder.clearContext();
47
+ // HttpSession session = request.getSession(false);
48
+ // if (session != null) {
49
+ // session.invalidate();
50
+ // }
51
+ // response.sendRedirect(Routes.USER + "/login");
52
+ // return;
53
+ // }
54
+ // }
55
+
56
+ // filterChain.doFilter(request, response);
57
+ // }
58
+
59
+ // @Override
60
+ // protected boolean shouldNotFilter(HttpServletRequest request) {
61
+ // String uri = request.getRequestURI();
62
+
63
+ // return uri.startsWith("/css/")
64
+ // || uri.startsWith("/js/")
65
+ // || uri.startsWith("/images/");
66
+ // }
67
+ // }
src/main/java/com/attendenceSystem/security/ForceChangePasswordInterceptor.java ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // package com.attendenceSystem.security;
2
+
3
+ // import org.springframework.stereotype.Component;
4
+ // import org.springframework.web.servlet.HandlerInterceptor;
5
+
6
+ // import com.attendenceSystem.constant.Routes;
7
+ // import com.attendenceSystem.entity.User;
8
+ // import com.attendenceSystem.repository.UserRepository;
9
+ // import com.attendenceSystem.util.SecurityUtil;
10
+
11
+ // import jakarta.servlet.http.HttpServletRequest;
12
+ // import jakarta.servlet.http.HttpServletResponse;
13
+ // import lombok.RequiredArgsConstructor;
14
+
15
+ // @Component
16
+ // @RequiredArgsConstructor
17
+ // public class ForceChangePasswordInterceptor implements HandlerInterceptor {
18
+ // private final UserRepository userRepository;
19
+
20
+ // @Override
21
+ // public boolean preHandle(
22
+ // HttpServletRequest request,
23
+ // HttpServletResponse response,
24
+ // Object handler)
25
+ // throws Exception {
26
+ // String username = SecurityUtil.getCurrentUserName();
27
+ // if (username == null) {
28
+ // return true;
29
+ // }
30
+ // User user = userRepository.findUserByUsername(username).orElse(null);
31
+ // if (user == null) {
32
+ // return true;
33
+ // }
34
+ // String uri = request.getRequestURI();
35
+ // if (user.isMustChangePassword() && !uri.startsWith(Routes.USER + "/change-password")) {
36
+ // response.sendRedirect(Routes.USER + "/change-password");
37
+ // return false;
38
+ // }
39
+ // return true;
40
+ // }
41
+ // }
src/main/java/com/attendenceSystem/security/SecurityConfig.java ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.attendenceSystem.security;
2
+
3
+ import org.springframework.context.annotation.Bean;
4
+ import org.springframework.context.annotation.Configuration;
5
+ import org.springframework.security.authentication.AuthenticationManager;
6
+ import org.springframework.security.authentication.ProviderManager;
7
+ import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
8
+ import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
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.core.userdetails.UserDetailsService;
12
+ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
13
+ import org.springframework.security.crypto.password.PasswordEncoder;
14
+ import org.springframework.security.web.SecurityFilterChain;
15
+ import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
16
+
17
+ // import com.attendenceSystem.constant.Routes;
18
+ // import com.attendenceSystem.entity.enums.Role;
19
+
20
+ import lombok.RequiredArgsConstructor;
21
+
22
+ @Configuration
23
+ @EnableWebSecurity
24
+ @RequiredArgsConstructor
25
+ public class SecurityConfig {
26
+ // private final ActiveUserFilter activeUserFilter;
27
+ private final AuthenticationConfiguration authenticationConfiguration;
28
+
29
+ @Bean
30
+ public PasswordEncoder passwordEncoder() {
31
+ return new BCryptPasswordEncoder();
32
+ }
33
+
34
+ @Bean
35
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
36
+ http
37
+ .authorizeHttpRequests(auth -> auth
38
+ .anyRequest().permitAll())
39
+ .csrf(csrf -> csrf.disable());
40
+ return http.build();
41
+ }
42
+
43
+ @Bean
44
+ public AuthenticationManager authenticationManager() throws Exception {
45
+ return authenticationConfiguration.getAuthenticationManager();
46
+ }
47
+ // Chỉ dùng để test admin
48
+ // @Bean
49
+ // public UserDetailsService userDetailsService(
50
+ // PasswordEncoder passwordEncoder) {
51
+
52
+ // UserDetails admin = User.builder()
53
+ // .username("admin")
54
+ // .password(passwordEncoder.encode("123456"))
55
+ // .roles(Role.ADMIN.name())
56
+ // .build();
57
+
58
+ // return new InMemoryUserDetailsManager(admin);
59
+ // }
60
+ }
src/main/java/com/attendenceSystem/user/dto/request/LoginRequest.java DELETED
@@ -1,20 +0,0 @@
1
- package com.attendenceSystem.user.dto.request;
2
-
3
-
4
- import jakarta.validation.constraints.Email;
5
- import jakarta.validation.constraints.NotBlank;
6
- import jakarta.validation.constraints.Size;
7
- import lombok.Data;
8
-
9
- @Data
10
- public class LoginRequest {
11
- @NotBlank(message = "Email không được để trống")
12
- @Size(max = 255, message = "Email không được vượt quá 255 ký tự")
13
- @Email(message = "Email không đúng định dạng")
14
- private String email;
15
- @NotBlank(message = "Mật khẩu không được để trống")
16
- @Size(min = 8, message = "Mật khẩu phải chứa ít nhất 8 kí tự")
17
- private String password;
18
-
19
-
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/dto/request/RegisterRequest.java DELETED
@@ -1,38 +0,0 @@
1
- package com.attendenceSystem.user.dto.request;
2
-
3
- import com.attendenceSystem.annotation.PasswordMatch;
4
- import com.attendenceSystem.user.entity.User;
5
- import com.fasterxml.jackson.annotation.JsonProperty;
6
-
7
- import jakarta.validation.constraints.Email;
8
- import jakarta.validation.constraints.NotBlank;
9
- import jakarta.validation.constraints.Size;
10
- import lombok.Data;
11
- import lombok.NonNull;
12
-
13
- @Data
14
- @PasswordMatch
15
- public class RegisterRequest {
16
- @NotBlank(message = "Email không được để trống")
17
- @Size(max = 255, message = "Email không được vượt quá 255 ký tự")
18
- @Email(message = "Email không đúng định dạng")
19
- private String email;
20
- @NotBlank(message = "Mật khẩu không được để trống")
21
- @Size(min = 8, message = "Mật khẩu phải chứa ít nhất 8 kí tự")
22
- private String password;
23
- @NotBlank(message = "Mật khẩu xác nhận không được để trống")
24
- @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
25
- private String rePassword;
26
- @NotBlank(message = "Họ tên không được để trống")
27
- @Size(max = 255, message = "Họ tên không được vượt quá 255 ký tự")
28
- private String fullName;
29
-
30
- @NonNull
31
- public User toEntity(String hashPassword) {
32
- return User.builder()
33
- .email(this.email)
34
- .password(hashPassword)
35
- .fullName(this.fullName)
36
- .build();
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/dto/response/UserResponse.java DELETED
@@ -1,17 +0,0 @@
1
- package com.attendenceSystem.user.dto.response;
2
-
3
- import lombok.Builder;
4
- import lombok.Data;
5
-
6
- @Data
7
- @Builder
8
- public class UserResponse {
9
- private Long id;
10
- private String email;
11
- private String fullName;
12
- private String avatar;
13
- private String status;
14
- private String createdAt;
15
- private String updatedAt;
16
- private Boolean deleted;
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/entity/converter/RoleConverter.java DELETED
@@ -1,15 +0,0 @@
1
- // package com.attendenceSystem.user.entity.converter;
2
-
3
- // @Converter(autoApply = true)
4
- // public class RoleConverter implements AttributeConverter<Role, Integer> {
5
-
6
- // @Override
7
- // public Integer convertToDatabaseColumn(Role role) {
8
- // return role == null ? null : role.getValue();
9
- // }
10
-
11
- // @Override
12
- // public Role convertToEntityAttribute(Integer dbData) {
13
- // return dbData == null ? null : Role.fromValue(dbData);
14
- // }
15
- // }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/mapper/request/LoginRequestMapper.java DELETED
@@ -1,5 +0,0 @@
1
- package com.attendenceSystem.user.mapper.request;
2
-
3
- public class LoginRequestMapper {
4
-
5
- }
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/mapper/request/RegisterRequestMapper.java DELETED
@@ -1,5 +0,0 @@
1
- package com.attendenceSystem.user.mapper.request;
2
-
3
- public class RegisterRequestMapper {
4
-
5
- }
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/repository/UserRepository.java DELETED
@@ -1,11 +0,0 @@
1
- package com.attendenceSystem.user.repository;
2
-
3
- import org.springframework.data.jpa.repository.JpaRepository;
4
- import org.springframework.stereotype.Repository;
5
-
6
- import com.attendenceSystem.user.entity.User;
7
-
8
- @Repository
9
- public interface UserRepository extends JpaRepository<User, Long> {
10
-
11
- }
 
 
 
 
 
 
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/service/UserService.java DELETED
@@ -1,15 +0,0 @@
1
- package com.attendenceSystem.user.service;
2
-
3
- import com.attendenceSystem.user.dto.request.LoginRequest;
4
- import com.attendenceSystem.user.dto.request.RegisterRequest;
5
- import com.attendenceSystem.user.dto.response.UserResponse;
6
-
7
- public interface UserService {
8
- UserResponse login(LoginRequest request);
9
-
10
- void register(RegisterRequest request);
11
-
12
- void deleteUser(Long id);
13
-
14
- UserResponse findAccountById(Long id);
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/main/java/com/attendenceSystem/user/service/impl/UserServiceImpl.java DELETED
@@ -1,65 +0,0 @@
1
- package com.attendenceSystem.user.service.impl;
2
-
3
- import java.time.Instant;
4
- import java.time.ZoneId;
5
-
6
- import com.attendenceSystem.user.dto.request.LoginRequest;
7
- import com.attendenceSystem.user.dto.request.RegisterRequest;
8
- import com.attendenceSystem.user.dto.response.UserResponse;
9
- import com.attendenceSystem.user.entity.User;
10
- import com.attendenceSystem.user.repository.UserRepository;
11
- import com.attendenceSystem.user.service.UserService;
12
- import com.attendenceSystem.util.TimeUtil;
13
-
14
- import lombok.RequiredArgsConstructor;
15
-
16
- @RequiredArgsConstructor
17
- public class UserServiceImpl implements UserService {
18
- private final UserRepository userRepository;
19
- private final ZoneId applicationZoneId;
20
- // private final PasswordEncoder passwordEncoder;
21
-
22
- @Override
23
- public UserResponse login(LoginRequest request) {
24
- // Tìm tài khoản thông qua email từ request, không có báo lỗi.
25
-
26
- // Kiểm tra mật khẩu từ request có chính xác không. Sai báo lỗi
27
-
28
- // Trả UserResponse
29
- return null;
30
- }
31
-
32
- // @Transactional
33
- @Override
34
- public void register(RegisterRequest request) {
35
- // Kiểm tra email
36
-
37
- // encode password
38
-
39
- // Lưu User
40
- }
41
-
42
- @Override
43
- public void deleteUser(Long id) {
44
- // TODO Auto-generated method stub
45
- throw new UnsupportedOperationException("Unimplemented method 'deleteUser'");
46
- }
47
-
48
- @Override
49
- public UserResponse findAccountById(Long id) {
50
- // Kiểm tra id == null
51
-
52
- // Tìm kiếm user thông qua id
53
-
54
- // Trả về UserResponse.
55
- return null;
56
- }
57
-
58
- private String getCurrentTime() {
59
-
60
- return TimeUtil.formatInstant(
61
- Instant.now(),
62
- applicationZoneId);
63
- }
64
-
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/main/java/com/attendenceSystem/validator/PasswordMatchValidator.java CHANGED
@@ -1,7 +1,7 @@
1
  package com.attendenceSystem.validator;
2
 
3
  import com.attendenceSystem.annotation.PasswordMatch;
4
- import com.attendenceSystem.user.dto.request.RegisterRequest;
5
 
6
  import jakarta.validation.ConstraintValidator;
7
  import jakarta.validation.ConstraintValidatorContext;
@@ -13,13 +13,13 @@ public class PasswordMatchValidator
13
  public boolean isValid(RegisterRequest request,
14
  ConstraintValidatorContext context) {
15
 
16
- if (request.getPassword() == null
17
- || request.getRePassword() == null) {
18
  return true;
19
  }
20
 
21
- boolean valid = request.getPassword()
22
- .equals(request.getRePassword());
23
 
24
  if (!valid) {
25
  context.disableDefaultConstraintViolation();
 
1
  package com.attendenceSystem.validator;
2
 
3
  import com.attendenceSystem.annotation.PasswordMatch;
4
+ import com.attendenceSystem.module.user.dto.request.RegisterRequest;
5
 
6
  import jakarta.validation.ConstraintValidator;
7
  import jakarta.validation.ConstraintValidatorContext;
 
13
  public boolean isValid(RegisterRequest request,
14
  ConstraintValidatorContext context) {
15
 
16
+ if (request.password() == null
17
+ || request.rePassword() == null) {
18
  return true;
19
  }
20
 
21
+ boolean valid = request.password()
22
+ .equals(request.rePassword());
23
 
24
  if (!valid) {
25
  context.disableDefaultConstraintViolation();
src/main/resources/application.properties CHANGED
@@ -23,14 +23,14 @@ spring.devtools.livereload.enabled=true
23
  server.servlet.jsp.init-parameters.development=true
24
 
25
  # DataSource Configuration for SQL Server
26
- # spring.datasource.url=jdbc:mariadb://localhost:3306/MOONBLIGHT
27
- # spring.datasource.username=root
28
- # spring.datasource.password=QQQewqwqa401!
29
- # spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
30
-
31
- spring.datasource.url=jdbc:mysql://localhost:3306/game_promo_web
32
  spring.datasource.username=root
33
- spring.datasource.password=annguyenthanh2k5
 
 
 
 
 
34
 
35
 
36
  # SMPT EMAIL
@@ -40,7 +40,18 @@ spring.datasource.password=annguyenthanh2k5
40
  # spring.mail.password=lzzxdgzmirxdwqdv
41
 
42
  # JPA configuration
 
 
 
 
43
 
 
 
44
 
 
 
 
 
 
45
 
46
- >>>>>>> Stashed changes
 
23
  server.servlet.jsp.init-parameters.development=true
24
 
25
  # DataSource Configuration for SQL Server
26
+ spring.datasource.url=jdbc:mariadb://localhost:3306/ATTENDANCE
 
 
 
 
 
27
  spring.datasource.username=root
28
+ spring.datasource.password=QQQewqwqa401!
29
+ spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
30
+
31
+ # spring.datasource.url=jdbc:mysql://localhost:3306/game_promo_web
32
+ # spring.datasource.username=root
33
+ # spring.datasource.password=annguyenthanh2k5
34
 
35
 
36
  # SMPT EMAIL
 
40
  # spring.mail.password=lzzxdgzmirxdwqdv
41
 
42
  # JPA configuration
43
+ spring.jpa.hibernate.ddl-auto=update
44
+ spring.jpa.show-sql=true
45
+
46
+
47
 
48
+ # spring.mail.properties.mail.smtp.auth=true
49
+ # spring.mail.properties.mail.smtp.starttls.enable=true
50
 
51
+ # Catch exception
52
+ # server.error.include-message=never
53
+ # server.error.include-binding-errors=never
54
+ # server.error.include-stacktrace=never
55
+ # server.error.include-exception=false
56
 
57
+ app.timezone=Asia/Ho_Chi_Minh
src/main/resources/templates/cms/{auths → auth}/login.html RENAMED
File without changes
src/main/resources/templates/cms/{auths → auth}/register.html RENAMED
File without changes
src/main/resources/templates/cms/{auths → auth}/verify-otp.html RENAMED
File without changes
src/main/resources/templates/cms/{documents → document}/document-create.html RENAMED
File without changes
src/main/resources/templates/cms/{documents → document}/document-detail.html RENAMED
File without changes