Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
// thymeleaf
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.5.3'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-mail'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/menu/3").setViewName("index");
registry.addViewController("/menu/4").setViewName("index");

registry.addViewController("/test").setViewName("test");

//security
registry.addViewController("/login").setViewName("login");
registry.addViewController("/register").setViewName("register");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ public String getPassword() {
return user.getPassword();
}

// 추가
public String getProvider() {
return user.getProvider();
}

public String getEmail() {
return user.getEmail();
}

@Override
public String getUsername() {
return user.getUsername();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package gubun.financialledger.user.controller;

import gubun.financialledger.user.auth.PrincipalDetails;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

// 메인페이지 로그인한 유저 정보 전달
@GetMapping("/")
public ModelAndView currentUser(@AuthenticationPrincipal PrincipalDetails user) {
ModelAndView mv = new ModelAndView();
mv.setViewName("index");
mv.addObject("user", user);
return mv;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package gubun.financialledger.user.controller;

import gubun.financialledger.user.auth.PrincipalDetails;
import gubun.financialledger.user.dto.IdInquiryForm;
import gubun.financialledger.user.dto.UserUpdateForm;
import gubun.financialledger.user.entity.User;
import gubun.financialledger.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.security.Principal;
import java.util.Optional;

@Slf4j
@Controller
@RequestMapping("/profile")
@RequiredArgsConstructor
public class ProfileController {

private final UserService userService;

@GetMapping
public ModelAndView currentUser(@AuthenticationPrincipal PrincipalDetails user) {
ModelAndView mv = new ModelAndView();
mv.setViewName("profile");
mv.addObject("user", user);
return mv;
}

@ResponseBody
@PutMapping("/users")
public String userUpdate(
@AuthenticationPrincipal PrincipalDetails user,
@Validated @ModelAttribute("form") UserUpdateForm form, BindingResult bindingResult
) {
//구현중
return "success";
}

@ResponseBody
@DeleteMapping("/users")
public String deleteUser(
@RequestBody String username) {
userService.deleteUser(username);
return "redirect:/";
}
}
31 changes: 31 additions & 0 deletions src/main/java/gubun/financialledger/user/dto/UserUpdateForm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package gubun.financialledger.user.dto;

import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;

@Data
public class UserUpdateForm {

@NotBlank(message = "비밀번호를 작성해주세요.")
@Pattern(
regexp = "^.*(?=^.{8,15}$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&+=]).*$",
message = "비밀번호는 숫자, 문자, 특수문자 포함의 8~15자 이내로 작성해주세요."
)
private String currentPassword;

@NotBlank(message = "비밀번호를 작성해주세요.")
@Pattern(
regexp = "^.*(?=^.{8,15}$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&+=]).*$",
message = "비밀번호는 숫자, 문자, 특수문자 포함의 8~15자 이내로 작성해주세요."
)
private String password;

@NotBlank(message = "비밀번호를 작성해주세요.")
@Pattern(
regexp = "^.*(?=^.{8,15}$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&+=]).*$",
message = "비밀번호는 숫자, 문자, 특수문자 포함의 8~15자 이내로 작성해주세요."
)
private String repeatPassword;
}
3 changes: 3 additions & 0 deletions src/main/java/gubun/financialledger/user/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ public User(UserRole role, String email, String password, String username, Boole
public void updatePassword(String password){
this.password = password;
}
public void deleteUser(Boolean isDeleted){
this.isDeleted = isDeleted;
}
}
11 changes: 11 additions & 0 deletions src/main/java/gubun/financialledger/user/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,15 @@ public Optional<User> isValidatedUser(String username, String email){
public void updatePassword(User user, String password){
user.updatePassword(passwordEncoder.encode(password));
}

@Transactional
public void deleteUser(String username) {
Optional<User> user = userRepository.findByUsername(username);
if(user.isPresent()) {
User u = user.get();
u.deleteUser(true);
userRepository.save(u);
}
// 탈퇴 시 logout 진행
}
}
Binary file added src/main/resources/static/images/default_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/google_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 62 additions & 0 deletions src/main/resources/static/js/subpages/userProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
function changePassword(){
$("#userUpdateBtn").show();
$("#cancelBtn").show();
$("#changePasswordBtn").hide();
$("#deleteUserBtn").hide();
$("#pw0").show();
$("#pw1").show();
$("#pw2").show();
}

function cancelUpdate(){
$("#userUpdateBtn").hide();
$("#cancelBtn").hide();
$("#changePasswordBtn").show();
$("#deleteUserBtn").show();
$("#pw0").hide();
$("#pw1").hide();
$("#pw2").hide();
}

function deleteUser(){
console.log("deleteUser");
$.ajax({
url: "/profile/users",
dataType: "json",
contentType: "application/json; charset=UTF-8",
type: "DELETE",
data: $("#inputUsername").val(),
beforeSend: function (jqXHR, settings) {
//CSRF 해결
let header = $("meta[name='_csrf_header']").attr("content");
let token = $("meta[name='_csrf']").attr("content");
jqXHR.setRequestHeader(header, token);
},
done: function (data) {
console.log(data);
if(data === "success"){
alert("회원탈퇴에 성공하였습니다.");
} else {
alert("회원탈퇴에 실패하였습니다.");
}
},

});
}

function userUpdate(){
console.log("userUpdate");

// [Step1] : userUpdateValidation
let inputPassword = $("inputPassword").val()
let inputPasswordCheck = $("inputPasswordCheck").val();

//새 비밀번호 검증 check 검증 -> Spring Valid로 하도록 변경
// if (inputPassword != inputPasswordCheck) {
//
// alert("새 비밀번호가 일치 하지 않습니다.");
// return;
// }
//구현중..
}

29 changes: 29 additions & 0 deletions src/main/resources/templates/fragments/config.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!-- 공통으로 사용할 css, js 파일 등의 선언 코드를 모은 파일 -->
<th:block th:fragment="configFragment">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>가계부</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

<!-- CSS -->
<link rel="stylesheet" th:href="@{/vendor/fontawesome-free/css/all.min.css}">
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
<link rel="stylesheet" th:href="@{/css/sb-admin-2.min.css}" >

<!-- JS -->
<script th:src="@{/vendor/jquery/jquery.min.js}"></script>
<script th:src="@{/vendor/bootstrap/js/bootstrap.bundle.min.js}"></script>
<script th:src="@{/vendor/jquery-easing/jquery.easing.min.js}"></script>
<script th:src="@{/js/sb-admin-2.min.js}"></script>
<script th:src="@{/vendor/chart.js/Chart.min.js}"></script>
<script th:src="@{/js/demo/chart-area-demo.js}"></script>
<script th:src="@{/js/demo/chart-pie-demo.js}"></script>
</head>
</th:block>
</html>
12 changes: 12 additions & 0 deletions src/main/resources/templates/fragments/footer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!--footerFragment 선언-->
<div th:fragment="footerFragment">
<footer class="sticky-footer bg-white">
<div class="container my-auto">
<div class="copyright text-center my-auto">
<span>Copyright &copy; Your Website 2022</span>
</div>
</div>
</footer>
</div>
</html>
21 changes: 21 additions & 0 deletions src/main/resources/templates/fragments/logoutModal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<!-- Logout Modal-->
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" th:href="@{/logout}">Logout</a>
</div>
</div>
</div>
</div>
</html>
Loading