diff --git a/wake/Utils/KeychainHelper.swift b/wake/Utils/KeychainHelper.swift index b2c4127..a8e35ec 100644 --- a/wake/Utils/KeychainHelper.swift +++ b/wake/Utils/KeychainHelper.swift @@ -4,7 +4,7 @@ import Security /// 用于安全存储和检索敏感信息(如令牌)的 Keychain 帮助类 public class KeychainHelper { // Keychain 键名 - private enum KeychainKey: String { + private enum KeychainKey: String, CaseIterable { case accessToken = "com.memorywake.accessToken" case refreshToken = "com.memorywake.refreshToken" } @@ -35,6 +35,38 @@ public class KeychainHelper { delete(for: .refreshToken) } + /// 清除所有存储的 Keychain 数据 + public static func clearAll() { + // 清除所有已知的 keychain 项 + KeychainKey.allCases.forEach { key in + delete(for: key) + } + + // 额外清理:删除所有通用密码项(作为安全措施) + let query: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecReturnAttributes as String: true, + kSecMatchLimit as String: kSecMatchLimitAll + ] + + var result: AnyObject? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + if status == errSecSuccess, let items = result as? [[String: Any]] { + for item in items { + if let account = item[kSecAttrAccount as String] as? String, + let service = item[kSecAttrService as String] as? String { + let deleteQuery: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecAttrAccount as String: account, + kSecAttrService as String: service + ] + SecItemDelete(deleteQuery as CFDictionary) + } + } + } + } + // MARK: - 私有方法 private static func save(_ string: String, for key: KeychainKey) -> Bool { diff --git a/wake/Utils/Router.swift b/wake/Utils/Router.swift index 09d5dad..5e4b673 100644 --- a/wake/Utils/Router.swift +++ b/wake/Utils/Router.swift @@ -2,6 +2,7 @@ import SwiftUI @MainActor enum AppRoute: Hashable { + case login case avatarBox case feedbackView case feedbackDetail(type: FeedbackView.FeedbackType) @@ -12,6 +13,8 @@ enum AppRoute: Hashable { @ViewBuilder var view: some View { switch self { + case .login: + LoginView() case .avatarBox: AvatarBoxView() case .feedbackView: diff --git a/wake/View/Owner/UserInfo/AvatarPicker.swift b/wake/View/Owner/UserInfo/AvatarPicker.swift index 49cd59a..98e3982 100644 --- a/wake/View/Owner/UserInfo/AvatarPicker.swift +++ b/wake/View/Owner/UserInfo/AvatarPicker.swift @@ -56,6 +56,7 @@ public struct AvatarPicker: View { SVGImage(svgName: "IP") .frame(width: avatarSize, height: avatarSize) .contentShape(Rectangle()) + .clipShape(RoundedRectangle(cornerRadius: 20)) .overlay( RoundedRectangle(cornerRadius: 20) .stroke(style: StrokeStyle(