Skip to content

Commit

Permalink
Refactor PasswordManager options into Config struct
Browse files Browse the repository at this point in the history
Update README
  • Loading branch information
cocojoe committed Apr 10, 2017
1 parent d3468ad commit 373a933
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 44 deletions.
8 changes: 4 additions & 4 deletions App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>org-appextension-feature-password-management</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
Expand All @@ -50,9 +54,5 @@
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>org-appextension-feature-password-management</string>
</array>
</dict>
</plist>
1 change: 1 addition & 0 deletions App/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ViewController: UIViewController {
.classic()
.withOptions {
applyDefaultOptions(&$0)
$0.passwordManager = PasswordManagerConfig(appIdentifier: "www.myapp.com", displayName: "My App")
$0.customSignupFields = [
CustomTextField(name: "first_name", placeholder: "First Name", icon: LazyImage(name: "ic_person", bundle: Lock.bundle)),
CustomTextField(name: "last_name", placeholder: "Last Name", icon: LazyImage(name: "ic_person", bundle: Lock.bundle))
Expand Down
4 changes: 2 additions & 2 deletions Lock/ClassicRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ struct ClassicRouter: Router {
let authentication = self.lock.authentication
let interactor = DatabaseInteractor(connection: database, authentication: authentication, user: self.user, options: self.lock.options, dispatcher: lock.observerStore)
let presenter = DatabasePresenter(interactor: interactor, connection: database, navigator: self, options: self.lock.options)
if self.lock.options.showPasswordManager, OnePassword.isAvailable() {
let passwordManager = OnePassword(identifier: self.lock.options.passwordManagerAppIdentifier, controller: self.controller)
if self.lock.options.passwordManager.isEnabled, OnePassword.isAvailable() {
let passwordManager = OnePassword(withConfig: self.lock.options.passwordManager, controller: self.controller)
presenter.passwordManager = passwordManager
}
if !oauth2.isEmpty {
Expand Down
2 changes: 0 additions & 2 deletions Lock/IconButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class IconButton: UIView {

private func layoutButton() {
let button = UIButton(type: .custom)

self.addSubview(button)

constraintEqual(anchor: button.topAnchor, toAnchor: self.topAnchor)
Expand All @@ -69,7 +68,6 @@ class IconButton: UIView {
button.translatesAutoresizingMaskIntoConstraints = false

button.addTarget(self, action: #selector(pressed), for: .touchUpInside)

self.button = button
}

Expand Down
4 changes: 1 addition & 3 deletions Lock/LockOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,5 @@ struct LockOptions: OptionBuildable {
var audience: String?

var passwordlessMethod: PasswordlessMethod = .code

var showPasswordManager: Bool = true
var passwordManagerAppIdentifier: String = Bundle.main.bundleIdentifier!
var passwordManager: PasswordManagerConfig = PasswordManagerConfig()
}
30 changes: 23 additions & 7 deletions Lock/OnePassword.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ protocol PasswordManager {

class OnePassword: PasswordManager {

let identifier: String
let config: PasswordManagerConfig
weak var controller: UIViewController?
var fields: [String: InputField] = [:]

required init(identifier: String, controller: UIViewController?) {
self.identifier = identifier
required init(withConfig config: PasswordManagerConfig, controller: UIViewController?) {
self.config = config
self.controller = controller
}

Expand All @@ -47,7 +47,7 @@ class OnePassword: PasswordManager {

func login(callback: @escaping (Error?, [String: InputField]?) -> Void) {
guard let controller = self.controller else { return }
LockOnePasswordExtension.shared().findLogin(forURLString: self.identifier, for: controller, sender: nil) { (result, error) in
LockOnePasswordExtension.shared().findLogin(forURLString: self.config.appIdentifier, for: controller, sender: nil) { (result, error) in
guard error == nil else {
return callback(error, nil)
}
Expand All @@ -58,10 +58,10 @@ class OnePassword: PasswordManager {
}

func store(withPolicy policy: [String: Any]?, callback: @escaping (Error?, [String: InputField]?) -> Void) {
guard let displayName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String, let controller = self.controller else { return }
var loginDetails: [String: String] = [ AppExtensionTitleKey: displayName ]
guard let controller = self.controller else { return }
var loginDetails: [String: String] = [ AppExtensionTitleKey: self.config.displayName ]
self.fields.forEach { loginDetails[$0] = $1.text }
LockOnePasswordExtension.shared().storeLogin(forURLString: self.identifier, loginDetails: loginDetails, passwordGenerationOptions: policy, for: controller, sender: nil) { (result, error) in
LockOnePasswordExtension.shared().storeLogin(forURLString: self.config.appIdentifier, loginDetails: loginDetails, passwordGenerationOptions: policy, for: controller, sender: nil) { (result, error) in
guard error == nil else {
return callback(error, nil)
}
Expand All @@ -71,3 +71,19 @@ class OnePassword: PasswordManager {
}
}
}

public struct PasswordManagerConfig {
public var isEnabled: Bool = true
public let appIdentifier: String
public let displayName: String

public init() {
self.appIdentifier = Bundle.main.bundleIdentifier!
self.displayName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
}

public init(appIdentifier: String, displayName: String) {
self.appIdentifier = appIdentifier
self.displayName = displayName
}
}
7 changes: 2 additions & 5 deletions Lock/OptionBuildable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,8 @@ public protocol OptionBuildable: Options {
/// Specify the passwordless method, send a passcode or magic link. By default is .code
var passwordlessMethod: PasswordlessMethod { get set }

/// Show password manager button when user credentials are needed, e.g. during Sign Up, and allow storing/retrieving credentials from the password manager. By default is true
var showPasswordManager: Bool { get set }

/// Application identifier used by the password manager, if you also have a web app we recommend adding your site url. By default is the application bundle identifier
var passwordManagerAppIdentifier: String { get set }
/// Configuration to be used by the password manager.
var passwordManager: PasswordManagerConfig { get set }
}

extension OptionBuildable {
Expand Down
4 changes: 1 addition & 3 deletions Lock/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,5 @@ public protocol Options {
var audience: String? { get }

var passwordlessMethod: PasswordlessMethod { get }

var showPasswordManager: Bool { get }
var passwordManagerAppIdentifier: String { get }
var passwordManager: PasswordManagerConfig { get }
}
16 changes: 10 additions & 6 deletions LockTests/OnePasswordSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class OnePasswordSpec: QuickSpec {

var onePassword: OnePassword?
var viewController: MockViewController?
var passwordConfig: PasswordManagerConfig!

describe("availability") {

Expand All @@ -45,16 +46,18 @@ class OnePasswordSpec: QuickSpec {
beforeEach {
onePassword = nil
viewController = MockViewController()
passwordConfig = PasswordManagerConfig()
}

it("should init with identifier") {
onePassword = OnePassword(identifier: "www.mysite.com", controller: nil)
expect(onePassword?.identifier) == "www.mysite.com"
it("should init with default config") {
onePassword = OnePassword(withConfig: passwordConfig, controller: nil)
expect(onePassword?.config.appIdentifier) == Bundle.main.bundleIdentifier!
expect(onePassword?.config.displayName) == Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String
expect(onePassword?.config.isEnabled) == true
}

it("should init with identifier and controller") {
onePassword = OnePassword(identifier: "www.mysite.com", controller: viewController)
expect(onePassword?.identifier) == "www.mysite.com"
onePassword = OnePassword(withConfig: passwordConfig, controller: viewController)
expect(onePassword?.controller).to(equal(viewController))
}

Expand All @@ -64,7 +67,8 @@ class OnePasswordSpec: QuickSpec {

beforeEach {
viewController = MockViewController()
onePassword = OnePassword(identifier: "www.mysite.com", controller: viewController)
passwordConfig = PasswordManagerConfig()
onePassword = OnePassword(withConfig: passwordConfig, controller: viewController)
}

it("should present extension prompt on login") {
Expand Down
11 changes: 7 additions & 4 deletions LockTests/OptionsSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,17 @@ class OptionsSpec: QuickSpec {
expect(options.passwordlessMethod).to(equal(PasswordlessMethod.code))
}

it("should show passwordManager") {
expect(options.showPasswordManager) == true
it("should have passwordManager enabled") {
expect(options.passwordManager.isEnabled) == true
}

it("should match bundler identifier") {
expect(options.passwordManagerAppIdentifier) == Bundle.main.bundleIdentifier
it("should have passwordManager app bundler identifier") {
expect(options.passwordManager.appIdentifier) == Bundle.main.bundleIdentifier!
}

it("should have passwordManager app display name") {
expect(options.passwordManager.displayName) == Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String
}
}

describe("validation") {
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ Need help migrating from v1? Please check our [Migration Guide](MIGRATION.md)
Add the following line to your Podfile:

```ruby
pod "Lock", "~> 2.1.0"
pod "Lock", "~> 2.1"
```

### Carthage

In your `Cartfile` add

```ruby
github "auth0/Lock.swift" ~>2.1.0
github "auth0/Lock.swift" ~> 2.1
```

## Usage
Expand Down Expand Up @@ -361,25 +361,25 @@ When signing up the default information requirements are the user's *email* and

*Note: You must specify the icon to use with your custom text field and store it in your App's bundle.*

#### 1Password
#### Password Manager

By default 1Password support is enabled, although you will still need to have the 1Password app installed for the option to be visible in the login and signup screens. You can disable 1Password support using the `showPasswordManager` option.
By default password manager support using [1Password](https://1password.com/) is enabled for database connections, although you will still need to have the 1Password app installed for the option to be visible in the login and signup screens. You can disable 1Password support using the `isEnabled` property of the `passwordManager`.

```swift
.withOptions {
$0.showPasswordManager = false
$0.passwordManager.isEnabled = false
}
```

By default the `passwordManagerAppIdentifier` will be set to the app bundle identifier. If you need to share credentials with your website that also uses the same Auth0 connection, then you can use name of the website e.g.
By default the `appIdentifier` will be set to the app's bundle identifier and the `displayName` will be set to the app's display name. You can customize this as follows:

```swift
.withOptions {
$0.passwordManagerAppIdentifier = "www.website.com"
$0.passwordManager = PasswordManagerConfig(appIdentifier: "www.myapp.com", displayName: "My App")
}
```

You will also need to add the following to your app's `info.plist`:
You will need to add the following to your app's `info.plist`:

```xml
<key>LSApplicationQueriesSchemes</key>
Expand Down

0 comments on commit 373a933

Please sign in to comment.