Skip to content

Commit

Permalink
Feature to disable log in after sign up
Browse files Browse the repository at this point in the history
Generic notification presenter added
Tests added
  • Loading branch information
cocojoe committed Dec 29, 2016
1 parent cf0df71 commit 69d034e
Show file tree
Hide file tree
Showing 16 changed files with 404 additions and 178 deletions.
12 changes: 12 additions & 0 deletions Lock.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
objects = {

/* Begin PBXBuildFile section */
5B011CDE1E13E16500543F12 /* NotificationStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B011CDD1E13E16500543F12 /* NotificationStatus.swift */; };
5B011CE01E13E3DB00543F12 /* NotificationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B011CDF1E13E3DB00543F12 /* NotificationPresenter.swift */; };
5B011CE21E13F2EF00543F12 /* NotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B011CE11E13F2EF00543F12 /* NotificationView.swift */; };
5B09717C1DC8F229003AA88F /* EnterpriseDomain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B09717B1DC8F229003AA88F /* EnterpriseDomain.swift */; };
5B09717E1DC8F292003AA88F /* EnterpriseActiveAuthInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B09717D1DC8F292003AA88F /* EnterpriseActiveAuthInteractor.swift */; };
5B0971801DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B09717F1DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift */; };
Expand Down Expand Up @@ -190,6 +193,9 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
5B011CDD1E13E16500543F12 /* NotificationStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationStatus.swift; sourceTree = "<group>"; };
5B011CDF1E13E3DB00543F12 /* NotificationPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationPresenter.swift; sourceTree = "<group>"; };
5B011CE11E13F2EF00543F12 /* NotificationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationView.swift; sourceTree = "<group>"; };
5B09717B1DC8F229003AA88F /* EnterpriseDomain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseDomain.swift; path = Lock/EnterpriseDomain.swift; sourceTree = SOURCE_ROOT; };
5B09717D1DC8F292003AA88F /* EnterpriseActiveAuthInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseActiveAuthInteractor.swift; path = Lock/EnterpriseActiveAuthInteractor.swift; sourceTree = SOURCE_ROOT; };
5B09717F1DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseDomainPresenter.swift; path = Lock/EnterpriseDomainPresenter.swift; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -437,6 +443,7 @@
children = (
5BB4A7C01DF9A38E008E8C37 /* DatabaseView.swift */,
5F1C49921D8360DF005B74FC /* LoadingView.swift */,
5B011CE11E13F2EF00543F12 /* NotificationView.swift */,
5F73CDD31D3073BE00D8D8D1 /* DatabaseForgotPasswordView.swift */,
5B0971811DC8FAC5003AA88F /* EnterpriseDomainView.swift */,
5B4DE0181DD670F7004C8AC2 /* EnterpriseActiveAuthView.swift */,
Expand Down Expand Up @@ -536,6 +543,7 @@
children = (
5FEEE8161DB6AC6C00B4DFED /* PasswordPolicy */,
5F2496B71D665AC500A1C6E2 /* UserAttribute.swift */,
5B011CDD1E13E16500543F12 /* NotificationStatus.swift */,
5FBE5CB71D3D8F030038536D /* User.swift */,
5F57DFC51D4F79DD00C54DA8 /* AuthStyle.swift */,
5F1C498D1D8360AA005B74FC /* Style.swift */,
Expand Down Expand Up @@ -564,6 +572,7 @@
5F1C498F1D8360BF005B74FC /* ConnectionLoadingPresenter.swift */,
5B09717F1DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift */,
5F73CDD51D30790500D8D8D1 /* DatabaseForgotPasswordPresenter.swift */,
5B011CDF1E13E3DB00543F12 /* NotificationPresenter.swift */,
5B4DE0161DD67064004C8AC2 /* EnterpriseActiveAuthPresenter.swift */,
5FC434891D1DF82A005188BC /* DatabasePresenter.swift */,
5F73CDCF1D30250900D8D8D1 /* MessagePresenter.swift */,
Expand Down Expand Up @@ -939,6 +948,7 @@
5F2496B31D665A5600A1C6E2 /* DatabaseUserCreator.swift in Sources */,
5F1C499B1D836190005B74FC /* CustomTextField.swift in Sources */,
5BB4A7C11DF9A38E008E8C37 /* DatabaseView.swift in Sources */,
5B011CE01E13E3DB00543F12 /* NotificationPresenter.swift in Sources */,
5F70F1E71D790773004698DA /* OptionBuildable.swift in Sources */,
5FBE5CB81D3D8F030038536D /* User.swift in Sources */,
5F99AA861D1B0BF100D27842 /* Resources.swift in Sources */,
Expand All @@ -953,6 +963,7 @@
5FC4348C1D1DFC5A005188BC /* Form.swift in Sources */,
5F73CDD01D30250900D8D8D1 /* MessagePresenter.swift in Sources */,
5F70F1E51D790735004698DA /* Options.swift in Sources */,
5B011CE21E13F2EF00543F12 /* NotificationView.swift in Sources */,
5FDB41D01D2C95B100166B67 /* MessageView.swift in Sources */,
5F2496B61D665AA800A1C6E2 /* InputValidationError.swift in Sources */,
5FFC54FE1D37E3F700579581 /* Routes.swift in Sources */,
Expand Down Expand Up @@ -999,6 +1010,7 @@
5F73CDD41D3073BE00D8D8D1 /* DatabaseForgotPasswordView.swift in Sources */,
5F99AA961D1C4AF400D27842 /* CredentialView.swift in Sources */,
5F1C498E1D8360AA005B74FC /* Style.swift in Sources */,
5B011CDE1E13E16500543F12 /* NotificationStatus.swift in Sources */,
5F73CDDA1D30957900D8D8D1 /* DatabasePasswordInteractor.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
1 change: 1 addition & 0 deletions Lock/DatabaseAuthenticatableError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum DatabaseAuthenticatableError: Error, LocalizableError {
case tooManyAttempts
case multifactorRequired
case multifactorInvalid
case noLoginAfterSignup

var localizableMessage: String {
switch self {
Expand Down
6 changes: 5 additions & 1 deletion Lock/DatabaseInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,11 @@ struct DatabaseInteractor: DatabaseAuthenticatable, DatabaseUserCreator, Loggabl
.start {
switch $0 {
case .success:
login.start { self.handle(result: $0, callback: { callback(nil, $0) }) }
if self.options.loginAfterSignup {
login.start { self.handle(result: $0, callback: { callback(nil, $0) }) }
} else {
callback(nil,.noLoginAfterSignup)
}
case .failure(let cause as AuthenticationError) where cause.isPasswordNotStrongEnough:
callback(.passwordTooWeak, nil)
case .failure(let cause as AuthenticationError) where cause.isPasswordAlreadyUsed:
Expand Down
6 changes: 4 additions & 2 deletions Lock/DatabasePresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ class DatabasePresenter: Presentable, Loggable {
interactor.create { createError, loginError in
Queue.main.async {
button.inProgress = false

guard createError != nil || loginError != nil else {
self.logger.debug("Logged in!")
return
Expand All @@ -169,7 +168,10 @@ class DatabasePresenter: Presentable, Loggable {
self.navigator.navigate(.multifactor)
return
}

if let error = loginError, case .noLoginAfterSignup = error {
self.navigator.navigate(.notification(status: .signedup))
return
}
let error: LocalizableError = createError ?? loginError!
form?.needsToUpdateState()
self.messagePresenter?.showError(error)
Expand Down
15 changes: 15 additions & 0 deletions Lock/Lock.xcassets/ic_email_sent.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_email_sent.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"template-rendering-intent" : "original"
}
}
Binary file not shown.
1 change: 1 addition & 0 deletions Lock/LockOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct LockOptions: OptionBuildable {
var initialScreen: DatabaseScreen = .login
var usernameStyle: DatabaseIdentifierStyle = [.Username, .Email]
var customSignupFields: [CustomTextField] = []
var loginAfterSignup: Bool = true

// Enterprise
var activeDirectoryEmailAsUsername: Bool = false
Expand Down
39 changes: 39 additions & 0 deletions Lock/NotificationPresenter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// NotificationPresenter.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 Foundation

class NotificationPresenter: Presentable, Loggable {

var customLogger: Logger?
var status: NotificationStatus
var messagePresenter: MessagePresenter?

init(status: NotificationStatus) {
self.status = status
}

var view: View {
let view = NotificationView(withStatus: self.status)
return view
}
}
27 changes: 27 additions & 0 deletions Lock/NotificationStatus.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// NotificationStatus.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 Foundation

enum NotificationStatus {
case signedup
}
69 changes: 69 additions & 0 deletions Lock/NotificationView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// NotificationView.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

class NotificationView: UIView, View {

init(withStatus status: NotificationStatus) {
super.init(frame: CGRect.zero)

let center = UILayoutGuide()
let imageView = UIImageView()
let messageLabel = UILabel()

self.addSubview(imageView)
self.addSubview(messageLabel)
self.addLayoutGuide(center)

constraintEqual(anchor: center.leftAnchor, toAnchor: self.leftAnchor)
constraintEqual(anchor: center.topAnchor, toAnchor: self.topAnchor)
constraintEqual(anchor: center.rightAnchor, toAnchor: self.rightAnchor)
constraintEqual(anchor: center.bottomAnchor, toAnchor: self.bottomAnchor)

constraintEqual(anchor: imageView.centerYAnchor, toAnchor: center.centerYAnchor, constant: -20)
constraintEqual(anchor: imageView.centerXAnchor, toAnchor: center.centerXAnchor)
imageView.translatesAutoresizingMaskIntoConstraints = false

constraintEqual(anchor: imageView.bottomAnchor, toAnchor: messageLabel.topAnchor, constant: -20)
constraintEqual(anchor: center.centerXAnchor, toAnchor: messageLabel.centerXAnchor)
messageLabel.translatesAutoresizingMaskIntoConstraints = false

messageLabel.numberOfLines = 0
messageLabel.textAlignment = .center
messageLabel.font = regularSystemFont(size: 15)

switch(status) {
case .signedup:
messageLabel.text = "Thanks for signing up.".i18n(key: "com.auth0.lock.notification.signup", comment: "Signed Up")
imageView.image = LazyImage(name: "ic_email_sent", bundle: bundleForLock()).image()
}

}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func apply(style: Style) {
}
}
3 changes: 3 additions & 0 deletions Lock/OptionBuildable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ public protocol OptionBuildable: Options {
/// Additional fields showed for Database Sign Up. By default the list is empty
var customSignupFields: [CustomTextField] { get set }

/// Automatically log user in after sign up. By default true
var loginAfterSignup: Bool { get set }

/// Should enterprise credential auth require email instead of username. By default is false
var activeDirectoryEmailAsUsername: Bool { get set }

Expand Down
1 change: 1 addition & 0 deletions Lock/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public protocol Options {
var initialScreen: DatabaseScreen { get }
var usernameStyle: DatabaseIdentifierStyle { get }
var customSignupFields: [CustomTextField] { get }
var loginAfterSignup: Bool { get }

// Enterprise
var activeDirectoryEmailAsUsername: Bool { get }
Expand Down
8 changes: 8 additions & 0 deletions Lock/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ class Router: Navigable {
return presenter
}

func notification(_ status: NotificationStatus) -> Presentable? {
let presenter = NotificationPresenter(status: status)
presenter.customLogger = self.lock.logger
return presenter
}

var showBack: Bool {
guard let routes = self.controller?.routes else { return false }
return !routes.history.isEmpty
Expand Down Expand Up @@ -187,6 +193,8 @@ class Router: Navigable {
presentable = self.multifactor
case .enterpriseActiveAuth(let connection):
presentable = self.EnterpriseActiveAuth(connection)
case .notification(let status):
presentable = self.notification(status)
default:
self.lock.logger.warn("Ignoring navigation \(route)")
return
Expand Down
3 changes: 3 additions & 0 deletions Lock/Routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ enum Route: Equatable {
case forgotPassword
case multifactor
case enterpriseActiveAuth(connection: EnterpriseConnection)
case notification(status: NotificationStatus)
}

func == (lhs: Route, rhs: Route) -> Bool {
Expand All @@ -57,6 +58,8 @@ func == (lhs: Route, rhs: Route) -> Bool {
return true
case (.enterpriseActiveAuth(let lhsConnection), .enterpriseActiveAuth(let rhsConnection)):
return lhsConnection.name == rhsConnection.name
case (.notification(let lhsStatus), .notification(let rhsStatus)):
return lhsStatus == rhsStatus
default:
return false
}
Expand Down
Loading

0 comments on commit 69d034e

Please sign in to comment.