-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Executive Summary
This codebase review of the Sobers recovery app (Expo 54/React Native 0.81) reveals a well-maintained, production-ready application with solid architecture, comprehensive testing (97 test files), and proper error tracking integration. The main areas requiring attention are: (1) a security concern with Math.random() for invite codes, (2) privacy-sensitive Sentry configuration, and (3) skipped tests that need resolution.
Health Score: B+
Justification: Strong fundamentals with excellent test coverage structure, proper logging patterns, and good separation of concerns. Deductions for the security issue with random invite code generation, sendDefaultPii: true in Sentry config, and skipped tests. The codebase shows active maintenance with recent improvements.
Top 5 Priority Items
| Priority | Finding | Severity | Effort |
|---|---|---|---|
| 1 | Security: Math.random() used for invite code generation |
HIGH | Low |
| 2 | Privacy: Sentry sendDefaultPii: true sends PII |
MEDIUM | Low |
| 3 | Bug: useFrameworkReady hook missing dependency array |
MEDIUM | Low |
| 4 | Testing: Skipped MeetingsScreen tests need fixing | MEDIUM | Medium |
| 5 | Code Smell: SettingsContent.tsx setTimeout without cleanup | LOW | Low |
Detailed Findings
🔴 Security Issues
1. Insecure Random Number Generation for Invite Codes
- File:
app/(app)/(tabs)/profile/index.tsx:169 - Issue: Uses
Math.random().toString(36).substring(2, 10).toUpperCase()for invite code generation - Risk:
Math.random()is not cryptographically secure and produces predictable values - Recommendation: Use
crypto.getRandomValues()for secure random generation - Note: Issue security: Replace Math.random() with crypto.getRandomValues() for invite codes #320 already tracks this - verify if implemented
2. Sentry PII Configuration
- File:
lib/sentry.ts:78 - Issue:
sendDefaultPii: truesends user IP addresses and other PII to Sentry - Risk: Privacy compliance concerns (GDPR, CCPA)
- Recommendation: Set to
falseand rely on privacy hooks for selective data collection - Note: Previous issue security: Disable sendDefaultPii in Sentry configuration #348 tracked this - verify current state
🟡 Code Health Issues
3. Missing Dependency Array in useFrameworkReady
- File:
hooks/useFrameworkReady.ts:10-12 - Issue:
useEffectcalled without dependency array causes re-run on every render - Code:
useEffect(() => { window.frameworkReady?.(); }); // Missing []
- Recommendation: Add empty dependency array
[]for mount-only behavior - Note: Issue 🐛 useFrameworkReady hook missing dependency array causes effect to run on every render #308 already tracks this
4. Skipped Tests in MeetingsScreen
- File:
__tests__/app/program/meetings.test.tsx:106 - Issue: Entire
MeetingsScreentest suite is skipped withdescribe.skip - Reason: "Fix mock setup - tests fail with Unable to find node on an unmounted component"
- Impact: Reduced test coverage for critical meeting tracking feature
- Note: Issues test: Fix skipped MeetingsScreen tests in meetings.test.tsx #354, 🧪 Fix skipped MeetingsScreen tests #360, test: Fix skipped MeetingsScreen tests in meetings.test.tsx #344 track this
5. setTimeout Without Cleanup
- File:
components/settings/SettingsContent.tsx:607 - Issue:
setTimeout(() => setCopiedField(null), 2000)without cleanup - Risk: Potential memory leak if component unmounts before timeout
- Recommendation: Use
useRefto track timeout and clear in cleanup
🟢 Positive Observations
- No
console.login production code - Proper logger usage enforced - No hardcoded secrets - Environment variables properly used
- No
dangerouslySetInnerHTMLoreval()- No XSS vectors found - Privacy hooks implemented -
sentry-privacy.tsstrips sensitive data - Comprehensive test structure - 97 test files covering all major areas
- Strong TypeScript usage - Strict mode enabled
- OAuth implementation - Robust handling with race condition guards
Test Coverage Analysis
- Total Test Files: 97
- Skipped Test Suites: 2 (MeetingsScreen, one navigation test)
- Coverage Goal: 80% (per CLAUDE.md)
Missing Test Coverage Areas:
components/program/DayDetailSheet.tsx- No dedicated test filecomponents/program/LogMeetingSheet.tsx- No dedicated test filecomponents/program/MeetingListItem.tsx- No dedicated test file
🔄 Documentation Status
- CLAUDE.md: Current and comprehensive
- README.md: Accurate project structure, up-to-date commands
- Project structure in README: Matches actual codebase
Dependency Health
Key Dependencies (all recent versions):
- expo: ~54.0.32 ✅
- react: 19.1.0 ✅
- react-native: 0.81.5 ✅
- @supabase/supabase-js: ^2.93.2 ✅
- @sentry/react-native: 7.2.0 ✅
- typescript: ~5.9.3 ✅
No critical security vulnerabilities detected in primary dependencies.
Existing Issues Relevant to Findings
Several findings are already tracked:
- 🐛 useFrameworkReady hook missing dependency array causes effect to run on every render #308 - useFrameworkReady hook missing dependency array
- security: Replace Math.random() with crypto.getRandomValues() for invite codes #320 - Replace Math.random() with crypto.getRandomValues()
- security: Disable sendDefaultPii in Sentry configuration #348 - Disable sendDefaultPii in Sentry
- test: Fix skipped MeetingsScreen tests in meetings.test.tsx #354, 🧪 Fix skipped MeetingsScreen tests #360, test: Fix skipped MeetingsScreen tests in meetings.test.tsx #344 - Fix skipped MeetingsScreen tests
- refactor: Split SettingsContent.tsx (2,088 lines) into focused modules #346 - Split SettingsContent.tsx (2,088 lines)
Recommendations
Immediate Actions
- Verify security: Replace Math.random() with crypto.getRandomValues() for invite codes #320 (Math.random replacement) is merged - HIGH priority security fix
- Verify security: Disable sendDefaultPii in Sentry configuration #348 (sendDefaultPii: false) is merged - Privacy compliance
- Resolve 🐛 useFrameworkReady hook missing dependency array causes effect to run on every render #308 (useFrameworkReady dependency array)
Short-term
- Fix MeetingsScreen test mock setup to restore test coverage
- Add missing tests for DayDetailSheet, LogMeetingSheet, MeetingListItem
- Add setTimeout cleanup in SettingsContent.tsx
Long-term
- Consider splitting AuthContext.tsx (647 lines) into smaller contexts
- Implement global data fetching layer (React Query) for consistency
- Continue addressing SettingsContent.tsx refactoring (refactor: Split SettingsContent.tsx (2,088 lines) into focused modules #346)
Generated by automated daily codebase review