Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ca44e8a967 | |||
| ce3efa299e | |||
| ad2ecb0b82 | |||
| f7bff90844 | |||
| 658958c9ef | |||
| ea031f3755 | |||
| 320e0d6011 | |||
| bda9fad391 | |||
| 363863746b | |||
| 1a12816643 | |||
| 6abb55a656 | |||
| 8cc6f775db | |||
| c3c10d1479 | |||
| 13b00504ac | |||
| 208b0be097 | |||
| 8c45451230 | |||
| dbdc06cf7e | |||
| 898a6d37aa | |||
| f67970c280 | |||
| 47b99d1858 | |||
| 384a3a5e47 | |||
| 207a2d692a | |||
| ea6ae8c022 | |||
| de262cec7b | |||
| 09013156dc | |||
| 2e77ce373e | |||
| c959549b99 | |||
| a974065fef | |||
| a23f0f73f3 | |||
| f26210b71a | |||
| 284b843e30 |
@@ -114,6 +114,8 @@ dependencies {
|
||||
api group: 'commons-io', name: 'commons-io', version: '2.11.0'
|
||||
|
||||
|
||||
compileOnly files('libs/damo-manager.jar')
|
||||
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
|
||||
testImplementation 'ch.qos.logback:logback-classic:1.2.10'
|
||||
|
||||
Binary file not shown.
@@ -4,8 +4,10 @@ package com.eactive.apim.portal.agreements.entity;
|
||||
public enum AgreementType {
|
||||
TERMS_OF_USE("TERMS_OF_USE", "이용약관"),
|
||||
PRIVACY_POLICY("PRIVACY_POLICY", "개인정보처리방침"),
|
||||
PRIVACY_COLLECT("PRIVACY_COLLECT", "개인정보수집동의서"),
|
||||
PRIVACY_COLLECT_IND("PRIVACY_COLLECT_IND", "개인용 개인정보수집동의서"),
|
||||
PRIVACY_COLLECT_ORG("PRIVACY_COLLECT_ORG", "법인용 개인정보수집동의서");
|
||||
PRIVACY_COLLECT_ORG("PRIVACY_COLLECT_ORG", "법인용 개인정보수집동의서"),
|
||||
NOTIFICATION_CONSENT("NOTIFICATION_CONSENT", "알림 수신 동의서");
|
||||
|
||||
private final String code;
|
||||
private final String description;
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.eactive.apim.portal.agreements.entity.AgreementsId;
|
||||
import com.eactive.apim.portal.agreements.entity.AgreementsStatus;
|
||||
import com.eactive.apim.portal.agreements.repository.AgreementsRepository;
|
||||
import com.eactive.apim.portal.common.exception.NotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -16,6 +17,7 @@ import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
@Slf4j
|
||||
public class AgreementsService {
|
||||
|
||||
private static final String NOT_FOUND_MESSAGE = "해당 버전의 약관이 존재하지 않습니다.";
|
||||
@@ -111,6 +113,7 @@ public class AgreementsService {
|
||||
public List<Agreements> findAllAgreementsSortPublishedOn(AgreementType agreementType) {
|
||||
List<Agreements> agreements = agreementsRepository.findAllByAgreementsTypeOrderByPublishedOnDesc(agreementType);
|
||||
if(agreements.isEmpty()) {
|
||||
log.error("해당 약관 종류의 약관이 존재하지 않습니다. agreementType={}", agreementType);
|
||||
throw new IllegalStateException(NOT_FOUND_BY_DATE_MESSAGE);
|
||||
}
|
||||
return agreements;
|
||||
|
||||
@@ -16,6 +16,7 @@ import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
@@ -23,6 +24,7 @@ import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Entity
|
||||
@Data
|
||||
@Table(name = "ptl_credential")
|
||||
|
||||
@@ -77,5 +77,21 @@ public class Approval implements Serializable, com.eactive.eai.data.Data {
|
||||
private LocalDateTime approvalDate;
|
||||
|
||||
@Column(name = "expect_end_date")
|
||||
private String expectEndDate; //예상완료일
|
||||
private String expectEndDate; //예상완료일 (yyyyMMdd)
|
||||
|
||||
/** 예상완료일(yyyyMMdd)의 한글 요일. 값이 없거나 형식이 맞지 않으면 빈 문자열. (예: "토") */
|
||||
@Transient
|
||||
public String getExpectEndDateDayOfWeek() {
|
||||
if (expectEndDate == null || expectEndDate.length() < 8) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
return java.time.LocalDate
|
||||
.parse(expectEndDate.substring(0, 8), java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
|
||||
.getDayOfWeek()
|
||||
.getDisplayName(java.time.format.TextStyle.SHORT, java.util.Locale.KOREAN);
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.eactive.apim.portal.common.entity;
|
||||
|
||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||
import kjb.safedb.KjbNotRnnoJpaAttributeConverter;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
@@ -34,7 +34,7 @@ public abstract class Auditable {
|
||||
* 최초등록자ID
|
||||
*/
|
||||
@Column(name = "created_by")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
@CreatedBy
|
||||
private String createdBy;
|
||||
|
||||
@@ -50,7 +50,7 @@ public abstract class Auditable {
|
||||
* 최종수정자ID
|
||||
*/
|
||||
@Column(name = "LAST_MODIFIED_BY")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
@LastModifiedBy
|
||||
private String lastModifiedBy;
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.eactive.apim.portal.common.util;
|
||||
|
||||
/**
|
||||
* 한국 전화번호/연락처 정규화 유틸 (portal·admin 공유).
|
||||
*
|
||||
* 전화번호 저장은 본 유틸로 하이픈 구분 정규형으로 통일한다. 저장 형식이 경로별로
|
||||
* 달라(가입=원본, 초대=하이픈, SSO=숫자만) 휴대폰 기반 조회/초대 매칭이 어긋나는 것을 막는다.
|
||||
* 암호화 컨버터가 붙은 필드는 {@code @PrePersist}/{@code @PreUpdate} 에서 본 메서드로 평문을
|
||||
* 정규화한 뒤 암호화되므로 암복호화에 영향이 없다.
|
||||
*/
|
||||
public final class PhoneNumberUtil {
|
||||
|
||||
private PhoneNumberUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국 전화번호를 하이픈 구분 정규형으로 변환한다.
|
||||
* 숫자만 추출 후 prefix/길이로 포맷하며, 해당 규칙에 맞지 않는 값은 원본을 그대로 반환한다.
|
||||
* 멱등(이미 정규형이면 동일 결과)이며 null/blank 는 원본을 반환한다.
|
||||
*
|
||||
* <pre>
|
||||
* 휴대폰 01X 11자리 → XXX-XXXX-XXXX (010-1234-5678)
|
||||
* 휴대폰 01X 10자리 → XXX-XXX-XXXX (011-123-4567)
|
||||
* 서울 02 9자리 → 02-XXX-XXXX (02-123-4567)
|
||||
* 서울 02 10자리 → 02-XXXX-XXXX (02-1234-5678)
|
||||
* 지역/070 0XX 10자리 → 0XX-XXX-XXXX (031-234-5678)
|
||||
* 지역/070 0XX 11자리 → 0XX-XXXX-XXXX (070-1234-5678)
|
||||
* 안심 050X 12자리 → 0XXX-XXXX-XXXX (0507-1234-5678)
|
||||
* 대표 15/16/18XX 8자리 → XXXX-XXXX (1588-1234)
|
||||
* 그 외/null → 원본 그대로
|
||||
* </pre>
|
||||
*/
|
||||
public static String normalize(String raw) {
|
||||
if (raw == null) {
|
||||
return null;
|
||||
}
|
||||
String digits = raw.replaceAll("[^0-9]", "");
|
||||
int len = digits.length();
|
||||
if (len == 0) {
|
||||
return raw;
|
||||
}
|
||||
|
||||
// 대표번호 15XX/16XX/18XX (8자리, 지역번호 없음)
|
||||
if (len == 8 && (digits.startsWith("15") || digits.startsWith("16") || digits.startsWith("18"))) {
|
||||
return digits.substring(0, 4) + "-" + digits.substring(4);
|
||||
}
|
||||
// 안심번호 050X (12자리)
|
||||
if (len == 12 && digits.startsWith("050")) {
|
||||
return digits.substring(0, 4) + "-" + digits.substring(4, 8) + "-" + digits.substring(8);
|
||||
}
|
||||
// 서울 02
|
||||
if (digits.startsWith("02")) {
|
||||
if (len == 9) {
|
||||
return "02-" + digits.substring(2, 5) + "-" + digits.substring(5);
|
||||
}
|
||||
if (len == 10) {
|
||||
return "02-" + digits.substring(2, 6) + "-" + digits.substring(6);
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
// 휴대폰/지역/070 등 0XX
|
||||
if (digits.startsWith("0")) {
|
||||
if (len == 10) {
|
||||
return digits.substring(0, 3) + "-" + digits.substring(3, 6) + "-" + digits.substring(6);
|
||||
}
|
||||
if (len == 11) {
|
||||
return digits.substring(0, 3) + "-" + digits.substring(3, 7) + "-" + digits.substring(7);
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자만 추출(발송 게이트웨이 전달·등가 비교용). null 은 그대로 반환.
|
||||
*/
|
||||
public static String digitsOnly(String raw) {
|
||||
return raw == null ? null : raw.replaceAll("[^0-9]", "");
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.entity;
|
||||
|
||||
import com.eactive.apim.portal.common.entity.Auditable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "DJB_APISTATUS_INCIDENT")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DjbApistatusIncident extends Auditable {
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name = "seqDjbApistatusIncident",
|
||||
sequenceName = "SEQ_DJB_APISTATUS_INCIDENT", allocationSize = 1)
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqDjbApistatusIncident")
|
||||
@Column(name = "INCIDENT_ID", nullable = false)
|
||||
private Long incidentId;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "KIND", length = 20, nullable = false)
|
||||
private IncidentKind kind;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "STATE", length = 30)
|
||||
private IncidentState state;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "PREVIOUS_STATE", length = 30)
|
||||
private IncidentState previousState;
|
||||
|
||||
@Column(name = "TITLE", length = 500, nullable = false)
|
||||
private String title;
|
||||
|
||||
@Column(name = "SUMMARY", length = 2000)
|
||||
private String summary;
|
||||
|
||||
@Column(name = "STARTED_AT")
|
||||
private LocalDateTime startedAt;
|
||||
|
||||
@Column(name = "END_AT")
|
||||
private LocalDateTime endAt;
|
||||
|
||||
@Column(name = "DETECTED_BY", length = 30, nullable = false)
|
||||
private String detectedBy = "MANUAL";
|
||||
|
||||
@Column(name = "INTERFACE_ID", length = 200)
|
||||
private String interfaceId;
|
||||
|
||||
@Column(name = "NOTICE_ID", length = 36)
|
||||
private String noticeId;
|
||||
|
||||
@Column(name = "DRAFT_YN", length = 1, nullable = false)
|
||||
private String draftYn = "N";
|
||||
|
||||
@Column(name = "FIX_YN", length = 1, nullable = false)
|
||||
private String fixYn = "N";
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.entity;
|
||||
|
||||
import com.eactive.apim.portal.common.entity.Auditable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "DJB_APISTATUS_INCIDENT_API")
|
||||
@IdClass(DjbApistatusIncidentApiId.class)
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
|
||||
public class DjbApistatusIncidentApi extends Auditable {
|
||||
|
||||
@Id
|
||||
@EqualsAndHashCode.Include
|
||||
@Column(name = "INCIDENT_ID", nullable = false)
|
||||
private Long incidentId;
|
||||
|
||||
@Id
|
||||
@EqualsAndHashCode.Include
|
||||
@Column(name = "API_ID", length = 30, nullable = false)
|
||||
private String apiId;
|
||||
|
||||
@Column(name = "API_NAME", length = 200)
|
||||
private String apiName;
|
||||
|
||||
@Column(name = "RECOVERED_AT")
|
||||
private LocalDateTime recoveredAt;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DjbApistatusIncidentApiId implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long incidentId;
|
||||
private String apiId;
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.entity;
|
||||
|
||||
import com.eactive.apim.portal.common.entity.Auditable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
import javax.persistence.Table;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "DJB_APISTATUS_INCIDENT_TIMELINE")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DjbApistatusIncidentTimeline extends Auditable {
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name = "seqDjbApistatusIncidentTimeline",
|
||||
sequenceName = "SEQ_DJB_APISTATUS_INCIDENT_TIMELINE", allocationSize = 1)
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqDjbApistatusIncidentTimeline")
|
||||
@Column(name = "TIMELINE_ID", nullable = false)
|
||||
private Long timelineId;
|
||||
|
||||
@Column(name = "INCIDENT_ID", nullable = false)
|
||||
private Long incidentId;
|
||||
|
||||
@Column(name = "EVENT_AT", nullable = false)
|
||||
private LocalDateTime eventAt;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "STATE_AFTER", length = 30)
|
||||
private IncidentState stateAfter;
|
||||
|
||||
@Column(name = "BODY", length = 4000, nullable = false)
|
||||
private String body;
|
||||
|
||||
@Column(name = "AUTHOR_TYPE", length = 20, nullable = false)
|
||||
private String authorType = "OPERATOR";
|
||||
|
||||
@Column(name = "VISIBLE_YN", length = 1, nullable = false)
|
||||
private String visibleYn = "Y";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.entity;
|
||||
|
||||
public enum IncidentKind {
|
||||
INCIDENT,
|
||||
MAINTENANCE
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.entity;
|
||||
|
||||
public enum IncidentState {
|
||||
INVESTIGATING,
|
||||
IDENTIFIED,
|
||||
MONITORING,
|
||||
RESOLVED,
|
||||
CANCELED
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.repository;
|
||||
|
||||
import com.eactive.apim.portal.djb.apistatus.incident.entity.DjbApistatusIncidentApi;
|
||||
import com.eactive.apim.portal.djb.apistatus.incident.entity.DjbApistatusIncidentApiId;
|
||||
import com.eactive.eai.rms.data.EMSDataSource;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
@EMSDataSource
|
||||
public interface DjbApistatusIncidentApiRepository
|
||||
extends JpaRepository<DjbApistatusIncidentApi, DjbApistatusIncidentApiId> {
|
||||
|
||||
List<DjbApistatusIncidentApi> findByIncidentIdOrderByApiId(Long incidentId);
|
||||
|
||||
void deleteByIncidentId(Long incidentId);
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.repository;
|
||||
|
||||
import com.eactive.apim.portal.djb.apistatus.incident.entity.DjbApistatusIncident;
|
||||
import com.eactive.eai.rms.data.EMSDataSource;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
@EMSDataSource
|
||||
public interface DjbApistatusIncidentRepository
|
||||
extends JpaRepository<DjbApistatusIncident, Long>, JpaSpecificationExecutor<DjbApistatusIncident> {
|
||||
|
||||
Optional<DjbApistatusIncident> findByNoticeId(String noticeId);
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.eactive.apim.portal.djb.apistatus.incident.repository;
|
||||
|
||||
import com.eactive.apim.portal.djb.apistatus.incident.entity.DjbApistatusIncidentTimeline;
|
||||
import com.eactive.eai.rms.data.EMSDataSource;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
@EMSDataSource
|
||||
public interface DjbApistatusIncidentTimelineRepository
|
||||
extends JpaRepository<DjbApistatusIncidentTimeline, Long> {
|
||||
|
||||
List<DjbApistatusIncidentTimeline> findByIncidentIdOrderByEventAtAsc(Long incidentId);
|
||||
|
||||
void deleteByIncidentId(Long incidentId);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.eactive.apim.portal.invitation.entity;
|
||||
|
||||
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||
import com.eactive.apim.portal.invitation.entity.UserInvitationEnums.InvitationStatus;
|
||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||
import lombok.Data;
|
||||
import org.hibernate.annotations.Comment;
|
||||
@@ -29,10 +31,15 @@ public class UserInvitation {
|
||||
@Comment("기관ID")
|
||||
private String orgId;
|
||||
|
||||
@Column(name = "INVITATION_EMAIL", length = 30, nullable = false)
|
||||
@Column(name = "INVITATION_EMAIL", length = 256)
|
||||
@Comment("초대이메일")
|
||||
private String invitationEmail;
|
||||
|
||||
@Column(name = "INVITATION_MOBILE", length = 256)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
@Comment("초대휴대폰")
|
||||
private String invitationMobile;
|
||||
|
||||
@Column(name = "INVITATION_DATE", length = 14, nullable = false)
|
||||
@Convert(converter = LocalDateTimeToStringConverter14.class)
|
||||
@Comment("초대일시")
|
||||
@@ -56,4 +63,11 @@ public class UserInvitation {
|
||||
@Comment("만료일시")
|
||||
private LocalDateTime expiresOn;
|
||||
|
||||
/** 저장 시 초대 휴대폰을 하이픈 구분 정규형으로 통일 */
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void normalizePhones() {
|
||||
this.invitationMobile = PhoneNumberUtil.normalize(this.invitationMobile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ public class UserInvitationCancelEvent implements MessageEventHandler {
|
||||
Map<String, String> requestParams = new HashMap<>();
|
||||
requestParams.put("corpName", params.get("corpName").toString());
|
||||
requestParams.put("managerName", params.get("managerName").toString());
|
||||
// DB 템플릿 USER_INVITATION_CANCELED SMS 변수(%ORG_NAME%)에 매핑
|
||||
requestParams.put("ORG_NAME", params.get("corpName").toString());
|
||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ public class UserInvitationEvent implements MessageEventHandler {
|
||||
requestParams.put("url", params.get("url").toString());
|
||||
requestParams.put("loginId",params.get("corpName").toString() + " 이용자");
|
||||
requestParams.put("authNumber", params.get("authNumber").toString());
|
||||
// DB 템플릿 USER_INVITATION SMS 변수(%ORG_NAME%)에 매핑 (USER_NAME 은 공통 자동주입)
|
||||
requestParams.put("ORG_NAME", params.get("corpName").toString());
|
||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -22,4 +22,11 @@ public interface UserInvitationRepository extends JpaRepository<UserInvitation,
|
||||
Optional<UserInvitation> findFirstByInvitationEmailAndOrgIdAndStatus(String email, String orgId, InvitationStatus status);
|
||||
|
||||
Optional<UserInvitation> findFirstByInvitationEmailAndOrgId(String email, String orgId);
|
||||
|
||||
// 휴대폰 번호 기반 초대 조회 (INVITATION_MOBILE 은 결정적 암호화로 저장되어 equality 조회 가능)
|
||||
Optional<UserInvitation> findFirstByInvitationMobileAndStatus(String mobile, InvitationStatus status);
|
||||
|
||||
Optional<UserInvitation> findFirstByInvitationMobileAndOrgIdAndStatus(String mobile, String orgId, InvitationStatus status);
|
||||
|
||||
Optional<UserInvitation> findFirstByInvitationMobileAndOrgId(String mobile, String orgId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.eactive.apim.portal.jpa;
|
||||
|
||||
import com.eactive.ext.djb.DamoManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
@Slf4j
|
||||
@Converter
|
||||
public class PersonalDataEncryptConverter implements AttributeConverter<String, String> {
|
||||
|
||||
|
||||
/**
|
||||
* 암호화
|
||||
* @param attribute the entity attribute value to be converted
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String convertToDatabaseColumn(String attribute) {
|
||||
String originalAttribute = attribute;
|
||||
if (StringUtils.isNotEmpty(attribute)) {
|
||||
attribute = DamoManager.getInstance().encrypt(attribute);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
// originalAttribute 홀수 글자 마스킹
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < originalAttribute.length(); i++) {
|
||||
if (i % 2 == 0) {
|
||||
sb.append(originalAttribute.charAt(i));
|
||||
} else {
|
||||
sb.append("*");
|
||||
}
|
||||
}
|
||||
|
||||
originalAttribute = sb.toString();
|
||||
log.debug("DB 암호화 : {} -> {}", originalAttribute, attribute);
|
||||
}
|
||||
}
|
||||
|
||||
return attribute;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 복호화
|
||||
* @param dbData the data from the database column to be
|
||||
* converted
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String convertToEntityAttribute(String dbData) {
|
||||
|
||||
String dbDataOriginal = dbData;
|
||||
if (StringUtils.isNotEmpty(dbData)) {
|
||||
if (this.isEncrypted(dbData)) {
|
||||
try {
|
||||
dbData = DamoManager.getInstance().decrypt(dbData);
|
||||
} catch (Exception e) {
|
||||
// 복호화 실패시 원본 반환
|
||||
String logData = dbData.length() <= 3 ? dbData : dbData.substring(0, 3) + "...";
|
||||
log.warn("DB 복호화 실패: 복호화하지 않고 원본 반환. dbData={} (Length : {})", logData, dbData.length());
|
||||
return dbData;
|
||||
}
|
||||
} else {
|
||||
log.debug("DB 복호화 경고: Base64 형식이 아님. 복호화하지 않고 원본 반환. dbData={}", dbData);
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
// 복호화 결과(평문) 홀수 글자 마스킹
|
||||
String maskedDbData = dbData;
|
||||
if (StringUtils.isNotEmpty(dbData)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < dbData.length(); i++) {
|
||||
if (i % 2 == 0) {
|
||||
sb.append(dbData.charAt(i));
|
||||
} else {
|
||||
sb.append("*");
|
||||
}
|
||||
}
|
||||
maskedDbData = sb.toString();
|
||||
}
|
||||
log.debug("DB 복호화 : {} -> {}", dbDataOriginal, maskedDbData);
|
||||
}
|
||||
|
||||
return dbData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 damo-manager 가 bypass 모드(무변환)인지 여부.
|
||||
* bypass 면 {@code encrypt}/{@code decrypt} 가 원문을 그대로 반환하므로 암호화/정규화가 no-op 이 된다.
|
||||
* 레거시 평문 일괄 암호화 같은 마이그레이션 작업은 이 경우 의미가 없으므로 호출 측에서 차단해야 한다.
|
||||
*/
|
||||
public boolean isBypassMode() {
|
||||
return DamoManager.getInstance().isBypassMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 암호화 여부 확인(base64 인코딩 여부로 판단, 또는 0-9, - 로 구성된 경우 암호화 되지 않은 걸로 판단(연락처))
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
private boolean isEncrypted(String data) {
|
||||
if (StringUtils.isEmpty(data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 숫자, - 로만 구성된 경우 암호화 되지 않은 걸로 판단 (ex: 연락처)
|
||||
if (data.matches("^[0-9-]+$")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = data.trim();
|
||||
|
||||
// Base64 형식 체크
|
||||
if (!data.matches("^[A-Za-z0-9+/]+={0,2}$")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Base64 길이 체크 (4의 배수)
|
||||
if (data.length() % 4 != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.eactive.apim.portal.partnership.event;
|
||||
|
||||
import com.eactive.apim.portal.template.entity.MessageCode;
|
||||
import com.eactive.apim.portal.template.service.MessageEventHandler;
|
||||
import com.eactive.apim.portal.template.service.MessageRecipient;
|
||||
import com.eactive.apim.portal.template.service.MessageSendEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class PartnershipCreatedEvent implements MessageEventHandler {
|
||||
|
||||
public static final MessageCode KEY = MessageCode.PARTNERSHIP_CREATED;
|
||||
|
||||
@Override
|
||||
public boolean allowAdditionalRecipients() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||
Map<String, String> requestParams = new HashMap<>();
|
||||
String subject = toStr(params.get("bizSubject"));
|
||||
if (subject.isEmpty()) {
|
||||
subject = toStr(params.get("subject"));
|
||||
}
|
||||
requestParams.put("partnershipId", toStr(params.get("partnershipId")));
|
||||
requestParams.put("bizSubject", subject);
|
||||
requestParams.put("subject", subject);
|
||||
requestParams.put("writerName", toStr(params.get("writerName")));
|
||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||
}
|
||||
|
||||
private String toStr(Object value) {
|
||||
return value == null ? "" : value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageCode getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "개선요청/제휴 게시물 등록";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "<div>사용 가능 변수: </div><br/>"
|
||||
+ "<div> - userName: 수신자 이름 </div><br/>"
|
||||
+ "<div> - userId: 수신자 ID (이메일) </div><br/>"
|
||||
+ "<div> - partnershipId: 신청 ID </div><br/>"
|
||||
+ "<div> - bizSubject: 신청 제목 </div><br/>"
|
||||
+ "<div> - subject: 신청 제목 (별칭) </div><br/>"
|
||||
+ "<div> - writerName: 작성자 이름 </div><br/>";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.eactive.apim.portal.portalorg.entity;
|
||||
|
||||
import com.eactive.apim.portal.common.entity.Auditable;
|
||||
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums.ApprovalStatus;
|
||||
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums.OrgStatus;
|
||||
import lombok.Data;
|
||||
@@ -91,4 +92,34 @@ public class PortalOrg extends Auditable implements Serializable, com.eactive.ea
|
||||
@Column(name = "sc_phone_number", length = 20)
|
||||
@Comment("고객센터연락처")
|
||||
private String scPhoneNumber;
|
||||
|
||||
@Column(name = "reverse_proxy_path", length = 255)
|
||||
@Comment("리버스 프록시 경로")
|
||||
private String reverseProxyPath;
|
||||
|
||||
/** 저장 시 전화번호를 하이픈 구분 정규형으로 통일 */
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void normalizePhones() {
|
||||
this.orgPhoneNumber = PhoneNumberUtil.normalize(this.orgPhoneNumber);
|
||||
this.scPhoneNumber = PhoneNumberUtil.normalize(this.scPhoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 법인 반려/삭제(탈퇴) 시 사업자등록번호·법인등록번호 등 민감/개인정보 필드를 제거한다.
|
||||
* orgName·orgStatus·approvalStatus 등 상태값은 호출 측에서 별도 설정한다.
|
||||
*/
|
||||
public void clearSensitiveDataOnRemoval() {
|
||||
this.corpRegNo = null;
|
||||
this.compRegNo = null;
|
||||
this.orgCode = null;
|
||||
this.compRegFile = null;
|
||||
this.ceoName = null;
|
||||
this.orgAddr = null;
|
||||
this.orgPhoneNumber = null;
|
||||
this.scPhoneNumber = null;
|
||||
this.orgSectors = null;
|
||||
this.orgIndustryType = null;
|
||||
this.serviceName = null;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -51,13 +51,24 @@ public class PortalPropertyService extends AbstractDataService<PortalPropertyGro
|
||||
Optional<PortalProperty> existingProperty = portalPropertyRepository.findById(propertyId);
|
||||
|
||||
if (existingProperty.isPresent()) {
|
||||
return existingProperty.get().getPropertyValue();
|
||||
PortalProperty property = existingProperty.get();
|
||||
// 설명(property_desc)이 비어 있으면 코드가 넘긴 description 으로 채운다.
|
||||
// (값이 있으면 관리자 편집분 보존 — 덮어쓰지 않음)
|
||||
if (isBlank(property.getPropertyDesc()) && !isBlank(description)) {
|
||||
property.setPropertyDesc(description);
|
||||
portalPropertyRepository.save(property);
|
||||
}
|
||||
return property.getPropertyValue();
|
||||
}
|
||||
|
||||
// 프로퍼티가 없으면 기본값으로 생성
|
||||
return createDefaultProperty(groupName, propertyName, defaultValue, description);
|
||||
}
|
||||
|
||||
private static boolean isBlank(String s) {
|
||||
return s == null || s.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 기본 프로퍼티를 DB에 생성
|
||||
*/
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.eactive.apim.portal.portaluser.entity;
|
||||
|
||||
import com.eactive.apim.portal.common.entity.Auditable;
|
||||
import com.eactive.apim.portal.portalorg.entity.PortalOrg;
|
||||
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;import com.eactive.apim.portal.portalorg.entity.PortalOrg;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.ApprovalStatus;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.RoleCode;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.UserStatus;
|
||||
import java.io.Serializable;
|
||||
|
||||
import kjb.safedb.KjbNotRnnoJpaAttributeConverter;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.hibernate.annotations.Comment;
|
||||
@@ -22,7 +22,7 @@ import java.time.LocalDateTime;
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true)
|
||||
|
||||
@Entity
|
||||
@Table(name = "ptl_user")
|
||||
@Table(name = "PTL_USER")
|
||||
public class PortalUser extends Auditable implements Serializable, com.eactive.eai.data.Data {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -34,7 +34,7 @@ public class PortalUser extends Auditable implements Serializable, com.eactive.e
|
||||
|
||||
@Column(name = "login_id", length = 200, nullable = false)
|
||||
@Comment("로그인ID")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String loginId;
|
||||
|
||||
@Column(name = "password_hash", length = 60)
|
||||
@@ -47,17 +47,17 @@ public class PortalUser extends Auditable implements Serializable, com.eactive.e
|
||||
|
||||
@Column(name = "phone_number", length = 50)
|
||||
@Comment("전화번호")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String phoneNumber;
|
||||
|
||||
@Column(name = "mobile_number", length = 50)
|
||||
@Comment("휴대폰 번호")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String mobileNumber;
|
||||
|
||||
@Column(name = "email_addr", length = 200)
|
||||
@Comment("이메일주소")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String emailAddr;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@@ -99,4 +99,12 @@ public class PortalUser extends Auditable implements Serializable, com.eactive.e
|
||||
@Column(name = "withdrawal_reason", length=200)
|
||||
@Comment("회원탈퇴사유")
|
||||
private String withdrawalReason;
|
||||
|
||||
/** 저장 시 전화번호를 하이픈 구분 정규형으로 통일 */
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void normalizePhones() {
|
||||
this.phoneNumber = PhoneNumberUtil.normalize(this.phoneNumber);
|
||||
this.mobileNumber = PhoneNumberUtil.normalize(this.mobileNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.eactive.apim.portal.portaluser.entity;
|
||||
|
||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||
import kjb.safedb.KjbNotRnnoJpaAttributeConverter;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
|
||||
import javax.persistence.*;
|
||||
@@ -25,9 +25,14 @@ public class TwoFactorAuth {
|
||||
private String id;
|
||||
|
||||
@Column(name = "recipient", length = 255)
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String recipient;
|
||||
|
||||
// recipient 가 암호화 컬럼이라 값으로 동등 조회/중복정리가 불가능하므로,
|
||||
// recipient 평문의 결정적 해시(HMAC-SHA256, hex)를 별도 조회 키로 둔다. (비암호화)
|
||||
@Column(name = "recipient_key", length = 64)
|
||||
private String recipientKey;
|
||||
|
||||
@Column(name = "auth_number", length = 255)
|
||||
private String authNumber;
|
||||
|
||||
@@ -49,6 +54,14 @@ public class TwoFactorAuth {
|
||||
this.recipient = recipient;
|
||||
}
|
||||
|
||||
public String getRecipientKey() {
|
||||
return recipientKey;
|
||||
}
|
||||
|
||||
public void setRecipientKey(String recipientKey) {
|
||||
this.recipientKey = recipientKey;
|
||||
}
|
||||
|
||||
public String getAuthNumber() {
|
||||
return authNumber;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,10 @@ public class UserPasswordResetEvent implements MessageEventHandler {
|
||||
@Override
|
||||
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||
Map<String, String> requestParams = new HashMap<>();
|
||||
requestParams.put("tempPassword", (String) params.get("tempPassword"));
|
||||
String tempPassword = (String) params.get("tempPassword");
|
||||
requestParams.put("tempPassword", tempPassword);
|
||||
// DB 템플릿 USER_PASSWORD_RESET SMS 변수(%TEMP_PASSWORD%)에 매핑
|
||||
requestParams.put("TEMP_PASSWORD", tempPassword);
|
||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -23,7 +23,10 @@ public class UserVerificationEmailEvent implements MessageEventHandler {
|
||||
@Override
|
||||
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||
Map<String, String> requestParams = new HashMap<>();
|
||||
requestParams.put("authNumber", (String) params.get("authNumber"));
|
||||
String authNumber = (String) params.get("authNumber");
|
||||
requestParams.put("authNumber", authNumber);
|
||||
// DB 템플릿 USER_VERIFICATION_EMAIL 변수(%AUTH_NO%)에 매핑
|
||||
requestParams.put("AUTH_NO", authNumber);
|
||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -24,7 +24,10 @@ public class UserVerificationMobilePhoneEvent implements MessageEventHandler {
|
||||
@Override
|
||||
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||
Map<String, String> requestParams = new HashMap<>();
|
||||
requestParams.put("authNumber", (String) params.get("authNumber"));
|
||||
String authNumber = (String) params.get("authNumber");
|
||||
requestParams.put("authNumber", authNumber);
|
||||
// DB 템플릿 USER_VERIFICATION_MOBILEPHONE SMS 변수(%AUTH_CODE%)에 매핑
|
||||
requestParams.put("AUTH_CODE", authNumber);
|
||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,11 @@ public interface PortalUserRepository extends BaseRepository<PortalUser, String>
|
||||
|
||||
boolean existsByLoginId(String loginId);
|
||||
|
||||
boolean existsByMobileNumber(String mobileNumber);
|
||||
|
||||
// 휴대폰 번호 기반 기존 회원 조회 (mobileNumber 는 유니크 제약이 없어 다건 가능)
|
||||
List<PortalUser> findAllByMobileNumber(String mobileNumber);
|
||||
|
||||
@Query("SELECT u FROM PortalUser u WHERE u.portalOrg = :org AND u.userStatus != :status")
|
||||
Page<PortalUser> findActiveUsers(@Param("org") PortalOrg org, @Param("status") PortalUserEnums.UserStatus status, Pageable pageable);
|
||||
|
||||
@@ -36,5 +41,12 @@ public interface PortalUserRepository extends BaseRepository<PortalUser, String>
|
||||
long countByPortalOrg(PortalOrg portalOrg);
|
||||
|
||||
Optional<PortalUser> findByUserName(String userName);
|
||||
|
||||
// 암복
|
||||
@Query(
|
||||
value = "select * from ${ems.datasource.schema}.ptl_user where email_addr = :emailAddr",
|
||||
nativeQuery = true
|
||||
)
|
||||
Optional<PortalUser> findByEmailAddrRaw(@Param("emailAddr") String emailAddr);
|
||||
}
|
||||
|
||||
|
||||
+9
@@ -6,7 +6,16 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface TwoFactorAuthRepository extends JpaRepository<TwoFactorAuth, String> {
|
||||
|
||||
// recipientKey(결정적 해시) 기반 조회/정리. recipient 가 암호화 컬럼이라 값 동등 조회가 깨지는 문제를 우회한다.
|
||||
Optional<TwoFactorAuth> findByRecipientKey(String recipientKey);
|
||||
|
||||
void deleteAllByRecipientKey(String recipientKey);
|
||||
|
||||
// 아래 두 메서드는 recipient(암호화 컬럼) 기반이라 신뢰할 수 없음 — 신규 코드에서는 RecipientKey 버전을 사용할 것.
|
||||
@Deprecated
|
||||
Optional<TwoFactorAuth> findByRecipient(String recipientKey);
|
||||
|
||||
@Deprecated
|
||||
void deleteAllByRecipient(String recipient);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public class Inquiry extends Auditable {
|
||||
|
||||
/**
|
||||
* 문의 상태 (예: 대기중, 답변 완료 등)
|
||||
* @DjbInquiryStatus 참조
|
||||
*/
|
||||
@Column(name = "INQUIRY_STATUS", length = 32)
|
||||
private String inquiryStatus;
|
||||
|
||||
@@ -10,85 +10,47 @@ public enum MessageCode {
|
||||
|
||||
|
||||
// 사용자 이벤트 영역
|
||||
USER_VERIFICATION_EMAIL("이메일 주소 인증", "FM_APIM001", Channels.EMAIL),
|
||||
USER_VERIFICATION_MOBILEPHONE("휴대폰 번호 인증", "S55_ICT_0006", Channels.KAKAO_ALIMTALK),
|
||||
USER_VERIFICATION_EMAIL("이메일 주소 인증", null, Channels.EMAIL),
|
||||
USER_VERIFICATION_MOBILEPHONE("휴대폰 번호 인증", null, Channels.KAKAO_ALIMTALK),
|
||||
|
||||
USER_PASSWORD_RESET("비밀번호 재설정", "FM_APIM002", Channels.EMAIL),
|
||||
USER_PASSWORD_CHANGED("사용자 비밀번호 변경", "FM_APIM003", Channels.EMAIL),
|
||||
USER_PASSWORD_RESET("비밀번호 재설정", null, Channels.KAKAO_ALIMTALK),
|
||||
USER_PASSWORD_CHANGED("사용자 비밀번호 변경", null, Channels.KAKAO_ALIMTALK),
|
||||
|
||||
USER_ACCOUNT_LOCKED("계정 잠금 알림", "FM_APIM004", Channels.EMAIL),
|
||||
USER_ACCOUNT_LOCKED("계정 잠금 알림", null, Channels.KAKAO_ALIMTALK),
|
||||
|
||||
// 법인관리자 이벤트 영역
|
||||
USER_INVITATION("법인 이용자 이메일 초대", "FM_APIM005", Channels.EMAIL),
|
||||
USER_INVITATION_CANCELED("법인 이용자 이메일 초대 취소", "FM_APIM006", Channels.EMAIL),
|
||||
|
||||
MANAGER_WITH_ORG_REGISTER_APPROVED("법인관리자 및 법인 등록 승인", "FM_APIM007", Channels.EMAIL),
|
||||
MANAGER_WITH_ORG_REGISTER_REJECTED("법인관리자 및 법인 등록 거절", "FM_APIM008", Channels.EMAIL),
|
||||
USER_INVITATION("법인 이용자 이메일 초대", null, Channels.KAKAO_ALIMTALK),
|
||||
USER_INVITATION_CANCELED("법인 이용자 이메일 초대 취소", null, Channels.KAKAO_ALIMTALK),
|
||||
|
||||
MANAGER_WITH_ORG_REGISTER_APPROVED("법인관리자 및 법인 등록 승인", null, Channels.KAKAO_ALIMTALK),
|
||||
MANAGER_WITH_ORG_REGISTER_REJECTED("법인관리자 및 법인 등록 거절", null, Channels.KAKAO_ALIMTALK),
|
||||
|
||||
// 관리자 영역
|
||||
APP_REGISTER_APPROVED("앱 등록 승인", "FM_APIM009", Channels.EMAIL),
|
||||
APP_REGISTER_REJECTED("앱 등록 거절", "FM_APIM010", Channels.EMAIL),
|
||||
APP_APPROVE("앱 사용 승인", null, Channels.KAKAO_ALIMTALK),
|
||||
APP_REJECTED("앱 사용 거절", null, Channels.KAKAO_ALIMTALK),
|
||||
|
||||
// Q&A 등록/댓글 등록 알림 (DJBank 커스텀 — portal-admin 수신)
|
||||
INQUIRY_CREATED("Q&A 등록 알림", null, Channels.NONE),
|
||||
INQUIRY_COMMENT_CREATED("Q&A 댓글 등록 알림", null, Channels.NONE),
|
||||
INQUIRY_CREATED("Q&A 등록 알림", null, Channels.SWING),
|
||||
INQUIRY_COMMENT_CREATED("Q&A 댓글 등록 알림", null, Channels.SWING),
|
||||
PARTNERSHIP_CREATED("개선요청/제휴 게시물 등록 알림", null, Channels.SWING),
|
||||
|
||||
|
||||
// API상태 모니터링
|
||||
API_STATUS_CHANGED("API 상태 변화", "FM_APIM011", Channels.MESSENGER),
|
||||
// 유량제어 토큰 획득 실패
|
||||
INFLOW_TOKEN_FAILED("유량제어 토큰 획득 실패", "FM_APIM012", Channels.MESSENGER),
|
||||
// 제주은행
|
||||
API_STATUS_CHANGED("API 상태 변화", null, Channels.SWING),
|
||||
INFLOW_TOKEN_FAILED("유량제어 토큰 획득 실패", null, Channels.SWING),
|
||||
ADMIN_VERIFICATION_MOBILEPHONE("관리자포탈 휴대폰 번호 인증", null, Channels.KAKAO_ALIMTALK),
|
||||
|
||||
|
||||
// 미 사용, 미 분류
|
||||
@Deprecated
|
||||
// 레거시/미사용 — Event 핸들러 클래스 호환을 위해 유지 (실제 발송 없음)
|
||||
API_APPROVED("API 승인 알림", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
API_REJECTED("API 거절 알림", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
APP_REGISTER("앱 등록 완료", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
USER_MANAGER_ASSIGNED("관리자 권한 부여", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
REQUEST_AUTH_NUMBER("인증번호 요청", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
USER_WITHDRAWAL_APPROVED("계정 비활성화", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
USER_ACTIVATION("사용자 활성화 완료", null, Channels.NONE), // 이게 왜...이메일 인증인건데........
|
||||
|
||||
@Deprecated
|
||||
APP_REGISTER_REQUEST("앱 등록 요청", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
APP_REGISTER_REJECTED("앱 등록 거절", null, Channels.NONE),
|
||||
UNKNOWN_ERROR("알수 없는 에러 발생", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
PASSWORD_RESET_COMPLETE("비밀번호 변경 완료", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
REQUEST_PASSWORD_RESET("비밀번호 초기화 요청", null, Channels.NONE),
|
||||
|
||||
@Deprecated // 정확한 용도 모름
|
||||
USER_REGISTRATION_APPROVED("사용자 등록 승인 완료", null, Channels.NONE),
|
||||
|
||||
@Deprecated // 정확한 용도 모름
|
||||
USER_REGISTRATION_DENIED("사용자 등록 거절", null, Channels.NONE),
|
||||
|
||||
|
||||
@Deprecated // 정확한 용도 모름
|
||||
USER_REGISTRATION_REQUEST_ADMIN("사용자 등록 승인 요청", null, Channels.NONE),
|
||||
|
||||
@Deprecated // 정확한 용도 모름
|
||||
USER_REGISTRATION_DENIED("사용자 등록 거절", null, Channels.NONE),
|
||||
USER_REGISTRATION_REQUEST_USER("사용자 등록 요청 완료", null, Channels.NONE),
|
||||
|
||||
@Deprecated
|
||||
REQUEST_PASSWORD_RESET("비밀번호 초기화 요청", null, Channels.NONE),
|
||||
USER_MANAGER_ASSIGNED("관리자 권한 부여", null, Channels.NONE),
|
||||
USER_REGISTRATION_APPROVED("사용자 등록 승인 완료", null, Channels.NONE),
|
||||
PASSWORD_RESET_COMPLETE("비밀번호 변경 완료", null, Channels.NONE),
|
||||
INQUIRY_RESPONSE("QnA 답변 작성", null, Channels.NONE)
|
||||
;
|
||||
|
||||
@@ -98,7 +60,8 @@ public enum MessageCode {
|
||||
@Getter
|
||||
private final String serviceId;
|
||||
@Getter
|
||||
private final int channels;
|
||||
@Deprecated // 삭제 예정
|
||||
private int channels = 0;
|
||||
|
||||
|
||||
public static Optional<MessageCode> findServiceId(String code) {
|
||||
@@ -110,6 +73,11 @@ public enum MessageCode {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
MessageCode(String description, String serviceId) {
|
||||
this.description = description;
|
||||
this.serviceId = serviceId;
|
||||
// this.channels = channel.getValue();
|
||||
}
|
||||
|
||||
MessageCode(String description, String serviceId, Channels channel) {
|
||||
this.description = description;
|
||||
@@ -122,7 +90,7 @@ public enum MessageCode {
|
||||
NONE (0b0000),
|
||||
EMAIL (0b0001),
|
||||
KAKAO_ALIMTALK (0b0010),
|
||||
MESSENGER (0b0100),
|
||||
SWING (0b0100),
|
||||
;
|
||||
|
||||
@Getter
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.eactive.apim.portal.template.entity;
|
||||
|
||||
|
||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUser;
|
||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||
import kjb.safedb.KjbNotRnnoJpaAttributeConverter;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
@@ -53,20 +53,23 @@ public class MessageRequest implements Serializable {
|
||||
|
||||
private String username;
|
||||
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String email;
|
||||
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String phone;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private String userId;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "user_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
@JoinColumn(name = "user_id", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||
@NotFound(action = NotFoundAction.IGNORE)
|
||||
@Comment("발송 대상 사용자")
|
||||
private PortalUser user;
|
||||
|
||||
@Comment("UMS 연계용 UID")
|
||||
@Column(name="ums_uid", length = 16)
|
||||
@Column(name="ums_uid", length = 36)
|
||||
private String umsUid;
|
||||
|
||||
@Column(name = "messenger_id")
|
||||
@@ -80,5 +83,4 @@ public class MessageRequest implements Serializable {
|
||||
|
||||
@Column(name = "service_id")
|
||||
private String serviceId;
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ import lombok.*;
|
||||
@Builder
|
||||
public class MessageRecipient {
|
||||
private String username;
|
||||
private String userId; //email
|
||||
private String userId;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String messengerId;
|
||||
|
||||
@@ -19,7 +20,8 @@ public class MessageRecipient {
|
||||
public static MessageRecipient of(PortalUser user) {
|
||||
MessageRecipient recipient = new MessageRecipient();
|
||||
recipient.setUsername(user.getUserName());
|
||||
recipient.setUserId(user.getEmailAddr());
|
||||
recipient.setUserId(user.getLoginId());
|
||||
recipient.setEmail(user.getEmailAddr());
|
||||
recipient.setPhone(user.getPhoneNumber());
|
||||
return recipient;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class MessageSendService {
|
||||
List<MessageRecipient> recipients = new ArrayList<>();
|
||||
|
||||
for (UserInfo user : template.getAdditionalRecipients()) {
|
||||
MessageRecipient messageRecipient = new MessageRecipient(user.getUsername(), user.getUserid(), user.getCphnno(), user.getUserid());
|
||||
MessageRecipient messageRecipient = new MessageRecipient(user.getUsername(), user.getUserid(), user.getEmad(), user.getCphnno(), user.getUserid());
|
||||
recipients.add(messageRecipient);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class MessageSendService {
|
||||
String subject = buildMessage(template.getSubjectTemplate(), messageParams);
|
||||
|
||||
if (template.getEnableSms().equalsIgnoreCase("Y")) {
|
||||
String smsEaiInterfaceId = portalProperties.get("message.integration.eaiId.sms");
|
||||
String smsEaiInterfaceId = portalProperties.get("ums.sms.if_id");
|
||||
MessageRequest smsRequest = new MessageRequest();
|
||||
smsRequest.setMessageCode(MessageCode.valueOf(template.getMessageCode().toUpperCase()));
|
||||
smsRequest.setSubject(subject);
|
||||
@@ -88,14 +88,19 @@ public class MessageSendService {
|
||||
smsRequest.setUsername(user.getUsername());
|
||||
smsRequest.setPhone(user.getPhone());
|
||||
smsRequest.setEaiInterfaceId(smsEaiInterfaceId);
|
||||
smsRequest.setServiceId(portalProperties.get("message.integration.template.sms." + template.getMessageCode()));
|
||||
smsRequest.setMessageType("KAKAO");
|
||||
smsRequest.setServiceId(portalProperties.get("ums.sms.tx_id"));
|
||||
smsRequest.setUserId(user.getUserId());
|
||||
if ("ADMIN_VERIFICATION_MOBILEPHONE".equals(template.getMessageCode().toUpperCase())) {
|
||||
smsRequest.setMessageType("KAKAO");
|
||||
} else {
|
||||
smsRequest.setMessageType("SMS");
|
||||
}
|
||||
messageRequestRepository.save(smsRequest);
|
||||
logger.debug(smsRequest.toString());
|
||||
}
|
||||
|
||||
if (template.getEnableEmail().equalsIgnoreCase("Y")) {
|
||||
String mailEaiInterfaceId = portalProperties.get("message.integration.eaiId.email");
|
||||
String mailEaiInterfaceId = portalProperties.get("ums.email.if_id");
|
||||
MessageRequest emailRequest = new MessageRequest();
|
||||
emailRequest.setMessageCode(MessageCode.valueOf(template.getMessageCode().toUpperCase()));
|
||||
emailRequest.setSubject(subject);
|
||||
@@ -105,13 +110,15 @@ public class MessageSendService {
|
||||
emailRequest.setUsername(user.getUsername());
|
||||
emailRequest.setEmail(user.getUserId());
|
||||
emailRequest.setEaiInterfaceId(mailEaiInterfaceId);
|
||||
emailRequest.setServiceId(portalProperties.get("message.integration.template.email." + template.getMessageCode()));
|
||||
emailRequest.setServiceId(portalProperties.get("ums.email.tx_id"));
|
||||
emailRequest.setMessageType("EMAIL");
|
||||
emailRequest.setUserId(user.getUserId());
|
||||
messageRequestRepository.save(emailRequest);
|
||||
logger.debug(emailRequest.toString());
|
||||
}
|
||||
|
||||
if (template.getEnableMessenger().equalsIgnoreCase("Y")) {
|
||||
String swingEaiInterfaceId = portalProperties.get("ums.messenger.if_id");
|
||||
MessageRequest messengerRequest = new MessageRequest();
|
||||
messengerRequest.setMessageCode(MessageCode.valueOf(template.getMessageCode()));
|
||||
messengerRequest.setSubject(subject);
|
||||
@@ -120,15 +127,24 @@ public class MessageSendService {
|
||||
messengerRequest.setRequestDate(LocalDateTime.now());
|
||||
messengerRequest.setUsername(user.getUsername());
|
||||
messengerRequest.setMessengerId(user.getUserId());
|
||||
messengerRequest.setEaiInterfaceId(swingEaiInterfaceId);
|
||||
messengerRequest.setServiceId(portalProperties.get("ums.messenger.tx_id"));
|
||||
messengerRequest.setMessageType("MESSENGER");
|
||||
messengerRequest.setUserId(user.getUserId());
|
||||
messageRequestRepository.save(messengerRequest);
|
||||
logger.debug(messengerRequest.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateMessageParams(MessageRecipient user, Map<String, String> messageParams) {
|
||||
// 공통 자동주입. 대문자 별칭(USER_ID/USER_NAME)은 DB 템플릿 변수 표기와 맞춘다.
|
||||
// putIfAbsent 이므로 개별 이벤트(createEvent)가 먼저 넣은 값이 있으면 그대로 둔다(오버라이드).
|
||||
messageParams.put("userId", user.getUserId());
|
||||
messageParams.putIfAbsent("USER_ID", user.getUserId());
|
||||
|
||||
if (StringUtils.hasText(user.getUsername())) {
|
||||
messageParams.put("userName", user.getUsername());
|
||||
messageParams.putIfAbsent("USER_NAME", user.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
package com.eactive.apim.portal.user.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Convert;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||
import com.eactive.eai.data.converter.StringTrimConverter;
|
||||
import com.eactive.eai.data.entity.AbstractEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
|
||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||
import com.eactive.eai.data.converter.StringTrimConverter;
|
||||
import com.eactive.eai.data.entity.AbstractEntity;
|
||||
import kjb.safedb.KjbNotRnnoJpaAttributeConverter;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true)
|
||||
@@ -54,7 +47,7 @@ public class UserInfo extends AbstractEntity<String> implements Serializable {
|
||||
|
||||
@Column(length = 40)
|
||||
@Comment("휴대폰 번호")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String cphnno;
|
||||
|
||||
@Column(length = 40)
|
||||
@@ -63,7 +56,7 @@ public class UserInfo extends AbstractEntity<String> implements Serializable {
|
||||
|
||||
@Column(length = 100)
|
||||
@Comment("이메일 주소")
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String emad;
|
||||
|
||||
@Column(length = 3)
|
||||
@@ -147,4 +140,12 @@ public class UserInfo extends AbstractEntity<String> implements Serializable {
|
||||
public @NonNull String getId() {
|
||||
return userid;
|
||||
}
|
||||
|
||||
/** 저장 시 전화번호를 하이픈 구분 정규형으로 통일 */
|
||||
@PrePersist
|
||||
@PreUpdate
|
||||
private void normalizePhones() {
|
||||
this.cphnno = PhoneNumberUtil.normalize(this.cphnno);
|
||||
this.ofctelno = PhoneNumberUtil.normalize(this.ofctelno);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
package com.eactive.apim.portal.user.entity;
|
||||
|
||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||
import java.time.LocalDateTime;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Convert;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.TableGenerator;
|
||||
|
||||
import kjb.safedb.KjbNotRnnoJpaAttributeConverter;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@TableGenerator(
|
||||
name = "USER_LOGIN_LOG_GEN",
|
||||
table = "PTL_ID",
|
||||
@@ -32,7 +25,7 @@ public class UserLog {
|
||||
private Long logId;
|
||||
|
||||
@Column(name = "login_id", nullable = false)
|
||||
@Convert(converter = KjbNotRnnoJpaAttributeConverter.class)
|
||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||
private String loginId;
|
||||
|
||||
@Column(name = "login_time")
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
package kjb.safedb;
|
||||
|
||||
//import com.eactive.ext.kjb.safedb.KjbSafedbWrapper;
|
||||
//import com.eactive.ext.kjb.safedb.SafeDBColumns;
|
||||
//import com.eactive.ext.kjb.safedb.Utils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.AttributeConverter;
|
||||
import javax.persistence.Converter;
|
||||
|
||||
@Converter
|
||||
@Slf4j
|
||||
public class KjbNotRnnoJpaAttributeConverter implements AttributeConverter<String, String> {
|
||||
private static final Logger needFixLogger = LoggerFactory.getLogger("eapim.portal.needfix");
|
||||
|
||||
/**
|
||||
* 암호화
|
||||
* @param attribute the entity attribute value to be converted
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String convertToDatabaseColumn(String attribute) {
|
||||
// log.debug("DB 암호화 #1 - {} / {}", attribute, SafeDBColumns.NOT_RNNO);
|
||||
|
||||
// String originalAttribute = attribute;
|
||||
// if (StringUtils.isNotEmpty(attribute)) {
|
||||
// KjbSafedbWrapper wrapper = KjbSafedbWrapper.getInstance();
|
||||
// attribute = wrapper.encryptNotRnnoString(attribute);
|
||||
//
|
||||
// if (log.isDebugEnabled()) {
|
||||
// // originalAttribute 홀수 글자 마스킹
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (int i = 0; i < originalAttribute.length(); i++) {
|
||||
// if (i % 2 == 0) {
|
||||
// sb.append(originalAttribute.charAt(i));
|
||||
// } else {
|
||||
// sb.append("*");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// originalAttribute = sb.toString();
|
||||
// log.debug("DB 암호화 #2 : {} -> {}", originalAttribute, attribute);
|
||||
// }
|
||||
// }
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* 복호화
|
||||
* @param dbData the data from the database column to be
|
||||
* converted
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String convertToEntityAttribute(String dbData) {
|
||||
// log.debug("DB 복호화 #1 - {} / {}", dbData, SafeDBColumns.NOT_RNNO);
|
||||
|
||||
// String dbDataOriginal = dbData;
|
||||
// if (StringUtils.isNotEmpty(dbData)) {
|
||||
// if (this.isEncrypted(dbData)) {
|
||||
// KjbSafedbWrapper safeDBWrapper = KjbSafedbWrapper.getInstance();
|
||||
// try {
|
||||
// dbData = safeDBWrapper.decryptNotRnno(dbData);
|
||||
// } catch (Exception e) {
|
||||
// // 복호화 실패시 원본 반환
|
||||
// String logData = dbData.length() <= 3 ? dbData : dbData.substring(0, 3) + "...";
|
||||
// log.warn("DB 복호화 실패: 복호화하지 않고 원본 반환. dbData={} (Length : {})", logData, dbData.length());
|
||||
// needFixLogger.warn("DB 복호화 실패: 복호화하지 않고 원본 반환. dbData={} (Length : {})", logData, dbData.length(), e);
|
||||
// return dbData;
|
||||
// }
|
||||
// } else {
|
||||
// log.debug("DB 복호화 경고: Base64 형식이 아님. 복호화하지 않고 원본 반환. dbData={}", dbData);
|
||||
// }
|
||||
// }
|
||||
|
||||
// log.debug("DB 복호화 #2 : {} -> {}", dbDataOriginal, dbData);
|
||||
|
||||
return dbData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 암호화 여부 확인(base64 인코딩 여부로 판단, 또는 0-9, - 로 구성된 경우 암호화 되지 않은 걸로 판단(연락처))
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
private boolean isEncrypted(String data) {
|
||||
// if (StringUtils.isEmpty(data)) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // 숫자, - 로만 구성된 경우 암호화 되지 않은 걸로 판단 (ex: 연락처)
|
||||
// if (data.matches("^[0-9-]+$")) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// data = data.trim();
|
||||
//
|
||||
// // Base64 형식 체크
|
||||
// if (!Utils.isBase64(data)) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// // Base64 길이 체크 (4의 배수)
|
||||
// if (data.length() % 4 != 0) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user