Commit Graph

27 Commits

Author SHA1 Message Date
null b64ae1f29a fix: block answer delete in rules, enforce userId match on create (batch v1.0.18) 2026-06-20 01:19:02 -05:00
null 8de5990230 fix: add Tink dependency, release key cleanup, rules hardening (batch v1.0.17) 2026-06-20 01:10:20 -05:00
null 84eab1825b feat: add thread sealed answers, release key cleanup, rules hardening (batch v1.0.16) 2026-06-20 00:41:48 -05:00
null 4900d8ab6b fix: add answerDate to Firestore rules allowed fields (batch v1.0.15) 2026-06-20 00:26:52 -05:00
null a3993d08df feat: implement partner-proof sealed answers (batches 1-8)
- UserKeyManager: per-user keypair stored in Android Keystore
- SealedAnswerEncryptor: one-time answer key, sealed:v1 ciphertext
- PendingAnswerKeyStore: local EncryptedSharedPreferences storage
- ReleaseKeyEncryptor: keybox:v1 encrypted to recipient public key
- SealedRevealManager: full reveal flow with mutual key release
- AnswerCommitment: SHA-256 commitment hash over canonical payload
- FirestoreDeviceKeyDataSource: public key CRUD
- FirestoreReleaseKeyDataSource: release key CRUD
- FirestoreAnswerDataSource: sealed answer writes with schemaVersion=3
- FirestoreCollections: sealed answer and release key paths
- firestore.rules: ownership, immutability, timing, prefix enforcement
- HomeViewModel: sealed answer state integration
- AnswerRevealScreen/ViewModel: sealed reveal flow with UX states
- CloserApp: initialize UserKeyManager on startup
- LocalAnswer model: schemaVersion field
- Unit tests: SealedAnswerEncryptor, ReleaseKeyEncryptor, AnswerCommitment
- Crypto test vectors: docs/crypto/sealed-answer-test-vectors.json
- .gitignore: add partner-proof build plan
2026-06-20 00:23:58 -05:00
null 8be7b7da0e chore: update couple create rule comment to reflect server-only flow (batch v0.2.20) 2026-06-19 21:52:19 -05:00
null 39255c8733 fix: prevent invite code enumeration via Cloud Function (batch v0.2.18)
- Remove client-side read access to invites (only inviter can read own invite)
- Deny direct client update to invites (server-side only via Admin SDK)
- Add acceptInviteCallable Cloud Function: validates code, creates couple,
  updates user docs, marks invite accepted, returns wrapped key for local decryption
- Update Android client: FirestoreInviteDataSource calls callable function,
  InviteConfirmViewModel uses acceptInvite + unwrapAndStore flow
