mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-03-25 08:55:46 +00:00
Better handling of when AppleId is not a developer
This commit is contained in:
parent
04c79c36ad
commit
1496f32e28
4 changed files with 49 additions and 12 deletions
|
|
@ -148,11 +148,12 @@ public class Client {
|
|||
/// Use the olympus session endpoint to see if the existing session is still valid
|
||||
public func validateSession() -> AnyPublisher<Void, Error> {
|
||||
return Current.network.dataTask(with: URLRequest.olympusSession)
|
||||
.tryMap { (data, response) in
|
||||
guard
|
||||
let jsonObject = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any],
|
||||
jsonObject["provider"] != nil
|
||||
else { throw AuthenticationError.invalidSession }
|
||||
.map(\.data)
|
||||
.decode(type: AppleSession.self, decoder: JSONDecoder())
|
||||
.tryMap { session in
|
||||
if session.provider == nil {
|
||||
throw AuthenticationError.notDeveloperAppleId
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
|
@ -174,6 +175,7 @@ public enum AuthenticationState: Equatable {
|
|||
case unauthenticated
|
||||
case waitingForSecondFactor(TwoFactorOption, AuthOptionsResponse, AppleSessionData)
|
||||
case authenticated
|
||||
case notAppleDeveloper
|
||||
}
|
||||
|
||||
public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
|
||||
|
|
@ -186,7 +188,8 @@ public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
|
|||
case accountUsesUnknownAuthenticationKind(String?)
|
||||
case accountLocked(String)
|
||||
case badStatusCode(statusCode: Int, data: Data, response: HTTPURLResponse)
|
||||
|
||||
case notDeveloperAppleId
|
||||
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case .invalidSession:
|
||||
|
|
@ -212,6 +215,8 @@ public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
|
|||
return message
|
||||
case let .badStatusCode(statusCode, _, _):
|
||||
return "Received an unexpected status code: \(statusCode). If you continue to have problems, please submit a bug report in the Help menu."
|
||||
case .notDeveloperAppleId:
|
||||
return "You are not registered as an Apple Developer. Please visit Apple Developer Registration. https://developer.apple.com/register/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -362,3 +367,20 @@ public enum SecurityCode {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Object returned from olympus/v1/session
|
||||
/// Used to check Provider, and show name
|
||||
/// If Provider is nil, we can assume the Apple User is NOT an Apple Developer and can't download Xcode.
|
||||
public struct AppleSession: Decodable, Equatable {
|
||||
public let user: AppleUser
|
||||
public let provider: AppleProvider?
|
||||
}
|
||||
|
||||
public struct AppleProvider: Decodable, Equatable {
|
||||
public let providerId: Int
|
||||
public let name: String
|
||||
}
|
||||
|
||||
public struct AppleUser: Decodable, Equatable {
|
||||
public let fullName: String
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,9 +40,15 @@ extension AppState {
|
|||
}
|
||||
|
||||
private func install(_ installationType: InstallationType, downloader: Downloader, attemptNumber: Int) -> AnyPublisher<InstalledXcode, Error> {
|
||||
// We need to check if the Apple ID that is logged in is an Apple Developer
|
||||
// Since users can use xcodereleases, we don't check for Apple ID on a xcode list refresh
|
||||
// If the Apple Id is not a developer, the download action will try and download a xip that is invalid, causing a `xcode13.0.xip is damaged and can't be expanded.`
|
||||
Logger.appState.info("Using \(downloader) downloader")
|
||||
|
||||
return getXcodeArchive(installationType, downloader: downloader)
|
||||
return validateSession()
|
||||
.flatMap { _ in
|
||||
self.getXcodeArchive(installationType, downloader: downloader)
|
||||
}
|
||||
.flatMap { xcode, url -> AnyPublisher<InstalledXcode, Swift.Error> in
|
||||
self.installArchivedXcode(xcode, at: url)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,12 @@ extension AppState {
|
|||
private func updateAvailableXcodes(from dataSource: DataSource) -> AnyPublisher<[AvailableXcode], Error> {
|
||||
switch dataSource {
|
||||
case .apple:
|
||||
return signInIfNeeded()
|
||||
return signInIfNeeded()
|
||||
.flatMap { [unowned self] in
|
||||
// this will check to see if the Apple ID is a valid Apple Developer or not.
|
||||
// If it's not, we can't use the Apple source to get xcode info.
|
||||
self.validateSession()
|
||||
}
|
||||
.flatMap { [unowned self] in self.releasedXcodes().combineLatest(self.prereleaseXcodes()) }
|
||||
.receive(on: DispatchQueue.main)
|
||||
.map { releasedXcodes, prereleaseXcodes in
|
||||
|
|
|
|||
|
|
@ -116,8 +116,9 @@ class AppState: ObservableObject {
|
|||
.receive(on: DispatchQueue.main)
|
||||
.handleEvents(receiveCompletion: { completion in
|
||||
if case .failure = completion {
|
||||
self.authenticationState = .unauthenticated
|
||||
self.presentedSheet = .signIn
|
||||
// this is causing some awkwardness with showing an alert with the error and also popping up the sign in view
|
||||
// self.authenticationState = .unauthenticated
|
||||
// self.presentedSheet = .signIn
|
||||
}
|
||||
})
|
||||
.eraseToAnyPublisher()
|
||||
|
|
@ -227,7 +228,7 @@ class AppState: ObservableObject {
|
|||
self.authError = error
|
||||
case .finished:
|
||||
switch self.authenticationState {
|
||||
case .authenticated, .unauthenticated:
|
||||
case .authenticated, .unauthenticated, .notAppleDeveloper:
|
||||
self.presentedSheet = nil
|
||||
self.secondFactorData = nil
|
||||
case let .waitingForSecondFactor(option, authOptions, sessionData):
|
||||
|
|
@ -315,7 +316,7 @@ class AppState: ObservableObject {
|
|||
self.$authenticationState
|
||||
.filter { state in
|
||||
switch state {
|
||||
case .authenticated, .unauthenticated: return true
|
||||
case .authenticated, .unauthenticated, .notAppleDeveloper: return true
|
||||
case .waitingForSecondFactor: return false
|
||||
}
|
||||
}
|
||||
|
|
@ -324,6 +325,9 @@ class AppState: ObservableObject {
|
|||
if state == .unauthenticated {
|
||||
throw AuthenticationError.invalidSession
|
||||
}
|
||||
if state == .notAppleDeveloper {
|
||||
throw AuthenticationError.notDeveloperAppleId
|
||||
}
|
||||
return Void()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue