102 lines
2.8 KiB
Swift
102 lines
2.8 KiB
Swift
|
//Made by Lumaa
|
||
|
|
||
|
import Foundation
|
||
|
|
||
|
public struct AppAccount: Codable, Identifiable, Hashable {
|
||
|
public let server: String
|
||
|
public var accountName: String?
|
||
|
public let oauthToken: OauthToken?
|
||
|
public static let saveKey: String = "threaded-appaccount.current"
|
||
|
|
||
|
public var key: String {
|
||
|
if let oauthToken {
|
||
|
"\(server):\(oauthToken.createdAt)"
|
||
|
} else {
|
||
|
"\(server):anonymous"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public var id: String {
|
||
|
key
|
||
|
}
|
||
|
|
||
|
public init(server: String,
|
||
|
accountName: String?,
|
||
|
oauthToken: OauthToken? = nil)
|
||
|
{
|
||
|
self.server = server
|
||
|
self.accountName = accountName
|
||
|
self.oauthToken = oauthToken
|
||
|
}
|
||
|
|
||
|
func saveAsCurrent() throws {
|
||
|
let encoder = JSONEncoder()
|
||
|
let json = try encoder.encode(self)
|
||
|
UserDefaults.standard.setValue(json, forKey: AppAccount.saveKey)
|
||
|
}
|
||
|
|
||
|
static func loadAsCurrent() throws -> AppAccount? {
|
||
|
let decoder = JSONDecoder()
|
||
|
if let data = UserDefaults.standard.data(forKey: AppAccount.saveKey) {
|
||
|
let account = try decoder.decode(AppAccount.self, from: data)
|
||
|
return account
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extension AppAccount: Sendable {}
|
||
|
|
||
|
public enum Oauth: Endpoint {
|
||
|
case authorize(clientId: String)
|
||
|
case token(code: String, clientId: String, clientSecret: String)
|
||
|
|
||
|
public func path() -> String {
|
||
|
switch self {
|
||
|
case .authorize:
|
||
|
"oauth/authorize"
|
||
|
case .token:
|
||
|
"oauth/token"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public var jsonValue: Encodable? {
|
||
|
switch self {
|
||
|
case let .token(code, clientId, clientSecret):
|
||
|
TokenData(clientId: clientId, clientSecret: clientSecret, code: code)
|
||
|
default:
|
||
|
nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public struct TokenData: Encodable {
|
||
|
public let grantType = "authorization_code"
|
||
|
public let clientId: String
|
||
|
public let clientSecret: String
|
||
|
public let redirectUri = AppInfo.scheme
|
||
|
public let code: String
|
||
|
public let scope = AppInfo.scopes
|
||
|
}
|
||
|
|
||
|
public func queryItems() -> [URLQueryItem]? {
|
||
|
switch self {
|
||
|
case let .authorize(clientId):
|
||
|
return [
|
||
|
.init(name: "response_type", value: "code"),
|
||
|
.init(name: "client_id", value: clientId),
|
||
|
.init(name: "redirect_uri", value: AppInfo.scheme),
|
||
|
.init(name: "scope", value: AppInfo.scopes),
|
||
|
]
|
||
|
default:
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public struct OauthToken: Codable, Hashable, Sendable {
|
||
|
public let accessToken: String
|
||
|
public let tokenType: String
|
||
|
public let scope: String
|
||
|
public let createdAt: Double
|
||
|
}
|