diff --git a/yobble/Network/SessionsService.swift b/yobble/Network/SessionsService.swift index 3dd01e3..acd40b0 100644 --- a/yobble/Network/SessionsService.swift +++ b/yobble/Network/SessionsService.swift @@ -128,6 +128,49 @@ final class SessionsService { } } + func revoke(sessionId: UUID, completion: @escaping (Result) -> Void) { + client.request( + path: "/v1/auth/sessions/revoke/\(sessionId.uuidString)", + method: .post, + requiresAuth: true + ) { [decoder] result in + switch result { + case .success(let response): + do { + let apiResponse = try decoder.decode(APIResponse.self, from: response.data) + guard apiResponse.status == "fine" else { + let message = apiResponse.detail ?? NSLocalizedString("Не удалось завершить сессию.", comment: "Sessions service revoke unexpected status") + completion(.failure(SessionsServiceError.unexpectedStatus(message))) + return + } + completion(.success(apiResponse.data.message)) + } catch { + let debugMessage = Self.describeDecodingError(error: error, data: response.data) + if AppConfig.DEBUG { + print("[SessionsService] decode revoke failed: \(debugMessage)") + } + completion(.failure(SessionsServiceError.decoding(debugDescription: debugMessage))) + } + case .failure(let error): + if case let NetworkError.server(_, data) = error, + let data, + let message = Self.errorMessage(from: data) { + completion(.failure(SessionsServiceError.unexpectedStatus(message))) + return + } + completion(.failure(error)) + } + } + } + + func revoke(sessionId: UUID) async throws -> String { + try await withCheckedThrowingContinuation { continuation in + revoke(sessionId: sessionId) { result in + continuation.resume(with: result) + } + } + } + private static func decodeDate(from decoder: Decoder) throws -> Date { let container = try decoder.singleValueContainer() let string = try container.decode(String.self) diff --git a/yobble/Resources/Localizable.xcstrings b/yobble/Resources/Localizable.xcstrings index 815a0a1..f6d49d6 100644 --- a/yobble/Resources/Localizable.xcstrings +++ b/yobble/Resources/Localizable.xcstrings @@ -987,6 +987,9 @@ "Не удалось завершить другие сессии." : { "comment" : "Sessions service revoke-all unexpected status" }, + "Не удалось завершить сессию." : { + "comment" : "Sessions service revoke unexpected status" + }, "Не удалось загрузить историю чата." : { }, diff --git a/yobble/Views/Tab/Settings/ActiveSessionsView.swift b/yobble/Views/Tab/Settings/ActiveSessionsView.swift index 2d2cbad..741f6af 100644 --- a/yobble/Views/Tab/Settings/ActiveSessionsView.swift +++ b/yobble/Views/Tab/Settings/ActiveSessionsView.swift @@ -50,17 +50,19 @@ struct ActiveSessionsView: View { .padding(.vertical, 8) } } - + + if !otherSessions.isEmpty{ + Section { + revokeOtherSessionsButton + } + } + if !otherSessions.isEmpty { Section(header: Text(String(format: NSLocalizedString("Другие устройства (%d)", comment: "Заголовок секции других устройств с количеством"), otherSessions.count))) { ForEach(otherSessions) { session in sessionRow(for: session) } } - - Section { - revokeOtherSessionsButton - } } } }