security: 보안 강제 시스템 구축 + 하드코딩 비밀번호 제거
보안 감사 결과 CRITICAL 2건, HIGH 5건 발견 → 수정 완료 + 자동화 구축. [보안 수정] - issue-view.js: 하드코딩 비밀번호 → crypto.getRandomValues() 랜덤 생성 - pushSubscriptionController.js: ntfy 비밀번호 → process.env.NTFY_SUB_PASSWORD - DEPLOY-GUIDE.md/PROGRESS.md/migration SQL: 평문 비밀번호 → placeholder - docker-compose.yml/.env.example: NTFY_SUB_PASSWORD 환경변수 추가 [보안 강제 시스템 - 신규] - scripts/security-scan.sh: 8개 규칙 (CRITICAL 2, HIGH 4, MEDIUM 2) 3모드(staged/all/diff), severity, .securityignore, MEDIUM 임계값 - .githooks/pre-commit: 로컬 빠른 피드백 - .githooks/pre-receive-server.sh: Gitea 서버 최종 차단 bypass 거버넌스([SECURITY-BYPASS: 사유] + 사용자 제한 + 로그) - SECURITY-CHECKLIST.md: 10개 카테고리 자동/수동 구분 - docs/SECURITY-GUIDE.md: 운영자 가이드 (워크플로우, bypass, FAQ) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
127
system1-factory/web/public/js/tbm/utils.js
Normal file
127
system1-factory/web/public/js/tbm/utils.js
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* TBM - Utilities
|
||||
* TBM 관련 유틸리티 함수들 (공통 함수는 CommonUtils에 위임)
|
||||
*/
|
||||
|
||||
class TbmUtils {
|
||||
constructor() {
|
||||
this._common = window.CommonUtils;
|
||||
console.log('[TbmUtils] 초기화 완료');
|
||||
}
|
||||
|
||||
// --- CommonUtils 위임 ---
|
||||
getTodayKST() { return this._common.getTodayKST(); }
|
||||
formatDate(dateString) { return this._common.formatDate(dateString); }
|
||||
getDayOfWeek(dateString) { return this._common.getDayOfWeek(dateString); }
|
||||
isToday(dateString) { return this._common.isToday(dateString); }
|
||||
generateUUID() { return this._common.generateUUID(); }
|
||||
escapeHtml(text) { return this._common.escapeHtml(text); }
|
||||
|
||||
// --- TBM 전용 ---
|
||||
|
||||
/**
|
||||
* 날짜 표시용 포맷 (MM월 DD일)
|
||||
*/
|
||||
formatDateDisplay(dateString) {
|
||||
if (!dateString) return '';
|
||||
const [year, month, day] = dateString.split('-');
|
||||
return `${parseInt(month)}월 ${parseInt(day)}일`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 날짜를 연/월/일/요일 형식으로 포맷
|
||||
*/
|
||||
formatDateFull(dateString) {
|
||||
if (!dateString) return '';
|
||||
const [year, month, day] = dateString.split('-');
|
||||
const dayName = this._common.getDayOfWeek(dateString);
|
||||
return `${year}년 ${parseInt(month)}월 ${parseInt(day)}일 (${dayName})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 시간을 HH:MM 형식으로 반환
|
||||
*/
|
||||
getCurrentTime() {
|
||||
return new Date().toTimeString().slice(0, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 날씨 조건명 반환
|
||||
*/
|
||||
getWeatherConditionName(code) {
|
||||
const names = {
|
||||
clear: '맑음', rain: '비', snow: '눈', heat: '폭염',
|
||||
cold: '한파', wind: '강풍', fog: '안개', dust: '미세먼지'
|
||||
};
|
||||
return names[code] || code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 날씨 아이콘 반환
|
||||
*/
|
||||
getWeatherIcon(code) {
|
||||
const icons = {
|
||||
clear: '☀️', rain: '🌧️', snow: '❄️', heat: '🔥',
|
||||
cold: '🥶', wind: '💨', fog: '🌫️', dust: '😷'
|
||||
};
|
||||
return icons[code] || '🌤️';
|
||||
}
|
||||
|
||||
/**
|
||||
* 카테고리명 반환
|
||||
*/
|
||||
getCategoryName(category) {
|
||||
const names = {
|
||||
'PPE': '개인 보호 장비', 'EQUIPMENT': '장비 점검',
|
||||
'ENVIRONMENT': '작업 환경', 'EMERGENCY': '비상 대응',
|
||||
'WEATHER': '날씨', 'TASK': '작업'
|
||||
};
|
||||
return names[category] || category;
|
||||
}
|
||||
|
||||
/**
|
||||
* 상태 배지 HTML 반환
|
||||
*/
|
||||
getStatusBadge(status) {
|
||||
const badges = {
|
||||
'draft': '<span class="tbm-card-status draft">진행중</span>',
|
||||
'completed': '<span class="tbm-card-status completed">완료</span>',
|
||||
'cancelled': '<span class="tbm-card-status cancelled">취소</span>'
|
||||
};
|
||||
return badges[status] || '';
|
||||
}
|
||||
}
|
||||
|
||||
// 전역 인스턴스 생성
|
||||
window.TbmUtils = new TbmUtils();
|
||||
|
||||
// 하위 호환성: TBM 전용 유틸 (showToast, formatDate, waitForApi, generateUUID는 api-base.js 전역)
|
||||
window.getTodayKST = () => window.TbmUtils.getTodayKST();
|
||||
|
||||
// 카테고리별 그룹화
|
||||
window.groupChecksByCategory = function(checks) {
|
||||
return checks.reduce((acc, check) => {
|
||||
const category = check.check_category || 'OTHER';
|
||||
if (!acc[category]) acc[category] = [];
|
||||
acc[category].push(check);
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
// 작업별 그룹화
|
||||
window.groupChecksByTask = function(checks) {
|
||||
return checks.reduce((acc, check) => {
|
||||
const taskId = check.task_id || 0;
|
||||
const taskName = check.task_name || '기타 작업';
|
||||
if (!acc[taskId]) acc[taskId] = { name: taskName, items: [] };
|
||||
acc[taskId].items.push(check);
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
// Admin 사용자 확인
|
||||
window.isAdminUser = function() {
|
||||
return window.TbmState?.isAdminUser() || false;
|
||||
};
|
||||
|
||||
console.log('[Module] tbm/utils.js 로드 완료');
|
||||
Reference in New Issue
Block a user