Skip to content

Commit

Permalink
Implement initialWebAuthenticationMethod and its tests
Browse files Browse the repository at this point in the history
  • Loading branch information
onevcat committed Dec 17, 2024
1 parent 249b6a0 commit 5da9db4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 6 deletions.
13 changes: 12 additions & 1 deletion LineSDK/LineSDK/Login/LoginManagerParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ extension LoginManager {
#else
public var allowRecreatingLoginProcess = false
#endif

/// Specifies the initial web authentication method to be used when starting the login process.
///
/// By default, `.email` is used to provide input boxes for email and password.
public var initialWebAuthenticationMethod: WebAuthenticationMethod = .email

/// Creates a default `LoginManager.Parameters` value.
public init() {}
Expand All @@ -89,7 +94,13 @@ extension LoginManager {
/// consent screen.
case aggressive
}


/// The method used for the authentication when using the web authentication flow.
public enum WebAuthenticationMethod: String {
case email
case qrCode
}

/// Represents the language used in the web page.
public struct WebPageLanguage {
/// :nodoc:
Expand Down
11 changes: 9 additions & 2 deletions LineSDK/LineSDK/Login/LoginProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,15 @@ class WebLoginFlow: NSObject {
weak var safariViewController: UIViewController?

init(parameter: LoginProcess.FlowParameters) {
let webLoginURLBase = URL(string: Constant.lineWebAuthURL)!
url = webLoginURLBase.appendedLoginQuery(parameter)
var component = URLComponents(string: Constant.lineWebAuthURL)!
if parameter.loginParameter.initialWebAuthenticationMethod == .qrCode {
if let _ = component.fragment {
assertionFailure("Multiple fragment is not yet supported. Require review or report to developer.")
}
component.fragment = "/qr"
}
let baseURL = component.url!
url = baseURL.appendedLoginQuery(parameter)
}

func start(in viewController: UIViewController?) {
Expand Down
50 changes: 47 additions & 3 deletions LineSDK/LineSDKTests/Login/LoginFlowTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,22 @@ class LoginFlowTests: XCTestCase, ViewControllerCompatibleTest {
return p
}()
)


let parameterWithInitialQRMethod = LoginProcess.FlowParameters(
channelID: "123",
universalLinkURL: nil,
scopes: [.profile, .openID],
pkce: PKCE(),
processID: "abc",
nonce: "kkk",
loginParameter: {
var p = LoginManager.Parameters()
p.botPromptStyle = .normal
p.initialWebAuthenticationMethod = .qrCode
return p
}()
)

// Login URL has a double escaped query.
func testLoginQueryURLEncode() {

Expand Down Expand Up @@ -178,7 +193,7 @@ class LoginFlowTests: XCTestCase, ViewControllerCompatibleTest {
XCTAssertNotEqual(item.value, item.value?.removingPercentEncoding)
XCTAssertTrue(item.value!.removingPercentEncoding!.contains("prompt_bot_id=@abc123"))
}

// URL Scheme has a triple escaped query.
func testURLSchemeQueryEncode() {
let baseURL = Constant.lineAppAuthURLv2
Expand Down Expand Up @@ -259,7 +274,36 @@ class LoginFlowTests: XCTestCase, ViewControllerCompatibleTest {
flow.start(in: rootViewController)
waitForExpectations(timeout: 1.0, handler: nil)
}


func testWebLoginFlowWithQRCodeFirst() {
let expect = expectation(description: "\(#file)_\(#line)")
let flow = WebLoginFlow(parameter: parameterWithInitialQRMethod)
let webURL = URL(string: Constant.lineWebAuthURL)!
let components = URLComponents(url: flow.url, resolvingAgainstBaseURL: false)
XCTAssertEqual(components?.scheme, "https")
XCTAssertEqual(components?.host, webURL.host)
XCTAssertEqual(components?.path, webURL.path)

XCTAssertEqual(components?.fragment, "/qr")
XCTAssertTrue(flow.url.absoluteString.contains("#/qr"))

let rootViewController = setupViewController()

flow.onNext.delegate(on: self) { [unowned flow] (self, next) in
expect.fulfill()
self.resetViewController()
switch next {
case .safariViewController:
XCTAssertEqual(rootViewController.presentedViewController, flow.safariViewController)
default:
XCTFail("Should present a safari web view controller.")
}
}

flow.start(in: rootViewController)
waitForExpectations(timeout: 1.0, handler: nil)
}

func testAppSwitchingObserver() {
let expect = expectation(description: "\(#file)_\(#line)")
let observer = LoginProcess.AppSwitchingObserver()
Expand Down

0 comments on commit 5da9db4

Please sign in to comment.