mirror of
https://github.com/mas-cli/mas
synced 2024-11-25 21:10:24 +00:00
Migrate ISStoreAccount
from Grand Central Dispatch to PromiseKit.
Partial #562 Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
This commit is contained in:
parent
aceb4c3ddb
commit
c01f7c541e
6 changed files with 72 additions and 66 deletions
|
@ -11,6 +11,7 @@
|
||||||
--disable blankLinesAroundMark
|
--disable blankLinesAroundMark
|
||||||
--disable consecutiveSpaces
|
--disable consecutiveSpaces
|
||||||
--disable hoistPatternLet
|
--disable hoistPatternLet
|
||||||
|
--disable hoistTry
|
||||||
--disable indent
|
--disable indent
|
||||||
--disable trailingCommas
|
--disable trailingCommas
|
||||||
|
|
||||||
|
|
|
@ -7,85 +7,81 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import CommerceKit
|
import CommerceKit
|
||||||
|
import PromiseKit
|
||||||
import StoreFoundation
|
import StoreFoundation
|
||||||
|
|
||||||
extension ISStoreAccount: StoreAccount {
|
extension ISStoreAccount: StoreAccount {
|
||||||
static var primaryAccount: ISStoreAccount? {
|
static var primaryAccount: Promise<ISStoreAccount> {
|
||||||
if #available(macOS 10.13, *) {
|
if #available(macOS 10.13, *) {
|
||||||
let group = DispatchGroup()
|
return race(
|
||||||
group.enter()
|
Promise<ISStoreAccount> { seal in
|
||||||
|
ISServiceProxy.genericShared().accountService.primaryAccount { storeAccount in
|
||||||
var account: ISStoreAccount?
|
seal.fulfill(storeAccount)
|
||||||
ISServiceProxy.genericShared().accountService.primaryAccount { storeAccount in
|
}
|
||||||
account = storeAccount
|
},
|
||||||
group.leave()
|
after(seconds: 30).then {
|
||||||
}
|
Promise(error: MASError.notSignedIn)
|
||||||
|
}
|
||||||
_ = group.wait(timeout: .now() + 30)
|
)
|
||||||
|
|
||||||
return account
|
|
||||||
} else {
|
} else {
|
||||||
return CKAccountStore.shared().primaryAccount
|
return .value(CKAccountStore.shared().primaryAccount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func signIn(username: String, password: String, systemDialog: Bool = false) throws -> ISStoreAccount {
|
static func signIn(username: String, password: String, systemDialog: Bool) -> Promise<ISStoreAccount> {
|
||||||
if #available(macOS 10.13, *) {
|
if #available(macOS 10.13, *) {
|
||||||
// Signing in is no longer possible as of High Sierra.
|
// Signing in is no longer possible as of High Sierra.
|
||||||
// https://github.com/mas-cli/mas/issues/164
|
// https://github.com/mas-cli/mas/issues/164
|
||||||
throw MASError.notSupported
|
return Promise(error: MASError.notSupported)
|
||||||
} else {
|
} else {
|
||||||
if let account = primaryAccount, account.isSignedIn {
|
return
|
||||||
throw MASError.alreadySignedIn(asAccountId: account.identifier)
|
primaryAccount
|
||||||
}
|
.then { account -> Promise<ISStoreAccount> in
|
||||||
|
if account.isSignedIn {
|
||||||
|
return Promise(error: MASError.alreadySignedIn(asAccountId: account.identifier))
|
||||||
|
}
|
||||||
|
|
||||||
let password =
|
let password =
|
||||||
password.isEmpty && !systemDialog
|
password.isEmpty && !systemDialog
|
||||||
? String(validatingUTF8: getpass("Password: "))!
|
? String(validatingUTF8: getpass("Password: "))!
|
||||||
: password
|
: password
|
||||||
|
|
||||||
guard !password.isEmpty || systemDialog else {
|
guard !password.isEmpty || systemDialog else {
|
||||||
throw MASError.noPasswordProvided
|
return Promise(error: MASError.noPasswordProvided)
|
||||||
}
|
}
|
||||||
|
|
||||||
let accountService = ISServiceProxy.genericShared().accountService
|
let context = ISAuthenticationContext(accountID: 0)
|
||||||
accountService.setStoreClient(ISStoreClient(storeClientType: 0))
|
context.appleIDOverride = username
|
||||||
|
|
||||||
let context = ISAuthenticationContext(accountID: 0)
|
let signInPromise =
|
||||||
context.appleIDOverride = username
|
Promise<ISStoreAccount> { seal in
|
||||||
if !systemDialog {
|
let accountService = ISServiceProxy.genericShared().accountService
|
||||||
context.demoMode = true
|
accountService.setStoreClient(ISStoreClient(storeClientType: 0))
|
||||||
context.demoAccountName = username
|
accountService.signIn(with: context) { success, storeAccount, error in
|
||||||
context.demoAccountPassword = password
|
if success, let storeAccount {
|
||||||
context.demoAutologinMode = true
|
seal.fulfill(storeAccount)
|
||||||
}
|
} else {
|
||||||
|
seal.reject(MASError.signInFailed(error: error as NSError?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let group = DispatchGroup()
|
if systemDialog {
|
||||||
group.enter()
|
return signInPromise
|
||||||
|
} else {
|
||||||
|
context.demoMode = true
|
||||||
|
context.demoAccountName = username
|
||||||
|
context.demoAccountPassword = password
|
||||||
|
context.demoAutologinMode = true
|
||||||
|
|
||||||
var storeAccount: ISStoreAccount?
|
return race(
|
||||||
var maserror: MASError?
|
signInPromise,
|
||||||
// Only works on macOS Sierra and below
|
after(seconds: 30).then {
|
||||||
accountService.signIn(with: context) { success, account, error in
|
Promise(error: MASError.signInFailed(error: nil))
|
||||||
if success, let account {
|
}
|
||||||
storeAccount = account
|
)
|
||||||
} else {
|
}
|
||||||
maserror = .signInFailed(error: error as NSError?)
|
|
||||||
}
|
}
|
||||||
group.leave()
|
|
||||||
}
|
|
||||||
|
|
||||||
if systemDialog {
|
|
||||||
group.wait()
|
|
||||||
} else {
|
|
||||||
_ = group.wait(timeout: .now() + 30)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let storeAccount {
|
|
||||||
return storeAccount
|
|
||||||
}
|
|
||||||
|
|
||||||
throw maserror ?? MASError.signInFailed(error: nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ extension SSPurchase {
|
||||||
// Monterey obscures the user's App Store account information, but allows
|
// Monterey obscures the user's App Store account information, but allows
|
||||||
// redownloads without passing the account to SSPurchase.
|
// redownloads without passing the account to SSPurchase.
|
||||||
// https://github.com/mas-cli/mas/issues/417
|
// https://github.com/mas-cli/mas/issues/417
|
||||||
if let storeAccount = ISStoreAccount.primaryAccount {
|
if let storeAccount = try? ISStoreAccount.primaryAccount.wait() {
|
||||||
accountIdentifier = storeAccount.dsID
|
accountIdentifier = storeAccount.dsID
|
||||||
appleID = storeAccount.identifier
|
appleID = storeAccount.identifier
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,11 @@ public struct AccountCommand: CommandProtocol {
|
||||||
return .failure(.notSupported)
|
return .failure(.notSupported)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let account = ISStoreAccount.primaryAccount {
|
do {
|
||||||
print(account.identifier)
|
print(try ISStoreAccount.primaryAccount.wait().identifier)
|
||||||
} else {
|
return .success(())
|
||||||
return .failure(.notSignedIn)
|
} catch {
|
||||||
|
return .failure(error as? MASError ?? .failed(error: error as NSError))
|
||||||
}
|
}
|
||||||
return .success(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ public struct SignInCommand: CommandProtocol {
|
||||||
password: options.password,
|
password: options.password,
|
||||||
systemDialog: options.dialog
|
systemDialog: options.dialog
|
||||||
)
|
)
|
||||||
|
.wait()
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(error as? MASError ?? .signInFailed(error: error as NSError))
|
return .failure(error as? MASError ?? .signInFailed(error: error as NSError))
|
||||||
|
|
|
@ -11,6 +11,8 @@ import Foundation
|
||||||
public enum MASError: Error, Equatable {
|
public enum MASError: Error, Equatable {
|
||||||
case notSupported
|
case notSupported
|
||||||
|
|
||||||
|
case failed(error: NSError?)
|
||||||
|
|
||||||
case notSignedIn
|
case notSignedIn
|
||||||
case noPasswordProvided
|
case noPasswordProvided
|
||||||
case signInFailed(error: NSError?)
|
case signInFailed(error: NSError?)
|
||||||
|
@ -46,6 +48,12 @@ extension MASError: CustomStringConvertible {
|
||||||
For more information see: \
|
For more information see: \
|
||||||
https://github.com/mas-cli/mas#%EF%B8%8F-known-issues
|
https://github.com/mas-cli/mas#%EF%B8%8F-known-issues
|
||||||
"""
|
"""
|
||||||
|
case .failed(let error):
|
||||||
|
if let error {
|
||||||
|
return "Failed: \(error.localizedDescription)"
|
||||||
|
} else {
|
||||||
|
return "Failed"
|
||||||
|
}
|
||||||
case .signInFailed(let error):
|
case .signInFailed(let error):
|
||||||
if let error {
|
if let error {
|
||||||
return "Sign in failed: \(error.localizedDescription)"
|
return "Sign in failed: \(error.localizedDescription)"
|
||||||
|
|
Loading…
Reference in a new issue