Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passwordless Email (Code/Link) and Social #395

Merged
merged 12 commits into from
Mar 19, 2017
Merged

Conversation

cocojoe
Copy link
Member

@cocojoe cocojoe commented Feb 16, 2017

Public API Methods:

Lock

  • static func continueAuth(using userActivity: NSUserActivity) -> Bool: Support NSUserActivity callbacks
  • func onPasswordless(callback: @escaping (String) -> Void) -> Lock : Be informed of passwordless auth initiated with identifier.
  • static func passwordless(): Lock passwordless instance loading Auth0 client info from Auth0.plist file in main bundle.
  • static func passwordless(clientId: String, domain: String) -> Lock: Lock passwordless instance using clientId and domain

New Options

  • passwordlessMethod: Specify to send a passcode .emailCode or universal link .emailLink

@hzalaz hzalaz changed the base branch from v2 to master February 16, 2017 21:23
@cocojoe cocojoe force-pushed the feature_passwordless_email branch from 4d4ad09 to 7da20b3 Compare February 20, 2017 10:55
@cocojoe
Copy link
Member Author

cocojoe commented Feb 20, 2017

Notes:

Enabling Universal Links

AppDelegate

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
    return Lock.continueAuth(using: userActivity)
}

Setup

  • Enable the 'associated domains' in app capabilities
  • Add your auth0 domain applinks:{DOMAIN}
  • Check Auth0 Dashboard Select Client -> Advanced -> Mobile Settings App Bundle Identifier is set.

@cocojoe cocojoe force-pushed the feature_passwordless_email branch from 35abc97 to 203eb04 Compare February 20, 2017 21:29
@cocojoe
Copy link
Member Author

cocojoe commented Mar 2, 2017

passwordless_1
passwordless_2
passwordless_3
passwordless_4
passwordless_5
passwordless_6
passwordless_7
passwordless_8
passwordless_10

@cocojoe cocojoe force-pushed the feature_passwordless_email branch from c85ded4 to 42dfb07 Compare March 6, 2017 10:07
@cocojoe cocojoe changed the title Added Passwordless Email Code/MagicLink Support Passwordless Email (Code/Link) and Social Mar 6, 2017
@cocojoe
Copy link
Member Author

cocojoe commented Mar 6, 2017

Although it will make the PR a little bigger, might make more sense to wait for SMS support as it has improvements and relies on this branch anyway as a base. So any change to this PR will need to be rebased anyway.

