G-1: 메신저 Webhook Relay + _send_to_room 실제 httpx 호출 구현 G-2: POST /api/tasks/bulk SR 대량작업 엔드포인트 (최대 100건) G-3: 라이선스 만료 알림 스케줄러 (매일 09:00 KST) G-4: 체험판 upgrade_banner 필드 + license.py 배너 로직 G-5: core/auto_rca.py + incidents/problem auto-rca 엔드포인트 G-6: core/deploy_impact.py + vibe impact-analysis 엔드포인트 G-7: core/ticket_classifier.py + SR 생성 시 AI 분류 + ai-suggestion API G-8: VulnPatchRecord 모델 + vuln_scan 패치추적 4개 엔드포인트 G-9: core/jira_sync.py + gateway Jira/Confluence 연동 엔드포인트 G-10: core/push_notify.py + routers/push.py + PushSubscription 모델 G-11: approvals 다중승인 (위임/서명/기한초과/마감연장) G-12: alembic.ini + migrations/ + cicd/migrate_to_postgres.sh 하네스: guardia-orchestrator 확장기능 Phase 반영 봇명령어: /sr /status /license /bulk 슬래시 명령어 추가 설치스크립트: setup/ (Ubuntu, CentOS, RHEL, Windows) --test 옵션 포함 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
125 lines
4.4 KiB
HTML
125 lines
4.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>GUARDiA ITSM — 비밀번호 변경</title>
|
|
<link rel="stylesheet" href="/static/login.css">
|
|
<style>
|
|
/* change-password 전용 추가 스타일 */
|
|
.pw-strength {
|
|
height: 4px; border-radius: 2px;
|
|
background: var(--border);
|
|
margin-top: 6px; overflow: hidden;
|
|
}
|
|
.pw-strength-bar {
|
|
height: 100%; border-radius: 2px;
|
|
transition: width .3s, background .3s;
|
|
width: 0;
|
|
}
|
|
.pw-strength-label {
|
|
font-size: 11px; color: var(--muted); margin-top: 4px;
|
|
}
|
|
.pw-match-msg {
|
|
font-size: 11px; margin-top: 4px;
|
|
}
|
|
.pw-match-msg.ok { color: #2bac76; }
|
|
.pw-match-msg.fail { color: #f85149; }
|
|
|
|
.must-change-banner {
|
|
background: rgba(227,179,65,.1);
|
|
border: 1px solid rgba(227,179,65,.3);
|
|
border-radius: var(--radius);
|
|
padding: 10px 14px;
|
|
font-size: 13px; color: #e3b341;
|
|
margin-bottom: 20px;
|
|
display: flex; align-items: flex-start; gap: 8px;
|
|
}
|
|
.must-change-banner.hidden { display: none; }
|
|
|
|
.pw-rules {
|
|
font-size: 11px; color: var(--muted);
|
|
margin-top: 6px; line-height: 1.6;
|
|
}
|
|
.pw-rules li { list-style: none; }
|
|
.pw-rules li::before { content: "• "; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="login-bg">
|
|
<div id="login-wrap">
|
|
<div id="login-card">
|
|
|
|
<!-- 로고 -->
|
|
<div id="login-logo">
|
|
<div class="logo-shield"><span>G</span></div>
|
|
<div class="logo-text">
|
|
<div class="logo-title">비밀번호 변경</div>
|
|
<div class="logo-sub" id="user-subtitle">GUARDiA ITSM</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 최초 로그인 배너 -->
|
|
<div class="must-change-banner" id="must-change-banner">
|
|
<span>⚠️</span>
|
|
<span>초기 비밀번호(<code style="background:rgba(255,255,255,.1);padding:1px 5px;border-radius:3px">1111</code>)를 사용 중입니다. 새 비밀번호로 변경해 주세요.</span>
|
|
</div>
|
|
|
|
<!-- 폼 -->
|
|
<form id="cp-form">
|
|
<div class="field-group">
|
|
<label for="cur-pw">현재 비밀번호</label>
|
|
<div class="pw-wrap">
|
|
<input type="password" id="cur-pw" placeholder="현재 비밀번호" required>
|
|
<button type="button" class="pw-toggle" onclick="togglePw('cur-pw',this)" tabindex="-1">👁</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field-group">
|
|
<label for="new-pw">새 비밀번호</label>
|
|
<div class="pw-wrap">
|
|
<input type="password" id="new-pw" placeholder="새 비밀번호 (4자 이상)"
|
|
oninput="checkStrength(this.value); checkMatch()" required>
|
|
<button type="button" class="pw-toggle" onclick="togglePw('new-pw',this)" tabindex="-1">👁</button>
|
|
</div>
|
|
<div class="pw-strength"><div class="pw-strength-bar" id="strength-bar"></div></div>
|
|
<div class="pw-strength-label" id="strength-label"></div>
|
|
<ul class="pw-rules">
|
|
<li>4자 이상 (영문, 숫자, 특수문자 조합 권장)</li>
|
|
<li>현재 비밀번호와 달라야 합니다</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="field-group">
|
|
<label for="confirm-pw">새 비밀번호 확인</label>
|
|
<div class="pw-wrap">
|
|
<input type="password" id="confirm-pw" placeholder="새 비밀번호 재입력"
|
|
oninput="checkMatch()" required>
|
|
<button type="button" class="pw-toggle" onclick="togglePw('confirm-pw',this)" tabindex="-1">👁</button>
|
|
</div>
|
|
<div class="pw-match-msg" id="match-msg"></div>
|
|
</div>
|
|
|
|
<div id="cp-error" class="error-msg" style="display:none"></div>
|
|
|
|
<button type="submit" id="cp-btn" class="btn-login">
|
|
<span id="cp-btn-text">비밀번호 변경</span>
|
|
<span id="cp-spinner" class="spinner" style="display:none"></span>
|
|
</button>
|
|
</form>
|
|
|
|
<div style="text-align:center;margin-top:14px">
|
|
<a href="#" id="skip-link" style="font-size:12px;color:var(--muted);text-decoration:none">
|
|
나중에 변경하기 →
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
<div id="login-footer">© 2026 GUARDiA — 보안 정책: 90일마다 비밀번호 변경 권장</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="/static/change-password.js"></script>
|
|
</body>
|
|
</html>
|