2023-03-05 19:35:25 +00:00
|
|
|
//
|
|
|
|
// UserAccountInfo.swift
|
|
|
|
// UserAccounts
|
|
|
|
//
|
|
|
|
// Created by Shadowfacts on 3/5/23.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
import CryptoKit
|
|
|
|
|
2023-04-20 02:20:05 +00:00
|
|
|
public struct UserAccountInfo: Equatable, Hashable, Identifiable {
|
2023-03-05 19:35:25 +00:00
|
|
|
public let id: String
|
|
|
|
public let instanceURL: URL
|
|
|
|
public let clientID: String
|
|
|
|
public let clientSecret: String
|
|
|
|
public private(set) var username: String!
|
|
|
|
public let accessToken: String
|
|
|
|
|
|
|
|
fileprivate static let tempAccountID = "temp"
|
|
|
|
|
|
|
|
static func id(instanceURL: URL, username: String?) -> String {
|
|
|
|
// We hash the instance host and username to form the account ID
|
|
|
|
// so that account IDs will match across devices, allowing for data syncing and handoff.
|
|
|
|
var hasher = SHA256()
|
|
|
|
hasher.update(data: instanceURL.host!.data(using: .utf8)!)
|
|
|
|
if let username {
|
|
|
|
hasher.update(data: username.data(using: .utf8)!)
|
|
|
|
}
|
|
|
|
return Data(hasher.finalize()).base64EncodedString()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Only to be used for temporary MastodonController needed to fetch own account info and create final UserAccountInfo with real username
|
|
|
|
public init(tempInstanceURL instanceURL: URL, clientID: String, clientSecret: String, accessToken: String) {
|
|
|
|
self.id = UserAccountInfo.tempAccountID
|
|
|
|
self.instanceURL = instanceURL
|
|
|
|
self.clientID = clientID
|
|
|
|
self.clientSecret = clientSecret
|
|
|
|
self.accessToken = accessToken
|
|
|
|
}
|
|
|
|
|
|
|
|
init(instanceURL: URL, clientID: String, clientSecret: String, username: String? = nil, accessToken: String) {
|
|
|
|
self.id = UserAccountInfo.id(instanceURL: instanceURL, username: username)
|
|
|
|
self.instanceURL = instanceURL
|
|
|
|
self.clientID = clientID
|
|
|
|
self.clientSecret = clientSecret
|
|
|
|
self.username = username
|
|
|
|
self.accessToken = accessToken
|
|
|
|
}
|
|
|
|
|
|
|
|
init?(userDefaultsDict dict: [String: String]) {
|
|
|
|
guard let id = dict["id"],
|
|
|
|
let instanceURL = dict["instanceURL"],
|
|
|
|
let url = URL(string: instanceURL),
|
|
|
|
let clientID = dict["clientID"],
|
|
|
|
let secret = dict["clientSecret"],
|
|
|
|
let accessToken = dict["accessToken"] else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
self.id = id
|
|
|
|
self.instanceURL = url
|
|
|
|
self.clientID = clientID
|
|
|
|
self.clientSecret = secret
|
|
|
|
self.username = dict["username"]
|
|
|
|
self.accessToken = accessToken
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A filename-safe string for this account
|
|
|
|
public var persistenceKey: String {
|
|
|
|
// slashes are not allowed in the persistent store coordinator name
|
|
|
|
id.replacingOccurrences(of: "/", with: "_")
|
|
|
|
}
|
|
|
|
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
public static func ==(lhs: UserAccountInfo, rhs: UserAccountInfo) -> Bool {
|
|
|
|
return lhs.id == rhs.id
|
|
|
|
}
|
|
|
|
}
|