mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-18 03:03:31 +01:00
Verifies StoreApp.isPledged status when updating source
This commit is contained in:
@@ -154,6 +154,7 @@ final class FetchSourceOperation: ResultOperation<Source>
|
|||||||
let identifier = source.identifier
|
let identifier = source.identifier
|
||||||
|
|
||||||
try self.verify(source, response: response)
|
try self.verify(source, response: response)
|
||||||
|
try self.verifyPledges(for: source, in: childContext)
|
||||||
|
|
||||||
try childContext.save()
|
try childContext.save()
|
||||||
|
|
||||||
@@ -223,6 +224,63 @@ private extension FetchSourceOperation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func verifyPledges(for source: Source, in context: NSManagedObjectContext) throws
|
||||||
|
{
|
||||||
|
guard let patreonURL = source.patreonURL, let patreonAccount = DatabaseManager.shared.patreonAccount(in: context) else { return }
|
||||||
|
|
||||||
|
let normalizedPatreonURL = try patreonURL.normalized()
|
||||||
|
|
||||||
|
guard let pledge = patreonAccount.pledges.first(where: { pledge in
|
||||||
|
do
|
||||||
|
{
|
||||||
|
let normalizedCampaignURL = try pledge.campaignURL.normalized()
|
||||||
|
return normalizedCampaignURL == normalizedPatreonURL
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.main.error("Failed to normalize Patreon URL \(pledge.campaignURL, privacy: .public). \(error.localizedDescription, privacy: .public)")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}) else { return }
|
||||||
|
|
||||||
|
// User is pledged to this source's Patreon, so check which apps they're pledged to.
|
||||||
|
|
||||||
|
// We only assign `isPledged = true` because false is already the default,
|
||||||
|
// and only one check needs to be true for isPledged to be true.
|
||||||
|
|
||||||
|
for app in source.apps where app.isPledgeRequired
|
||||||
|
{
|
||||||
|
if let requiredAppPledge = app.pledgeAmount
|
||||||
|
{
|
||||||
|
if pledge.amount >= requiredAppPledge
|
||||||
|
{
|
||||||
|
app.isPledged = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let tierIDs = app._tierIDs
|
||||||
|
{
|
||||||
|
let tier = pledge.tiers.first { tierIDs.contains($0.identifier) }
|
||||||
|
if tier != nil
|
||||||
|
{
|
||||||
|
app.isPledged = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let rewardID = app._rewardID
|
||||||
|
{
|
||||||
|
let reward = pledge.rewards.first { $0.identifier == rewardID }
|
||||||
|
if reward != nil
|
||||||
|
{
|
||||||
|
app.isPledged = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func verifySourceNotBlocked(_ source: Source, response: URLResponse?) throws
|
func verifySourceNotBlocked(_ source: Source, response: URLResponse?) throws
|
||||||
{
|
{
|
||||||
guard let blockedSources = UserDefaults.shared.blockedSources else { return }
|
guard let blockedSources = UserDefaults.shared.blockedSources else { return }
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ public extension DatabaseManager
|
|||||||
|
|
||||||
let predicate = NSPredicate(format: "%K == %@", #keyPath(PatreonAccount.identifier), patreonAccountID)
|
let predicate = NSPredicate(format: "%K == %@", #keyPath(PatreonAccount.identifier), patreonAccountID)
|
||||||
|
|
||||||
let patreonAccount = PatreonAccount.first(satisfying: predicate, in: context)
|
let patreonAccount = PatreonAccount.first(satisfying: predicate, in: context, requestProperties: [\.relationshipKeyPathsForPrefetching: [#keyPath(PatreonAccount._pledges)]])
|
||||||
return patreonAccount
|
return patreonAccount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,12 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
|
|||||||
|
|
||||||
@NSManaged public private(set) var loggedErrors: NSSet /* Set<LoggedError> */ // Use NSSet to avoid eagerly fetching values.
|
@NSManaged public private(set) var loggedErrors: NSSet /* Set<LoggedError> */ // Use NSSet to avoid eagerly fetching values.
|
||||||
|
|
||||||
|
/* Non-Core Data Properties */
|
||||||
|
|
||||||
|
// Used to set isPledged after fetching source.
|
||||||
|
public var _tierIDs: Set<String>?
|
||||||
|
public var _rewardID: String?
|
||||||
|
|
||||||
@nonobjc public var source: Source? {
|
@nonobjc public var source: Source? {
|
||||||
set {
|
set {
|
||||||
self._source = newValue
|
self._source = newValue
|
||||||
@@ -420,6 +426,9 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
|
|||||||
// No conditions, so default to pledgeAmount of 0 to simplify logic.
|
// No conditions, so default to pledgeAmount of 0 to simplify logic.
|
||||||
self._pledgeAmount = 0 as NSDecimalNumber
|
self._pledgeAmount = 0 as NSDecimalNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._tierIDs = patreon.tiers
|
||||||
|
self._rewardID = patreon.benefit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -427,6 +436,9 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
|
|||||||
self.isHiddenWithoutPledge = false
|
self.isHiddenWithoutPledge = false
|
||||||
self._pledgeAmount = nil
|
self._pledgeAmount = nil
|
||||||
self.pledgeCurrency = nil
|
self.pledgeCurrency = nil
|
||||||
|
|
||||||
|
self._tierIDs = nil
|
||||||
|
self._rewardID = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
Reference in New Issue
Block a user