Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Simplified.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
03F94CD11DD6288C00CE8F4F /* AccountsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F94CD01DD6288C00CE8F4F /* AccountsManager.swift */; };
081387571BC574DA003DEA6A /* UILabel+NYPLAppearanceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 081387561BC574DA003DEA6A /* UILabel+NYPLAppearanceAdditions.m */; };
0813875A1BC5767F003DEA6A /* UIButton+NYPLAppearanceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 081387591BC5767F003DEA6A /* UIButton+NYPLAppearanceAdditions.m */; };
0826CD2924AA21B2000F4030 /* SamlIDPCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0826CD2824AA21B2000F4030 /* SamlIDPCell.swift */; };
0826CD2F24AA2801000F4030 /* LibraryDescriptionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0826CD2E24AA2801000F4030 /* LibraryDescriptionCell.swift */; };
085640CE1BB99FC30088BDBF /* NSURL+NYPLURLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 085640CD1BB99FC30088BDBF /* NSURL+NYPLURLAdditions.m */; };
0857A0F72478337D00C7984E /* NYPLSessionCredentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0857A0F62478337D00C7984E /* NYPLSessionCredentials.swift */; };
0857A0FF247835FF00C7984E /* KeychainStoredVariable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0857A0FE247835FF00C7984E /* KeychainStoredVariable.swift */; };
Expand All @@ -33,6 +35,8 @@
086C45D624AE77CA00F5108E /* NYPLBasicAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086C45D524AE77CA00F5108E /* NYPLBasicAuth.swift */; };
086C45D724AE77CA00F5108E /* NYPLBasicAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086C45D524AE77CA00F5108E /* NYPLBasicAuth.swift */; };
086C45DC24AE77E600F5108E /* NYPLUserAccountFrontEndValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08C481AD247CAEEB003A6723 /* NYPLUserAccountFrontEndValidation.swift */; };
089E42C6249A823800310360 /* NYPLCookiesWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 089E42C5249A823800310360 /* NYPLCookiesWebViewController.swift */; };
089E430C24A2459100310360 /* LoginCellTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 089E430B24A2459100310360 /* LoginCellTypes.swift */; };
08A352201BDE8E410040BF1D /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08A3521F1BDE8E410040BF1D /* CFNetwork.framework */; };
08A352221BDE8E560040BF1D /* libicucore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 08A352211BDE8E560040BF1D /* libicucore.tbd */; };
08A352241BDE8E640040BF1D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08A352231BDE8E640040BF1D /* Security.framework */; };
Expand Down Expand Up @@ -567,6 +571,8 @@
081387561BC574DA003DEA6A /* UILabel+NYPLAppearanceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+NYPLAppearanceAdditions.m"; sourceTree = "<group>"; };
081387581BC5767F003DEA6A /* UIButton+NYPLAppearanceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+NYPLAppearanceAdditions.h"; sourceTree = "<group>"; };
081387591BC5767F003DEA6A /* UIButton+NYPLAppearanceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+NYPLAppearanceAdditions.m"; sourceTree = "<group>"; };
0826CD2824AA21B2000F4030 /* SamlIDPCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SamlIDPCell.swift; sourceTree = "<group>"; };
0826CD2E24AA2801000F4030 /* LibraryDescriptionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryDescriptionCell.swift; sourceTree = "<group>"; };
085640CC1BB99FC30088BDBF /* NSURL+NYPLURLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+NYPLURLAdditions.h"; sourceTree = "<group>"; };
085640CD1BB99FC30088BDBF /* NSURL+NYPLURLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+NYPLURLAdditions.m"; sourceTree = "<group>"; };
0857A0F62478337D00C7984E /* NYPLSessionCredentials.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NYPLSessionCredentials.swift; sourceTree = "<group>"; };
Expand All @@ -578,6 +584,8 @@
085D31DE1BE3CD3C007F7672 /* NSURLRequest+NYPLURLRequestAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLRequest+NYPLURLRequestAdditions.m"; sourceTree = "<group>"; };
085D31FB1BE7BE86007F7672 /* ReaderClientCert.sig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReaderClientCert.sig; sourceTree = "<group>"; };
086C45D524AE77CA00F5108E /* NYPLBasicAuth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NYPLBasicAuth.swift; sourceTree = "<group>"; };
089E42C5249A823800310360 /* NYPLCookiesWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NYPLCookiesWebViewController.swift; sourceTree = "<group>"; };
089E430B24A2459100310360 /* LoginCellTypes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginCellTypes.swift; sourceTree = "<group>"; };
08A3521F1BDE8E410040BF1D /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
08A352211BDE8E560040BF1D /* libicucore.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libicucore.tbd; path = usr/lib/libicucore.tbd; sourceTree = SDKROOT; };
08A352231BDE8E640040BF1D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -1079,6 +1087,16 @@
name = CardCreator;
sourceTree = "<group>";
};
089E430724A2456E00310360 /* Login */ = {
isa = PBXGroup;
children = (
089E430B24A2459100310360 /* LoginCellTypes.swift */,
0826CD2824AA21B2000F4030 /* SamlIDPCell.swift */,
0826CD2E24AA2801000F4030 /* LibraryDescriptionCell.swift */,
);
name = Login;
sourceTree = "<group>";
};
110AF8881961D652004887C3 /* My Books */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1321,6 +1339,7 @@
111E75791A80165C00718AD7 /* NYPLSettingsSplitViewController.m */,
E6BA02B71DE4B6F600F76404 /* RemoteHTMLViewController.swift */,
731A5B1124621F2B00B5E663 /* NYPLSignInBusinessLogic.swift */,
089E42C5249A823800310360 /* NYPLCookiesWebViewController.swift */,
);
name = Settings;
sourceTree = "<group>";
Expand Down Expand Up @@ -1513,6 +1532,7 @@
A823D816192BABA400B55DE2 /* Simplified */ = {
isa = PBXGroup;
children = (
089E430724A2456E00310360 /* Login */,
110AF8891961D66C004887C3 /* Additions */,
110AF8901961D822004887C3 /* Book */,
0345BFEE1DBF031B00398B6F /* CardCreator */,
Expand Down Expand Up @@ -2261,6 +2281,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0826CD2F24AA2801000F4030 /* LibraryDescriptionCell.swift in Sources */,
2DE514351DC3F0BE005A58BD /* NYPLCirculationAnalytics.swift in Sources */,
171966A924170819007BB87E /* NYPLBookState.swift in Sources */,
03DE7BE91DBF0DE400E89064 /* UpdateCheckShim.swift in Sources */,
Expand Down Expand Up @@ -2404,6 +2425,8 @@
113DB8A719C24E54004E1154 /* NYPLIndeterminateProgressView.m in Sources */,
119BEB89198C43A600121439 /* NSString+NYPLStringAdditions.m in Sources */,
E6B6E76F1F6859A4007EE361 /* NYPLKeychainManager.swift in Sources */,
089E42C6249A823800310360 /* NYPLCookiesWebViewController.swift in Sources */,
0826CD2924AA21B2000F4030 /* SamlIDPCell.swift in Sources */,
5D7CF8B922C3FC06007CAA34 /* NYPLErrorLogger.swift in Sources */,
A499BF261B39EFC7002F8B8B /* NYPLOPDSEntryGroupAttributes.m in Sources */,
1196F75B1970727C00F62670 /* NYPLMyBooksDownloadCenter.m in Sources */,
Expand All @@ -2415,6 +2438,7 @@
8CE9C471237F84820072E964 /* NYPLBookDetailsProblemDocumentViewController.swift in Sources */,
A4BA1D131B43046B006F83DF /* NYPLCatalogGroupedFeed.m in Sources */,
11F3773319E0876F00487769 /* NYPLCatalogFacet.m in Sources */,
089E430C24A2459100310360 /* LoginCellTypes.swift in Sources */,
1158812E1A894F4E008672C3 /* NYPLAccountSignInViewController.m in Sources */,
5D3A28CC22D3DA850042B3BD /* NYPLUserProfileDocument.swift in Sources */,
03F94CD11DD6288C00CE8F4F /* AccountsManager.swift in Sources */,
Expand Down
92 changes: 54 additions & 38 deletions Simplified/Account.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,25 @@ private let userAcceptedEULAKey = "NYPLSettingsUserAcceptedEULA"
private let userAboveAgeKey = "NYPLSettingsUserAboveAgeKey"
private let accountSyncEnabledKey = "NYPLAccountSyncEnabledKey"


@objcMembers
class SamlIDP: NSObject, Codable {
let url: URL

private let displayNames: [String: String]?
private let descriptions: [String: String]?

var displayName: String? { displayNames?["en"] }
var idpDescription: String? { descriptions?["en"] }

init?(opdsLink: OPDS2Link) {
guard let url = URL(string: opdsLink.href) else { return nil }
self.url = url
self.displayNames = opdsLink.displayNames?.reduce(into: [String: String]()) { $0[$1.language] = $1.value }
self.descriptions = opdsLink.descriptions?.reduce(into: [String: String]()) { $0[$1.language] = $1.value }
}
}

// MARK: AccountDetails
// Extra data that gets loaded from an OPDS2AuthenticationDocument,
@objcMembers final class AccountDetails: NSObject {
Expand All @@ -28,29 +47,59 @@ private let accountSyncEnabledKey = "NYPLAccountSyncEnabledKey"
let supportsBarcodeDisplay:Bool
let coppaUnderUrl:URL?
let coppaOverUrl:URL?

let oauthIntermediaryUrl:URL?
let methodDescription: String?

let samlIdps: [SamlIDP]?

init(auth: OPDS2AuthenticationDocument.Authentication) {
authType = AuthType(rawValue: auth.type) ?? .none
let authType = AuthType(rawValue: auth.type) ?? .none
self.authType = authType
authPasscodeLength = auth.inputs?.password.maximumLength ?? 99
patronIDKeyboard = LoginKeyboard.init(auth.inputs?.login.keyboard) ?? .standard
pinKeyboard = LoginKeyboard.init(auth.inputs?.password.keyboard) ?? .standard
patronIDLabel = auth.labels?.login
pinLabel = auth.labels?.password
methodDescription = auth.description
supportsBarcodeScanner = auth.inputs?.login.barcodeFormat == "Codabar"
supportsBarcodeDisplay = supportsBarcodeScanner

switch authType {
case .coppa:
coppaUnderUrl = URL.init(string: auth.links?.first(where: { $0.rel == "http://librarysimplified.org/terms/rel/authentication/restriction-not-met" })?.href ?? "")
coppaOverUrl = URL.init(string: auth.links?.first(where: { $0.rel == "http://librarysimplified.org/terms/rel/authentication/restriction-met" })?.href ?? "")
oauthIntermediaryUrl = nil
samlIdps = nil

case .oauthIntermediary:
oauthIntermediaryUrl = URL.init(string: auth.links?.first(where: { $0.rel == "authenticate" })?.href ?? "")
coppaUnderUrl = nil
coppaOverUrl = nil
samlIdps = nil

case .saml:
samlIdps = auth.links?.filter { $0.rel == "authenticate" }.compactMap { SamlIDP(opdsLink: $0) }
oauthIntermediaryUrl = nil
coppaUnderUrl = nil
coppaOverUrl = nil

case .none, .basic, .anonymous:
oauthIntermediaryUrl = nil
coppaUnderUrl = nil
coppaOverUrl = nil
samlIdps = nil

}
}

var needsAuth:Bool {
return authType == .basic || authType == .oauthIntermediary || authType == .saml
}

var needsAgeCheck:Bool {
return authType == .coppa
}

var isCatalogSecured: Bool {
return authType == .oauthIntermediary || authType == .saml
}
Expand All @@ -76,6 +125,9 @@ private let accountSyncEnabledKey = "NYPLAccountSyncEnabledKey"
supportsBarcodeDisplay = authentication.supportsBarcodeDisplay
coppaUnderUrl = authentication.coppaUnderUrl
coppaOverUrl = authentication.coppaOverUrl
oauthIntermediaryUrl = authentication.oauthIntermediaryUrl
methodDescription = authentication.methodDescription
samlIdps = authentication.samlIdps
}
}

Expand All @@ -90,42 +142,6 @@ private let accountSyncEnabledKey = "NYPLAccountSyncEnabledKey"
let userProfileUrl:String?
let signUpUrl:URL?
let loansUrl:URL?
var authType: AuthType {
return auths.first?.authType ?? .none
}

var authPasscodeLength: UInt {
return auths.first?.authPasscodeLength ?? 99
}

var patronIDKeyboard: LoginKeyboard {
return auths.first?.patronIDKeyboard ?? .standard
}

var pinKeyboard: LoginKeyboard {
return auths.first?.pinKeyboard ?? .standard
}

var supportsBarcodeScanner: Bool {
return auths.first?.supportsBarcodeScanner ?? false
}

var supportsBarcodeDisplay: Bool {
return auths.first?.supportsBarcodeDisplay ?? false
}

var coppaUnderUrl: URL? {
return auths.first?.coppaUnderUrl
}

var coppaOverUrl: URL? {
return auths.first?.coppaOverUrl
}

var needsAuth:Bool {
return authType == .basic
}

var defaultAuth: Authentication? {
guard auths.count > 1 else { return auths.first }
return auths.first(where: { !$0.isCatalogSecured }) ?? auths.first
Expand Down
8 changes: 7 additions & 1 deletion Simplified/AccountsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,13 @@ private let prodUrlHash = prodUrl.absoluteString.md5().base64EncodedStringUrlSaf
object: nil
)

self.loadCatalogs(completion: {_ in })
// It needs to be done asynchronously, so that init returns prior to calling it
// Otherwise it would try to access itself before intialization is finished
// Network executor will try to access shared accounts manager, as it needs it to get headers data
// Thik of this async block as you would about viewDidLoad which is triggered after a view is loaded
OperationQueue.current?.underlyingQueue?.async {
self.loadCatalogs(completion: {_ in })
}
}

