Trusted Entitlements: add support for signing request headers#3424
Conversation
03c29a7 to
beb69fc
Compare
658c490 to
b777a9f
Compare
700fc54 to
50ad627
Compare
b777a9f to
958a5a9
Compare
|
|
||
| static func headerParametersForSignatureHeader(with headers: RequestHeaders) -> RequestHeaders { | ||
| if let header = HTTPRequest.headerParametersForSignatureHeader(headers: headers) { | ||
| return [RequestHeader.headerParametersForSignature.rawValue: header] |
There was a problem hiding this comment.
This is tested by snapshot tests.
26c660b to
5d0afcb
Compare
958a5a9 to
01268ef
Compare
This allows us to verify exactly what headers are included in all requests. It also simplifies the implementation for #3424.
01268ef to
7a2c93b
Compare
9ec2f4b to
132dca7
Compare
…er hash Follow up to #3424. This adds coverage to ensure that the backend continues to sign correctly for old SDK versions that don't support this.
Trusted Entitlements: add support for signing request headersTrusted Entitlements: add support for signing request headers
| } | ||
|
|
||
| @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *) | ||
| static func signingParameterHash(_ values: [String]) -> String { |
There was a problem hiding this comment.
This is now a shared method for both POST body and header parameters.
| nonce + | ||
| path + | ||
| postParameterHash + | ||
| headerParametersHash + |
There was a problem hiding this comment.
Thanks to unit tests I was able to get this right. Initially I had this before the post hash.
| let response = """ | ||
| {"request_date":"2023-12-08T19:17:04Z","request_date_ms":1702063024731,"subscriber":{"entitlements":{},"first_seen":"2023-12-08T19:13:02Z","last_seen":"2023-12-08T19:13:02Z","management_url":null,"non_subscriptions":{},"original_app_user_id":"$RCAnonymousID:6ca4535c42714f88abc99c563703f113","original_application_version":null,"original_purchase_date":null,"other_purchases":{},"subscriptions":{}}}\n | ||
| """ | ||
| let expectedSignature = "x2qnlHOl5WuzGi4TbSUVHxzlKELRCfrRYG9XAiso7ucZTQAAYEZqbguA3X0YfCJqCKh2hnTLSdEr4R+t23xBlTxceWZu2TJjK3461UJKpUnrwXDv+tYo2K54IoS3/tsEr3VmB5ppKAq0P2CR7SwbsDPpxUlHBcl5/4XJvb/DHOnTKjIVd4WJ+57LLWvIV9sDHnj9XxiBez+p5cEjez1RtUis0XdCfAFXU8XfAq6ggiEJKX4F" |
There was a problem hiding this comment.
I've generated these from the backend, so we can confirm that these real signatures are valid.
03c0f9f to
ad9af4c
Compare
33a7047 to
26eb5bf
Compare
…er hash Follow up to #3424. This adds coverage to ensure that the backend continues to sign correctly for old SDK versions that don't support this.
…s-15 (#3501) Requested by @NachoSoto for [trusted-entitlements-headers](https://github.com/RevenueCat/purchases-ios/tree/trusted-entitlements-headers) Co-authored-by: Distiller <distiller@static.38.23.39.57.cyberlynk.net>
26eb5bf to
730c8b5
Compare
…er hash Follow up to #3424. This adds coverage to ensure that the backend continues to sign correctly for old SDK versions that don't support this.
|
This should be ready, but the signature is still wrong on the load shedder |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3424 +/- ##
==========================================
+ Coverage 85.97% 86.02% +0.05%
==========================================
Files 240 241 +1
Lines 17494 17552 +58
==========================================
+ Hits 15040 15099 +59
+ Misses 2454 2453 -1 ☔ View full report in Codecov by Sentry. |
|
Merging this! 🎉 |
…er hash Follow up to #3424. This adds coverage to ensure that the backend continues to sign correctly for old SDK versions that don't support this.
**This is an automatic release.** ### RevenueCatUI * `Paywalls`: add header image to `watchOS` paywalls (#3542) via NachoSoto (@NachoSoto) * `Paywalls`: improve template 5 landscape layout (#3534) via NachoSoto (@NachoSoto) * `Paywalls`: fix template 5 footer loading view alignment (#3537) via NachoSoto (@NachoSoto) * `Paywalls`: improve template 1 landscape layout (#3532) via NachoSoto (@NachoSoto) * `Paywalls`: fix `ColorInformation.multiScheme` on `watchOS` (#3530) via NachoSoto (@NachoSoto) ### Other Changes * `Trusted Entitlements`: tests for signature verification without header hash (#3505) via NachoSoto (@NachoSoto) * `.debugRevenueCatOverlay`: added `Locale` (#3539) via NachoSoto (@NachoSoto) * `Trusted Entitlements`: add support for signing request headers (#3424) via NachoSoto (@NachoSoto) * `CI`: Add architecture to cache keys (#3538) via Mark Villacampa (@MarkVillacampa) * `Paywalls Tester`: remove double close button (#3531) via NachoSoto (@NachoSoto) * Fix `RevenueCatUI` snapshot tests (#3526) via NachoSoto (@NachoSoto)
…ad of Offering Matches the Android PR #3424 changes: - Replace `offering: Offering?` property with `@_spi(Internal) presentedOfferingContext` so the params object stores the derived context rather than the raw Offering - Add `@_spi(Internal)` designated init for hybrid SDK (PHC) passthrough of pre-resolved presentedOfferingContext without requiring an Offering object - Deprecate `init(paywallId:offeringId:)` in favour of `init(paywallId:offering:)` - Update `trackCustomPaywallImpression` resolution order to match Android: params.presentedOfferingContext → cached[offeringId] → cached.current - Update Swift and ObjC API testers accordingly
…ad of Offering Matches the Android PR #3424 changes: - Replace `offering: Offering?` property with `@_spi(Internal) presentedOfferingContext` so the params object stores the derived context rather than the raw Offering - Add `@_spi(Internal)` designated init for hybrid SDK (PHC) passthrough of pre-resolved presentedOfferingContext without requiring an Offering object - Deprecate `init(paywallId:offeringId:)` in favour of `init(paywallId:offering:)` - Update `trackCustomPaywallImpression` resolution order to match Android: params.presentedOfferingContext → cached[offeringId] → cached.current - Update Swift and ObjC API testers accordingly
* Add presented offering context to custom paywall events * Update API testers for offering-based custom paywall impression init * Add tests for placement and targeting in custom paywall events * Accept Offering for custom paywall impression and derive context * Decouple custom paywall wire request from PaywallEvent's nested context type * Look up offeringId in cached offerings to derive presented offering context * Update baseline swiftinterface files for `rickvdl/add-presented-offering-context-to-custom-paywall-events` (#6722) * Add presented offering context to custom paywall events * Update API testers for offering-based custom paywall impression init * Add tests for placement and targeting in custom paywall events * Accept Offering for custom paywall impression and derive context * Decouple custom paywall wire request from PaywallEvent's nested context type * Look up offeringId in cached offerings to derive presented offering context * Update baseline swiftinterface files --------- Co-authored-by: Rick van der Linden <rick.vanderlinden@revenuecat.com> * Inline offering resolution as plain if-let in trackCustomPaywallImpression * Fix race between init and applicationWillEnterForeground in TransactionMetadataSyncHelper The syncIfNeeded call in Purchases.init races with the call from applicationWillEnterForeground: if the init task acquires isSyncing first (even with empty metadata), it blocks the foreground notification task from running. Removing the init call is safe because applicationWillEnterForeground fires reliably on startup and covers the sync need. * Revert "Fix race between init and applicationWillEnterForeground in TransactionMetadataSyncHelper" This reverts commit d977926. * Align CustomPaywallImpressionParams with Android: store context instead of Offering Matches the Android PR #3424 changes: - Replace `offering: Offering?` property with `@_spi(Internal) presentedOfferingContext` so the params object stores the derived context rather than the raw Offering - Add `@_spi(Internal)` designated init for hybrid SDK (PHC) passthrough of pre-resolved presentedOfferingContext without requiring an Offering object - Deprecate `init(paywallId:offeringId:)` in favour of `init(paywallId:offering:)` - Update `trackCustomPaywallImpression` resolution order to match Android: params.presentedOfferingContext → cached[offeringId] → cached.current - Update Swift and ObjC API testers accordingly * Fix lint: suppress line_length for @available deprecated message * Remove params.offering tests — property replaced by presentedOfferingContext * Update baseline swiftinterface files (#6864) * Include placement and targeting in custom paywall event map --------- Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>
This adds support for including arbitrary headers in the signature verification, therefore preventing tampering of them.