- 로그인 중복 세션 확인 및 기존 세션 강제 로그아웃 처리 추가
- 세션 타이머 데스크톱·모바일 표시 및 경고 스타일 동기화
This commit is contained in:
@@ -5333,6 +5333,14 @@ select.form-control {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.session-timer-mobile {
|
||||
margin-right: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.session-timer-mobile .session-timer-text {
|
||||
min-width: 34px;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
background: #FFFFFF;
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -31,3 +31,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 모바일 헤더(햄버거 버튼 좌측)용 타이머
|
||||
.session-timer-mobile {
|
||||
margin-right: $spacing-sm;
|
||||
font-size: $font-size-xs;
|
||||
|
||||
.session-timer-text {
|
||||
min-width: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,36 @@
|
||||
form.checkId.checked = ((form.id.value = getCookie('saveid')) !== null);
|
||||
}
|
||||
|
||||
// 로그인 전 중복 접속 확인 → 중복 시 기존 세션 강제 로그아웃 여부 질의
|
||||
function checkDuplicateAndLogin(form) {
|
||||
var loginId = form.id.value;
|
||||
$.ajax({
|
||||
url: /*[[@{/api/session/check-duplicate}]]*/ '/api/session/check-duplicate',
|
||||
type: 'POST',
|
||||
data: { loginId: loginId },
|
||||
success: function (data) {
|
||||
if (data && data.duplicateSession) {
|
||||
$('#loginLoading').removeClass('active');
|
||||
var msg = '해당 계정은 이미 다른 곳(' + data.ipAddress + ')에서 접속 중입니다.<br>'
|
||||
+ '접속 시각: ' + data.loginTime + '<br><br>'
|
||||
+ '기존 접속을 해제하고 로그인하시겠습니까?';
|
||||
customPopups.showConfirm(msg, function (confirmed) {
|
||||
if (confirmed) {
|
||||
$('#loginLoading').addClass('active');
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
// 중복 체크 실패 시 로그인은 그대로 진행
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fnInit() {
|
||||
let form = document.getElementById('loginForm');
|
||||
if (form) {
|
||||
@@ -179,7 +209,7 @@
|
||||
$('#loginLoading').removeClass('active');
|
||||
customPopups.showAlert('[[#{login.passLengthShort}]]');
|
||||
} else {
|
||||
form.submit();
|
||||
checkDuplicateAndLogin(form);
|
||||
}
|
||||
}
|
||||
form.classList.add('was-validated');
|
||||
|
||||
@@ -107,6 +107,10 @@
|
||||
</div>
|
||||
|
||||
<div class="mobile-right">
|
||||
<span class="session-timer session-timer-mobile" sec:authorize="isAuthenticated()" title="남은 세션 시간">
|
||||
<i class="fas fa-clock session-timer-icon"></i>
|
||||
<span class="session-timer-text">--:--</span>
|
||||
</span>
|
||||
<button class="mobile-menu-btn" id="mobileMenuToggle" aria-label="메뉴">
|
||||
<span class="hamburger-line"></span>
|
||||
<span class="hamburger-line"></span>
|
||||
@@ -261,7 +265,8 @@
|
||||
var WARNING_SECONDS = 60; // 만료 60초 전 연장 확인 모달
|
||||
var POLL_INTERVAL_MS = 30000; // 서버 잔여시간 동기화 주기
|
||||
|
||||
var timerText = document.getElementById('sessionRemainingTime');
|
||||
// 데스크톱·모바일 타이머 텍스트를 모두 갱신 (id 대신 클래스 사용)
|
||||
var timerTexts = document.querySelectorAll('.session-timer-text');
|
||||
var countdownTimer = null;
|
||||
var promptShown = false; // 연장 확인 모달 중복 표시 방지
|
||||
var redirecting = false;
|
||||
@@ -284,12 +289,16 @@
|
||||
}
|
||||
|
||||
function render() {
|
||||
if (!timerText) return;
|
||||
timerText.textContent = formatTime(remainingSeconds);
|
||||
if (remainingSeconds <= WARNING_SECONDS) {
|
||||
timerText.classList.add('session-timer-warning');
|
||||
} else {
|
||||
timerText.classList.remove('session-timer-warning');
|
||||
if (!timerTexts.length) return;
|
||||
var label = formatTime(remainingSeconds);
|
||||
var warn = remainingSeconds <= WARNING_SECONDS;
|
||||
for (var i = 0; i < timerTexts.length; i++) {
|
||||
timerTexts[i].textContent = label;
|
||||
if (warn) {
|
||||
timerTexts[i].classList.add('session-timer-warning');
|
||||
} else {
|
||||
timerTexts[i].classList.remove('session-timer-warning');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user