Expanded user-derived database models.
This commit is contained in:
		
							parent
							
								
									8c2a84755d
								
							
						
					
					
						commit
						9218a38850
					
				| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					package nl.andrewlalis.gymboard_api.domains.auth.controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dto.UserPersonalDetailsPayload;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dto.UserPersonalDetailsResponse;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dto.UserResponse;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.model.User;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.service.UserService;
 | 
				
			||||||
 | 
					import org.springframework.security.core.annotation.AuthenticationPrincipal;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.GetMapping;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.PostMapping;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.RequestBody;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.RestController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@RestController
 | 
				
			||||||
 | 
					public class UserController {
 | 
				
			||||||
 | 
						private final UserService userService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public UserController(UserService userService) {
 | 
				
			||||||
 | 
							this.userService = userService;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@GetMapping(path = "/auth/me/personal-details")
 | 
				
			||||||
 | 
						public UserPersonalDetailsResponse getMyPersonalDetails(@AuthenticationPrincipal User user) {
 | 
				
			||||||
 | 
							return userService.getPersonalDetails(user.getId());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@PostMapping(path = "/auth/me/personal-details")
 | 
				
			||||||
 | 
						public UserResponse updateMyPersonalDetails(
 | 
				
			||||||
 | 
								@AuthenticationPrincipal User user,
 | 
				
			||||||
 | 
								@RequestBody UserPersonalDetailsPayload payload
 | 
				
			||||||
 | 
						) {
 | 
				
			||||||
 | 
							return userService.updatePersonalDetails(user.getId(), payload);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					package nl.andrewlalis.gymboard_api.domains.auth.dao;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.model.UserPersonalDetails;
 | 
				
			||||||
 | 
					import org.springframework.data.jpa.repository.JpaRepository;
 | 
				
			||||||
 | 
					import org.springframework.stereotype.Repository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Repository
 | 
				
			||||||
 | 
					public interface UserPersonalDetailsRepository extends JpaRepository<UserPersonalDetails, String> {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					package nl.andrewlalis.gymboard_api.domains.auth.dto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.time.LocalDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public record UserPersonalDetailsPayload(
 | 
				
			||||||
 | 
							LocalDate birthDate,
 | 
				
			||||||
 | 
							Float currentWeight,
 | 
				
			||||||
 | 
							String currentWeightUnit,
 | 
				
			||||||
 | 
							String sex
 | 
				
			||||||
 | 
					) {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					package nl.andrewlalis.gymboard_api.domains.auth.dto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.model.UserPersonalDetails;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.time.format.DateTimeFormatter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public record UserPersonalDetailsResponse(
 | 
				
			||||||
 | 
							String userId,
 | 
				
			||||||
 | 
							String birthDate,
 | 
				
			||||||
 | 
							float currentWeight,
 | 
				
			||||||
 | 
							String currentWeightUnit,
 | 
				
			||||||
 | 
							float currentMetricWeight,
 | 
				
			||||||
 | 
							String sex
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						public UserPersonalDetailsResponse(UserPersonalDetails pd) {
 | 
				
			||||||
 | 
							this(
 | 
				
			||||||
 | 
									pd.getUserId(),
 | 
				
			||||||
 | 
									pd.getBirthDate().format(DateTimeFormatter.ISO_LOCAL_DATE),
 | 
				
			||||||
 | 
									pd.getCurrentWeight().floatValue(),
 | 
				
			||||||
 | 
									pd.getCurrentWeightUnit().name(),
 | 
				
			||||||
 | 
									pd.getCurrentMetricWeight().floatValue(),
 | 
				
			||||||
 | 
									pd.getSex().name()
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,9 @@ public class User {
 | 
				
			||||||
	@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, optional = false, fetch = FetchType.LAZY)
 | 
						@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, optional = false, fetch = FetchType.LAZY)
 | 
				
			||||||
	private UserPersonalDetails personalDetails;
 | 
						private UserPersonalDetails personalDetails;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, optional = false, fetch = FetchType.LAZY)
 | 
				
			||||||
 | 
						private UserPreferences preferences;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public User() {}
 | 
						public User() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public User(String id, boolean activated, String email, String passwordHash, String name) {
 | 
						public User(String id, boolean activated, String email, String passwordHash, String name) {
 | 
				
			||||||
| 
						 | 
					@ -50,6 +53,7 @@ public class User {
 | 
				
			||||||
		this.name = name;
 | 
							this.name = name;
 | 
				
			||||||
		this.roles = new HashSet<>();
 | 
							this.roles = new HashSet<>();
 | 
				
			||||||
		this.personalDetails = new UserPersonalDetails(this);
 | 
							this.personalDetails = new UserPersonalDetails(this);
 | 
				
			||||||
 | 
							this.preferences = new UserPreferences(this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public String getId() {
 | 
						public String getId() {
 | 
				
			||||||
| 
						 | 
					@ -91,4 +95,8 @@ public class User {
 | 
				
			||||||
	public UserPersonalDetails getPersonalDetails() {
 | 
						public UserPersonalDetails getPersonalDetails() {
 | 
				
			||||||
		return personalDetails;
 | 
							return personalDetails;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public UserPreferences getPreferences() {
 | 
				
			||||||
 | 
							return preferences;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,19 @@ public class UserPersonalDetails {
 | 
				
			||||||
	public enum PersonSex {
 | 
						public enum PersonSex {
 | 
				
			||||||
		MALE,
 | 
							MALE,
 | 
				
			||||||
		FEMALE,
 | 
							FEMALE,
 | 
				
			||||||
		UNKNOWN
 | 
							UNKNOWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public static PersonSex parse(String s) {
 | 
				
			||||||
 | 
								if (s != null && !s.isBlank()) {
 | 
				
			||||||
 | 
									s = s.strip().toUpperCase();
 | 
				
			||||||
 | 
									if (s.equals("M") || s.equals("MALE") || s.equals("MAN")) {
 | 
				
			||||||
 | 
										return MALE;
 | 
				
			||||||
 | 
									} else if (s.equals("F") || s.equals("FEMALE") || s.equals("WOMAN")) {
 | 
				
			||||||
 | 
										return FEMALE;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return UNKNOWN;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Id
 | 
						@Id
 | 
				
			||||||
| 
						 | 
					@ -50,6 +62,10 @@ public class UserPersonalDetails {
 | 
				
			||||||
		this.userId = user.getId();
 | 
							this.userId = user.getId();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public String getUserId() {
 | 
				
			||||||
 | 
							return userId;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public User getUser() {
 | 
						public User getUser() {
 | 
				
			||||||
		return user;
 | 
							return user;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					package nl.andrewlalis.gymboard_api.domains.auth.model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import jakarta.persistence.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Entity
 | 
				
			||||||
 | 
					@Table(name = "auth_user_preferences")
 | 
				
			||||||
 | 
					public class UserPreferences {
 | 
				
			||||||
 | 
						@Id
 | 
				
			||||||
 | 
						@Column(name = "user_id", length = 26)
 | 
				
			||||||
 | 
						private String userId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@OneToOne(optional = false, fetch = FetchType.LAZY)
 | 
				
			||||||
 | 
						@PrimaryKeyJoinColumn(name = "user_id", referencedColumnName = "id")
 | 
				
			||||||
 | 
						private User user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Flag which, if true, indicates that the user's account is private, and
 | 
				
			||||||
 | 
						 * only approved users may view certain information about them.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						@Column(nullable = false)
 | 
				
			||||||
 | 
						private boolean accountPrivate = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * The user's preferred locale. This should always refer to one of the
 | 
				
			||||||
 | 
						 * available locales offered by the front-end app.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						@Column(nullable = false)
 | 
				
			||||||
 | 
						private String locale = "en-US";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public UserPreferences() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public UserPreferences(User user) {
 | 
				
			||||||
 | 
							this.user = user;
 | 
				
			||||||
 | 
							this.userId = user.getId();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public String getUserId() {
 | 
				
			||||||
 | 
							return userId;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public User getUser() {
 | 
				
			||||||
 | 
							return user;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean isAccountPrivate() {
 | 
				
			||||||
 | 
							return accountPrivate;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setAccountPrivate(boolean accountPrivate) {
 | 
				
			||||||
 | 
							this.accountPrivate = accountPrivate;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public String getLocale() {
 | 
				
			||||||
 | 
							return locale;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public void setLocale(String locale) {
 | 
				
			||||||
 | 
							this.locale = locale;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,13 +2,16 @@ package nl.andrewlalis.gymboard_api.domains.auth.service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import jakarta.mail.MessagingException;
 | 
					import jakarta.mail.MessagingException;
 | 
				
			||||||
import jakarta.mail.internet.MimeMessage;
 | 
					import jakarta.mail.internet.MimeMessage;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.api.model.WeightUnit;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.PasswordResetCodeRepository;
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dao.PasswordResetCodeRepository;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.domains.auth.dto.*;
 | 
					 | 
				
			||||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserActivationCodeRepository;
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dao.UserActivationCodeRepository;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dao.UserPersonalDetailsRepository;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dao.UserRepository;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.dto.*;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.domains.auth.model.PasswordResetCode;
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.model.PasswordResetCode;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.domains.auth.model.User;
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.model.User;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.domains.auth.model.UserActivationCode;
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.model.UserActivationCode;
 | 
				
			||||||
 | 
					import nl.andrewlalis.gymboard_api.domains.auth.model.UserPersonalDetails;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.util.StringGenerator;
 | 
					import nl.andrewlalis.gymboard_api.util.StringGenerator;
 | 
				
			||||||
import nl.andrewlalis.gymboard_api.util.ULID;
 | 
					import nl.andrewlalis.gymboard_api.util.ULID;
 | 
				
			||||||
import org.slf4j.Logger;
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
| 
						 | 
					@ -23,6 +26,7 @@ import org.springframework.stereotype.Service;
 | 
				
			||||||
import org.springframework.transaction.annotation.Transactional;
 | 
					import org.springframework.transaction.annotation.Transactional;
 | 
				
			||||||
import org.springframework.web.server.ResponseStatusException;
 | 
					import org.springframework.web.server.ResponseStatusException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.math.BigDecimal;
 | 
				
			||||||
import java.security.SecureRandom;
 | 
					import java.security.SecureRandom;
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.LocalDateTime;
 | 
				
			||||||
import java.util.Random;
 | 
					import java.util.Random;
 | 
				
			||||||
| 
						 | 
					@ -33,6 +37,7 @@ public class UserService {
 | 
				
			||||||
	private static final Logger log = LoggerFactory.getLogger(UserService.class);
 | 
						private static final Logger log = LoggerFactory.getLogger(UserService.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final UserRepository userRepository;
 | 
						private final UserRepository userRepository;
 | 
				
			||||||
 | 
						private final UserPersonalDetailsRepository userPersonalDetailsRepository;
 | 
				
			||||||
	private final UserActivationCodeRepository activationCodeRepository;
 | 
						private final UserActivationCodeRepository activationCodeRepository;
 | 
				
			||||||
	private final PasswordResetCodeRepository passwordResetCodeRepository;
 | 
						private final PasswordResetCodeRepository passwordResetCodeRepository;
 | 
				
			||||||
	private final ULID ulid;
 | 
						private final ULID ulid;
 | 
				
			||||||
| 
						 | 
					@ -44,13 +49,14 @@ public class UserService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public UserService(
 | 
						public UserService(
 | 
				
			||||||
			UserRepository userRepository,
 | 
								UserRepository userRepository,
 | 
				
			||||||
			UserActivationCodeRepository activationCodeRepository,
 | 
								UserPersonalDetailsRepository userPersonalDetailsRepository, UserActivationCodeRepository activationCodeRepository,
 | 
				
			||||||
			PasswordResetCodeRepository passwordResetCodeRepository,
 | 
								PasswordResetCodeRepository passwordResetCodeRepository,
 | 
				
			||||||
			ULID ulid,
 | 
								ULID ulid,
 | 
				
			||||||
			PasswordEncoder passwordEncoder,
 | 
								PasswordEncoder passwordEncoder,
 | 
				
			||||||
			JavaMailSender mailSender
 | 
								JavaMailSender mailSender
 | 
				
			||||||
	) {
 | 
						) {
 | 
				
			||||||
		this.userRepository = userRepository;
 | 
							this.userRepository = userRepository;
 | 
				
			||||||
 | 
							this.userPersonalDetailsRepository = userPersonalDetailsRepository;
 | 
				
			||||||
		this.activationCodeRepository = activationCodeRepository;
 | 
							this.activationCodeRepository = activationCodeRepository;
 | 
				
			||||||
		this.passwordResetCodeRepository = passwordResetCodeRepository;
 | 
							this.passwordResetCodeRepository = passwordResetCodeRepository;
 | 
				
			||||||
		this.ulid = ulid;
 | 
							this.ulid = ulid;
 | 
				
			||||||
| 
						 | 
					@ -220,4 +226,36 @@ public class UserService {
 | 
				
			||||||
		LocalDateTime activationCodeCutoff = LocalDateTime.now().minus(UserActivationCode.VALID_FOR);
 | 
							LocalDateTime activationCodeCutoff = LocalDateTime.now().minus(UserActivationCode.VALID_FOR);
 | 
				
			||||||
		activationCodeRepository.deleteAllByCreatedAtBefore(activationCodeCutoff);
 | 
							activationCodeRepository.deleteAllByCreatedAtBefore(activationCodeCutoff);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Transactional
 | 
				
			||||||
 | 
						public UserResponse updatePersonalDetails(String id, UserPersonalDetailsPayload payload) {
 | 
				
			||||||
 | 
							User user = userRepository.findById(id)
 | 
				
			||||||
 | 
									.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
 | 
				
			||||||
 | 
							var pd = user.getPersonalDetails();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pd.setBirthDate(payload.birthDate());
 | 
				
			||||||
 | 
							BigDecimal currentWeight = payload.currentWeight() == null ? null : BigDecimal.valueOf(payload.currentWeight());
 | 
				
			||||||
 | 
							WeightUnit currentWeightUnit = WeightUnit.parse(payload.currentWeightUnit());
 | 
				
			||||||
 | 
							BigDecimal currentMetricWeight = null;
 | 
				
			||||||
 | 
							if (currentWeight != null) {
 | 
				
			||||||
 | 
								if (currentWeightUnit == WeightUnit.POUNDS) {
 | 
				
			||||||
 | 
									currentMetricWeight = WeightUnit.toKilograms(currentWeight);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									currentMetricWeight = new BigDecimal(currentWeight.toString());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pd.setCurrentWeight(currentWeight);
 | 
				
			||||||
 | 
							pd.setCurrentWeightUnit(currentWeightUnit);
 | 
				
			||||||
 | 
							pd.setCurrentMetricWeight(currentMetricWeight);
 | 
				
			||||||
 | 
							pd.setSex(UserPersonalDetails.PersonSex.parse(payload.sex()));
 | 
				
			||||||
 | 
							user = userRepository.save(user);
 | 
				
			||||||
 | 
							return new UserResponse(user);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Transactional(readOnly = true)
 | 
				
			||||||
 | 
						public UserPersonalDetailsResponse getPersonalDetails(String id) {
 | 
				
			||||||
 | 
							var pd = userPersonalDetailsRepository.findById(id)
 | 
				
			||||||
 | 
									.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
 | 
				
			||||||
 | 
							return new UserPersonalDetailsResponse(pd);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@ package nl.andrewlalis.gymboardsearch.config;
 | 
				
			||||||
import org.springframework.beans.factory.annotation.Value;
 | 
					import org.springframework.beans.factory.annotation.Value;
 | 
				
			||||||
import org.springframework.context.annotation.Bean;
 | 
					import org.springframework.context.annotation.Bean;
 | 
				
			||||||
import org.springframework.context.annotation.Configuration;
 | 
					import org.springframework.context.annotation.Configuration;
 | 
				
			||||||
import org.springframework.core.env.Environment;
 | 
					 | 
				
			||||||
import org.springframework.web.cors.CorsConfiguration;
 | 
					import org.springframework.web.cors.CorsConfiguration;
 | 
				
			||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 | 
					import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 | 
				
			||||||
import org.springframework.web.filter.CorsFilter;
 | 
					import org.springframework.web.filter.CorsFilter;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue