Files
purchases-ios/Sources/Networking/RemoteConfigAPI.swift
T
Rick cf77437cc0 feat(remote-config): verify RC container signatures (#7046)
* feat(remote-config): use opaque manifest token models

* fix(remote-config): simplify manifest token model

* feat(remote-config): verify RC container signatures

* refactor(remote-config): isolate signature payload context

* refactor(remote-config): clarify fetch and signing context

* fix(remote-config): log signature payload failures

* fix(remote-config): correct checksum mismatch verification tests

* fix(remote-config): clarify checksum mismatch test behavior

* fix(remote-config): expect enforced checksum verification failure

* fix(remote-config): address signing review feedback

* fix(remote-config): verify no-content response context

* fix(remote-config): expect no-content verification failure code

* refactor(remote-config): group signature verified paths
2026-06-25 17:03:58 +02:00

58 lines
1.7 KiB
Swift

//
// RemoteConfigAPI.swift
// RevenueCat
//
// Created by Rick van der Linden on 27/05/2026.
// Copyright © 2026 RevenueCat, Inc. All rights reserved.
import Foundation
class RemoteConfigAPI {
typealias RemoteConfigResponseHandler = Backend.ResponseHandler<RemoteConfigFetchResult>
private let callbackCache: CallbackCache<RemoteConfigCallback>
private let backendConfig: BackendConfiguration
init(backendConfig: BackendConfiguration) {
self.backendConfig = backendConfig
self.callbackCache = .init()
}
func getRemoteConfig(
request: RemoteConfigRequest = .init(),
isAppBackgrounded: Bool,
completion: @escaping RemoteConfigResponseHandler
) {
let factory = GetRemoteConfigOperation.createFactory(
configuration: self.backendConfig,
callbackCache: self.callbackCache,
request: request
)
let callback = RemoteConfigCallback(cacheKey: factory.cacheKey, completion: completion)
let cacheStatus = self.callbackCache.add(callback)
self.backendConfig.addCacheableOperation(
with: factory,
delay: .default(forBackgroundedApp: isAppBackgrounded),
cacheStatus: cacheStatus
)
}
}
struct RemoteConfigFetchResult {
/// `nil` represents a successful `204 No Content` response. Malformed or undecodable
/// container bytes should fail before this result is created.
let container: RCContainer?
let verificationResult: VerificationResult
init(response: VerifiedHTTPResponse<RCContainer?>) {
self.container = response.body
self.verificationResult = response.verificationResult
}
}