Skip to content
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
b3efb25
Add PingOneMFA actionable push notification support to the SDK module…
gioraping May 25, 2026
0ecfd9c
fix(PingExample): use iOS 16-compatible .onChange(of:) in PingOneMFAN…
gioraping May 26, 2026
585eac3
fix(PingOneMFA): add MFAPushNotification typealias to resolve module/…
gioraping May 26, 2026
4ebb157
fix(PingExample): initialize PingOneMFA on demand in didRegisterForRe…
gioraping May 26, 2026
d3cdc58
fix project files
gioraping May 26, 2026
f2e1550
fix
gioraping May 26, 2026
3120dad
string fixes
gioraping May 26, 2026
ddcf9eb
uneeded metadata removed
gioraping May 26, 2026
f47763c
removing config API
gioraping May 28, 2026
86f62ec
renaming public SDK api
gioraping May 28, 2026
b38a1ae
remving reference
gioraping May 28, 2026
57fc057
refactoring
gioraping May 31, 2026
5a7d46b
added readme file
gioraping May 31, 2026
4004d8c
account ui small change
gioraping May 31, 2026
977d154
show detailed error messages
gioraping May 31, 2026
e26db05
documination
gioraping May 31, 2026
09c6dc6
added fixes to readme
gioraping May 31, 2026
e5ccd5c
added link
gioraping May 31, 2026
647eaef
fix
gioraping May 31, 2026
41bd9b5
Merge branch 'develop' into feature/mfa-integration
gioraping May 31, 2026
82ecd8f
api refactor returning list of errors
gioraping Jun 1, 2026
1a975ee
dismissh notification view in case push isCancelAuth
gioraping Jun 1, 2026
bd0b0bf
better success message in case of deny
gioraping Jun 1, 2026
1f8d111
refactoring setDeviceToken and getDeviceInfo API
gioraping Jun 2, 2026
3801831
fix inline
gioraping Jun 7, 2026
2fa71a5
fix
gioraping Jun 7, 2026
35d3f58
fix
gioraping Jun 7, 2026
a46f8d1
fix
gioraping Jun 8, 2026
59536a7
handle race condition during initialize
gioraping Jun 16, 2026
2c063eb
Add PingOneMFADeviceInfo result type
gioraping Jun 16, 2026
d875db2
fixes
gioraping Jun 16, 2026
be0a62a
better handling of parsing exceptions
gioraping Jun 21, 2026
6be1c9c
fixes in PingMFAError class
gioraping Jun 21, 2026
1a0e196
tests fixes
gioraping Jun 21, 2026
2be1e5d
test fixes
gioraping Jun 21, 2026
5ba0c2d
readme updated
gioraping Jun 21, 2026
27819d7
fix sample app issues
gioraping Jun 21, 2026
b9b507e
fix PushNotification
gioraping Jun 21, 2026
8c0573c
Merge branch 'develop' into feature/mfa-integration
gioraping Jun 21, 2026
2629ab9
fix test
gioraping Jun 21, 2026
e108fc3
fix comments
gioraping Jun 22, 2026
7aaec5f
fix
gioraping Jun 22, 2026
bee7e2c
fixes in handling push notification flow
gioraping Jun 23, 2026
5e5368b
no message
gioraping Jun 23, 2026
3aa73e1
readme fixes
gioraping Jun 23, 2026
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
11 changes: 10 additions & 1 deletion Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ let package = Package(
.library(name: "PingOath", targets: ["PingOath"]),
.library(name: "PingPush", targets: ["PingPush"]),
.library(name: "PingAuthMigration", targets: ["PingAuthMigration"]),
.library(name: "PingOneMFA", targets: ["PingOneMFA"]),

// MARK: - Utilities
.library(name: "PingBinding", targets: ["PingBinding"])
Expand All @@ -57,7 +58,8 @@ let package = Package(
.package(url: "https://github.com/pingidentity/pingone-signals-sdk-ios.git", "5.4.0"..<"5.5.0"),
.package(url: "https://github.com/facebook/facebook-ios-sdk.git", "16.3.1"..<"16.4.0"),
.package(url: "https://github.com/google/GoogleSignIn-iOS.git", exact: "9.0.0"),
.package(url: "https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk.git", "18.8.1"..<"18.9.0")
.package(url: "https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk.git", "18.8.1"..<"18.9.0"),
.package(url: "https://github.com/pingidentity/pingone-mobile-sdk-ios.git", exact: "2.3.1")
],
targets: [
// MARK: - Foundation Targets (No dependencies)
Expand Down Expand Up @@ -303,7 +305,16 @@ let package = Package(
exclude: ["AuthMigration.h"],
resources: [.copy("PrivacyInfo.xcprivacy")]
),

.target(
name: "PingOneMFA",
dependencies: [
.product(name: "PingOneSDK", package: "pingone-mobile-sdk-ios")
],
path: "PingOneMFA/PingOneMFA",
exclude: ["PingOneMFA.h"],
resources: [.copy("PrivacyInfo.xcprivacy")]
),

// MARK: - Utility Targets
.target(
name: "PingBinding",
Expand Down
592 changes: 592 additions & 0 deletions PingOneMFA/PingOneMFA.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FILEHEADER</key>
<string>
// ___FILENAME___
// ___PACKAGENAME___
//
// Copyright (c) ___YEAR___ Ping Identity Corporation. All rights reserved.
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//
</string>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1610"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14C0CBAE9D4D412388F63F45"
BuildableName = "PingOneMFATests.xctest"
BlueprintName = "PingOneMFATests"
ReferencedContainer = "container:PingOneMFA.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "14C0CBAE9D4D412388F63F45"
BuildableName = "PingOneMFATests.xctest"
BlueprintName = "PingOneMFATests"
ReferencedContainer = "container:PingOneMFA.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
54 changes: 54 additions & 0 deletions PingOneMFA/PingOneMFA/AccountParser.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// AccountParser.swift
// PingOneMFA
//
// Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//

import Foundation

internal struct AccountParser {

internal static func parse(_ deviceInfo: [String: Any]?) -> [PingOneMfaAccount] {
guard let deviceInfo,
let data = try? JSONSerialization.data(withJSONObject: deviceInfo),
Comment thread
gioraping marked this conversation as resolved.
Outdated
let decoded = try? JSONDecoder().decode([String: RegionDto].self, from: data)
else { return [] }

return decoded.flatMap { region, regionDto in
regionDto.users.map { user in
PingOneMfaAccount(
region: region,
id: user.id ?? "",
deviceId: user.device?.id ?? "",
environmentId: user.environment?.id ?? "",
name: user.name?.given ?? "",
family: user.name?.family ?? ""
)
}
}
}
}

private struct RegionDto: Decodable {
var users: [UserDto] = []
}

private struct UserDto: Decodable {
var id: String?
var environment: IdContainer?
var device: IdContainer?
var name: NameDto?
}

private struct IdContainer: Decodable {
var id: String?
}

private struct NameDto: Decodable {
var given: String?
var family: String?
}
29 changes: 29 additions & 0 deletions PingOneMFA/PingOneMFA/Geo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// PingOneMFAConfig.swift
Comment thread
gioraping marked this conversation as resolved.
Outdated
// PingOneMFA
//
// Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//

import Foundation

/// Geographic region selector for the PingOneMFA SDK.
///
/// Specifies the PingOne cloud region to connect to. Maps 1:1 to `PingOneSDK.PingOneGeo`
/// without leaking the upstream module.
public enum Geo: Sendable, Equatable {
/// The North America region.
case northAmerica
/// The Europe region.
case europe
/// The Australia region.
case australia
/// The Canada region.
case canada
/// The Singapore region.
case singapore
}

29 changes: 29 additions & 0 deletions PingOneMFA/PingOneMFA/OtpCodeInfo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// OtpCodeInfo.swift
// PingOneMFA
//
// Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.
//

import Foundation

/// A value type representing a one-time passcode with its validity window.
public struct OtpCodeInfo: Sendable, Equatable {
/// The current OTP code string to display to the user.
public let code: String
/// The number of seconds remaining before this code expires.
public let secondsRemaining: Int

/// Creates an `OtpCodeInfo` with the given code and remaining validity.
///
/// - Parameters:
/// - code: The current OTP code string.
/// - secondsRemaining: Seconds until the code expires.
public init(code: String, secondsRemaining: Int) {
self.code = code
self.secondsRemaining = secondsRemaining
}
}
21 changes: 21 additions & 0 deletions PingOneMFA/PingOneMFA/PingOneMFA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// PingOneMFA.h
// PingOneMFA
//
// Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
//
// This software may be modified and distributed under the terms
// of the MIT license. See the LICENSE file for details.


#import <Foundation/Foundation.h>

//! Project version number for PingOneMFA.
FOUNDATION_EXPORT double PingOneMFAVersionNumber;

//! Project version string for PingOneMFA.
FOUNDATION_EXPORT const unsigned char PingOneMFAVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <PingOneMFA/PublicHeader.h>


Loading