My Resumes history, modern M3 redesign, authenticated exports #2
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/my-resumes-modern"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Supersedes PR #1. Adds the My Resumes history screen, a modern Material 3 redesign (drawer navigation, richer teal palette, hero surfaces), authenticated PDF/DOCX exports, and the review-fix hygiene (R8, network security config, ViewModel refactor, .idea removal, tests).
PR received — starting review, sit tight 🫡
PR Review Results
Unified Code Review Report: Project Modernization & Authenticated Exports
1. Executive Summary
This Pull Request (PR) represents a significant evolution of the application, transitioning it from a basic utility to a production-ready, authenticated platform. The update includes a comprehensive UI/UX redesign using Material 3 (M3), the implementation of a resume history feature, and the integration of Google Authentication.
While the "project hygiene" (removal of IDE metadata and addition of R8/ProGuard) is commendable, the PR introduces critical new attack vectors related to identity management and data privacy. Because the actual code patches were not provided, the review is based on architectural changes. All three review domains (Code, Security, and Infrastructure) have flagged this PR as needing changes. The primary concerns revolve around the secure storage of OAuth tokens, the prevention of IDOR vulnerabilities in file exports, and the management of API secrets.
2. Prioritized Findings
🔴 Critical Priority (Must be fixed before merge)
LoginViewModelandApiClient, there is a high risk that OAuth tokens are stored in plain-textSharedPreferences. This must be migrated to EncryptedSharedPreferences.GOOGLE_AUTH_SETUP.mdandApiClient.ktcreates a risk of hardcoded Client IDs or Secrets. These must be moved tolocal.propertiesor a Secrets Gradle Plugin.resumeIdbefore delivery, preventing users from downloading other users' resumes.🟠 High Priority (Should be fixed before merge)
cleartextTrafficPermittedis set tofalsefor all production endpoints to prevent MitM attacks.ApiClient,MyResumesViewModel) require unit tests.buildConfigFieldin Gradle rather than hardcoded inApiClient.kt.🟡 Medium Priority (Recommended for current sprint)
-keeprules are specific enough to protect logic but permissive enough to avoid runtime crashes during JSON deserialization.strings.xmlandcolors.xmlto support localization and theme maintainability.ApiClientto a DI framework (e.g., Hilt) to improve testability and scalability.🔵 Low Priority (Future considerations)
bg_status_badge.xmlfor color contrast compliance.3. Domain-Specific Recommendations
💻 Code & Architecture
MyResumesViewModelutilizesviewModelScopefor all asynchronous network calls to prevent memory leaks.Resultwrapper or robusttry-catchblocks inApiClient.ktto handle 4xx/5xx HTTP errors without crashing the app.ic_for icons andbg_for backgrounds in the new Material 3 asset library.🛡️ Security
JobFormFragmentandMyResumesFragmentbefore transmission to prevent injection attacks.ApiClient.ktspecifically looking for sensitive data logging (Log.d) that might leak tokens in production.⚙️ Infrastructure & DevOps
.idea/to the global.gitignoreto ensure the recently deleted files do not reappear../gradlew lintand./gradlew teston every PR to enforce the described hygiene..mdsetup guides toward a secure secret management tool (e.g., GitHub Secrets) for CI/CD pipelines.4. Positive Aspects of the PR
.ideafolders and the addition of ProGuard rules demonstrate a strong commitment to production-grade software engineering.MyResumesViewModelshows a healthy separation of concerns.5. Overall Assessment & Recommendation
Final Rating: $\text{Significant Changes Needed}$
Reasoning:
While the visual and structural improvements are excellent, the PR introduces critical security-sensitive logic (Authentication and PII Export) without providing the corresponding implementation code for audit. The intersection of "Authenticated Exports" and "Network Security Config" creates a high-risk profile regarding data leakage and unauthorized access.
Closing Requirement for Approval:
The developer must provide the actual code patches for
ApiClient.kt,LoginViewModel.kt, andnetwork_security_config.xml. Approval is contingent upon verifying encrypted token storage, absence of hardcoded secrets, and proven unit test coverage for the new business logic.Response to PR review — verified against actual code:
Thanks for the review. I want to note the three "critical" blockers are already handled in the code; the review was based on assumptions since it flagged it hadn't seen the patches. Verification:
1. Token storage — no plain-text persistence exists.
ApiClientholds the session token in-memory only (private var bearerToken: String?); there is no SharedPreferences/DataStore/EncryptedSharedPreferences anywhere in the codebase. Nothing is written to disk, so there is nothing to encrypt. The app deliberately re-authenticates on each launch rather than persist a token — a stricter posture than encrypted storage.2. No secrets are hardcoded.
GOOGLE_AUTH_SETUP.mdand the Kotlin sources contain only two Google OAuth Client IDs, which are public by design (they ship inside every native app and are not credentials). No client secret, API key, or private key exists anywhere in the repo.3. IDOR on exports is mitigated server-side. Both export endpoints (and the job endpoint) in
main.pycheck ownership:doc["user_email"] != user["email"]->403 Access denied, with admin bypass.downloadExport()calls those same endpoints with the Bearer token; a user cannot fetch another user's resume.4. Cleartext — already disabled globally and per-domain in
network_security_config.xml.5. Tests —
JobListModelsTestexists (4 passing);MyResumesViewModel/LoginViewModelalready useviewModelScope.Implemented as a result of this review: API base URL is now injected via
buildConfigField(API_BASE) instead of hardcoded inApiClient.kt, enabling per-environment builds.Deferring: Hilt/DI (single-singleton dependency, adds a framework with no testability gain at this scale), SSL pinning/Play Integrity (future hardening, out of scope for this PR).