75 lines
2.4 KiB
Swift
75 lines
2.4 KiB
Swift
|
//
|
||
|
// FervorClient.swift
|
||
|
// Fervor
|
||
|
//
|
||
|
// Created by Shadowfacts on 11/25/21.
|
||
|
//
|
||
|
|
||
|
import Foundation
|
||
|
|
||
|
public class FervorClient {
|
||
|
|
||
|
let instanceURL: URL
|
||
|
let session: URLSession
|
||
|
public var accessToken: String?
|
||
|
|
||
|
private let decoder = JSONDecoder()
|
||
|
|
||
|
public init(instanceURL: URL, accessToken: String?, session: URLSession = .shared) {
|
||
|
self.instanceURL = instanceURL
|
||
|
self.accessToken = accessToken
|
||
|
self.session = session
|
||
|
}
|
||
|
|
||
|
private func buildURL(path: String) -> URL {
|
||
|
var components = URLComponents(url: instanceURL, resolvingAgainstBaseURL: false)!
|
||
|
components.path = path
|
||
|
return components.url!
|
||
|
}
|
||
|
|
||
|
private func performRequest<T: Decodable>(_ request: URLRequest) async throws -> T {
|
||
|
var request = request
|
||
|
if let accessToken = accessToken {
|
||
|
request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
|
||
|
}
|
||
|
let (data, _) = try await session.data(for: request, delegate: nil)
|
||
|
let decoded = try decoder.decode(T.self, from: data)
|
||
|
return decoded
|
||
|
}
|
||
|
|
||
|
public func register(clientName: String, website: URL? = nil, redirectURI: URL) async throws -> ClientRegistration {
|
||
|
var request = URLRequest(url: buildURL(path: "/api/v1/register"))
|
||
|
request.httpMethod = "POST"
|
||
|
request.setURLEncodedBody(params: [
|
||
|
"client_name": clientName,
|
||
|
"website": website?.absoluteString,
|
||
|
"redirect_uri": redirectURI.absoluteString,
|
||
|
])
|
||
|
return try await performRequest(request)
|
||
|
}
|
||
|
|
||
|
public func token(authCode: String, redirectURI: URL, clientID: String, clientSecret: String) async throws -> Token {
|
||
|
var request = URLRequest(url: buildURL(path: "/oauth/token"))
|
||
|
request.httpMethod = "POST"
|
||
|
request.setURLEncodedBody(params: [
|
||
|
"grant_type": "authorization_code",
|
||
|
"authorization_code": authCode,
|
||
|
"redirect_uri": redirectURI.absoluteString,
|
||
|
"client_id": clientID,
|
||
|
"client_secret": clientSecret,
|
||
|
])
|
||
|
return try await performRequest(request)
|
||
|
}
|
||
|
|
||
|
public struct Auth {
|
||
|
public let accessToken: String
|
||
|
public let refreshToken: String?
|
||
|
}
|
||
|
|
||
|
public enum Error: Swift.Error {
|
||
|
case urlSession(Swift.Error)
|
||
|
case decode(Swift.Error)
|
||
|
}
|
||
|
|
||
|
}
|