android flesh out
This commit is contained in:
211
docs/android-testing/INTERNAL_TESTING.md
Normal file
211
docs/android-testing/INTERNAL_TESTING.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Kordant Android — Internal Testing Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the internal testing process for the Kordant Android app.
|
||||
It covers tester onboarding, testing checklists, feedback collection, and iteration cycles.
|
||||
|
||||
## Play Store Internal Testing Setup
|
||||
|
||||
### 1. Create Internal Testing Track
|
||||
|
||||
1. Go to [Google Play Console](https://play.google.com/console)
|
||||
2. Navigate to **Testing → Internal testing**
|
||||
3. Create a new internal testing track
|
||||
4. Add testers by email address
|
||||
|
||||
### 2. Internal Testing Group (Target: 20+ testers)
|
||||
|
||||
Add the following categories of testers:
|
||||
|
||||
| Category | Count | Purpose |
|
||||
|----------|-------|---------|
|
||||
| Engineering team | 5-10 | Core functionality validation |
|
||||
| Product/QA | 3-5 | Feature verification |
|
||||
| Design | 1-2 | UI/UX validation |
|
||||
| External trusted | 10+ | Real-world device coverage |
|
||||
|
||||
### 3. Device Coverage
|
||||
|
||||
Ensure testers cover these Android versions and device types:
|
||||
|
||||
| Android Version | API Level | Priority |
|
||||
|----------------|-----------|----------|
|
||||
| Android 14 | 34 | High |
|
||||
| Android 13 | 33 | High |
|
||||
| Android 12 | 32 | Medium |
|
||||
| Android 11 | 30 | Medium |
|
||||
| Android 10 | 29 | Low |
|
||||
|
||||
| Device Type | Examples |
|
||||
|-------------|----------|
|
||||
| Pixel | Pixel 6, 7, 8, Fold |
|
||||
| Samsung | Galaxy S23, S24, Tab S9 |
|
||||
| Xiaomi | Redmi Note series |
|
||||
| OnePlus | OnePlus 11, 12 |
|
||||
| Foldable | Pixel Fold, Galaxy Z Fold |
|
||||
|
||||
## Test Invitation Email Template
|
||||
|
||||
```
|
||||
Subject: You're invited to test Kordant Android (Internal Testing)
|
||||
|
||||
Hi [Name],
|
||||
|
||||
You've been selected as an internal tester for the Kordant Android app.
|
||||
Your feedback will help us ship a polished, production-ready app.
|
||||
|
||||
**What to test:**
|
||||
- App installation and first launch
|
||||
- Authentication (email/password + Google Sign-In)
|
||||
- Dashboard and threat score display
|
||||
- Service screens (DarkWatch, VoicePrint, SpamShield, etc.)
|
||||
- Push notifications
|
||||
- Call screening (SpamShield)
|
||||
- Settings and preferences
|
||||
- Offline behavior
|
||||
- Performance (cold start, scrolling, animations)
|
||||
|
||||
**How to install:**
|
||||
1. Click the link below to join the internal testing program
|
||||
2. Open the Google Play Store on your Android device
|
||||
3. Search for "Kordant"
|
||||
4. Tap "Accept" to join as a tester
|
||||
5. The app will appear in your Play Store — tap "Install"
|
||||
|
||||
[INSERT PLAY CONSOLE TESTING LINK]
|
||||
|
||||
**Testing period:** [START DATE] to [END DATE]
|
||||
|
||||
**How to report issues:**
|
||||
- In-app: Use the feedback form in Settings
|
||||
- Email: testing@kordant.ai
|
||||
- Slack: #android-testing channel
|
||||
|
||||
Thank you for helping us build a great app!
|
||||
|
||||
The Kordant Team
|
||||
```
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Installation & First Launch
|
||||
- [ ] App installs from Play Store without errors
|
||||
- [ ] Cold start completes under 1.5 seconds
|
||||
- [ ] Splash screen displays correctly
|
||||
- [ ] No crashes on first launch
|
||||
|
||||
### Authentication
|
||||
- [ ] Email/password login works
|
||||
- [ ] Email/password signup works
|
||||
- [ ] Google Sign-In works
|
||||
- [ ] Forgot password flow works
|
||||
- [ ] Reset password flow works
|
||||
- [ ] Biometric authentication (if enabled)
|
||||
- [ ] Token refresh works silently
|
||||
- [ ] Logout clears all data
|
||||
|
||||
### Dashboard
|
||||
- [ ] Threat score displays correctly
|
||||
- [ ] Recent alerts load and display
|
||||
- [ ] Service summary cards show correct counts
|
||||
- [ ] Pull-to-refresh works
|
||||
- [ ] Alert detail navigation works
|
||||
- [ ] Service navigation works
|
||||
|
||||
### Services
|
||||
- [ ] DarkWatch screen loads watchlist
|
||||
- [ ] VoicePrint enrollment works
|
||||
- [ ] SpamShield rules display
|
||||
- [ ] HomeTitle properties load
|
||||
- [ ] RemoveBrokers listings display
|
||||
|
||||
### Notifications
|
||||
- [ ] Permission dialog shows on first launch (Android 13+)
|
||||
- [ ] Push notifications display correctly
|
||||
- [ ] Notification deep links route to correct screen
|
||||
- [ ] Different notification priorities display correctly
|
||||
|
||||
### Security Features
|
||||
- [ ] Certificate pinning active (check logs)
|
||||
- [ ] Encrypted storage for sensitive data
|
||||
- [ ] Root detection works (test on rooted device)
|
||||
- [ ] Permissions have rationale dialogs
|
||||
|
||||
### Performance
|
||||
- [ ] Cold start under 1.5s on Pixel 6
|
||||
- [ ] No ANRs when scrolling large lists
|
||||
- [ ] Image loading is smooth
|
||||
- [ ] Background sync doesn't drain battery
|
||||
|
||||
### Accessibility
|
||||
- [ ] TalkBack reads all interactive elements
|
||||
- [ ] All icons have content descriptions
|
||||
- [ ] Color contrast meets WCAG AA
|
||||
- [ ] Font scaling works up to 200%
|
||||
|
||||
### Offline Behavior
|
||||
- [ ] App works without network
|
||||
- [ ] Cached data displays when offline
|
||||
- [ ] Queue shows pending requests
|
||||
- [ ] Sync resolves when network returns
|
||||
|
||||
## Feedback Collection
|
||||
|
||||
### Channels
|
||||
1. **Play Console Feedback**: Testers can leave feedback directly in Play Store
|
||||
2. **In-app Feedback**: Settings → Help & Feedback
|
||||
3. **Slack**: #android-testing channel
|
||||
4. **Email**: testing@kordant.ai
|
||||
|
||||
### Feedback Template
|
||||
```
|
||||
**Issue Title:** [Brief description]
|
||||
**Device:** [Model, Android version]
|
||||
**Steps to Reproduce:**
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
**Expected:**
|
||||
**Actual:**
|
||||
**Screenshots:** (attach if possible)
|
||||
**Severity:** [Critical / High / Medium / Low]
|
||||
```
|
||||
|
||||
## Crash Reporting
|
||||
|
||||
Firebase Crashlytics is integrated and automatically reports:
|
||||
- Native crashes (Java/Kotlin)
|
||||
- ANRs (Application Not Responding)
|
||||
- Non-fatal exceptions
|
||||
- Custom logs
|
||||
|
||||
### Monitoring Dashboard
|
||||
- [Firebase Crashlytics Dashboard](https://console.firebase.google.com/project/kordant/crashlytics)
|
||||
- Alert configured for crash-free session rate < 99%
|
||||
|
||||
## Iteration Cycle
|
||||
|
||||
1. **Build** (Day 1): Fix critical bugs, prepare new AAB
|
||||
2. **Upload** (Day 1): Upload to internal testing track
|
||||
3. **Test** (Day 2-7): Testers validate, report issues
|
||||
4. **Triage** (Day 7): Review feedback, prioritize bugs
|
||||
5. **Fix** (Day 8-10): Address critical and high-priority issues
|
||||
6. **Repeat**: Upload new build every 1-2 weeks
|
||||
|
||||
## Known Issues
|
||||
|
||||
Track known issues in the project's issue tracker with label `android-internal-testing`.
|
||||
|
||||
| Issue | Severity | Status | Notes |
|
||||
|-------|----------|--------|-------|
|
||||
| [Link] | Critical | Open | Description |
|
||||
|
||||
## Promotion to Closed Testing
|
||||
|
||||
After internal testing validation:
|
||||
1. Create closed testing track in Play Console
|
||||
2. Set up Google Group for external testers
|
||||
3. Submit for Google review (may take 1-3 days)
|
||||
4. Recruit external testers via landing page
|
||||
5. Monitor crash-free rate and feedback
|
||||
119
docs/encrypted-storage-audit-report.md
Normal file
119
docs/encrypted-storage-audit-report.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Encrypted Storage Audit Report
|
||||
|
||||
## Overview
|
||||
Security audit of all local data storage in the Kordant Android app, completed as part of Android Production Readiness (Task 07).
|
||||
|
||||
## Audit Date
|
||||
2026-06-01
|
||||
|
||||
## Classification: Sensitive vs Non-Sensitive
|
||||
|
||||
### Sensitive Data (requires encryption at rest)
|
||||
| Data | Storage Location | Encryption | Reason |
|
||||
|------|-----------------|------------|--------|
|
||||
| Auth access token | `SecureStorageManager` (EncryptedSharedPreferences) | AES-256-GCM | Session credential |
|
||||
| Auth refresh token | `SecureStorageManager` (EncryptedSharedPreferences) | AES-256-GCM | Long-lived credential |
|
||||
| User profile (name, email, phone) | `SecureStorageManager` + `CacheManager` | AES-256-GCM + AES-256-GCM file | PII |
|
||||
| Biometric preference | `SecureStorageManager` (EncryptedSharedPreferences) | AES-256-GCM | Security-sensitive setting |
|
||||
| Subscription data | `CacheManager` (encrypted file) | AES-256-GCM file | Payment-related info |
|
||||
| Voice enrollments (biometric prints) | `CacheManager` (encrypted file) | AES-256-GCM file | Biometric data |
|
||||
| FCM device token | `SecureStorageManager` (EncryptedSharedPreferences) | AES-256-GCM | Device identifier |
|
||||
|
||||
### Non-Sensitive Data (plaintext acceptable)
|
||||
| Data | Storage Location | Notes |
|
||||
|------|-----------------|-------|
|
||||
| Theme preference (system/light/dark) | `UserPreferencesDataStore` | User setting, no PII |
|
||||
| Dark mode toggle | `UserPreferencesDataStore` | User setting |
|
||||
| Notification preferences | `UserPreferencesDataStore` | User setting |
|
||||
| Language/locale | `UserPreferencesDataStore` | User setting |
|
||||
| Onboarding completion | `UserPreferencesDataStore` | App state |
|
||||
| Watchlist items | `CacheManager` (plain file) | External entities being monitored |
|
||||
| Data exposures | `CacheManager` (plain file) | Public data breach records |
|
||||
| Alerts | `CacheManager` (plain file) | Notification records |
|
||||
| Spam rules | `CacheManager` (plain file) | Call filtering rules |
|
||||
| Properties | `CacheManager` (plain file) | Property addresses (public record) |
|
||||
| Voice analysis results | `CacheManager` (plain file) | Analysis output, not raw prints |
|
||||
| Broker listings | `CacheManager` (plain file) | Public broker data |
|
||||
| Removal requests | `CacheManager` (plain file) | Request status |
|
||||
| Pending request queue | `cacheDir/pending_requests.json` | Offline queue (transient) |
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### 1. Two-tier Secure Storage
|
||||
- **`SecureStorageManager`**: Wraps `EncryptedSharedPreferences` (AES-256-GCM, key in Android Keystore) for persistently stored secrets that survive app restarts (auth tokens, biometric pref, cached user profile).
|
||||
- **`CacheManager` (encrypted mode)**: AES-256-GCM file-level encryption for TTL-bounded cached responses containing PII. Uses a derived key (acceptable for transient cache data).
|
||||
|
||||
### 2. DataStore for Non-Sensitive Preferences
|
||||
- `UserPreferencesDataStore` uses `androidx.datastore:datastore-preferences` for non-sensitive user settings.
|
||||
- Replaces in-memory-only preferences (previous state: ViewModels held settings in memory without persistence).
|
||||
- Excluded from encrypted storage because these settings contain no PII or credentials.
|
||||
|
||||
### 3. Secure Deletion Strategy
|
||||
- **Overwrite-before-remove**: Sensitive keys in `SecureStorageManager` are overwritten with random data 3× before removal.
|
||||
- **Logout**: Clears auth tokens (with overwrite), cache files (with secure delete), and DataStore preferences.
|
||||
- **Account deletion (GDPR)**: `clearAllData()` removes absolutely everything including biometric preferences.
|
||||
|
||||
### 4. Cache Security
|
||||
- **50 MB size limit**: CacheManager enforces a global 50 MB limit with LRU-like eviction (oldest files deleted first).
|
||||
- **Sensitive key encryption**: Cache files for `current_user`, `subscription`, and `voice_enrollments` are AES-256-GCM encrypted.
|
||||
- **Secure eviction**: When evicting cache files, sensitive ones are overwritten with random data before deletion.
|
||||
|
||||
### 5. Backup Exclusion Strategy
|
||||
- **`kordant_secure_storage.xml` and `kordant_auth_prefs.xml`**: Excluded from both cloud backup and device transfer because:
|
||||
- Master key is device-bound (Android Keystore), so backup would be undecryptable on another device.
|
||||
- Auth tokens and PII should not persist across device transfers for security reasons.
|
||||
- **`kordant_user_preferences.xml` (DataStore)**: Included in backup (non-sensitive settings).
|
||||
- **Cache directories**: Excluded from backup (rebuilt from API).
|
||||
- **Cached PII files**: Explicitly excluded from file-level backup.
|
||||
|
||||
## Before vs After
|
||||
|
||||
### SharedPreferences
|
||||
| Before | After |
|
||||
|--------|-------|
|
||||
| Auth tokens in `EncryptedSharedPreferences` (but duplicated in `AuthRepository` and `AuthInterceptor` with separate instances) | Unified `SecureStorageManager` singleton accessed via `KordantApp.secureStorageManager` |
|
||||
| Biometric pref in plain `SharedPreferences`: `kordant_biometric_prefs` | Migrated to `EncryptedSharedPreferences` via `SecureStorageManager` |
|
||||
| No user profile persistence | User profile persisted in `SecureStorageManager` (encrypted) |
|
||||
|
||||
### DataStore
|
||||
| Before | After |
|
||||
|--------|-------|
|
||||
| No DataStore usage (settings were in-memory only in ViewModels) | `UserPreferencesDataStore` for theme, language, notification preferences, onboarding status |
|
||||
|
||||
### CacheManager
|
||||
| Before | After |
|
||||
|--------|-------|
|
||||
| All cache files in `cacheDir/*.cache` in plain JSON | Sensitive keys (`current_user`, `subscription`, `voice_enrollments`) encrypted with AES-256-GCM on disk |
|
||||
| No cache size limit | 50 MB limit with automatic eviction |
|
||||
| Simple `file.delete()` | Secure overwrite + delete for sensitive cache files |
|
||||
|
||||
### Backup Rules
|
||||
| Before | After |
|
||||
|--------|-------|
|
||||
| Default rules (everything included) | Encrypted prefs explicitly excluded; only non-sensitive DataStore included |
|
||||
|
||||
## Verification Checklist
|
||||
- [x] All sensitive data in EncryptedSharedPreferences
|
||||
- [x] Auth tokens encrypted at rest
|
||||
- [x] Refresh tokens encrypted at rest
|
||||
- [x] Non-sensitive preferences in DataStore
|
||||
- [x] No sensitive data in unencrypted cache
|
||||
- [x] Secure deletion overwriting data
|
||||
- [x] Sensitive storage excluded from backup
|
||||
- [x] Logout clears all auth data
|
||||
- [x] Account deletion removes all local data
|
||||
- [x] No plaintext sensitive data discoverable in app files
|
||||
|
||||
## Verification Commands (for QA)
|
||||
```bash
|
||||
# Check that encrypted prefs file exists and is binary (not plaintext)
|
||||
# File is at /data/data/com.kordant.android/shared_prefs/kordant_secure_storage.xml
|
||||
# It should NOT contain plaintext values
|
||||
|
||||
# Check that unencrypted cache files don't contain PII
|
||||
# Files at /data/data/com.kordant.android/cache/*.cache
|
||||
# grep for email, token, name patterns - should find nothing for sensitive keys
|
||||
|
||||
# Verify backup exclusion
|
||||
# Check backup_rules.xml and data_extraction_rules.xml exclude encrypted prefs
|
||||
```
|
||||
Reference in New Issue
Block a user