ManaBrandConfig.logoAssetName ergänzt — Apps liefern einen Asset- Catalog-Namen, ManaAuthScaffold rendert das Bundle-Asset 64×64pt ohne Tint statt eines getinteten SF-Symbols. logoSymbol bleibt Fallback. Hintergrund: Pageta hat ein eigenes Apple-Icon-Composer-SVG; SF- Symbol "book.pages" sah neben dem polierten App-Icon unecht aus. Additive Änderung, alle bestehenden Apps quellkompatibel. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.6 KiB
Changelog
Alle Änderungen werden hier dokumentiert. Format orientiert an Keep a Changelog, Versionierung nach Semver.
[Unreleased]
[0.7.0] — 2026-05-22
Minor — logoAssetName in ManaBrandConfig. Apps können jetzt
ein eigenes Logo-Asset (Asset-Catalog-Name) statt eines SF-Symbols
für den Login-/Sign-Up-/Forgot-Password-Header liefern.
Hintergrund
Pageta hat ein eigenes Apple-Icon-Composer-SVG; das SF-Symbol
book.pages (vorher) sah neben dem polierten App-Icon unecht aus.
Andere Apps mit echten Logo-Assets (kommt) werden den gleichen
Migrationspfad gehen können.
Neu
ManaBrandConfig.logoAssetName: String?— Name eines Image-Assets im Bundle der konsumierenden App. Hat Vorrang vorlogoSymbol.ManaAuthScaffoldrendertlogoAssetName64×64pt,aspectRatio(.fit), ohne Tint (Asset behält Originalfarben — typisch Apple-Icon- Composer-Output mit Gradient). Fallback bleibt SF-Symbol mit Tint.
Geändert
ManaBrandConfig.inithat einen zusätzlichen optionalen ParameterlogoAssetName: String? = nil. Quellkompatibel — bestehende Apps brauchen nichts ändern.systemDefault-Config setztlogoAssetName: nilexplizit (kein Verhaltenswechsel).
Tests
- 50/50 grün (keine neuen Tests — die
ManaBrandConfig-Änderung ist rein additiv, gerendertes Asset hängt am Bundle der App).
Adoption
Apps mit eigenem Logo:
ManaBrandConfig(
appName: "Pageta",
logoSymbol: "book.pages", // SF-Fallback bleibt
logoAssetName: "PagetaLogo", // Asset-Catalog-Name, hat Vorrang
...
)
[0.6.0] — 2026-05-17
Minor — neues Library-Product ManaWebShell. WKWebView-Hülle für
Hybrid-Apps (Web-Lese-Surfaces + native Submit/Widget/ShareExt).
Extrahiert aus den fast-byte-identischen WebShell/-Ordnern in
seepuls-native und zitare-native (~900 LOC, davon ~700 LOC
Duplikat). Audit 2026-05-17 Vorschlag V2.
Neu
WebShellView(public SwiftUI View) —WKWebView-Wrapper mit Progress-Bar, Pull-to-Refresh (iOS), Fehler-Snackbar, External-Link- Delegation in den System-Browser. Universal (iOS + macOS).WebShellConfig(public, Sendable) — Host-Whitelist mit Wildcard- Support ("*.mana.how"), User-Agent, Theme-Hints (background, progressTint, errorBackground/Foreground/Icon), User-Scripts.WebTarget(public, Equatable+Sendable) — URL + monoton wachsenderreloadToken. Forciert Reload bei Universal-Link auf aktuelle URL.WebNavState(public, @Observable, @MainActor) — reaktiver Navigation-State (isLoading, estimatedProgress, lastError, currentURL, canGoBack).WebShellCoordinator(public, @MainActor) —WKNavigationDelegateWKUIDelegate-Implementierung. KVO-Observations, Pull-to-Refresh- Action.
WebShellScripts(public Enum, @MainActor) — vor-gefertigteWKUserScript-Helfer:preferDarkScheme,syncDarkMode(localStorageKey:),hideElements(selectors:tagName:). Apps stapeln nach Bedarf.
Logging
- ManaWebShell loggt unter Subsystem
ev.mana.webshell, Kategorieweb. App-OSLog bleibt unverändert.
Tests
ManaWebShellTestsmit 6 Tests gegenWebShellConfig.isAllowed. Coverage für exakte Hosts,*.root-Wildcard, Root-selbst, Negativ-Cases, leere Whitelist. 6/6 grün.
Migrations-Hinweis
seepuls-native und zitare-native können ihre lokalen
Sources/Features/WebShell/-Dateien gegen ManaWebShell ersetzen.
Pattern in mana/docs/playbooks/HYBRID_NATIVE_APP.md (entsteht
parallel). App-spezifisches (CookieBridge, App-Theme als
config.backgroundColor) bleibt in der App.
[0.5.0] — 2026-05-14
Minor — ManaTwoFactorAccountRow + ManaBackupCodeRegenerateView.
Macht den 2FA-Vollausbau in der AccountView nutzbar. Setzt
mana-swift-core ≥ 1.5.0 voraus (getProfile()).
Neu
ManaTwoFactorAccountRow— Drop-in für AccountView. Holt den 2FA-Status viaAuthClient.getProfile()und zeigt:- Off: "Zwei-Faktor aktivieren" → öffnet
ManaTwoFactorEnrollView - An: "Zwei-Faktor aktiv" + "Backup-Codes erneuern" + "Zwei-Faktor deaktivieren"
- Off: "Zwei-Faktor aktivieren" → öffnet
ManaBackupCodeRegenerateView— Re-Auth via Passwort, zeigt neue Backup-Codes + Copy-to-Clipboard.TwoFactorAccountRowModel— internes@Observable-VM, reloaded Status nach Enroll/Disable/Regenerate.
Damit ist 2FA in den Apps end-to-end nutzbar — User kann aktivieren, Backup-Codes verwalten, deaktivieren. Der Login-Flow ist seit v0.3.0 durchgängig.
[0.4.0] — 2026-05-14
Minor — 2FA-Enrollment-UI (Mini-Sprint B). Setzt mana-swift-core ≥ 1.4.0 voraus.
Neu
ManaTwoFactorEnrollView+TwoFactorEnrollmentViewModel— 3-Phasen-Wizard:- Passwort eingeben (Re-Auth)
- QR-Code (via
CoreImage.CIFilter.qrCodeGenerator, plattform- unabhängig auf iOS+macOS) scannen + 6-stelligen Test-Code eingeben - Backup-Codes anzeigen + Copy-to-Clipboard
ManaTwoFactorDisableView— Single-Step-Sheet, Re-Auth via Passwort + destruktiver Bestätigungs-Button.
Tests
- 5 neue Tests für Enroll-VM (Success, falsches PW, canSubmitVerify 6-Ziffern-Guard, confirmVerify Phase-Wechsel, backupCodes-Accessor).
- 44/44 grün.
[0.3.0] — 2026-05-14
Minor — ManaTwoFactorChallengeView für 2FA-Login. Setzt
mana-swift-core ≥ 1.3.0 voraus (Status .twoFactorRequired).
Neu
ManaTwoFactorChallengeView+TwoFactorChallengeViewModel— 6-stelliger TOTP-Code-Input (Number-Pad auf iOS), Fallback auf Backup-Codes via Toggle, "Abbrechen" routet viaauth.signOut(keepGuestMode:)zurück zum Login.LoginViewModel.Status.twoFactorRequired(email:)als neuer Case.ManaLoginViewschaltet bei.twoFactorRequiredautomatisch aufManaTwoFactorChallengeViewum (analog zu.emailNotVerified).
Tests
- 6 neue Tests für
TwoFactorChallengeViewModel: canSubmit-Guards (TOTP 6 Ziffern, Backup beliebig), toggleMode-State-Reset, submit bei Erfolg/Fehler, Backup-Code-Routing. - 39/39 grün.
[0.2.0] — 2026-05-13
Minor — Action-Level-Gate für Apps mit Guest-/Login-optional-Modus.
Komplett additiv; braucht mana-swift-core ≥ 1.2.0.
ManaAuthUI — neu: ManaAuthGate
ManaAuthGate—@Observable-State-Maschine, die eine Aktion erst laufen lässt, wenn der User eingeloggt ist. Wenn nicht, wird das Sign-In-Sheet aufgeklappt und die Aktion gemerkt; nach erfolgreichem Sign-In läuft sie automatisch.- Zwei
require-Overloads: synchron (() -> Void) und async (() async -> Void). Konsumenten schreibengate.require { ... }ohne sich um das Gate-Lifecycle zu kümmern. ManaAuthGateModifier/View.manaAuthGate(_:signIn:)— hängt das Sign-In-Sheet an einen Root-View und beobachtetauth.status. Wechsel auf.signedInschließt das Sheet und löst die Pending- Aktion aus; manuelles Dismiss verwirft die Pending-Aktion.lastReasonals optionaler Telemetrie-Hint prorequire-Call.
Konvention
Native-Apps sollen mana-swift-core v1.2.0 + Guest-Mode + diesen Gate
als Standardweg nutzen. Pattern für Cards/Manaspur/Memoro:
- Beim App-Start:
bootstrap(), dann bei.signedOut→enterGuestMode(). - Root-View zeigt immer App-Inhalte; nie eine Vollbild-Login-Wall.
- Aktionen, die einen Account brauchen, werden in
gate.require { ... }gewrappt — Login wird zur Inline-Eskalation statt zum App-Block.
Memoro hat dieses Muster informell schon umgesetzt (ContentView ohne Hard-Gate). Cards + Manaspur ziehen mit ihren nächsten Releases nach.
Tests
- 7 neue Tests für
ManaAuthGate: sofortiger Run bei.signedIn, Defer bei.signedOut/.guest,resolvePendingnach Sign-In,cancelPending,lastReason-Tracking.
[0.1.0] — 2026-05-13
Phase 2 aus dem Native-Auth-Vollausbau-Plan (Option A, siehe
../mana/docs/MANA_SWIFT.md). Entstanden weil drei Apps fast-byte-
identische LoginView.swift-Dateien hatten und Sign-Up/Forgot-PW
komplett fehlten.
ManaAuthUI (neu)
ManaBrandConfig— App-injiziertes Bündel aus appName, tagline, primary/surface/background/error-Colors. Apps liefern hier ihr Theme (z.B. forest für Cards/Manaspur, default-mana für Memoro).- Base-Components:
ManaAuthScaffold,ManaPrimaryButton,ManaTextField,ManaSecureField— geteilte Bausteine, alle brand-aware. ManaLoginView+LoginViewModel— Email/PW-Login mit Sign-Up- und Forgot-PW-Buttons. Bei.emailNotVerifiedautomatisch insManaEmailVerifyGateViewumgeleitet (Resend-Mail-Button).ManaSignUpView+SignUpViewModel— Registrierung mit Email/Name/Passwort. Nach Submit: Bestätigungs-Mail-Hinweis-Screen.ManaEmailVerifyGateView— wenn Login.emailNotVerifiedwarf, bietet "Bestätigungs-Mail erneut senden".ManaForgotPasswordView+ForgotPasswordViewModel— Reset-Mail anfordern. Server antwortet immer 200 (keine User-Enumeration), UI meldet generisch.ManaResetPasswordView+ResetPasswordViewModel— neues Passwort setzen mit Token aus Reset-Mail. Wird aus dem Universal-Link-Handler der App aufgerufen.ManaChangeEmailView,ManaChangePasswordView,ManaDeleteAccountView— Account-Bausteine für die AccountView der App.ManaDeleteAccountViewist App-Store-Pflicht (Guideline 5.1.1(v)) für jede App mit Account-Erstellung.
Tests
- ViewModel-Tests via URLProtocol-Mock für jeden Auth-Flow.
- Brand-Config-Defaults.
Bekannte Einschränkungen
ManaChangeEmailView/ManaChangePasswordView/ManaDeleteAccountViewfunktionieren erst nach Phase-3-Server-PR (Bearer-Plugin inmana-auth). UI ist fertig, Wire ist fertig, Server muss nachziehen.- 2FA, Magic-Link, Passkey-Flows nicht enthalten. Folgen in v0.2.0 zusammen mit ManaCore v1.2.0 und dem Server-PR.