Lock/Lock.swift Outdated
*/
public static func passwordless() -> Lock {
let newLock = Lock()
return newLock.withOptions { $0.passwordless = true }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we do this in the init?

Lock/Lock.swift Outdated

- returns: true if the link is of the appropriate format, false otherwise
*/
public static func continueAuth(withActivity userActivity: NSUserActivity) -> Bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continueAuth(using userActivity: NSUserActivity) -> Bool

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in next PR, will update in general public API bits.

var activeDirectoryEmailAsUsername: Bool = false
var enterpriseConnectionUsingActiveAuth: [String] = []

var oidcConformant: Bool = false
var audience: String?

var passwordlessMethod: PasswordlessMethod = .code
var passwordless: Bool = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either passwordlessOnly or classicMode to denote its one or the other

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k

constraintEqual(anchor: center.topAnchor, toAnchor: self.topAnchor)
constraintEqual(anchor: center.rightAnchor, toAnchor: self.rightAnchor, constant: -20)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the padding go? in the input?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to have vanished after rebase.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what vanished? I can still see the change being done in this branch that removes the padding

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I miss interpreted you original comment. In the SingleInputView component, it wasn't as reusable (or compressible) as it could be so tidied the usage up in general. I checked the presenters that use it. MFA, ForgotPassword, EnterpriseDomain and Passwordless.

var onCancel: () -> Void = { }
var onSignUp: (String, [String: Any]) -> Void = { _ in }
var onForgotPassword: (String) -> Void = { _ in }
var onAuth: (Credentials) -> () = { _ in }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't the change from () to Void part of the linter warnings?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is old, ran a Lint pass.


import Foundation

class PasswordlessActivity: PasswordlessUserActivity {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we follow the same style as the Auth tx where the handler has all the code and dependencies and we avoid retaining the messagePresenter

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, think I tried this initially then had an issue so swapped to this to get running. If okay I'll address in another PR as internal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool we can do it in another PR

var messagePresenter: MessagePresenter?

var view: View {
switch self.screen {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have made two presenters and distinct screens to avoid polluting them

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a lot cleaner in followup PR

@@ -35,6 +35,7 @@ protocol Navigable {
func resetScroll(_ animated: Bool)
func scroll(toPosition: CGPoint, animated: Bool)

func onBack() -> ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we have this one? I remember we had an event to go back

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a method, however it's not in the protocol so inaccessible in the presenters.

@@ -35,6 +35,7 @@ protocol Navigable {
func resetScroll(_ animated: Bool)
func scroll(toPosition: CGPoint, animated: Bool)

func onBack() -> ()
}

struct Router: Navigable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldnt we have one router for classic and another for passwordless? The code seems more of a mess than it was previously

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, it would be clearer in terms of internal separation, although it's 20 line block of code vs duplication of a lot more code. I don't really mind either way.

Lock/Lock.swift Outdated

- returns: Lock itself for chaining
*/
public func onPasswordless(callback: @escaping (String, PasswordlessMethod) -> ()) -> Lock {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why having the method here is useful? Also its missing docs on what the callback yields

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may or may not be useful, I look at it that a developer may want to know when they are sending out Email/SMS and hook into their own analytics. I'll update docs although I feel it should just be the identifier now.

@cocojoe cocojoe force-pushed the feature_passwordless_email branch from 42dfb07 to 0d9b83e Compare March 14, 2017 11:04

- parameter name: name of the connection
*/
mutating func passwordless(name: String)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how you will tell if its sms or email?

Copy link
Member Author

@cocojoe cocojoe Mar 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see any options in dashboard to create custom email/sms connections? (Like you can with OAuth2) So in Passwordless SMS it simply selects by name, unless I am missing something?

CDN

{
    connections =     (
                {
            name = email;
        }
    );
    name = email;
},
{
    connections =     (
                {
            name = sms;
        }
    );
    name = sms;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can create any connection with Auth0 API.

constraintEqual(anchor: center.topAnchor, toAnchor: self.topAnchor)
constraintEqual(anchor: center.rightAnchor, toAnchor: self.rightAnchor, constant: -20)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what vanished? I can still see the change being done in this branch that removes the padding

}

internal extension OptionBuildable {
func validate() -> UnrecoverableError? {
extension OptionBuildable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is not internal?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My error.

}

public enum PasswordlessMethod: Int, Equatable {
case emailCode = 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magicLink or code

Copy link
Member Author

@cocojoe cocojoe Mar 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this inline with Lock.Android which has emailCode, emailLink, smsCode, smsLink. Passwordless SMS is based on this so backported it so no breaking public change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok but lets only have magicLink and code in another PR


import Foundation

enum PasswordlessScreen {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for?

Copy link
Member Author

@cocojoe cocojoe Mar 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for Passwordless routing, naming inspired by DatabaseScreen
Stage 1 .request. - Request a code/link
Stage 2a .code - Passcode Auth
Stage 2b .linkSent - Universal Link Confirmation


import Foundation

class PasswordlessActivity: PasswordlessUserActivity {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool we can do it in another PR

@@ -35,6 +35,7 @@ protocol Navigable {
func resetScroll(_ animated: Bool)
func scroll(toPosition: CGPoint, animated: Bool)

func onBack()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably was lost but why we added this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not accessible by the presenters as it's not in the protocol, I used it as a convenience in the Passwordless presenter for routing back if code/link has not been delivered. There is no real reason an onBack() method shouldn't be in a Navigation protocol.

let presenter = DatabasePresenter(interactor: interactor, connection: database, navigator: self, options: self.lock.options)
if !oauth2.isEmpty {

if !self.lock.classicMode {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think this will be far cleaner using different routers to avoid the if-else nightmare. What are the parts that will be duplicated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add one and see how it looks.

cocojoe and others added 12 commits March 19, 2017 17:28
Renamed activity callback to continueAuth(withActivity:
Added support for Social Connections in Passwordless mode
PasswordlessView UI Improvements
Refactored usage of SingleInputView across views
Updated	README
Update Tests
Rebase Fixes
Split Options Validation into Classic / Passwordless
Update PasswordlessMethod
Update Public API naming
Added classic flag to Lock init
Added Lock passwordless init
onPasswordless only has identifier now
Fix Force wrap
Update Tests
Router Split into RouterClassic and RouterPasswordless
Added Tests
@hzalaz hzalaz force-pushed the feature_passwordless_email branch from 940d571 to e9159de Compare March 19, 2017 20:29
@hzalaz hzalaz merged commit 71a0403 into master Mar 19, 2017
@hzalaz hzalaz added this to the v2-Next milestone Mar 19, 2017
@hzalaz hzalaz deleted the feature_passwordless_email branch April 6, 2017 23:39
@hzalaz hzalaz modified the milestones: v2-Next, 2.2.0 Apr 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants