- EncryptedSharedPreferences를 사용한 암호화된 사용자 저장
- SHA-256 해싱으로 비밀번호 보안 강화 (username을 salt로 사용)
- 사용자 CRUD 기능 (추가/수정/삭제/조회)
- 사용자 관리 UI 추가 (UserManagementActivity)
- FTP 인증 로직을 placeholder에서 실제 검증으로 변경
- 기본 admin/admin 사용자 자동 생성
- 마지막 사용자 삭제 방지 기능
보안 기능:
- 이중 보안: 비밀번호 해싱 + EncryptedSharedPreferences
- 평문 저장 없음
- 유효성 검사 (username: 3-20자 영숫자+_, password: 최소 4자)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
FTP RFC 2640 표준에 따라 파일명을 NFC 형식으로 전송하도록 변경.
- 기존 NFD 변환 코드 제거 (convertFileListToNFD, denormalizeFilename 호출)
- Windows 클라이언트: NFC로 받아 한글이 정상 표시
- Mac 클라이언트: NFC를 자동으로 NFD 변환하여 처리
- 파일 검색 시 NFD/NFC 양방향 호환성은 findFileWithNormalization()으로 유지
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
방화벽 환경에서 특정 포트 범위만 개방하여 사용할 수 있도록 데이터 포트 범위 설정 기능 추가.
- FTPConfig에 minDataPort, maxDataPort 설정 추가 (기본값: 50000-50100)
- FTPDataConnection에서 지정된 범위 내 사용 가능한 포트 자동 할당
- MainActivity UI에 데이터 포트 범위 설정 필드 추가
- 포트 범위 유효성 검증 (최소 10개 포트, 1024-65535 범위)
- 범위 미지정 시 기존처럼 랜덤 포트 사용
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
onResume()에서 실제 FTPService 실행 상태를 확인하여 UI를 동기화함으로써 화면 전환 또는 앱 재시작 시에도 올바른 버튼 상태가 표시되도록 수정.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
macOS NFD와 Android NFC 유니코드 정규화 차이로 인한 한글 파일명 처리 오류 수정.
파일 검색 시 NFD/NFC 모두 지원하도록 개선하여 macOS에서 업로드/다운로드/삭제 작업이 정상 동작함.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
문제: Android 11+ Scoped Storage로 인해 EPERM (Operation not permitted) 에러 발생
- Storage Access Framework로 디렉토리 선택했지만 File API로 쓰기 시도
- 권한 부족으로 파일 업로드(STOR) 실패
해결:
- AndroidManifest.xml에 MANAGE_EXTERNAL_STORAGE 권한 추가
- MainActivity에서 Android 11+ (API 30+) 권한 요청 로직 추가
* Environment.isExternalStorageManager()로 권한 확인
* Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION으로 설정 화면 이동
* 서버 시작 전 권한 체크 추가
- 이 권한으로 외부 저장소 전체에 File API 접근 가능
사용자는 앱 실행 시 "All files access" 권한 활성화 필요
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- FTPConfig 클래스 생성: SharedPreferences 기반 설정 관리
* 포트 번호 저장/로드
* 루트 디렉토리 URI 및 경로 저장/로드
- MainActivity UI 업데이트
* ScrollView로 전체 레이아웃 감싸기
* 설정 섹션 추가 (포트 입력, 디렉토리 선택)
* Storage Access Framework로 디렉토리 선택 기능
* 설정 유효성 검사 (포트 범위: 1024-65535)
- MainActivity 로직 업데이트
* ActivityResultLauncher로 디렉토리 선택
* takePersistableUriPermission으로 지속적 권한 획득
* 설정 로드 및 저장 기능
* 서버 시작 전 루트 디렉토리 필수 체크
- FTPService 수정
* Intent로 포트 및 루트 디렉토리 전달받음
* FTPServer에 설정값 전달
- FTPServer 생성자 확장
* 포트 및 루트 디렉토리 파라미터 추가
* FTPSession에 설정값 전달
- FTPSession 생성자 확장
* 루트 디렉토리 파라미터 추가
* FTPFileSystem에 전달
- FTPFileSystem 생성자 확장
* 사용자 지정 루트 디렉토리 지원
* null일 경우 기본 디렉토리 사용
* 경로 유효성 검증
이제 사용자가 원하는 디렉토리를 FTP 루트로 설정 가능
Android 11+ Scoped Storage 문제 해결
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Android Gradle Plugin 7.1.3과 호환 문제로 compileSdk 36 → 34로 변경
- targetSdk도 34로 변경
- FTPFileSystem에서 final 필드 rootDirectory에 두 번 할당하는 버그 수정
* getDefaultRootDirectory() 헬퍼 메서드로 로직 분리
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- RETR 명령어 구현: 파일 다운로드
* 파일 존재 여부 확인
* 데이터 연결을 통한 파일 스트림 전송
* 전송 바이트 수 로깅
* 에러 처리 및 연결 자동 종료
- STOR 명령어 구현: 파일 업로드
* 현재 디렉토리에 파일 생성
* 데이터 연결을 통한 파일 스트림 수신
* 전송 완료 후 파일 크기 확인
* 에러 처리 및 연결 자동 종료
- 두 명령어 모두 PASV 선행 필수
- FileInputStream/FileOutputStream을 사용한 스트림 처리
- 전송 성공/실패에 따른 적절한 응답 코드 반환
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- FTPDataConnection 클래스 생성: 데이터 연결 관리
* Passive Mode를 위한 ServerSocket 생성
* 동적 포트 할당 및 클라이언트 연결 수락
* 데이터 송수신 기능 (바이트 배열, 문자열, 스트림)
* 30초 타임아웃 설정
- FTPSession에 데이터 연결 통합
* dataConnection 필드 및 transferType 필드 추가
* 세션 종료 시 데이터 연결 자동 닫기
- PASV 명령어 구현
* Passive Mode 진입
* 서버 주소와 포트를 h1,h2,h3,h4,p1,p2 형식으로 응답
* 이전 데이터 연결 자동 종료
- TYPE 명령어 구현
* ASCII (A) 및 Binary (I) 모드 지원
* 전송 타입 상태 관리
- LIST/NLST 명령어를 데이터 연결로 수정
* PASV 명령어 선행 필수
* 데이터 연결을 통해 파일 목록 전송
* 전송 완료 후 연결 자동 종료
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- FTPFileSystem 클래스 생성: 파일 시스템 추상화
* 안드로이드 외부 저장소의 FTPServer 디렉토리를 루트로 설정
* 경로 보안 검증 (루트 디렉토리 escape 방지)
* 상대/절대 경로 지원
- FTPSession에 파일 시스템 통합
* FTPFileSystem 인스턴스 추가
* PWD 명령어를 파일 시스템 기반으로 수정
- 디렉토리 탐색 명령어 구현
* CWD: 디렉토리 변경
* CDUP: 상위 디렉토리로 이동
- 파일 목록 명령어 구현
* LIST: 상세 파일 목록 (Unix 스타일)
* NLST: 파일명만 나열
* 임시로 제어 연결을 통해 전송 (데이터 연결은 Phase 4에서 구현)
- 파일/디렉토리 관리 명령어 구현
* MKD: 디렉토리 생성
* RMD: 디렉토리 삭제
* DELE: 파일 삭제
* SIZE: 파일 크기 조회
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- AndroidManifest.xml에 필요한 권한 추가 (INTERNET, STORAGE 등)
- FTPResponse 클래스 생성: FTP 응답 코드 상수 정의
- FTPSession 클래스 생성: 개별 클라이언트 세션 처리
* 명령어 읽기/응답 보내기 기본 루프
* USER, PASS, QUIT, SYST, PWD, NOOP 명령어 처리
- FTPServer 클래스 생성: 메인 서버 로직
* ServerSocket으로 포트 2121에서 수신 대기
* ExecutorService로 다중 클라이언트 연결 관리
- FTPService 클래스 생성: 백그라운드 포그라운드 서비스
* 서버 시작/중지 Intent 처리
* 알림 채널 및 포그라운드 서비스 구현
- MainActivity UI 업데이트: 서버 제어 기능
* 시작/중지 버튼 추가
* 서버 상태 표시
* 런타임 권한 요청 처리
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>