Native-Konstanten ziehen mit dem Web-Cutover zu .zitare.com- Subdomains nach. Universal-Link-AASA-Liste enthält jetzt zitare.com + app.zitare.com (zitare.mana.how raus). webBaseURL ist jetzt das echte publicWebURL (zitare.com), wie ursprünglich geplant. CookieBridge bleibt Skeleton — die `.mana.how`-Cookie-Domain- Strategie greift nicht für `.zitare.com`. Hinweis im Kommentar gesetzt, Update vor ζ-3 nötig. Code-Only. Erst nach nächstem Native-Build/TestFlight-Upload live. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
80 lines
3.3 KiB
Swift
80 lines
3.3 KiB
Swift
import Foundation
|
|
import ManaCore
|
|
import WebKit
|
|
|
|
/// Reicht den mana-auth-JWT als Cookie an den `WKWebView` weiter, sodass
|
|
/// eingeloggte `(app)`-Routen auf `app.zitare.com` ohne zweiten Login
|
|
/// erreichbar sind.
|
|
///
|
|
/// **Phase ζ-1: Skeleton.** Methoden existieren, werden aber heute
|
|
/// nicht aufgerufen — bevor sie scharfgeschaltet werden, muss der
|
|
/// Cookie-SSO-Pfad auf der Web-Seite (`zitare/apps/api/src/auth/`
|
|
/// und `apps/zitare/src/lib/auth/token-helper.ts`) gegen einen
|
|
/// *echten* mana-auth-Token End-to-End getestet sein (Verifikations-
|
|
/// Lücke in `zitare/STATUS.md`).
|
|
///
|
|
/// **Cross-Domain-Hinweis 2026-05-20:** Mana-Auth setzt den Cookie
|
|
/// auf `.mana.how`. Seit dem Zitare-Cutover auf `app.zitare.com`
|
|
/// kann dieser Cookie nicht mehr direkt geteilt werden. Der WebView-
|
|
/// Auth-Pfad braucht stattdessen Bearer-Token-Injection (siehe
|
|
/// Web-App `apps/zitare/src/lib/auth.ts` Pattern: Cross-Origin
|
|
/// /refresh gegen auth.mana.how mit credentials:include) oder ein
|
|
/// dediziertes Cookie auf `.zitare.com` via mana-auth-Erweiterung.
|
|
/// Diese Klasse ist noch nicht angepasst — Update kommt vor ζ-3.
|
|
///
|
|
/// **Cookie-Schema** (gespiegelt zu mana-auth, siehe
|
|
/// `mana/services/mana-auth/src/auth/cookies.ts`):
|
|
/// - Name: `mana.access` (JWT) und optional `mana.refresh` (Opaque)
|
|
/// - Domain: `.mana.how` (greift heute nicht für `.zitare.com`)
|
|
/// - Path: `/`
|
|
/// - Secure: true, HTTPOnly: false (WebView muss lesen können),
|
|
/// SameSite: Lax
|
|
enum CookieBridge {
|
|
/// Setzt den `mana.access`-Cookie im geteilten `WKHTTPCookieStore`,
|
|
/// wenn der `AuthClient` einen gültigen JWT hält. No-op sonst.
|
|
@MainActor
|
|
static func installManaAccess(from auth: AuthClient) async {
|
|
guard case .signedIn = auth.status, let token = currentAccessToken(from: auth) else {
|
|
Log.web.debug("CookieBridge: kein signedIn-Token, no-op")
|
|
return
|
|
}
|
|
guard let cookie = makeAccessCookie(token: token) else {
|
|
Log.web.warning("CookieBridge: konnte Cookie-Properties nicht bauen")
|
|
return
|
|
}
|
|
let store = WKWebsiteDataStore.default().httpCookieStore
|
|
await store.setCookie(cookie)
|
|
Log.web.info("CookieBridge: mana.access für .mana.how gesetzt")
|
|
}
|
|
|
|
/// Entfernt den `mana.access`-Cookie wieder — etwa nach Logout.
|
|
@MainActor
|
|
static func removeManaAccess() async {
|
|
let store = WKWebsiteDataStore.default().httpCookieStore
|
|
let cookies = await store.allCookies()
|
|
for cookie in cookies where cookie.name == "mana.access" {
|
|
await store.deleteCookie(cookie)
|
|
}
|
|
Log.web.info("CookieBridge: mana.access entfernt")
|
|
}
|
|
|
|
private static func currentAccessToken(from auth: AuthClient) -> String? {
|
|
// ManaCore hält den JWT im Keychain. In ζ-3 ersetzt durch die
|
|
// tatsächliche `auth.currentAccessToken()`-API; heute nur
|
|
// Skelett-Hook, damit Cookie-Setup und API in Reichweite sind.
|
|
// Linter beruhigen ohne unused warning:
|
|
_ = auth
|
|
return nil
|
|
}
|
|
|
|
private static func makeAccessCookie(token: String) -> HTTPCookie? {
|
|
HTTPCookie(properties: [
|
|
.name: "mana.access",
|
|
.value: token,
|
|
.domain: ".mana.how",
|
|
.path: "/",
|
|
.secure: true,
|
|
.sameSitePolicy: HTTPCookieStringPolicy.sameSiteLax
|
|
])
|
|
}
|
|
}
|