Add automatic nearby discovery and simplify device presence UI
This commit is contained in:
38
docs/NEARBY_DISCOVERY.md
Normal file
38
docs/NEARBY_DISCOVERY.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 기기 발견
|
||||
|
||||
기기 목록은 Socket.IO 변경 이벤트로 갱신한다. 계속 목록을 조회하는 검색 루프나 대기 스피너는 사용하지 않는다. 실제 새 기기 이벤트 후 서버 조회를 기다리는 동안에만 카드 형태의 스켈레톤을 표시하며, 정보를 받으면 같은 자리에서 실제 카드로 바뀐다. 조회 실패 시 스켈레톤은 최대 5초 뒤 사라진다. 연결 해제 시 짧게 사라지는 효과를 적용하고, 동작 줄이기 설정을 존중한다.
|
||||
|
||||
## 같은 네트워크
|
||||
|
||||
기존의 검증된 공인 IP 그룹 발견을 유지한다. 운영에서는 Cloudflare → NPM → hop. 프록시 경로를 검증하고 활성화해야 한다. 실제 NAS에서 기존 사용자가 같은 네트워크 자동 발견을 확인했다. 방 참여 중에는 해당 방 기기만 표시한다.
|
||||
|
||||
## 위치로 근처 기기 찾기
|
||||
|
||||
- 기본 반경 100m. 위치는 내부에서 자동으로 확인하며 별도 검색 버튼·거리 안내 문구를 표시하지 않는다. 양쪽 브라우저가 위치 권한을 허용해야 한다. 첫 요청의 권한 창은 브라우저가 표시한다.
|
||||
- HTTPS 필요. 위치 권한 거절·미지원·오차가 너무 큰 경우 기존 QR/네트워크 연결을 유지한다. 거절 후 반복 권한 요청을 하지 않는다. 브라우저에서 권한을 다시 허용하거나 발견 허용을 바꾸면 상태를 반영한다.
|
||||
- 위도·경도는 소수점 4자리로 줄여 프로세스 메모리에만 보관한다. DB·브라우저 저장소·다른 기기 응답에는 좌표를 넣지 않는다. 브라우저 위치 권한 상태를 사용하며 별도 동의 플래그를 저장하지 않는다.
|
||||
- 화면이 보이고 연결·발견 허용 상태일 때만 2분마다 위치를 갱신한다. 이동 추적 `watchPosition`은 사용하지 않는다.
|
||||
- 발견 허용 끄기·권한 해제·탭 숨김·방 참여·접속 종료 시 해당 탭 좌표를 제거한다. 강제 종료 등으로 제거 신호가 누락되어도 150초 후 만료한다.
|
||||
- 다른 탭에서 검색 중인 같은 기기는 마지막 유효한 좌표가 사라질 때까지 표시될 수 있다.
|
||||
- 위치가 바뀌어 목록에 변화가 있을 때만 관련 기기에 이벤트를 보낸다. 파일 시스템 정리는 1분 간격이며 요청·세션 만료 정리는 별도로 유지한다.
|
||||
- 위치 오차 때문에 근처 사용자 누락이나 옆 건물 사용자가 표시될 수 있다. 실제 Bluetooth 거리나 접속 경로를 증명하는 기능은 아니다. 전송에는 기존 수락 절차와 접근 검사 모두 적용한다.
|
||||
- 링크 수락으로 새 탭이 열려 위치가 제거되는 경우에는 수락 직전 확인된 요청 ID에 한해 15초짜리 일회성 수락 권한을 사용한다. 좌표를 연장하거나 방·차단·발견 허용 경계를 우회하지 않는다.
|
||||
|
||||
설정 기본값:
|
||||
|
||||
```dotenv
|
||||
LOCATION_DISCOVERY_ENABLED=true
|
||||
LOCATION_DISCOVERY_RADIUS_METERS=100
|
||||
```
|
||||
|
||||
기존 NAS `.env`에 항목이 없어도 기본값이 적용된다. 새 주소·포트 설정은 필요 없다.
|
||||
|
||||
## 기종 정보와 이름
|
||||
|
||||
지원하는 Chromium Android 브라우저에서는 `navigator.userAgentData.getHighEntropyValues(['model'])`로 모델 정보를 읽는다. 지원하지 않거나 브라우저가 공개하지 않으면 기존 이름·고유 코드를 표시한다. 모델 정보 조회는 최대 1초만 기다리며 실패가 접속을 막지 않는다.
|
||||
|
||||
일반 기본 이름(Android 등)은 모델이 있으면 모델로 표시한다. 직접 지정한 이름은 항상 우선하며, 모든 카드에 고유 코드도 함께 표시한다. 같은 모델 여러 대는 코드와 이름 변경으로 구분할 수 있다. 모델·플랫폼 정보는 연결 중 서버 메모리에만 두고 마지막 연결 종료 후 정리한다.
|
||||
|
||||
제조사는 브라우저가 제공하는 필드가 아니다. `SM-`/`GT-`는 Samsung, `Pixel`은 Google로 제한적으로 추정한다. 모르는 모델은 추정하지 않는다. 브라우저 브랜드(Chrome 등)를 기기 제조사로 사용하지 않는다. OS에서 지정한 개인 기기 이름, 일련번호, MAC 주소는 읽지 않는다. iPhone의 정확한 기종도 이 방식으로 보장하지 않는다.
|
||||
|
||||
모델 힌트의 범위와 공개 제한은 [MDN 문서](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues)를 참고했다.
|
||||
@@ -47,5 +47,5 @@
|
||||
- 개인 보관함 기본 한도 2GiB: 임시 저장·받은 항목의 유효한 파일 원본을 계정별로 중복 없이 합산. 받은 파일도 포함하고 삭제·만료한 접근권은 개인 사용량에서 제외한다. 다른 사람의 원본과 저장소를 물리적으로 공유하더라도 계정별 한도는 분리한다.
|
||||
- 개인 한도 초과 시 기기 수신·다운로드는 계속하고 해당 파일의 계정 수신 기록만 생략한다. 짧은 알림을 표시한다. 업로드 중인 개인 저장의 예약과 삭제 복원도 한도를 검사한다. 익명 파일 저장 한도는 개인 보관함과 별도이며 익명 화면의 내역은 계속 숨긴다.
|
||||
- 파일은 8MiB 조각으로 전송하며 같은 파일 내용 검증·이미 받은 위치·중복 조각·서버 재시작을 처리한다. 자동 재시도 실패 시 기존 단일 버튼이 다시 전송으로 바뀐다. 완료 전후 취소와 접근 범위 검사는 유지한다.
|
||||
- 운영 자동 발견은 신뢰한 인접 프록시에서 온 CF-Connecting-IP만 사용하고, 원본 IP와 프록시 진단 결과는 일반 사용자에게 공개하지 않는다. 같은 공인 IP를 계속 탐색한다는 상태를 표시한다.
|
||||
- 운영 자동 발견은 신뢰한 인접 프록시에서 온 CF-Connecting-IP만 사용하고, 원본 IP와 프록시 진단 결과는 일반 사용자에게 공개하지 않는다. 목록 변화는 접속 이벤트로 갱신하고 대기 중 반복 탐색 문구를 표시하지 않는다. 위치 허용 기반 100m 근처 검색도 제공하며 상세 동작은 NEARBY_DISCOVERY.md를 따른다.
|
||||
- PWA 설치: Android 등 설치 이벤트 지원 브라우저는 설치 창, iPhone은 홈 화면 추가 안내. 설치 앱 안에서는 버튼을 숨긴다. Service Worker는 민감한 자료나 API를 캐시하지 않고 오프라인에서는 인터넷 연결 안내만 제공한다.
|
||||
|
||||
@@ -87,3 +87,13 @@
|
||||
- PWA manifest·PNG 아이콘·실제 Service Worker·iPhone 설치 안내·설치 이벤트·설치 후 숨김·320px 헤더·오프라인 안내·민감한 데이터 캐시 없음 검증. 실제 OS 설치와 실물 Safari/Android는 사용자 기기에서 확인해야 한다.
|
||||
- 개인 보관함 2GiB의 직접 저장·받은 파일 합산, 다른 계정 격리, 한도 초과 수신의 다운로드 유지·계정 기록 생략, 삭제 후 공간 회수·초과 복원 거절을 확인했다.
|
||||
- 전체 빌드와 남은 타입 검사 통과. 운영 Docker 이미지 빌드와 재시작 후 SQLite integrity·세션·기기명·기존 파일·미완료 업로드 조각의 위치 보존 및 이어 보내기 완료 검증. 실제 NAS·Cloudflare·NPM 경로 활성화는 deploy.md의 운영 진단으로 수행한다.
|
||||
|
||||
## 2026-10-12 위치 검색과 접속 상태 UI 업데이트
|
||||
|
||||
- 전체 빌드와 남은 타입 검사 통과. API 테스트 73개 통과.
|
||||
- 양쪽 위치 동의·100m 반경·좌표 오차/유효성·여러 탭·만료·발견 허용 끄기·방 격리·기존 접근 경계·수락 직전 위치 해제를 검사했다. 위치는 서버 메모리에만 저장한다.
|
||||
- 실제 Chrome 브라우저에서 위치 권한 허용 후 별도 검색 버튼·거리 안내 없이 자동 발견, 대기 중 반복 API 요청 없음, 모바일·탭 숨김 후 위치 삭제/복귀, 거리 밖 제외·권한 거절 후 반복 요청 없음, 수락 후 링크 자동 열기를 검증했다. 좌표는 테스트 브라우저의 위치 시뮬레이션을 사용했으며 실제 NAS 주변 GPS 환경은 배포 후 확인해야 한다.
|
||||
- 별도 브라우저 검증에서 새 기기 이벤트 후 서버 조회를 지연시켜 카드 스켈레톤을 확인하고, 정보 도착 후 실제 카드로 교체·직접 지정한 이름 우선·모델별 이름·제조사 제한 추정·연결 해제 애니메이션·메타데이터 정리를 검사했다. 기기 12대의 4/3/2열 반응형과 빈 화면도 확인했다.
|
||||
- 기존 브라우저 테스트 5종(익명 전송, 계정 보관함, 방 기기 관리, 분할 업로드, PWA) 모두 통과했다. 수락 팝업·자동 열기/다운로드·재시도·7일 보관·2GiB 용량 경계는 유지한다.
|
||||
- 운영 Docker 이미지 빌드 및 재시작 후 SQLite integrity·세션·기기명·파일·미완료 분할 업로드 복구 테스트 통과. 화면 정리 이후에도 같은 검증을 완료했다.
|
||||
- NAS 업데이트 순서는 deploy.md에 기록했다. 새 도메인·포트는 필요 없고 실제 NAS에 대한 원격 배포는 수행하지 않았다.
|
||||
|
||||
Reference in New Issue
Block a user