Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fa64e33
refactor(GiniBankAPILibrary): Remove pinning SPM
ValentinaIancu-Gini Mar 25, 2025
5692de7
refactor(GiniCaptureSDK): Remove pinning SPM
ValentinaIancu-Gini Mar 25, 2025
dda7a3b
refactor(GiniBankSDK): Remove pinning SPM
ValentinaIancu-Gini Mar 25, 2025
43f08ff
refactor(GiniBankSDK): Remove pinning example project
ValentinaIancu-Gini Mar 25, 2025
10c1e2d
refactor(GiniBankSDK): Refactor unit tests for GalleryManager
ValentinaIancu-Gini Mar 25, 2025
95c7872
feat(GiniBankAPILibrary): Add Gini internal code for pinning configur…
ValentinaIancu-Gini Mar 25, 2025
e7a24a3
feat(GiniBankAPILibrary): Update documentation after removing TrustKit
ValentinaIancu-Gini Mar 25, 2025
69061ac
feat(GiniBankAPILibrary): Update initializers in `GiniBankAPI` to inc…
ValentinaIancu-Gini Mar 25, 2025
9e33332
fix(GiniCaptureSDK): Fix Xcode warnings
ValentinaIancu-Gini Mar 28, 2025
9d7689b
feat(GiniBankSDKExample): Add example to test Screen API with default…
ValentinaIancu-Gini Mar 28, 2025
095b3b3
feat(GiniBankSDKExample): Add integration tests for pinning
ValentinaIancu-Gini Mar 31, 2025
6f745cd
feat(GiniBankSDKExample): Add extra comment
ValentinaIancu-Gini Mar 31, 2025
cbb355d
feat(GiniBankSDK): Add methods to support pinning configuration to in…
ValentinaIancu-Gini Mar 31, 2025
3576416
fix(GiniBankSDK): Fix documentation style
ValentinaIancu-Gini Apr 1, 2025
a8352c0
fix(GiniBankAPILibrary): Update documentation after removing TrustKit
ValentinaIancu-Gini Apr 1, 2025
30769c5
fix(GiniBankSDK): Fix documentation
ValentinaIancu-Gini Apr 1, 2025
423d7ff
ci: Update workflows to remove pinning packages and projects
ValentinaIancu-Gini Apr 1, 2025
4838493
feat(GiniBankSDKExample): Remove pinning example app
ValentinaIancu-Gini Apr 1, 2025
20fbc44
fix(GiniBankAPILibrary): Update jazzy file
ValentinaIancu-Gini Apr 8, 2025
f0f03a5
fix(GiniBankAPILibrary): Improve code documentation
ValentinaIancu-Gini Apr 22, 2025
50ce79a
fix(GiniBankSDK): Improve code documentation
ValentinaIancu-Gini Apr 22, 2025
5aa6e39
Merge branch 'GiniBankSDK-release-4.0.0' into PP-1067-Remove-TrustKit…
ValentinaIancu-Gini Apr 22, 2025
49cbfff
fix(GiniBankSDKExample): Fix integration test for payment request for…
ValentinaIancu-Gini Apr 22, 2025
e4438bf
Merge branch 'GiniBankSDK-release-4.0.0' into PP-1067-Remove-TrustKit…
ValentinaIancu-Gini Jul 15, 2025
f701cc3
Merge branch 'GiniBankSDK-release-4.0.0' into PP-1067-Remove-TrustKit…
ValentinaIancu-Gini Oct 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions .github/workflows/bank-api-library.check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
target: [GiniBankAPILibrary, GiniBankAPILibraryPinning]
target: [GiniBankAPILibrary]
destination: ['platform=iOS Simulator,OS=18.5,name=iPhone 16']
steps:
- uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
Expand All @@ -38,12 +38,6 @@ jobs:
cd BankAPILibrary/GiniBankAPILibrary
swift package update

