docs(02): add missing auth store actuals to plan
This commit is contained in:
@@ -17,7 +17,9 @@ files_modified:
|
|||||||
- iosApp/iosApp/iOSApp.swift
|
- iosApp/iosApp/iOSApp.swift
|
||||||
- iosApp/Podfile
|
- iosApp/Podfile
|
||||||
- composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.jvm.kt
|
- composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.jvm.kt
|
||||||
|
- composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.jvm.kt
|
||||||
- composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.wasmJs.kt
|
- composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.wasmJs.kt
|
||||||
|
- composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.wasmJs.kt
|
||||||
- composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStoreContractTest.kt
|
- composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStoreContractTest.kt
|
||||||
autonomous: true
|
autonomous: true
|
||||||
requirements: [AUTH-01, AUTH-02, AUTH-04, AUTH-05]
|
requirements: [AUTH-01, AUTH-02, AUTH-04, AUTH-05]
|
||||||
@@ -26,6 +28,7 @@ must_haves:
|
|||||||
- "iOS and Android login use AppAuth authorization-code flow with PKCE through system browser and recipe://callback"
|
- "iOS and Android login use AppAuth authorization-code flow with PKCE through system browser and recipe://callback"
|
||||||
- "Requested scopes are exactly openid profile email offline_access"
|
- "Requested scopes are exactly openid profile email offline_access"
|
||||||
- "AuthState JSON is stored through explicit iOS Keychain and Android EncryptedSharedPreferences-backed stores"
|
- "AuthState JSON is stored through explicit iOS Keychain and Android EncryptedSharedPreferences-backed stores"
|
||||||
|
- "Every configured KMP target has a SecureAuthStateStore actual, including JVM and Wasm stubs"
|
||||||
- "JVM target has DEV_AUTH_TOKEN dev stub; Wasm target throws NotImplementedError(\"Wasm OIDC: v2\")"
|
- "JVM target has DEV_AUTH_TOKEN dev stub; Wasm target throws NotImplementedError(\"Wasm OIDC: v2\")"
|
||||||
- "Logout platform clients support RP-initiated end-session and local store clearing"
|
- "Logout platform clients support RP-initiated end-session and local store clearing"
|
||||||
artifacts:
|
artifacts:
|
||||||
@@ -38,6 +41,12 @@ must_haves:
|
|||||||
- path: "composeApp/src/iosMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.ios.kt"
|
- path: "composeApp/src/iosMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.ios.kt"
|
||||||
provides: "iOS Keychain storage with AfterFirstUnlockThisDeviceOnly per D-14"
|
provides: "iOS Keychain storage with AfterFirstUnlockThisDeviceOnly per D-14"
|
||||||
contains: "kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly"
|
contains: "kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly"
|
||||||
|
- path: "composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.jvm.kt"
|
||||||
|
provides: "JVM dev-only in-memory AuthState store actual so desktop tests compile"
|
||||||
|
contains: "actual class SecureAuthStateStore"
|
||||||
|
- path: "composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.wasmJs.kt"
|
||||||
|
provides: "Wasm non-persistent AuthState store actual so wasm target compiles while OIDC remains v2"
|
||||||
|
contains: "actual class SecureAuthStateStore"
|
||||||
- path: "iosApp/iosApp/Info.plist"
|
- path: "iosApp/iosApp/Info.plist"
|
||||||
provides: "recipe URL scheme registration"
|
provides: "recipe URL scheme registration"
|
||||||
contains: "CFBundleURLSchemes"
|
contains: "CFBundleURLSchemes"
|
||||||
@@ -148,18 +157,24 @@ Output: expect/actual OIDC client, explicit secure auth state store, URL callbac
|
|||||||
- composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/main.kt
|
- composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/main.kt
|
||||||
- composeApp/src/webMain/kotlin/dev/ulfrx/recipe/main.kt
|
- composeApp/src/webMain/kotlin/dev/ulfrx/recipe/main.kt
|
||||||
</read_first>
|
</read_first>
|
||||||
<files>composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.jvm.kt, composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.wasmJs.kt</files>
|
<files>composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.jvm.kt, composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.jvm.kt, composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.wasmJs.kt, composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.wasmJs.kt</files>
|
||||||
<action>
|
<action>
|
||||||
JVM actual reads `DEV_AUTH_TOKEN` from environment and returns `OidcResult.Success(authStateJson = "dev:$token", accessToken = token, idToken = null, expiresAtEpochMillis = Long.MAX_VALUE)` when present. If missing, return `OidcResult.AuthError("DEV_AUTH_TOKEN is not set")`; do not hardcode a usable bearer token.
|
JVM actual reads `DEV_AUTH_TOKEN` from environment and returns `OidcResult.Success(authStateJson = "dev:$token", accessToken = token, idToken = null, expiresAtEpochMillis = Long.MAX_VALUE)` when present. If missing, return `OidcResult.AuthError("DEV_AUTH_TOKEN is not set")`; do not hardcode a usable bearer token.
|
||||||
|
|
||||||
|
JVM `SecureAuthStateStore` actual must compile for desktop dev/tests without pretending to be production secure storage. Implement `actual class SecureAuthStateStore` with a private nullable in-memory `authStateJson` property and exact methods `read()`, `write(authStateJson: String)`, and `clear()`. This store is dev-only and process-local; do not use it for mobile targets.
|
||||||
|
|
||||||
Wasm actual throws exactly `NotImplementedError("Wasm OIDC: v2")` for login/refresh/logout per D-03.
|
Wasm actual throws exactly `NotImplementedError("Wasm OIDC: v2")` for login/refresh/logout per D-03.
|
||||||
|
|
||||||
|
Wasm `SecureAuthStateStore` actual must also exist so `:composeApp:compileKotlinWasmJs` compiles. Implement `actual class SecureAuthStateStore` with the same private nullable in-memory `authStateJson` property and `read()`, `write(authStateJson: String)`, `clear()` methods. Because Wasm OIDC itself throws `NotImplementedError("Wasm OIDC: v2")`, this store is non-persistent and only satisfies the KMP actual contract.
|
||||||
</action>
|
</action>
|
||||||
<verify>
|
<verify>
|
||||||
<automated>./gradlew :composeApp:jvmTest :composeApp:compileKotlinWasmJs</automated>
|
<automated>./gradlew :composeApp:jvmTest :composeApp:compileKotlinWasmJs</automated>
|
||||||
</verify>
|
</verify>
|
||||||
<acceptance_criteria>
|
<acceptance_criteria>
|
||||||
- `grep -q 'DEV_AUTH_TOKEN' composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.jvm.kt`
|
- `grep -q 'DEV_AUTH_TOKEN' composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.jvm.kt`
|
||||||
|
- `grep -q 'actual class SecureAuthStateStore' composeApp/src/jvmMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.jvm.kt`
|
||||||
- `grep -q 'NotImplementedError("Wasm OIDC: v2")' composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.wasmJs.kt`
|
- `grep -q 'NotImplementedError("Wasm OIDC: v2")' composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/OidcClient.wasmJs.kt`
|
||||||
|
- `grep -q 'actual class SecureAuthStateStore' composeApp/src/webMain/kotlin/dev/ulfrx/recipe/auth/SecureAuthStateStore.wasmJs.kt`
|
||||||
- `./gradlew :composeApp:jvmTest :composeApp:compileKotlinWasmJs` exits 0
|
- `./gradlew :composeApp:jvmTest :composeApp:compileKotlinWasmJs` exits 0
|
||||||
</acceptance_criteria>
|
</acceptance_criteria>
|
||||||
<done>Secondary targets compile without expanding Phase 2 scope into real Desktop/Wasm OIDC.</done>
|
<done>Secondary targets compile without expanding Phase 2 scope into real Desktop/Wasm OIDC.</done>
|
||||||
|
|||||||
Reference in New Issue
Block a user