CLAUDE.md
feature/auth/CLAUDE.mdCLAUDE.md
Quality
58/100
Scores the file, not the repository.Length
585 words
8 headings · 2 code blocksRepository
17k
— · pushed 5 days agoLast changed
3 days ago
First indexed 3 days ago.1# Auth Feature23Three GitHub sign-in paths, picked per session: **web OAuth + PKCE + handoff** (primary), **device flow** (fallback), **Personal Access Token paste** (last resort). Works on Android + Desktop.45## Structure67```8feature/auth/9├── domain/repository/AuthenticationRepository.kt # contract + AuthPath, DeviceFlowStart, PollOutcome, WebAuthRegistration, PatRejectedException10├── data/11│ ├── crypto/PkceGenerator.kt # SHA-256 PKCE triplet (state + verifier + challenge)12│ ├── network/GitHubAuthApi.kt # direct + backend-proxied device-flow endpoints13│ ├── network/WebAuthApi.kt # web-OAuth register + handoff consume14│ ├── repository/AuthenticationRepositoryImpl.kt15│ └── di16└── presentation/17 ├── AuthenticationViewModel / State / Action / Event / Root18 ├── AuthDeepLinkBus.kt # SharedFlow bridge from app-level deep-link parser to VM19 └── components/20```2122## Key interface2324```kotlin25interface AuthenticationRepository {26 val accessTokenFlow: Flow<String?>2728 suspend fun startDeviceFlow(): DeviceFlowStart29 suspend fun awaitDeviceToken(start: GithubDeviceStart): GithubDeviceTokenSuccess30 suspend fun pollDeviceTokenOnce(deviceCode: String, path: AuthPath): PollOutcome3132 suspend fun signInWithPat(token: String): Result<Unit>3334 suspend fun registerWebAuth(): Result<WebAuthRegistration>35 suspend fun exchangeWebAuthHandoff(handoffId: String): Result<String>36}3738enum class AuthPath { Backend, Direct }39```4041## Navigation4243`GithubStoreGraph.AuthenticationScreen`.4445## Web OAuth path (primary)46471. `PkceGenerator.generate()` → `(state, codeVerifier, codeChallenge)` (S256).482. `WebAuthApi.register(state, codeChallenge, codeVerifier)` → POST `https://github-store.org/auth/register`. Cloudflare Worker stores `(state → {codeVerifier, codeChallenge})` in Workers KV with short TTL and returns `auth_url` (the `github.com/login/oauth/authorize?…` URL).493. VM opens `auth_url` in user's browser via `BrowserHelper`.504. User authorizes on GitHub. GitHub redirects to `https://github-store.org/auth/callback?code=…&state=…`.515. Worker re-validates `state`, exchanges `code` against `api.github-store.org` (backend posts to GitHub `/oauth/access_token` with the stored verifier), backend writes `(handoffId → access_token)` to Postgres with 60s TTL.526. Worker redirects browser to `githubstore://auth?h=<handoffId>` (custom scheme picked up by app via OS deep link).537. App-level `DeepLinkParser` routes the URI through `AuthDeepLinkBus`. VM calls `exchangeWebAuthHandoff(handoffId)` → `WebAuthApi.consumeHandoff` → POST `api.github-store.org/v1/oauth/handoff/<id>` (atomic `DELETE…RETURNING` — single-use). Token lands in `TokenStore`.5455Custom scheme is public — any app can fire `githubstore://auth?…`. The `state` parameter and 60s server-side TTL are the integrity guards; without a live KV entry the handoff is a no-op.5657## Device flow path (fallback)5859Used when web flow can't complete (browser unreachable, deep link not registered, user explicitly picks "Use device code instead").6061- Primary sub-path: backend proxy `/v1/auth/device/start` + `/poll` on `api.github-store.org` for networks throttling `github.com` (China, corporate filters).62- Each session picks one `AuthPath` (`Backend` | `Direct`), persists in `SavedStateHandle`. Only escalates `Backend → Direct` on infra errors (timeout / 5xx / 429-without-Retry-After). HTTP 4xx and GitHub negative 200-bodies (`authorization_pending`, `slow_down`, `access_denied`, `expired_token`, `bad_verification_code`) are real answers — never trigger fallback.63- Backend rate limits hard: 10 starts/hr, 200 polls/hr per IP. Don't add retry loops on top of Ktor's `HttpRequestRetry(maxRetries = 2)`.64- Backend responses carry `X-Request-ID` — `GitHubAuthApi` embeds it in error messages via `asRequestIdTag()` for cross-log correlation.6566## PAT path (last resort)6768`signInWithPat(token)`:691. Client-side format check (rejects obvious paste-errors — needs `ghp_` / `github_pat_` prefix).702. Network check against GitHub `/user`. 401 → `PatRejectedException(BadCredentials)`, 403 → `InsufficientScope`, other non-2xx → `Other(statusCode)`. On reject the sheet stays open.713. If GitHub is unreachable (timeout/DNS/block) the token persists optimistically — the whole reason this path exists is for users who can't reach GitHub reliably. A bad-but-unreachable token surfaces a 401 on the first authenticated call.7273## Notes7475- Token stored via `TokenStore` (DataStore-backed). `accessTokenFlow` observed app-wide.76- `GITHUB_CLIENT_ID` in `local.properties` for builds — must match the OAuth App registered on the backend and used by the Worker.77- Endpoints: `WEB_ORIGIN = https://github-store.org`, `BACKEND_ORIGIN = https://api.github-store.org`. Constants in `core/data/network/BackendEndpoints.kt`.78- Android deep-link filters in `composeApp/src/androidMain/AndroidManifest.xml`: scheme `githubstore`, hosts `auth`, `callback`, `repo`, `apps`. Desktop registers the protocol via `DesktopDeepLink` on Win/Linux (macOS uses the bundle Info.plist `CFBundleURLTypes`).79
Also in kurikomi-labs/komi-store
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| kurikomi-labs/komi-storefeature/dev-profile/CLAUDE.md · 17k | CLAUDE.md | arch | 40/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/favourites/CLAUDE.md · 17k | CLAUDE.md | arch | 40/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/home/CLAUDE.md · 17k | CLAUDE.md | arch | 54/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/profile/CLAUDE.md · 17k | CLAUDE.md | arch | 54/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/tweaks/CLAUDE.md · 17k | CLAUDE.md | archmonorepo | 54/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/recently-viewed/CLAUDE.md · 17k | CLAUDE.md | arch | 35/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/search/CLAUDE.md · 17k | CLAUDE.md | arch | 54/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/starred/CLAUDE.md · 17k | CLAUDE.md | arch | 54/100 | 3 days ago | |
| kurikomi-labs/komi-storeAGENTS.md · 17k | AGENTS.md | buildlint-formatstylearch+1 | 97/100 | 3 days ago | |
| kurikomi-labs/komi-storeCLAUDE.md · 17k | CLAUDE.md | buildstylearchgit | 78/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/apps/CLAUDE.md · 17k | CLAUDE.md | arch | 58/100 | 3 days ago | |
| kurikomi-labs/komi-storefeature/details/CLAUDE.md · 17k | CLAUDE.md | arch | 53/100 | 3 days ago |
Diff against feature/dev-profile/CLAUDE.md Diff against feature/favourites/CLAUDE.md Diff against feature/home/CLAUDE.md Diff against feature/profile/CLAUDE.md Diff against feature/tweaks/CLAUDE.md Diff against feature/recently-viewed/CLAUDE.md Diff against feature/search/CLAUDE.md Diff against feature/starred/CLAUDE.md Diff against AGENTS.md Diff against CLAUDE.md Diff against feature/apps/CLAUDE.md Diff against feature/details/CLAUDE.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| livewire/livewireCLAUDE.md · 24k | CLAUDE.md | setupbuildteststyle+4 | 100/100 | 3 days ago | |
| filamentphp/filamentCLAUDE.md · 32k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| stacklok/toolhiveCLAUDE.md · 2.0k | CLAUDE.md | buildteststylearch+4 | 100/100 | 3 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 3 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 3 days ago |
