Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reset FIDO NFC issue and visual improvements in configuration views #148

Merged
merged 2 commits into from
Nov 18, 2024
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
32 changes: 22 additions & 10 deletions Authenticator.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
B4C93E8929B89DE300C2A8B8 /* DetachedMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C93E8829B89DE300C2A8B8 /* DetachedMenu.swift */; };
B4C93E9329C1B2BC00C2A8B8 /* AboutWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C93E9229C1B2BC00C2A8B8 /* AboutWrapper.swift */; };
B4C93E9529C1B90900C2A8B8 /* AddAccountWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C93E9429C1B90900C2A8B8 /* AddAccountWrapper.swift */; };
B4D71E812CE4E6E6004D4C29 /* YubiKit in Frameworks */ = {isa = PBXBuildFile; productRef = B4D71E802CE4E6E6004D4C29 /* YubiKit */; };
B4DB228A299BC373003110ED /* OATHSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DB2289299BC373003110ED /* OATHSession.swift */; };
B4FE90D02A42028400B59170 /* VersionHistoryWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FE90CF2A42028400B59170 /* VersionHistoryWrapper.swift */; };
B4FE90D22A4431AB00B59170 /* NotificationsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4FE90D12A4431AB00B59170 /* NotificationsViewModel.swift */; };
Expand Down Expand Up @@ -299,6 +300,7 @@
buildActionMask = 2147483647;
files = (
B44E5E842C74C8CC007ABB79 /* YubiKit in Frameworks */,
B4D71E812CE4E6E6004D4C29 /* YubiKit in Frameworks */,
B42A39332B2A03D20039DB26 /* YubiKit in Frameworks */,
B9F0FF11F842A39183974083 /* (null) in Frameworks */,
51AFD4DA271D4278008F2630 /* QuartzCore.framework in Frameworks */,
Expand Down Expand Up @@ -633,6 +635,7 @@
packageProductDependencies = (
B42A39322B2A03D20039DB26 /* YubiKit */,
B44E5E832C74C8CC007ABB79 /* YubiKit */,
B4D71E802CE4E6E6004D4C29 /* YubiKit */,
);
productName = Authenticator;
productReference = 818866B322DFD729006BC0A8 /* Authenticator.app */;
Expand Down Expand Up @@ -695,7 +698,7 @@
);
mainGroup = 818866AA22DFD729006BC0A8;
packageReferences = (
B44E5E822C74C8CC007ABB79 /* XCLocalSwiftPackageReference "../yubikit-ios" */,
B4D71E7F2CE4E6E6004D4C29 /* XCRemoteSwiftPackageReference "yubikit-ios" */,
);
productRefGroup = 818866B422DFD729006BC0A8 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -932,7 +935,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = TokenExtension/TokenExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 143;
CURRENT_PROJECT_VERSION = 163;
DEVELOPMENT_TEAM = LQA3CS5MM7;
INFOPLIST_FILE = TokenExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
Expand All @@ -956,7 +959,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = TokenExtension/TokenExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 143;
CURRENT_PROJECT_VERSION = 163;
DEVELOPMENT_TEAM = LQA3CS5MM7;
INFOPLIST_FILE = TokenExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
Expand Down Expand Up @@ -1106,7 +1109,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Authenticator/Authenticator.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 143;
CURRENT_PROJECT_VERSION = 163;
DEVELOPMENT_TEAM = LQA3CS5MM7;
HEADER_SEARCH_PATHS = "../Submodules/YubiKit/**";
INFOPLIST_FILE = Authenticator/Info.plist;
Expand Down Expand Up @@ -1136,7 +1139,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Authenticator/Authenticator.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 143;
CURRENT_PROJECT_VERSION = 163;
DEVELOPMENT_TEAM = LQA3CS5MM7;
HEADER_SEARCH_PATHS = "../Submodules/YubiKit/**";
INFOPLIST_FILE = Authenticator/Info.plist;
Expand Down Expand Up @@ -1244,12 +1247,16 @@
};
/* End XCConfigurationList section */

