Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion MIRACLTrust.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Pod::Spec.new do |s|
s.name = "MIRACLTrust"
s.summary = "MIRACL Trust SDK for iOS"
s.requires_arc = true
s.version = "1.6.0"
s.version = "1.6.1"
s.license = { :type => "Apache2", :file => "LICENSE" }
s.author = { "MIRACL" => "[email protected]" }
s.homepage = "https://github.com/miracl/trust-sdk-ios"
Expand Down
10 changes: 8 additions & 2 deletions MIRACLTrust/MIRACLTrust-Sources/MIRACLTrust.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,21 @@ import Foundation
/// - completionHandler: a closure called when the verification has been completed. It can contain a verification response object or an optional error object.
@objc public func _sendVerificationEmail(
userId: String,
crossDeviceSession: CrossDeviceSession,
crossDeviceSession: CrossDeviceSession? = nil,
completionHandler: @escaping VerificationCompletionHandler
) {
do {
var sessionType = SessionType.noSession

if let crossDeviceSession {
sessionType = .crossDevice(sessionId: crossDeviceSession.sessionId)
}

let verificator = try Verificator(
userId: userId,
projectId: projectId,
deviceName: deviceName,
sessionType: .crossDevice(sessionId: crossDeviceSession.sessionId),
sessionType: sessionType,
miraclAPI: miraclAPI,
completionHandler: completionHandler
)
Expand Down
20 changes: 10 additions & 10 deletions MIRACLTrust/MIRACLTrust.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1783,7 +1783,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
MARKETING_VERSION = "$(MIRACL_SDK_VERSION)";
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -1846,7 +1846,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
MARKETING_VERSION = "$(MIRACL_SDK_VERSION)";
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand All @@ -1870,7 +1870,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
PRODUCT_BUNDLE_IDENTIFIER = "com.miracl.trust.sdk-ios.MIRACLTrustTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -1890,7 +1890,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
PRODUCT_BUNDLE_IDENTIFIER = "com.miracl.trust.sdk-ios.MIRACLTrustTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -1912,7 +1912,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
PRODUCT_BUNDLE_IDENTIFIER = com.radoslavpenev.MIRACLTrustIntegrationTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "MIRACLTrustIntegrationTests/Cases/MIRACLTrustIntegrationTests-Bridging-Header.h";
Expand All @@ -1937,7 +1937,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
PRODUCT_BUNDLE_IDENTIFIER = com.radoslavpenev.MIRACLTrustIntegrationTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "MIRACLTrustIntegrationTests/Cases/MIRACLTrustIntegrationTests-Bridging-Header.h";
Expand All @@ -1960,7 +1960,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
PRODUCT_BUNDLE_IDENTIFIER = "com.miracl.applclippoc.MIRACLTrust-Test-Host-App";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
Expand All @@ -1980,7 +1980,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.miracl.applclippoc.MIRACLTrust-Test-Host-App";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -2019,7 +2019,7 @@
"$(PROJECT_DIR)/MIRACLTrust-Sources/Crypto/src",
);
MARKETING_VERSION = "$(MIRACL_SDK_VERSION)";
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
MODULEMAP_FILE = "$(SRCROOT)/MIRACLTrust-Sources/MIRACLTrust.modulemap";
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
Expand Down Expand Up @@ -2068,7 +2068,7 @@
"$(PROJECT_DIR)/MIRACLTrust-Sources/Crypto/src",
);
MARKETING_VERSION = "$(MIRACL_SDK_VERSION)";
MIRACL_SDK_VERSION = 1.6.0;
MIRACL_SDK_VERSION = 1.6.1;
MODULEMAP_FILE = "$(SRCROOT)/MIRACLTrust-Sources/MIRACLTrust.modulemap";
ONLY_ACTIVE_ARCH = NO;
OTHER_CFLAGS = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class VerificationIntegrationTests: XCTestCase {
let registrationTestCase = RegistrationTestCase()
let deviceName = "iOS Simulator"
let sessionDetailsTestCase = SessionDetailsTestCase()
let crossDeviceSessionTestCase = CrossDeviceSessionCase()
let api = PlatformAPIWrapper()
let gmailService = GmailServiceTestWrapper()

Expand All @@ -29,7 +30,7 @@ class VerificationIntegrationTests: XCTestCase {

var configuration: Configuration?

func testVerification() async throws {
func testVerificationWithoutAuthenticationSession() async throws {
let extendedMailAddress = "int+\(UUID().uuidString)@miracl.com"

configuration = try Configuration
Expand Down Expand Up @@ -67,6 +68,44 @@ class VerificationIntegrationTests: XCTestCase {
XCTAssertEqual(activationTokenResponse?.projectId, projectId)
}

func testVerificationWithoutCrossDeviceSession() async throws {
let extendedMailAddress = "int+\(UUID().uuidString)@miracl.com"

configuration = try Configuration
.Builder(
projectId: projectId,
projectURL: projectURLDV
).userStorage(userStorage: storage)
.build()
try MIRACLTrust.configure(with: XCTUnwrap(configuration))

let timestamp = Date()
let (verified, error) = verificationTestCase.sendVerificationEmailForCrossDeviceSession(
userId: extendedMailAddress
)

XCTAssertNotNil(verified)
XCTAssertNil(error)

let verificationResult = try await gmailService.getVerificationURL(receiver: extendedMailAddress, timestamp: timestamp)
let verificationURL = try XCTUnwrap(verificationResult)

let queryItems = try XCTUnwrap(URLComponents(url: verificationURL, resolvingAgainstBaseURL: false)?.queryItems)

let userIdItem = try XCTUnwrap(queryItems.filter { item in
item.name == "user_id"
}.first)
XCTAssertEqual(userIdItem.value, extendedMailAddress)

let (activationTokenResponse, activationTokenError) = try activationTokenTestCase.getActivationToken(
verificationURL: XCTUnwrap(verificationURL)
)

XCTAssertNil(activationTokenError)
XCTAssertNotNil(activationTokenResponse)
XCTAssertEqual(activationTokenResponse?.projectId, projectId)
}

func testVerificationWithMpinId() async throws {
let extendedMailAddress = "int+\(UUID().uuidString)@miracl.com"

Expand Down Expand Up @@ -197,13 +236,46 @@ class VerificationIntegrationTests: XCTestCase {
XCTAssertEqual(response.accessId, accessId)
}

func testVerificationWithCrossDeviceSessionDetails() async throws {
let extendedMailAddress = "int+\(UUID().uuidString)@miracl.com"
let accessId = try XCTUnwrap(api.getAccessId(projectId: projectId, projectURL: projectURLDV))
let qrCode = "https://mcl.mpin.io#\(accessId)"

configuration = try Configuration
.Builder(projectId: projectId, projectURL: projectURLDV)
.userStorage(userStorage: storage)
.build()
try MIRACLTrust.configure(with: XCTUnwrap(configuration))

let crossDeviceSession = try await crossDeviceSessionTestCase.getCrossDeviceSessionForQRCode(qrCode: qrCode)

let timestamp = Date()
let (verified, error) = verificationTestCase.sendVerificationEmailForCrossDeviceSession(
userId: extendedMailAddress,
crossDeviceSession: crossDeviceSession
)
XCTAssertNotNil(verified)
XCTAssertNil(error)

let verificationURL = try await gmailService.getVerificationURL(receiver: extendedMailAddress, timestamp: timestamp)

let (activationTokenResponse, activationTokenError) = try activationTokenTestCase.getActivationToken(
verificationURL: XCTUnwrap(verificationURL)
)

XCTAssertNil(activationTokenError)
let response = try XCTUnwrap(activationTokenResponse)
XCTAssertEqual(response.accessId, accessId)
}

func testEmailCodeVerification() async throws {
let extendedMailAddress = "int+\(UUID().uuidString)@miracl.com"

configuration = try Configuration
.Builder(projectId: projectIdECV, projectURL: projectURLECV)
.userStorage(userStorage: storage)
.build()

try MIRACLTrust.configure(with: XCTUnwrap(configuration))

let timestamp = Date()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,30 @@ class VerificationTestCase {

return (verificationResponse, returnedError)
}

func sendVerificationEmailForCrossDeviceSession(
userId: String,
crossDeviceSession: CrossDeviceSession? = nil
) -> (VerificationResponse?, Error?) {
let waitForVerification = XCTestExpectation(description: "wait for verification")

nonisolated(unsafe) var verificationResponse: VerificationResponse?
nonisolated(unsafe) var returnedError: Error?

MIRACLTrust.getInstance()._sendVerificationEmail(
userId: userId,
crossDeviceSession: crossDeviceSession
) { result, error in
verificationResponse = result
returnedError = error
waitForVerification.fulfill()
}

let waitResult = XCTWaiter.wait(for: [waitForVerification], timeout: operationTimeout)
if waitResult != .completed {
XCTFail("Failed expectation")
}

return (verificationResponse, returnedError)
}
}
67 changes: 66 additions & 1 deletion MIRACLTrust/MIRACLTrustTests/MIRACLTrustTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class MIRACLTrustTests: XCTestCase {
mockAPI.signingSessionCompleterError = nil
mockAPI.signingSessionCompleterResultCall = .success
mockAPI.signingSessionCompleterResponse = SigningSessionCompleterResponse(status: "signed")

mockAPI.verificationResponse = VerificationRequestResponse(backoff: backoff, method: "link")
mockAPI.verificationResultCall = .success
mockAPI.verificationError = nil
}

func createMockCrypto() {
Expand Down Expand Up @@ -174,6 +178,47 @@ class MIRACLTrustTests: XCTestCase {
wait(for: [expectation], timeout: 20.0)
}

func testSendVerificationEmailWithCrossDeviceSession() throws {
let completionHandlerExpectation = XCTestExpectation(description: "sendVerificationEmail with cross device session")
let crossDeviceSession = createCrossDeviceSession()

MIRACLTrust.getInstance()._sendVerificationEmail(userId: randomString, crossDeviceSession: crossDeviceSession) { response, error in
XCTAssertNil(error)
XCTAssertNotNil(response)

completionHandlerExpectation.fulfill()
}

wait(for: [completionHandlerExpectation], timeout: 20.0)
}

func testSendVerificationEmailWithAuthenticationSessionDetails() throws {
let completionHandlerExpectation = XCTestExpectation(description: "sendVerificationEmail with authentication session")
let authenticationSessionDetails = createSessionDetails()

MIRACLTrust.getInstance().sendVerificationEmail(userId: randomString, authenticationSessionDetails: authenticationSessionDetails) { response, error in
XCTAssertNil(error)
XCTAssertNotNil(response)

completionHandlerExpectation.fulfill()
}

wait(for: [completionHandlerExpectation], timeout: 20.0)
}

func testSendVerificationEmailWithoutCrossDeviceSession() throws {
let completionHandlerExpectation = XCTestExpectation(description: "sendVerificationEmail without cross device session")

MIRACLTrust.getInstance()._sendVerificationEmail(userId: randomString) { response, error in
XCTAssertNil(error)
XCTAssertNotNil(response)

completionHandlerExpectation.fulfill()
}

wait(for: [completionHandlerExpectation], timeout: 20.0)
}

func testGetActivationToken() throws {
let userId = "[email protected]"
let verificationURL = try XCTUnwrap(URL(string: "https://api.mpin.io/verification/confirmation?code=af1cc549573718409de44d8bf2e67a06&user_id=\(userId)"))
Expand Down Expand Up @@ -977,7 +1022,7 @@ class MIRACLTrustTests: XCTestCase {

func testGetNotExisitingUser() throws {
projectId = randomString
var userDTO = createUserDTO()
let userDTO = createUserDTO()

try mockUserStorage.add(user: userDTO)
XCTAssertNil(MIRACLTrust.getInstance().getUser(by: randomString))
Expand Down Expand Up @@ -1068,4 +1113,24 @@ class MIRACLTrustTests: XCTestCase {
expireTime: Date()
)
}

private func createCrossDeviceSession() -> CrossDeviceSession {
CrossDeviceSession(
userId: UUID().uuidString,
projectName: UUID().uuidString,
projectLogoURL: UUID().uuidString,
projectId: UUID().uuidString,
pinLength: 4,
verificationMethod: .standardEmail,
verificationURL: UUID().uuidString,
verificationCustomText: UUID().uuidString,
identityTypeLabel: UUID().uuidString,
quickCodeEnabled: true,
limitQuickCodeRegistration: false,
identityType: .alphanumeric,
sessionId: UUID().uuidString,
sessionDescription: "",
signingHash: ""
)
}
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ To integrate using Apple's Swift package manager, without
Xcode integration, add the following as a dependency to your Package.swift:

```bash
.package(url: "https://github.com/miracl/trust-sdk-ios", .upToNextMajor(from: "1.6.0"))
.package(url: "https://github.com/miracl/trust-sdk-ios", .upToNextMajor(from: "1.6.1"))
```

In both cases after the package is downloaded, go to the
Expand Down
Loading