Ubisam-MobileGit/tasks/011-login-repository-list.md

72 lines
4.2 KiB
Markdown

# TASK-011: Sign in and list accessible repositories
Status: complete
Owner: Codex
Reviewer: Claude
## Outcome
A user can sign in to the configured company Gitea through the system browser and see every repository visible to that account in a localized read-only list.
## Scope
- Included: system-browser OAuth, verified HTTPS App Link callback, PKCE code exchange, authenticated identity check, Keystore-backed token storage, logout, paged `/user/repos` loading, and login/loading/content/empty/error UI states.
- Excluded: branches, file browsing, commits, diffs, pull requests, issues, offline repository caching, and every write operation.
## Writable paths
- `app/build.gradle.kts`
- `gradle/libs.versions.toml`
- `app/src/main/AndroidManifest.xml`
- `app/src/main/java/com/ubisam/ubgitea/MainActivity.kt`
- `app/src/main/java/com/ubisam/ubgitea/core/auth/android/`
- `app/src/main/java/com/ubisam/ubgitea/core/network/`
- `app/src/main/java/com/ubisam/ubgitea/data/auth/`
- `app/src/main/java/com/ubisam/ubgitea/data/repositories/`
- `app/src/main/java/com/ubisam/ubgitea/feature/repositories/`
- Matching test paths
- `app/src/main/res/values/strings_repositories.xml`
- `app/src/main/res/xml/data_extraction_rules.xml`
- `tasks/002b-oauth-android-integration.md`
- `tasks/004-gitea-api-client.md`
- `tasks/005-repository-branch-ui.md`
- `tasks/011-login-repository-list.md`
- `docs/development-log.md`
## Acceptance criteria
- [x] Login opens an external browsable HTTPS intent and no WebView dependency or component exists.
- [x] The manifest accepts only the configured verified HTTPS callback host and path.
- [x] Callback processing uses TASK-002A validation and clears pending verifier/state on every terminal result.
- [x] Code exchange sends client ID, redirect URI, original verifier, and no client secret.
- [x] Access/refresh tokens are encrypted with an Android Keystore key, excluded from backup, redacted from string output, and removed on logout.
- [x] The authenticated `/api/v1/user` call confirms the account before repository loading.
- [x] `/api/v1/user/repos` follows pagination to completion, deduplicates by stable repository ID, and has a bounded page count.
- [x] DTOs remain in data packages; UI models contain no token, HTTP, or Android persistence types.
- [x] UI has localized signed-out, browser-waiting, loading, content, empty, authentication-expired, permission-denied, offline, and server-error states.
- [x] Repository rows identify owner/name, visibility, optional description, and default branch; logout is explicit.
- [x] Unit tests cover exchange form, callback terminal clearing, token codec, repository mapping/pagination/deduplication, and error mapping.
- [x] Build, unit tests, lint, focused tests, secret scan, and independent review pass.
## External evidence
- OAuth application is configured as a public client with the registered redirect URI.
- `https://gitea.ubisampaju.synology.me/.well-known/assetlinks.json` publicly serves `com.ubisam.ubgitea` with both development certificate fingerprints.
## Required checks
```text
./gradlew assembleDebug
./gradlew testDebugUnitTest
./gradlew lintDebug
```
## Evidence
- `./gradlew testDebugUnitTest assembleDebug lintDebug` — passed; 57 tests across 16 suites, 0 failures/errors; debug APK and lint report generated.
- Focused authentication, callback, token-codec, HTTP transport, repository pagination/mapping, error mapping, and immutable UI-state tests passed.
- `git diff --check` and the sensitive-pattern scan passed; no WebView or production client secret exists.
- Independent review confirmed the browser/App Link, PKCE, Keystore/backup, identity-before-repositories, and bounded pagination design. Its P1 browser-cancellation, response-read, and token-retained error-recovery findings were fixed, together with signed-in error/logout UX, nullable DTO validation, immutable snapshots, and focused regression tests. Final re-review found no remaining P0/P1.
- Hosted `assetlinks.json` was visually confirmed by the product owner with both development signing fingerprints.
- Product-owner device E2E on 2026-08-25 passed: account login returned through the verified App Link and the app displayed the accessible internal repository list from the production Gitea instance.