Skip to content

Commit

Permalink
Fix UserID Refresh for New Jobs (#262)
Browse files Browse the repository at this point in the history
* set the right flag for isEnroll in orchestrated enhanced selfie capture screen. update the location of selfie and livenessimages when submission fails.

* grab last selfie enrollment userid from pasteboard, use new generated user id for selfie authentication

* fix the layout issues with biometric kyc and enhanced kyc country picker.

* bump version number. remove comments.

* add encryption compliance key and value for non exempt encryption
  • Loading branch information
tobitech authored Dec 11, 2024
1 parent 26a110f commit 304fe7f
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 85 deletions.
12 changes: 6 additions & 6 deletions Example/SmileID.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
20B6D5EC2C21CE660023D51C /* DataStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20B6D5EB2C21CE660023D51C /* DataStoreError.swift */; };
20C360C82C454C130008DBDE /* RootViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20C360C72C454C130008DBDE /* RootViewModel.swift */; };
20DFA0EC2C21917100AC2AE7 /* View+TextSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20DFA0EB2C21917100AC2AE7 /* View+TextSelection.swift */; };
20F3D6F32C25F4D700B32751 /* BuildFile in Sources */ = {isa = PBXBuildFile; };
20F3D6F32C25F4D700B32751 /* (null) in Sources */ = {isa = PBXBuildFile; };
20F3D6F62C25F5C100B32751 /* SmileID.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 20F3D6F42C25F5C100B32751 /* SmileID.xcdatamodeld */; };
5829A8C02BC7429A001C1E7E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5829A8BF2BC7429A001C1E7E /* PrivacyInfo.xcprivacy */; };
585BE4882AC7748E0091DDD8 /* RestartableTimerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585BE4872AC7748E0091DDD8 /* RestartableTimerTest.swift */; };
Expand All @@ -48,7 +48,7 @@
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
620F1E982B69194900185CD2 /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 620F1E972B69194900185CD2 /* AlertView.swift */; };
620F1E9A2B691ABB00185CD2 /* BuildFile in Resources */ = {isa = PBXBuildFile; };
620F1E9A2B691ABB00185CD2 /* (null) in Resources */ = {isa = PBXBuildFile; };
624777D02B0CDC9F00952842 /* EnhancedKycWithIdInputScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 624777CF2B0CDC9F00952842 /* EnhancedKycWithIdInputScreen.swift */; };
62F6766F2B0D173600417419 /* EnhancedKycWithIdInputScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62F6766E2B0D173600417419 /* EnhancedKycWithIdInputScreenViewModel.swift */; };
62F676712B0E00E800417419 /* EnhancedKycResultDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62F676702B0E00E800417419 /* EnhancedKycResultDelegate.swift */; };
Expand Down Expand Up @@ -549,7 +549,7 @@
buildActionMask = 2147483647;
files = (
1EFAB3172A375265008E3C13 /* Images.xcassets in Resources */,
620F1E9A2B691ABB00185CD2 /* BuildFile in Resources */,
620F1E9A2B691ABB00185CD2 /* (null) in Resources */,
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
5829A8C02BC7429A001C1E7E /* PrivacyInfo.xcprivacy in Resources */,
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
Expand Down Expand Up @@ -698,7 +698,7 @@
1ED53F6D2A2F28590020BEFB /* SmileTextField.swift in Sources */,
91CB21A52AC10C61005AEBF5 /* NavigationBar.swift in Sources */,
1ED53F6B2A2F28590020BEFB /* ProductCell.swift in Sources */,
20F3D6F32C25F4D700B32751 /* BuildFile in Sources */,
20F3D6F32C25F4D700B32751 /* (null) in Sources */,
1E60ED382A29C306002695FF /* Constants.swift in Sources */,
624777D02B0CDC9F00952842 /* EnhancedKycWithIdInputScreen.swift in Sources */,
1ED53F712A2F28590020BEFB /* EnterUserIDView.swift in Sources */,
Expand Down Expand Up @@ -891,7 +891,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 39;
CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 99P7YGX9Q6;
Expand Down Expand Up @@ -924,7 +924,7 @@
CODE_SIGN_IDENTITY = "Apple Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 39;
CURRENT_PROJECT_VERSION = 40;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 99P7YGX9Q6;
Expand Down
40 changes: 21 additions & 19 deletions Example/SmileID/BiometricKYC/BiometricKycWithIdInputScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct BiometricKycWithIdInputScreen: View {
let delegate: BiometricKycResultDelegate

@State private var selectedCountry: CountryInfo?
@ObservedObject var viewModel: BiometricKycWithIdInputScreenViewModel
@StateObject var viewModel: BiometricKycWithIdInputScreenViewModel

var body: some View {
switch viewModel.step {
Expand All @@ -19,25 +19,27 @@ struct BiometricKycWithIdInputScreen: View {
}
.frame(maxWidth: .infinity)
case .idTypeSelection(let countryList):
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
VStack {
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
)
}
}
case .consent(let country, let idType, let requiredFields):
SmileID.consentScreen(
Expand Down
38 changes: 20 additions & 18 deletions Example/SmileID/EnhancedKYC/EnhancedKycWithIdInputScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,27 @@ struct EnhancedKycWithIdInputScreen: View {
}
.frame(maxWidth: .infinity)
case .idTypeSelection(let countryList):
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
VStack {
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
)
}
}
case .consent(let country, let idType, let requiredFields):
SmileID.consentScreen(
Expand Down
12 changes: 6 additions & 6 deletions Example/SmileID/Home/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ struct HomeView: View {
},
content: {
SmileID.smartSelfieEnrollmentScreen(
userId: viewModel.smartSelfieEnrollmentUserId,
userId: viewModel.newUserId,
jobId: viewModel.newJobId,
allowAgentMode: true,
delegate: SmartSelfieEnrollmentDelegate(
userId: viewModel.smartSelfieEnrollmentUserId,
userId: viewModel.newUserId,
onEnrollmentSuccess: viewModel.onSmartSelfieEnrollment,
onError: viewModel.didError
)
Expand All @@ -47,7 +47,7 @@ struct HomeView: View {
},
content: {
SmartSelfieAuthWithUserIdEntry(
initialUserId: viewModel.smartSelfieEnrollmentUserId,
initialUserId: viewModel.lastSelfieEnrollmentUserId ?? "",
delegate: viewModel
)
}
Expand All @@ -60,12 +60,12 @@ struct HomeView: View {
},
content: {
SmileID.smartSelfieEnrollmentScreen(
userId: viewModel.smartSelfieEnrollmentUserId,
userId: viewModel.newUserId,
jobId: viewModel.newJobId,
allowAgentMode: true,
useStrictMode: true,
delegate: SmartSelfieEnrollmentDelegate(
userId: viewModel.smartSelfieEnrollmentUserId,
userId: viewModel.newUserId,
onEnrollmentSuccess: viewModel.onSmartSelfieEnrollment,
onError: viewModel.didError
)
Expand All @@ -80,7 +80,7 @@ struct HomeView: View {
},
content: {
SmartSelfieAuthWithUserIdEntry(
initialUserId: viewModel.smartSelfieEnrollmentUserId,
initialUserId: viewModel.lastSelfieEnrollmentUserId ?? "",
useStrictMode: true,
delegate: viewModel
)
Expand Down
5 changes: 4 additions & 1 deletion Example/SmileID/Home/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ class HomeViewModel: ObservableObject,
@Published var partnerId: String
var networkMonitor = NetworkMonitor.shared

@Published private(set) var smartSelfieEnrollmentUserId = generateUserId()
var lastSelfieEnrollmentUserId: String? {
guard let value = UIPasteboard.general.string else { return nil }
return value.hasPrefix("user-") ? value : nil
}
@Published private(set) var newUserId: String = generateUserId()
@Published private(set) var newJobId: String = generateJobId()

Expand Down
2 changes: 2 additions & 0 deletions Example/SmileID/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,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>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
Expand Down
38 changes: 20 additions & 18 deletions Sources/SmileID/Classes/Consent/OrchestratedConsentScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public struct ConsentScreen: View {
.padding(16)

VStack(spacing: 16) {
ForEach(0..<consentInfos.count) { index in
ForEach(0..<consentInfos.count, id: \.self) { index in
let consentInfo = consentInfos[index]
HStack(alignment: .top, spacing: 16) {
Image(uiImage: consentInfo.0)
Expand All @@ -100,8 +100,8 @@ public struct ConsentScreen: View {
.frame(maxWidth: .infinity)
}
}
.frame(maxWidth: .infinity)
.padding(4)
.frame(maxWidth: .infinity)
.padding(4)

Spacer()
Divider()
Expand All @@ -117,39 +117,41 @@ public struct ConsentScreen: View {
Text(SmileIDResourcesHelper.localizedString(for: "Consent.Disclaimer", partnerName))
.foregroundColor(SmileID.theme.onLight)
.font(SmileID.theme.body)
.multilineTextAlignment(.center)
VStack(spacing: 8) {
Button(action: onConsentGranted) {
Text(SmileIDResourcesHelper.localizedString(for: "Consent.Allow"))
.padding(14)
.font(SmileID.theme.button)
.frame(maxWidth: .infinity)
}
.background(SmileID.theme.accent)
.foregroundColor(SmileID.theme.onDark)
.cornerRadius(60)
.frame(maxWidth: .infinity)
.padding(.horizontal)
.background(SmileID.theme.accent)
.foregroundColor(SmileID.theme.onDark)
.cornerRadius(60)
.frame(maxWidth: .infinity)
.padding(.horizontal)

Button(action: onCancel) {
Text(SmileIDResourcesHelper.localizedString(for: "Consent.Cancel"))
.padding(14)
.font(SmileID.theme.button)
.frame(maxWidth: .infinity)
}
.background(Color.clear)
.foregroundColor(SmileID.theme.accent)
.overlay(
RoundedRectangle(cornerRadius: 60)
.stroke(SmileID.theme.accent, lineWidth: 4)
)
.cornerRadius(60)
.frame(maxWidth: .infinity)
.padding(.horizontal)
.background(Color.clear)
.foregroundColor(SmileID.theme.accent)
.overlay(
RoundedRectangle(cornerRadius: 60)
.stroke(SmileID.theme.accent, lineWidth: 4)
)
.cornerRadius(60)
.frame(maxWidth: .infinity)
.padding(.horizontal)
if showAttribution {
Image(uiImage: SmileIDResourcesHelper.SmileEmblem)
}
}
}.preferredColorScheme(.light)
}
.preferredColorScheme(.light)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,9 @@ extension EnhancedSmartSelfieViewModel: SelfieSubmissionDelegate {
func submissionDidFail(
with error: Error,
errorMessage: String?,
errorMessageRes: String?
errorMessageRes: String?,
updatedSelfieImageUrl: URL?,
updatedLivenessImages: [URL]
) {
invalidateSubmissionTask()
HapticManager.shared.notification(type: .error)
Expand All @@ -493,6 +495,8 @@ extension EnhancedSmartSelfieViewModel: SelfieSubmissionDelegate {
self.errorMessage = errorMessage
self.errorMessageRes = errorMessageRes
self.selfieCaptureState = .processing(.error)
self.selfieImageURL = updatedSelfieImageUrl
self.livenessImages = updatedLivenessImages
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import SwiftUI

protocol SelfieSubmissionDelegate: AnyObject {
func submissionDidSucceed(_ apiResponse: SmartSelfieResponse)
func submissionDidFail(with error: Error, errorMessage: String?, errorMessageRes: String?)
func submissionDidFail(
with error: Error,
errorMessage: String?,
errorMessageRes: String?,
updatedSelfieImageUrl: URL?,
updatedLivenessImages: [URL]
)
}

final class SelfieSubmissionManager {
Expand Down Expand Up @@ -211,20 +217,31 @@ final class SelfieSubmissionManager {
.submissionDidFail(
with: error,
errorMessage: errorMessageRes,
errorMessageRes: errorMessage
errorMessageRes: errorMessage,
updatedSelfieImageUrl: selfieImageUrl,
updatedLivenessImages: livenessImages
)
return
}

if SmileID.allowOfflineMode, SmileIDError.isNetworkFailure(error: smileIDError) {
self.delegate?.submissionDidFail(with: smileIDError, errorMessage: nil, errorMessageRes: "Offline.Message")
self.delegate?
.submissionDidFail(
with: smileIDError,
errorMessage: nil,
errorMessageRes: "Offline.Message",
updatedSelfieImageUrl: selfieImageUrl,
updatedLivenessImages: livenessImages
)
} else {
let (errorMessageRes, errorMessage) = toErrorMessage(error: smileIDError)
self.delegate?
.submissionDidFail(
with: smileIDError,
errorMessage: errorMessage,
errorMessageRes: errorMessageRes
errorMessageRes: errorMessageRes,
updatedSelfieImageUrl: selfieImageUrl,
updatedLivenessImages: livenessImages
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ public struct OrchestratedSelfieCaptureScreen: View {
for: "Confirmation.Failure"
),
errorSubtitle: getErrorSubtitle(
errorMessageRes: $viewModel.errorMessageRes.wrappedValue,
errorMessage: $viewModel.errorMessage.wrappedValue
errorMessageRes: viewModel.errorMessageRes,
errorMessage: viewModel.errorMessage
),
errorIcon: SmileIDResourcesHelper.Scan,
continueButtonText: SmileIDResourcesHelper.localizedString(
Expand Down Expand Up @@ -105,8 +105,8 @@ public struct OrchestratedSelfieCaptureScreen: View {
)
} else {
SelfieCaptureScreen(
allowAgentMode: allowAgentMode,
viewModel: viewModel
viewModel: viewModel,
allowAgentMode: allowAgentMode
)
.onAppear {
viewModel.updateLocalMetadata(localMetadata)
Expand Down
Loading

0 comments on commit 304fe7f

Please sign in to comment.