fix(account): harden session refresh recovery

Persist refresh operation identity across failures and validate revoked Apple credentials so clients recover without unsafe token rotation.
This commit is contained in:
Rocky
2026-08-25 16:43:47 +08:00
parent 57844ce615
commit 309d743fd3
16 changed files with 438 additions and 33 deletions
@@ -218,10 +218,24 @@ public struct AppAttestKeyState: Codable, Equatable, Sendable {
}
}
public struct AccountRefreshTransaction: Codable, Equatable, Sendable {
public let refreshTokenDigest: String
public let operationId: UUID
public init(refreshTokenDigest: String, operationId: UUID) {
self.refreshTokenDigest = refreshTokenDigest
self.operationId = operationId
}
}
public protocol AccountSessionVault: Sendable {
func loadSession() async throws -> AccountSession?
func saveSession(_ session: AccountSession) async throws
func clearSession() async throws
func beginRefreshTransaction(
refreshTokenDigest: String
) async throws -> AccountRefreshTransaction
func clearRefreshTransaction() async throws
}
public protocol AppAttestKeyStateStoring: Sendable {
@@ -230,6 +244,12 @@ public protocol AppAttestKeyStateStoring: Sendable {
func clearAppAttestKeyState() async throws
}
public protocol AppleUserIdentifierStoring: Sendable {
func loadAppleUserIdentifier() async throws -> String?
func saveAppleUserIdentifier(_ userIdentifier: String) async throws
func clearAppleUserIdentifier() async throws
}
public protocol OOBEInstallationIDStoring: Sendable {
func oobeInstallationID() async throws -> UUID
}
@@ -305,6 +325,7 @@ struct LegacyAPIErrorEnvelope: Codable, Sendable {
struct RefreshSessionRequest: Codable, Sendable {
let refreshToken: String
let refreshOperationId: UUID
}
struct DeleteAccountRequest: Codable, Sendable {