diff --git a/Lock.xcodeproj/project.pbxproj b/Lock.xcodeproj/project.pbxproj index 6b091eaab..d13b3bbb6 100644 --- a/Lock.xcodeproj/project.pbxproj +++ b/Lock.xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ 5B0971801DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B09717F1DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift */; }; 5B0971821DC8FAC5003AA88F /* EnterpriseDomainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0971811DC8FAC5003AA88F /* EnterpriseDomainView.swift */; }; 5BA563F11DD117550002D3AB /* EnterpriseDomainInteractorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA563EF1DD1171F0002D3AB /* EnterpriseDomainInteractorSpec.swift */; }; - 5BC6BC0C1DCBDDC9002EA81C /* EnterpriseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC6BC0B1DCBDDC9002EA81C /* EnterpriseView.swift */; }; 5BCED4C71DD1FEAA00E2CE8A /* EnterpriseDomainPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BCED4C51DD1FCF200E2CE8A /* EnterpriseDomainPresenterSpec.swift */; }; 5F14565A1D5130E80085DF9C /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F1456591D5130E80085DF9C /* Colors.swift */; }; 5F14565B1D5237180085DF9C /* LazyImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F92C68E1D50EAC200CCE6C0 /* LazyImage.swift */; }; @@ -203,7 +202,6 @@ 5B09717F1DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseDomainPresenter.swift; path = Lock/EnterpriseDomainPresenter.swift; sourceTree = SOURCE_ROOT; }; 5B0971811DC8FAC5003AA88F /* EnterpriseDomainView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseDomainView.swift; path = Lock/EnterpriseDomainView.swift; sourceTree = SOURCE_ROOT; }; 5BA563EF1DD1171F0002D3AB /* EnterpriseDomainInteractorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseDomainInteractorSpec.swift; sourceTree = ""; }; - 5BC6BC0B1DCBDDC9002EA81C /* EnterpriseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseView.swift; path = Lock/EnterpriseView.swift; sourceTree = SOURCE_ROOT; }; 5BCED4C51DD1FCF200E2CE8A /* EnterpriseDomainPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseDomainPresenterSpec.swift; sourceTree = ""; }; 5F1456591D5130E80085DF9C /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Colors.swift; path = Lock/Colors.swift; sourceTree = SOURCE_ROOT; }; 5F14565D1D5237820085DF9C /* DatabaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DatabaseView.swift; path = Lock/DatabaseView.swift; sourceTree = SOURCE_ROOT; }; @@ -633,7 +631,6 @@ 5F99AA931D1BABFC00D27842 /* SecondaryButton.swift */, 5F51EE671D1C88FC0024BCD6 /* SignUpView.swift */, 5F51EE691D1CBC830024BCD6 /* SingleInputView.swift */, - 5BC6BC0B1DCBDDC9002EA81C /* EnterpriseView.swift */, 5FD6772B1D4C303C004B87C4 /* AuthButton.swift */, ); path = Components; @@ -949,7 +946,6 @@ 5B0971821DC8FAC5003AA88F /* EnterpriseDomainView.swift in Sources */, 5FBE5CC61D3E7F9D0038536D /* MultifactorPresenter.swift in Sources */, 5FEAE2101D1A5691005C0028 /* HeaderView.swift in Sources */, - 5BC6BC0C1DCBDDC9002EA81C /* EnterpriseView.swift in Sources */, 5F99AA8C1D1B3F1300D27842 /* InputField.swift in Sources */, 5FBE5CBA1D3E59B90038536D /* MultifactorCodeView.swift in Sources */, 5F1C49901D8360BF005B74FC /* ConnectionLoadingPresenter.swift in Sources */, diff --git a/Lock/EnterpriseDomainPresenter.swift b/Lock/EnterpriseDomainPresenter.swift index ca819dcbf..11b8a506b 100644 --- a/Lock/EnterpriseDomainPresenter.swift +++ b/Lock/EnterpriseDomainPresenter.swift @@ -26,6 +26,9 @@ class EnterpriseDomainPresenter: Presentable, Loggable { var interactor: EnterpriseDomainInteractor var customLogger: Logger? + + // Social connections + var authPresenter: AuthPresenter? init(interactor: EnterpriseDomainInteractor) { self.interactor = interactor @@ -35,7 +38,8 @@ class EnterpriseDomainPresenter: Presentable, Loggable { var view: View { let email = self.interactor.validEmail ? self.interactor.email : nil - let view = EnterpriseDomainView(email: email) + let authCollectionView = self.authPresenter?.newViewToEmbed(withInsets: UIEdgeInsetsMake(0, 0, 0, 0), isLogin: true) + let view = EnterpriseDomainView(email: email, authCollectionView: authCollectionView) let form = view.form view.form?.onValueChange = { input in self.messagePresenter?.hideCurrent() @@ -78,4 +82,5 @@ class EnterpriseDomainPresenter: Presentable, Loggable { } return view } + } diff --git a/Lock/EnterpriseDomainView.swift b/Lock/EnterpriseDomainView.swift index e9b7d3c5b..5969544ef 100644 --- a/Lock/EnterpriseDomainView.swift +++ b/Lock/EnterpriseDomainView.swift @@ -23,51 +23,84 @@ import UIKit class EnterpriseDomainView: UIView, View { - + weak var form: Form? weak var primaryButton: PrimaryButton? - - init(email: String?) { + weak var authCollectionView: AuthCollectionView? + + private weak var container: UIStackView? + + init(email: String?, authCollectionView: AuthCollectionView? = nil) { let primaryButton = PrimaryButton() - let domainView = EnterpriseView() - let center = UILayoutGuide() - + let domainView = EnterpriseSingleInputView() + let container = UIStackView() + self.primaryButton = primaryButton self.form = domainView - + self.container = container + super.init(frame: CGRectZero) - - self.addSubview(domainView) + + self.addSubview(container) self.addSubview(primaryButton) - self.addLayoutGuide(center) - - constraintEqual(anchor: center.leftAnchor, toAnchor: self.leftAnchor, constant: 20) - constraintEqual(anchor: center.topAnchor, toAnchor: self.topAnchor) - constraintEqual(anchor: center.rightAnchor, toAnchor: self.rightAnchor, constant: -20) - constraintEqual(anchor: center.bottomAnchor, toAnchor: primaryButton.topAnchor) - - constraintEqual(anchor: domainView.leftAnchor, toAnchor: center.leftAnchor) - constraintEqual(anchor: domainView.rightAnchor, toAnchor: center.rightAnchor) - constraintEqual(anchor: domainView.centerYAnchor, toAnchor: center.centerYAnchor) - constraintGreaterOrEqual(anchor: domainView.topAnchor, toAnchor: center.topAnchor, constant: 10, priority: UILayoutPriorityDefaultLow - 1) - constraintGreaterOrEqual(anchor: domainView.bottomAnchor, toAnchor: center.bottomAnchor, constant: -10, priority: UILayoutPriorityDefaultLow - 1) - domainView.translatesAutoresizingMaskIntoConstraints = false - + + container.alignment = .Fill + container.axis = .Vertical + container.distribution = .EqualSpacing + container.spacing = 5 + + container.addArrangedSubview(strutView()) + if let authCollectionView = authCollectionView { + self.authCollectionView = authCollectionView + container.addArrangedSubview(authCollectionView) + let label = UILabel() + label.text = "or".i18n(key: "com.auth0.lock.database.separator", comment: "Social separator") + label.font = mediumSystemFont(size: 13.75) + label.textColor = UIColor ( red: 0.0, green: 0.0, blue: 0.0, alpha: 0.54 ) + label.textAlignment = .Center + container.addArrangedSubview(label) + } + container.addArrangedSubview(domainView) + container.addArrangedSubview(strutView()) + + constraintEqual(anchor: container.topAnchor, toAnchor: self.topAnchor) + constraintEqual(anchor: container.leftAnchor, toAnchor: self.leftAnchor, constant: 20) + constraintEqual(anchor: container.rightAnchor, toAnchor: self.rightAnchor, constant: -20) + constraintEqual(anchor: container.bottomAnchor, toAnchor: primaryButton.topAnchor) + container.translatesAutoresizingMaskIntoConstraints = false + constraintEqual(anchor: primaryButton.leftAnchor, toAnchor: self.leftAnchor) constraintEqual(anchor: primaryButton.rightAnchor, toAnchor: self.rightAnchor) constraintEqual(anchor: primaryButton.bottomAnchor, toAnchor: self.bottomAnchor) primaryButton.translatesAutoresizingMaskIntoConstraints = false - + + domainView.type = .Email domainView.returnKey = .Done domainView.value = email + } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + func apply(style style: Style) { self.primaryButton?.apply(style: style) } + +} + +private func strutView(withHeight height: CGFloat = 50) -> UIView { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + dimension(view.heightAnchor, withValue: height) + return view +} + +public class EnterpriseSingleInputView : SingleInputView { + + public override func intrinsicContentSize() -> CGSize { + return CGSize(width: UIViewNoIntrinsicMetric, height: 50) + } } diff --git a/Lock/EnterpriseView.swift b/Lock/EnterpriseView.swift deleted file mode 100644 index 7cfc59bf4..000000000 --- a/Lock/EnterpriseView.swift +++ /dev/null @@ -1,108 +0,0 @@ -// EnterpriseView.swift -// -// Copyright (c) 2016 Auth0 (http://auth0.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import UIKit - -public class EnterpriseView: UIView, Form { - private var inputField: InputField - private var stackView: UIStackView - - var value: String? { - get { - return self.inputField.text - } - set { - self.inputField.text = newValue - } - } - - var type: InputField.InputType = .Email { - didSet { - self.inputField.type = self.type - } - } - - var returnKey: UIReturnKeyType = .Done { - didSet { - self.inputField.returnKey = self.returnKey - } - } - - var onValueChange: (InputField) -> () = { _ in } { - didSet { - self.inputField.onTextChange = self.onValueChange - } - } - - var onReturn: (InputField) -> () { - get { - return self.inputField.onReturn - } - set { - self.inputField.onReturn = newValue - } - } - - func needsToUpdateState() { - self.inputField.needsToUpdateState() - } - - // MARK:- Initialisers - - required override public init(frame: CGRect) { - self.inputField = InputField() - self.stackView = UIStackView(arrangedSubviews: [inputField]) - super.init(frame: frame) - self.layoutForm() - } - - public convenience init() { - self.init(frame: CGRectZero) - } - - public required convenience init?(coder aDecoder: NSCoder) { - self.init(frame: CGRectZero) - } - - // MARK:- Layout - - private func layoutForm() { - self.addSubview(self.stackView) - - constraintEqual(anchor: self.stackView.leftAnchor, toAnchor: self.leftAnchor) - constraintEqual(anchor: self.stackView.topAnchor, toAnchor: self.topAnchor) - constraintEqual(anchor: self.stackView.rightAnchor, toAnchor: self.rightAnchor) - constraintEqual(anchor: self.stackView.bottomAnchor, toAnchor: self.bottomAnchor) - self.stackView.translatesAutoresizingMaskIntoConstraints = false - - self.stackView.alignment = .Fill - self.stackView.axis = .Vertical - self.stackView.distribution = .EqualCentering - - inputField.type = self.type - inputField.returnKey = self.returnKey - } - - public override func intrinsicContentSize() -> CGSize { - return CGSize(width: UIViewNoIntrinsicMetric, height: 244) - } -} diff --git a/Lock/Router.swift b/Lock/Router.swift index ceb765f9a..2b8914b73 100644 --- a/Lock/Router.swift +++ b/Lock/Router.swift @@ -96,6 +96,10 @@ struct Router: Navigable { let authInteractor = Auth0OAuth2Interactor(webAuth: self.lock.webAuth, onCredentials: self.onAuthentication, options: self.lock.options) let interactor = EnterpriseDomainInteractor(connections: connections.enterprise, authentication: authInteractor) let presenter = EnterpriseDomainPresenter(interactor: interactor) + if !connections.oauth2.isEmpty { + let interactor = Auth0OAuth2Interactor(webAuth: self.lock.webAuth, onCredentials: self.onAuthentication, options: self.lock.options) + presenter.authPresenter = AuthPresenter(connections: connections, interactor: interactor, customStyle: self.lock.style.oauth2) + } return presenter } if !connections.oauth2.isEmpty { diff --git a/LockTests/Presenters/EnterpriseDomainPresenterSpec.swift b/LockTests/Presenters/EnterpriseDomainPresenterSpec.swift index c78f2371e..8b70686ec 100644 --- a/LockTests/Presenters/EnterpriseDomainPresenterSpec.swift +++ b/LockTests/Presenters/EnterpriseDomainPresenterSpec.swift @@ -35,10 +35,13 @@ class EnterpriseDomainPresenterSpec: QuickSpec { var messagePresenter: MockMessagePresenter! var connections: OfflineConnections! var oauth2: MockOAuth2! + var authPresenter: MockAuthPresenter! beforeEach { messagePresenter = MockMessagePresenter() oauth2 = MockOAuth2() + authPresenter = MockAuthPresenter(connections: OfflineConnections(), interactor: MockAuthInteractor(), customStyle: [:]) + connections = OfflineConnections() connections.enterprise(name: "testAD", domains: ["test.com"]) @@ -57,7 +60,7 @@ class EnterpriseDomainPresenterSpec: QuickSpec { interactor.validEmail = true presenter = EnterpriseDomainPresenter(interactor: interactor) - let view = (presenter.view as! EnterpriseDomainView).form as! EnterpriseView + let view = (presenter.view as! EnterpriseDomainView).form as! EnterpriseSingleInputView expect(view.value).to(equal(email)) } @@ -66,7 +69,7 @@ class EnterpriseDomainPresenterSpec: QuickSpec { interactor.validEmail = false presenter = EnterpriseDomainPresenter(interactor: interactor) - let view = (presenter.view as! EnterpriseDomainView).form as! EnterpriseView + let view = (presenter.view as! EnterpriseDomainView).form as! EnterpriseSingleInputView expect(view.value).toNot(equal(email)) } } @@ -155,6 +158,22 @@ class EnterpriseDomainPresenterSpec: QuickSpec { } + + describe("auth buttons") { + + it("should init view with social view") { + presenter.authPresenter = authPresenter + let view = presenter.view as? EnterpriseDomainView + expect(view?.authCollectionView).to(equal(authPresenter.authView)) + } + + it("should init view with not social view") { + presenter.authPresenter = nil + let view = presenter.view as? EnterpriseDomainView + expect(view?.authCollectionView).to(beNil()) + } + + } } }