Fixes “Device Already Registered” error

This commit is contained in:
Riley Testut
2020-01-21 15:12:48 -08:00
parent 5f29b38d64
commit 301d7261c2
4 changed files with 125 additions and 62 deletions

View File

@@ -260,6 +260,18 @@ private extension AppManager
refreshAnisetteDataOperation.addDependency(authenticationOperation ?? findServerOperation)
operations.append(refreshAnisetteDataOperation)
/* Prepare Developer Account */
let prepareDeveloperAccountOperation = PrepareDeveloperAccountOperation(group: group)
prepareDeveloperAccountOperation.resultHandler = { (result) in
switch result
{
case .failure(let error): group.error = error
case .success: break
}
}
prepareDeveloperAccountOperation.addDependency(refreshAnisetteDataOperation)
operations.append(prepareDeveloperAccountOperation)
for app in apps
{
let context = AppOperationContext(bundleIdentifier: app.bundleIdentifier, group: group)
@@ -272,7 +284,7 @@ private extension AppManager
guard let resignedApp = self.process(result, context: context) else { return }
context.resignedApp = resignedApp
}
resignAppOperation.addDependency(refreshAnisetteDataOperation)
resignAppOperation.addDependency(prepareDeveloperAccountOperation)
progress.addChild(resignAppOperation.progress, withPendingUnitCount: 20)
operations.append(resignAppOperation)

View File

@@ -0,0 +1,81 @@
//
// PrepareDeveloperAccountOperation.swift
// AltStore
//
// Created by Riley Testut on 1/7/20.
// Copyright © 2020 Riley Testut. All rights reserved.
//
import Foundation
import Roxas
import AltSign
@objc(PrepareDeveloperAccountOperation)
class PrepareDeveloperAccountOperation: ResultOperation<Void>
{
let group: OperationGroup
init(group: OperationGroup)
{
self.group = group
super.init()
self.progress.totalUnitCount = 2
}
override func main()
{
super.main()
if let error = self.group.error
{
self.finish(.failure(error))
return
}
guard
let signer = self.group.signer,
let session = self.group.session
else { return self.finish(.failure(OperationError.invalidParameters)) }
// Register Device
self.registerCurrentDevice(for: signer.team, session: session) { (result) in
let result = result.map { _ in () }
self.finish(result)
}
}
}
private extension PrepareDeveloperAccountOperation
{
func registerCurrentDevice(for team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result<ALTDevice, Error>) -> Void)
{
guard let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String else {
return completionHandler(.failure(OperationError.unknownUDID))
}
ALTAppleAPI.shared.fetchDevices(for: team, session: session) { (devices, error) in
do
{
let devices = try Result(devices, error).get()
if let device = devices.first(where: { $0.identifier == udid })
{
completionHandler(.success(device))
}
else
{
ALTAppleAPI.shared.registerDevice(name: UIDevice.current.name, identifier: udid, team: team, session: session) { (device, error) in
completionHandler(Result(device, error))
}
}
}
catch
{
completionHandler(.failure(error))
}
}
}
}

View File

@@ -41,46 +41,41 @@ class ResignAppOperation: ResultOperation<ALTApplication>
let session = self.context.group.session
else { return self.finish(.failure(OperationError.invalidParameters)) }
// Register Device
self.registerCurrentDevice(for: signer.team, session: session) { (result) in
guard let _ = self.process(result) else { return }
// Prepare Provisioning Profiles
self.prepareProvisioningProfiles(app.fileURL, team: signer.team, session: session) { (result) in
guard let profiles = self.process(result) else { return }
// Prepare Provisioning Profiles
self.prepareProvisioningProfiles(app.fileURL, team: signer.team, session: session) { (result) in
guard let profiles = self.process(result) else { return }
// Prepare app bundle
let prepareAppProgress = Progress.discreteProgress(totalUnitCount: 2)
self.progress.addChild(prepareAppProgress, withPendingUnitCount: 3)
let prepareAppBundleProgress = self.prepareAppBundle(for: app, profiles: profiles) { (result) in
guard let appBundleURL = self.process(result) else { return }
// Prepare app bundle
let prepareAppProgress = Progress.discreteProgress(totalUnitCount: 2)
self.progress.addChild(prepareAppProgress, withPendingUnitCount: 3)
print("Resigning App:", self.context.bundleIdentifier)
let prepareAppBundleProgress = self.prepareAppBundle(for: app, profiles: profiles) { (result) in
guard let appBundleURL = self.process(result) else { return }
// Resign app bundle
let resignProgress = self.resignAppBundle(at: appBundleURL, signer: signer, profiles: Array(profiles.values)) { (result) in
guard let resignedURL = self.process(result) else { return }
print("Resigning App:", self.context.bundleIdentifier)
// Resign app bundle
let resignProgress = self.resignAppBundle(at: appBundleURL, signer: signer, profiles: Array(profiles.values)) { (result) in
guard let resignedURL = self.process(result) else { return }
// Finish
do
{
let destinationURL = InstalledApp.refreshedIPAURL(for: app)
try FileManager.default.copyItem(at: resignedURL, to: destinationURL, shouldReplace: true)
// Finish
do
{
let destinationURL = InstalledApp.refreshedIPAURL(for: app)
try FileManager.default.copyItem(at: resignedURL, to: destinationURL, shouldReplace: true)
// Use appBundleURL since we need an app bundle, not .ipa.
guard let resignedApplication = ALTApplication(fileURL: appBundleURL) else { throw OperationError.invalidApp }
self.finish(.success(resignedApplication))
}
catch
{
self.finish(.failure(error))
}
// Use appBundleURL since we need an app bundle, not .ipa.
guard let resignedApplication = ALTApplication(fileURL: appBundleURL) else { throw OperationError.invalidApp }
self.finish(.success(resignedApplication))
}
catch
{
self.finish(.failure(error))
}
prepareAppProgress.addChild(resignProgress, withPendingUnitCount: 1)
}
prepareAppProgress.addChild(prepareAppBundleProgress, withPendingUnitCount: 1)
prepareAppProgress.addChild(resignProgress, withPendingUnitCount: 1)
}
prepareAppProgress.addChild(prepareAppBundleProgress, withPendingUnitCount: 1)
}
}
@@ -105,35 +100,6 @@ class ResignAppOperation: ResultOperation<ALTApplication>
private extension ResignAppOperation
{
func registerCurrentDevice(for team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result<ALTDevice, Error>) -> Void)
{
guard let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String else {
return completionHandler(.failure(OperationError.unknownUDID))
}
ALTAppleAPI.shared.fetchDevices(for: team, session: session) { (devices, error) in
do
{
let devices = try Result(devices, error).get()
if let device = devices.first(where: { $0.identifier == udid })
{
completionHandler(.success(device))
}
else
{
ALTAppleAPI.shared.registerDevice(name: UIDevice.current.name, identifier: udid, team: team, session: session) { (device, error) in
completionHandler(Result(device, error))
}
}
}
catch
{
completionHandler(.failure(error))
}
}
}
func prepareProvisioningProfiles(_ fileURL: URL, team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result<[String: ALTProvisioningProfile], Error>) -> Void)
{
guard let bundle = Bundle(url: fileURL), let app = ALTApplication(fileURL: fileURL) else { return completionHandler(.failure(OperationError.invalidApp)) }