Compare commits
	
		
			2 Commits
		
	
	
		
			a588a33338
			...
			c78dfbcf12
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c78dfbcf12 | |||
| 19251ed52f | 
@ -151,7 +151,7 @@ final class AuthService {
 | 
			
		||||
                        return
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    completion(true, apiResponse.data.message)
 | 
			
		||||
                    completion(true, NSLocalizedString(apiResponse.data.message, comment: ""))
 | 
			
		||||
                } catch {
 | 
			
		||||
                    completion(false, NSLocalizedString("Не удалось обработать ответ сервера.", comment: ""))
 | 
			
		||||
                }
 | 
			
		||||
@ -280,20 +280,28 @@ final class AuthService {
 | 
			
		||||
        case .network(let err):
 | 
			
		||||
            return String(format: NSLocalizedString("Ошибка сети: %@", comment: ""), err.localizedDescription)
 | 
			
		||||
        case .server(let statusCode, let data):
 | 
			
		||||
            if let message = extractMessage(from: data) {
 | 
			
		||||
                return message
 | 
			
		||||
            }
 | 
			
		||||
            let message = extractMessage(from: data)
 | 
			
		||||
 | 
			
		||||
            switch statusCode {
 | 
			
		||||
            case 401:
 | 
			
		||||
                return NSLocalizedString("Необходимо авторизоваться заново.", comment: "")
 | 
			
		||||
            case 403:
 | 
			
		||||
                if let message,
 | 
			
		||||
                   Self.changePasswordForbiddenMessages.contains(message) {
 | 
			
		||||
                    return NSLocalizedString(message, comment: "")
 | 
			
		||||
                }
 | 
			
		||||
                return NSLocalizedString("Старый пароль указан неверно или совпадает с новым.", comment: "")
 | 
			
		||||
            case 422:
 | 
			
		||||
                if let message {
 | 
			
		||||
                    return message
 | 
			
		||||
                }
 | 
			
		||||
                return NSLocalizedString("Проверьте данные и повторите попытку.", comment: "")
 | 
			
		||||
            case 429:
 | 
			
		||||
                return NSLocalizedString("Слишком много попыток. Попробуйте позже.", comment: "")
 | 
			
		||||
            default:
 | 
			
		||||
                if let message {
 | 
			
		||||
                    return message
 | 
			
		||||
                }
 | 
			
		||||
                return String(format: NSLocalizedString("Ошибка сервера: %@", comment: ""), "\(statusCode)")
 | 
			
		||||
            }
 | 
			
		||||
        case .unauthorized:
 | 
			
		||||
@ -305,7 +313,8 @@ final class AuthService {
 | 
			
		||||
 | 
			
		||||
    private func extractMessage(from data: Data?) -> String? {
 | 
			
		||||
        guard let data else { return nil }
 | 
			
		||||
        if let response = try? JSONDecoder().decode(ErrorResponse.self, from: data) {
 | 
			
		||||
        let decoder = JSONDecoder()
 | 
			
		||||
        if let response = try? decoder.decode(ErrorResponse.self, from: data) {
 | 
			
		||||
            if let message = response.data?.message, !message.isEmpty {
 | 
			
		||||
                return message
 | 
			
		||||
            }
 | 
			
		||||
@ -313,10 +322,61 @@ final class AuthService {
 | 
			
		||||
                return detail
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if let jsonObject = try? JSONSerialization.jsonObject(with: data) {
 | 
			
		||||
            if let dictionary = jsonObject as? [String: Any] {
 | 
			
		||||
                if let detail = Self.normalizedMessage(dictionary["detail"] as? String) {
 | 
			
		||||
                    return detail
 | 
			
		||||
                }
 | 
			
		||||
                if let dataDict = dictionary["data"] as? [String: Any],
 | 
			
		||||
                   let message = Self.normalizedMessage(dataDict["message"] as? String) {
 | 
			
		||||
                    return message
 | 
			
		||||
                }
 | 
			
		||||
                if let errors = dictionary["errors"] as? [[String: Any]],
 | 
			
		||||
                   let firstMessage = errors.compactMap({ Self.normalizedMessage($0["message"] as? String) }).first {
 | 
			
		||||
                    return firstMessage
 | 
			
		||||
                }
 | 
			
		||||
            } else if let array = jsonObject as? [[String: Any]] {
 | 
			
		||||
                if let firstMessage = array.compactMap({ item -> String? in
 | 
			
		||||
                    if let detail = Self.normalizedMessage(item["detail"] as? String) {
 | 
			
		||||
                        return detail
 | 
			
		||||
                    }
 | 
			
		||||
                    if let message = Self.normalizedMessage(item["message"] as? String) {
 | 
			
		||||
                        return message
 | 
			
		||||
                    }
 | 
			
		||||
                    if let msg = Self.normalizedMessage(item["msg"] as? String) {
 | 
			
		||||
                        return msg
 | 
			
		||||
                    }
 | 
			
		||||
                    return nil
 | 
			
		||||
                }).first {
 | 
			
		||||
                    return firstMessage
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if let string = Self.normalizedMessage(String(data: data, encoding: .utf8)) {
 | 
			
		||||
            return string
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return nil
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private extension AuthService {
 | 
			
		||||
    static let changePasswordForbiddenMessages: Set<String> = [
 | 
			
		||||
        "Неверный текущий пароль",
 | 
			
		||||
        "Пароль должен отличаться от старого",
 | 
			
		||||
        "Пароль не удовлетворяет требованиям"
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    static func normalizedMessage(_ raw: String?) -> String? {
 | 
			
		||||
        guard let raw = raw?.trimmingCharacters(in: .whitespacesAndNewlines), !raw.isEmpty else {
 | 
			
		||||
            return nil
 | 
			
		||||
        }
 | 
			
		||||
        return raw
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
private struct LoginRequest: Encodable {
 | 
			
		||||
    let login: String
 | 
			
		||||
    let password: String
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -12,24 +12,24 @@ enum ThemeOption: String, CaseIterable, Identifiable {
 | 
			
		||||
    var title: String {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .system:
 | 
			
		||||
            return "Системная"
 | 
			
		||||
            return NSLocalizedString("Системная", comment: "")
 | 
			
		||||
        case .oledDark:
 | 
			
		||||
            return "OLEG тёмный"
 | 
			
		||||
            return NSLocalizedString("OLEG тёмный", comment: "")
 | 
			
		||||
        case .dark:
 | 
			
		||||
            return "Тёмная"
 | 
			
		||||
            return NSLocalizedString("Тёмная", comment: "")
 | 
			
		||||
        case .lightTest:
 | 
			
		||||
            return "Светлая"
 | 
			
		||||
            return NSLocalizedString("Светлая", comment: "")
 | 
			
		||||
        case .custom:
 | 
			
		||||
            return "Кастомная"
 | 
			
		||||
            return NSLocalizedString("Кастомная", comment: "")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var note: String? {
 | 
			
		||||
        switch self {
 | 
			
		||||
        case .lightTest:
 | 
			
		||||
            return "Тестовая версия"
 | 
			
		||||
            return NSLocalizedString("Тестовая версия", comment: "")
 | 
			
		||||
        case .dark, .custom:
 | 
			
		||||
            return "Недоступна"
 | 
			
		||||
            return NSLocalizedString("Недоступна", comment: "")
 | 
			
		||||
        default:
 | 
			
		||||
            return nil
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -176,7 +176,7 @@ struct ChangePasswordView: View {
 | 
			
		||||
        .alert(item: $alertData) { data in
 | 
			
		||||
            Alert(
 | 
			
		||||
                title: Text(data.kind == .success
 | 
			
		||||
                             ? NSLocalizedString("Пароль обновлен", comment: "")
 | 
			
		||||
                             ? NSLocalizedString("Ура!", comment: "")
 | 
			
		||||
                             : NSLocalizedString("Ошибка", comment: "")),
 | 
			
		||||
                message: Text(data.message),
 | 
			
		||||
                dismissButton: .default(Text(NSLocalizedString("OK", comment: ""))) {
 | 
			
		||||
 | 
			
		||||
@ -21,9 +21,9 @@ struct SettingsView: View {
 | 
			
		||||
//            }
 | 
			
		||||
 | 
			
		||||
            // MARK: - Безопасность
 | 
			
		||||
            Section(header: Text("Безопасность")) {
 | 
			
		||||
            Section(header: Text(NSLocalizedString("Безопасность", comment: ""))) {
 | 
			
		||||
                NavigationLink(destination: ChangePasswordView()) {
 | 
			
		||||
                    Label("Сменить пароль", systemImage: "key")
 | 
			
		||||
                    Label(NSLocalizedString("Сменить пароль", comment: ""), systemImage: "key")
 | 
			
		||||
                }
 | 
			
		||||
                NavigationLink(destination: Text("Заглушка: Двухфакторная аутентификация")) {
 | 
			
		||||
                    Label("Двухфакторная аутентификация", systemImage: "lock.shield")
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user