From cebd1a19232f06ce33d3f619863e9e1b6ca4f120 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Tue, 16 Jul 2024 17:11:06 -0300 Subject: [PATCH 01/63] Create NetworkHelper --- Example/Tests/NetworkHelperTests.swift | 133 ++++++++++++++++++ Example/TrustlySDK.xcodeproj/project.pbxproj | 66 +++++---- .../TrustlySDK/Helpers/NetworkHelper.swift | 62 ++++++++ 3 files changed, 230 insertions(+), 31 deletions(-) create mode 100644 Example/Tests/NetworkHelperTests.swift create mode 100644 Sources/TrustlySDK/Helpers/NetworkHelper.swift diff --git a/Example/Tests/NetworkHelperTests.swift b/Example/Tests/NetworkHelperTests.swift new file mode 100644 index 0000000..bdcd39a --- /dev/null +++ b/Example/Tests/NetworkHelperTests.swift @@ -0,0 +1,133 @@ +// +// NetworkHelperTests.swift +// TrustlySDK_Tests +// +// Created by Marcos Rivereto on 16/07/24. +// Copyright © 2024 CocoaPods. All rights reserved. +// + +import XCTest +@testable import TrustlySDK + +final class NetworkHelperTests: XCTestCase { + + override func setUpWithError() throws { + } + + override func tearDownWithError() throws { + + } + + func testIsLocalEnvironment() throws { + + var expectedResult = true + + var result = isLocalUrl(environment: "local") + + XCTAssertEqual(expectedResult, result) + + expectedResult = false + + result = isLocalUrl(environment: "sandbox") + + XCTAssertEqual(expectedResult, result) + } + + func testThrowsInvalidUrlError() throws { + + XCTAssertThrowsError(try buildEnvironment( + function: "widget", + environment: "", + localUrl: "", + paymentType: "Retrieval", + build: "3.2.2" + )) { error in + XCTAssertEqual(error as! NetworkError, NetworkError.invalidUrl) + } + } + + func testBuildLocalEnvironment() throws { + + let environment = try buildEnvironment( + function: "widget", + environment: "local", + localUrl: "192.168.0.1", + paymentType: "Retrieval", + build: "3.2.2" + ) + + let expectedIsLocal = true + let expectedUrl = URL(string: "http://192.168.0.1:8000/start/selectBank/widget?v=3.2.2-ios-sdk")! + + XCTAssertEqual(expectedIsLocal, environment.isLocal) + XCTAssertEqual(expectedUrl, environment.url) + } + + func testBuildLocalHostEnvironment() throws { + + let environment = try buildEnvironment( + function: "widget", + environment: "local", + localUrl: "", + paymentType: "Retrieval", + build: "3.2.2" + ) + + let expectedIsLocal = true + let expectedUrl = URL(string: "http://localhost:8000/start/selectBank/widget?v=3.2.2-ios-sdk")! + + XCTAssertEqual(expectedIsLocal, environment.isLocal) + XCTAssertEqual(expectedUrl, environment.url) + } + + func testBuildDynamicEnvironment() throws { + + let environment = try buildEnvironment( + function: "widget", + environment: "dynamic", + localUrl: "trustlyTest", + paymentType: "Retrieval", + build: "3.2.2" + ) + + let expectedIsLocal = false + let expectedUrl = URL(string: "https://trustlyTest.int.trustly.one/start/selectBank/widget?v=3.2.2-ios-sdk")! + + XCTAssertEqual(expectedIsLocal, environment.isLocal) + XCTAssertEqual(expectedUrl, environment.url) + } + + func testBuildSandboxEnvironment() throws { + + let environment = try buildEnvironment( + function: "widget", + environment: "sandbox", + localUrl: "", + paymentType: "Retrieval", + build: "3.2.2" + ) + + let expectedIsLocal = false + let expectedUrl = URL(string: "https://sandbox.paywithmybank.com/start/selectBank/widget?v=3.2.2-ios-sdk")! + + XCTAssertEqual(expectedIsLocal, environment.isLocal) + XCTAssertEqual(expectedUrl, environment.url) + } + + func testBuildProductionEnvironment() throws { + + let environment = try buildEnvironment( + function: "widget", + environment: "", + localUrl: "", + paymentType: "Retrieval", + build: "3.2.2" + ) + + let expectedIsLocal = false + let expectedUrl = URL(string: "https://paywithmybank.com/start/selectBank/widget?v=3.2.2-ios-sdk")! + + XCTAssertEqual(expectedIsLocal, environment.isLocal) + XCTAssertEqual(expectedUrl, environment.url) + } +} diff --git a/Example/TrustlySDK.xcodeproj/project.pbxproj b/Example/TrustlySDK.xcodeproj/project.pbxproj index edd63bb..b4ef80b 100644 --- a/Example/TrustlySDK.xcodeproj/project.pbxproj +++ b/Example/TrustlySDK.xcodeproj/project.pbxproj @@ -10,13 +10,14 @@ 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */; }; 15987B0929DEF79D00D7A395 /* TrustlyLightBoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15987B0829DEF79D00D7A395 /* TrustlyLightBoxViewController.swift */; }; 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */; }; + 15D96FB32C46E6B700296BC4 /* NetworkHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D96FB22C46E6B700296BC4 /* NetworkHelperTests.swift */; }; + 340657DFE7244067A8F33A0D /* Pods_TrustlySDK_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C63286550C0E975AC9573DF /* Pods_TrustlySDK_Example.framework */; }; 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; - 6BACCDB4604ECDF537904C79 /* Pods_TrustlySDK_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4425929EEE562201E9CA4EEC /* Pods_TrustlySDK_Tests.framework */; }; - A086097EF9B9D26BB68DDA77 /* Pods_TrustlySDK_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24C6055BF6640A73038BF66E /* Pods_TrustlySDK_Example.framework */; }; + EAA849D68ABE2A9FE8DEE76D /* Pods_TrustlySDK_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4225824F0F3C24EF9803BCD1 /* Pods_TrustlySDK_Tests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -30,14 +31,16 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 007648E5463CB8D6E576A917 /* Pods-TrustlySDK_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Tests.debug.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Tests/Pods-TrustlySDK_Tests.debug.xcconfig"; sourceTree = ""; }; + 06A59A0ECC7F2C369392E6A5 /* Pods-TrustlySDK_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Example.release.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Example/Pods-TrustlySDK_Example.release.xcconfig"; sourceTree = ""; }; + 080249A29F70B36248BD8984 /* Pods-TrustlySDK_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Example.debug.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Example/Pods-TrustlySDK_Example.debug.xcconfig"; sourceTree = ""; }; + 10C7972A664657BB9F51ED82 /* Pods-TrustlySDK_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Tests.release.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Tests/Pods-TrustlySDK_Tests.release.xcconfig"; sourceTree = ""; }; 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManagerTests.swift; sourceTree = ""; }; 15987B0829DEF79D00D7A395 /* TrustlyLightBoxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustlyLightBoxViewController.swift; sourceTree = ""; }; 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidationHelperTests.swift; sourceTree = ""; }; + 15D96FB22C46E6B700296BC4 /* NetworkHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkHelperTests.swift; sourceTree = ""; }; 2416E32056EECA07B4C86E1B /* TrustlySDK.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = TrustlySDK.podspec; path = ../TrustlySDK.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 24C6055BF6640A73038BF66E /* Pods_TrustlySDK_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustlySDK_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 38845E178FF73A019452105E /* Pods-TrustlySDK_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Tests.debug.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Tests/Pods-TrustlySDK_Tests.debug.xcconfig"; sourceTree = ""; }; - 4374DB88B53812152BC15F73 /* Pods-TrustlySDK_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Tests.release.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Tests/Pods-TrustlySDK_Tests.release.xcconfig"; sourceTree = ""; }; - 4425929EEE562201E9CA4EEC /* Pods_TrustlySDK_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustlySDK_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4225824F0F3C24EF9803BCD1 /* Pods_TrustlySDK_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustlySDK_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50EFC16F37CBC7AAB7A131C5 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 607FACD01AFB9204008FA782 /* TrustlySDK_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TrustlySDK_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -48,8 +51,7 @@ 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 607FACE51AFB9204008FA782 /* TrustlySDK_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrustlySDK_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - E4A893CD7E4194BD1860A4BF /* Pods-TrustlySDK_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Example.debug.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Example/Pods-TrustlySDK_Example.debug.xcconfig"; sourceTree = ""; }; - F6B3BBFE7E8396C2B1D558CB /* Pods-TrustlySDK_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Example.release.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Example/Pods-TrustlySDK_Example.release.xcconfig"; sourceTree = ""; }; + 9C63286550C0E975AC9573DF /* Pods_TrustlySDK_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustlySDK_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F72862DF6A4016E58E06BEDD /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; /* End PBXFileReference section */ @@ -58,7 +60,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A086097EF9B9D26BB68DDA77 /* Pods_TrustlySDK_Example.framework in Frameworks */, + 340657DFE7244067A8F33A0D /* Pods_TrustlySDK_Example.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -66,7 +68,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6BACCDB4604ECDF537904C79 /* Pods_TrustlySDK_Tests.framework in Frameworks */, + EAA849D68ABE2A9FE8DEE76D /* Pods_TrustlySDK_Tests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -77,6 +79,7 @@ isa = PBXGroup; children = ( 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */, + 15D96FB22C46E6B700296BC4 /* NetworkHelperTests.swift */, ); name = Helpers; sourceTree = ""; @@ -89,7 +92,7 @@ 607FACE81AFB9204008FA782 /* Tests */, 607FACD11AFB9204008FA782 /* Products */, 73C0574CF1D12D0640026299 /* Pods */, - 6F76060C4BEB86C115EBDDAE /* Frameworks */, + B3D0888992DAE88957E6F72F /* Frameworks */, ); sourceTree = ""; }; @@ -153,24 +156,24 @@ name = "Podspec Metadata"; sourceTree = ""; }; - 6F76060C4BEB86C115EBDDAE /* Frameworks */ = { + 73C0574CF1D12D0640026299 /* Pods */ = { isa = PBXGroup; children = ( - 24C6055BF6640A73038BF66E /* Pods_TrustlySDK_Example.framework */, - 4425929EEE562201E9CA4EEC /* Pods_TrustlySDK_Tests.framework */, + 080249A29F70B36248BD8984 /* Pods-TrustlySDK_Example.debug.xcconfig */, + 06A59A0ECC7F2C369392E6A5 /* Pods-TrustlySDK_Example.release.xcconfig */, + 007648E5463CB8D6E576A917 /* Pods-TrustlySDK_Tests.debug.xcconfig */, + 10C7972A664657BB9F51ED82 /* Pods-TrustlySDK_Tests.release.xcconfig */, ); - name = Frameworks; + path = Pods; sourceTree = ""; }; - 73C0574CF1D12D0640026299 /* Pods */ = { + B3D0888992DAE88957E6F72F /* Frameworks */ = { isa = PBXGroup; children = ( - E4A893CD7E4194BD1860A4BF /* Pods-TrustlySDK_Example.debug.xcconfig */, - F6B3BBFE7E8396C2B1D558CB /* Pods-TrustlySDK_Example.release.xcconfig */, - 38845E178FF73A019452105E /* Pods-TrustlySDK_Tests.debug.xcconfig */, - 4374DB88B53812152BC15F73 /* Pods-TrustlySDK_Tests.release.xcconfig */, + 9C63286550C0E975AC9573DF /* Pods_TrustlySDK_Example.framework */, + 4225824F0F3C24EF9803BCD1 /* Pods_TrustlySDK_Tests.framework */, ); - path = Pods; + name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ @@ -180,11 +183,11 @@ isa = PBXNativeTarget; buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "TrustlySDK_Example" */; buildPhases = ( - E90016EDF08FB3DCC19102F1 /* [CP] Check Pods Manifest.lock */, + 4C1123B0A9B63FEEE253549C /* [CP] Check Pods Manifest.lock */, 607FACCC1AFB9204008FA782 /* Sources */, 607FACCD1AFB9204008FA782 /* Frameworks */, 607FACCE1AFB9204008FA782 /* Resources */, - 63B59E6FC13D7828E4A76443 /* [CP] Embed Pods Frameworks */, + 3F913F740053A38AA729CF9E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -199,7 +202,7 @@ isa = PBXNativeTarget; buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "TrustlySDK_Tests" */; buildPhases = ( - 1EF00209D977EB1E4795E902 /* [CP] Check Pods Manifest.lock */, + 34541602E1F2C59451CB248A /* [CP] Check Pods Manifest.lock */, 607FACE11AFB9204008FA782 /* Sources */, 607FACE21AFB9204008FA782 /* Frameworks */, 607FACE31AFB9204008FA782 /* Resources */, @@ -278,7 +281,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1EF00209D977EB1E4795E902 /* [CP] Check Pods Manifest.lock */ = { + 34541602E1F2C59451CB248A /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -300,7 +303,7 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 63B59E6FC13D7828E4A76443 /* [CP] Embed Pods Frameworks */ = { + 3F913F740053A38AA729CF9E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -318,7 +321,7 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TrustlySDK_Example/Pods-TrustlySDK_Example-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - E90016EDF08FB3DCC19102F1 /* [CP] Check Pods Manifest.lock */ = { + 4C1123B0A9B63FEEE253549C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -359,6 +362,7 @@ files = ( 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */, 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */, + 15D96FB32C46E6B700296BC4 /* NetworkHelperTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -506,7 +510,7 @@ }; 607FACF01AFB9204008FA782 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E4A893CD7E4194BD1860A4BF /* Pods-TrustlySDK_Example.debug.xcconfig */; + baseConfigurationReference = 080249A29F70B36248BD8984 /* Pods-TrustlySDK_Example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 935WTYE9VM; @@ -526,7 +530,7 @@ }; 607FACF11AFB9204008FA782 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F6B3BBFE7E8396C2B1D558CB /* Pods-TrustlySDK_Example.release.xcconfig */; + baseConfigurationReference = 06A59A0ECC7F2C369392E6A5 /* Pods-TrustlySDK_Example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 935WTYE9VM; @@ -546,7 +550,7 @@ }; 607FACF31AFB9204008FA782 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 38845E178FF73A019452105E /* Pods-TrustlySDK_Tests.debug.xcconfig */; + baseConfigurationReference = 007648E5463CB8D6E576A917 /* Pods-TrustlySDK_Tests.debug.xcconfig */; buildSettings = { DEVELOPMENT_TEAM = 935WTYE9VM; FRAMEWORK_SEARCH_PATHS = ( @@ -574,7 +578,7 @@ }; 607FACF41AFB9204008FA782 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4374DB88B53812152BC15F73 /* Pods-TrustlySDK_Tests.release.xcconfig */; + baseConfigurationReference = 10C7972A664657BB9F51ED82 /* Pods-TrustlySDK_Tests.release.xcconfig */; buildSettings = { DEVELOPMENT_TEAM = 935WTYE9VM; FRAMEWORK_SEARCH_PATHS = ( diff --git a/Sources/TrustlySDK/Helpers/NetworkHelper.swift b/Sources/TrustlySDK/Helpers/NetworkHelper.swift new file mode 100644 index 0000000..03e3fb3 --- /dev/null +++ b/Sources/TrustlySDK/Helpers/NetworkHelper.swift @@ -0,0 +1,62 @@ +// +// NetworkHelper.swift +// TrustlySDK +// +// Created by Marcos Rivereto on 16/07/24. +// + +import Foundation + +enum NetworkError: Error { + case invalidUrl +} + +/** @abstract Get all informations to build the correct environment informations. + @param function: String + @param environment: String + @param localUrl: String + @param paymentType: String + @param build: String + @throws NetworkError.invalidUrl + @result (url: URL, isLocal: Bool) + */ +func buildEnvironment(function: String, environment: String, localUrl: String, paymentType: String, build: String) throws -> (url: URL, isLocal: Bool) { + var fn = function + var subDomain = "" + var urlString = "" + + if !environment.isEmpty { + subDomain = String(format:"%@.", environment) + } + + if "index" == fn && + "Verification" != paymentType { + fn = "selectBank" + } + + if isLocalUrl(environment: environment) { + let domain = localUrl.isEmpty ? "localhost" : localUrl + urlString = "http://\(domain):8000/start/selectBank/\(fn)?v=\(build)-ios-sdk" + + } else if (environment == "dynamic") { + urlString = "https://\(localUrl).int.trustly.one/start/selectBank/\(fn)?v=\(build)-ios-sdk" + + } else { + urlString = "https://\(subDomain)paywithmybank.com/start/selectBank/\(fn)?v=\(build)-ios-sdk" + } + + guard let url = URL(string: urlString) else { + print("Invalid url: \(urlString)") + throw NetworkError.invalidUrl + } + + return (url: url, isLocal: isLocalUrl(environment: environment)) +} + +/** @abstract Validate if we are handling with local environment. + @param environment: String + @result Bool + */ +func isLocalUrl(environment: String) -> Bool { + return !environment.isEmpty && "local" == environment +} From 2476e33fb3a7387dce9860a5d1747a8face0a145 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Tue, 16 Jul 2024 17:12:24 -0300 Subject: [PATCH 02/63] Change getEndpointUrl for buildEnvironment --- Sources/TrustlySDK/TrustlyView.swift | 125 ++++++++++++++------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 206f7bc..68427b7 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -164,17 +164,31 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri bankSelectedHandler = onBankSelected - let url = getEndpointUrl(function: "widget", establishData:establishData as! [String : String]) + "&" + urlEncoded(query) + "#" + urlEncoded(hash) - var request = URLRequest(url: URL(string: url)!) + do { + let environment = try buildEnvironment( + function: "widget", + environment: (eD["env"] ?? "") as! String, + localUrl: (eD["localUrl"] ?? "") as! String, + paymentType: (eD["paymentType"] ?? "") as! String, + build: build + ) + + isLocalEnvironment = environment.isLocal + + var request = URLRequest(url: environment.url) - request.httpMethod = "GET" - request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField:"Accept") + request.httpMethod = "GET" + request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField:"Accept") - self.notifyEvent("widget", "loading") + self.notifyEvent("widget", "loading") - self.mainWebView!.tag = WidgetView - self.mainWebView!.load(request) + self.mainWebView!.tag = WidgetView + self.mainWebView!.load(request) + } catch { + print("Unexpected error: \(error).") + } + return self } @@ -214,38 +228,52 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri returnHandler = onReturn cancelHandler = onCancel externalUrlHandler = nil + + do { + let environment = try buildEnvironment( + function: "index", + environment: (eD["env"] ?? "") as! String, + localUrl: (eD["localUrl"] ?? "") as! String, + paymentType: (eD["paymentType"] ?? "") as! String, + build: build + ) + + isLocalEnvironment = environment.isLocal + + var request = URLRequest(url: environment.url) - let url = getEndpointUrl(function: "index", establishData:establishData! as! [String:String]) - var request = URLRequest(url: URL(string: url)!) - - request.httpMethod = "POST" - request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField:"Accept") - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type") + request.httpMethod = "POST" + request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField:"Accept") + request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type") - let requestData = urlEncoded(establishData!).data(using: .utf8) + let requestData = urlEncoded(establishData!).data(using: .utf8) - request.setValue(String(format:"%lu", requestData!.count), forHTTPHeaderField:"Content-Length") - request.httpBody = requestData - - let semaphore = DispatchSemaphore(value:0) - - var httpData:Data? - var response:URLResponse? - var error:Error? - URLSession.shared.dataTask(with: request) { (data, resp, err) in - httpData = data - response = resp - error = err - semaphore.signal() - }.resume() - - semaphore.wait() - - if(error == nil){ - self.mainWebView?.load(httpData!, mimeType:"text/html", characterEncodingName:"UTF-8", baseURL: (response?.url)!) - } else { - self.cancelHandler!(self, [:]) + request.setValue(String(format:"%lu", requestData!.count), forHTTPHeaderField:"Content-Length") + request.httpBody = requestData + + let semaphore = DispatchSemaphore(value:0) + + var httpData:Data? + var response:URLResponse? + var error:Error? + URLSession.shared.dataTask(with: request) { (data, resp, err) in + httpData = data + response = resp + error = err + semaphore.signal() + }.resume() + + semaphore.wait() + + if(error == nil){ + self.mainWebView?.load(httpData!, mimeType:"text/html", characterEncodingName:"UTF-8", baseURL: (response?.url)!) + } else { + self.cancelHandler!(self, [:]) + } + } catch { + print("Unexpected error: \(error).") } + return self } @@ -485,33 +513,6 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri } } - func getEndpointUrl(function:String, establishData:[String:String]) -> String { - var fn = function - let env = establishData["env"] - let localUrl = establishData["localUrl"] - var subDomain = "" - var url:String - - if env != nil && env!.count > 0 { - subDomain = String(format:"%@.", env!) - } - - if "index" == fn && - "Verification" != establishData["paymentType"] && - establishData["paymentType"] != nil { - fn = "selectBank" - } - - if ("local" == env), let urlLocal = localUrl { - url = "http://"+urlLocal+"/start/selectBank/"+fn+"?v="+build+"-ios-sdk" - isLocalEnvironment = true - - } else { - url = "https://"+subDomain+"paywithmybank.com/start/selectBank/"+fn+"?v="+build+"-ios-sdk" - } - return url - } - func parametersForUrl(_ url:URL) -> [AnyHashable : Any] { let absoluteString = url.absoluteString var queryStringDictionary = [String : String]() From 3e8ad6be05e8f32b8e490e2e48a018e5296817f4 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Tue, 16 Jul 2024 17:12:32 -0300 Subject: [PATCH 03/63] Update Podfile.lock --- Example/Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 38cfc5c..996419d 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - TrustlySDK (3.2.1) + - TrustlySDK (3.2.2) DEPENDENCIES: - TrustlySDK (from `../`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - TrustlySDK: 8426a3ec86b7ea314fe593401912fab9d7a68db1 + TrustlySDK: 507ad3f6d631c120bf1cfc1ff366060fb7aced7e PODFILE CHECKSUM: 2d88e8d6e29e33aaa64b36a8d0e73ac21b25b6ba From ef5057fbeb4d66e5f2b569a1413c81e3b09a604d Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Tue, 16 Jul 2024 17:13:13 -0300 Subject: [PATCH 04/63] Fix xcode warning --- Example/TrustlySDK/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/TrustlySDK/ViewController.swift b/Example/TrustlySDK/ViewController.swift index a89e1a8..92eebca 100644 --- a/Example/TrustlySDK/ViewController.swift +++ b/Example/TrustlySDK/ViewController.swift @@ -40,7 +40,7 @@ class ViewController: UIViewController { print("onChangeListener: \(eventName) \(attributes)") } - self.trustlyView.selectBankWidget(establishData: establishData) { (view, data) in + let _ = self.trustlyView.selectBankWidget(establishData: establishData) { (view, data) in print("returnParameters:\(data)") self.establishData = data } From b729f0c59cccef98f220ba73f545916db04527bf Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 22 Jul 2024 10:13:01 -0300 Subject: [PATCH 05/63] Move auxiliary functions to NetworkHelper --- Example/Tests/NetworkHelperTests.swift | 23 +++++++++++ .../TrustlySDK/Helpers/NetworkHelper.swift | 35 +++++++++++++++++ Sources/TrustlySDK/TrustlyView.swift | 38 ++----------------- 3 files changed, 62 insertions(+), 34 deletions(-) diff --git a/Example/Tests/NetworkHelperTests.swift b/Example/Tests/NetworkHelperTests.swift index bdcd39a..21cc7db 100644 --- a/Example/Tests/NetworkHelperTests.swift +++ b/Example/Tests/NetworkHelperTests.swift @@ -130,4 +130,27 @@ final class NetworkHelperTests: XCTestCase { XCTAssertEqual(expectedIsLocal, environment.isLocal) XCTAssertEqual(expectedUrl, environment.url) } + + func testUrlEncoded() throws { + + let data:[AnyHashable : Any] = [ + "param1": "\nvalue1" + ] + + let expectedResult = "param1=%0Avalue1" + let result = urlEncoded(data) + + XCTAssertEqual(expectedResult, result) + } + + func testUrlDecoded() throws { + + let content = "%0Avalue1" + + let result = urlDecode(content) + + let expectedResult = "\nvalue1" + + XCTAssertEqual(expectedResult, result) + } } diff --git a/Sources/TrustlySDK/Helpers/NetworkHelper.swift b/Sources/TrustlySDK/Helpers/NetworkHelper.swift index 03e3fb3..8bcba53 100644 --- a/Sources/TrustlySDK/Helpers/NetworkHelper.swift +++ b/Sources/TrustlySDK/Helpers/NetworkHelper.swift @@ -60,3 +60,38 @@ func buildEnvironment(function: String, environment: String, localUrl: String, p func isLocalUrl(environment: String) -> Bool { return !environment.isEmpty && "local" == environment } + +/** @abstract Merge, format and encode all parameters. + @param data:[AnyHashable : Any] + @result String + */ +func urlEncoded(_ data:[AnyHashable : Any]) -> String { + var parts = [String]() + for (key,value) in data { + let part = String(format:"%@=%@", urlEncode(key), urlEncode(value)) + parts.append(part) + } + return parts.joined(separator: "&") +} + +/** @abstract Remove all Percent encoding. + @param object: Any + @result String + */ +func urlDecode(_ object: Any) -> String { + guard let str = object as? String else { return "" } + + return str.removingPercentEncoding ?? "" +} + +/** @abstract Add all Percent encoding. + @param object: Any + @result String + */ +private func urlEncode(_ object: Any) -> String { + guard let str = object as? String else { return "" } + + let set = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-._~") + + return str.addingPercentEncoding(withAllowedCharacters: set) ?? "" +} diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 68427b7..e3f7354 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -461,10 +461,10 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri //messages switch(host){ case "push": - let params = self.urlDecode(query)?.components(separatedBy: "|") - if ("PayWithMyBank.createTransaction" == params?[0]) && bankSelectedHandler != nil { - if params?.count ?? 0 > 1 { - establishData?["paymentProviderId"] = params?[1] + let params = urlDecode(query).components(separatedBy: "|") + if ("PayWithMyBank.createTransaction" == params[0]) && bankSelectedHandler != nil { + if params.count > 1 { + establishData?["paymentProviderId"] = params[1] } if let establishData = establishData { @@ -557,36 +557,6 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri return grp } - private func toString(_ object: Any?) -> String? { - if let object = object { - return "\(object)" - } - return nil - } - - private func urlEncode(_ object: Any?) -> String? { - let str = toString(object) - let set = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-._~") - - return str?.addingPercentEncoding(withAllowedCharacters: set) - } - - private func urlDecode(_ object: Any?) -> String? { - let string = toString(object) - - return string?.removingPercentEncoding - } - - - func urlEncoded(_ data:[AnyHashable : Any?]) -> String! { - var parts = [String]() - for (key,value) in data { - let part = String(format:"%@=%@", urlEncode(key)!, urlEncode(value)!) - parts.append(part) - } - return parts.joined(separator: "&") - } - private func addSessionCid() { self.establishData?["sessionCid"] = sessionCid From 1772eca88d202f99cb086c8dea03fc1799f15d33 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 22 Jul 2024 10:13:17 -0300 Subject: [PATCH 06/63] Remove comment code --- Sources/TrustlySDK/TrustlyView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index e3f7354..9c76260 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -438,7 +438,6 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri let request = navigationAction.request let targetFrame = navigationAction.targetFrame; let host = request.url?.host - //let relative = request.url?.relativePath ?? "" let query = request.url?.query ?? "" let scheme = request.url?.scheme ?? "" let absolute = request.url?.absoluteString From 60b639424da6f13664da3abd817575b6a61d4c09 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 22 Jul 2024 10:42:58 -0300 Subject: [PATCH 07/63] Add query and hash to build environment --- Sources/TrustlySDK/Helpers/NetworkHelper.swift | 10 +++++++++- Sources/TrustlySDK/TrustlyView.swift | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Sources/TrustlySDK/Helpers/NetworkHelper.swift b/Sources/TrustlySDK/Helpers/NetworkHelper.swift index 8bcba53..32026f7 100644 --- a/Sources/TrustlySDK/Helpers/NetworkHelper.swift +++ b/Sources/TrustlySDK/Helpers/NetworkHelper.swift @@ -20,7 +20,7 @@ enum NetworkError: Error { @throws NetworkError.invalidUrl @result (url: URL, isLocal: Bool) */ -func buildEnvironment(function: String, environment: String, localUrl: String, paymentType: String, build: String) throws -> (url: URL, isLocal: Bool) { +func buildEnvironment(function: String, environment: String, localUrl: String, paymentType: String, build: String, query: [String : Any]? = nil, hash: [String : Any]? = nil) throws -> (url: URL, isLocal: Bool) { var fn = function var subDomain = "" var urlString = "" @@ -45,6 +45,14 @@ func buildEnvironment(function: String, environment: String, localUrl: String, p urlString = "https://\(subDomain)paywithmybank.com/start/selectBank/\(fn)?v=\(build)-ios-sdk" } + if let query = query { + urlString = "\(urlString)&\(urlEncoded(query))" + } + + if let hash = hash { + urlString = "\(urlString)#\(urlEncoded(hash))" + } + guard let url = URL(string: urlString) else { print("Invalid url: \(urlString)") throw NetworkError.invalidUrl diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 9c76260..b500c40 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -170,7 +170,9 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri environment: (eD["env"] ?? "") as! String, localUrl: (eD["localUrl"] ?? "") as! String, paymentType: (eD["paymentType"] ?? "") as! String, - build: build + build: build, + query: query, + hash: hash ) isLocalEnvironment = environment.isLocal From 9e321f627bdf70b3794631520b0fe71a4f8c1063 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 22 Jul 2024 10:47:59 -0300 Subject: [PATCH 08/63] Fix xcode warning --- Example/TrustlySDK/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/TrustlySDK/ViewController.swift b/Example/TrustlySDK/ViewController.swift index 92eebca..8f1decd 100644 --- a/Example/TrustlySDK/ViewController.swift +++ b/Example/TrustlySDK/ViewController.swift @@ -85,7 +85,7 @@ extension ViewController: TrustlyLightboxViewProtocol { // MARK: - Alert functions private func showAlert(title: String, message: String){ - var dialogMessage = UIAlertController(title: title, message: message, preferredStyle: .alert) + let dialogMessage = UIAlertController(title: title, message: message, preferredStyle: .alert) // Create OK button with action handler let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in From ea45339906da296f5c5d90069c52c77a036bde76 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 22 Jul 2024 10:54:22 -0300 Subject: [PATCH 09/63] Update version to 3.2.3 --- README.md | 1 + Sources/TrustlySDK/TrustlyView.swift | 2 +- TrustlySDK.podspec | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index adc0c7a..95511b9 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ ___ | VERSION | DESCRIPTION | BRANCH | | :-------: | :----------- | :----------- | +3.2.3 | Fix a bug when we try to send an establish data with an array value | *main* 3.2.2 | Fix a bug when we try to check if the sdk is loading a error page(400 and 500) | *main* 3.2.1 | Prepare the sdk to support Buck build system | *main* 3.2.0 | Add PrivacyInfo.xcprivacy | *main* diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index b500c40..4be80d3 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -35,7 +35,7 @@ let NavBarHeight:Int = 26 let NavBarIconWidth:Int = 10 let NavBarIconHeight:Int = 10 -let build = "3.2.2" +let build = "3.2.3" let CloseIconBase64:String! = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAG1SURBVHgB3diLTcNADAZgpxOUBVA6CYzQDdoRGMETABMAG8AEVUdggmaDdoMYn5KTQlSau8RnW/ySVUWyo/sa9XEH8E9SDS+IaM0vO647rmNVVUdwFF5feAlr3HLVXN+8xq9x047rQr/zAk4SEFwbrma0xhNXHZvqK4iYdzDODUTMITbu6XbMMAmIkHbV968n7re3wFD3mdhwhXe8Thl4pLSoYRKfRMxpOPhBaSmOyUS0XLvxDcwxmYgQ/OtGZhgxhCVGHGGBKYbQxBRHaGDUECUx6ogSGDOEJMYcIYFxg1iKcYWYi6Fuz9MkziBoJgPz6RYxA+MXIYxB8JCFGARPmYlB8JhMDIJQViAY6s6XHjJG7sFTKP8Xe5g38JCFCB8YIYQtRhhhg5mBQEr/NtPB0IK/4m4wtHA/wdeVOYaENkWmGBLe2ZlgqND2VBVDhffYKhhSOigoiiHl044iGDI6shHFkPG5kwjGGiGG8YBYjKHuaTSJgwgKycQ8x6Ft4gCCYjIw5ziACc0IBknEtLF56okgGCYB0w6bT9carBExExgcNtZch37xoc5cT+AoPeZ1ALhExA8NsASbTxPzlwAAAABJRU5ErkJggg==" diff --git a/TrustlySDK.podspec b/TrustlySDK.podspec index c1718f9..01c45db 100644 --- a/TrustlySDK.podspec +++ b/TrustlySDK.podspec @@ -9,7 +9,7 @@ Pod::Spec.new do |s| s.name = 'TrustlySDK' - s.version = '3.2.2' + s.version = '3.2.3' s.summary = 'This SDK help the merchants to integrate their solutions with Trustly Widget and LightBox.' s.swift_version = '5.0' From b42398a8600c5f3a8669a2a5fad2d13e2ea02cda Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 5 Aug 2024 10:12:36 -0300 Subject: [PATCH 10/63] Move hard coded strings to Constants file --- Sources/TrustlySDK/TrustlyView.swift | 15 ++++++++------- TrustlySDKConstants.swift | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 TrustlySDKConstants.swift diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 4be80d3..0438db8 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -54,8 +54,8 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri private var changeListenerHandler:TrustlyListenerCallback? private var establishData:[AnyHashable : Any]? private var mainWebView:WKWebView! - private var returnUrl = "msg://return" - private var cancelUrl = "msg://cancel" + private var returnUrl = Constants.RETURN_URL + private var cancelUrl = Constants.CANCEL_URL private var urlScheme = "" private var webSession: ASWebAuthenticationSession! private var baseUrls = ["paywithmybank.com", "trustly.one"] @@ -199,8 +199,9 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri self.addSessionCid() - let deviceType = establishData?["deviceType"] ?? "mobile" + ":ios:native" + let deviceType = "\(establishData?["deviceType"] ?? Constants.DEVICE_TYPE):\(Constants.DEVICE_PLATFORM)" establishData?["deviceType"] = deviceType + if let lang = establishData?["metadata.lang"] as? String { establishData?["lang"] = lang } @@ -212,11 +213,11 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri } - returnUrl = "msg://return" + returnUrl = Constants.RETURN_URL establishData?["returnUrl"] = returnUrl - cancelUrl = "msg://cancel" + cancelUrl = Constants.CANCEL_URL establishData?["cancelUrl"] = cancelUrl - establishData?["version"] = "2" + establishData?["version"] = Constants.ESTABLISH_VERSION establishData?["grp"] = self.getGrp() if establishData?["paymentProviderId"] != nil { @@ -298,7 +299,7 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri public func verify(verifyData:[AnyHashable : Any], onReturn: TrustlyCallback?, onCancel: TrustlyCallback?) -> UIView? { var mutableDictionary = verifyData - mutableDictionary["paymentType"] = "Verification" + mutableDictionary["paymentType"] = Constants.PAYMENTTYPE_VERIFICATION return establish(establishData: mutableDictionary, onReturn:onReturn, onCancel:onCancel) } diff --git a/TrustlySDKConstants.swift b/TrustlySDKConstants.swift new file mode 100644 index 0000000..95779ee --- /dev/null +++ b/TrustlySDKConstants.swift @@ -0,0 +1,19 @@ +// +// TrustlySDKConstants.swift +// TrustlySDK +// +// Created by Marcos Rivereto on 01/08/24. +// + +import Foundation + + +class Constants { + static let RETURN_URL = "msg://return" + static let CANCEL_URL = "msg://cancel" + static let ESTABLISH_VERSION = "2" + static let DEVICE_TYPE = "mobile" + static let DEVICE_PLATFORM = "ios:native" + static let PAYMENTTYPE_VERIFICATION = "Verification" + +} From ebd42ce7bf94c3217fdd70b5433927db64b9e341 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 5 Aug 2024 11:26:39 -0300 Subject: [PATCH 11/63] Clean code --- Sources/TrustlySDK/TrustlyView.swift | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 0438db8..2aff3f3 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -24,20 +24,6 @@ func Rgb2UIColor(_ r: CGFloat, _ g: CGFloat, _ b: CGFloat) -> UIColor { } let WidgetView:Int = 100 - -let ExternalLinkViewTag:Int = 99 -let ExternalLinkTitleTag:Int = 98 -let ExternalLinkSubtitleTag:Int = 97 -let ExternalLinkWebViewTag:Int = 96 -let ExternalLinkPrintBtnTag:Int = 95 - -let NavBarHeight:Int = 26 -let NavBarIconWidth:Int = 10 -let NavBarIconHeight:Int = 10 - -let build = "3.2.3" - -let CloseIconBase64:String! = "iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAG1SURBVHgB3diLTcNADAZgpxOUBVA6CYzQDdoRGMETABMAG8AEVUdggmaDdoMYn5KTQlSau8RnW/ySVUWyo/sa9XEH8E9SDS+IaM0vO647rmNVVUdwFF5feAlr3HLVXN+8xq9x047rQr/zAk4SEFwbrma0xhNXHZvqK4iYdzDODUTMITbu6XbMMAmIkHbV968n7re3wFD3mdhwhXe8Thl4pLSoYRKfRMxpOPhBaSmOyUS0XLvxDcwxmYgQ/OtGZhgxhCVGHGGBKYbQxBRHaGDUECUx6ogSGDOEJMYcIYFxg1iKcYWYi6Fuz9MkziBoJgPz6RYxA+MXIYxB8JCFGARPmYlB8JhMDIJQViAY6s6XHjJG7sFTKP8Xe5g38JCFCB8YIYQtRhhhg5mBQEr/NtPB0IK/4m4wtHA/wdeVOYaENkWmGBLe2ZlgqND2VBVDhffYKhhSOigoiiHl044iGDI6shHFkPG5kwjGGiGG8YBYjKHuaTSJgwgKycQ8x6Ft4gCCYjIw5ziACc0IBknEtLF56okgGCYB0w6bT9carBExExgcNtZch37xoc5cT+AoPeZ1ALhExA8NsASbTxPzlwAAAABJRU5ErkJggg==" @available(iOS 12.0, *) public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate { @@ -78,7 +64,7 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri } - func notifyListener(_ eventName:String!, _ eventDetails:[AnyHashable : Any]!) { + private func notifyListener(_ eventName:String!, _ eventDetails:[AnyHashable : Any]!) { if(changeListenerHandler != nil) { changeListenerHandler!(eventName, eventDetails) } From 7598b7622319a60f22543e6f879fe6bc5d1d31b9 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 29 Jan 2024 14:40:04 -0300 Subject: [PATCH 12/63] Create class to handle with url treatment --- Example/Tests/URLUtilsTests.swift | 88 ++++++++++++++++++++ Example/TrustlySDK.xcodeproj/project.pbxproj | 11 +++ Sources/TrustlySDK/Utils/Constants.swift | 15 ++++ Sources/TrustlySDK/Utils/URLUtils.swift | 56 +++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 Example/Tests/URLUtilsTests.swift create mode 100644 Sources/TrustlySDK/Utils/Constants.swift create mode 100644 Sources/TrustlySDK/Utils/URLUtils.swift diff --git a/Example/Tests/URLUtilsTests.swift b/Example/Tests/URLUtilsTests.swift new file mode 100644 index 0000000..b94317f --- /dev/null +++ b/Example/Tests/URLUtilsTests.swift @@ -0,0 +1,88 @@ +// +// URLUtilsTests.swift +// TrustlySDK_Tests +// +// Created by Marcos Rivereto on 29/01/24. +// Copyright © 2024 CocoaPods. All rights reserved. +// + +import XCTest +@testable import TrustlySDK + +final class URLUtilsTests: XCTestCase { + + var establishData:Dictionary = [:] + + override func setUp() { + super.setUp() + + self.establishData = ["accessId": "A48B73F694C4C8EE6306", + "merchantId" : "110005514", + "currency" : "USD", + "amount" : "1.00", + "merchantReference" : "g:cac73df7-52b4-47d7-89d3-9628d4cfb65e", + "paymentType" : "Retrieval", + "returnUrl": "/returnUrl", + "cancelUrl": "/cancelUrl", + "requestSignature": "HT5mVOqBXa8ZlvgX2USmPeLns5o=", + "customer.name": "John IOS", + "customer.address.country": "US", + "metadata.urlScheme": "demoapp://", + "description": "First Data Mobile Test"] + } + + func testBuildEndpointUrlProdEnvironment() throws { + + let expectedUrlForWidget = "https://\(Constants.baseDomain)/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" + let expectedUrlForIndex = "https://\(Constants.baseDomain)/start/selectBank/selectBank?v=\(Constants.buildSDK)-ios-sdk" + + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + + XCTAssertEqual(expectedUrlForWidget, urlBuiltForWidget) + + let urlBuiltForIndex = try? URLUtils.buildEndpointUrl(function: "index", establishData: self.establishData as! [String : String]) + + XCTAssertEqual(expectedUrlForIndex, urlBuiltForIndex) + + } + + func testBuildEndpointUrlSubdomainEnvironment() throws { + + self.establishData["env"] = "sandbox" + + let expectedUrl = "https://sandbox.\(Constants.baseDomain)/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" + + + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + + XCTAssertEqual(expectedUrl, urlBuiltForWidget) + + } + + func testBuildEndpointUrlLocalEnvironmentWithOutLocalUrl() throws { + + self.establishData["env"] = "local" + + XCTAssertThrowsError(try URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String])) { error in + XCTAssertEqual(error as! TrustlyURLError, TrustlyURLError.missingLocalUrl) + } + } + + func testBuildEndpointUrlLocalEnvironment() throws { + + self.establishData["env"] = "local" + self.establishData["localUrl"] = "192.168.0.15:8000" + + XCTAssertNoThrow(try URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String])) + + let expectedUrl = "http://192.168.0.15:8000/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" + + + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + + XCTAssertEqual(expectedUrl, urlBuiltForWidget) + + } + +} + diff --git a/Example/TrustlySDK.xcodeproj/project.pbxproj b/Example/TrustlySDK.xcodeproj/project.pbxproj index b4ef80b..785e57e 100644 --- a/Example/TrustlySDK.xcodeproj/project.pbxproj +++ b/Example/TrustlySDK.xcodeproj/project.pbxproj @@ -12,6 +12,10 @@ 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */; }; 15D96FB32C46E6B700296BC4 /* NetworkHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D96FB22C46E6B700296BC4 /* NetworkHelperTests.swift */; }; 340657DFE7244067A8F33A0D /* Pods_TrustlySDK_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C63286550C0E975AC9573DF /* Pods_TrustlySDK_Example.framework */; }; + 15BB98602B68120100A9210B /* URLUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15BB985F2B68120100A9210B /* URLUtilsTests.swift */; }; + 15D5276929FBFCF4006BEAEC /* SuccessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D5276729FBFCF4006BEAEC /* SuccessViewController.swift */; }; + 15D5276A29FBFCF4006BEAEC /* SuccessViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 15D5276829FBFCF4006BEAEC /* SuccessViewController.xib */; }; + 15D5276C29FC016B006BEAEC /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D5276B29FC016B006BEAEC /* BaseViewController.swift */; }; 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; @@ -39,6 +43,11 @@ 15987B0829DEF79D00D7A395 /* TrustlyLightBoxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustlyLightBoxViewController.swift; sourceTree = ""; }; 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidationHelperTests.swift; sourceTree = ""; }; 15D96FB22C46E6B700296BC4 /* NetworkHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkHelperTests.swift; sourceTree = ""; }; + 15BB985F2B68120100A9210B /* URLUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLUtilsTests.swift; sourceTree = ""; }; + 15D5276029FAE84C006BEAEC /* TrustlySDK_Example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TrustlySDK_Example.entitlements; sourceTree = ""; }; + 15D5276729FBFCF4006BEAEC /* SuccessViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessViewController.swift; sourceTree = ""; }; + 15D5276829FBFCF4006BEAEC /* SuccessViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SuccessViewController.xib; sourceTree = ""; }; + 15D5276B29FC016B006BEAEC /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; }; 2416E32056EECA07B4C86E1B /* TrustlySDK.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = TrustlySDK.podspec; path = ../TrustlySDK.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 4225824F0F3C24EF9803BCD1 /* Pods_TrustlySDK_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustlySDK_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50EFC16F37CBC7AAB7A131C5 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; @@ -133,6 +142,7 @@ children = ( 15BEC9B22C383F3600050FB9 /* Helpers */, 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */, + 15BB985F2B68120100A9210B /* URLUtilsTests.swift */, 607FACE91AFB9204008FA782 /* Supporting Files */, ); path = Tests; @@ -363,6 +373,7 @@ 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */, 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */, 15D96FB32C46E6B700296BC4 /* NetworkHelperTests.swift in Sources */, + 15BB98602B68120100A9210B /* URLUtilsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/TrustlySDK/Utils/Constants.swift b/Sources/TrustlySDK/Utils/Constants.swift new file mode 100644 index 0000000..f1608c6 --- /dev/null +++ b/Sources/TrustlySDK/Utils/Constants.swift @@ -0,0 +1,15 @@ +// +// Constants.swift +// Pods-TrustlySDK_Example +// +// Created by Marcos Rivereto on 29/01/24. +// + +import Foundation + + +struct Constants { + static let buildSDK = "3.1.1" + static let baseDomain = "paywithmybank.com" + +} diff --git a/Sources/TrustlySDK/Utils/URLUtils.swift b/Sources/TrustlySDK/Utils/URLUtils.swift new file mode 100644 index 0000000..c0be555 --- /dev/null +++ b/Sources/TrustlySDK/Utils/URLUtils.swift @@ -0,0 +1,56 @@ +// +// URLUtils.swift +// TrustlySDK +// +// Created by Marcos Rivereto on 29/01/24. +// + +import Foundation + +enum TrustlyURLError: Error { + case missingLocalUrl +} + +struct URLUtils { + + static func buildEndpointUrl(function:String, establishData:[String:String]) throws -> String { + + var httpProtocol = "https" + var domain = Constants.baseDomain + var resource = function + + + if let environment = establishData["env"], !environment.isEmpty { + + if environment == "local" { + httpProtocol = "http" + + if let localUrl = establishData["localUrl"], !localUrl.isEmpty { + domain = localUrl + + } else { + print("Error: When env is local, you must provide the localUrl.") + throw TrustlyURLError.missingLocalUrl + } + + } else { + httpProtocol = "https" + domain = "\(environment).\(domain)" + } + } + + if "index" == resource && + "Verification" != establishData["paymentType"] && + establishData["paymentType"] != nil { + resource = "selectBank" + } + + + return buildStringUrl(httpProtocol: httpProtocol, domain: domain, resource: resource, build: Constants.buildSDK) + } + + private static func buildStringUrl(httpProtocol: String, domain: String, resource: String, build: String) -> String{ + return "\(httpProtocol)://\(domain)/start/selectBank/\(resource)?v=\(build)-ios-sdk" + } + +} From 9af8d94c93786aafbd5220dff929184d482ff5f7 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 29 Jan 2024 14:59:28 -0300 Subject: [PATCH 13/63] Remove unused print --- Sources/TrustlySDK/Utils/URLUtils.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/TrustlySDK/Utils/URLUtils.swift b/Sources/TrustlySDK/Utils/URLUtils.swift index c0be555..0964d56 100644 --- a/Sources/TrustlySDK/Utils/URLUtils.swift +++ b/Sources/TrustlySDK/Utils/URLUtils.swift @@ -29,7 +29,6 @@ struct URLUtils { domain = localUrl } else { - print("Error: When env is local, you must provide the localUrl.") throw TrustlyURLError.missingLocalUrl } From a07267b52f0eaffde4dc193e6c6ab14ab5a49c20 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 29 Jan 2024 15:02:33 -0300 Subject: [PATCH 14/63] Update selectBankWidget to use URLUtils --- Sources/TrustlySDK/TrustlyView.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 2aff3f3..3d9ed0b 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -164,6 +164,8 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri isLocalEnvironment = environment.isLocal var request = URLRequest(url: environment.url) + let url = try URLUtils.buildEndpointUrl(function: "widget", establishData: establishData as! [String : String]) + "&" + urlEncoded(query) + "#" + urlEncoded(hash) + var request = URLRequest(url: URL(string: url)!) request.httpMethod = "GET" request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField:"Accept") @@ -172,6 +174,13 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri self.mainWebView!.tag = WidgetView self.mainWebView!.load(request) + + } catch TrustlyURLError.missingLocalUrl { + print("Error: When env is local, you must provide the localUrl.") + + } catch { + print("Error: building url.") + } } catch { print("Unexpected error: \(error).") From e026f12ca867ac939167125b89cea6d69ce63aaf Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 1 Feb 2024 11:44:41 -0300 Subject: [PATCH 15/63] Add isLocalEnvironment flag in URLUtils --- Example/Tests/URLUtilsTests.swift | 17 +++++++++++++++++ Sources/TrustlySDK/TrustlyView.swift | 3 +-- Sources/TrustlySDK/Utils/URLUtils.swift | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Example/Tests/URLUtilsTests.swift b/Example/Tests/URLUtilsTests.swift index b94317f..d7e6912 100644 --- a/Example/Tests/URLUtilsTests.swift +++ b/Example/Tests/URLUtilsTests.swift @@ -83,6 +83,23 @@ final class URLUtilsTests: XCTestCase { XCTAssertEqual(expectedUrl, urlBuiltForWidget) } + + func testBuildEndpointUrlIsLocalEnvironmentFlag() throws { + + self.establishData["env"] = "local" + self.establishData["localUrl"] = "192.168.0.15:8000" + + XCTAssertNoThrow(try URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String])) + + let expectedUrl = "http://192.168.0.15:8000/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" + + + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + + XCTAssertEqual(expectedUrl, urlBuiltForWidget) + XCTAssertEqual(true, URLUtils.isLocalEnvironment) + + } } diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 3d9ed0b..55da2e2 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -45,7 +45,6 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri private var urlScheme = "" private var webSession: ASWebAuthenticationSession! private var baseUrls = ["paywithmybank.com", "trustly.one"] - private var isLocalEnvironment = false private let oauthLoginPath = "/oauth/login/" private var sessionCid = "ios wrong sessionCid" private var cid = "ios wrong cid" @@ -579,7 +578,7 @@ extension TrustlyView { let path = url.path //1.1: On the main view creates a new OAuth view (new WKWebview) and opens the URL there - if isLocalEnvironment || (self.checkUrl(host: host) && + if URLUtils.isLocalEnvironment || (self.checkUrl(host: host) && path.contains(self.oauthLoginPath)) { self.buildASWebAuthenticationSession(url: url, callbackURL: urlScheme) diff --git a/Sources/TrustlySDK/Utils/URLUtils.swift b/Sources/TrustlySDK/Utils/URLUtils.swift index 0964d56..6d95a21 100644 --- a/Sources/TrustlySDK/Utils/URLUtils.swift +++ b/Sources/TrustlySDK/Utils/URLUtils.swift @@ -12,6 +12,8 @@ enum TrustlyURLError: Error { } struct URLUtils { + + static var isLocalEnvironment = false static func buildEndpointUrl(function:String, establishData:[String:String]) throws -> String { @@ -23,6 +25,7 @@ struct URLUtils { if let environment = establishData["env"], !environment.isEmpty { if environment == "local" { + isLocalEnvironment = true httpProtocol = "http" if let localUrl = establishData["localUrl"], !localUrl.isEmpty { @@ -33,6 +36,7 @@ struct URLUtils { } } else { + isLocalEnvironment = false httpProtocol = "https" domain = "\(environment).\(domain)" } From 2d00d87b508668858b6bdb399ef84d16cbf7354b Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 1 Feb 2024 11:46:05 -0300 Subject: [PATCH 16/63] Change establish function to use URLUtils --- Sources/TrustlySDK/TrustlyView.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 55da2e2..49864ce 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -238,6 +238,9 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri isLocalEnvironment = environment.isLocal var request = URLRequest(url: environment.url) + let url = try URLUtils.buildEndpointUrl(function: "index", establishData: establishData as! [String : String]) + + var request = URLRequest(url: URL(string: url)!) request.httpMethod = "POST" request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField:"Accept") @@ -271,6 +274,15 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri print("Unexpected error: \(error).") } + + } catch TrustlyURLError.missingLocalUrl { + print("Error: When env is local, you must provide the localUrl.") + + } catch { + print("Error: building url.") + } + + return self } From d817955a85ef1980b81bb1b1ae07501d7e7bb326 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 5 Feb 2024 14:37:29 -0300 Subject: [PATCH 17/63] Change urlEncode to URLUtils --- Sources/TrustlySDK/TrustlyView.swift | 10 ++++---- Sources/TrustlySDK/Utils/URLUtils.swift | 32 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 49864ce..4a09879 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -246,7 +246,7 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri request.setValue("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", forHTTPHeaderField:"Accept") request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type") - let requestData = urlEncoded(establishData!).data(using: .utf8) + let requestData = URLUtils.urlEncoded(establishData!).data(using: .utf8) request.setValue(String(format:"%lu", requestData!.count), forHTTPHeaderField:"Content-Length") request.httpBody = requestData @@ -469,10 +469,10 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri //messages switch(host){ case "push": - let params = urlDecode(query).components(separatedBy: "|") - if ("PayWithMyBank.createTransaction" == params[0]) && bankSelectedHandler != nil { - if params.count > 1 { - establishData?["paymentProviderId"] = params[1] + let params = URLUtils.urlDecode(query)?.components(separatedBy: "|") + if ("PayWithMyBank.createTransaction" == params?[0]) && bankSelectedHandler != nil { + if params?.count ?? 0 > 1 { + establishData?["paymentProviderId"] = params?[1] } if let establishData = establishData { diff --git a/Sources/TrustlySDK/Utils/URLUtils.swift b/Sources/TrustlySDK/Utils/URLUtils.swift index 6d95a21..181e350 100644 --- a/Sources/TrustlySDK/Utils/URLUtils.swift +++ b/Sources/TrustlySDK/Utils/URLUtils.swift @@ -15,6 +15,7 @@ struct URLUtils { static var isLocalEnvironment = false + // MARK: Build url static func buildEndpointUrl(function:String, establishData:[String:String]) throws -> String { var httpProtocol = "https" @@ -56,4 +57,35 @@ struct URLUtils { return "\(httpProtocol)://\(domain)/start/selectBank/\(resource)?v=\(build)-ios-sdk" } + + // MARK: Encode url and parameters + static func urlEncoded(_ data:[AnyHashable : Any?]) -> String! { + var parts = [String]() + for (key,value) in data { + let part = String(format:"%@=%@", urlEncode(key)!, urlEncode(value)!) + parts.append(part) + } + return parts.joined(separator: "&") + } + + private static func urlEncode(_ object: Any?) -> String? { + let str = toString(object) + let set = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-._~") + + return str?.addingPercentEncoding(withAllowedCharacters: set) + } + + static func urlDecode(_ object: Any?) -> String? { + let string = toString(object) + + return string?.removingPercentEncoding + } + + private static func toString(_ object: Any?) -> String? { + if let object = object { + return "\(object)" + } + return nil + } + } From e50f84100d5919913c81120f781f129b7b0461af Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Mon, 5 Feb 2024 14:38:43 -0300 Subject: [PATCH 18/63] Add establishASWebAuthentication function --- Sources/TrustlySDK/TrustlyView.swift | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 4a09879..66631b4 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -285,6 +285,57 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri return self } + + public func establishASWebAuthentication(establishData eD: [AnyHashable : Any], onReturn: TrustlyCallback?, onCancel: TrustlyCallback?){ + establishData = eD + + self.addSessionCid() + + let deviceType = establishData?["deviceType"] ?? "mobile" + ":ios:native" + establishData?["deviceType"] = deviceType + if let lang = establishData?["metadata.lang"] as? String { + establishData?["lang"] = lang + } + + establishData?["metadata.sdkIOSVersion"] = build + + if establishData?.index(forKey: "metadata.integrationContext") == nil { + establishData?["metadata.integrationContext"] = inAppIntegrationContext + } + + + returnUrl = "msg://return" + establishData?["returnUrl"] = returnUrl + cancelUrl = "msg://cancel" + establishData?["cancelUrl"] = cancelUrl + establishData?["version"] = "2" + establishData?["grp"] = self.getGrp() + + if establishData?["paymentProviderId"] != nil { + establishData?["widgetLoaded"] = "true" + } + + if let scheme = establishData?["metadata.urlScheme"] as? String { + self.urlScheme = scheme.components(separatedBy: ":")[0] + } + + returnHandler = onReturn + cancelHandler = onCancel + externalUrlHandler = nil + + do { + let url = try URLUtils.buildEndpointUrl(function: "index", establishData: establishData as! [String : String]) + + self.buildASWebAuthenticationSession(url: URL(string: "http://192.168.0.8:8000/start/lightbox?environment=sandbox&establishData=%7B%22accessId%22%3A%22A48B73F694C4C8EE6306%22%2C%22amount%22%3A%229.99%22%2C%22cancelUrl%22%3A%22trustlysdk%3A%2F%2Ffailure%22%2C%22currency%22%3A%22USD%22%2C%22customer%22%3A%7B%22address%22%3A%7B%22country%22%3A%22US%22%7D%2C%22name%22%3A%22John%20Doe%22%7D%2C%22merchantId%22%3A%22110005514%22%2C%22merchantReference%22%3A%22443446%22%2C%22paymentType%22%3A%22Deferred%22%2C%22returnUrl%22%3A%22trustlysdk%3A%2F%2Fsuccess%22%7D")!, callbackURL: "trustlyback") + + } catch TrustlyURLError.missingLocalUrl { + print("Error: When env is local, you must provide the localUrl.") + + } catch { + print("Error: building url.") + } + + } public func hybrid(url address : String, returnUrl: String, onReturn: TrustlyCallback?, cancelUrl: String, onCancel: TrustlyCallback?) -> UIView? { guard let url = URL(string:address) else { From ef32443fbcc6f77c4cff8af7cbf2df205f92a730 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 8 Feb 2024 10:07:25 -0300 Subject: [PATCH 19/63] Create enum ResourceUrls --- Example/Tests/URLUtilsTests.swift | 16 +++++++-------- Sources/TrustlySDK/TrustlyView.swift | 10 +++++++++- Sources/TrustlySDK/Utils/URLUtils.swift | 26 ++++++++++++++----------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Example/Tests/URLUtilsTests.swift b/Example/Tests/URLUtilsTests.swift index d7e6912..d6b0d43 100644 --- a/Example/Tests/URLUtilsTests.swift +++ b/Example/Tests/URLUtilsTests.swift @@ -36,11 +36,11 @@ final class URLUtilsTests: XCTestCase { let expectedUrlForWidget = "https://\(Constants.baseDomain)/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" let expectedUrlForIndex = "https://\(Constants.baseDomain)/start/selectBank/selectBank?v=\(Constants.buildSDK)-ios-sdk" - let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(resourceUrl: .widget, establishData: self.establishData as! [String : String]) XCTAssertEqual(expectedUrlForWidget, urlBuiltForWidget) - let urlBuiltForIndex = try? URLUtils.buildEndpointUrl(function: "index", establishData: self.establishData as! [String : String]) + let urlBuiltForIndex = try? URLUtils.buildEndpointUrl(resourceUrl: .index, establishData: self.establishData as! [String : String]) XCTAssertEqual(expectedUrlForIndex, urlBuiltForIndex) @@ -53,7 +53,7 @@ final class URLUtilsTests: XCTestCase { let expectedUrl = "https://sandbox.\(Constants.baseDomain)/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" - let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(resourceUrl: .widget, establishData: self.establishData as! [String : String]) XCTAssertEqual(expectedUrl, urlBuiltForWidget) @@ -63,7 +63,7 @@ final class URLUtilsTests: XCTestCase { self.establishData["env"] = "local" - XCTAssertThrowsError(try URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String])) { error in + XCTAssertThrowsError(try URLUtils.buildEndpointUrl(resourceUrl: .widget, establishData: self.establishData as! [String : String])) { error in XCTAssertEqual(error as! TrustlyURLError, TrustlyURLError.missingLocalUrl) } } @@ -73,12 +73,12 @@ final class URLUtilsTests: XCTestCase { self.establishData["env"] = "local" self.establishData["localUrl"] = "192.168.0.15:8000" - XCTAssertNoThrow(try URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String])) + XCTAssertNoThrow(try URLUtils.buildEndpointUrl(resourceUrl: .widget, establishData: self.establishData as! [String : String])) let expectedUrl = "http://192.168.0.15:8000/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" - let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(resourceUrl: .widget, establishData: self.establishData as! [String : String]) XCTAssertEqual(expectedUrl, urlBuiltForWidget) @@ -89,12 +89,12 @@ final class URLUtilsTests: XCTestCase { self.establishData["env"] = "local" self.establishData["localUrl"] = "192.168.0.15:8000" - XCTAssertNoThrow(try URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String])) + XCTAssertNoThrow(try URLUtils.buildEndpointUrl(resourceUrl: .widget, establishData: self.establishData as! [String : String])) let expectedUrl = "http://192.168.0.15:8000/start/selectBank/widget?v=\(Constants.buildSDK)-ios-sdk" - let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(function: "widget", establishData: self.establishData as! [String : String]) + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(resourceUrl: .widget, establishData: self.establishData as! [String : String]) XCTAssertEqual(expectedUrl, urlBuiltForWidget) XCTAssertEqual(true, URLUtils.isLocalEnvironment) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 66631b4..20f94a7 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -19,6 +19,14 @@ import WebKit import AuthenticationServices import SafariServices +enum ResourceUrls: String { + case index = "index" + case widget = "widget" + case establish = "establish" + case selectBank = "selectBank" + +} + func Rgb2UIColor(_ r: CGFloat, _ g: CGFloat, _ b: CGFloat) -> UIColor { UIColor(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1.0) } @@ -324,7 +332,7 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri externalUrlHandler = nil do { - let url = try URLUtils.buildEndpointUrl(function: "index", establishData: establishData as! [String : String]) + let url = try URLUtils.buildEndpointUrl(resourceUrl: .index, establishData: establishData as! [String : String]) self.buildASWebAuthenticationSession(url: URL(string: "http://192.168.0.8:8000/start/lightbox?environment=sandbox&establishData=%7B%22accessId%22%3A%22A48B73F694C4C8EE6306%22%2C%22amount%22%3A%229.99%22%2C%22cancelUrl%22%3A%22trustlysdk%3A%2F%2Ffailure%22%2C%22currency%22%3A%22USD%22%2C%22customer%22%3A%7B%22address%22%3A%7B%22country%22%3A%22US%22%7D%2C%22name%22%3A%22John%20Doe%22%7D%2C%22merchantId%22%3A%22110005514%22%2C%22merchantReference%22%3A%22443446%22%2C%22paymentType%22%3A%22Deferred%22%2C%22returnUrl%22%3A%22trustlysdk%3A%2F%2Fsuccess%22%7D")!, callbackURL: "trustlyback") diff --git a/Sources/TrustlySDK/Utils/URLUtils.swift b/Sources/TrustlySDK/Utils/URLUtils.swift index 181e350..d01ce95 100644 --- a/Sources/TrustlySDK/Utils/URLUtils.swift +++ b/Sources/TrustlySDK/Utils/URLUtils.swift @@ -16,18 +16,19 @@ struct URLUtils { static var isLocalEnvironment = false // MARK: Build url - static func buildEndpointUrl(function:String, establishData:[String:String]) throws -> String { + static func buildEndpointUrl(resourceUrl:ResourceUrls, establishData:[String:String]) throws -> String { var httpProtocol = "https" var domain = Constants.baseDomain var resource = function + var resource = resourceUrl if let environment = establishData["env"], !environment.isEmpty { - if environment == "local" { + if environment == "local" || environment == "dynamic" { isLocalEnvironment = true - httpProtocol = "http" + httpProtocol = environment == "local" ? "http" : "https" if let localUrl = establishData["localUrl"], !localUrl.isEmpty { domain = localUrl @@ -35,7 +36,7 @@ struct URLUtils { } else { throw TrustlyURLError.missingLocalUrl } - + } else { isLocalEnvironment = false httpProtocol = "https" @@ -43,18 +44,21 @@ struct URLUtils { } } - if "index" == resource && - "Verification" != establishData["paymentType"] && - establishData["paymentType"] != nil { - resource = "selectBank" + switch resourceUrl { + case .index: + if "Verification" != establishData["paymentType"] && + establishData["paymentType"] != nil{ + resource = .selectBank + } + default: + break; } - return buildStringUrl(httpProtocol: httpProtocol, domain: domain, resource: resource, build: Constants.buildSDK) } - private static func buildStringUrl(httpProtocol: String, domain: String, resource: String, build: String) -> String{ - return "\(httpProtocol)://\(domain)/start/selectBank/\(resource)?v=\(build)-ios-sdk" + private static func buildStringUrl(httpProtocol: String, domain: String, resource: ResourceUrls, build: String) -> String{ + return "\(httpProtocol)://\(domain)/start/selectBank/\(resource.rawValue)?v=\(build)-ios-sdk" } From 91add52393590923e4a05b00dabd212f3eae607e Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 8 Feb 2024 10:18:40 -0300 Subject: [PATCH 20/63] Introduce isAppLocation flag --- Example/Tests/URLUtilsTests.swift | 13 +++++++++++++ Sources/TrustlySDK/Utils/URLUtils.swift | 14 ++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Example/Tests/URLUtilsTests.swift b/Example/Tests/URLUtilsTests.swift index d6b0d43..f17c833 100644 --- a/Example/Tests/URLUtilsTests.swift +++ b/Example/Tests/URLUtilsTests.swift @@ -68,6 +68,19 @@ final class URLUtilsTests: XCTestCase { } } + func testBuildEndpointUrlIsAppLocation() throws { + + self.establishData["env"] = "sandbox" + + let expectedUrl = "https://sandbox.\(Constants.baseDomain)/start/app/establish?v=\(Constants.buildSDK)-ios-sdk" + + + let urlBuiltForWidget = try? URLUtils.buildEndpointUrl(resourceUrl: .establish, establishData: self.establishData as! [String : String], isAppLocation: true) + + XCTAssertEqual(expectedUrl, urlBuiltForWidget) + + } + func testBuildEndpointUrlLocalEnvironment() throws { self.establishData["env"] = "local" diff --git a/Sources/TrustlySDK/Utils/URLUtils.swift b/Sources/TrustlySDK/Utils/URLUtils.swift index d01ce95..b68c019 100644 --- a/Sources/TrustlySDK/Utils/URLUtils.swift +++ b/Sources/TrustlySDK/Utils/URLUtils.swift @@ -16,12 +16,10 @@ struct URLUtils { static var isLocalEnvironment = false // MARK: Build url - static func buildEndpointUrl(resourceUrl:ResourceUrls, establishData:[String:String]) throws -> String { + static func buildEndpointUrl(resourceUrl:ResourceUrls, establishData:[String:String], isAppLocation: Bool = false) throws -> String { var httpProtocol = "https" var domain = Constants.baseDomain - var resource = function - var resource = resourceUrl if let environment = establishData["env"], !environment.isEmpty { @@ -54,11 +52,15 @@ struct URLUtils { break; } - return buildStringUrl(httpProtocol: httpProtocol, domain: domain, resource: resource, build: Constants.buildSDK) + return buildStringUrl(httpProtocol: httpProtocol, domain: domain, resource: resource, build: Constants.buildSDK, isAppLocation) } - private static func buildStringUrl(httpProtocol: String, domain: String, resource: ResourceUrls, build: String) -> String{ - return "\(httpProtocol)://\(domain)/start/selectBank/\(resource.rawValue)?v=\(build)-ios-sdk" + private static func buildStringUrl(httpProtocol: String, domain: String, resource: ResourceUrls, build: String, _ isAppLocation: Bool) -> String { + var location = isAppLocation ? "app" : "selectBank" + + return "\(httpProtocol)://\(domain)/start/\(location)/\(resource.rawValue)?v=\(build)-ios-sdk" + // http://192.168.0.118:8000/start/app/establish?accessId=A48B73F694C4C8EE6306&token=ewo[…]2tEZFU5eHNrUUt0T3NIL3BNPSIsCiAgICAibGFuZyI6ICJlbl9VUyIKfQ== + // https://sandbox.paywithmybank.com/start/selectBank/widget?v=3.1.1-ios-sdk } From 90656be4218df7f7b0c76525f16f312f2ff4d811 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 8 Feb 2024 11:43:50 -0300 Subject: [PATCH 21/63] Create JSONUtils to convert dictionary to json objects --- Example/Tests/JsonUtilsTests.swift | 46 ++++++++++++++ Example/TrustlySDK.xcodeproj/project.pbxproj | 4 ++ Sources/TrustlySDK/Utils/JSONUtils.swift | 65 ++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 Example/Tests/JsonUtilsTests.swift create mode 100644 Sources/TrustlySDK/Utils/JSONUtils.swift diff --git a/Example/Tests/JsonUtilsTests.swift b/Example/Tests/JsonUtilsTests.swift new file mode 100644 index 0000000..77dc4e6 --- /dev/null +++ b/Example/Tests/JsonUtilsTests.swift @@ -0,0 +1,46 @@ +// +// JsonUtilsTests.swift +// TrustlySDK_Tests +// +// Created by Marcos Rivereto on 08/02/24. +// Copyright © 2024 CocoaPods. All rights reserved. +// + +import XCTest +@testable import TrustlySDK + +final class JsonUtilsTests: XCTestCase { + + var establishData:Dictionary = [:] + + override func setUp() { + super.setUp() + + self.establishData = ["accessId": "A48B73F694C4C8EE6306", + "merchantId" : "110005514"] + + } + + func testBuildJsonString() throws { + + let expectedString = "{\"merchantId\":\"110005514\",\"accessId\":\"A48B73F694C4C8EE6306\"}".hash + + + let jsonString = JSONUtils.getJsonStringFrom(dicticionary: self.establishData)! + + XCTAssertEqual(expectedString, jsonString.hash) + + } + + func testBuildJsonBase64() throws { + + let jsonStringBase64 = JSONUtils.getJsonBase64From(dicticionary: self.establishData)! + let newDictionary = JSONUtils.getDictionaryFrom(jsonStringBase64: jsonStringBase64)! + + + XCTAssertEqual(newDictionary, self.establishData) + + } + + +} diff --git a/Example/TrustlySDK.xcodeproj/project.pbxproj b/Example/TrustlySDK.xcodeproj/project.pbxproj index 785e57e..39f11be 100644 --- a/Example/TrustlySDK.xcodeproj/project.pbxproj +++ b/Example/TrustlySDK.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 15D5276929FBFCF4006BEAEC /* SuccessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D5276729FBFCF4006BEAEC /* SuccessViewController.swift */; }; 15D5276A29FBFCF4006BEAEC /* SuccessViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 15D5276829FBFCF4006BEAEC /* SuccessViewController.xib */; }; 15D5276C29FC016B006BEAEC /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D5276B29FC016B006BEAEC /* BaseViewController.swift */; }; + 15E049852B7510BA0084B71A /* JsonUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15E049842B7510BA0084B71A /* JsonUtilsTests.swift */; }; 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; @@ -48,6 +49,7 @@ 15D5276729FBFCF4006BEAEC /* SuccessViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuccessViewController.swift; sourceTree = ""; }; 15D5276829FBFCF4006BEAEC /* SuccessViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SuccessViewController.xib; sourceTree = ""; }; 15D5276B29FC016B006BEAEC /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; }; + 15E049842B7510BA0084B71A /* JsonUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonUtilsTests.swift; sourceTree = ""; }; 2416E32056EECA07B4C86E1B /* TrustlySDK.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = TrustlySDK.podspec; path = ../TrustlySDK.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 4225824F0F3C24EF9803BCD1 /* Pods_TrustlySDK_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrustlySDK_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50EFC16F37CBC7AAB7A131C5 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; @@ -144,6 +146,7 @@ 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */, 15BB985F2B68120100A9210B /* URLUtilsTests.swift */, 607FACE91AFB9204008FA782 /* Supporting Files */, + 15E049842B7510BA0084B71A /* JsonUtilsTests.swift */, ); path = Tests; sourceTree = ""; @@ -371,6 +374,7 @@ buildActionMask = 2147483647; files = ( 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */, + 15E049852B7510BA0084B71A /* JsonUtilsTests.swift in Sources */, 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */, 15D96FB32C46E6B700296BC4 /* NetworkHelperTests.swift in Sources */, 15BB98602B68120100A9210B /* URLUtilsTests.swift in Sources */, diff --git a/Sources/TrustlySDK/Utils/JSONUtils.swift b/Sources/TrustlySDK/Utils/JSONUtils.swift new file mode 100644 index 0000000..e2f6818 --- /dev/null +++ b/Sources/TrustlySDK/Utils/JSONUtils.swift @@ -0,0 +1,65 @@ +// +// JSONUtils.swift +// TrustlySDK +// +// Created by Marcos Rivereto on 08/02/24. +// + +import Foundation + +struct JSONUtils { + + static private func getJsonDataFrom(dicticionary: [String : Any]) -> Data? { + + do { + + let jsonData:Data = try JSONSerialization.data(withJSONObject: dicticionary) + + return jsonData + + } catch { + print(error.localizedDescription) + } + + return nil + } + + static func getJsonStringFrom(dicticionary: [String : Any]) -> String? { + + guard let jsonData = getJsonDataFrom(dicticionary: dicticionary) else { return nil } + + let jsonString:String = String(data: jsonData, encoding: .utf8)! + + return jsonString + + } + + static func getJsonBase64From(dicticionary: [String : Any]) -> String? { + + guard let jsonData = getJsonDataFrom(dicticionary: dicticionary) else { return nil } + let jsonBase64 = jsonData.base64EncodedString() + + return jsonBase64 + + } + + static func getDictionaryFrom(jsonStringBase64: String) -> [String : String]? { + + do { + + if let decodedData = Data(base64Encoded: jsonStringBase64) { + let newDictionary = try JSONSerialization.jsonObject(with: decodedData, options: []) as? [String: String] + + return newDictionary + + } else { + print("Not Base64") + } + + } catch { + print(error.localizedDescription) + } + + return nil + } +} From 601d615ca2a9a2efa9d7c21d60094b58163d70de Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 15 Feb 2024 14:46:33 -0300 Subject: [PATCH 22/63] Change function parameters --- Sources/TrustlySDK/Utils/JSONUtils.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/TrustlySDK/Utils/JSONUtils.swift b/Sources/TrustlySDK/Utils/JSONUtils.swift index e2f6818..68bf3b9 100644 --- a/Sources/TrustlySDK/Utils/JSONUtils.swift +++ b/Sources/TrustlySDK/Utils/JSONUtils.swift @@ -9,7 +9,7 @@ import Foundation struct JSONUtils { - static private func getJsonDataFrom(dicticionary: [String : Any]) -> Data? { + static private func getJsonDataFrom(dicticionary: [AnyHashable : Any]) -> Data? { do { @@ -24,7 +24,7 @@ struct JSONUtils { return nil } - static func getJsonStringFrom(dicticionary: [String : Any]) -> String? { + static func getJsonStringFrom(dicticionary: [AnyHashable : Any]) -> String? { guard let jsonData = getJsonDataFrom(dicticionary: dicticionary) else { return nil } @@ -34,7 +34,7 @@ struct JSONUtils { } - static func getJsonBase64From(dicticionary: [String : Any]) -> String? { + static func getJsonBase64From(dicticionary: [AnyHashable : Any]) -> String? { guard let jsonData = getJsonDataFrom(dicticionary: dicticionary) else { return nil } let jsonBase64 = jsonData.base64EncodedString() From 06539328d52b41cab12a5f7d0dd15bee2af7dcb0 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 15 Feb 2024 14:47:01 -0300 Subject: [PATCH 23/63] Create EstablishDataUtils to normalize establish format --- Example/Tests/EstablishDataUtilsTests.swift | 40 +++++++++ Example/TrustlySDK.xcodeproj/project.pbxproj | 4 + .../TrustlySDK/Utils/EstablishDataUtils.swift | 85 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 Example/Tests/EstablishDataUtilsTests.swift create mode 100644 Sources/TrustlySDK/Utils/EstablishDataUtils.swift diff --git a/Example/Tests/EstablishDataUtilsTests.swift b/Example/Tests/EstablishDataUtilsTests.swift new file mode 100644 index 0000000..d3ca760 --- /dev/null +++ b/Example/Tests/EstablishDataUtilsTests.swift @@ -0,0 +1,40 @@ +// +// EstablishDataUtilsTests.swift +// TrustlySDK_Tests +// +// Created by Marcos Rivereto on 15/02/24. +// Copyright © 2024 CocoaPods. All rights reserved. +// + +import XCTest +@testable import TrustlySDK + +final class EstablishDataUtilsTests: XCTestCase { + + var establishData:Dictionary = [:] + + override func setUp() { + super.setUp() + + self.establishData = ["accessId": "A48B73F694C4C8EE6306", + "customer.address.country" : "US", + "customer.address.street" : "ABC Avenue", + "metadata.urlScheme": "demoapp://"] + + } + + func testNormalizeDotNotation() throws { + + let expectedEstablishData: [String : AnyHashable] = [ + "accessId": "A48B73F694C4C8EE6306", + "customer" : ["address": ["country": "US", "street": "ABC Avenue"]], + "metadata" : ["urlScheme": "demoapp://"] + ] + + let jsonString = EstablishDataUtils.normalizeEstablishWithDotNotation(establish: self.establishData) + + XCTAssertEqual(expectedEstablishData, jsonString) + + } + +} diff --git a/Example/TrustlySDK.xcodeproj/project.pbxproj b/Example/TrustlySDK.xcodeproj/project.pbxproj index 39f11be..219cb71 100644 --- a/Example/TrustlySDK.xcodeproj/project.pbxproj +++ b/Example/TrustlySDK.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 152541E62B7E74B20029F149 /* EstablishDataUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152541E52B7E74B20029F149 /* EstablishDataUtilsTests.swift */; }; 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */; }; 15987B0929DEF79D00D7A395 /* TrustlyLightBoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15987B0829DEF79D00D7A395 /* TrustlyLightBoxViewController.swift */; }; 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */; }; @@ -40,6 +41,7 @@ 06A59A0ECC7F2C369392E6A5 /* Pods-TrustlySDK_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Example.release.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Example/Pods-TrustlySDK_Example.release.xcconfig"; sourceTree = ""; }; 080249A29F70B36248BD8984 /* Pods-TrustlySDK_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Example.debug.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Example/Pods-TrustlySDK_Example.debug.xcconfig"; sourceTree = ""; }; 10C7972A664657BB9F51ED82 /* Pods-TrustlySDK_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrustlySDK_Tests.release.xcconfig"; path = "Target Support Files/Pods-TrustlySDK_Tests/Pods-TrustlySDK_Tests.release.xcconfig"; sourceTree = ""; }; + 152541E52B7E74B20029F149 /* EstablishDataUtilsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EstablishDataUtilsTests.swift; sourceTree = ""; }; 1587AB902A2FE043006F6FC3 /* SessionManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManagerTests.swift; sourceTree = ""; }; 15987B0829DEF79D00D7A395 /* TrustlyLightBoxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustlyLightBoxViewController.swift; sourceTree = ""; }; 15BEC9B32C383FB900050FB9 /* ValidationHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidationHelperTests.swift; sourceTree = ""; }; @@ -147,6 +149,7 @@ 15BB985F2B68120100A9210B /* URLUtilsTests.swift */, 607FACE91AFB9204008FA782 /* Supporting Files */, 15E049842B7510BA0084B71A /* JsonUtilsTests.swift */, + 152541E52B7E74B20029F149 /* EstablishDataUtilsTests.swift */, ); path = Tests; sourceTree = ""; @@ -375,6 +378,7 @@ files = ( 15BEC9B42C383FB900050FB9 /* ValidationHelperTests.swift in Sources */, 15E049852B7510BA0084B71A /* JsonUtilsTests.swift in Sources */, + 152541E62B7E74B20029F149 /* EstablishDataUtilsTests.swift in Sources */, 1587AB912A2FE043006F6FC3 /* SessionManagerTests.swift in Sources */, 15D96FB32C46E6B700296BC4 /* NetworkHelperTests.swift in Sources */, 15BB98602B68120100A9210B /* URLUtilsTests.swift in Sources */, diff --git a/Sources/TrustlySDK/Utils/EstablishDataUtils.swift b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift new file mode 100644 index 0000000..7a9571a --- /dev/null +++ b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift @@ -0,0 +1,85 @@ +// +// EstablishDataUtils.swift +// TrustlySDK +// +// Created by Marcos Rivereto on 15/02/24. +// + +import Foundation + + +struct EstablishDataUtils { + + /// Transform the establish removing the dot notation. Example: from ["customer.address.country": "US"] to ["customer": ["address": [country": "US"]]] + /// + /// - Parameter establish: An establish to be transformed + /// - Returns: A new [String : AnyHashable] object normalized + static func normalizeEstablishWithDotNotation(establish: [String : AnyHashable]) -> [String : AnyHashable] { + + var newEstablish = [String : AnyHashable]() + + establish.forEach { (key: String, value: AnyHashable) in + + if key.contains(".") { + parseData(origin: &newEstablish, key: key, value: value) + + } else { + newEstablish[key] = value + + } + + } + + return newEstablish + + } + + /// Responsible to parse the dot notation key, in a clena dictionary key. Example: from ["customer.address.country": "US"] to ["customer": ["address": [country": "US"]]] + /// + /// - Parameters: + /// - origin: The origin dicitionary + /// - key: The key with dot notation + /// - value: The value of the key + static private func parseData(origin: inout [String : AnyHashable], key: String, value: AnyHashable ) { + + if key.contains(".") { + origin.removeValue(forKey: key) + + let splitedKeys = splitDotNotationKeys(key) + + var newObject: [String : AnyHashable] + + if let object = origin[splitedKeys.mainKey] { + + newObject = object as! [String : AnyHashable] + newObject[splitedKeys.complementKey] = value + + } else { + newObject = [splitedKeys.complementKey: value] + } + + parseData(origin: &newObject, key: splitedKeys.complementKey, value: value) + origin[splitedKeys.mainKey] = newObject + + } else { + origin[key] = value + + } + } + + /// Split the dot notation key oin 2 parts, mainKey and complementKey. Example: from "customer.address.country" to (mainKey: customer, complementKey: address.country) + /// + /// - Parameters: + /// - key: The key with dot notation + /// - value: The value of the key + /// - Returns: (mainKey: String, complementKey: String) + static private func splitDotNotationKeys(_ key: String) -> (mainKey: String, complementKey: String) { + var keys = key.split(separator: ".") + + let firstKey = String(keys[0]) + keys.remove(at: 0) + let secondKey = keys.joined(separator: ".") + + return (mainKey: firstKey, complementKey: secondKey) + } +} From 31b1e21ee84d98b4a98f158b4aca6becee6ccf25 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 15 Feb 2024 16:09:54 -0300 Subject: [PATCH 24/63] Rename variable --- Example/Tests/EstablishDataUtilsTests.swift | 7 ++++++- Sources/TrustlySDK/Utils/EstablishDataUtils.swift | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Example/Tests/EstablishDataUtilsTests.swift b/Example/Tests/EstablishDataUtilsTests.swift index d3ca760..bfe9ec6 100644 --- a/Example/Tests/EstablishDataUtilsTests.swift +++ b/Example/Tests/EstablishDataUtilsTests.swift @@ -31,7 +31,12 @@ final class EstablishDataUtilsTests: XCTestCase { "metadata" : ["urlScheme": "demoapp://"] ] - let jsonString = EstablishDataUtils.normalizeEstablishWithDotNotation(establish: self.establishData) + let normalizedEstablish = EstablishDataUtils.normalizeEstablishWithDotNotation(establish: self.establishData) + + XCTAssertEqual(expectedEstablishData, normalizedEstablish) + + } + XCTAssertEqual(expectedEstablishData, jsonString) diff --git a/Sources/TrustlySDK/Utils/EstablishDataUtils.swift b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift index 7a9571a..4ae35ac 100644 --- a/Sources/TrustlySDK/Utils/EstablishDataUtils.swift +++ b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift @@ -10,6 +10,8 @@ import Foundation struct EstablishDataUtils { + // MARK: normalizeEstablishWithDotNotation + /// Transform the establish removing the dot notation. Example: from ["customer.address.country": "US"] to ["customer": ["address": [country": "US"]]] /// /// - Parameter establish: An establish to be transformed From 0b9489f427283678acb15f5f8d5537b9259d740f Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 15 Feb 2024 16:11:43 -0300 Subject: [PATCH 25/63] Create buildEstablishFrom --- Example/Tests/EstablishDataUtilsTests.swift | 16 +++++++++++++- .../TrustlySDK/Utils/EstablishDataUtils.swift | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Example/Tests/EstablishDataUtilsTests.swift b/Example/Tests/EstablishDataUtilsTests.swift index bfe9ec6..4228c7c 100644 --- a/Example/Tests/EstablishDataUtilsTests.swift +++ b/Example/Tests/EstablishDataUtilsTests.swift @@ -12,6 +12,7 @@ import XCTest final class EstablishDataUtilsTests: XCTestCase { var establishData:Dictionary = [:] + var urlWithParamters: String = "" override func setUp() { super.setUp() @@ -21,6 +22,8 @@ final class EstablishDataUtilsTests: XCTestCase { "customer.address.street" : "ABC Avenue", "metadata.urlScheme": "demoapp://"] + self.urlWithParamters = "demoapp://?transactionId=1003151780&transactionType=1&merchantReference=g:cac73df7-52b4-47d7-89d3-9628d4cfb65e&payment.paymentProvider.type=1&requestSignature=E0rbmsl4KOORibvsHoDvfqIqlaQ%3D" + } func testNormalizeDotNotation() throws { @@ -37,8 +40,19 @@ final class EstablishDataUtilsTests: XCTestCase { } + func testConvertUrlWithParameterToNormalizedEstablish() throws { + + let expectedEstablishData: [String : AnyHashable] = [ + "transactionId": "1003151780", + "transactionType": "1", + "merchantReference": "g:cac73df7-52b4-47d7-89d3-9628d4cfb65e", + "payment": ["paymentProvider": ["type" : "1"]], + "requestSignature": "E0rbmsl4KOORibvsHoDvfqIqlaQ%3D" + ] + + let normalizedEstablish = EstablishDataUtils.buildEstablishFrom(urlWithParameters: self.urlWithParamters) - XCTAssertEqual(expectedEstablishData, jsonString) + XCTAssertEqual(expectedEstablishData, normalizedEstablish) } diff --git a/Sources/TrustlySDK/Utils/EstablishDataUtils.swift b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift index 4ae35ac..e164d02 100644 --- a/Sources/TrustlySDK/Utils/EstablishDataUtils.swift +++ b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift @@ -84,4 +84,25 @@ struct EstablishDataUtils { return (mainKey: firstKey, complementKey: secondKey) } + + // MARK: buildEstablishFrom + + /// Convert url string with parameter to a normalized establish + /// + /// - Parameters: + /// - urlWithParameters + /// - Returns: [String : AnyHashable] + static func buildEstablishFrom(urlWithParameters: String) -> [String : AnyHashable] { + var establish: [String : AnyHashable] = [:] + + let parameters = urlWithParameters.split(separator: "?")[1] + + for parameter in parameters.split(separator: "&") { + let keyAndValue = parameter.split(separator: "=") + + establish[String(keyAndValue[0])] = String(keyAndValue[1]) + } + + return normalizeEstablishWithDotNotation(establish: establish) + } } From 72fc756fa53e74cf42d197812ebb0381b2e2d055 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 15 Feb 2024 16:12:04 -0300 Subject: [PATCH 26/63] Fix parameters type --- Sources/TrustlySDK/Utils/JSONUtils.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/TrustlySDK/Utils/JSONUtils.swift b/Sources/TrustlySDK/Utils/JSONUtils.swift index 68bf3b9..d9c5213 100644 --- a/Sources/TrustlySDK/Utils/JSONUtils.swift +++ b/Sources/TrustlySDK/Utils/JSONUtils.swift @@ -9,7 +9,7 @@ import Foundation struct JSONUtils { - static private func getJsonDataFrom(dicticionary: [AnyHashable : Any]) -> Data? { + static private func getJsonDataFrom(dicticionary: [String : AnyHashable]) -> Data? { do { @@ -24,7 +24,7 @@ struct JSONUtils { return nil } - static func getJsonStringFrom(dicticionary: [AnyHashable : Any]) -> String? { + static func getJsonStringFrom(dicticionary: [String : AnyHashable]) -> String? { guard let jsonData = getJsonDataFrom(dicticionary: dicticionary) else { return nil } @@ -34,7 +34,7 @@ struct JSONUtils { } - static func getJsonBase64From(dicticionary: [AnyHashable : Any]) -> String? { + static func getJsonBase64From(dicticionary: [String : AnyHashable]) -> String? { guard let jsonData = getJsonDataFrom(dicticionary: dicticionary) else { return nil } let jsonBase64 = jsonData.base64EncodedString() From aa13f670483a731466afc932c3773dbea8846776 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 15 Feb 2024 16:38:34 -0300 Subject: [PATCH 27/63] Create buildASWebAuthenticationSession, and change to work with it --- Sources/TrustlySDK/TrustlyView.swift | 34 +++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Sources/TrustlySDK/TrustlyView.swift b/Sources/TrustlySDK/TrustlyView.swift index 20f94a7..b6fbddc 100644 --- a/Sources/TrustlySDK/TrustlyView.swift +++ b/Sources/TrustlySDK/TrustlyView.swift @@ -325,6 +325,8 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri if let scheme = establishData?["metadata.urlScheme"] as? String { self.urlScheme = scheme.components(separatedBy: ":")[0] + establishData?["returnUrl"] = scheme + establishData?["cancelUrl"] = scheme } returnHandler = onReturn @@ -332,9 +334,15 @@ public class TrustlyView : UIView, TrustlyProtocol, WKNavigationDelegate, WKScri externalUrlHandler = nil do { - let url = try URLUtils.buildEndpointUrl(resourceUrl: .index, establishData: establishData as! [String : String]) - - self.buildASWebAuthenticationSession(url: URL(string: "http://192.168.0.8:8000/start/lightbox?environment=sandbox&establishData=%7B%22accessId%22%3A%22A48B73F694C4C8EE6306%22%2C%22amount%22%3A%229.99%22%2C%22cancelUrl%22%3A%22trustlysdk%3A%2F%2Ffailure%22%2C%22currency%22%3A%22USD%22%2C%22customer%22%3A%7B%22address%22%3A%7B%22country%22%3A%22US%22%7D%2C%22name%22%3A%22John%20Doe%22%7D%2C%22merchantId%22%3A%22110005514%22%2C%22merchantReference%22%3A%22443446%22%2C%22paymentType%22%3A%22Deferred%22%2C%22returnUrl%22%3A%22trustlysdk%3A%2F%2Fsuccess%22%7D")!, callbackURL: "trustlyback") + var url = try URLUtils.buildEndpointUrl(resourceUrl: .establish, establishData: establishData as! [String : String], isAppLocation: true) + + let normalizedEstablish:[String : AnyHashable] = EstablishDataUtils.normalizeEstablishWithDotNotation(establish: establishData as! [String : AnyHashable]) + + if let token = JSONUtils.getJsonBase64From(dicticionary: normalizedEstablish) { + url = "\(url)&accessId=\(establishData!["accessId"]!)&token=\(token)" + + self.buildASWebAuthenticationSession(url: URL(string: url)!, callbackURL: urlScheme, onReturn: onReturn, onCancel: onCancel) + } } catch TrustlyURLError.missingLocalUrl { print("Error: When env is local, you must provide the localUrl.") @@ -671,6 +679,26 @@ extension TrustlyView { webSession.start() } + private func buildASWebAuthenticationSession(url: URL, callbackURL: String, onReturn: TrustlyCallback?, onCancel: TrustlyCallback?) { + webSession = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURL, completionHandler: { (url, error) in + if let stringUrl = url?.absoluteString { + let returnedEstablish = EstablishDataUtils.buildEstablishFrom(urlWithParameters: stringUrl) + + onReturn?(self, returnedEstablish) + + } else { + onCancel?(self, [:]) + } + }) + + if #available(iOS 13, *) { + webSession.prefersEphemeralWebBrowserSession = true + webSession.presentationContextProvider = self + } + + webSession.start() + } + private func proceedToChooseAccount(){ self.mainWebView.evaluateJavaScript("window.Trustly.proceedToChooseAccount();", completionHandler: nil) } From 923ce589440cb821a1288a7907e04cbe515172a7 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Thu, 15 Feb 2024 16:44:29 -0300 Subject: [PATCH 28/63] Change to handle both lightbox --- Example/TrustlySDK/Base.lproj/Main.storyboard | 77 ++++++++++++++----- Example/TrustlySDK/ViewController.swift | 58 +++++++++++++- 2 files changed, 114 insertions(+), 21 deletions(-) diff --git a/Example/TrustlySDK/Base.lproj/Main.storyboard b/Example/TrustlySDK/Base.lproj/Main.storyboard index 644ff96..5084293 100644 --- a/Example/TrustlySDK/Base.lproj/Main.storyboard +++ b/Example/TrustlySDK/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -39,10 +39,42 @@ + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -82,7 +123,7 @@ - + diff --git a/Example/TrustlySDK/ViewController.swift b/Example/TrustlySDK/ViewController.swift index 8f1decd..90d6c3e 100644 --- a/Example/TrustlySDK/ViewController.swift +++ b/Example/TrustlySDK/ViewController.swift @@ -55,9 +55,6 @@ class ViewController: UIViewController { // MARK: - IBActions @IBAction func pay(_ sender: Any) { - - let trustlyLightboxViewController = TrustlyLightBoxViewController() - trustlyLightboxViewController.delegate = self if let amountText = amountTextView.text, let amount = Double(amountText) { @@ -67,8 +64,63 @@ class ViewController: UIViewController { self.present(trustlyLightboxViewController, animated: true) } + + if let emailText = emailTextView.text, !emailText.isEmpty { + + establishData["customer.email"] = emailText + + } + + self.openLightbox() } + + @IBAction func payWituAESWebAuth(_ sender: Any) { + + if let amountText = amountTextView.text, + let amount = Double(amountText) { + + establishData["amount"] = String(format: "%.2f", amount) + } + + if let emailText = emailTextView.text, !emailText.isEmpty { + + establishData["customer.email"] = emailText + + } + + self.openLightboxASWebAuthentication() + + } + + private func openLightbox(){ + let trustlyLightboxViewController = TrustlyLightBoxViewController() + trustlyLightboxViewController.delegate = self + + trustlyLightboxViewController.establishData = self.establishData + + self.present(trustlyLightboxViewController, animated: true) + + } + + private func openLightboxASWebAuthentication(){ + let trustlyLightboxPanel = TrustlyView() + + trustlyLightboxPanel.establishASWebAuthentication(establishData: establishData, + onReturn: {(trustlyView, returnParameters)->Void in + if let transactionId = returnParameters["transactionId"] { + self.showSuccessView(transactionId: transactionId as! String) + } else { + self.showFailureAlert() + } + + }, onCancel: {(payWithMyBank, returnParameters)->Void in + let response = returnParameters as! [String:String] + self.showFailureAlert() + }) + + } + } extension ViewController: TrustlyLightboxViewProtocol { From 66e70531a45abb07441febaf8a041d05c171e074 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Fri, 16 Feb 2024 17:15:48 -0300 Subject: [PATCH 29/63] Add url parameter to be returned --- Sources/TrustlySDK/Utils/EstablishDataUtils.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/TrustlySDK/Utils/EstablishDataUtils.swift b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift index e164d02..a86624a 100644 --- a/Sources/TrustlySDK/Utils/EstablishDataUtils.swift +++ b/Sources/TrustlySDK/Utils/EstablishDataUtils.swift @@ -94,6 +94,7 @@ struct EstablishDataUtils { /// - Returns: [String : AnyHashable] static func buildEstablishFrom(urlWithParameters: String) -> [String : AnyHashable] { var establish: [String : AnyHashable] = [:] + establish["url"] = urlWithParameters let parameters = urlWithParameters.split(separator: "?")[1] From de6ba98523e587e819706fd0e6debed58520ff83 Mon Sep 17 00:00:00 2001 From: Marcos Rivereto Date: Tue, 20 Feb 2024 10:30:04 -0300 Subject: [PATCH 30/63] Fix multiple PR comments --- Example/Tests/JsonUtilsTests.swift | 4 ++-- Example/TrustlySDK/Base.lproj/Main.storyboard | 4 ++-- Example/TrustlySDK/ViewController.swift | 2 +- Sources/TrustlySDK/TrustlyView.swift | 2 +- .../TrustlySDK/Utils/EstablishDataUtils.swift | 18 +++++++++--------- Sources/TrustlySDK/Utils/JSONUtils.swift | 12 ++++++------ 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Example/Tests/JsonUtilsTests.swift b/Example/Tests/JsonUtilsTests.swift index 77dc4e6..2f07523 100644 --- a/Example/Tests/JsonUtilsTests.swift +++ b/Example/Tests/JsonUtilsTests.swift @@ -26,7 +26,7 @@ final class JsonUtilsTests: XCTestCase { let expectedString = "{\"merchantId\":\"110005514\",\"accessId\":\"A48B73F694C4C8EE6306\"}".hash - let jsonString = JSONUtils.getJsonStringFrom(dicticionary: self.establishData)! + let jsonString = JSONUtils.getJsonStringFrom(dictionary: self.establishData)! XCTAssertEqual(expectedString, jsonString.hash) @@ -34,7 +34,7 @@ final class JsonUtilsTests: XCTestCase { func testBuildJsonBase64() throws { - let jsonStringBase64 = JSONUtils.getJsonBase64From(dicticionary: self.establishData)! + let jsonStringBase64 = JSONUtils.getJsonBase64From(dictionary: self.establishData)! let newDictionary = JSONUtils.getDictionaryFrom(jsonStringBase64: jsonStringBase64)! diff --git a/Example/TrustlySDK/Base.lproj/Main.storyboard b/Example/TrustlySDK/Base.lproj/Main.storyboard index 5084293..7970fb0 100644 --- a/Example/TrustlySDK/Base.lproj/Main.storyboard +++ b/Example/TrustlySDK/Base.lproj/Main.storyboard @@ -50,7 +50,7 @@ - +