From a7b31ec7a28c78a043fd22c98f814b6b2fe3e33b Mon Sep 17 00:00:00 2001 From: Magesh K <47920326+mahee96@users.noreply.github.com> Date: Sun, 8 Dec 2024 02:50:40 +0530 Subject: [PATCH] clean-checkpoint-2-restore-missing --- AltDaemon/AltDaemon-Bridging-Header.h | 59 -------- AltDaemon/AltDaemon.entitlements | 22 --- AltDaemon/AnisetteDataManager.swift | 65 --------- AltDaemon/AppManager.swift | 138 ------------------ AltDaemon/DaemonRequestHandler.swift | 123 ---------------- AltDaemon/XPCConnectionHandler.swift | 93 ------------ AltDaemon/main.swift | 14 -- AltStore/AppDelegate.swift | 4 +- AltStore/Managing Apps/AppManager.swift | 103 +++++-------- .../Operations/Errors/OperationError.swift | 3 +- AltStore/Operations/VerifyAppOperation.swift | 2 +- AltStore/Sources/SourcesViewController.swift | 106 +++++++------- .../AltStore 10.xcdatamodel/contents | 1 + .../AltStore 12.xcdatamodel/contents | 1 + .../AltStore 13.xcdatamodel/contents | 1 + .../AltStore 14.xcdatamodel/contents | 1 + .../AltStore 15.xcdatamodel/contents | 1 + .../AltStore 16.xcdatamodel/contents | 1 + .../AltStore 17.xcdatamodel/contents | 3 +- .../AltStore 9.xcdatamodel/contents | 1 + AltStoreCore/Model/LoggedError.swift | 12 +- .../xcmapping.xml | 4 +- 22 files changed, 114 insertions(+), 644 deletions(-) delete mode 100644 AltDaemon/AltDaemon-Bridging-Header.h delete mode 100644 AltDaemon/AltDaemon.entitlements delete mode 100644 AltDaemon/AnisetteDataManager.swift delete mode 100644 AltDaemon/AppManager.swift delete mode 100644 AltDaemon/DaemonRequestHandler.swift delete mode 100644 AltDaemon/XPCConnectionHandler.swift delete mode 100644 AltDaemon/main.swift diff --git a/AltDaemon/AltDaemon-Bridging-Header.h b/AltDaemon/AltDaemon-Bridging-Header.h deleted file mode 100644 index 94f57276..00000000 --- a/AltDaemon/AltDaemon-Bridging-Header.h +++ /dev/null @@ -1,59 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - -#import - -// Shared -#import "ALTConstants.h" -#import "ALTConnection.h" -#import "NSError+ALTServerError.h" -#import "CFNotificationName+AltStore.h" - -// libproc -int proc_pidpath(int pid, void * buffer, uint32_t buffersize); - -// Security.framework -CF_ENUM(uint32_t) { - kSecCSInternalInformation = 1 << 0, - kSecCSSigningInformation = 1 << 1, - kSecCSRequirementInformation = 1 << 2, - kSecCSDynamicInformation = 1 << 3, - kSecCSContentInformation = 1 << 4, - kSecCSSkipResourceDirectory = 1 << 5, - kSecCSCalculateCMSDigest = 1 << 6, -}; - -OSStatus SecStaticCodeCreateWithPath(CFURLRef path, uint32_t flags, void ** __nonnull CF_RETURNS_RETAINED staticCode); -OSStatus SecCodeCopySigningInformation(void *code, uint32_t flags, CFDictionaryRef * __nonnull CF_RETURNS_RETAINED information); - -NS_ASSUME_NONNULL_BEGIN - -@interface AKDevice : NSObject - -@property (class, readonly) AKDevice *currentDevice; - -@property (strong, readonly) NSString *serialNumber; -@property (strong, readonly) NSString *uniqueDeviceIdentifier; -@property (strong, readonly) NSString *serverFriendlyDescription; - -@end - -@interface AKAppleIDSession : NSObject - -- (instancetype)initWithIdentifier:(NSString *)identifier; - -- (NSDictionary *)appleIDHeadersForRequest:(NSURLRequest *)request; - -@end - -@interface LSApplicationWorkspace : NSObject - -@property (class, readonly) LSApplicationWorkspace *defaultWorkspace; - -- (BOOL)installApplication:(NSURL *)fileURL withOptions:(nullable NSDictionary *)options error:(NSError *_Nullable *)error; -- (BOOL)uninstallApplication:(NSString *)bundleIdentifier withOptions:(nullable NSDictionary *)options; - -@end - -NS_ASSUME_NONNULL_END diff --git a/AltDaemon/AltDaemon.entitlements b/AltDaemon/AltDaemon.entitlements deleted file mode 100644 index 0e9e5703..00000000 --- a/AltDaemon/AltDaemon.entitlements +++ /dev/null @@ -1,22 +0,0 @@ - - - - - application-identifier - $(DEVELOPMENT_TEAM).$(ORG_IDENTIFIER).AltDaemon - get-task-allow - - platform-application - - com.apple.authkit.client.private - - com.apple.private.mobileinstall.allowedSPI - - Install - Uninstall - InstallForLaunchServices - UninstallForLaunchServices - InstallLocalProvisioned - - - diff --git a/AltDaemon/AnisetteDataManager.swift b/AltDaemon/AnisetteDataManager.swift deleted file mode 100644 index daff25d6..00000000 --- a/AltDaemon/AnisetteDataManager.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// AnisetteDataManager.swift -// AltDaemon -// -// Created by Riley Testut on 6/1/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation - -import AltSign - -private extension UserDefaults -{ - @objc var localUserID: String? { - get { return self.string(forKey: #keyPath(UserDefaults.localUserID)) } - set { self.set(newValue, forKey: #keyPath(UserDefaults.localUserID)) } - } -} - -struct AnisetteDataManager -{ - static let shared = AnisetteDataManager() - - private let dateFormatter = ISO8601DateFormatter() - - private init() - { - dlopen("/System/Library/PrivateFrameworks/AuthKit.framework/AuthKit", RTLD_NOW); - } - - func requestAnisetteData() throws -> ALTAnisetteData - { - var request = URLRequest(url: URL(string: "https://developerservices2.apple.com/services/QH65B2/listTeams.action?clientId=XABBG36SBA")!) - request.httpMethod = "POST" - - let akAppleIDSession = unsafeBitCast(NSClassFromString("AKAppleIDSession")!, to: AKAppleIDSession.Type.self) - let akDevice = unsafeBitCast(NSClassFromString("AKDevice")!, to: AKDevice.Type.self) - - let session = akAppleIDSession.init(identifier: "com.apple.gs.xcode.auth") - let headers = session.appleIDHeaders(for: request) - - let device = akDevice.current - let date = self.dateFormatter.date(from: headers["X-Apple-I-Client-Time"] ?? "") ?? Date() - - var localUserID = UserDefaults.standard.localUserID - if localUserID == nil - { - localUserID = UUID().uuidString - UserDefaults.standard.localUserID = localUserID - } - - let anisetteData = ALTAnisetteData(machineID: headers["X-Apple-I-MD-M"] ?? "", - oneTimePassword: headers["X-Apple-I-MD"] ?? "", - localUserID: headers["X-Apple-I-MD-LU"] ?? localUserID ?? "", - routingInfo: UInt64(headers["X-Apple-I-MD-RINFO"] ?? "") ?? 0, - deviceUniqueIdentifier: device.uniqueDeviceIdentifier, - deviceSerialNumber: device.serialNumber, - deviceDescription: " ", - date: date, - locale: .current, - timeZone: .current) - return anisetteData - } -} diff --git a/AltDaemon/AppManager.swift b/AltDaemon/AppManager.swift deleted file mode 100644 index a0408ba2..00000000 --- a/AltDaemon/AppManager.swift +++ /dev/null @@ -1,138 +0,0 @@ -// -// AppManager.swift -// AltDaemon -// -// Created by Riley Testut on 6/1/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation - -import AltSign - -private extension URL -{ - static let profilesDirectoryURL = URL(fileURLWithPath: "/var/MobileDevice/ProvisioningProfiles", isDirectory: true) -} - -private extension CFNotificationName -{ - static let updatedProvisioningProfiles = CFNotificationName("MISProvisioningProfileRemoved" as CFString) -} - -struct AppManager -{ - static let shared = AppManager() - - private let appQueue = DispatchQueue(label: "com.rileytestut.AltDaemon.appQueue", qos: .userInitiated) - private let profilesQueue = OperationQueue() - - private let fileCoordinator = NSFileCoordinator() - - private init() - { - self.profilesQueue.name = "com.rileytestut.AltDaemon.profilesQueue" - self.profilesQueue.qualityOfService = .userInitiated - } - - func installApp(at fileURL: URL, bundleIdentifier: String, activeProfiles: Set?, completionHandler: @escaping (Result) -> Void) - { - self.appQueue.async { - let lsApplicationWorkspace = unsafeBitCast(NSClassFromString("LSApplicationWorkspace")!, to: LSApplicationWorkspace.Type.self) - - let options = ["CFBundleIdentifier": bundleIdentifier, "AllowInstallLocalProvisioned": NSNumber(value: true)] as [String : Any] - let result = Result { try lsApplicationWorkspace.default.installApplication(fileURL, withOptions: options) } - - completionHandler(result) - } - } - - func removeApp(forBundleIdentifier bundleIdentifier: String, completionHandler: @escaping (Result) -> Void) - { - self.appQueue.async { - let lsApplicationWorkspace = unsafeBitCast(NSClassFromString("LSApplicationWorkspace")!, to: LSApplicationWorkspace.Type.self) - lsApplicationWorkspace.default.uninstallApplication(bundleIdentifier, withOptions: nil) - - completionHandler(.success(())) - } - } - - func install(_ profiles: Set, activeProfiles: Set?, completionHandler: @escaping (Result) -> Void) - { - let intent = NSFileAccessIntent.writingIntent(with: .profilesDirectoryURL, options: []) - self.fileCoordinator.coordinate(with: [intent], queue: self.profilesQueue) { (error) in - do - { - if let error = error - { - throw error - } - - let installingBundleIDs = Set(profiles.map(\.bundleIdentifier)) - - let profileURLs = try FileManager.default.contentsOfDirectory(at: intent.url, includingPropertiesForKeys: nil, options: []) - - // Remove all inactive profiles (if active profiles are provided), and the previous profiles. - for fileURL in profileURLs - { - // Use memory mapping to reduce peak memory usage and stay within limit. - guard let profile = try? ALTProvisioningProfile(url: fileURL, options: [.mappedIfSafe]) else { continue } - - if installingBundleIDs.contains(profile.bundleIdentifier) || (activeProfiles?.contains(profile.bundleIdentifier) == false && profile.isFreeProvisioningProfile) - { - try FileManager.default.removeItem(at: fileURL) - } - else - { - print("Ignoring:", profile.bundleIdentifier, profile.uuid) - } - } - - for profile in profiles - { - let destinationURL = URL.profilesDirectoryURL.appendingPathComponent(profile.uuid.uuidString.lowercased()) - try profile.data.write(to: destinationURL, options: .atomic) - } - - completionHandler(.success(())) - } - catch - { - completionHandler(.failure(error)) - } - - // Notify system to prevent accidentally untrusting developer certificate. - CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), .updatedProvisioningProfiles, nil, nil, true) - } - } - - func removeProvisioningProfiles(forBundleIdentifiers bundleIdentifiers: Set, completionHandler: @escaping (Result) -> Void) - { - let intent = NSFileAccessIntent.writingIntent(with: .profilesDirectoryURL, options: []) - self.fileCoordinator.coordinate(with: [intent], queue: self.profilesQueue) { (error) in - do - { - let profileURLs = try FileManager.default.contentsOfDirectory(at: intent.url, includingPropertiesForKeys: nil, options: []) - - for fileURL in profileURLs - { - guard let profile = ALTProvisioningProfile(url: fileURL) else { continue } - - if bundleIdentifiers.contains(profile.bundleIdentifier) - { - try FileManager.default.removeItem(at: fileURL) - } - } - - completionHandler(.success(())) - } - catch - { - completionHandler(.failure(error)) - } - - // Notify system to prevent accidentally untrusting developer certificate. - CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), .updatedProvisioningProfiles, nil, nil, true) - } - } -} diff --git a/AltDaemon/DaemonRequestHandler.swift b/AltDaemon/DaemonRequestHandler.swift deleted file mode 100644 index 48b2d7c7..00000000 --- a/AltDaemon/DaemonRequestHandler.swift +++ /dev/null @@ -1,123 +0,0 @@ -// -// DaemonRequestHandler.swift -// AltDaemon -// -// Created by Riley Testut on 6/1/20. -// Copyright © 2019 Riley Testut. All rights reserved. -// - -import Foundation - -typealias DaemonConnectionManager = ConnectionManager - -private let connectionManager = ConnectionManager(requestHandler: DaemonRequestHandler(), - connectionHandlers: [XPCConnectionHandler()]) - -extension DaemonConnectionManager -{ - static var shared: ConnectionManager { - return connectionManager - } -} - -struct DaemonRequestHandler: RequestHandler -{ - func handleAnisetteDataRequest(_ request: AnisetteDataRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) - { - do - { - let anisetteData = try AnisetteDataManager.shared.requestAnisetteData() - - let response = AnisetteDataResponse(anisetteData: anisetteData) - completionHandler(.success(response)) - } - catch - { - completionHandler(.failure(error)) - } - } - - func handlePrepareAppRequest(_ request: PrepareAppRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) - { - guard let fileURL = request.fileURL else { return completionHandler(.failure(ALTServerError(.invalidRequest))) } - - print("Awaiting begin installation request...") - - connection.receiveRequest() { (result) in - print("Received begin installation request with result:", result) - - do - { - guard case .beginInstallation(let request) = try result.get() else { throw ALTServerError(.unknownRequest) } - guard let bundleIdentifier = request.bundleIdentifier else { throw ALTServerError(.invalidRequest) } - - AppManager.shared.installApp(at: fileURL, bundleIdentifier: bundleIdentifier, activeProfiles: request.activeProfiles) { (result) in - let result = result.map { InstallationProgressResponse(progress: 1.0) } - print("Installed app with result:", result) - - completionHandler(result) - } - } - catch - { - completionHandler(.failure(error)) - } - } - } - - func handleInstallProvisioningProfilesRequest(_ request: InstallProvisioningProfilesRequest, for connection: Connection, - completionHandler: @escaping (Result) -> Void) - { - AppManager.shared.install(request.provisioningProfiles, activeProfiles: request.activeProfiles) { (result) in - switch result - { - case .failure(let error): - print("Failed to install profiles \(request.provisioningProfiles.map { $0.bundleIdentifier }):", error) - completionHandler(.failure(error)) - - case .success: - print("Installed profiles:", request.provisioningProfiles.map { $0.bundleIdentifier }) - - let response = InstallProvisioningProfilesResponse() - completionHandler(.success(response)) - } - } - } - - func handleRemoveProvisioningProfilesRequest(_ request: RemoveProvisioningProfilesRequest, for connection: Connection, - completionHandler: @escaping (Result) -> Void) - { - AppManager.shared.removeProvisioningProfiles(forBundleIdentifiers: request.bundleIdentifiers) { (result) in - switch result - { - case .failure(let error): - print("Failed to remove profiles \(request.bundleIdentifiers):", error) - completionHandler(.failure(error)) - - case .success: - print("Removed profiles:", request.bundleIdentifiers) - - let response = RemoveProvisioningProfilesResponse() - completionHandler(.success(response)) - } - } - } - - func handleRemoveAppRequest(_ request: RemoveAppRequest, for connection: Connection, completionHandler: @escaping (Result) -> Void) - { - AppManager.shared.removeApp(forBundleIdentifier: request.bundleIdentifier) { (result) in - switch result - { - case .failure(let error): - print("Failed to remove app \(request.bundleIdentifier):", error) - completionHandler(.failure(error)) - - case .success: - print("Removed app:", request.bundleIdentifier) - - let response = RemoveAppResponse() - completionHandler(.success(response)) - } - } - } -} diff --git a/AltDaemon/XPCConnectionHandler.swift b/AltDaemon/XPCConnectionHandler.swift deleted file mode 100644 index c1571a3f..00000000 --- a/AltDaemon/XPCConnectionHandler.swift +++ /dev/null @@ -1,93 +0,0 @@ -// -// XPCConnectionHandler.swift -// AltDaemon -// -// Created by Riley Testut on 9/14/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation -import Security - -class XPCConnectionHandler: NSObject, ConnectionHandler -{ - var connectionHandler: ((Connection) -> Void)? - var disconnectionHandler: ((Connection) -> Void)? - - private let dispatchQueue = DispatchQueue(label: "io.altstore.XPCConnectionListener", qos: .utility) - private let listeners = XPCConnection.machServiceNames.map { NSXPCListener.makeListener(machServiceName: $0) } - - deinit - { - self.stopListening() - } - - func startListening() - { - for listener in self.listeners - { - listener.delegate = self - listener.resume() - } - } - - func stopListening() - { - self.listeners.forEach { $0.suspend() } - } -} - -private extension XPCConnectionHandler -{ - func disconnect(_ connection: Connection) - { - connection.disconnect() - - self.disconnectionHandler?(connection) - } -} - -extension XPCConnectionHandler: NSXPCListenerDelegate -{ - func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool - { - let maximumPathLength = 4 * UInt32(MAXPATHLEN) - - let pathBuffer = UnsafeMutablePointer.allocate(capacity: Int(maximumPathLength)) - defer { pathBuffer.deallocate() } - - proc_pidpath(newConnection.processIdentifier, pathBuffer, maximumPathLength) - - let path = String(cString: pathBuffer) - let fileURL = URL(fileURLWithPath: path) - - var code: UnsafeMutableRawPointer? - defer { code.map { Unmanaged.fromOpaque($0).release() } } - - var status = SecStaticCodeCreateWithPath(fileURL as CFURL, 0, &code) - guard status == 0 else { return false } - - var signingInfo: CFDictionary? - defer { signingInfo.map { Unmanaged.passUnretained($0).release() } } - - status = SecCodeCopySigningInformation(code, kSecCSInternalInformation | kSecCSSigningInformation, &signingInfo) - guard status == 0 else { return false } - - // Only accept connections from AltStore. - guard - let codeSigningInfo = signingInfo as? [String: Any], - let bundleIdentifier = codeSigningInfo["identifier"] as? String, - bundleIdentifier.contains(Bundle.Info.appbundleIdentifier) - else { return false } - - let connection = XPCConnection(newConnection) - newConnection.invalidationHandler = { [weak self, weak connection] in - guard let self = self, let connection = connection else { return } - self.disconnect(connection) - } - - self.connectionHandler?(connection) - - return true - } -} diff --git a/AltDaemon/main.swift b/AltDaemon/main.swift deleted file mode 100644 index a4b69654..00000000 --- a/AltDaemon/main.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// main.swift -// AltDaemon -// -// Created by Riley Testut on 6/2/20. -// Copyright © 2020 Riley Testut. All rights reserved. -// - -import Foundation - -autoreleasepool { - DaemonConnectionManager.shared.start() - RunLoop.current.run() -} diff --git a/AltStore/AppDelegate.swift b/AltStore/AppDelegate.swift index 18747746..7a08e54f 100644 --- a/AltStore/AppDelegate.swift +++ b/AltStore/AppDelegate.swift @@ -77,9 +77,9 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { UserDefaults.standard.preferredServerID = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.serverID) as? String - #if DEBUG || BETA +// #if DEBUG || BETA UserDefaults.standard.isDebugModeEnabled = true - #endif +// #endif self.prepareForBackgroundFetch() diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index 60bc278d..13a8ff73 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -304,10 +304,13 @@ extension AppManager func log(_ error: Error, operation: LoggedError.Operation, app: AppProtocol) { - switch error { - case ~OperationError.Code.cancelled: return // Don't log cancelled events - default: break + switch error + { + case is CancellationError: return // Don't log CancellationErrors + case let nsError as NSError where nsError.domain == CancellationError()._domain: return + default: break } + // Sanitize NSError on same thread before performing background task. let sanitizedError = (error as NSError).sanitizedForSerialization() @@ -903,6 +906,7 @@ extension AppManager var installedApp: InstalledApp? } + let appName = installedApp.name let context = Context() context.installedApp = installedApp @@ -915,12 +919,11 @@ extension AppManager let localizedTitle = String(format: NSLocalizedString("Failed to Enable JIT for %@", comment: ""), appName) let error = nsError.withLocalizedTitle(localizedTitle) - self.log(error, operation: .enableJIT, app: installedApp) +// self.log(error, operation: .enableJIT, app: installedApp) completionHandler(.failure(error)) } } - enableJITOperation.addDependency(findServerOperation) - + self.run([enableJITOperation], context: context, requiresSerialQueue: true) } @@ -1061,7 +1064,8 @@ private extension AppManager } var loggedErrorOperation: LoggedError.Operation { - switch self { + switch self + { case .install: return .install case .update: return .update case .refresh: return .refresh @@ -1351,7 +1355,14 @@ private extension AppManager } } - private func _install(_ app: AppProtocol, operation appOperation: AppOperation, group: RefreshGroup, context: InstallAppOperationContext? = nil, additionalEntitlements: [ALTEntitlement: Any] = [.increasedDebuggingMemoryLimit: ALTEntitlement.increasedDebuggingMemoryLimit, .increasedMemoryLimit: ALTEntitlement.increasedMemoryLimit, .extendedVirtualAddressing: ALTEntitlement.extendedVirtualAddressing], cacheApp: Bool = true, completionHandler: @escaping (Result) -> Void) -> Progress + private func _install(_ app: AppProtocol, + operation appOperation: AppOperation, + group: RefreshGroup, + context: InstallAppOperationContext? = nil, + additionalEntitlements: [ALTEntitlement: Any]? = [.increasedDebuggingMemoryLimit: ALTEntitlement.increasedDebuggingMemoryLimit, .increasedMemoryLimit: ALTEntitlement.increasedMemoryLimit, .extendedVirtualAddressing: ALTEntitlement.extendedVirtualAddressing], + reviewPermissions permissionReviewMode: VerifyAppOperation.PermissionReviewMode = .none, + cacheApp: Bool = true, + completionHandler: @escaping (Result) -> Void) -> Progress { let progress = Progress.discreteProgress(totalUnitCount: 100) @@ -1490,8 +1501,8 @@ private extension AppManager } removeAppExtensionsOperation.addDependency(verifyOperation) - - + + /* Refresh Anisette Data */ let refreshAnisetteDataOperation = FetchAnisetteDataOperation(context: group.context) refreshAnisetteDataOperation.resultHandler = { (result) in @@ -1511,7 +1522,7 @@ private extension AppManager switch result { case .failure(let error): context.error = error - case .success(let provisioningProfiles): + case .success(let provisioningProfiles): context.provisioningProfiles = provisioningProfiles print("PROVISIONING PROFILES \(context.provisioningProfiles)") } @@ -1642,7 +1653,7 @@ private extension AppManager } patchAppOperation.addDependency(deactivateAppsOperation) - + /* Resign */ let resignAppOperation = ResignAppOperation(context: context) resignAppOperation.resultHandler = { (result) in @@ -1752,8 +1763,7 @@ private extension AppManager } progress.addChild(fetchProvisioningProfilesOperation.progress, withPendingUnitCount: 60) fetchProvisioningProfilesOperation.addDependency(validateAppExtensionsOperation) - - + /* Refresh */ let refreshAppOperation = RefreshAppOperation(context: context) refreshAppOperation.resultHandler = { (result) in @@ -2055,7 +2065,7 @@ private extension AppManager let temporaryDirectoryURL = context.temporaryDirectory.appendingPathComponent("AltBackup-" + UUID().uuidString) try FileManager.default.createDirectory(at: temporaryDirectoryURL, withIntermediateDirectories: true, attributes: nil) - guard let altbackupFileURL = Bundle.main.url(forResource: "AltBackup", withExtension: "ipa") else { throw OperationError.appNotFound(name: app.name) } + guard let altbackupFileURL = Bundle.main.url(forResource: "AltBackup", withExtension: "ipa") else { throw OperationError.appNotFound(name: "AltBackup") } let unzippedAppBundleURL = try FileManager.default.unzipAppBundle(at: altbackupFileURL, toDirectory: temporaryDirectoryURL) guard let unzippedAppBundle = Bundle(url: unzippedAppBundleURL) else { throw OperationError.invalidApp } @@ -2201,20 +2211,27 @@ private extension AppManager catch let nsError as NSError { var appName: String! - if let app = operation.app as? (NSManagedObject & AppProtocol) { - if let context = app.managedObjectContext { + if let app = operation.app as? (NSManagedObject & AppProtocol) + { + if let context = app.managedObjectContext + { context.performAndWait { appName = app.name } - } else { + } + else + { appName = NSLocalizedString("Unknown App", comment: "") } - } else { + } + else + { appName = operation.app.name } let localizedTitle: String - switch operation { + switch operation + { case .install: localizedTitle = String(format: NSLocalizedString("Failed to Install %@", comment: ""), appName) case .refresh: localizedTitle = String(format: NSLocalizedString("Failed to Refresh %@", comment: ""), appName) case .update: localizedTitle = String(format: NSLocalizedString("Failed to Update %@", comment: ""), appName) @@ -2250,51 +2267,7 @@ private extension AppManager let request = UNNotificationRequest(identifier: AppManager.expirationWarningNotificationID, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) } - - func log(_ error: Error, operation: LoggedError.Operation, app: AppProtocol) - { - switch error - { - case is CancellationError: return // Don't log CancellationErrors - case let nsError as NSError where nsError.domain == CancellationError()._domain: return - default: break - } - - // Sanitize NSError on same thread before performing background task. - let sanitizedError = (error as NSError).sanitizedForSerialization() - - let loggedErrorOperation: LoggedError.Operation = { - switch operation - { - case .install: return .install - case .update: return .update - case .refresh: return .refresh - case .activate: return .activate - case .deactivate: return .deactivate - case .backup: return .backup - case .restore: return .restore - } - }() - - DatabaseManager.shared.persistentContainer.performBackgroundTask { context in - var app = app - if let managedApp = app as? NSManagedObject, let tempApp = context.object(with: managedApp.objectID) as? AppProtocol - { - app = tempApp - } - - do - { - _ = LoggedError(error: sanitizedError, app: app, operation: operation, context: context) - try context.save() - } - catch let saveError - { - print("[ALTLog] Failed to log error \(sanitizedError.domain) code \(sanitizedError.code) for \(app.bundleIdentifier):", saveError) - } - } - } - + func run(_ operations: [Foundation.Operation], context: OperationContext?, requiresSerialQueue: Bool = false) { // Find "Install AltStore" operation if it already exists in `context` diff --git a/AltStore/Operations/Errors/OperationError.swift b/AltStore/Operations/Errors/OperationError.swift index 9188742f..e9c82047 100644 --- a/AltStore/Operations/Errors/OperationError.swift +++ b/AltStore/Operations/Errors/OperationError.swift @@ -19,7 +19,7 @@ extension OperationError // General case unknown = 1000 case unknownResult = 1001 - case cancelled = 1002 +// case cancelled = 1002 case timedOut = 1003 case notAuthenticated = 1004 case appNotFound = 1005 @@ -200,7 +200,6 @@ struct OperationError: ALTLocalizedError { case .maximumAppIDLimitReached: return NSLocalizedString("Cannot register more than 10 App IDs within a 7 day period.", comment: "") case .noSources: return NSLocalizedString("There are no SideStore sources.", comment: "") case .missingAppGroup: return NSLocalizedString("SideStore's shared app group could not be accessed.", comment: "") - case .invalidParameters: return NSLocalizedString("Invalid parameters.", comment: "") case .forbidden: guard let failureReason = self._failureReason else { return NSLocalizedString("The operation is forbidden.", comment: "") } return failureReason diff --git a/AltStore/Operations/VerifyAppOperation.swift b/AltStore/Operations/VerifyAppOperation.swift index 83410f91..8edd4fb2 100644 --- a/AltStore/Operations/VerifyAppOperation.swift +++ b/AltStore/Operations/VerifyAppOperation.swift @@ -133,7 +133,7 @@ private extension VerifyAppOperation func verifyPermissions(of app: ALTApplication, @AsyncManaged match appVersion: AppVersion) async throws { guard self.permissionsMode != .none else { return } - guard let storeApp = await $appVersion.app else { throw OperationError.invalidParameters } + guard let storeApp = await $appVersion.app else { throw OperationError.invalidParameters("verifyPermissions requires storeApp to be non-nil") } // Verify source permissions match first. let allPermissions = try await self.verifyPermissions(of: app, match: storeApp) diff --git a/AltStore/Sources/SourcesViewController.swift b/AltStore/Sources/SourcesViewController.swift index 76520056..f26a7379 100644 --- a/AltStore/Sources/SourcesViewController.swift +++ b/AltStore/Sources/SourcesViewController.swift @@ -348,26 +348,26 @@ private extension SourcesViewController { func handleAddSourceDeepLink() { - let alertController = UIAlertController(title: NSLocalizedString("Add Source", comment: ""), message: nil, preferredStyle: .alert) - alertController.addTextField { (textField) in - textField.placeholder = "https://apps.sidestore.io" - textField.textContentType = .URL - } - alertController.addAction(.cancel) - alertController.addAction(UIAlertAction(title: NSLocalizedString("Add", comment: ""), style: .default) { (action) in - guard let text = alertController.textFields![0].text else { return } - guard var sourceURL = URL(string: text) else { return } - if sourceURL.scheme == nil { - guard let httpsSourceURL = URL(string: "https://" + text) else { return } - sourceURL = httpsSourceURL - } - - self.navigationItem.leftBarButtonItem?.isIndicatingActivity = true - - self.addSource(url: sourceURL) { _ in - self.navigationItem.leftBarButtonItem?.isIndicatingActivity = false - } - }) +// let alertController = UIAlertController(title: NSLocalizedString("Add Source", comment: ""), message: nil, preferredStyle: .alert) +// alertController.addTextField { (textField) in +// textField.placeholder = "https://apps.sidestore.io" +// textField.textContentType = .URL +// } +// alertController.addAction(.cancel) +// alertController.addAction(UIAlertAction(title: NSLocalizedString("Add", comment: ""), style: .default) { (action) in +// guard let text = alertController.textFields![0].text else { return } +// guard var sourceURL = URL(string: text) else { return } +// if sourceURL.scheme == nil { +// guard let httpsSourceURL = URL(string: "https://" + text) else { return } +// sourceURL = httpsSourceURL +// } +// +// self.navigationItem.leftBarButtonItem?.isIndicatingActivity = true +// +// self.addSource(url: sourceURL) { _ in +// self.navigationItem.leftBarButtonItem?.isIndicatingActivity = false +// } +// }) guard let url = self.deepLinkSourceURL, self.view.window != nil else { return } // Only handle deep link once. @@ -453,39 +453,39 @@ private extension SourcesViewController { completionHandler?(false) - let dispatchGroup = DispatchGroup() - - var sourcesByURL = [URL: Source]() - var fetchError: Error? - - for sourceURL in featuredSourceURLs - { - dispatchGroup.enter() - - AppManager.shared.fetchSource(sourceURL: sourceURL, managedObjectContext: context) { result in - // Serialize access to sourcesByURL. - context.performAndWait { - switch result - { - case .failure(let error): fetchError = error - case .success(let source): sourcesByURL[source.sourceURL] = source - } - - dispatchGroup.leave() - } - } - } - - dispatchGroup.notify(queue: .main) { - if let error = fetchError - { - print(error) - // 1 error doesn't mean all trusted sources failed to load! Riley, why did you do this??????? -// finish(.failure(error)) - } - let sources = featuredSourceURLs.compactMap { sourcesByURL[$0] } - finish(.success(sources)) - } +// let dispatchGroup = DispatchGroup() +// +// var sourcesByURL = [URL: Source]() +// var fetchError: Error? +// +// for sourceURL in featuredSourceURLs +// { +// dispatchGroup.enter() +// +// AppManager.shared.fetchSource(sourceURL: sourceURL, managedObjectContext: context) { result in +// // Serialize access to sourcesByURL. +// context.performAndWait { +// switch result +// { +// case .failure(let error): fetchError = error +// case .success(let source): sourcesByURL[source.sourceURL] = source +// } +// +// dispatchGroup.leave() +// } +// } +// } +// +// dispatchGroup.notify(queue: .main) { +// if let error = fetchError +// { +// print(error) +// // 1 error doesn't mean all trusted sources failed to load! Riley, why did you do this??????? +//// finish(.failure(error)) +// } +// let sources = featuredSourceURLs.compactMap { sourcesByURL[$0] } +// finish(.success(sources)) +// } self.present(error) } } diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 10.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 10.xcdatamodel/contents index fec61865..f5f27142 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 10.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 10.xcdatamodel/contents @@ -36,6 +36,7 @@ + diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 12.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 12.xcdatamodel/contents index 30810acb..61dba015 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 12.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 12.xcdatamodel/contents @@ -56,6 +56,7 @@ + diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 13.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 13.xcdatamodel/contents index a1866d15..da0121cc 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 13.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 13.xcdatamodel/contents @@ -71,6 +71,7 @@ + diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents index fe3172c2..ebd7667a 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 14.xcdatamodel/contents @@ -88,6 +88,7 @@ + diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 15.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 15.xcdatamodel/contents index 3367fcee..7e2e8441 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 15.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 15.xcdatamodel/contents @@ -88,6 +88,7 @@ + diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents index 6a764404..b36401d2 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 16.xcdatamodel/contents @@ -88,6 +88,7 @@ + diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 17.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 17.xcdatamodel/contents index f6b5f36c..cd65f8f5 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 17.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 17.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -88,6 +88,7 @@ + diff --git a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 9.xcdatamodel/contents b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 9.xcdatamodel/contents index 8370b14c..5280bd72 100644 --- a/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 9.xcdatamodel/contents +++ b/AltStoreCore/Model/AltStore.xcdatamodeld/AltStore 9.xcdatamodel/contents @@ -36,6 +36,7 @@ + diff --git a/AltStoreCore/Model/LoggedError.swift b/AltStoreCore/Model/LoggedError.swift index 50c92bd3..0a22dd45 100644 --- a/AltStoreCore/Model/LoggedError.swift +++ b/AltStoreCore/Model/LoggedError.swift @@ -19,7 +19,6 @@ extension LoggedError case deactivate case backup case restore - case connection case enableJIT } } @@ -69,11 +68,15 @@ public class LoggedError: NSManagedObject, Fetchable self._operation = operation?.rawValue let nsError: NSError - if let error = error as? ALTServerError, error.code == .underlyingError, let underlyingError = error.underlyingError { + if let error = error as? ALTServerError, error.code == .underlyingError, let underlyingError = error.underlyingError + { nsError = underlyingError as NSError - } else { + } + else + { nsError = error as NSError } + self.domain = nsError.domain self.code = Int32(nsError.code) self.userInfo = nsError.userInfo @@ -130,8 +133,7 @@ public extension LoggedError case .deactivate: return String(format: NSLocalizedString("Deactivate %@ Failed", comment: ""), self.appName) case .backup: return String(format: NSLocalizedString("Backup %@ Failed", comment: ""), self.appName) case .restore: return String(format: NSLocalizedString("Restore %@ Failed", comment: ""), self.appName) - case .connection: return String(format: NSLocalizedString("Connection during %@ Failed", comment: ""), self.appName) - case .enableJIT: return String(format: NSLocalizedString("Enabling JIT for %@ Failed", comment: ""), self.appName) + case .enableJIT: return String(format: NSLocalizedString("Enable JIT for %@ Failed", comment: ""), self.appName) } } } diff --git a/AltStoreCore/Model/Migrations/Mapping Models/AltStore12ToAltStore13.xcmappingmodel/xcmapping.xml b/AltStoreCore/Model/Migrations/Mapping Models/AltStore12ToAltStore13.xcmappingmodel/xcmapping.xml index fa8dce2b..8f4f1c63 100644 --- a/AltStoreCore/Model/Migrations/Mapping Models/AltStore12ToAltStore13.xcmappingmodel/xcmapping.xml +++ b/AltStoreCore/Model/Migrations/Mapping Models/AltStore12ToAltStore13.xcmappingmodel/xcmapping.xml @@ -10,7 +10,9 @@ NSPersistenceFrameworkVersion - 1244 + 1414 + NSStoreModelVersionChecksumKey + bMpud663vz0bXQE24C6Rh4MvJ5jVnzsD2sI3njZkKbc= NSStoreModelVersionHashes XDDevAttributeMapping