import '../../core/webdav.dart'; import '../../core/sftp.dart'; import '../../core/smb.dart'; import '../../core/ftp.dart'; import '../../core/remote_idle.dart'; import 'settings_group.dart'; /// 약속 (설정 A): 환경 설정 > 원격 서버 (WebDAV · SFTP · SMB · FTP) - 자기 키 (이름 · 처음 값 · 읽기 · 쓰기) 를 스스로 갖는다. /// 설정 하나를 더할 때는 이 파일만 고친다. 저장 파일의 키 이름은 예전 그대로 (평평한 키) class RemoteSettings implements SettingsGroup { /// 55: 로그인이 필요한 WebDAV 동영상을 다른 앱으로 열 때 'ask' (매번 묻기) · 'fetch' (늘 받아서) · 'url' (늘 주소로) String davExternalOpen = 'ask'; /// WebDAV 서버 (파일 탐색기 · Rsync 화면 위쪽 "SD 카드" 옆 탭). 비밀번호는 이 설정 파일에만. List webdavServers = []; /// 88: SFTP 서버 (WebDAV 옆 탭). 비밀번호 · 개인 키 · 키 암호는 안전 저장소에만 (설정 파일에는 평문으로 쓰지 않는다) List sftpServers = []; /// 88: Android SMB 서버 (smbj). 비밀번호는 안전 저장소에만. Windows 는 운영체제의 \서버\공유 를 쓴다 List smbServers = []; /// 보안 검토 6 (관리자 결정 10/18): SMB 서명이나 암호화가 되지 않는 연결은 막는다. 처음 끔 (오래된 NAS 가 붙지 않을 수 있어서). /// 꺼 두어도 서명 · 암호화가 안 되는 서버는 탐색기 탭에 ⚠ bool smbRequireSecure = false; /// l: FTP · FTPS 서버. 비밀번호는 안전 저장소에만 (설정 파일에는 평문으로 쓰지 않는다) List ftpServers = []; /// 관리자 판단 (10/20): 원격 서버 (FTP · SFTP · SMB · WebDAV) 받기 · 올리기에서 조각 사이를 기다리는 시간 (초). /// 이 시간 동안 아무것도 오가지 않으면 실패 ("서버가 답하지 않습니다"). 30 · 60 (처음) · 120 · 300 - 그 밖의 값은 60 int idleSeconds = RemoteIdle.defaultSeconds; @override void write(Map j, {required bool plainSecrets}) { j['webdavServers'] = [ for (final x in webdavServers) {...x.toJson(), if (plainSecrets) 'password': x.password}, ]; // 새 비밀 값은 안전 저장소에 못 써도 평문으로 쓰지 않는다 (사용자 결정 54) - plainSecrets 여도 넣지 않음 j['sftpServers'] = [for (final x in sftpServers) x.toJson()]; j['smbServers'] = [for (final x in smbServers) x.toJson()]; j['smbRequireSecure'] = smbRequireSecure; j['ftpServers'] = [for (final x in ftpServers) x.toJson()]; j['remoteIdleSeconds'] = idleSeconds; j['davExternalOpen'] = davExternalOpen; } @override void read(Map j) { davExternalOpen = const ['fetch', 'url'].contains(j['davExternalOpen']) ? j['davExternalOpen'] as String : 'ask'; webdavServers = [ for (final x in (j['webdavServers'] as List?) ?? const []) if (x is Map) DavServer.fromJson(x), ]; sftpServers = [ for (final x in (j['sftpServers'] as List?) ?? const []) if (x is Map) SftpServer.fromJson(x), ]; smbRequireSecure = j['smbRequireSecure'] is bool ? j['smbRequireSecure'] as bool : false; idleSeconds = RemoteIdle.choices.contains(j['remoteIdleSeconds']) ? j['remoteIdleSeconds'] as int : RemoteIdle.defaultSeconds; smbServers = [ for (final x in (j['smbServers'] as List?) ?? const []) if (x is Map) SmbServer.fromJson(x), ]; ftpServers = [ for (final x in (j['ftpServers'] as List?) ?? const []) if (x is Map) FtpServer.fromJson(x), ]; } }