Skip to content

fix: 공유 일정과 공개 프로필의 읽기 범위를 실제 관계로 좁힌다 (174) - #175

Merged
OnlyReadOneBook merged 1 commit into
mainfrom
feat/174
Sep 6, 2026
Merged

OnlyReadOneBook merged 1 commit into
mainfrom
feat/174

Conversation

@OnlyReadOneBook

@OnlyReadOneBook OnlyReadOneBook commented Sep 6, 2026 •

Copy link
Copy Markdown
Owner

📌𝘐𝘴𝘴𝘶𝘦𝘴

📎𝘞𝘰𝘳𝘬 𝘋𝘦𝘴𝘤𝘳𝘪𝘱𝘵𝘪𝘰𝘯

  • 내 일정은 공유 코드를 받아 등록한 가족에게만 보입니다. 전에는 로그인한 사람이면 누구나 볼 수 있었습니다
  • 완료 표시도 그 가족만 바꿀 수 있습니다
  • 공유 코드 화면에서 저장이 안 되면 이유가 화면에 남습니다. 전에는 조용히 지나갔습니다
  • 확인해 주세요: 가족 코드를 입력하고 저장한 뒤 그 사람의 오늘 일정이 보이는지, 완료 표시가 서로 반영되는지

💬𝘛𝘰 𝘙𝘦𝘷𝘪𝘦𝘸𝘦𝘳𝘴

무엇을 고쳤나

「로그인했는가」 는 범위가 아니다. Google 계정은 몇 초 만에 새로 만들 수 있어, 로그인만 조건으로 둔 컬렉션은 사실상 공개다.

자리 전 후
publicProfiles 읽기 로그인 사용자 전체(목록 포함) 문서 하나씩(get)만. 목록(list)은 아무도 못 함
publicProfiles 필드 id·name·shareCode id·name
공유 코드 중복 확인 publicProfiles 목록 질의 shareCodes/{code} 만들기 한 번
공유 일정 읽기 sharedCode 가 비어 있지 않으면 누구나 그 코드의 감시자로 등록한 사람만
공유 일정 완료 변경 같은 조건 같은 조건 + 감시자
getUserNames whereIn 목록 질의 문서별 읽기

읽기보다 쓰기가 더 아프다. 남이 완료 표시를 뒤집을 수 있으면 어르신이 약을 이미 먹은 줄로 안다.

끊어질 뻔한 자리를 함께 손봤다

감시자 등록 문서가 이제 읽기 권한의 근거다. 그래서:

  • FCM 토큰을 못 받아도 등록 자체는 한다(merge 로 써서 앞서 저장한 토큰을 지우지 않는다). 토큰이 없으면 알림만 못 받는데, 등록을 거르면 가족 일정이 통째로 안 보인다.
  • 등록에 실패한 코드는 기기에 저장하지 않고 화면에 이유를 남긴다. 앞 코드의 등록도 지우지 않는다 — 새 코드가 안 됐는데 앞의 것까지 잃으면 되돌아갈 자리가 없다.
  • 코드는 저장됐는데 등록만 실패한 채 남은 기기를 위해, 공유 일정을 구독하기 전에 등록을 다시 세운다. 그 사이 바뀐 FCM 토큰도 함께 갱신된다.
  • 계정을 지울 때 공유 코드 등록부도 반납한다. 사용자 문서를 먼저 지우면 코드를 알 길이 없어져 그 코드는 아무도 다시 쓰지 못한다.

확인

firestore-tests 34건 통과(에뮬레이터). 새로 잠근 것:

  • 코드를 받지 않은 제3자는 공유 일정을 읽지 못한다(문서 하나도, 질의로도)
  • 코드를 받지 않은 제3자는 completed·completedDates 를 바꾸지 못한다
  • 코드를 하나 받은 사람도 sharedCode > "" 로 다른 집 일정까지 훑지 못한다
  • publicProfiles 목록 조회가 막힌다
  • 공유 코드는 공개 프로필에 담기지 않는다
  • 이미 임자가 있는 코드는 가져가지 못하고, 등록부는 아무도 읽지 못한다
  • 공유 일정 41건을 한 코드에 두고 목록 조회가 통과한다 — 공유 읽기 규칙이 문서마다 감시자 등록을 확인하므로, 규칙의 문서 접근 한도에 걸리지 않는지 실제 건수로 쟀다

