카카오톡 인앱 WebView는 서브도메인 간 쿠키를 공유하지 않아 tkds에서 로그인 후 tkfb로 리다이렉트 시 인증이 풀리는 문제. - sso-relay.js: URL hash의 _sso= 토큰을 로컬 쿠키+localStorage로 설정 - gateway dashboard: 로그인 후 redirect URL에 #_sso=<token> 추가 - 전 서비스 HTML: core JS 직전에 sso-relay.js 로드 (81개 파일) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
399 lines
11 KiB
HTML
399 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>비밀번호 변경 - TK 공장관리</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<link rel="stylesheet" href="/static/css/tkfb.css?v=2026040103">
|
|
|
|
<style>
|
|
/* 페이지 전용 스타일 */
|
|
.password-page {
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
padding: 40px 20px;
|
|
}
|
|
|
|
.page-title {
|
|
text-align: center;
|
|
margin-bottom: 40px;
|
|
}
|
|
|
|
.page-title h1 {
|
|
font-size: 2rem;
|
|
color: #333;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.page-title p {
|
|
color: #666;
|
|
font-size: 1.1rem;
|
|
}
|
|
|
|
/* 카드 스타일 */
|
|
.password-card {
|
|
background: white;
|
|
border-radius: 16px;
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.card-header {
|
|
background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
|
|
color: white;
|
|
padding: 24px 32px;
|
|
}
|
|
|
|
.card-header h2 {
|
|
margin: 0;
|
|
font-size: 1.5rem;
|
|
font-weight: 600;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.card-body {
|
|
padding: 32px;
|
|
}
|
|
|
|
/* 알림 박스 */
|
|
.info-box {
|
|
background: #e3f2fd;
|
|
border: 1px solid #90caf9;
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
margin-bottom: 28px;
|
|
}
|
|
|
|
.info-box h4 {
|
|
margin: 0 0 12px 0;
|
|
color: #1565c0;
|
|
font-size: 1rem;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.info-box ul {
|
|
margin: 0;
|
|
padding-left: 24px;
|
|
color: #0d47a1;
|
|
}
|
|
|
|
.info-box li {
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
/* 폼 스타일 */
|
|
.password-form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
}
|
|
|
|
.form-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.form-group label {
|
|
font-weight: 600;
|
|
color: #333;
|
|
font-size: 0.95rem;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.input-wrapper {
|
|
position: relative;
|
|
}
|
|
|
|
.form-control {
|
|
width: 100%;
|
|
padding: 14px 48px 14px 16px;
|
|
border: 2px solid #e0e0e0;
|
|
border-radius: 8px;
|
|
font-size: 1rem;
|
|
transition: all 0.3s ease;
|
|
font-family: inherit;
|
|
}
|
|
|
|
.form-control:focus {
|
|
outline: none;
|
|
border-color: #ff9800;
|
|
box-shadow: 0 0 0 3px rgba(255, 152, 0, 0.1);
|
|
}
|
|
|
|
.password-toggle {
|
|
position: absolute;
|
|
right: 12px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
padding: 8px;
|
|
font-size: 1.2rem;
|
|
opacity: 0.6;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
.password-toggle:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* 버튼 */
|
|
.form-actions {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.btn {
|
|
padding: 14px 28px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
font-family: inherit;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: #ff9800;
|
|
color: white;
|
|
flex: 1;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: #f57c00;
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(255, 152, 0, 0.3);
|
|
}
|
|
|
|
.btn-primary:disabled {
|
|
background: #ccc;
|
|
cursor: not-allowed;
|
|
transform: none;
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: #f5f5f5;
|
|
color: #666;
|
|
border: 1px solid #e0e0e0;
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: #e0e0e0;
|
|
}
|
|
|
|
/* 메시지 */
|
|
.message-box {
|
|
padding: 16px;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
animation: slideDown 0.3s ease-out;
|
|
}
|
|
|
|
.message-box.error {
|
|
background: #ffebee;
|
|
border: 1px solid #ffcdd2;
|
|
color: #c62828;
|
|
}
|
|
|
|
.message-box.success {
|
|
background: #e8f5e9;
|
|
border: 1px solid #c8e6c9;
|
|
color: #2e7d32;
|
|
}
|
|
|
|
@keyframes slideDown {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
/* 하단 링크 */
|
|
.back-link {
|
|
text-align: center;
|
|
margin-top: 32px;
|
|
padding-top: 32px;
|
|
border-top: 1px solid #e0e0e0;
|
|
}
|
|
|
|
.back-link a {
|
|
color: #1976d2;
|
|
text-decoration: none;
|
|
font-size: 0.95rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
transition: color 0.2s;
|
|
}
|
|
|
|
.back-link a:hover {
|
|
color: #1565c0;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* 반응형 */
|
|
@media (max-width: 768px) {
|
|
.password-page {
|
|
padding: 20px 16px;
|
|
}
|
|
|
|
.card-body {
|
|
padding: 24px;
|
|
}
|
|
|
|
.form-actions {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.btn {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-50">
|
|
<header class="bg-orange-700 text-white sticky top-0 z-50">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex justify-between items-center h-14">
|
|
<div class="flex items-center gap-3">
|
|
<button id="mobileMenuBtn" class="lg:hidden text-orange-200 hover:text-white"><i class="fas fa-bars text-xl"></i></button>
|
|
<i class="fas fa-industry text-xl text-orange-200"></i>
|
|
<h1 class="text-lg font-semibold">TK 공장관리</h1>
|
|
</div>
|
|
<div class="flex items-center gap-4">
|
|
<span id="headerUserName" class="text-sm hidden sm:block">-</span>
|
|
<div id="headerUserAvatar" class="w-8 h-8 bg-orange-600 rounded-full flex items-center justify-center text-sm font-bold">-</div>
|
|
<button onclick="doLogout()" class="text-orange-200 hover:text-white" title="로그아웃"><i class="fas fa-sign-out-alt"></i></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
<div id="mobileOverlay" class="hidden fixed inset-0 bg-black/50 z-30 lg:hidden"></div>
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 fade-in">
|
|
<div class="flex gap-6">
|
|
<nav id="sideNav" class="hidden lg:flex flex-col gap-1 w-52 flex-shrink-0 pt-2 fixed lg:static z-40 bg-white lg:bg-transparent p-4 lg:p-0 rounded-lg lg:rounded-none shadow-lg lg:shadow-none top-14 left-0 bottom-0 overflow-y-auto"></nav>
|
|
<div class="flex-1 min-w-0">
|
|
<div class="password-page">
|
|
<div class="page-title">
|
|
<h1>비밀번호 변경</h1>
|
|
<p>계정 보안을 위해 정기적으로 비밀번호를 변경해주세요</p>
|
|
</div>
|
|
|
|
<div class="password-card">
|
|
<div class="card-header">
|
|
<h2>새 비밀번호 설정</h2>
|
|
</div>
|
|
|
|
<div class="card-body">
|
|
<!-- 메시지 영역 -->
|
|
<div id="message-area"></div>
|
|
|
|
<!-- 안내 정보 -->
|
|
<div class="info-box">
|
|
<h4>비밀번호 요구사항</h4>
|
|
<ul>
|
|
<li>최소 6자 이상 입력해주세요</li>
|
|
<li>영문 대/소문자, 숫자, 특수문자를 조합하면 더 안전합니다</li>
|
|
<li>개인정보나 쉬운 단어는 피해주세요</li>
|
|
<li>이전 비밀번호와 다르게 설정해주세요</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- 비밀번호 변경 폼 -->
|
|
<form id="changePasswordForm" class="password-form">
|
|
<div class="form-group">
|
|
<label for="currentPassword">현재 비밀번호</label>
|
|
<div class="input-wrapper">
|
|
<input
|
|
type="password"
|
|
id="currentPassword"
|
|
class="form-control"
|
|
placeholder="현재 비밀번호를 입력하세요"
|
|
required
|
|
autocomplete="current-password"
|
|
/>
|
|
<button type="button" class="password-toggle" data-target="currentPassword">보기</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="newPassword">새 비밀번호</label>
|
|
<div class="input-wrapper">
|
|
<input
|
|
type="password"
|
|
id="newPassword"
|
|
class="form-control"
|
|
placeholder="새 비밀번호를 입력하세요"
|
|
required
|
|
autocomplete="new-password"
|
|
/>
|
|
<button type="button" class="password-toggle" data-target="newPassword">보기</button>
|
|
</div>
|
|
<div id="passwordStrength"></div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="confirmPassword">새 비밀번호 확인</label>
|
|
<div class="input-wrapper">
|
|
<input
|
|
type="password"
|
|
id="confirmPassword"
|
|
class="form-control"
|
|
placeholder="새 비밀번호를 다시 입력하세요"
|
|
required
|
|
autocomplete="new-password"
|
|
/>
|
|
<button type="button" class="password-toggle" data-target="confirmPassword">보기</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="submit" class="btn btn-primary" id="submitBtn">
|
|
비밀번호 변경
|
|
</button>
|
|
<button type="button" class="btn btn-secondary" id="resetBtn">
|
|
초기화
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="back-link">
|
|
<a href="javascript:history.back()">
|
|
<span>←</span>
|
|
<span>이전 페이지로 돌아가기</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/js/sso-relay.js?v=20260401"></script>
|
|
<script src="/static/js/tkfb-core.js?v=2026040105"></script>
|
|
<script>initAuth();</script>
|
|
<script src="/js/change-password.js?v=2026040101"></script>
|
|
</body>
|
|
</html>
|