충돌 해결
This commit is contained in:
@@ -369,12 +369,12 @@ page:
|
||||
credential_detail:
|
||||
name: "인증키 정보"
|
||||
path: "/myapikey/credential_detail"
|
||||
change_password:
|
||||
password_verify:
|
||||
name: "비밀번호 변경"
|
||||
path: "/change_password"
|
||||
verify_current_password:
|
||||
path: "/password/verify"
|
||||
password_change:
|
||||
name: "비밀번호 변경"
|
||||
path: "/verify_current_password"
|
||||
path: "/password/change"
|
||||
myapikey_register_step1:
|
||||
name: "앱 생성 (기본 정보)"
|
||||
path: "/myapikey/register/step1"
|
||||
|
||||
@@ -69,6 +69,24 @@
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- ERROR 레벨만 별도 수집(스택 트레이스 포함). 장애 원인 추적용. -->
|
||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/error.log</file>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/backup/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<maxFileSize>200MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>${CONSOLE_EFFECTIVE_LEVEL}</level>
|
||||
@@ -89,12 +107,14 @@
|
||||
<root level="INFO">
|
||||
<appender-ref ref="ROLLING"/>
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="ERROR_FILE"/>
|
||||
</root>
|
||||
|
||||
<springProfile name="dev">
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="ROLLING"/>
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="ERROR_FILE"/>
|
||||
</root>
|
||||
</springProfile>
|
||||
</configuration>
|
||||
@@ -39,7 +39,7 @@ deptUserManageRegister.id=Department User ID
|
||||
deptUserManageRegister.name=Department User Name
|
||||
portalUser.confirm.password=Please enter your existing password
|
||||
portalUser.Register.userName=Name
|
||||
portalUser.Register.pass=Password (Combination of uppercase letters, lowercase letters, numbers, special characters, 8-20 characters)
|
||||
portalUser.Register.pass=Password (Combination of uppercase letters, lowercase letters, numbers, special characters, 8-50 characters)
|
||||
portalUser.Register.passConfirm=Confirm Password
|
||||
portalUser.Register.email=Email ID
|
||||
portalUser.Register.domain=Domain
|
||||
|
||||
@@ -39,7 +39,7 @@ deptUserManageRegister.name=\uBD80\uC11C \uC0AC\uC6A9\uC790 \uC774\uB984
|
||||
entrprsUserManageList.regName=\uBC95\uC778 \uC0AC\uC6A9\uC790 \uB4F1\uB85D \uC774\uB984
|
||||
portalUser.confirm.password=\uAE30\uC874 \uBE44\uBC00\uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694
|
||||
portalUser.Register.userName=\uC774\uB984
|
||||
portalUser.Register.pass=\uC601\uBB38 \uB300\uBB38\uC790,\uC601\uBB38 \uC18C\uBB38\uC790,\uC22B\uC790,\uD2B9\uC218\uBB38\uC790 \uC870\uD569 8-20\uC790
|
||||
portalUser.Register.pass=\uC601\uBB38 \uB300\uBB38\uC790,\uC601\uBB38 \uC18C\uBB38\uC790,\uC22B\uC790,\uD2B9\uC218\uBB38\uC790 \uC870\uD569 8-50\uC790
|
||||
portalUser.Register.passConfirm=\uBE44\uBC00\uBC88\uD638 \uD655\uC778
|
||||
portalUser.Register.email=\uC774\uBA54\uC77C \uC544\uC774\uB514
|
||||
portalUser.Register.domain=\uB3C4\uBA54\uC778
|
||||
|
||||
@@ -7571,6 +7571,69 @@ button.djb-comment-submit:disabled {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.password-policy-checklist {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 12px 0 0 0;
|
||||
}
|
||||
.password-policy-checklist li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 6px;
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
.password-policy-checklist li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.password-policy-checklist li .policy-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
.password-policy-checklist li .policy-icon::before {
|
||||
content: "•";
|
||||
}
|
||||
.password-policy-checklist li.is-idle {
|
||||
color: #888;
|
||||
}
|
||||
.password-policy-checklist li.is-idle .policy-icon {
|
||||
color: #b5b5b5;
|
||||
}
|
||||
.password-policy-checklist li.is-pass {
|
||||
color: #1a8f4c;
|
||||
}
|
||||
.password-policy-checklist li.is-pass .policy-icon {
|
||||
color: #1a8f4c;
|
||||
}
|
||||
.password-policy-checklist li.is-pass .policy-icon::before {
|
||||
content: "✔";
|
||||
}
|
||||
.password-policy-checklist li.is-fail {
|
||||
color: #d63a3a;
|
||||
}
|
||||
.password-policy-checklist li.is-fail .policy-icon {
|
||||
color: #d63a3a;
|
||||
}
|
||||
.password-policy-checklist li.is-fail .policy-icon::before {
|
||||
content: "✖";
|
||||
}
|
||||
|
||||
.password-policy-note {
|
||||
margin: 10px 0 0 0;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.hero-carousel-section {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@@ -17995,6 +18058,12 @@ input[type=checkbox]:checked + .custom-checkbox {
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
.detail-wrap .dt-cancel-notice {
|
||||
margin: 10px 0 0;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #64748b;
|
||||
}
|
||||
.detail-wrap .dt-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
File diff suppressed because one or more lines are too long
+28404
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 비밀번호 문자열 정책 라이브 검증 (공용)
|
||||
*
|
||||
* 서버 검증기 PasswordRuleValidator.isValid(= @PasswordRule) 의
|
||||
* "문자열" 규칙을 그대로 클라이언트로 포팅한다. 아이디/휴대전화 포함 여부는
|
||||
* 민감정보 노출을 피하기 위해 서버 검증에만 맡긴다.
|
||||
*
|
||||
* 사용법(마크업 구동):
|
||||
* <ul class="password-policy-checklist" data-password-input="newPassword">
|
||||
* <li data-rule="length" class="is-idle"><span class="policy-icon"></span><span class="policy-text">...</span></li>
|
||||
* ... (rule: length | letter | digit | special | nospace | norepeat | noseq)
|
||||
* </ul>
|
||||
* <input type="password" id="newPassword" ...>
|
||||
*
|
||||
* DOM ready 시 자동으로 스캔하여 대상 input 에 바인딩한다.
|
||||
*/
|
||||
(function (global) {
|
||||
'use strict';
|
||||
|
||||
// 3자리 연속(오름/내림) 문자·숫자 검사 — 서버 로직과 동일하게 대문자로 비교
|
||||
function hasSequential(pw) {
|
||||
var s = pw.toUpperCase();
|
||||
for (var i = 0; i < s.length - 2; i++) {
|
||||
var a = s.charCodeAt(i), b = s.charCodeAt(i + 1), c = s.charCodeAt(i + 2);
|
||||
var sameCategory = (a > 47 && c < 58) || (a > 64 && c < 91); // 숫자 0-9 또는 영문 A-Z
|
||||
var consecutive = Math.abs(c - b) === 1 && Math.abs(c - a) === 2;
|
||||
if (sameCategory && consecutive) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 규칙별 판정 함수 (통과=true)
|
||||
var RULES = {
|
||||
length: function (pw) { return pw.length >= 8 && pw.length <= 50; },
|
||||
letter: function (pw) { return /[a-zA-Z]/.test(pw); },
|
||||
digit: function (pw) { return /[0-9]/.test(pw); },
|
||||
special: function (pw) { return /[^A-Za-z0-9_]/.test(pw); }, // 서버 정규식 \W 기준 (밑줄 제외)
|
||||
nospace: function (pw) { return !/\s/.test(pw); },
|
||||
norepeat: function (pw) { return !/(\w)\1\1/.test(pw.toUpperCase()); },
|
||||
noseq: function (pw) { return !hasSequential(pw); }
|
||||
};
|
||||
|
||||
// 전체 문자열 규칙 통과 여부
|
||||
function isValid(pw) {
|
||||
if (!pw) {
|
||||
return false;
|
||||
}
|
||||
for (var key in RULES) {
|
||||
if (RULES.hasOwnProperty(key) && !RULES[key](pw)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 체크리스트(ul) 하나를 대상 input 에 바인딩
|
||||
function bind(input, list) {
|
||||
var $input = (input && input.jquery) ? input : $(input);
|
||||
var $list = (list && list.jquery) ? list : $(list);
|
||||
var $items = $list.find('li[data-rule]');
|
||||
if (!$input.length || !$items.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
function update() {
|
||||
var pw = $input.val() || '';
|
||||
$items.each(function () {
|
||||
var $li = $(this);
|
||||
var rule = RULES[$li.attr('data-rule')];
|
||||
if (!rule) {
|
||||
return;
|
||||
}
|
||||
$li.removeClass('is-idle is-pass is-fail');
|
||||
if (pw.length === 0) {
|
||||
$li.addClass('is-idle');
|
||||
} else {
|
||||
$li.addClass(rule(pw) ? 'is-pass' : 'is-fail');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$input.on('input.passwordPolicy', update);
|
||||
update();
|
||||
}
|
||||
|
||||
// 마크업 구동 자동 초기화
|
||||
function init(root) {
|
||||
var $root = root ? $(root) : $(document);
|
||||
$root.find('ul.password-policy-checklist[data-password-input]').each(function () {
|
||||
var $list = $(this);
|
||||
var input = document.getElementById($list.attr('data-password-input'));
|
||||
if (input) {
|
||||
bind(input, $list);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
global.PasswordPolicy = {
|
||||
RULES: RULES,
|
||||
isValid: isValid,
|
||||
bind: bind,
|
||||
init: init
|
||||
};
|
||||
|
||||
$(function () {
|
||||
init(document);
|
||||
});
|
||||
})(window);
|
||||
@@ -0,0 +1,75 @@
|
||||
// 비밀번호 문자열 정책 라이브 체크리스트 (마이페이지 비밀번호 변경 + 회원가입 공용)
|
||||
.password-policy-checklist {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 12px 0 0 0;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 6px;
|
||||
transition: color 0.15s ease;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.policy-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex-shrink: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
|
||||
&::before {
|
||||
content: "\2022"; // •
|
||||
}
|
||||
}
|
||||
|
||||
&.is-idle {
|
||||
color: #888;
|
||||
|
||||
.policy-icon {
|
||||
color: #b5b5b5;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-pass {
|
||||
color: #1a8f4c;
|
||||
|
||||
.policy-icon {
|
||||
color: #1a8f4c;
|
||||
|
||||
&::before {
|
||||
content: "\2714"; // ✔
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-fail {
|
||||
color: #d63a3a;
|
||||
|
||||
.policy-icon {
|
||||
color: #d63a3a;
|
||||
|
||||
&::before {
|
||||
content: "\2716"; // ✖
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.password-policy-note {
|
||||
margin: 10px 0 0 0;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
color: #888;
|
||||
}
|
||||
@@ -44,6 +44,7 @@
|
||||
@use 'components/breadcrumb' as *;
|
||||
@use 'components/test-env-notice' as *;
|
||||
@use 'components/djb-inquiry-comments' as *;
|
||||
@use 'components/password-policy' as *;
|
||||
|
||||
// 5. Page-specific styles
|
||||
@use 'pages/index' as *;
|
||||
|
||||
@@ -1232,6 +1232,14 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// 내부 결재 진행중: 신청 취소 불가 안내
|
||||
.dt-cancel-notice {
|
||||
margin: 10px 0 0;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
// Footer Buttons layout
|
||||
.dt-actions {
|
||||
display: flex;
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
<!-- Status Badge -->
|
||||
<span class="app-card-badge"
|
||||
th:classappend="${request.approval != null and request.approval.approvalStatus != null and request.approval.approvalStatus.toString() == 'REQUESTED' ? 'badge-requested' : 'badge-pending'}"
|
||||
th:text="${request.approval != null and request.approval.approvalStatus != null ? request.approval.approvalStatus.description : '승인대기'}">
|
||||
승인대기
|
||||
th:text="${request.approval != null and request.approval.approvalStatus != null ? request.approval.approvalStatus.description : '승인정보 없음'}">
|
||||
승인정보 없음
|
||||
</span>
|
||||
</div>
|
||||
<!-- App Description & Expected Completion Date -->
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
대기중
|
||||
</span>
|
||||
</div>
|
||||
<div class="dt-app-status-row" th:if="${appRequest.approval == null}">
|
||||
<span class="dt-status-badge status-pending">승인정보 없음</span>
|
||||
</div>
|
||||
<h3 class="dt-app-name" th:text="${appRequest.clientName}">앱 이름</h3>
|
||||
<!-- App Description -->
|
||||
<p class="dt-app-desc"
|
||||
@@ -200,12 +203,19 @@
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 내부 결재 진행중: 취소 불가 안내 -->
|
||||
<p class="dt-cancel-notice" sec:authorize="hasRole('ROLE_API_KEY_REQUEST')"
|
||||
th:if="${appRequest.approval != null and appRequest.approval.approvalStatus != null and
|
||||
appRequest.approval.approvalStatus.toString() == 'PROCESSING'}">
|
||||
내부 결재가 진행 중이라 신청을 취소할 수 없습니다. 취소가 필요한 경우 관리자에게 문의해 주세요.
|
||||
</p>
|
||||
|
||||
<!-- Bottom Navigation Actions -->
|
||||
<div class="dt-actions">
|
||||
<!-- Cancel Request Button (danger red) -->
|
||||
<button type="button" sec:authorize="hasRole('ROLE_API_KEY_REQUEST')" class="dt-btn-red"
|
||||
th:if="${appRequest.approval != null and appRequest.approval.approvalStatus != null and
|
||||
(appRequest.approval.approvalStatus.toString() == 'PENDING' or appRequest.approval.approvalStatus.toString() == 'REQUESTED')}"
|
||||
th:if="${appRequest.approval == null or (appRequest.approval.approvalStatus != null and
|
||||
(appRequest.approval.approvalStatus.toString() == 'PENDING' or appRequest.approval.approvalStatus.toString() == 'REQUESTED'))}"
|
||||
th:data-request-id="${appRequest.id}" onclick="cancelRequestById(this)">
|
||||
신청 취소
|
||||
</button>
|
||||
|
||||
@@ -51,16 +51,6 @@
|
||||
<!-- Credential Info Section Card -->
|
||||
<div class="dt-info-container">
|
||||
|
||||
<!-- 인증 방식 -->
|
||||
<div class="dt-row">
|
||||
<div class="dt-col">
|
||||
<label class="dt-label">인증 방식</label>
|
||||
<div class="dt-input-group">
|
||||
<div class="dt-input-box" th:text="${authType}">OAuth2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Client ID -->
|
||||
<div class="dt-row">
|
||||
<div class="dt-col">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<a class="nav-link" th:href="@{/my_company_info}">기업 정보 변경</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" th:href="@{/change_password}">비밀번호 변경</a>
|
||||
<a class="nav-link active" th:href="@{/password/verify}">비밀번호 변경</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="card mt-2">
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="password-change-wrapper">
|
||||
<h2 class="page-outer-title">비밀번호 변경</h2>
|
||||
|
||||
<form id="passwordChangeForm" th:action="@{/mypage/change_new_password}" method="post">
|
||||
<form id="passwordChangeForm" th:action="@{/password/change}" method="post">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
|
||||
|
||||
<div class="register-form-container">
|
||||
@@ -37,7 +37,7 @@
|
||||
<span class="form-label-text">새 비밀번호</span>
|
||||
</div>
|
||||
<div class="form-field-wrapper">
|
||||
<input type="password" name="newPassword" class="form-input"
|
||||
<input type="password" id="newPassword" name="newPassword" class="form-input"
|
||||
placeholder="새 비밀번호 입력" required>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,10 +52,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="password-rules-list">
|
||||
<li>영문 대문자, 소문자, 숫자, 특수문자 8~20자</li>
|
||||
<li>아이디, 휴대전화, 3자리 이상연속, 반복문자 사용불가</li>
|
||||
<ul class="password-policy-checklist" data-password-input="newPassword">
|
||||
<li data-rule="length" class="is-idle"><span class="policy-icon"></span><span class="policy-text">영문/숫자/특수문자 포함 8~50자</span></li>
|
||||
<li data-rule="letter" class="is-idle"><span class="policy-icon"></span><span class="policy-text">영문 포함</span></li>
|
||||
<li data-rule="digit" class="is-idle"><span class="policy-icon"></span><span class="policy-text">숫자 포함</span></li>
|
||||
<li data-rule="special" class="is-idle"><span class="policy-icon"></span><span class="policy-text">특수문자 포함</span></li>
|
||||
<li data-rule="nospace" class="is-idle"><span class="policy-icon"></span><span class="policy-text">공백 사용 불가</span></li>
|
||||
<li data-rule="norepeat" class="is-idle"><span class="policy-icon"></span><span class="policy-text">동일 문자 3자리 이상 반복 불가</span></li>
|
||||
<li data-rule="noseq" class="is-idle"><span class="policy-icon"></span><span class="policy-text">연속된 문자/숫자 3자리 이상 불가</span></li>
|
||||
</ul>
|
||||
<p class="password-policy-note">아이디, 휴대전화 번호는 비밀번호에 사용할 수 없습니다.</p>
|
||||
</div>
|
||||
|
||||
<div class="form-actions" style="justify-content: flex-end;">
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="password-change-wrapper">
|
||||
<h2 class="page-outer-title">비밀번호 변경</h2>
|
||||
|
||||
<form th:action="@{/verify_current_password}" method="post">
|
||||
<form th:action="@{/password/verify}" method="post">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
|
||||
|
||||
<div class="register-form-container">
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
<div class="form-actions" style="justify-content: flex-end;">
|
||||
<div class="right-buttons">
|
||||
<button type="button" class="btn-cancel" th:onclick="|location.href='@{/}'|">취소</button>
|
||||
<button type="button" class="btn-cancel" th:unless="${forcedPasswordReset}" th:onclick="|location.href='@{/}'|">취소</button>
|
||||
<button type="submit" class="btn-apply btn-primary">확인</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,6 +55,26 @@
|
||||
customPopups.showAlert([[${error}]]);
|
||||
})
|
||||
</script>
|
||||
<script th:if="${forcedPasswordReset}" th:inline="javascript">
|
||||
// 비밀번호 재설정 강제(ENFORCE): "변경" 또는 "로그아웃"만 선택 가능
|
||||
$(function () {
|
||||
$('#customConfirmCloseButton').hide();
|
||||
$('#customConfirmYesButton').text('변경');
|
||||
$('#customConfirmNoButton').text('로그아웃');
|
||||
customPopups.showConfirm(
|
||||
'계정 보안을 위해 비밀번호 재설정이 필요합니다.<br>비밀번호를 변경하거나 로그아웃해 주세요.',
|
||||
function (selection) {
|
||||
if (selection) {
|
||||
// 변경: 팝업 닫고 현재 페이지(비밀번호 변경)에서 진행
|
||||
$('#customConfirmCloseButton').show();
|
||||
} else {
|
||||
// 로그아웃
|
||||
window.location.href = [[@{/actionLogout.do}]];
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -78,6 +78,16 @@
|
||||
th:placeholder="#{portalUser.Register.pass}">
|
||||
<input type="hidden" name="isPasswordValid" id="isPasswordValid"/>
|
||||
<div id="password-validation" class="org-validation-message"></div>
|
||||
<ul class="password-policy-checklist" data-password-input="password">
|
||||
<li data-rule="length" class="is-idle"><span class="policy-icon"></span><span class="policy-text">영문/숫자/특수문자 포함 8~50자</span></li>
|
||||
<li data-rule="letter" class="is-idle"><span class="policy-icon"></span><span class="policy-text">영문 포함</span></li>
|
||||
<li data-rule="digit" class="is-idle"><span class="policy-icon"></span><span class="policy-text">숫자 포함</span></li>
|
||||
<li data-rule="special" class="is-idle"><span class="policy-icon"></span><span class="policy-text">특수문자 포함</span></li>
|
||||
<li data-rule="nospace" class="is-idle"><span class="policy-icon"></span><span class="policy-text">공백 사용 불가</span></li>
|
||||
<li data-rule="norepeat" class="is-idle"><span class="policy-icon"></span><span class="policy-text">동일 문자 3자리 이상 반복 불가</span></li>
|
||||
<li data-rule="noseq" class="is-idle"><span class="policy-icon"></span><span class="policy-text">연속된 문자/숫자 3자리 이상 불가</span></li>
|
||||
</ul>
|
||||
<p class="password-policy-note">아이디, 휴대전화 번호는 비밀번호에 사용할 수 없습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
<script th:src="@{/plugins/jquery/jquery-3.7.1.min.js}"></script>
|
||||
<script th:src="@{/js/lodash.js}"></script>
|
||||
<script th:src="@{/js/common.js}"></script>
|
||||
<script th:src="@{/js/password-policy.js}"></script>
|
||||
<script th:src="@{/js/moment.min.js}"></script>
|
||||
<script th:src="@{/js/daterangepicker.js}"></script>
|
||||
<script th:src="@{/plugins/codemirror/codemirror.js}"></script>
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
<a th:href="@{/statistics/api}"><i class="fas fa-chart-bar"></i>이용 통계</a>
|
||||
</li>
|
||||
<li><a th:href="@{/mypage}"><i class="fas fa-user-circle"></i>내 정보 관리</a></li>
|
||||
<li><a th:href="@{/change_password}"><i class="fas fa-lock"></i>비밀번호 변경</a></li>
|
||||
<li><a th:href="@{/password/verify}"><i class="fas fa-lock"></i>비밀번호 변경</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -253,7 +253,7 @@
|
||||
<li sec:authorize="hasRole('ROLE_API_KEY_REQUEST')"><a th:href="@{/webhook}">Webhook 관리</a></li>
|
||||
<li sec:authorize="hasRole('ROLE_APP')"><a th:href="@{/statistics/api}">이용 통계</a></li>
|
||||
<li><a th:href="@{/mypage}">내 정보 관리</a></li>
|
||||
<li><a th:href="@{/change_password}">비밀번호 변경</a></li>
|
||||
<li><a th:href="@{/password/verify}">비밀번호 변경</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
th:classappend="${activeMenu == 'profile'} ? 'service-nav__item--active' : ''"
|
||||
class="service-nav__item">내정보 관리</a>
|
||||
|
||||
<a th:href="@{/change_password}"
|
||||
<a th:href="@{/password/verify}"
|
||||
th:classappend="${activeMenu == 'password'} ? 'service-nav__item--active' : ''"
|
||||
class="service-nav__item">비밀번호 변경</a>
|
||||
</th:block>
|
||||
|
||||
Reference in New Issue
Block a user