Skip to content

Commit

Permalink
Merge pull request #289 from omise/develop
Browse files Browse the repository at this point in the history
[Dev -> Master] v5.1.0 (Netcetera 3DS)
  • Loading branch information
Andrei Solovev authored May 15, 2024
2 parents 59cadd7 + 415cdd5 commit 4a2b23c
Show file tree
Hide file tree
Showing 73 changed files with 2,208 additions and 376 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- uses: actions/checkout@v3

- name: Run xcodebuild with tests
run: xcodebuild -project dev.xcodeproj/ -scheme OmiseSDK -derivedDataPath Build/ -destination 'platform=iOS Simulator,name=iPhone 11,OS=16.2' -enableCodeCoverage YES clean build test CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO
run: xcodebuild -project dev.xcodeproj/ -scheme OmiseSDK -derivedDataPath Build/ -destination 'platform=iOS Simulator,name=iPhone 14,OS=17.5' -enableCodeCoverage YES clean build test CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO

- name: Convert Xcode coverage to SonarCloud format
run: bash xccov-to-sonarqube-generic.sh build/Logs/Test/*.xcresult/ > sonarqube-generic-coverage.xml
Expand Down
2 changes: 1 addition & 1 deletion ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/omise/omise-ios.git";
requirement = {
branch = feature/v5_refactoring;
branch = "feature/MIT-2470";
kind = branch;
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/omise/omise-ios.git",
"state" : {
"branch" : "feature/v5_refactoring",
"revision" : "a59269f3d734ebc17d8e717b5c03b17d5d67a679"
"branch" : "feature/MIT-2470",
"revision" : "4f1bbf9a0f0828c7531664276fc244fd8433a869"
}
},
{
"identity" : "spm",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ios-3ds-sdk/SPM",
"state" : {
"revision" : "a4e55d7f10294ea81abd1db393ae05606a5efa46",
"version" : "2.4.0"
}
}
],
Expand Down
4 changes: 0 additions & 4 deletions ExampleApp/Config.local.plist
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,5 @@
<dict>
<key>publicKey</key>
<string>pkey_</string>
<key>devVaultBaseURL</key>
<string></string>
<key>devApiBaseURL</key>
<string></string>
</dict>
</plist>
130 changes: 56 additions & 74 deletions ExampleApp/Resources/Main.storyboard

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions ExampleApp/Views/PaymentSettingTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ class PaymentSettingTableViewController: UITableViewController {
@IBOutlet private var paynowPaymentCell: UITableViewCell!
@IBOutlet private var truemoneyPaymentCell: UITableViewCell!
@IBOutlet private var truemoneyJumpAppPaymentCell: UITableViewCell!
@IBOutlet private var pointsCitiCell: UITableViewCell!
@IBOutlet private var fpxCell: UITableViewCell!
@IBOutlet private var rabbitLinepayCell: UITableViewCell!
@IBOutlet private var OCBCDigitalPaymentCell: UITableViewCell!
Expand Down Expand Up @@ -347,8 +346,6 @@ extension PaymentSettingTableViewController {
return .trueMoneyWallet
case truemoneyJumpAppPaymentCell:
return .trueMoneyJumpApp
case pointsCitiCell:
return .pointsCiti
case fpxCell:
return .fpx
case rabbitLinepayCell:
Expand Down Expand Up @@ -443,8 +440,6 @@ extension PaymentSettingTableViewController {
return truemoneyPaymentCell
case .trueMoneyJumpApp:
return truemoneyJumpAppPaymentCell
case .pointsCiti:
return pointsCitiCell
case .fpx:
return fpxCell
case .rabbitLinepay:
Expand Down
31 changes: 22 additions & 9 deletions ExampleApp/Views/ProductDetailViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class ProductDetailViewController: BaseViewController {
amount: paymentAmount,
currency: paymentCurrencyCode,
allowedPaymentMethods: usesCapabilityDataForPaymentMethods ? nil : allowedPaymentMethods,
skipCapabilityValidation: true,
isCardPaymentAllowed: true,
handleErrors: true,
delegate: self
Expand All @@ -56,12 +55,11 @@ class ProductDetailViewController: BaseViewController {
let text = textField.text,
let url = URL(string: text) else { return }

let deeplinkRedirectURLPattern = AppDeeplink.threeDSChallenge.urlString
let webRedirectURLPattern = "https://exampleapp.opn.ooo"
self.omiseSDK.presentAuthorizingPayment(
from: self,
authorizeURL: url,
returnURLs: [deeplinkRedirectURLPattern, webRedirectURLPattern],
expectedReturnURLStrings: ["https://omise.co"],
threeDSRequestorAppURLString: AppDeeplink.threeDSChallenge.urlString,
delegate: self
)
})
Expand All @@ -71,13 +69,13 @@ class ProductDetailViewController: BaseViewController {

// MARK: - Authorizing Payment View Controller Delegate

extension ProductDetailViewController: AuthorizingPaymentViewControllerDelegate {
func authorizingPaymentViewController(_ viewController: AuthorizingPaymentViewController, didCompleteAuthorizingPaymentWithRedirectedURL redirectedURL: URL) {
print("Payment is authorized with redirect url `\(redirectedURL)`")
extension ProductDetailViewController: AuthorizingPaymentDelegate {
func authorizingPaymentDidComplete(with redirectedURL: URL?) {
print("Payment is authorized with redirect url `\(String(describing: redirectedURL))`")
omiseSDK.dismiss()
}

func authorizingPaymentViewControllerDidCancel(_ viewController: AuthorizingPaymentViewController) {
func authorizingPaymentDidCancel() {
print("Payment is not authorized")
omiseSDK.dismiss()
}
}
Expand Down Expand Up @@ -124,6 +122,21 @@ extension ProductDetailViewController: ChoosePaymentMethodDelegate {
func choosePaymentMethodDidCancel() {
omiseSDK.dismiss()
}

func choosePaymentMethodDidComplete(with source: Source, token: Token) {
print("White-label installment payment Token is created with id '\(token.id)', Source id: '\(source.id)'")
omiseSDK.dismiss {
let alertController = UIAlertController(
title: "Token & Source Created\n(\(source.paymentInformation.sourceType.rawValue))",
message: "A token with id of \(token.id) and source with id of \(source.id) was successfully created. Please send this id to server to create a charge.",
preferredStyle: .alert
)
let okAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
}

}
}

// MARK: - Custom Credit Card Form View Controller Delegate
Expand Down
7 changes: 7 additions & 0 deletions OmiseSDK/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
"SourceType.installment_scb" = "Siam Commercial Bank";
"SourceType.installment_ttb" = "TMBThanachart Bank";
"SourceType.installment_uob" = "United Overseas Bank";
"SourceType.installment_wlb_ktc" = "KTC";
"SourceType.installment_wlb_kbank" = "Kasikorn Bank";
"SourceType.installment_wlb_scb" = "Siam Commercial Bank";
"SourceType.installment_wlb_bbl" = "Bangkok Bank";
"SourceType.installment_wlb_bay" = "Krungsri";
"SourceType.installment_wlb_first_choice" = "Krungsri First Choice";
"SourceType.installment_wlb_ttb" = "TMBThanachart Bank";
"SourceType.internet_banking_bay" = "Bank of Ayudhya";
"SourceType.internet_banking_bbl" = "Bangkok Bank";
"SourceType.paynow" = "PayNow";
Expand Down
7 changes: 7 additions & 0 deletions OmiseSDK/Resources/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
"SourceType.installment_scb" = "サイアム・コマーシャル銀行";
"SourceType.installment_ttb" = "TMBタナチャート銀行";
"SourceType.installment_uob" = "ユナイテッド・オーバーシーズ銀行";
"SourceType.installment_wlb_ktc" = "クルンタイカード";
"SourceType.installment_wlb_kbank" = "カシコン銀行";
"SourceType.installment_wlb_scb" = "サイアム・コマーシャル銀行";
"SourceType.installment_wlb_bbl" = "バンコク銀行";
"SourceType.installment_wlb_bay" = "クルンシィ";
"SourceType.installment_wlb_first_choice" = "クルンシィ・ファーストチョイス";
"SourceType.installment_wlb_ttb" = "TMBタナチャート銀行";
"SourceType.internet_banking_bay" = "アユタヤ銀行";
"SourceType.internet_banking_bbl" = "バンコク銀行";
"SourceType.paynow" = "PayNow";
Expand Down
4 changes: 4 additions & 0 deletions OmiseSDK/Resources/th.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"SourceType.installment_scb" = "ธนาคารไทยพาณิชย์";
"SourceType.installment_ttb" = "ธนาคารทีเอ็มบีธนชาต";
"SourceType.installment_uob" = "ธนาคารยูโอบี";
"SourceType.installment_wlb_ktc" = "เคทีซี";
"SourceType.installment_wlb_kbank" = "ธนาคารกสิกรไทย";
"SourceType.installment_wlb_scb" = "ธนาคารไทยพาณิชย์";
"SourceType.installment_wlb_bbl" = "ธนาคารกรุงเทพ";
"SourceType.internet_banking_bay" = "ธนาคารกรุงศรีอยุธยา";
"SourceType.internet_banking_bbl" = "ธนาคารกรุงเทพ";
"SourceType.paynow" = "เพย์นาว";
Expand Down
98 changes: 98 additions & 0 deletions OmiseSDK/Sources/3DS/Crypto/CryptData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import Foundation
import CommonCrypto

enum CryptoError: Error {
case invalidKeyLength
case creationError(Int)
case updateError(Int)
case finalError(Int)
}

// swiftlint:disable:next function_parameter_count function_body_length
func cryptData(
_ dataIn: Data,
operation: CCOperation, // kCCEncrypt, kCCDecrypt
mode: CCMode, // kCCModeECB, kCCModeCBC, etc.
algorithm: CCAlgorithm, // kCCAlgorithmAES, kCCAlgorithmDES, etc.
padding: CCPadding, // ccNoPadding, ccPKCS7Padding
keyLength: size_t,
iv: Data?,
key: Data
) throws -> Data {
guard key.count == keyLength else {
throw CryptoError.invalidKeyLength
}

var cryptor: CCCryptorRef?
var status = CCCryptorCreateWithMode(operation,
mode,
algorithm,
padding,
iv?.withUnsafeBytes { $0.baseAddress },
key.withUnsafeBytes { $0.baseAddress },
keyLength,
nil,
0,
0, // tweak XTS mode, numRounds
0, // CCModeOptions
&cryptor)

if status != kCCSuccess {
throw CryptoError.creationError(Int(status))
}

guard let cryptor = cryptor else {
throw CryptoError.creationError(Int(status))
}

defer {
CCCryptorRelease(cryptor)
}

let dataOutLength = CCCryptorGetOutputLength(cryptor, dataIn.count, true)
var dataOut = Data(count: dataOutLength)
var dataOutMoved = 0

status = dataOut.withUnsafeMutableBytes { dataOutPointer in
dataIn.withUnsafeBytes { dataInPointer -> CCCryptorStatus in
guard let dataInPointerBaseAddress = dataInPointer.baseAddress,
let dataOutPointerBaseAddress = dataOutPointer.baseAddress else {
return Int32(kCCParamError)
}
return CCCryptorUpdate(
cryptor,
dataInPointerBaseAddress,
dataIn.count,
dataOutPointerBaseAddress,
dataOutLength,
&dataOutMoved
)
}
}

if status != kCCSuccess {
throw CryptoError.updateError(Int(status))
}

var dataOutMovedFinal = 0
status = dataOut.withUnsafeMutableBytes { dataOutPointer in
guard let dataOutPointerBaseAddress = dataOutPointer.baseAddress else {
return Int32(kCCParamError)
}

return CCCryptorFinal(
cryptor,
dataOutPointerBaseAddress.advanced(by: dataOutMoved),
dataOutLength - dataOutMoved,
&dataOutMovedFinal
)
}

if status != kCCSuccess {
throw CryptoError.finalError(Int(status))
}

dataOut.count = dataOutMoved + dataOutMovedFinal

return dataOut
}
10 changes: 10 additions & 0 deletions OmiseSDK/Sources/3DS/Crypto/String+PemCert.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Foundation

extension String {
var pemCertificate: String {
self
.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "")
.replacingOccurrences(of: "-----END CERTIFICATE-----", with: "")
.replacingOccurrences(of: "\r\n", with: "")
}
}
15 changes: 15 additions & 0 deletions OmiseSDK/Sources/3DS/Crypto/String+sha512.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation
import CommonCrypto

extension String {
public var sha512: Data {
let data = Data(self.utf8)
var hash = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))

data.withUnsafeBytes {
_ = CC_SHA512($0.baseAddress, CC_LONG(data.count), &hash)
}

return Data(hash)
}
}
24 changes: 24 additions & 0 deletions OmiseSDK/Sources/3DS/NetceteraConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation

public struct NetceteraConfig {
public let id: String
public let deviceInfoEncryptionAlg: String
public let deviceInfoEncryptionEnc: String
public let deviceInfoEncryptionCertPem: String
public let directoryServerId: String
public let key: String
public let messageVersion: String
}

extension NetceteraConfig: Decodable {
/// Mapping keys to encode/decode JSON string
private enum CodingKeys: String, CodingKey {
case id = "identifier"
case deviceInfoEncryptionAlg = "device_info_encryption_alg"
case deviceInfoEncryptionEnc = "device_info_encryption_enc"
case deviceInfoEncryptionCertPem = "device_info_encryption_cert_pem"
case directoryServerId = "directory_server_id"
case key
case messageVersion = "message_version"
}
}
Loading

0 comments on commit 4a2b23c

Please sign in to comment.