Community feature#121
Merged
Merged
Conversation
A pilot-only social network on Firestore, gated behind the same RevenueCat Pro entitlement as Flight Intelligence and Backup/Sync. Features: - Create, discover, join, and leave groups (public or private) - Private groups: discoverable by name, owner approves each request - Per-group feed with posts (1000 chars + optional ICAO tag) - Members tab with owner-only approve/reject/remove controls - Editable pilot profile (name, home airport, ratings, aircraft, bio) - iOS/Android only, in-app notifications only (red badge on Members tab) Backend: - firestore.rules with self-only profile writes, owner-only deletes, public/private feed gating, and counter-only updates for members - firestore.indexes.json + .firebaserc preconfigured for the project - All Firestore access funneled through CommunityRepository UI: - Entry point: Pro Services bottom sheet -> Community - Routed at /community via the existing showPaywall(...) helper - Friendly setup banner shown if Firestore rules haven't been deployed Docs: - USER_MANUAL.md: new section 11.4, updated Pro row in platform table, six new entries in the Section 14 path index, UC-24 and UC-25 added Co-authored-by: Cursor <cursoragent@cursor.com>
Fixes the security audit findings on the v1 Community rules. All changes are rules-only except a small members-screen tweak so that non-members of private groups see a friendly message instead of a raw permission-denied error. Critical / high: - Counter updates now require an exact +/-1 delta and forbid negative values, instead of allowing any signed-in user to set memberCount and postCount to arbitrary numbers (audit #1). Long-term fix is a Cloud Function trigger; documented in the rules file. - All user-writable documents (profile, group, member, post, userGroups index) are now whitelisted on field keys and validated on types, lengths, and enum values, closing latent privilege escalation paths and DoS via oversized documents (audit #2, #4, #8, #12, #13). - Removed the unconstrained isGroupOwner(gid) branch on member create. Owner approvals now flow through update of an existing pending doc, with status pinned to pending -> active and role/joinedAt frozen (audit #3). Medium: - Member rosters are no longer enumerable by strangers. Reads of groups/{gid}/members require self, owner, public visibility, or active membership (audit #6). - Posts are now bounded to 1000 characters at the rule level (audit #7) and to a fixed field whitelist (audit #8). Hardening: - isActiveMember consolidated to a single get() lookup pattern via helper functions (audit #10 partial). - All timestamps validated as `is timestamp`; full server-timestamp enforcement deferred to a future Cloud Function (audit #13). Knowingly not fixed in v1 (documented inline): - Group metadata visibility: the group doc remains readable by any signed-in pilot so the Discover tab can surface private groups by name. Sensitive future fields must live in a separate restricted subcollection (audit #5). - Counter drift under adversarial use: ruled-bounded to +/-1 per call; long-term fix requires Cloud Functions (audit #11). - Owners can technically self-delete their membership through this rule; rules cannot distinguish "owner leaves" from "owner deletes group". The client repository blocks owner-leave at call time (audit #9). Co-authored-by: Cursor <cursoragent@cursor.com>
Fixes "Looking up a deactivated widget's ancestor is unsafe" crash when a Join/Leave/Delete future completes after the user has navigated away from the screen. - JoinLeaveButton._say bails when the button is unmounted before invoking the parent's onMessage closure. This was the source of the reported stack: _say -> onMessage -> Toast.showToast -> Theme.of against a deactivated element. - _MembershipBanner.onMessage additionally guards with context.mounted since it is a StatelessWidget whose element can be deactivated by a parent rebuild while the child button is still mounted. - Four other catch blocks (group create, post compose, profile edit, group delete) wrap their Toast.showToast call in a mounted check so failed-write toasts cannot fire after navigation. Co-authored-by: Cursor <cursoragent@cursor.com>
- New _DisclaimerStrip widget shown above the tabs on the main
Community screen: a compact, always-visible reminder that tap-opens
the full disclaimer.
- Info icon in the AppBar opens the same disclaimer dialog so it's
reachable from anywhere on the screen.
- Four points covered in the dialog:
* Apps4Av is not responsible for data loss
* Don't share sensitive information
* Apps4Av does not moderate community activity
* Apps4Av will not share data with third parties
- USER_MANUAL section 11.4 lists the same four points.
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.