- name: Check package GiniBankAPILibraryPinning
if: ${{ matrix.target == 'GiniBankAPILibraryPinning' }}
run: |
cd BankAPILibrary/GiniBankAPILibraryPinning
swift package update

# Setup ruby to run unit tests for the GiniBankAPILibrary
- name: Setup ruby
uses: ruby/setup-ruby@dffc446db9ba5a0c4446edb5bca1c5c473a806c5 # v1.245.0
Expand Down
18 changes: 1 addition & 17 deletions .github/workflows/bank-api-library.release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,7 @@ jobs:
"repo_password": "${{ secrets.RELEASE_GITHUB_PASSWORD }}",
"ci": "true"
}

- name: Publish GiniBankAPILibraryPinning package to the release repo
uses: maierj/fastlane-action@5a3b971aaa26776459bb26894d6c1a1a84a311a7 # v3.1.0
with:
lane: 'publish_swift_package'
options: >
{
"project_folder": "BankAPILibrary",
"package_folder": "GiniBankAPILibraryPinning",
"version_file_path": "BankAPILibrary/GiniBankAPILibraryPinning/Sources/GiniBankAPILibraryPinning/GiniBankAPILibraryPinningVersion.swift",
"git_tag": "${{ github.ref }}",
"repo_url": "https://github.com/gini/bank-api-library-pinning-ios.git",
"repo_user": "${{ secrets.RELEASE_GITHUB_USER }}",
"repo_password": "${{ secrets.RELEASE_GITHUB_PASSWORD }}",
"ci": "true"
}


release-documentation:
needs: release
uses: gini/gini-mobile-ios/.github/workflows/bank-api-library.publish.docs.yml@main
Expand Down
27 changes: 3 additions & 24 deletions .github/workflows/bank-sdk.check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
target: [GiniBankSDK, GiniBankSDKPinning]
destination: ['platform=iOS Simulator,OS=18.5,name=iPhone 16']
target: [GiniBankSDK]
destination: ['platform=iOS Simulator,OS=17.5,name=iPhone 15']
steps:
- uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
Expand All @@ -39,12 +39,6 @@ jobs:
cd BankSDK/GiniBankSDK
swift package update

- name: Check package GiniBankSDKPinning
if: ${{ matrix.target == 'GiniBankSDKPinning' }}
run: |
cd BankSDK/GiniBankSDKPinning
swift package update

# Setup ruby to run unit tests for the GiniBankSDK
- name: Setup ruby
uses: ruby/setup-ruby@dffc446db9ba5a0c4446edb5bca1c5c473a806c5 # v1.245.0
Expand Down Expand Up @@ -80,19 +74,4 @@ jobs:
CODE_SIGNING_REQUIRED=NO
ONLY_ACTIVE_ARCH=NO
CLIENT_ID="gini-mobile-test"
CLIENT_SECRET="$TEST_CLIENT_SECRET"

- name: Build pinning example app and run unit and integration tests
env:
TEST_CLIENT_SECRET: ${{ secrets.GINI_MOBILE_TEST_CLIENT_SECRET }}
if: ${{ matrix.target == 'GiniBankSDKPinning' }}
run: >
xcodebuild clean test
-project BankSDK/GiniBankSDKPinningExample/GiniBankSDKPinningExample.xcodeproj
-scheme "GiniBankSDKPinningExampleTests"
-destination "${{ matrix.destination }}"
CODE_SIGN_IDENTITY=""
CODE_SIGNING_REQUIRED=NO
ONLY_ACTIVE_ARCH=NO
CLIENT_ID="gini-mobile-test"
CLIENT_SECRET="$TEST_CLIENT_SECRET"
CLIENT_SECRET="${{ secrets.GINI_MOBILE_TEST_CLIENT_SECRET }}"
16 changes: 0 additions & 16 deletions .github/workflows/bank-sdk.release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,6 @@ jobs:
"ci": "true"
}