let completionHandlerAccessQueue = DispatchQueue(label: "libraryListCompletionHandlerAccessQueue")
Expand Down
36 changes: 36 additions & 0 deletions Simplified/LibraryDescriptionCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// LibraryDescriptionCell.swift
// SimplyE
//
// Created by Jacek Szyja on 29/06/2020.
// Copyright © 2020 NYPL Labs. All rights reserved.
//

import UIKit

@objcMembers
class LibraryDescriptionCell: UITableViewCell {

let descriptionLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.font = UIFont(name: "AvenirNext-Regular", size: 12)
return label
}()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(descriptionLabel)

descriptionLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
descriptionLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
descriptionLabel.widthAnchor.constraint(equalTo: contentView.widthAnchor, constant: -32).isActive = true
descriptionLabel.heightAnchor.constraint(equalTo: contentView.heightAnchor, constant: -16).isActive = true
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
37 changes: 37 additions & 0 deletions Simplified/LoginCellTypes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// LoginCellTypes.swift
// SimplyE
//
// Created by Jacek Szyja on 23/06/2020.
// Copyright © 2020 NYPL Labs. All rights reserved.
//

import Foundation

@objcMembers
class AuthMethodCellType: NSObject {
let authenticationMethod: AccountDetails.Authentication

init(authenticationMethod: AccountDetails.Authentication) {
self.authenticationMethod = authenticationMethod
}
}

@objcMembers
class InfoHeaderCellType: NSObject {
let information: String

init(information: String) {
self.information = information
}
}

@objcMembers
class SamlIdpCellType: NSObject {
let idp: SamlIDP

init(idp: SamlIDP) {
self.idp = idp
}
}

2 changes: 2 additions & 0 deletions Simplified/NYPLAccountSignInViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
// and pin.
+ (void)authorizeUsingExistingBarcodeAndPinWithCompletionHandler:(void (^)(void))handler;

+ (void)authorizeUsingIntermediaryWithCompletionHandler:(void (^)(void))handler;

@end
Loading