/* Begin XCLocalSwiftPackageReference section */
B44E5E822C74C8CC007ABB79 /* XCLocalSwiftPackageReference "../yubikit-ios" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = "../yubikit-ios";
/* Begin XCRemoteSwiftPackageReference section */
B4D71E7F2CE4E6E6004D4C29 /* XCRemoteSwiftPackageReference "yubikit-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Yubico/yubikit-ios";
requirement = {
branch = main;
kind = branch;
};
};
/* End XCLocalSwiftPackageReference section */
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
B42A39322B2A03D20039DB26 /* YubiKit */ = {
Expand All @@ -1260,6 +1267,11 @@
isa = XCSwiftPackageProductDependency;
productName = YubiKit;
};
B4D71E802CE4E6E6004D4C29 /* YubiKit */ = {
isa = XCSwiftPackageProductDependency;
package = B4D71E7F2CE4E6E6004D4C29 /* XCRemoteSwiftPackageReference "yubikit-ios" */;
productName = YubiKit;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 818866AB22DFD729006BC0A8 /* Project object */;
Expand Down
89 changes: 89 additions & 0 deletions Authenticator/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@
}
},
"Confirm OATH reset" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand Down Expand Up @@ -1048,6 +1049,7 @@
}
},
"FIDO factory reset" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand Down Expand Up @@ -1113,6 +1115,7 @@
}
},
"FIDO PIN protection" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand All @@ -1129,6 +1132,7 @@
}
},
"FIDO reset" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand Down Expand Up @@ -1178,6 +1182,7 @@
}
},
"For additional security and to prevent unauthorized access the FIDO application can be protected by a PIN." : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand All @@ -1194,6 +1199,7 @@
}
},
"For additional security and to prevent unauthorized access the YubiKey can be password protected." : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand Down Expand Up @@ -1708,7 +1714,24 @@
}
}
},
"OATH password" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Mots de passe OATH"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "OATHパスワード"
}
}
}
},
"OATH password protection" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand Down Expand Up @@ -2453,6 +2476,22 @@
}
}
},
"Reset FIDO" : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Réinitialiser FIDO"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "FIDOのリセット"
}
}
}
},
"Reset FIDO application" : {
"comment" : "FIDO reset NFC confirmation message",
"localizations" : {
Expand Down Expand Up @@ -2587,6 +2626,7 @@
}
},
"Saved passwords has been cleared" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand Down Expand Up @@ -3121,6 +3161,22 @@
}
}
},
"This will irrevocably delete all OATH TOTP/HOTP accounts from your YubiKey." : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Cela supprimera définitivement tous les comptes OATH TOTP/HOTP de votre YubiKey."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "これにより、すべてのOATH TOTP/HOTPアカウントがYubiKeyから削除されます。削除は取り消すことができません。"
}
}
}
},
"This will irrevocably delete all U2F and FIDO2 accounts, including passkeys, from your YubiKey." : {
"localizations" : {
"fr" : {
Expand Down Expand Up @@ -3169,6 +3225,38 @@
}
}
},
"To prevent unauthorized access the FIDO application can be protected by a PIN." : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pour éviter tout accès non autorisé, l'application FIDO peut être protégée par un code PIN."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "不正アクセスを防ぐため、FIDOアプリケーションはPINで保護することができる。"
}
}
}
},
"To prevent unauthorized access the OATH application can be protected by a password." : {
"localizations" : {
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Pour empêcher tout accès non autorisé, l'application OATH peut être protégée par un mot de passe."
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "不正アクセスを防ぐため、OATHアプリケーションはパスワードで保護することができます。"
}
}
}
},
"To prevent unauthorized access this YubiKey is protected with a password." : {
"comment" : "OATH password entry enter password",
"localizations" : {
Expand Down Expand Up @@ -3604,6 +3692,7 @@
}
},
"YubiKey has been reset" : {
"extractionState" : "stale",
"localizations" : {
"fr" : {
"stringUnit" : {
Expand Down
17 changes: 15 additions & 2 deletions Authenticator/Model/ConfigurationViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ class ConfigurationViewModel: ObservableObject {

let connection = Connection()

@Published var deviceInfo: YKFManagementDeviceInfo?
@Published var deviceInfo: YKFManagementDeviceInfo? {
didSet {
resetDeviceInfoTask?.cancel()
resetDeviceInfoTask = nil
}
}

var resetDeviceInfoTask: Task<Void, Error>?

init() {
Logger.allocation.debug("ConfigurationViewModel: init")
Expand Down Expand Up @@ -52,7 +59,13 @@ class ConfigurationViewModel: ObservableObject {
}

func start() {
deviceInfo = nil
resetDeviceInfoTask = Task.detached {
try? await Task.sleep(for: .seconds(1))
guard !Task.isCancelled else { return }
Task.detached { @MainActor in
self.deviceInfo = nil
}
}
waitForConnection()
}

Expand Down
13 changes: 8 additions & 5 deletions Authenticator/Model/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,14 @@ class Connection: NSObject {
smartCardConnection?.stop()
accessoryConnection?.stop()
nfcConnection?.stop()
if YubiKitDeviceCapabilities.supportsMFIAccessoryKey {
YubiKitManager.shared.startAccessoryConnection()
}
if YubiKitDeviceCapabilities.supportsSmartCardOverUSBC {
YubiKitManager.shared.startSmartCardConnection()
// stop() returns immediately but closing the connection will take a few cycles so we need to wait to make sure it's closed before restarting.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if YubiKitDeviceCapabilities.supportsMFIAccessoryKey {
YubiKitManager.shared.startAccessoryConnection()
}
if YubiKitDeviceCapabilities.supportsSmartCardOverUSBC {
YubiKitManager.shared.startSmartCardConnection()
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions Authenticator/UI/YubiKeyConfiguration/ConfigurationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,11 @@ struct ConfigurationView: View {
Text("Manage PIN")
}
NavigationLink {
FIDOResetView()
.onDisappear {
FIDOResetView {
Task.detached { @MainActor in
model.start()
}
}
} label: {
ListIconView(image: Image(systemName: "trash"), color: Color(.systemRed), padding: 5)
Text("Reset FIDO application")
Expand Down
4 changes: 2 additions & 2 deletions Authenticator/UI/YubiKeyConfiguration/FIDOPINView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ struct FIDOPINView: View {

var body: some View {
SettingsView(image: Image(systemName: "lock.shield"), imageColor: Color(.systemPurple)) {
Text("FIDO PIN protection").font(.title2).bold()
Text("FIDO PIN").font(.title2).bold()

Text("For additional security and to prevent unauthorized access the FIDO application can be protected by a PIN.")
Text("To prevent unauthorized access the FIDO application can be protected by a PIN.")
.font(.subheadline)
.multilineTextAlignment(.center)

Expand Down
Loading
Loading