단위 테스트 121건 · 정책 테스트 249건 · lint · ktlint 통과.

배포 순서

규칙은 저장소 파일을 고치는 것만으로 적용되지 않는다. 머지로 새 테스터 빌드가 나간 뒤 firebase deploy --only firestore:rules 를 돌린다. 옛 빌드는 공유 일정 읽기는 그대로 되지만(감시자 문서가 이미 있다) 소유자 이름이 비고, 새로 가입하면 공유 코드를 못 만든다.

비공개 보안 권고 GHSA-5473-2vph-69w6.

「로그인했는가」 는 범위가 아니었다. Google 계정은 몇 초 만에 새로 만들 수 있어,
로그인만 조건으로 둔 컬렉션은 사실상 공개였다.

- publicProfiles 는 get 만 열고 list 를 막는다. 목록이 열려 있으면 문서 이름을
  몰라도 컬렉션을 통째로 훑을 수 있어 「아는 사람만 본다」 가 성립하지 않았다.
- 공유 코드를 공개 프로필에서 빼고, 코드를 문서 이름으로 삼는 등록부(shareCodes)로
  옮긴다. 중복 확인이 만들기 한 번으로 끝나 확인과 저장 사이의 틈도 함께 사라진다.
- 공유 일정의 읽기와 완료 변경을 그 코드의 감시자로 등록한 사람으로 좁힌다.
  읽기보다 이쪽이 더 아프다 — 남이 완료로 바꿔 두면 어르신이 약을 이미 먹은 줄로 안다.
- getUserNames 를 목록 질의에서 문서별 읽기로 바꾼다.
- 감시자 등록이 이제 읽기 권한의 근거라, FCM 토큰을 못 받아도 등록은 되게 한다.
  등록에 실패한 코드는 저장하지 않고 화면에 이유를 남긴다. 앞 코드도 그대로 둔다.
- 코드가 저장됐는데 등록만 실패한 채 남은 기기를 위해, 공유 일정을 구독하기 전에
  등록을 다시 세운다.

규칙 테스트에 제3자 계정을 넣어 읽기·완료 변경이 모두 막히는 것과, 공유 일정이
많아도 목록 조회가 규칙의 문서 접근 한도에 걸리지 않는 것을 실제 건수로 잠갔다.

비공개 보안 권고 GHSA-5473-2vph-69w6.
@OnlyReadOneBook
OnlyReadOneBook merged commit 3eea3ec into main Sep 6, 2026
13 checks passed
@OnlyReadOneBook
OnlyReadOneBook deleted the feat/174 branch September 6, 2026 06:46
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

❌ Screenshot test fail — baseline 과 CI rendered PNG 차이.

📦 Artifact: https://github.com/1hyok/SlowClock/actions/runs/34017573854 (페이지 하단 Artifacts → screenshot-test-results)

🔍 확인 위치 (artifact zip 내부):

  • diff PNG: preview/debug/diffs/...
  • rendered PNG: preview/debug/rendered/... (CI 환경에서 새로 그린 결과)
  • baseline PNG: repo <module>/src/screenshotTestDebug/reference/... (:app · :feature:main)

📝 조치 가이드:

  • 의도된 시각 변경 → 이 PR에 screenshot-baseline 라벨을 붙여 CI baseline 생성 요청
  • diff 가 anti-aliasing/font 차이로 보이면 docker 환경 변경 여부 (Dockerfile.screenshot) 점검

CI ↔ 로컬 환경 차이는 본 워크플로의 container 단계가 root fix 한다 (docs/testing/screenshot.md 참조).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: 공유 일정과 공개 프로필의 읽기 범위를 실제 관계로 좁힌다

1 participant