import Foundation import Martin /// Turns a SASL authentication failure into an actionable Russian message. /// The raw `` condition (captured by `LumaSaslFailureModule`) /// wins over Martin's `SaslError`, because Martin maps every unknown RFC /// 6120 condition (e.g. `account-disabled`) to `not_authorized`. enum SaslFailureMessage { static func describe(error: Error, condition: String?, serverText: String?) -> String { if let serverText, !serverText.isEmpty { return "Сервер отклонил вход: \(serverText)" } switch condition { case "account-disabled": return "Аккаунт отключён на сервере. Обратитесь к администратору сервера." case "credentials-expired": return "Срок действия пароля истёк. Обновите пароль на сервере." case "encryption-required": return "Сервер требует шифрование канала для входа." case "malformed-request": return "Сервер не смог обработать запрос входа. Попробуйте ещё раз." case "restricted-connection": return "Сервер ограничил подключения с этого адреса." default: break } if let saslError = error as? SaslError { switch saslError { case .not_authorized: return "Сервер отклонил имя пользователя или пароль. Проверьте JID и пароль." case .temporary_auth_failure: return "Сервер временно не может проверить учётные данные. Попробуйте через минуту." case .server_not_trusted: return "Сервер не прошёл проверку подписи SCRAM." case .incorrect_encoding: return "Сервер не принял кодировку учётных данных." case .invalid_authzid: return "Сервер отклонил идентификатор авторизации." case .invalid_mechanism, .mechanism_too_weak: return "Сервер не поддерживает доступные способы входа." case .aborted: return "Вход прерван." } } return error.localizedDescription } }