- name: Publish GiniBankSDKPinning package to the release repo
uses: maierj/fastlane-action@5a3b971aaa26776459bb26894d6c1a1a84a311a7 # v3.1.0
with:
lane: 'publish_swift_package'
options: >
{
"project_folder": "BankSDK",
"package_folder": "GiniBankSDKPinning",
"version_file_path": "BankSDK/GiniBankSDKPinning/Sources/GiniBankSDKPinning/GiniBankSDKPinningVersion.swift",
"git_tag": "${{ github.ref }}",
"repo_url": "https://github.com/gini/bank-sdk-pinning-ios.git",
"repo_user": "${{ secrets.RELEASE_GITHUB_USER }}",
"repo_password": "${{ secrets.RELEASE_GITHUB_PASSWORD }}",
"ci": "true"
}

release-documentation:
needs: release
uses: gini/gini-mobile-ios/.github/workflows/bank-sdk.publish.docs.yml@main
Expand Down
11 changes: 3 additions & 8 deletions .github/workflows/capture-sdk.check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
target: [GiniCaptureSDK, GiniCaptureSDKPinning]
destination: ['platform=iOS Simulator,OS=18.5,name=iPhone 16']
target: [GiniCaptureSDK]
destination: ['platform=iOS Simulator,OS=17.5,name=iPhone 15']
steps:
- uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
Expand All @@ -38,13 +38,8 @@ jobs:
cd CaptureSDK/GiniCaptureSDK
swift package update

- name: Check package GiniCaptureSDKPinning
if: ${{ matrix.target == 'GiniCaptureSDKPinning' }}
run: |
cd CaptureSDK/GiniCaptureSDKPinning
swift package update

# Setup ruby to run unit tests for the GiniCaptureSDK and GiniCaptureSDKPinning
# Setup ruby to run unit tests for the GiniCaptureSDK
- name: Setup ruby
uses: ruby/setup-ruby@dffc446db9ba5a0c4446edb5bca1c5c473a806c5 # v1.245.0
with:
Expand Down
16 changes: 0 additions & 16 deletions .github/workflows/capture-sdk.release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,6 @@ jobs:
"ci": "true"
}

- name: Publish GiniCaptureSDKPinning package to the release repo
uses: maierj/fastlane-action@5a3b971aaa26776459bb26894d6c1a1a84a311a7 # v3.1.0
with:
lane: 'publish_swift_package'
options: >
{
"project_folder": "CaptureSDK",
"package_folder": "GiniCaptureSDKPinning",
"version_file_path": "CaptureSDK/GiniCaptureSDKPinning/Sources/GiniCaptureSDKPinning/GiniCaptureSDKPinningVersion.swift",
"git_tag": "${{ github.ref }}",
"repo_url": "https://github.com/gini/capture-sdk-pinning-ios.git",
"repo_user": "${{ secrets.RELEASE_GITHUB_USER }}",
"repo_password": "${{ secrets.RELEASE_GITHUB_PASSWORD }}",
"ci": "true"
}

release-documentation:
needs: release
uses: gini/gini-mobile-ios/.github/workflows/capture-sdk.publish.docs.yml@main
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ You can also specify a custom path segment, if your proxy url requires it:

## Public Key Pinning