- Deprecate CoupleRepositoryImpl.createCouple (client-side path removed)
- Update Firestore rules tests: unpaired read now denied, direct update now denied
- 118/118 tests passing
2026-06-19 21:46:12 -05:00
null 70bb0a346c fix: normalize crypto files to plain ASCII (batch v0.2.14)
- Replace smart quotes, em dash, prime, right arrow in comments with ASCII equivalents
- Affected: CoupleEncryptionManager.kt, FieldEncryptor.kt, RecoveryKeyManager.kt
2026-06-19 21:22:27 -05:00
null 55ca3dce27 fix: Firestore rules hardening, recovery phrase strength, test cleanup (batch v0.2.12)
- Firestore rules: add isCouplesMember(coupleId) to question thread answer writes (prevents outsider writes)
- Firestore rules: allow currentIndex increment on same-status session updates (fixes thread progression)
- RecoveryKeyManager: PHRASE_WORD_COUNT 6→10 (~80 bits entropy)
- build.gradle.kts: exclude META-INF/versions/9/OSGI-INF/MANIFEST.MF (packaging conflict)
- .gitignore: add firebase-debug.log, firestore-debug.log
- firestore-tests: configurable emulator port via FIRESTORE_EMULATOR_PORT env var
- firestore-tests: fix invite outsider test (seed with different coupleId), fix non-starter session test (active→completed allowed), remove redundant beforeEach(seedThread), add outsider-write-denied test for thread answers
- visual-identity.md: update encryption claim gating note
2026-06-19 21:08:55 -05:00
null 3233c54ab2 feat: strict E2EE — encryption migration, Firestore rules enforcement, version 2 protocol (batch v0.2.11)
- Add CoupleAnswerMigrationDataSource: one-time per-user rewrite of all historical answer-bearing fields (daily answers, thread answers/messages, ThisOrThat, DesireSync, HowWell, Wheel) to ciphertext
- Add EncryptionUpgradeScreen + ViewModel: handles version-0→1→2 migration, recovery phrase display, partner coordination
- Add FieldEncryptorTest: round-trip, cross-couple binding, null-key, plaintext-not-leaked
- CoupleEncryptionManager: STRICT_ENCRYPTION_VERSION=2, requireAead() throws on missing key, setupLegacyCouple, pendingRecoveryPhrase/acknowledge
- CoupleKeyStore: pending recovery phrase storage/clear
- FieldEncryptor: switch from android.util.Base64 to java.util.Base64
- All data sources: use requireAead() (throws instead of silent plaintext fallback), encrypt all answer-bearing writes
- FirestoreCoupleDataSource: beginEncryptionMigration (atomic version-0→1 claim), markEncryptionMigrationComplete (per-user + version-2 promotion)
- CoupleRepositoryImpl: require wrappedKey on invite acceptance (no more optional)
- HomeScreen/ViewModel: route to EncryptionUpgradeScreen for version-0 or unmigrated version-1 couples
- Firestore rules: isCiphertext validator, isEncryptedAnswerPayload, isStartingEncryptionMigration, isCompletingOwnEncryptionMigration, isUpdatingRecoveryWrap, isUpdatingCoupleRhythm; enforce ciphertext on all answer/message writes; game collection rules (this_or_that, desire_sync, how_well, wheel) with per-user answer ownership; couple doc update split into 4 mutually exclusive paths; invite doc requires createdAt + wrappedKey fields; isImmutable uses diff().hasAny() instead of field equality
- Firestore rules tests: encryption migration scenarios, plaintext rejection, per-user answer ownership, game collection ciphertext enforcement
- firebase.json: emulator port 8180
- .gitignore: firestore-tests/node_modules
2026-06-19 20:53:52 -05:00
null e7b45cc84f fix: profile photo temp dir, Firestore rules field-level lockdown (batch v0.2.10)
- Move temp profile photos to filesDir/photos/ subdirectory with mkdirs
- Update file_paths.xml to scope FileProvider to photos/ subdirectory
- Firestore rules: restrict couple doc updates to only mutable fields (streakCount, lastAnsweredAt, wrappedCoupleKey, kdfSalt, kdfParams, encryptionVersion) — prevents client from overwriting currentQuestionId, activePackId, id
2026-06-19 20:33:08 -05:00
null 30fddcc2df feat: E2EE — Tink AEAD, Argon2id KDF, recovery phrase, encrypted Firestore fields (batch v0.2.6)
- Add crypto module: CoupleKeyStore (EncryptedSharedPreferences), RecoveryKeyManager (Argon2id + AES-256-GCM key wrap), FieldEncryptor (AEAD per-field), CoupleEncryptionManager (orchestration)
- Add Tink + Bouncy Castle dependencies to build.gradle.kts, register AeadConfig in CloserApp
- Encrypt answer fields (writtenText, selectedOptionIds, scaleValue) on write, decrypt on read
- Encrypt DesireSync, HowWell, WheelAnswer, QuestionThread fields via CoupleEncryptionManager
- Generate recovery phrase during invite creation, display in CreateInviteScreen
- Add recovery phrase input to InviteConfirmScreen for encrypted invites
- Add RecoveryScreen + RecoveryViewModel for post-pairing key recovery
- Update Couple model with encryptionVersion, wrappedCoupleKey, kdfSalt, kdfParams
- Update Firestore rules: allow couple doc creation by members, fcmTokens path, encryptionVersion monotonic check, invite doc extended fields
2026-06-19 19:52:35 -05:00
null 9e587a23dd feat: update question thread data source, repository, ViewModel, and Firestore security rules 2026-06-19 03:19:58 -05:00
null eaac8ffcc9 feat: couple-scoped daily question, answer sync, partner notifications, and answer review 2026-06-18 00:18:05 -05:00
null d86a5de2a0 fix: deny client access to entitlement_events collection 2026-06-17 19:42:41 -05:00
null 19c6b4a6cb fix: real uid in bucket list, Firestore rules hardening for date plans & bucket list 2026-06-17 19:41:27 -05:00
null b049024ba9 feat: update date_plan_preferences Firestore rules to use auto-IDs 2026-06-17 19:12:14 -05:00
null 2b1238a64c feat: add Firestore rules for entitlements and notification_queue collections 2026-06-17 19:10:45 -05:00
null 557af3e546 feat(dates): add Date Builder + Bucket List — backend models, Room DAOs, Firestore sources, repositories, UI screens, ViewModels, navigation routes, Firestore rules 2026-06-17 00:05:46 -05:00
null 512a6c9f42 feat(dates): add Date Match MVP Phase 1 — swipe UI, Firestore models, 30+ seed ideas, match reveal 2026-06-16 23:30:58 -05:00
null a412247bf3 security: kimi-k2.7 review fixes — Ed25519 crypto API, Firestore rules try/catch removal, atomic idempotency, RevenueCat 8.20.0, rate limiter fix, remove plaintext fallback, tighten push wording 2026-06-16 22:42:53 -05:00
null b8b2cc68c4 security: fix webhook signature fail-open (now throws 500 on missing key), fix overly restrictive couple update rules 2026-06-16 22:11:51 -05:00
null c28ce9c58d security: restrict couple-level Firestore writes — immutable fields, owner-only messages/reactions, server-only deletes, valid state transitions 2026-06-16 21:46:56 -05:00
null bd1ea5cecd security: fix invite rules missing-doc bypass, webhook timing attack, entitlement replay protection and entitlement_id check 2026-06-16 21:45:04 -05:00
null afeb1a1a03 docs: add README, add proguard rules, Firestore entitlement checker, network security config, update build config and onboarding 2026-06-16 20:16:47 -05:00
null e42de938e7 fix: update Invite model, backup rules, and Firestore security rules 2026-06-16 19:44:28 -05:00
null 1a33d4f2b9 feat(analytics): Firebase Analytics, Crashlytics, ObservabilityModule, Firestore rules 2026-06-16 01:13:20 -05:00