# ITMS SR 소스 변경 상세 (변경 전 → 변경 후) — 2026-07-19 > 리뷰·감사 추적용. 자격증명·AES 암호문·프로파일 yml·키파일은 변경 대상 아님(미기재). 빌드: `:api:compileJava :front:compileJava` BUILD SUCCESSFUL. --- ## SR#1 잠긴 계정 비밀번호 초기화 차단 + 메일 미발송 결함 ### `api/src/main/java/com/urpsys/itmsapi/sys/controller/UserManageController.java` (관리자 초기화) 변경 전: ```java LinkedHashMap userInfoMap = userManageService.selectUser(requestMap); if(CommonUtil.nvl(userInfoMap.get("emailAdres")).equals("")) { resBody.put("resultCd" , "-1" ); resBody.put("resultMsg", "E-mail 이 존재하지 않습니다." ); return ResultData.ok(resBody); } ``` 변경 후: ```java LinkedHashMap userInfoMap = userManageService.selectUser(requestMap); // SR#1 : 계정이 잠겨 있으면 초기화 차단 (잠금 해제 후 가능) if(CommonUtil.nvl(userInfoMap.get("lockAt")).equals("Y")) { resBody.put("resultCd" , "-2" ); resBody.put("resultMsg", "계정이 잠겨 있습니다. [로그인인증제한해제]로 잠금을 먼저 해제한 후 비밀번호를 초기화하세요." ); return ResultData.ok(resBody); } if(CommonUtil.nvl(userInfoMap.get("emailAdres")).equals("")) { ... 동일 ... } ``` ### `api/src/main/java/com/urpsys/baseapi/main/controller/MainController.java` (로그인화면 초기화) 변경 전: ```java else if(!CommonUtil.nvl(userInfoMap.get("emailAdres")).equals(requestMap.get("userEmail"))) { resBody.put("resultCd" , -6 ); resBody.put("resultMsg", "사용자정보가 일치하지 않습니다." ); return ResultData.ok(resBody); } String strResetPassword = CommonUtil.getRandomChar(10); ``` 변경 후: ```java else if(!CommonUtil.nvl(userInfoMap.get("emailAdres")).equals(requestMap.get("userEmail"))) { ... 동일 ... } // SR#1 : 계정 잠금 시 초기화 차단 + 안내 else if(CommonUtil.nvl(userInfoMap.get("lockAt")).equals("Y")) { resBody.put("resultCd" , -7 ); resBody.put("resultMsg", "로그인 시도 횟수 초과로 계정이 잠겼습니다. " + getAdminDisplay() + "에게 문의 바랍니다." ); return ResultData.ok(resBody); } String strResetPassword = CommonUtil.getRandomChar(10); ``` ### `front/.../webapp/WEB-INF/jsp/main/PopPasswordReset.jsp` (서버 안내 메시지 노출) 변경 전: ```javascript else { alert("비밀번호 초기화에 실패하였습니다. \n사용자정보을 확인해주시길 바랍니다."); } ``` 변경 후: ```javascript else { if(data.resultMsg != null && data.resultMsg != "") { alert(data.resultMsg); } else { alert("비밀번호 초기화에 실패하였습니다. \n사용자정보을 확인해주시길 바랍니다."); } } ``` --- ## SR#2, SR#3, D03 로그인 메시지(잠금/오입력 구분 + 관리자 성명 동적) ### `front/src/main/java/com/urpsys/basefront/controller/MainController.java` 변경 전: ```java if(srError[0].equals("-1")) { strErrorMsg = "고객님의 아이디는 5회 로그인 오류로 인해 잠금처리 되었습니다. 시스템 관리자에게 연락해 주세요."; } else if(srError[0].equals("-2")) { strErrorMsg = "아이디 혹은 비밀번호을 확인해주세요. 5회 로그인 오류인경우 아이디가 잠금처리가 됩니다."; } else if(srError[0].equals("-3")) { strErrorMsg = "아이디 혹은 비밀번호을 확인해주세요. 5회 로그인 오류인경우 아이디가 잠금처리가 됩니다."; } ``` 변경 후: ```java if(srError[0].equals("-1")) { strErrorMsg = "로그인 시도 횟수 초과로 계정이 잠겼습니다. " + getAdminDisplay() + "에게 문의 바랍니다."; } else if(srError[0].equals("-2")) { strErrorMsg = "아이디 또는 패스워드가 잘못 되었습니다. 아이디와 패스워드를 정확히 입력해 주세요."; } else if(srError[0].equals("-3")) { strErrorMsg = "아이디 또는 패스워드가 잘못 되었습니다. 아이디와 패스워드를 정확히 입력해 주세요."; } ``` 추가(동적 관리자 표기 — 프로파일 yml `custom.adminName`/`custom.adminTitle` 미설정 시 "시스템 관리자"): ```java @Value("${custom.adminName:}") private String strAdminName; @Value("${custom.adminTitle:}") private String strAdminTitle; private String getAdminDisplay() { String n = (strAdminName==null)?"":strAdminName.trim(); String t = (strAdminTitle==null)?"":strAdminTitle.trim(); if(n.equals("")) return "시스템 관리자"; return "시스템 관리자(" + n + (t.equals("")?"":" "+t) + ")"; } ``` (api `baseapi/main/MainController`에도 동일 `getAdminDisplay()`/`@Value` 추가 — SR#1 잠금 메시지용) --- ## SR#7, SR#10 "등록" 버튼 → "임시저장" ### `front/.../jsp/itms/srm/{SvcDeskInsert,SvcDeskCopyInsert,ReportCheckInsert,ReportCheckCopyInsert,ReportIssueInsert,ReportIssueCopyInsert,ReportErrorInsert,ReportErrorCopyInsert,ReportOtherInsert,ReportOtherCopyInsert}.jsp` (10파일) 변경 전(각 파일 등록/승인요청 옆의 단독 등록 버튼): ```jsp ``` 변경 후: ```jsp ``` (`등록/승인요청` 버튼은 그대로 유지. 단독 신청 버튼만 있는 `SvcDeskReqInsert.jsp`는 제외.) --- ## SR#8 중복 "새로만들기" 제거 ### `front/.../jsp/itms/srm/ReportIssueDetail.jsp` 변경 전(승인요청 블록 + 수정/삭제 블록에 각각 새로만들기 → 2개 표출): ```jsp ``` 댓글 삭제 조건 변경 전: `` → 변경 후: `` --- ## F10 게시판 조회수/댓글수 표기 ### `api/.../mapper/.../itms/bbs/BBSAdminManageMapper.xml` 변경 후 추가(select 컬럼): ```xml , ( SELECT COUNT(1) FROM TB_CMNT_INFO cc WHERE cc.NTT_ID = a.NTT_ID AND cc.USE_AT = 'Y' ) AS cmntCnt ``` ### `front/.../jsp/itms/bbs/admin/NoticeList.jsp` 헤더에 `댓글수`, 본문에 `` 추가(빈목록 colspan 7/5/4 → 8/6/5). --- ## F12 로고/파비콘 브랜딩 관리(KIC) ### 신규 `front/.../basefront/controller/BrandingController.java` - `GET /branding/logo`·`/branding/favicon` : 업로드본 우선, 없으면 번들 KIC 기본자산(webapp `/branding/default/*`) 폴백. 캐시무효화 헤더. - `GET /branding/brandingManageView.do` : 관리자 화면(비관리자 → 메인 리다이렉트). - `POST /branding/upload.do` : 관리자 검증 + 확장자 화이트리스트(logo: svg/png/jpg/gif, favicon: ico/png/svg/jpg/gif) + 2MB 제한 + 저장파일명 서버고정(`kind.ext`, 사용자 파일명 미사용→경로조작 차단) + canonical 경로 재확인. ### `front/.../basefront/config/SecurityConfig.java` 변경 후 추가: `.antMatchers("/branding/logo", "/branding/favicon").permitAll()` (로그인 전 표출). ### 참조 변경(정적 로고/파비콘 → 동적 엔드포인트) - `front/.../jsp/main/LoginUsr.jsp`·`LoginUsr_kic.jsp` : `${ctx}/images/main/logo.png` → `${ctx}/branding/logo` - `front/.../jsp/tilesLayout/{uritms-base-main1,uritms-base-main2,uritms-base-popup1,uritms-popup1}.jsp` : `` → `href="${pageContext.request.contextPath}/branding/favicon"` - `front/.../jsp/main/inc/IncHeader.jsp` : `

` 에 `background-image:url('')` 인라인 지정 ### 신규 자산·화면 - `front/src/main/webapp/branding/default/logo.svg`·`favicon.jpg` (KIC 공식 자산 번들) - `front/.../jsp/branding/brandingManage.jsp` (업로드/미리보기 화면) --- ## D04 검색 후 페이지네이션 검색조건 소실 ### `front/.../jsp/itms/sys/AuthorGroupManage.jsp` 변경 전: `` (해당 함수 미정의 → 검색조건 유실) 변경 후: `` (listForm 재제출 → searchCondition/searchKeyword 유지)