If you want to use _Certificate pinning_, then pass your public key pinning configuration (see [TrustKit repo](https://github.com/datatheorem/TrustKit) for more information) as follows:
If you want to use _Certificate pinning_, then pass your public key pinning configuration as follows:

```swift
let yourPublicPinningConfig = [
kTSKPinnedDomains: [
"Bank-api.gini.net": [
"pay-api.gini.net": [
kTSKPublicKeyHashes: [
// old *.gini.net public key
"cNzbGowA+LNeQ681yMm8ulHxXiGojHE8qAjI+M7bIxU=",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,7 @@ dependencies: [
]
```

In case that you want to use the certificate pinning in the library, add `GiniBankAPILibraryPinning`:
```swift
dependencies: [
.package(url: "https://github.com/gini/bank-api-library-pinning-ios.git", .exact("3.8.0"))
]
```

## Manually

If you prefer not to use a dependency management tool, you can integrate the Gini Bank API Library into your project manually.
To do so drop the [GiniBankAPILibrary](https://github.com/gini/gini-mobile-ios/tree/main/BankAPILibrary/GiniBankAPILibrary/Sources/GiniBankAPILibrary) (classes and assets) folder into your project and add the files to your target.

Xcode will automatically check your project for swift files and will create an autogenerated import header for you.
Use this header in an Objective-C project by adding

```Obj-C
#import "YourProjectName-Swift.h"
```

to your implementation or header files. Note that spaces in your project name result in underscores. So `Your Project` becomes `Your_Project-Swift.h`.
28 changes: 2 additions & 26 deletions BankAPILibrary/GiniBankAPILibrary/Documentation/source/License.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Always make sure to ship all license notices and permissions with your applicati

## The Gini Bank API Library for iOS is licensed under a Private License.

Copyright (c) 2014-2024, Gini GmbH
Copyright (c) 2014-2025, Gini GmbH
All rights reserved.

The Gini Bank API Library is licensed through Gini GmbH ("Gini") and may not be
Expand All @@ -20,7 +20,7 @@ Always make sure to ship all license notices and permissions with your applicati

## The Gini Bank API Library Pinning for iOS is licensed under a Private License.

Copyright (c) 2014-2024, Gini GmbH
Copyright (c) 2014-2025, Gini GmbH
All rights reserved.

The Gini Bank API Library Pinning is licensed through Gini GmbH ("Gini") and may not be
Expand All @@ -32,27 +32,3 @@ Always make sure to ship all license notices and permissions with your applicati

For license related inquiries contact Gini via the email address
[email protected].

## [TrustKit](https://github.com/datatheorem/TrustKit)

The MIT License (MIT)

Copyright (c) 2015 Data Theorem, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,36 @@ To initialize the library, you will need to use the snippet below:
secret: "your-secret",
domain: "your-domain"))
.build()
```
```

## Public Key Pinning

Your pinning configuration should have `pay-api.gini.net` domain like in the example below:

```swift
let yourPublicPinningConfig = [
kTSKPinnedDomains: [
"pay-api.gini.net": [
kTSKPublicKeyHashes: [
// old *.gini.net public key
"cNzbGowA+LNeQ681yMm8ulHxXiGojHE8qAjI+M7bIxU=",
// new *.gini.net public key, active from around June 2020
"zEVdOCzXU8euGVuMJYPr3DUU/d1CaKevtr0dW0XzZNo="
]],
"user.gini.net": [
kTSKPublicKeyHashes: [
// old *.gini.net public key
"cNzbGowA+LNeQ681yMm8ulHxXiGojHE8qAjI+M7bIxU=",
// new *.gini.net public key, active from around June 2020
"zEVdOCzXU8euGVuMJYPr3DUU/d1CaKevtr0dW0XzZNo="
]],
]] as [String: Any]

let giniBankAPI = GiniBankAPI
.Builder(client: Client(id: "your-id",
secret: "your-secret",
domain: "your-domain"),
api: .default,
pinningConfig: yourPublicPinningConfig)
.build()
```
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,14 @@ extension GiniBankAPI {
public var sessionDelegate: URLSessionDelegate? = nil

/**
* Creates a Gini Bank API Library.
* Initializes a Gini Bank API Library instance.
*
* - Parameter client: The Gini Bank API client credentials
* - Parameter api: The Gini Bank API that the library interacts with. `APIDomain.default` by default
* - Parameter userApi: The Gini User API that the library interacts with. `UserDomain.default` by default
* - Parameter logLevel: The log level. `LogLevel.none` by default.
* - Parameter sessionDelegate: The session delegate `URLSessionDelegate` will be set for Gini Bank API Library with `Pinning`.
* - Parameters:
* - client: The Gini Bank API client credentials
* - api: The Gini Bank API that the library interacts with. `APIDomain.default` by default
* - userApi: The Gini User API that the library interacts with. `UserDomain.default` by default
* - logLevel: The desired log level. Defaults to `LogLevel.none`.
* - sessionDelegate: The session delegate `URLSessionDelegate` will be set for Gini Bank API Library with `Pinning`.
*/
public init(client: Client,
api: APIDomain = .default,
Expand All @@ -102,9 +103,15 @@ extension GiniBankAPI {
self.logLevel = logLevel
self.sessionDelegate = sessionDelegate
}

/**
* Creates a Gini Bank API Library to be used with a transparent proxy and a custom api access token source.
* Initializes a Gini Bank API Library instance configured with a transparent proxy and a custom api access token source.
*
* - Parameters:
* - customApiDomain: A custom api domain string.
* - alternativeTokenSource: A protocol for using custom api access token
* - logLevel: The desired log level. Defaults to `LogLevel.none`.
* - sessionDelegate: The session delegate `URLSessionDelegate` will be set for Gini Bank API Library with `Pinning`.
*/
public init(customApiDomain: String = APIDomain.default.domainString,
alternativeTokenSource: AlternativeTokenSource,
Expand All @@ -116,6 +123,47 @@ extension GiniBankAPI {
self.sessionDelegate = sessionDelegate
}

/**
* Initializes a Gini Bank API Library instance configured with a certificate pinning configuration.
*
* - Parameters:
* - client: The Gini Bank API client credentials
* - api: The Gini Bank API that the library interacts with. `APIDomain.default` by default
* - userApi: The Gini User API that the library interacts with. `UserDomain.default` by default
* - pinningConfig: A dictionary specifying the certificate pinning configuration in the format `["PinnedDomains": ["PublicKeyHashes"]]`.
* - logLevel: The desired log level. Defaults to `LogLevel.none`.
*/
public init(client: Client,
api: APIDomain = .default,
userApi: UserDomain = .default,
pinningConfig: [String: [String]],
logLevel: LogLevel = .none) {
self.init(client: client,
api: api,
userApi: userApi,
logLevel: logLevel,
sessionDelegate: GiniSessionDelegate(pinningConfig: pinningConfig))
}

/**
* Initializes a Gini Bank API Library instance configured with a transparent proxy and a custom api access token source and certificate pinning configuration.
*
* - Parameters:
* - customApiDomain: A custom api domain string.
* - alternativeTokenSource: A protocol-conforming instance used to provide a custom API access token.
* - pinningConfig: A dictionary specifying the certificate pinning configuration in the format `["PinnedDomains": ["PublicKeyHashes"]]`.
* - logLevel: The desired log level. Defaults to `LogLevel.none`.
*/
public init(customApiDomain: String = APIDomain.default.domainString,
alternativeTokenSource: AlternativeTokenSource,
pinningConfig: [String: [String]],
logLevel: LogLevel = .none) {
self.init(customApiDomain: customApiDomain,
alternativeTokenSource: alternativeTokenSource,
logLevel: logLevel,
sessionDelegate: GiniSessionDelegate(pinningConfig: pinningConfig))
}

public func build() -> GiniBankAPI {
// Save client information
save(client)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// GiniSessionDelegate.swift
//
//
// Copyright © 2024 Gini GmbH. All rights reserved.
//

import Foundation

class GiniSessionDelegate: NSObject, URLSessionDelegate {
private let pinningManager: SSLPinningManager

internal init(pinningConfig: [String: [String]]) {
self.pinningManager = SSLPinningManager(pinningConfig: pinningConfig)
}

func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
pinningManager.validate(challenge: challenge, completionHandler: completionHandler)
}
}
Loading
Loading