Include admin/API/banner nativi, form contatti e reset copertina standard con layout edit più ampio. Co-authored-by: Cursor <cursoragent@cursor.com>
126 lines
4.2 KiB
Swift
126 lines
4.2 KiB
Swift
import Foundation
|
|
import Security
|
|
|
|
struct StoredSession: Equatable, Sendable {
|
|
let user: User
|
|
let accessToken: String
|
|
let refreshToken: String
|
|
}
|
|
|
|
@MainActor
|
|
final class TokenStore: ObservableObject {
|
|
@Published private(set) var session: StoredSession?
|
|
@Published private(set) var activeTeamId: String?
|
|
|
|
private let defaults = UserDefaults.standard
|
|
private let service = "com.matchlivetv.match-live-tv.auth"
|
|
|
|
init() {
|
|
session = loadSession()
|
|
activeTeamId = defaults.string(forKey: Keys.activeTeamId)
|
|
}
|
|
|
|
func saveSession(_ session: StoredSession) {
|
|
self.session = session
|
|
saveKeychain(key: Keys.accessToken, value: session.accessToken)
|
|
saveKeychain(key: Keys.refreshToken, value: session.refreshToken)
|
|
defaults.set(session.user.id, forKey: Keys.userId)
|
|
defaults.set(session.user.email, forKey: Keys.userEmail)
|
|
defaults.set(session.user.name, forKey: Keys.userName)
|
|
defaults.set(session.user.role, forKey: Keys.userRole)
|
|
}
|
|
|
|
func saveActiveTeamId(_ teamId: String) {
|
|
activeTeamId = teamId
|
|
defaults.set(teamId, forKey: Keys.activeTeamId)
|
|
}
|
|
|
|
func clear() {
|
|
session = nil
|
|
activeTeamId = nil
|
|
deleteKeychain(key: Keys.accessToken)
|
|
deleteKeychain(key: Keys.refreshToken)
|
|
defaults.removeObject(forKey: Keys.userId)
|
|
defaults.removeObject(forKey: Keys.userEmail)
|
|
defaults.removeObject(forKey: Keys.userName)
|
|
defaults.removeObject(forKey: Keys.userRole)
|
|
defaults.removeObject(forKey: Keys.activeTeamId)
|
|
}
|
|
|
|
private func loadSession() -> StoredSession? {
|
|
guard let access = loadKeychain(key: Keys.accessToken),
|
|
let refresh = loadKeychain(key: Keys.refreshToken),
|
|
let id = defaults.string(forKey: Keys.userId) else { return nil }
|
|
return StoredSession(
|
|
user: User(
|
|
id: id,
|
|
email: defaults.string(forKey: Keys.userEmail) ?? "",
|
|
name: defaults.string(forKey: Keys.userName) ?? "",
|
|
role: defaults.string(forKey: Keys.userRole) ?? "coach"
|
|
),
|
|
accessToken: access,
|
|
refreshToken: refresh
|
|
)
|
|
}
|
|
|
|
private enum Keys {
|
|
static let accessToken = "access_token"
|
|
static let refreshToken = "refresh_token"
|
|
static let userId = "user_id"
|
|
static let userEmail = "user_email"
|
|
static let userName = "user_name"
|
|
static let userRole = "user_role"
|
|
static let activeTeamId = "active_team_id"
|
|
}
|
|
|
|
private func saveKeychain(key: String, value: String) {
|
|
let data = Data(value.utf8)
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassGenericPassword,
|
|
kSecAttrService as String: service,
|
|
kSecAttrAccount as String: key,
|
|
]
|
|
SecItemDelete(query as CFDictionary)
|
|
var add = query
|
|
add[kSecValueData as String] = data
|
|
SecItemAdd(add as CFDictionary, nil)
|
|
}
|
|
|
|
private func loadKeychain(key: String) -> String? {
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassGenericPassword,
|
|
kSecAttrService as String: service,
|
|
kSecAttrAccount as String: key,
|
|
kSecReturnData as String: true,
|
|
kSecMatchLimit as String: kSecMatchLimitOne,
|
|
]
|
|
var result: AnyObject?
|
|
guard SecItemCopyMatching(query as CFDictionary, &result) == errSecSuccess,
|
|
let data = result as? Data else { return nil }
|
|
return String(data: data, encoding: .utf8)
|
|
}
|
|
|
|
private func deleteKeychain(key: String) {
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassGenericPassword,
|
|
kSecAttrService as String: service,
|
|
kSecAttrAccount as String: key,
|
|
]
|
|
SecItemDelete(query as CFDictionary)
|
|
}
|
|
}
|
|
|
|
final class AnnouncementStore {
|
|
private let key = "mltv.dismissedAnnouncements"
|
|
|
|
func dismissedIds() -> Set<String> {
|
|
Set(UserDefaults.standard.stringArray(forKey: key) ?? [])
|
|
}
|
|
|
|
func dismiss(_ id: String) {
|
|
var ids = dismissedIds()
|
|
ids.insert(id)
|
|
UserDefaults.standard.set(Array(ids), forKey: key)
|
|
}
|
|
}
|