Add authorization to instance-calls (IOS-264)

This will improve using the app with `LIMITED_FEDERATION_INSTANCES`
This commit is contained in:
Nathan Mattes 2024-05-08 18:12:52 +02:00
parent cf0eb1e10a
commit c64bdc72d4
13 changed files with 36 additions and 22 deletions

View File

@ -272,7 +272,7 @@ extension MastodonPickServerViewController {
authenticationViewModel.isAuthenticating.send(true)
context.apiService.instance(domain: server.domain)
context.apiService.instance(domain: server.domain, authenticationBox: nil)
.compactMap { [weak self] response -> AnyPublisher<MastodonPickServerViewModel.SignUpResponseFirst, Error>? in
guard let self = self else { return nil }
guard response.value.registrations != false else {

View File

@ -167,7 +167,7 @@ extension MastodonPickServerViewModel {
self.unindexedServers.value = nil
return self.context.apiService.webFinger(domain: domain)
.flatMap { domain -> AnyPublisher<Result<Mastodon.Response.Content<[Mastodon.Entity.Server]>, Error>, Never> in
return self.context.apiService.instance(domain: domain)
return self.context.apiService.instance(domain: domain, authenticationBox: nil)
.map { response -> Result<Mastodon.Response.Content<[Mastodon.Entity.Server]>, Error>in
let newResponse = response.map { [Mastodon.Entity.Server(domain: domain, instance: $0)] }
return Result.success(newResponse)

View File

@ -22,7 +22,7 @@ extension MastodonRegisterViewController {
viewController.context = context
viewController.coordinator = coordinator
let instanceResponse = try await context.apiService.instance(domain: domain).singleOutput()
let instanceResponse = try await context.apiService.instance(domain: domain, authenticationBox: nil).singleOutput()
let applicationResponse = try await context.apiService.createApplication(domain: domain).singleOutput()
let accessTokenResponse = try await context.apiService.applicationAccessToken(
domain: domain,

View File

@ -283,7 +283,7 @@ extension WelcomeViewController {
authenticationViewModel.isAuthenticating.send(true)
context.apiService.instance(domain: server.domain)
context.apiService.instance(domain: server.domain, authenticationBox: nil)
.compactMap { [weak self] response -> AnyPublisher<MastodonPickServerViewModel.SignUpResponseFirst, Error>? in
guard let self = self else { return nil }
guard response.value.registrations != false else {

View File

@ -67,7 +67,7 @@ class ReportViewModel {
// bind server rules
Task { @MainActor in
do {
let response = try await context.apiService.instance(domain: authContext.mastodonAuthenticationBox.domain)
let response = try await context.apiService.instance(domain: authContext.mastodonAuthenticationBox.domain, authenticationBox: authContext.mastodonAuthenticationBox)
.timeout(3, scheduler: DispatchQueue.main)
.singleOutput()
let rules = response.value.rules ?? []

View File

@ -75,7 +75,7 @@ extension SettingsCoordinator: SettingsViewControllerDelegate {
let serverDetailsViewController = ServerDetailsViewController(domain: domain, appContext: appContext, authContext: authContext, sceneCoordinator: sceneCoordinator)
serverDetailsViewController.delegate = self
appContext.apiService.instanceV2(domain: domain)
appContext.apiService.instanceV2(domain: domain, authenticationBox: authContext.mastodonAuthenticationBox)
.sink { _ in
} receiveValue: { content in
@ -83,7 +83,7 @@ extension SettingsCoordinator: SettingsViewControllerDelegate {
}
.store(in: &disposeBag)
appContext.apiService.extendedDescription(domain: domain)
appContext.apiService.extendedDescription(domain: domain, authenticationBox: authContext.mastodonAuthenticationBox)
.sink { _ in
} receiveValue: { content in

View File

@ -14,18 +14,23 @@ import MastodonSDK
extension APIService {
public func instance(
domain: String
domain: String,
authenticationBox: MastodonAuthenticationBox?
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Instance>, Error> {
return Mastodon.API.Instance.instance(session: session, domain: domain)
return Mastodon.API.Instance.instance(session: session, authorization: authenticationBox?.userAuthorization, domain: domain)
}
public func instanceV2(
domain: String
domain: String,
authenticationBox: MastodonAuthenticationBox?
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.V2.Instance>, Error> {
return Mastodon.API.V2.Instance.instance(session: session, domain: domain)
return Mastodon.API.V2.Instance.instance(session: session, authorization: authenticationBox?.userAuthorization, domain: domain)
}
public func extendedDescription(domain: String) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.ExtendedDescription>, Error> {
return Mastodon.API.Instance.extendedDescription(session: session, domain: domain)
public func extendedDescription(
domain: String,
authenticationBox: MastodonAuthenticationBox?
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.ExtendedDescription>, Error> {
return Mastodon.API.Instance.extendedDescription(session: session, authorization: authenticationBox?.userAuthorization, domain: domain)
}
}

View File

@ -45,11 +45,11 @@ public final class InstanceService {
extension InstanceService {
func updateInstance(domain: String) {
guard let apiService = self.apiService else { return }
apiService.instance(domain: domain)
guard let apiService else { return }
apiService.instance(domain: domain, authenticationBox: authenticationService?.mastodonAuthenticationBoxes.first)
.flatMap { [unowned self] response -> AnyPublisher<Void, Error> in
if response.value.version?.majorServerVersion(greaterThanOrEquals: 4) == true {
return apiService.instanceV2(domain: domain)
return apiService.instanceV2(domain: domain, authenticationBox: authenticationService?.mastodonAuthenticationBoxes.first)
.flatMap { return self.updateInstanceV2(domain: domain, response: $0) }
.eraseToAnyPublisher()
} else {

View File

@ -28,9 +28,10 @@ extension Mastodon.API.Instance {
/// - Returns: `AnyPublisher` contains `Instance` nested in the response
public static func instance(
session: URLSession,
authorization: Mastodon.API.OAuth.Authorization?,
domain: String
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Instance>, Error> {
let request = Mastodon.API.get(url: instanceEndpointURL(domain: domain))
let request = Mastodon.API.get(url: instanceEndpointURL(domain: domain), authorization: authorization)
return session.dataTaskPublisher(for: request)
.tryMap { data, response in
let value: Mastodon.Entity.Instance
@ -62,9 +63,10 @@ extension Mastodon.API.Instance {
/// [Document](https://docs.joinmastodon.org/methods/instance/#extended_description)
public static func extendedDescription(
session: URLSession,
authorization: Mastodon.API.OAuth.Authorization?,
domain: String
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.ExtendedDescription>, Error> {
let request = Mastodon.API.get(url: extendedDescriptionEndpointURL(domain: domain))
let request = Mastodon.API.get(url: extendedDescriptionEndpointURL(domain: domain), authorization: authorization)
return session.dataTaskPublisher(for: request)
.tryMap { data, response in
let value = try Mastodon.API.decode(type: Mastodon.Entity.ExtendedDescription.self, from: data, response: response)

View File

@ -21,12 +21,13 @@ extension Mastodon.API.V2.Instance {
/// - Returns: `AnyPublisher` contains `Instance` nested in the response
public static func instance(
session: URLSession,
authorization: Mastodon.API.OAuth.Authorization?,
domain: String
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.V2.Instance>, Error> {
let request = Mastodon.API.get(
url: instanceEndpointURL(domain: domain),
query: nil,
authorization: nil
authorization: authorization
)
return session.dataTaskPublisher(for: request)
.tryMap { data, response in

View File

@ -211,7 +211,7 @@ extension Mastodon.API {
return try Mastodon.API.decoder.decode(type, from: data)
} catch let decodeError {
#if DEBUG
debugPrint("\(response.url), Data: \(String(data: data, encoding: .utf8)), \(decodeError)")
debugPrint("URL: \(String(describing: response.url))\nData: \(String(data: data, encoding: .utf8) ?? "-")\nError:\(decodeError)\n----\n")
#endif
guard let httpURLResponse = response as? HTTPURLResponse else {

View File

@ -8,7 +8,7 @@ extension Mastodon.Entity {
/// ## Reference:
/// [Document](https://docs.joinmastodon.org/entities/ExtendedDescription/)
public struct ExtendedDescription: Codable {
public let updatedAt: Date
public let updatedAt: Date?
public let content: String
enum CodingKeys: String, CodingKey {

View File

@ -110,7 +110,12 @@ private extension ActionRequestHandler {
func continueWithSearch(_ query: String) {
guard
let url = URL(string: query),
let host = url.host
let host = url.host,
let activeAuthenticationBox = Self.appContext
.authenticationService
.mastodonAuthenticationBoxes
.first
else {
return doneWithInvalidLink()
}
@ -119,6 +124,7 @@ private extension ActionRequestHandler {
.Instance
.instance(
session: .shared,
authorization: activeAuthenticationBox.userAuthorization,
domain: host
)
.receive(on: DispatchQueue.main)