mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Add HealthChat API and extended profile services (#9)
Expose OpenID tokens and homeserver credentials from the client proxy, and add fork-only services for the HealthChat member directory backend (api.healthchat.ch) plus a service that reads MSC4133 extended profile fields directly from the homeserver. Groundwork for the members tab and the profile screens. Claude-Session: https://claude.ai/code/session_013qdTbAWsZj2quQzEkagXaS
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Reads profiles straight from the homeserver's profile endpoint, which — unlike the
|
||||
/// Rust SDK's `getProfile` — includes the extended profile fields (MSC4133).
|
||||
final class ExtendedProfileService: ExtendedProfileServiceProtocol {
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let urlSession: URLSession
|
||||
|
||||
init(clientProxy: ClientProxyProtocol, urlSession: URLSession = .shared) {
|
||||
self.clientProxy = clientProxy
|
||||
self.urlSession = urlSession
|
||||
}
|
||||
|
||||
func profile(for userID: String) async -> Result<ExtendedProfile, ExtendedProfileServiceError> {
|
||||
guard case let .success(credentials) = clientProxy.homeserverCredentials() else {
|
||||
return .failure(.missingCredentials)
|
||||
}
|
||||
|
||||
let url = credentials.homeserverURL.appending(path: "_matrix/client/v3/profile/\(userID)")
|
||||
var request = URLRequest(url: url)
|
||||
request.setValue("Bearer \(credentials.accessToken)", forHTTPHeaderField: "Authorization")
|
||||
|
||||
let data: Data
|
||||
do {
|
||||
let (responseData, response) = try await urlSession.data(for: request)
|
||||
|
||||
guard let httpResponse = response as? HTTPURLResponse else {
|
||||
return .failure(.networkFailure)
|
||||
}
|
||||
guard httpResponse.statusCode == 200 else {
|
||||
MXLog.error("Failed fetching the extended profile for \(userID) with status: \(httpResponse.statusCode)")
|
||||
return .failure(.httpStatus(httpResponse.statusCode))
|
||||
}
|
||||
|
||||
data = responseData
|
||||
} catch {
|
||||
MXLog.error("Failed fetching the extended profile for \(userID) with error: \(error)")
|
||||
return .failure(.networkFailure)
|
||||
}
|
||||
|
||||
do {
|
||||
return try .success(JSONDecoder().decode(ExtendedProfile.self, from: data))
|
||||
} catch {
|
||||
MXLog.error("Failed decoding the extended profile for \(userID) with error: \(error)")
|
||||
return .failure(.decodingFailure)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user