mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-19 03:33:36 +01:00
Verifies source’s identifier doesn’t change after refreshing
This commit is contained in:
@@ -428,7 +428,7 @@ extension AppManager
|
|||||||
let operations = sources.map { (source) -> FetchSourceOperation in
|
let operations = sources.map { (source) -> FetchSourceOperation in
|
||||||
dispatchGroup.enter()
|
dispatchGroup.enter()
|
||||||
|
|
||||||
let fetchSourceOperation = FetchSourceOperation(sourceURL: source.sourceURL, managedObjectContext: managedObjectContext)
|
let fetchSourceOperation = FetchSourceOperation(source: source, managedObjectContext: managedObjectContext)
|
||||||
fetchSourceOperation.resultHandler = { (result) in
|
fetchSourceOperation.resultHandler = { (result) in
|
||||||
switch result
|
switch result
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,11 +21,15 @@ extension SourceError
|
|||||||
case unsupported
|
case unsupported
|
||||||
case duplicateBundleID
|
case duplicateBundleID
|
||||||
case duplicateVersion
|
case duplicateVersion
|
||||||
|
|
||||||
|
case changedID
|
||||||
}
|
}
|
||||||
|
|
||||||
static func unsupported(_ source: Source) -> SourceError { SourceError(code: .unsupported, source: source) }
|
static func unsupported(_ source: Source) -> SourceError { SourceError(code: .unsupported, source: source) }
|
||||||
static func duplicateBundleID(_ bundleID: String, source: Source) -> SourceError { SourceError(code: .duplicateBundleID, source: source, bundleID: bundleID) }
|
static func duplicateBundleID(_ bundleID: String, source: Source) -> SourceError { SourceError(code: .duplicateBundleID, source: source, bundleID: bundleID) }
|
||||||
static func duplicateVersion(_ version: String, for app: StoreApp, source: Source) -> SourceError { SourceError(code: .duplicateVersion, source: source, app: app, version: version) }
|
static func duplicateVersion(_ version: String, for app: StoreApp, source: Source) -> SourceError { SourceError(code: .duplicateVersion, source: source, app: app, version: version) }
|
||||||
|
|
||||||
|
static func changedID(_ identifier: String, previousID: String, source: Source) -> SourceError { SourceError(code: .changedID, source: source, sourceID: identifier, previousSourceID: previousID) }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SourceError: ALTLocalizedError
|
struct SourceError: ALTLocalizedError
|
||||||
@@ -39,6 +43,10 @@ struct SourceError: ALTLocalizedError
|
|||||||
var bundleID: String?
|
var bundleID: String?
|
||||||
var version: String?
|
var version: String?
|
||||||
|
|
||||||
|
// Store in userInfo so they can be viewed from Error Log.
|
||||||
|
@UserInfoValue var sourceID: String?
|
||||||
|
@UserInfoValue var previousSourceID: String?
|
||||||
|
|
||||||
var errorFailureReason: String {
|
var errorFailureReason: String {
|
||||||
switch self.code
|
switch self.code
|
||||||
{
|
{
|
||||||
@@ -67,6 +75,18 @@ struct SourceError: ALTLocalizedError
|
|||||||
|
|
||||||
let failureReason = String(format: NSLocalizedString("The source “%@” contains %@ for %@.", comment: ""), self.$source.name, versionFragment, appFragment)
|
let failureReason = String(format: NSLocalizedString("The source “%@” contains %@ for %@.", comment: ""), self.$source.name, versionFragment, appFragment)
|
||||||
return failureReason
|
return failureReason
|
||||||
|
|
||||||
|
case .changedID:
|
||||||
|
let failureReason = String(format: NSLocalizedString("The identifier of the source “%@” has changed.", comment: ""), self.$source.name)
|
||||||
|
return failureReason
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var recoverySuggestion: String? {
|
||||||
|
switch self.code
|
||||||
|
{
|
||||||
|
case .changedID: return NSLocalizedString("A source cannot change its identifier once added. This source can no longer be updated.", comment: "")
|
||||||
|
default: return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,6 +97,10 @@ class FetchSourceOperation: ResultOperation<Source>
|
|||||||
let sourceURL: URL
|
let sourceURL: URL
|
||||||
let managedObjectContext: NSManagedObjectContext
|
let managedObjectContext: NSManagedObjectContext
|
||||||
|
|
||||||
|
// Non-nil when updating an existing source.
|
||||||
|
@Managed
|
||||||
|
private var source: Source?
|
||||||
|
|
||||||
private let session: URLSession
|
private let session: URLSession
|
||||||
|
|
||||||
private lazy var dateFormatter: ISO8601DateFormatter = {
|
private lazy var dateFormatter: ISO8601DateFormatter = {
|
||||||
@@ -84,10 +108,23 @@ class FetchSourceOperation: ResultOperation<Source>
|
|||||||
return dateFormatter
|
return dateFormatter
|
||||||
}()
|
}()
|
||||||
|
|
||||||
init(sourceURL: URL, managedObjectContext: NSManagedObjectContext = DatabaseManager.shared.persistentContainer.newBackgroundContext())
|
// New source
|
||||||
|
convenience init(sourceURL: URL, managedObjectContext: NSManagedObjectContext = DatabaseManager.shared.persistentContainer.newBackgroundContext())
|
||||||
|
{
|
||||||
|
self.init(sourceURL: sourceURL, source: nil, managedObjectContext: managedObjectContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing source
|
||||||
|
convenience init(source: Source, managedObjectContext: NSManagedObjectContext = DatabaseManager.shared.persistentContainer.newBackgroundContext())
|
||||||
|
{
|
||||||
|
self.init(sourceURL: source.sourceURL, source: source, managedObjectContext: managedObjectContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
private init(sourceURL: URL, source: Source?, managedObjectContext: NSManagedObjectContext)
|
||||||
{
|
{
|
||||||
self.sourceURL = sourceURL
|
self.sourceURL = sourceURL
|
||||||
self.managedObjectContext = managedObjectContext
|
self.managedObjectContext = managedObjectContext
|
||||||
|
self.source = source
|
||||||
|
|
||||||
let configuration = URLSessionConfiguration.default
|
let configuration = URLSessionConfiguration.default
|
||||||
configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
|
configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
|
||||||
@@ -191,5 +228,10 @@ private extension FetchSourceOperation
|
|||||||
versions.insert(version.version)
|
versions.insert(version.version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let previousSourceID = self.$source.identifier
|
||||||
|
{
|
||||||
|
guard source.identifier == previousSourceID else { throw SourceError.changedID(source.identifier, previousID: previousSourceID, source: source) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user