Skip to content

Commit

Permalink
Public release 1.0.4
Browse files Browse the repository at this point in the history
Public release 1.0.4
  • Loading branch information
EugeneIOs authored Feb 25, 2021
2 parents 2532dd7 + 3e9ab8a commit 99239e9
Show file tree
Hide file tree
Showing 72 changed files with 1,031 additions and 148 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Table of contents
* [Import SDK](#import-sdk)
* [Create VGSShow instance and VGS UI Elements](#create-vgsshow-instance-and-vgs-ui-elements)
* [Make reveal data request](#make-reveal-data-request)
* [Local Testing](#local-testing)
* [Demo Application](#demo-application)
* [Releases](#releases)
* [Metrics](#metrics)
Expand Down Expand Up @@ -173,6 +174,9 @@ func revealData() {
}
}
```
## Local Testing
To test and verify your integration with VGS directly from your local machine you can use [VGS Satellite](https://github.com/verygoodsecurity/vgs-satellite).
Check our Satellite [integration guide](https://www.verygoodsecurity.com/docs/vgs-show/ios-sdk/vgs-satellite-integration).

## Demo Application
Demo application for collecting card data on iOS is <a href="https://github.com/verygoodsecurity/vgs-show-ios/tree/main/VGSShowDemoApp">here</a>.
Expand Down
52 changes: 47 additions & 5 deletions Sources/VGSShowSDK/Core/APIClient/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,48 @@

import Foundation

/// Holds base API client logic.
internal class APIClient {

typealias RequestCompletion = ((_ response: APIRequestResult) -> Void)?

// MARK: - Constants

enum Constants {
/// Constants.
internal enum Constants {
static let validStatuses: Range<Int> = 200..<300
}

// MARK: - Vars

var customHeader: VGSHTTPHeaders?
/// Custom headers.
internal var customHeader: VGSHTTPHeaders?

/// Default request headers with vgs client info.
internal static let defaultHttpHeaders: VGSHTTPHeaders = {
// Add Headers
let version = ProcessInfo.processInfo.operatingSystemVersion
let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"

let source = VGSAnalyticsClient.Constants.Metadata.source
let medium = VGSAnalyticsClient.Constants.Metadata.medium
let trStatus = VGSAnalyticsClient.shared.shouldCollectAnalytics ? "default" : "none"

return [
"vgs-client": "source=\(source)&medium=\(medium)&content=\(Utils.vgsShowVersion)&osVersion=\(versionString)&vgsShowSessionId=\(VGSShowAnalyticsSession.shared.vgsShowSessionId)"
"vgs-client": "source=\(source)&medium=\(medium)&content=\(Utils.vgsShowVersion)&osVersion=\(versionString)&vgsShowSessionId=\(VGSShowAnalyticsSession.shared.vgsShowSessionId)&tr=\(trStatus)"
]
}()

/// URLSession object.
internal let urlSession = URLSession(configuration: .ephemeral)

/// Vault ID.
private let vaultId: String

/// Vault URL.
private let vaultUrl: URL?

/// Base URL depends on current api policy.
internal var baseURL: URL? {
return self.hostURLPolicy.url
}
Expand All @@ -50,11 +59,18 @@ internal class APIClient {
/// Serial queue for syncing requests on resolving hostname flow.
private let dataSyncQueue: DispatchQueue = .init(label: "iOS.VGSShowSDK.ResolveHostNameRequestsQueue")

/// Sync semaphore.
private let syncSemaphore: DispatchSemaphore = .init(value: 1)

// MARK: - Initialization

required init(tenantId: String, regionalEnvironment: String, hostname: String?) {
/// Initialization.
/// - Parameters:
/// - tenantId: `String` object, should be valid tenant id.
/// - regionalEnvironment: `String` object, should be valid environment.
/// - hostname: `String?` object, should be valid hostname or `nil`.
/// - satellitePort: `Int?` object, custom port for satellite configuration. **IMPORTANT! Use only with .sandbox environment!**.
required internal init(tenantId: String, regionalEnvironment: String, hostname: String?, satellitePort: Int?) {
self.vaultUrl = VGSShow.generateVaultURL(tenantId: tenantId, regionalEnvironment: regionalEnvironment)
self.vaultId = tenantId

Expand All @@ -64,6 +80,26 @@ internal class APIClient {
return
}

// Check satellite port is *nil* for regular API flow.
guard satellitePort == nil else {
// Try to build satellite URL.
guard let port = satellitePort, let satelliteURL = VGSShowSatelliteUtils.buildSatelliteURL(with: regionalEnvironment, hostname: hostname, satellitePort: port) else {

// Use vault URL as fallback if cannot resolve satellite flow.
self.hostURLPolicy = .vaultURL(validVaultURL)
return
}

// Use satellite URL and return.
self.hostURLPolicy = .satelliteURL(satelliteURL)

let message = "Satellite has been configured successfully! Satellite URL is: \(satelliteURL.absoluteString)"
let event = VGSLogEvent(level: .info, text: message)
VGSLogger.shared.forwardLogEvent(event)

return
}

guard let hostnameToResolve = hostname, !hostnameToResolve.isEmpty else {

if let name = hostname, name.isEmpty {
Expand All @@ -84,7 +120,7 @@ internal class APIClient {

// MARK: - Public

func sendRequestWithJSON(path: String, method: VGSHTTPMethod = .post, value: VGSJSONData?, completion block: RequestCompletion) {
internal func sendRequestWithJSON(path: String, method: VGSHTTPMethod = .post, value: VGSJSONData?, completion block: RequestCompletion) {

let payload = VGSRequestPayloadBody.json(value)
resolveURLForRequest(path: path, method: method, payload: payload, block: block)
Expand All @@ -102,9 +138,15 @@ internal class APIClient {

let url: URL?

let infoEventText = "API will start request with current URL policy: \(hostURLPolicy.description)"
let infoEvent = VGSLogEvent(level: .info, text: infoEventText)
VGSLogger.shared.forwardLogEvent(infoEvent)

switch hostURLPolicy {
case .invalidVaultURL:
url = nil
case .satelliteURL(let satelliteURL):
url = satelliteURL
case .vaultURL(let vaultURL):
url = vaultURL
case .customHostURL(let status):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ internal enum APICustomHostStatus {
*/
case useDefaultVault(_ vaultURL: URL)

var url: URL? {
/// `URL` inferred from custom hostname status flow.
internal var url: URL? {
switch self {
case .isResolving:
return nil
Expand All @@ -42,3 +43,20 @@ internal enum APICustomHostStatus {
}
}
}

// MARK: - CustomStringConvertible

extension APICustomHostStatus: CustomStringConvertible {

/// Custom description.
var description: String {
switch self {
case .useDefaultVault(let url):
return ".useDefaultVault, default Vault url: \(url.absoluteString)"
case .resolved(let url):
return ".resolved, custom host url: \(url.absoluteString)"
case .isResolving(let hostnameToResolve):
return ".isResolving hostname in progress for \(hostnameToResolve)"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import Foundation

/// Defines API client policy for resolving URL.
internal enum APIHostURLPolicy {

/**
Expand All @@ -28,14 +29,44 @@ internal enum APIHostURLPolicy {
*/
case invalidVaultURL

var url: URL? {
/**
Use satellite url for local testing.
- Parameters:
- url: `URL` object, should be valid satellite URL for local testing.
*/
case satelliteURL(_ satelliteURL: URL)

/// `URL?` inferred from current API policy flow.
internal var url: URL? {
switch self {
case .invalidVaultURL:
return nil
case .vaultURL(let vaultURL):
return vaultURL
case .customHostURL(let hostStatus):
return hostStatus.url
case .satelliteURL(let satelliteURL):
return satelliteURL
}
}
}

// MARK: - CustomStringConvertible

extension APIHostURLPolicy: CustomStringConvertible {

/// Custom description.
var description: String {
switch self {
case .invalidVaultURL:
return "*.invalidVaultURL* - API url is *nil*, SDK has incorrect configuration."
case .vaultURL(let vaultURL):
return "*.vaultURL* - use regular flow, url: \(vaultURL.absoluteString)"
case .customHostURL(let status):
return "*.customHostURL* with status: \(status.description)"
case .satelliteURL(let satelliteURL):
return "*.satelliteURL* - url: \(satelliteURL.absoluteString)"
}
}
}
Loading

0 comments on commit 99239e9

Please sign in to comment.