2018-08-19 20:14:04 +00:00
//
// O n b o a r d i n g V i e w C o n t r o l l e r . s w i f t
// T u s k e r
//
// C r e a t e d b y S h a d o w f a c t s o n 8 / 1 8 / 1 8 .
// C o p y r i g h t © 2 0 1 8 S h a d o w f a c t s . A l l r i g h t s r e s e r v e d .
//
import UIKit
import AuthenticationServices
protocol OnboardingViewControllerDelegate {
2020-01-08 02:29:15 +00:00
func didFinishOnboarding ( account : LocalData . UserAccountInfo )
2018-08-19 20:14:04 +00:00
}
2019-09-15 19:01:35 +00:00
class OnboardingViewController : UINavigationController {
2018-08-19 20:14:04 +00:00
2019-06-19 23:12:42 +00:00
static var blocks : [ NSRegularExpression ] = {
guard let path = Bundle . main . path ( forResource : " DomainBlocks " , ofType : " plist " ) ,
let array = NSArray ( contentsOfFile : path ) as ? [ String ] else { return [ ] }
return array . compactMap { try ? NSRegularExpression ( pattern : $0 , options : . caseInsensitive ) }
} ( )
2019-09-15 19:01:35 +00:00
var onboardingDelegate : OnboardingViewControllerDelegate ?
2018-08-19 20:14:04 +00:00
2019-09-15 19:01:35 +00:00
var instanceSelector = InstanceSelectorTableViewController ( )
2018-08-19 20:14:04 +00:00
var authenticationSession : ASWebAuthenticationSession ?
2018-10-20 16:03:18 +00:00
init ( ) {
2019-09-15 19:01:35 +00:00
super . init ( rootViewController : instanceSelector )
2018-10-20 16:03:18 +00:00
}
required init ? ( coder aDecoder : NSCoder ) {
fatalError ( " init(coder:) has not been implemented " )
}
2018-08-19 20:14:04 +00:00
override func viewDidLoad ( ) {
super . viewDidLoad ( )
2019-09-15 19:01:35 +00:00
instanceSelector . delegate = self
}
}
extension OnboardingViewController : InstanceSelectorTableViewControllerDelegate {
2020-01-08 02:29:15 +00:00
func didSelectInstance ( url instanceURL : URL ) {
let mastodonController = MastodonController ( instanceURL : instanceURL )
mastodonController . registerApp { ( clientID , clientSecret ) in
var components = URLComponents ( url : instanceURL , resolvingAgainstBaseURL : false ) !
2018-08-19 20:14:04 +00:00
components . path = " /oauth/authorize "
components . queryItems = [
URLQueryItem ( name : " client_id " , value : clientID ) ,
URLQueryItem ( name : " response_type " , value : " code " ) ,
URLQueryItem ( name : " scope " , value : " read write follow " ) ,
2020-06-23 23:32:30 +00:00
URLQueryItem ( name : " redirect_uri " , value : " tusker://oauth " )
2018-08-19 20:14:04 +00:00
]
2019-09-15 19:01:35 +00:00
let authorizeURL = components . url !
2018-08-19 20:14:04 +00:00
2020-06-23 23:32:30 +00:00
self . authenticationSession = ASWebAuthenticationSession ( url : authorizeURL , callbackURLScheme : " tusker " ) { url , error in
2018-08-20 21:23:35 +00:00
guard error = = nil ,
let url = url ,
let components = URLComponents ( url : url , resolvingAgainstBaseURL : true ) ,
let item = components . queryItems ? . first ( where : { $0 . name = = " code " } ) ,
2019-09-24 18:45:29 +00:00
let authCode = item . value else { return }
2018-08-20 21:23:35 +00:00
2020-01-08 02:29:15 +00:00
mastodonController . authorize ( authorizationCode : authCode ) { ( accessToken ) in
2020-05-10 18:41:07 +00:00
// c o n s t r u c t a t e m p o r a r y U s e r A c c o u n t I n f o i n s t a n c e f o r t h e M a s t o d o n C o n t r o l l e r t o u s e t o f e t c h i t ' s o w n a c c o u n t
let tempAccountInfo = LocalData . UserAccountInfo ( id : " temp " , instanceURL : instanceURL , clientID : clientID , clientSecret : clientSecret , username : nil , accessToken : accessToken )
mastodonController . accountInfo = tempAccountInfo
2020-04-12 15:14:10 +00:00
2020-09-16 21:52:00 +00:00
mastodonController . getOwnAccount { ( result ) in
2020-01-08 02:29:15 +00:00
DispatchQueue . main . async {
2020-09-16 21:52:00 +00:00
switch result {
case let . failure ( error ) :
let alert = UIAlertController ( title : " Unable to Verify Credentials " , message : " Your account could not be fetched at this time: \( error . localizedDescription ) " , preferredStyle : . alert )
alert . addAction ( UIAlertAction ( title : " Ok " , style : . default , handler : nil ) )
self . present ( alert , animated : true )
case let . success ( account ) :
// t h i s n e e d s t o h a p p e n o n t h e m a i n t h r e a d b e c a u s e i t p u b l i s h e s a n e w v a l u e f o r t h e O b s e r v a b l e O b j e c t
let accountInfo = LocalData . shared . addAccount ( instanceURL : instanceURL , clientID : clientID , clientSecret : clientSecret , username : account . username , accessToken : accessToken )
mastodonController . accountInfo = accountInfo
self . onboardingDelegate ? . didFinishOnboarding ( account : accountInfo )
}
2020-01-08 02:29:15 +00:00
}
2018-08-20 21:23:35 +00:00
}
}
2018-08-19 20:14:04 +00:00
}
2019-07-27 22:31:55 +00:00
DispatchQueue . main . async {
2020-06-24 01:35:14 +00:00
// P r e f e r e p h e m e r a l s e s s i o n s t o m a k e i t e a s i e r t o s i g n i n t o m u l t i p l e a c c o u n t s o n t h e s a m e i n s t a n c e .
self . authenticationSession ! . prefersEphemeralWebBrowserSession = true
2019-07-27 22:31:55 +00:00
self . authenticationSession ! . presentationContextProvider = self
self . authenticationSession ! . start ( )
}
2018-08-19 20:14:04 +00:00
}
}
}
2019-06-04 17:31:12 +00:00
extension OnboardingViewController : ASWebAuthenticationPresentationContextProviding {
func presentationAnchor ( for session : ASWebAuthenticationSession ) -> ASPresentationAnchor {
2019-06-11 17:21:22 +00:00
return view . window !
2019-06-04 17:31:12 +00:00
}
}