HTTPClient: added signature validation and introduced ErrorCode.signatureVerificationFailed#2272
Conversation
e224bb7 to
6ea5b98
Compare
7685cad to
131208e
Compare
There was a problem hiding this comment.
This tests backwards compatibility with old responses. We handle that as a cache miss.
There was a problem hiding this comment.
This test was moved below to SignatureVerificationHTTPClientTests
Codecov Report
@@ Coverage Diff @@
## main #2272 +/- ##
==========================================
- Coverage 86.20% 86.20% -0.01%
==========================================
Files 186 187 +1
Lines 12306 12407 +101
==========================================
+ Hits 10609 10696 +87
- Misses 1697 1711 +14
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
HTTPClient: added signature validationHTTPClient: added signature validation
There was a problem hiding this comment.
Can we extend HTTPRequest to have a IntegrityVerifiedHTTPRequest that guarantees contains a Nonce? And then make this signature expect that class in particular. Doesn't make sense to validate a HTTPRequest that is not sending Nonces.
There was a problem hiding this comment.
That's definitely an alternative approach, but that's not very Swift-y. We'd have to move away from it being a struct and lose the value semantics on this type (can't inherit structs)
I think the main issue is this is bad name. It returns HTTPResponseValidationResult.notRequested if the request doesn't need to be verified, so maybe instead of createAndValidate it should just be HTTPResponse.create(with:...).
There was a problem hiding this comment.
Alternatively we'd have to make HTTPResponse a protocol and use a generic <Response: HTTPResponseType> everywhere to maintain type safety at compile time instead of doing that at runtime. But at that point it would be an overkill.
There was a problem hiding this comment.
Hummm... I see... I have no clue about swift :)
And something like createRequestAndValidator() that returns a request with the nonce, and a validator ready to use (contains the nonce)? It feels weird to have this generic create and validate that sometimes will not validate, plus there is not a lot of type safety, there is no way to enforce validation for some kind of request.
That way the request remains generic, you will just build a validator when requesting a request with validation. If not requesting validation, you will just have a create that builds a request.
Again, all this not knowing a thing about swift patterns :)
There was a problem hiding this comment.
I renamed this, I think it's clearer now. I do get your point of seemingly validating requests that don't require it.
HTTPResponse always has an HTTPResponseValidationResult (even if it's .notRequested).
So HTTPResponse.create(with:body:request:..) is the new API. It may or may not do any validation, but it'll return an HTTPResponse with the appropriate information. Does that sound less weird?
|
Apologies for the big diff 🙏🏻 I couldn't really split the changes here into multiple PRs since they're all connected. |
HTTPClient: added signature validationHTTPClient: added signature validation and introduced ErrorCode.signatureVerificationFailed
fbbf8a7 to
45b2ea1
Compare
cadamsdotcom
left a comment
There was a problem hiding this comment.
Nice change @NachoSoto. Not a swift expert, but looks good to me. The API with the optional requesting of verification is going to prove handy if we decide to do this for more endpoint in future..
PS particularly liked how simple the sign and createSalt test methods got, the simple keypair generation with private let (privateKey, publicKey) = SigningTests.createRandomKey(), and how packing things into test classes creates clean encapsulation. Learned a bunch about Swift reading this, thanks for sending it through!
45b2ea1 to
8fcf9ca
Compare
8fcf9ca to
a08492a
Compare
|
I'm thinking of renaming the |
I think that name makes sense 👍 |
There was a problem hiding this comment.
we need to be very careful with the case where it wasn't available. I can see us messing this up and breaking things for iOS 12 easily.
I wouldn't even mind having a separate case where for .unsupportedOSVersion or something
There was a problem hiding this comment.
but, when in doubt, I'd just consider it "valid" for older OS versions. You can't "cheat" this check so it's not really a useful hack, and being forced into staying with iOS 12 is probably a dealbreaker for most attackers anyway
There was a problem hiding this comment.
We talked about this offline.
We're going to solve this by making the "validated" APIs only available in iOS 13+, to force users to decide how to handle older versions.
The configuration API is already not available below, so it's also clear that you can't use it on older devices.
There was a problem hiding this comment.
So this will change in a followup PR I imagine right?
There was a problem hiding this comment.
we're interchangeably using validation and verification throughout the feature, we should pick one and settle. I think verification is more technically appropriate for this
There was a problem hiding this comment.
also... do we ever clean these up?
It feels like if we have an eTag but it doesn't have validation information and validation has been activated, we should kill the old eTag, but I don't recall what our cleanup mechanism for this was
There was a problem hiding this comment.
also, we're not storing when validationResult = failed, so this would never be true, right?
There was a problem hiding this comment.
last question: what are we doing here when validation wasn't requested at all? Like, if validation is disabled, this should behave exactly as it always has
There was a problem hiding this comment.
we're interchangeably using validation and verification throughout the feature, we should pick one and settle. I think verification is more technically appropriate for this
I fixed those inconsistencies in #2277. I went with validation but we can change it back.
It feels like if we have an eTag but it doesn't have validation information and validation has been activated, we should kill the old eTag
Hmm good point, let me see if we have a test case for that and if not I'll add it.
also, we're not storing when validationResult = failed, so this would never be true, right?
That's correct, it's just an extra safety check. I can add a comment.
what are we doing here when validation wasn't requested at all? Like, if validation is disabled, this should behave exactly as it always has
It does, and all the existing tests still pass.
There was a problem hiding this comment.
Okay, updated ETagManager to ignore etags for the case where the stored cache had no validation but the new request requires a signature.
tonidero
left a comment
There was a problem hiding this comment.
Still need to review tests but looking good!
a08492a to
7a62e5b
Compare
|
All comments addressed. |
There was a problem hiding this comment.
So this will change in a followup PR I imagine right?
| var statusCode: HTTPStatusCode | ||
| var responseHeaders: HTTPClient.ResponseHeaders | ||
| var body: Body | ||
| var validationResult: HTTPResponseValidationResult |
There was a problem hiding this comment.
I may be missing something but why did we make these var instead of let?
There was a problem hiding this comment.
So we can modify the validation result after it's initially created in HTTPClient (just an implementation detail).
Note that structs have value semantics, so this isn't like having mutable data in other languages.
Example:
struct Data {
// Technically mutable
var a: Int
var b: String
}
let d = Data(a: 1, b: "test")
d.a +=1 // Error, `d` is immutable!
func f(_ d: Data) {
d.a += 1 // Error, d is immutable
}Additionally, structs get implicitly copied (they have value semantics, not reference), they're passed by value, so you can't lead to shared mutable state.
So basically it doesn't make a difference if these are vars, it just makes creating copies with different values easier without needing to do it manually calling the constructor again.
There was a problem hiding this comment.
Right, I asked about this before and I forgot 😅 thanks for explaining again!
| struct ETagHeaderRequest { | ||
| var urlRequest: URLRequest | ||
| var refreshETag: Bool | ||
| var signatureVerificationEnabled: Bool |
There was a problem hiding this comment.
Same here, could these be let? I don't think callers of this mock would need to modify this?
There was a problem hiding this comment.
Ditto, it doesn't make a difference, it would only be mutable for a var ETagHeaderRequest anyway.
Depends on #2272 and #2278. Depends on https://github.com/RevenueCat/khepri/pull/5232.
…2267)⚠️ 🎉 This also changes integration tests to use `EntitlementVerificationLevel.enforced` so that integration tests fail if signatures are invalid. #### Depends on: - https://github.com/RevenueCat/khepri/pull/5191 - https://github.com/RevenueCat/khepri/pull/5204 - #2214 - #2215 - #2216 - #2272 _Marking this as `feat`ure because it contains a new error in `PurchasesDiagnostics.Error`_
### New Features * New `ErrorCode.signatureVerificationFailed` which will be used for an upcoming feature ### Bugfixes * `Purchases.deinit`: don't reset `Purchases.proxyURL` (#2346) via NachoSoto (@NachoSoto) <details> <summary><b>Other Changes</b></summary> * Introduced `Configuration.EntitlementVerificationMode` and `VerificationResult` (#2277) via NachoSoto (@NachoSoto) * `PurchasesDiagnostics`: added step to verify signature verification (#2267) via NachoSoto (@NachoSoto) * `HTTPClient`: added signature validation and introduced `ErrorCode.signatureVerificationFailed` (#2272) via NachoSoto (@NachoSoto) * `ETagManager`: don't use ETags if response verification failed (#2347) via NachoSoto (@NachoSoto) * `Integration Tests`: removed `@preconcurrency import` (#2464) via NachoSoto (@NachoSoto) * Clean up: moved `ReceiptParserTests-Info.plist` out of root (#2460) via NachoSoto (@NachoSoto) * Update `CHANGELOG` (#2461) via NachoSoto (@NachoSoto) * Update `SwiftSnapshotTesting` (#2453) via NachoSoto (@NachoSoto) * Fixed docs (#2432) via Kaunteya Suryawanshi (@kaunteya) * Remove unnecessary line break (#2435) via Andy Boedo (@aboedo) * `ProductEntitlementMapping`: enabled entitlement mapping fetching (#2425) via NachoSoto (@NachoSoto) * `BackendPostReceiptDataTests`: increased timeout to fix flaky test (#2426) via NachoSoto (@NachoSoto) * Updated requirements to drop Xcode 13.x support (#2419) via NachoSoto (@NachoSoto) * `Integration Tests`: fixed flaky errors when loading offerings (#2420) via NachoSoto (@NachoSoto) * `PurchaseTester`: fixed compilation for `internal` entitlement verification (#2417) via NachoSoto (@NachoSoto) * `ETagManager`/`HTTPClient`: sending new `X-RC-Last-Refresh-Time` header (#2373) via NachoSoto (@NachoSoto) * `ETagManager`: don't send validation time if not present (#2490) via NachoSoto (@NachoSoto) * SwiftUI Sample Project: Refactor Package terms method to a computed property (#2405) via Joseph Kokenge (@JOyo246) * Clean up v3 load shedder integration tests (#2402) via Andy Boedo (@aboedo) * Fix iOS 12 compilation (#2394) via NachoSoto (@NachoSoto) * Added new `VerificationResult.verifiedOnDevice` (#2379) via NachoSoto (@NachoSoto) * `PurchaseTester`: fix memory leaks (#2392) via Keita Watanabe (@kitwtnb) * Integration tests: add scheduled job (#2389) via Andy Boedo (@aboedo) * Add lane for running iOS v3 load shedder integration tests (#2388) via Andy Boedo (@aboedo) * iOS v3 load shedder integration tests (#2387) via Andy Boedo (@aboedo) * `Offline Entitlements`: created `LoadShedderIntegrationTests` (#2362) via NachoSoto (@NachoSoto) * Purchases.configure: log warning if attempting to use a static appUserID (#2385) via Mark Villacampa (@MarkVillacampa) * `SubscriberAttributesManagerIntegrationTests`: fixed flaky failures (#2381) via NachoSoto (@NachoSoto) * `@DefaultDecodable.Now`: fixed flaky test (#2374) via NachoSoto (@NachoSoto) * `PurchaseTesterSwiftUI`: fixed iOS compilation (#2376) via NachoSoto (@NachoSoto) * `SubscriberAttributesManagerIntegrationTests`: fixed potential race condition (#2380) via NachoSoto (@NachoSoto) * `Offline Entitlements`: create `CustomerInfo` from offline entitlements (#2358) via NachoSoto (@NachoSoto) * Added `@DefaultDecodable.Now` (#2372) via NachoSoto (@NachoSoto) * `HTTPClient`: debug log when performing redirects (#2371) via NachoSoto (@NachoSoto) * `HTTPClient`: new flag to force server errors (#2370) via NachoSoto (@NachoSoto) * `OfferingsManager`: fixed Xcode 13.x build (#2369) via NachoSoto (@NachoSoto) * `Offline Entitlements`: store `ProductEntitlementMapping` in cache (#2355) via NachoSoto (@NachoSoto) * `Offline Entitlements`: added support for fetching `ProductEntitlementMappingResponse` in `OfflineEntitlementsAPI` (#2353) via NachoSoto (@NachoSoto) * `Offline Entitlements`: created `ProductEntitlementMapping` (#2365) via NachoSoto (@NachoSoto) * Implemented `NetworkError.isServerDown` (#2367) via NachoSoto (@NachoSoto) * `ETagManager`: added test for 304 responses with no etag (#2360) via NachoSoto (@NachoSoto) * `TestLogHandler`: increased default capacity (#2357) via NachoSoto (@NachoSoto) * `OfferingsManager`: moved log to common method to remove hardcoded string (#2363) via NachoSoto (@NachoSoto) * `Offline Entitlements`: created `ProductEntitlementMappingResponse` (#2351) via NachoSoto (@NachoSoto) * `HTTPClient`: added test for 2xx response for request with etag (#2361) via NachoSoto (@NachoSoto) * `PurchaseTesterSwiftUI` improvements (#2345) via NachoSoto (@NachoSoto) * `ConfigureStrings`: fixed double-space typo (#2344) via NachoSoto (@NachoSoto) * `ETagManagerTests`: fixed tests on iOS 12 (#2349) via NachoSoto (@NachoSoto) * `DeviceCache`: simplified constructor (#2354) via NachoSoto (@NachoSoto) * `Trusted Entitlements`: changed all APIs to `internal` (#2350) via NachoSoto (@NachoSoto) * `VerificationResult.notRequested`: removed caching reference (#2337) via NachoSoto (@NachoSoto) * Finished signature verification `HTTPClient` tests (#2333) via NachoSoto (@NachoSoto) * `Configuration.Builder.with(entitlementVerificationMode:)`: improved documentation (#2334) via NachoSoto (@NachoSoto) * `ETagManager`: don't ignore failed etags with `Signing.VerificationMode.informational` (#2331) via NachoSoto (@NachoSoto) * `IdentityManager`: clear `ETagManager` and `DeviceCache` if verification is enabled but cached `CustomerInfo` is not (#2330) via NachoSoto (@NachoSoto) * Made `Configuration.EntitlementVerificationMode.enforced` unavailable (#2329) via NachoSoto (@NachoSoto) * Refactor: reorganized files in new Security and Misc folders (#2326) via NachoSoto (@NachoSoto) * `CustomerInfo`: use same grace period logic for active subscriptions (#2327) via NachoSoto (@NachoSoto) * `HTTPClient`: don't verify 4xx/5xx responses (#2322) via NachoSoto (@NachoSoto) * `EntitlementInfo`: request date is not optional (#2325) via NachoSoto (@NachoSoto) * `CustomerInfo`: removed `entitlementVerification` (#2320) via NachoSoto (@NachoSoto) * Renamed `VerificationResult.notVerified` to `.notRequested` (#2321) via NachoSoto (@NachoSoto) * `EntitlementInfo`: add a grace period limit to outdated entitlements (#2288) via NachoSoto (@NachoSoto) * Update `CustomerInfo.requestDate` from 304 responses (#2310) via NachoSoto (@NachoSoto) * `Signing`: added request time & eTag to signature verification (#2309) via NachoSoto (@NachoSoto) * `HTTPClient`: changed header search to be case-insensitive (#2308) via NachoSoto (@NachoSoto) * `HTTPClient`: automatically add `nonce` based on `HTTPRequest.Path` (#2286) via NachoSoto (@NachoSoto) * `PurchaseTester`: added ability to reload `CustomerInfo` with a custom `CacheFetchPolicy` (#2312) via NachoSoto (@NachoSoto) * Fix issue where underlying error information for product fetch errors was not printed in log. (#2281) via Chris Vasselli (@chrisvasselli) * `PurchaseTester`: added ability to set `Configuration.EntitlementVerificationMode` (#2290) via NachoSoto (@NachoSoto) * SwiftUI: Paywall View should respond to changes on the UserView model (#2297) via ConfusedVorlon (@ConfusedVorlon) * Deprecate `usesStoreKit2IfAvailable` (#2293) via Andy Boedo (@aboedo) * `Signing`: updated to use production public key (#2274) via NachoSoto (@NachoSoto) </details> --------- Co-authored-by: RCGitBot <dev+RCGitBot@revenuecat.com>
### New Features * New `ErrorCode.signatureVerificationFailed` which will be used for an upcoming feature ### Bugfixes * `Purchases.deinit`: don't reset `Purchases.proxyURL` (RevenueCat#2346) via NachoSoto (@NachoSoto) <details> <summary><b>Other Changes</b></summary> * Introduced `Configuration.EntitlementVerificationMode` and `VerificationResult` (RevenueCat#2277) via NachoSoto (@NachoSoto) * `PurchasesDiagnostics`: added step to verify signature verification (RevenueCat#2267) via NachoSoto (@NachoSoto) * `HTTPClient`: added signature validation and introduced `ErrorCode.signatureVerificationFailed` (RevenueCat#2272) via NachoSoto (@NachoSoto) * `ETagManager`: don't use ETags if response verification failed (RevenueCat#2347) via NachoSoto (@NachoSoto) * `Integration Tests`: removed `@preconcurrency import` (RevenueCat#2464) via NachoSoto (@NachoSoto) * Clean up: moved `ReceiptParserTests-Info.plist` out of root (RevenueCat#2460) via NachoSoto (@NachoSoto) * Update `CHANGELOG` (RevenueCat#2461) via NachoSoto (@NachoSoto) * Update `SwiftSnapshotTesting` (RevenueCat#2453) via NachoSoto (@NachoSoto) * Fixed docs (RevenueCat#2432) via Kaunteya Suryawanshi (@kaunteya) * Remove unnecessary line break (RevenueCat#2435) via Andy Boedo (@aboedo) * `ProductEntitlementMapping`: enabled entitlement mapping fetching (RevenueCat#2425) via NachoSoto (@NachoSoto) * `BackendPostReceiptDataTests`: increased timeout to fix flaky test (RevenueCat#2426) via NachoSoto (@NachoSoto) * Updated requirements to drop Xcode 13.x support (RevenueCat#2419) via NachoSoto (@NachoSoto) * `Integration Tests`: fixed flaky errors when loading offerings (RevenueCat#2420) via NachoSoto (@NachoSoto) * `PurchaseTester`: fixed compilation for `internal` entitlement verification (RevenueCat#2417) via NachoSoto (@NachoSoto) * `ETagManager`/`HTTPClient`: sending new `X-RC-Last-Refresh-Time` header (RevenueCat#2373) via NachoSoto (@NachoSoto) * `ETagManager`: don't send validation time if not present (RevenueCat#2490) via NachoSoto (@NachoSoto) * SwiftUI Sample Project: Refactor Package terms method to a computed property (RevenueCat#2405) via Joseph Kokenge (@JOyo246) * Clean up v3 load shedder integration tests (RevenueCat#2402) via Andy Boedo (@aboedo) * Fix iOS 12 compilation (RevenueCat#2394) via NachoSoto (@NachoSoto) * Added new `VerificationResult.verifiedOnDevice` (RevenueCat#2379) via NachoSoto (@NachoSoto) * `PurchaseTester`: fix memory leaks (RevenueCat#2392) via Keita Watanabe (@kitwtnb) * Integration tests: add scheduled job (RevenueCat#2389) via Andy Boedo (@aboedo) * Add lane for running iOS v3 load shedder integration tests (RevenueCat#2388) via Andy Boedo (@aboedo) * iOS v3 load shedder integration tests (RevenueCat#2387) via Andy Boedo (@aboedo) * `Offline Entitlements`: created `LoadShedderIntegrationTests` (RevenueCat#2362) via NachoSoto (@NachoSoto) * Purchases.configure: log warning if attempting to use a static appUserID (RevenueCat#2385) via Mark Villacampa (@MarkVillacampa) * `SubscriberAttributesManagerIntegrationTests`: fixed flaky failures (RevenueCat#2381) via NachoSoto (@NachoSoto) * `@DefaultDecodable.Now`: fixed flaky test (RevenueCat#2374) via NachoSoto (@NachoSoto) * `PurchaseTesterSwiftUI`: fixed iOS compilation (RevenueCat#2376) via NachoSoto (@NachoSoto) * `SubscriberAttributesManagerIntegrationTests`: fixed potential race condition (RevenueCat#2380) via NachoSoto (@NachoSoto) * `Offline Entitlements`: create `CustomerInfo` from offline entitlements (RevenueCat#2358) via NachoSoto (@NachoSoto) * Added `@DefaultDecodable.Now` (RevenueCat#2372) via NachoSoto (@NachoSoto) * `HTTPClient`: debug log when performing redirects (RevenueCat#2371) via NachoSoto (@NachoSoto) * `HTTPClient`: new flag to force server errors (RevenueCat#2370) via NachoSoto (@NachoSoto) * `OfferingsManager`: fixed Xcode 13.x build (RevenueCat#2369) via NachoSoto (@NachoSoto) * `Offline Entitlements`: store `ProductEntitlementMapping` in cache (RevenueCat#2355) via NachoSoto (@NachoSoto) * `Offline Entitlements`: added support for fetching `ProductEntitlementMappingResponse` in `OfflineEntitlementsAPI` (RevenueCat#2353) via NachoSoto (@NachoSoto) * `Offline Entitlements`: created `ProductEntitlementMapping` (RevenueCat#2365) via NachoSoto (@NachoSoto) * Implemented `NetworkError.isServerDown` (RevenueCat#2367) via NachoSoto (@NachoSoto) * `ETagManager`: added test for 304 responses with no etag (RevenueCat#2360) via NachoSoto (@NachoSoto) * `TestLogHandler`: increased default capacity (RevenueCat#2357) via NachoSoto (@NachoSoto) * `OfferingsManager`: moved log to common method to remove hardcoded string (RevenueCat#2363) via NachoSoto (@NachoSoto) * `Offline Entitlements`: created `ProductEntitlementMappingResponse` (RevenueCat#2351) via NachoSoto (@NachoSoto) * `HTTPClient`: added test for 2xx response for request with etag (RevenueCat#2361) via NachoSoto (@NachoSoto) * `PurchaseTesterSwiftUI` improvements (RevenueCat#2345) via NachoSoto (@NachoSoto) * `ConfigureStrings`: fixed double-space typo (RevenueCat#2344) via NachoSoto (@NachoSoto) * `ETagManagerTests`: fixed tests on iOS 12 (RevenueCat#2349) via NachoSoto (@NachoSoto) * `DeviceCache`: simplified constructor (RevenueCat#2354) via NachoSoto (@NachoSoto) * `Trusted Entitlements`: changed all APIs to `internal` (RevenueCat#2350) via NachoSoto (@NachoSoto) * `VerificationResult.notRequested`: removed caching reference (RevenueCat#2337) via NachoSoto (@NachoSoto) * Finished signature verification `HTTPClient` tests (RevenueCat#2333) via NachoSoto (@NachoSoto) * `Configuration.Builder.with(entitlementVerificationMode:)`: improved documentation (RevenueCat#2334) via NachoSoto (@NachoSoto) * `ETagManager`: don't ignore failed etags with `Signing.VerificationMode.informational` (RevenueCat#2331) via NachoSoto (@NachoSoto) * `IdentityManager`: clear `ETagManager` and `DeviceCache` if verification is enabled but cached `CustomerInfo` is not (RevenueCat#2330) via NachoSoto (@NachoSoto) * Made `Configuration.EntitlementVerificationMode.enforced` unavailable (RevenueCat#2329) via NachoSoto (@NachoSoto) * Refactor: reorganized files in new Security and Misc folders (RevenueCat#2326) via NachoSoto (@NachoSoto) * `CustomerInfo`: use same grace period logic for active subscriptions (RevenueCat#2327) via NachoSoto (@NachoSoto) * `HTTPClient`: don't verify 4xx/5xx responses (RevenueCat#2322) via NachoSoto (@NachoSoto) * `EntitlementInfo`: request date is not optional (RevenueCat#2325) via NachoSoto (@NachoSoto) * `CustomerInfo`: removed `entitlementVerification` (RevenueCat#2320) via NachoSoto (@NachoSoto) * Renamed `VerificationResult.notVerified` to `.notRequested` (RevenueCat#2321) via NachoSoto (@NachoSoto) * `EntitlementInfo`: add a grace period limit to outdated entitlements (RevenueCat#2288) via NachoSoto (@NachoSoto) * Update `CustomerInfo.requestDate` from 304 responses (RevenueCat#2310) via NachoSoto (@NachoSoto) * `Signing`: added request time & eTag to signature verification (RevenueCat#2309) via NachoSoto (@NachoSoto) * `HTTPClient`: changed header search to be case-insensitive (RevenueCat#2308) via NachoSoto (@NachoSoto) * `HTTPClient`: automatically add `nonce` based on `HTTPRequest.Path` (RevenueCat#2286) via NachoSoto (@NachoSoto) * `PurchaseTester`: added ability to reload `CustomerInfo` with a custom `CacheFetchPolicy` (RevenueCat#2312) via NachoSoto (@NachoSoto) * Fix issue where underlying error information for product fetch errors was not printed in log. (RevenueCat#2281) via Chris Vasselli (@chrisvasselli) * `PurchaseTester`: added ability to set `Configuration.EntitlementVerificationMode` (RevenueCat#2290) via NachoSoto (@NachoSoto) * SwiftUI: Paywall View should respond to changes on the UserView model (RevenueCat#2297) via ConfusedVorlon (@ConfusedVorlon) * Deprecate `usesStoreKit2IfAvailable` (RevenueCat#2293) via Andy Boedo (@aboedo) * `Signing`: updated to use production public key (RevenueCat#2274) via NachoSoto (@NachoSoto) </details> --------- Co-authored-by: RCGitBot <dev+RCGitBot@revenuecat.com>
Fixes CSDK-634.
Changes:
HTTPResponseValidationResultHTTPResponseValidationResultandHTTPClient.ResponseHeaderstoHTTPResponseErrorCode.signatureVerificationFailedSigningTypeto createMockSigningto testHTTPClientwithout bothering with signaturesETagManagerto useHTTPResponse, making it easier to pass through response headers and verification resultsHTTPResponseValidationResultinETagManagercacheHTTPClienthandles signatures from response based onSystemInfo.responseVerificationLevelHTTPRequest.createIntegrityEnforcedRequestRequesttoHTTPRequest.createWithResponseVerificationHTTPClientETagManager