Login with email instead of username. Adding some code for Apple sign in
This commit is contained in:
parent
de6c6a7ac5
commit
f7bcaa96a2
@ -75,6 +75,7 @@
|
||||
7A7547DD2403180A004E8406 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DB2403180A004E8406 /* SectionHeader.swift */; };
|
||||
7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7A7547DC2403180A004E8406 /* SectionHeader.xib */; };
|
||||
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */; };
|
||||
7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A813DBD2506A57100CC93B9 /* AuthenticationServices.framework */; };
|
||||
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; };
|
||||
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */; };
|
||||
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = 7A96AE29246AFD6200297C33 /* Eureka */; };
|
||||
@ -157,6 +158,7 @@
|
||||
7A7547DB2403180A004E8406 /* SectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = "<group>"; };
|
||||
7A7547DC2403180A004E8406 /* SectionHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SectionHeader.xib; sourceTree = "<group>"; };
|
||||
7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehiclePhotoCell.swift; sourceTree = "<group>"; };
|
||||
7A813DBD2506A57100CC93B9 /* AuthenticationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthenticationServices.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/AuthenticationServices.framework; sourceTree = DEVELOPER_DIR; };
|
||||
7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResizeImage.swift; sourceTree = "<group>"; };
|
||||
7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleReportImage.swift; sourceTree = "<group>"; };
|
||||
7A92D0AB240425B100EF3B77 /* ATGMediaBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ATGMediaBrowser.framework; path = Carthage/Build/iOS/ATGMediaBrowser.framework; sourceTree = "<group>"; };
|
||||
@ -180,6 +182,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */,
|
||||
7AF58D342402A91C00CE01A0 /* Kingfisher in Frameworks */,
|
||||
7A0516162414EC1200FC55AC /* Differentiator in Frameworks */,
|
||||
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */,
|
||||
@ -305,6 +308,7 @@
|
||||
7A11474C23FFEE8700B424AF /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7A813DBD2506A57100CC93B9 /* AuthenticationServices.framework */,
|
||||
7A96AE2E246B2BCD00297C33 /* WebKit.framework */,
|
||||
7A92D0AB240425B100EF3B77 /* ATGMediaBrowser.framework */,
|
||||
7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */,
|
||||
@ -707,7 +711,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 25;
|
||||
CURRENT_PROJECT_VERSION = 26;
|
||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
@ -729,7 +733,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 25;
|
||||
CURRENT_PROJECT_VERSION = 26;
|
||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
|
||||
@ -2,6 +2,10 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.applesignin</key>
|
||||
<array>
|
||||
<string>Default</string>
|
||||
</array>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pme-aR-UNJ">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pme-aR-UNJ">
|
||||
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
@ -261,14 +261,14 @@
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="VEP-QD-i6y" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="28" width="375" height="85"/>
|
||||
<rect key="frame" x="0.0" y="28" width="375" height="85.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VEP-QD-i6y" id="8hH-8I-XLB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="85"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="85.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Kia (JF) Optima" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AQY-7N-q8D">
|
||||
<rect key="frame" x="8" y="8" width="124" height="21"/>
|
||||
<rect key="frame" x="8" y="8" width="124" height="21.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@ -280,7 +280,7 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cvf-vM-QnT" customClass="PlateView" customModule="AutoCat" customModuleProvider="target">
|
||||
<rect key="frame" x="8" y="37" width="317" height="40"/>
|
||||
<rect key="frame" x="8" y="37.5" width="317" height="40"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="Xoz-Iw-PCU"/>
|
||||
@ -716,13 +716,13 @@
|
||||
<stackView opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="1000" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="TMc-av-b0b">
|
||||
<rect key="frame" x="56.5" y="235.5" width="262.5" height="196"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Login" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Uey-88-eZL" customClass="CustomTextField" customModule="AutoCat" customModuleProvider="target">
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Email" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="Uey-88-eZL" customClass="CustomTextField" customModule="AutoCat" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="262.5" height="34"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="34" id="5fP-sM-e5U"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
<textInputTraits key="textInputTraits" keyboardType="emailAddress" textContentType="email"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
|
||||
<real key="value" value="1"/>
|
||||
@ -775,6 +775,19 @@
|
||||
<action selector="signupTapped:" destination="pme-aR-UNJ" eventType="touchUpInside" id="upt-yE-Xro"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="or" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SXb-1Q-TxY">
|
||||
<rect key="frame" x="0.0" y="196" width="262.5" height="0.0"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nId-Ov-fVe" customClass="ASAuthorizationAppleIDButton">
|
||||
<rect key="frame" x="0.0" y="196" width="262.5" height="0.0"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<connections>
|
||||
<action selector="appleSignInTapped:" destination="pme-aR-UNJ" eventType="touchUpInside" id="LrP-Rx-JeO"/>
|
||||
</connections>
|
||||
</view>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
@ -787,6 +800,7 @@
|
||||
<viewLayoutGuide key="safeArea" id="CSC-sQ-Tm5"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="appleSignIn" destination="nId-Ov-fVe" id="ifS-g1-O3I"/>
|
||||
<outlet property="login" destination="ltG-B1-UBj" id="Fc0-Cd-BKA"/>
|
||||
<outlet property="password" destination="G1p-Hz-8yn" id="8VI-cA-YrJ"/>
|
||||
<outlet property="signup" destination="hRD-Ha-MrP" id="VCG-25-bHL"/>
|
||||
|
||||
@ -2,19 +2,23 @@ import UIKit
|
||||
import RxSwift
|
||||
import RxCocoa
|
||||
import RealmSwift
|
||||
import AuthenticationServices
|
||||
|
||||
class AuthController: UIViewController {
|
||||
class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
||||
|
||||
@IBOutlet weak var username: UITextField!
|
||||
@IBOutlet weak var password: UITextField!
|
||||
@IBOutlet weak var login: UIButton!
|
||||
@IBOutlet weak var signup: UIButton!
|
||||
@IBOutlet weak var appleSignIn: ASAuthorizationAppleIDButton!
|
||||
|
||||
let bag = DisposeBag()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
self.appleSignIn.cornerRadius = 6
|
||||
|
||||
let authValid = Observable.combineLatest(self.username.rx.text, self.password.rx.text) { name, pass -> Bool in
|
||||
guard let name = name, let pass = pass else { return false }
|
||||
return name.count >= 4 && pass.count >= 5
|
||||
@ -23,44 +27,55 @@ class AuthController: UIViewController {
|
||||
authValid.bind(to: self.login.rx.isEnabled).disposed(by: self.bag)
|
||||
authValid.bind(to: self.signup.rx.isEnabled).disposed(by: self.bag)
|
||||
|
||||
if Settings.shared.user.login.count > 0 {
|
||||
self.username.text = Settings.shared.user.login
|
||||
if Settings.shared.user.email.count > 0 {
|
||||
self.username.text = Settings.shared.user.email
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func loginTapped(_ sender: UIButton) {
|
||||
guard let name = self.username.text, let pass = self.password.text else { return }
|
||||
guard let email = self.username.text, let pass = self.password.text else { return }
|
||||
|
||||
IHProgressHUD.show()
|
||||
Api.login(username: name, password: pass)
|
||||
Api.login(email: email, password: pass)
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:))
|
||||
.disposed(by: self.bag)
|
||||
}
|
||||
|
||||
@IBAction func signupTapped(_ sender: UIButton) {
|
||||
guard let name = self.username.text, let pass = self.password.text else { return }
|
||||
guard let email = self.username.text, let pass = self.password.text else { return }
|
||||
|
||||
IHProgressHUD.show()
|
||||
Api.signup(username: name, password: pass)
|
||||
Api.signUp(email: email, password: pass)
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:))
|
||||
.disposed(by: self.bag)
|
||||
}
|
||||
|
||||
func goToMainScreen(user: User) {
|
||||
guard let realm = try? Realm() else {
|
||||
IHProgressHUD.showError(withStatus: "Database error")
|
||||
return
|
||||
@IBAction func appleSignInTapped(_ sender: ASAuthorizationAppleIDButton) {
|
||||
let appleIDProvider = ASAuthorizationAppleIDProvider()
|
||||
let request = appleIDProvider.createRequest()
|
||||
request.requestedScopes = [.email]
|
||||
|
||||
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
|
||||
authorizationController.delegate = self
|
||||
authorizationController.presentationContextProvider = self
|
||||
authorizationController.performRequests()
|
||||
}
|
||||
|
||||
func goToMainScreen(user: User) {
|
||||
// guard let realm = try? Realm() else {
|
||||
// IHProgressHUD.showError(withStatus: "Database error")
|
||||
// return
|
||||
// }
|
||||
|
||||
IHProgressHUD.dismiss()
|
||||
|
||||
if user.login != Settings.shared.user.login {
|
||||
try? realm.write {
|
||||
realm.deleteAll()
|
||||
}
|
||||
}
|
||||
// if user.email != Settings.shared.user.email {
|
||||
// try? realm.write {
|
||||
// realm.deleteAll()
|
||||
// }
|
||||
// }
|
||||
|
||||
Settings.shared.user = user
|
||||
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||
@ -71,4 +86,38 @@ class AuthController: UIViewController {
|
||||
IHProgressHUD.showError(withStatus: error.localizedDescription)
|
||||
print(error)
|
||||
}
|
||||
|
||||
// MARK: - Apple SignIn
|
||||
|
||||
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
||||
return self.view.window!
|
||||
}
|
||||
|
||||
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
||||
switch authorization.credential {
|
||||
case let appleIDCredential as ASAuthorizationAppleIDCredential:
|
||||
guard let email = appleIDCredential.email else {
|
||||
IHProgressHUD.showError(withStatus: "Cannot get email")
|
||||
return
|
||||
}
|
||||
|
||||
IHProgressHUD.show()
|
||||
Api.signIn(email: email, password: appleIDCredential.user)
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:))
|
||||
.disposed(by: self.bag)
|
||||
|
||||
if let tokenData = appleIDCredential.identityToken {
|
||||
let token = String(data: tokenData, encoding: .utf8) ?? ""
|
||||
_ = Api.fbVerifyAssertion(provider: "apple.com", idToken: token).subscribe(onSuccess: { _ in
|
||||
print("")
|
||||
}, onError: { error in
|
||||
print(error)
|
||||
})
|
||||
}
|
||||
default:
|
||||
IHProgressHUD.showError(withStatus: "Unsupported authorization credential")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,9 +53,9 @@ class GoogleSignInController: UIViewController, WKNavigationDelegate {
|
||||
if let code = queryItems.first(where: { $0.name == "code" })?.value {
|
||||
decisionHandler(.cancel)
|
||||
self.getToken(code: code)
|
||||
.flatMap(fbVerifyAssertion)
|
||||
.flatMap { Api.fbVerifyAssertion(provider: "google.com", idToken: $0.id_token, accessToken: $0.access_token) }
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onNext: { _ in
|
||||
.subscribe(onSuccess: { _ in
|
||||
self.dismiss(animated: true, completion: self.completion)
|
||||
}, onError: { error in
|
||||
IHProgressHUD.showError(withStatus: error.localizedDescription)
|
||||
@ -85,7 +85,7 @@ class GoogleSignInController: UIViewController, WKNavigationDelegate {
|
||||
return String(data: Data(Base64FS.encode(data: hash)), encoding: .utf8)?.trimmingCharacters(in: CharacterSet(charactersIn: "="))
|
||||
}
|
||||
|
||||
func getToken(code: String) -> Observable<TokenResponse> {
|
||||
func getToken(code: String) -> Single<TokenResponse> {
|
||||
let tokenUrlString = Constants.googleTokenURL
|
||||
+ "?grant_type=authorization_code"
|
||||
+ "&code=" + code
|
||||
@ -96,54 +96,12 @@ class GoogleSignInController: UIViewController, WKNavigationDelegate {
|
||||
if let url = URL(string: tokenUrlString) {
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "POST"
|
||||
return URLSession.shared.rx.data(request: request).map { data in
|
||||
return URLSession.shared.rx.data(request: request).asSingle().map { data in
|
||||
return try JSONDecoder().decode(TokenResponse.self, from: data)
|
||||
}
|
||||
} else {
|
||||
let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Bad URL"])
|
||||
return Observable.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
public func fbVerifyAssertion(tokenResp: TokenResponse) -> Observable<Void> {
|
||||
let signupUrl = Constants.fbVerifyAssertion + "?key=" + (Constants.fbApiKey.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? Constants.fbApiKey)
|
||||
if let url = URL(string: signupUrl) {
|
||||
let innerBody = "providerId=google.com"
|
||||
+ "&id_token=" + tokenResp.id_token
|
||||
+ "&access_token=" + tokenResp.access_token
|
||||
|
||||
let body: [String:Any] = [
|
||||
"returnIdpCredential": true,
|
||||
"returnSecureToken": true,
|
||||
"autoCreate": true,
|
||||
"requestUri": "http://localhost",
|
||||
"postBody": innerBody
|
||||
]
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "POST"
|
||||
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
||||
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
request.addValue(Constants.fbClientVersion, forHTTPHeaderField: "X-Client-Version")
|
||||
request.addValue(Constants.vin01BUndleId, forHTTPHeaderField: "X-Ios-Bundle-Identifier")
|
||||
request.addValue(Constants.fbUserAgent, forHTTPHeaderField: "User-Agent")
|
||||
|
||||
return URLSession.shared.rx.json(request: request).map { response in
|
||||
guard let json = response as? [String: Any] else { return }
|
||||
if let newToken = json["idToken"] as? String {
|
||||
Settings.shared.user.googleIdToken = newToken
|
||||
print("Token: \(newToken)")
|
||||
}
|
||||
if let newRefreshToken = json["refreshToken"] as? String {
|
||||
Settings.shared.user.googleRefreshToken = newRefreshToken
|
||||
print("Refresh token: \(newRefreshToken)")
|
||||
}
|
||||
}.catchError { err in
|
||||
print(err)
|
||||
return .just(())
|
||||
}
|
||||
} else {
|
||||
return .just(())
|
||||
return Single.error(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import UIKit
|
||||
import Eureka
|
||||
import AuthenticationServices
|
||||
|
||||
class SettingsController: FormViewController {
|
||||
|
||||
@ -9,11 +10,11 @@ class SettingsController: FormViewController {
|
||||
form +++ Section("Profile")
|
||||
<<< LabelRow("AutoCatAccount") { row in
|
||||
row.title = "AutoCat Account"
|
||||
row.value = Settings.shared.user.login
|
||||
row.value = Settings.shared.user.email
|
||||
}
|
||||
<<< LabelRow("GoogleAccount") { row in
|
||||
row.title = "Google"
|
||||
if let jwtString = Settings.shared.user.googleIdToken, let jwt = JWT(string: jwtString) {
|
||||
if let jwtString = Settings.shared.user.firebaseIdToken, let jwt = JWT(string: jwtString) {
|
||||
row.value = jwt.payload.email
|
||||
} else {
|
||||
row.value = "Log In"
|
||||
@ -22,8 +23,8 @@ class SettingsController: FormViewController {
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
}
|
||||
}.onCellSelection { cell, row in
|
||||
if Settings.shared.user.googleIdToken != nil {
|
||||
self.displayLogoutSheet()
|
||||
if Settings.shared.user.firebaseIdToken != nil {
|
||||
self.displayLogoutSheet(for: "GoogleAccount")
|
||||
} else {
|
||||
self.loginToGoogle()
|
||||
}
|
||||
@ -90,18 +91,18 @@ class SettingsController: FormViewController {
|
||||
self.view.window?.rootViewController = storyboard.instantiateViewController(identifier: "AuthController")
|
||||
}
|
||||
|
||||
func displayLogoutSheet() {
|
||||
guard let jwtString = Settings.shared.user.googleIdToken, let jwt = JWT(string: jwtString) else { return }
|
||||
func displayLogoutSheet(for row: String) {
|
||||
guard let jwtString = Settings.shared.user.firebaseIdToken, let jwt = JWT(string: jwtString) else { return }
|
||||
|
||||
let sheet = UIAlertController(title: jwt.payload.name, message: "You are currently signed in with email \(jwt.payload.email). It will help to gather more data about vehicles.", preferredStyle: .actionSheet)
|
||||
|
||||
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in sheet.dismiss(animated: true, completion: nil) }
|
||||
let logout = UIAlertAction(title: "Sign Out", style: .destructive) { _ in
|
||||
Settings.shared.user.googleIdToken = nil
|
||||
Settings.shared.user.googleRefreshToken = nil
|
||||
if let googleRow = self.form.rowBy(tag: "GoogleAccount") as? LabelRow {
|
||||
googleRow.value = "Log In"
|
||||
googleRow.reload()
|
||||
Settings.shared.user.firebaseIdToken = nil
|
||||
Settings.shared.user.firebaseRefreshToken = nil
|
||||
if let row = self.form.rowBy(tag: row) as? LabelRow {
|
||||
row.value = "Log In"
|
||||
row.reload()
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,7 +116,7 @@ class SettingsController: FormViewController {
|
||||
if let vc = storyboard.instantiateViewController(identifier: "GoogleSignInController") as? GoogleSignInController {
|
||||
vc.completion = {
|
||||
guard let googleRow = self.form.rowBy(tag: "GoogleAccount") as? LabelRow else { return }
|
||||
if let jwtString = Settings.shared.user.googleIdToken, let jwt = JWT(string: jwtString) {
|
||||
if let jwtString = Settings.shared.user.firebaseIdToken, let jwt = JWT(string: jwtString) {
|
||||
googleRow.value = jwt.payload.email
|
||||
} else {
|
||||
googleRow.value = "Log In"
|
||||
@ -125,4 +126,8 @@ class SettingsController: FormViewController {
|
||||
self.present(vc, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
func loginToApple() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import Foundation
|
||||
|
||||
struct User: Codable {
|
||||
let login: String
|
||||
let email: String
|
||||
var token: String
|
||||
var googleIdToken: String?
|
||||
var googleRefreshToken: String?
|
||||
var firebaseIdToken: String?
|
||||
var firebaseRefreshToken: String?
|
||||
|
||||
init() {
|
||||
self.login = ""
|
||||
self.email = ""
|
||||
self.token = ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
import Foundation
|
||||
import RxSwift
|
||||
import RxCocoa
|
||||
|
||||
class Api {
|
||||
|
||||
// MARK: - Private wrappres
|
||||
|
||||
private static func genError(_ msg: String, suggestion: String, code: Int = 0) -> Error {
|
||||
return NSError(domain: "", code: code, userInfo: [NSLocalizedDescriptionKey: msg, NSLocalizedRecoverySuggestionErrorKey: suggestion])
|
||||
}
|
||||
@ -36,14 +40,14 @@ class Api {
|
||||
}
|
||||
|
||||
return URLSession.shared.rx.data(request: request).asSingle().map { data in
|
||||
// let str = String(data: data, encoding: .utf8)
|
||||
// print("================================")
|
||||
// if let string = str?.replacingOccurrences(of: "\\\"", with: "\"")
|
||||
// .replacingOccurrences(of: "\\'", with: "'")
|
||||
// .replacingOccurrences(of: "\\n", with: "") {
|
||||
// print(string)
|
||||
// }
|
||||
// print("================================")
|
||||
let str = String(data: data, encoding: .utf8)
|
||||
print("================================")
|
||||
if let string = str?.replacingOccurrences(of: "\\\"", with: "\"")
|
||||
.replacingOccurrences(of: "\\'", with: "'")
|
||||
.replacingOccurrences(of: "\\n", with: "") {
|
||||
print(string)
|
||||
}
|
||||
print("================================")
|
||||
let resp = try JSONDecoder().decode(Response<T>.self, from: data)
|
||||
if resp.success {
|
||||
return resp.data!
|
||||
@ -73,8 +77,10 @@ class Api {
|
||||
return self.makeRequest(api: api, method: method, body: body, params: nil as [String:Int]?)
|
||||
}
|
||||
|
||||
// MARK: - Firebase API
|
||||
|
||||
public static func refreshFbToken() -> Single<Void> {
|
||||
guard let token = Settings.shared.user.googleIdToken, let refreshToken = Settings.shared.user.googleRefreshToken, let jwt = JWT(string: token), jwt.expired else {
|
||||
guard let token = Settings.shared.user.firebaseIdToken, let refreshToken = Settings.shared.user.firebaseRefreshToken, let jwt = JWT(string: token), jwt.expired else {
|
||||
return .just(())
|
||||
}
|
||||
|
||||
@ -91,16 +97,16 @@ class Api {
|
||||
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
||||
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
request.addValue(Constants.fbClientVersion, forHTTPHeaderField: "X-Client-Version")
|
||||
request.addValue(Constants.vin01BUndleId, forHTTPHeaderField: "X-Ios-Bundle-Identifier")
|
||||
request.addValue(Constants.secondProviderBundleId, forHTTPHeaderField: "X-Ios-Bundle-Identifier")
|
||||
request.addValue(Constants.fbUserAgent, forHTTPHeaderField: "User-Agent")
|
||||
return URLSession.shared.rx.json(request: request).asSingle().map { resp in
|
||||
guard let json = resp as? [String: Any] else { return }
|
||||
if let newToken = json["id_token"] as? String {
|
||||
Settings.shared.user.googleIdToken = newToken
|
||||
Settings.shared.user.firebaseIdToken = newToken
|
||||
print("Token was successfully refresh to: \(newToken)")
|
||||
}
|
||||
if let newRefreshToken = json["refresh_token"] as? String {
|
||||
Settings.shared.user.googleRefreshToken = newRefreshToken
|
||||
Settings.shared.user.firebaseRefreshToken = newRefreshToken
|
||||
}
|
||||
}.catchError { error in
|
||||
print(error)
|
||||
@ -111,17 +117,72 @@ class Api {
|
||||
}
|
||||
}
|
||||
|
||||
public static func login(username: String, password: String) -> Single<User> {
|
||||
public static func fbVerifyAssertion(provider: String, idToken: String, accessToken: String? = nil) -> Single<Void> {
|
||||
let signupUrl = Constants.fbVerifyAssertion + "?key=" + (Constants.fbApiKey.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? Constants.fbApiKey)
|
||||
if let url = URL(string: signupUrl) {
|
||||
var innerBody = "providerId=" + provider
|
||||
+ "&id_token=" + idToken
|
||||
|
||||
if let accessToken = accessToken {
|
||||
innerBody += "&access_token=" + accessToken
|
||||
}
|
||||
|
||||
let body: [String:Any] = [
|
||||
"returnIdpCredential": true,
|
||||
"returnSecureToken": true,
|
||||
"autoCreate": true,
|
||||
"requestUri": "http://localhost",
|
||||
"postBody": innerBody
|
||||
]
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "POST"
|
||||
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
||||
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
request.addValue(Constants.fbClientVersion, forHTTPHeaderField: "X-Client-Version")
|
||||
request.addValue(Constants.secondProviderBundleId, forHTTPHeaderField: "X-Ios-Bundle-Identifier")
|
||||
request.addValue(Constants.fbUserAgent, forHTTPHeaderField: "User-Agent")
|
||||
|
||||
return URLSession.shared.rx.json(request: request).asSingle().map { response in
|
||||
guard let json = response as? [String: Any] else { return }
|
||||
if let newToken = json["idToken"] as? String {
|
||||
Settings.shared.user.firebaseIdToken = newToken
|
||||
print("Token: \(newToken)")
|
||||
}
|
||||
if let newRefreshToken = json["refreshToken"] as? String {
|
||||
Settings.shared.user.firebaseRefreshToken = newRefreshToken
|
||||
print("Refresh token: \(newRefreshToken)")
|
||||
}
|
||||
}.catchError { err in
|
||||
print(err)
|
||||
return .just(())
|
||||
}
|
||||
} else {
|
||||
return .just(())
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - AutoCat public API
|
||||
|
||||
public static func login(email: String, password: String) -> Single<User> {
|
||||
let body = [
|
||||
"login": username,
|
||||
"email": email,
|
||||
"password": password
|
||||
]
|
||||
return self.makeBodyRequest(api: "user/login", body: body)
|
||||
}
|
||||
|
||||
public static func signup(username: String, password: String) -> Single<User> {
|
||||
public static func signIn(email: String, password: String) -> Single<User> {
|
||||
let body = [
|
||||
"login": username,
|
||||
"email": email,
|
||||
"password": password
|
||||
]
|
||||
return self.makeBodyRequest(api: "user/signIn", body: body)
|
||||
}
|
||||
|
||||
public static func signUp(email: String, password: String) -> Single<User> {
|
||||
let body = [
|
||||
"email": email,
|
||||
"password": password
|
||||
]
|
||||
return self.makeBodyRequest(api: "user/signup", body: body)
|
||||
@ -137,7 +198,7 @@ class Api {
|
||||
"number": number,
|
||||
"forceUpdate": String(force)
|
||||
]
|
||||
if let token = Settings.shared.user.googleIdToken {
|
||||
if let token = Settings.shared.user.firebaseIdToken {
|
||||
body["googleIdToken"] = token
|
||||
}
|
||||
return self.makeBodyRequest(api: "vehicles/check", body: body).map { (vehicle: Vehicle) -> Vehicle in
|
||||
|
||||
@ -23,7 +23,7 @@ enum Constants {
|
||||
static let fbRefreshToken = "https://securetoken.googleapis.com/v1/token"
|
||||
static let fbUserAgent = "FirebaseAuth.iOS/6.5.1 ru.Vin01/1.0 iPhone/13.5 hw/sim"
|
||||
|
||||
static let vin01BUndleId = "ru.Vin01"
|
||||
static let secondProviderBundleId = "ru.Vin01"
|
||||
|
||||
static let reportLinkTokenSecret = "#TheTruthIsOutThere"
|
||||
static let reportLinkBaseURL = "https://auto.aliencat.pro/report.html"
|
||||
|
||||
@ -87,6 +87,9 @@ class Recorder {
|
||||
}
|
||||
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
|
||||
try AVAudioSession.sharedInstance().setActive(true)
|
||||
|
||||
let inFormat = self.engine.inputNode.outputFormat(forBus: 0)
|
||||
ExtAudioFileSetProperty(fileRef, kExtAudioFileProperty_ClientDataFormat, UInt32(MemoryLayout<AudioStreamBasicDescription>.size), inFormat.streamDescription)
|
||||
|
||||
@ -113,9 +116,6 @@ class Recorder {
|
||||
|
||||
self.engine.prepare()
|
||||
try self.engine.start()
|
||||
|
||||
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
|
||||
try AVAudioSession.sharedInstance().setActive(true)
|
||||
} catch {
|
||||
observer(.error(error))
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user