diff --git a/Shared/Network/AuthService.swift b/Shared/Network/AuthService.swift
index 92e140a..9d0cdd9 100644
--- a/Shared/Network/AuthService.swift
+++ b/Shared/Network/AuthService.swift
@@ -8,22 +8,287 @@
 import Foundation
 
 class AuthService {
-    func autoLogin(completion: @escaping (Bool) -> Void) {
-        // Симуляция проверки токена
-        DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
-            let success = false  // Пока всегда неуспешно, для теста
-            completion(success)
-        }
-    }
     
-    func login(username: String, password: String, completion: @escaping (Bool, String?) -> Void) {
-        // Симуляция запроса
-        DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
-            if username == "test" && password == "123123" {
+    func autoLogin(completion: @escaping (Bool, String?) -> Void) {
+        // 1️⃣ Проверяем наличие текущего пользователя
+        if let currentUser = UserDefaults.standard.string(forKey: "currentUser"),
+           let accessToken = KeychainService.shared.get(forKey: "access_token", service: currentUser),
+           let refreshToken = KeychainService.shared.get(forKey: "refresh_token", service: currentUser) {
+            if AppConfig.DEBUG{ print("AutoLogin: найден текущий пользователь — \(currentUser)")}
+            completion(true, nil)
+            return
+        }
+
+        // 2️⃣ Текущий пользователь не найден или токены отсутствуют
+        if AppConfig.DEBUG{ print("AutoLogin: текущий пользователь не найден или токены отсутствуют. Пробуем найти другого пользователя...")}
+        
+        let allUsers = KeychainService.shared.getAllServices()
+        
+        for user in allUsers {
+            let hasAccessToken = KeychainService.shared.get(forKey: "access_token", service: user) != nil
+            let hasRefreshToken = KeychainService.shared.get(forKey: "refresh_token", service: user) != nil
+            
+            if hasAccessToken && hasRefreshToken {
+                // Нашли пользователя с токенами — назначаем как currentUser
+                UserDefaults.standard.set(user, forKey: "currentUser")
+                if AppConfig.DEBUG{ print("AutoLogin: переключились на пользователя \(user)")}
                 completion(true, nil)
-            } else {
-                completion(false, "Неверные учетные данные.")
+                return
             }
         }
+        
+        // 3️⃣ Если никто не найден
+//        completion(false, "Не найден авторизованный пользователь. Пожалуйста, войдите снова.")
+        completion(false, nil)
+    }
+
+    
+    func login(username: String, password: String, completion: @escaping (Bool, String?) -> Void) {
+        let url = URL(string: "\(AppConfig.API_SERVER)/auth/login")!
+        var request = URLRequest(url: url)
+        request.httpMethod = "POST"
+        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+        request.setValue("\(AppConfig.USER_AGENT)", forHTTPHeaderField: "User-Agent")
+
+        let payload: [String: String] = [
+            "login": username,
+            "password": password
+        ]
+
+        do {
+            let jsonData = try JSONEncoder().encode(payload)
+            request.httpBody = jsonData
+        } catch {
+            DispatchQueue.main.async {
+                completion(false, NSLocalizedString("AuthService_error_serialization", comment: ""))
+            }
+            return
+        }
+
+        let task = URLSession.shared.dataTask(with: request) { data, response, error in
+            DispatchQueue.main.async {
+                if let error = error {
+                    let errorMessage = String(format: NSLocalizedString("AuthService_error_network", comment: ""), error.localizedDescription)
+                    completion(false, errorMessage)
+                    return
+                }
+                
+                guard let httpResponse = response as? HTTPURLResponse else {
+                    completion(false, NSLocalizedString("AuthService_error_invalid_response", comment: ""))
+                    return
+                }
+                
+                guard (200...299).contains(httpResponse.statusCode) else {
+                    if httpResponse.statusCode == 401{
+                        completion(false, NSLocalizedString("AuthService_error_invalid_credentials", comment: ""))
+                    } else if httpResponse.statusCode == 502{
+                        completion(false, NSLocalizedString("AuthService_error_server_unavailable", comment: ""))
+                    } else if httpResponse.statusCode == 429 {
+                        completion(false, NSLocalizedString("AuthService_error_too_many_requests", comment: ""))
+                    } else {
+                        let errorMessage = String(format: NSLocalizedString("AuthService_error_server_error", comment: ""), "\(httpResponse.statusCode)")
+                        completion(false, errorMessage)
+                    }
+                    return
+                }
+
+                guard let data = data else {
+                    completion(false, NSLocalizedString("AuthService_error_empty_response", comment: ""))
+                    return
+                }
+
+                do {
+                    let decoder = JSONDecoder()
+                    let loginResponse = try decoder.decode(LoginResponse.self, from: data)
+                    
+                    // Сохраняем токены в Keychain
+                    KeychainService.shared.save(loginResponse.access_token, forKey: "access_token", service: username)
+                    KeychainService.shared.save(loginResponse.refresh_token, forKey: "refresh_token", service: username)
+                    UserDefaults.standard.set(username, forKey: "currentUser")
+                    
+                    completion(true, nil)
+                } catch {
+                    completion(false, NSLocalizedString("AuthService_error_parsing_response", comment: ""))
+                }
+            }
+        }
+        task.resume()
+    }
+
+    func register(username: String, password: String, invite: String?, completion: @escaping (Bool, String?) -> Void) {
+        let url = URL(string: "\(AppConfig.API_SERVER)/auth/register")!
+        var request = URLRequest(url: url)
+        request.httpMethod = "POST"
+        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+        request.setValue(AppConfig.USER_AGENT, forHTTPHeaderField: "User-Agent")
+
+        let payload: [String: Any] = [
+            "login": username,
+            "password": password,
+            "invite": invite ?? NSNull()
+        ]
+        
+        do {
+            let jsonData = try JSONSerialization.data(withJSONObject: payload)
+            request.httpBody = jsonData
+        } catch {
+            DispatchQueue.main.async {
+                completion(false, NSLocalizedString("AuthService_error_serialization", comment: ""))
+            }
+            return
+        }
+
+        let task = URLSession.shared.dataTask(with: request) { data, response, error in
+            DispatchQueue.main.async {
+                if let error = error {
+                    let errorMessage = String(format: NSLocalizedString("AuthService_error_network", comment: ""), error.localizedDescription)
+                    completion(false, errorMessage)
+                    return
+                }
+                
+                guard let httpResponse = response as? HTTPURLResponse else {
+                    completion(false, NSLocalizedString("AuthService_error_invalid_response", comment: ""))
+                    return
+                }
+                
+                guard let data = data else {
+                    completion(false, NSLocalizedString("AuthService_error_empty_response", comment: ""))
+                    return
+                }
+                
+                let decoder = JSONDecoder()
+                
+                if (200...299).contains(httpResponse.statusCode) {
+                    do {
+                        let _ = try decoder.decode(RegisterResponse.self, from: data)
+                        if AppConfig.DEBUG{ print("Регистрация успешна. Пытаемся сразу войти...")}
+
+                        // Сразу логинимся
+                        self.login(username: username, password: password) { loginSuccess, loginMessage in
+                            if loginSuccess {
+                                completion(true, "Регистрация и вход выполнены успешно.")
+                            } else {
+                                // Регистрация успешна, но логин не удался — покажем сообщение
+                                completion(false, loginMessage ?? NSLocalizedString("AuthService_login_success_but_failed", comment: ""))
+                            }
+                        }
+                    } catch {
+                        completion(false, NSLocalizedString("AuthService_error_parsing_response", comment: ""))
+                    }
+                } else {
+                    // Ошибка сервера — пробуем распарсить message
+                    if let errorResponseMessage = try? decoder.decode(ErrorResponseMessage.self, from: data),
+                       let message = errorResponseMessage.message {
+                        
+                        if let jsonString = String(data: data, encoding: .utf8) {
+                            if AppConfig.DEBUG{ print("Raw JSON:", jsonString)}
+                        }
+                        if AppConfig.DEBUG{ print("message:", message)}
+                        
+                        if httpResponse.statusCode == 400 {
+                            if message.contains("Invalid invitation code") {
+                                completion(false, NSLocalizedString("AuthService_error_invalid_invitation_code", comment: ""))
+                            } else if message.contains("This invitation is not active") {
+                                completion(false, NSLocalizedString("AuthService_error_invitation_not_active", comment: ""))
+                            } else if message.contains("This invitation has reached its usage limit") {
+                                completion(false, NSLocalizedString("AuthService_error_invitation_usage_limit", comment: ""))
+                            } else if message.contains("This invitation has expired") {
+                                completion(false, NSLocalizedString("AuthService_error_invitation_expired", comment: ""))
+                            } else if message.contains("Login already registered") {
+                                completion(false, NSLocalizedString("AuthService_error_login_already_registered", comment: ""))
+                            } else {
+                                completion(false, message)
+                            }
+                        } else if httpResponse.statusCode == 403 {
+                            if message.contains("Registration is currently disabled") {
+                                completion(false, NSLocalizedString("AuthService_error_registration_disabled", comment: ""))
+                            } else {
+                                completion(false, message)
+                            }
+                        } else if httpResponse.statusCode == 429 {
+                            completion(false, NSLocalizedString("AuthService_error_too_many_requests", comment: ""))
+                        } else if httpResponse.statusCode == 502{
+                            completion(false, NSLocalizedString("AuthService_error_server_unavailable", comment: ""))
+                        } else {
+                            let errorMessage = String(format: NSLocalizedString("AuthService_error_server_error", comment: ""), "\(httpResponse.statusCode)")
+                            completion(false, errorMessage)
+                        }
+                    } else {
+                        // Не удалось распарсить JSON — fallback
+                        if httpResponse.statusCode == 400 {
+                            completion(false, NSLocalizedString("AuthService_error_invalid_request", comment: ""))
+                        } else if httpResponse.statusCode == 403 {
+                            completion(false, NSLocalizedString("AuthService_error_registration_forbidden", comment: ""))
+                        } else if httpResponse.statusCode == 429 {
+                            completion(false, NSLocalizedString("AuthService_error_too_many_requests", comment: ""))
+                        } else if httpResponse.statusCode == 502{
+                            completion(false, NSLocalizedString("AuthService_error_server_unavailable", comment: ""))
+                        } else {
+                            let errorMessage = String(format: NSLocalizedString("AuthService_error_server_error", comment: ""), "\(httpResponse.statusCode)")
+                            completion(false, errorMessage)
+                        }
+                    }
+                }
+            }
+        }
+        task.resume()
+    }
+
+
+
+
+    func logoutCurrentUser(completion: @escaping (Bool, String?) -> Void) {
+        guard let currentUser = UserDefaults.standard.string(forKey: "currentUser") else {
+            completion(false, "Не найден текущий пользователь.")
+            return
+        }
+        
+        // Удаляем токены текущего пользователя
+        KeychainService.shared.delete(forKey: "access_token", service: currentUser)
+        KeychainService.shared.delete(forKey: "refresh_token", service: currentUser)
+        
+        // Сбрасываем текущего пользователя
+        UserDefaults.standard.removeObject(forKey: "currentUser")
+        
+        // Пробуем переключиться на другого пользователя
+        let allUsers = KeychainService.shared.getAllServices()
+        for user in allUsers {
+            let hasAccessToken = KeychainService.shared.get(forKey: "access_token", service: user) != nil
+            let hasRefreshToken = KeychainService.shared.get(forKey: "refresh_token", service: user) != nil
+            
+            if hasAccessToken && hasRefreshToken {
+                UserDefaults.standard.set(user, forKey: "currentUser")
+                if AppConfig.DEBUG{ print("Logout: переключились на пользователя \(user)")}
+                completion(true, nil)
+                return
+            }
+        }
+
+        // Если пользователей больше нет
+//        completion(false, "Нет доступных пользователей. Пожалуйста, войдите снова.")
+        completion(false, nil)
     }
 }
+
+struct LoginResponse: Decodable {
+    let status: String
+    let access_token: String
+    let refresh_token: String
+    let token_type: String
+}
+
+struct TokenRefreshResponse: Decodable {
+    let status: String
+    let access_token: String
+    let token_type: String
+}
+
+struct RegisterResponse: Decodable {
+    let status: String
+    let message: String
+}
+
+struct ErrorResponseMessage: Decodable {
+    let status: String?
+    let message: String?
+}
diff --git a/Shared/Network/refreshtokenex.swift b/Shared/Network/refreshtokenex.swift
new file mode 100644
index 0000000..7852ec8
--- /dev/null
+++ b/Shared/Network/refreshtokenex.swift
@@ -0,0 +1,89 @@
+////
+////  refreshtokenex.swift
+////  volnahub (iOS)
+////
+////  Created by cheykrym on 11/06/2025.
+////
+//
+//import Foundation
+//
+//func autoLogin(completion: @escaping (Bool, String?) -> Void) {
+//    guard let username = UserDefaults.standard.string(forKey: "currentUser") else {
+//        completion(false, "Не найден текущий пользователь")
+//        return
+//    }
+//    
+//    guard let accessToken = KeychainService.shared.get(forKey: "access_token", service: username),
+//          let refreshToken = KeychainService.shared.get(forKey: "refresh_token", service: username) else {
+//        completion(false, "Токены отсутствуют. Пожалуйста, войдите снова.")
+//        return
+//    }
+//    
+////        let url = URL(string: "\(AppConfig.API_SERVER)/auth/refresh")!
+////        var request = URLRequest(url: url)
+////        request.httpMethod = "POST"
+////        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
+//////        request.setValue("VolnahubApp", forHTTPHeaderField: "User-Agent")
+////        request.setValue("VolnahubApp", forHTTPHeaderField: "\(AppConfig.USER_AGENT)")
+////
+////        let payload: [String: String] = [
+////            "access_token": accessToken,
+////            "refresh_token": refreshToken
+////        ]
+////
+////        do {
+////            let jsonData = try JSONEncoder().encode(payload)
+////            request.httpBody = jsonData
+////        } catch {
+////            DispatchQueue.main.async {
+////                completion(false, "Не удалось подготовить запрос.")
+////            }
+////            return
+////        }
+////
+////        let task = URLSession.shared.dataTask(with: request) { data, response, error in
+////            DispatchQueue.main.async {
+////                if let error = error {
+////                    print("AutoLogin error: \(error.localizedDescription)")
+////                    completion(false, "Ошибка сети: \(error.localizedDescription)")
+////                    return
+////                }
+////
+////                guard let httpResponse = response as? HTTPURLResponse else {
+////                    completion(false, "Некорректный ответ от сервера.")
+////                    return
+////                }
+////
+////                guard (200...299).contains(httpResponse.statusCode) else {
+////                    if httpResponse.statusCode == 401 {
+////                        print("деавторизация") //TODO
+////                        completion(false, "Сессия недействительна. Пожалуйста, войдите снова.")
+////                    } else if httpResponse.statusCode == 502 {
+////                        completion(false, "Сервер не отвечает. Попробуйте позже.")
+////                    } else {
+////                        completion(false, "Ошибка сервера: \(httpResponse.statusCode)")
+////                    }
+////                    return
+////                }
+////
+////                guard let data = data else {
+////                    completion(false, "Пустой ответ от сервера.")
+////                    return
+////                }
+////
+////                do {
+////                    let decoder = JSONDecoder()
+////                    let refreshResponse = try decoder.decode(TokenRefreshResponse.self, from: data)
+////
+////                    KeychainService.shared.save(refreshResponse.access_token, forKey: "access_token", service: username)
+////
+////                    print("AutoLogin: токен обновлён.")
+////                    completion(true, nil)
+////                } catch {
+////                    print("AutoLogin decode error: \(error.localizedDescription)")
+////                    completion(false, "Ошибка обработки ответа сервера.")
+////                }
+////            }
+////        }
+////        task.resume()
+//}
diff --git a/Shared/Resources/en.lproj/Localizable.strings b/Shared/Resources/en.lproj/Localizable.strings
index b9cd02e..b0a37e3 100644
--- a/Shared/Resources/en.lproj/Localizable.strings
+++ b/Shared/Resources/en.lproj/Localizable.strings
@@ -1,7 +1,54 @@
-/* 
+/*
   Localizable.strings
   volnahub
 
   Created by cheykrym on 10/06/2025.
-  
 */
+
+/* General */
+"ok" = "OK";
+"loading_placeholder" = "Loading...";
+
+/* LoginView */
+"LoginView_change_language" = "Language";
+"LoginView_login" = "Login";
+"LoginView_password" = "Password";
+"LoginView_button_login" = "Log in";
+"LoginView_error" = "Login error";
+"LoginView_button_register" = "Register";
+"LoginView_error_username_invalid" = "Username must be 3 to 32 characters (letters, digits, or _)";
+"LoginView_error_password_invalid" = "Password must be 6 to 32 characters long";
+
+/* RegistrationView */
+"RegistrationView_title" = "Registration";
+"RegistrationView_fullname" = "Full name";
+"RegistrationView_login" = "Login";
+"RegistrationView_error_username_invalid" = "Username must be 3 to 32 characters (letters, digits, or _)";
+"RegistrationView_password" = "Password";
+"RegistrationView_error_password_invalid" = "Password must be 6 to 32 characters long";
+"RegistrationView_confirm_password" = "Confirm password";
+"RegistrationView_error_confirm_password_invalid" = "Passwords do not match";
+"RegistrationView_invite" = "Invite code (optional)";
+"RegistrationView_button_register" = "Register";
+"RegistrationView_close" = "Close";
+"RegistrationView_error" = "Registration error";
+
+/* AuthService */
+"AuthService_error_invalid_invitation_code" = "Invalid invitation code.";
+"AuthService_error_invitation_not_active" = "The invitation is not active.";
+"AuthService_error_invitation_usage_limit" = "The invitation has reached its usage limit.";
+"AuthService_error_invitation_expired" = "The invitation has expired.";
+"AuthService_error_login_already_registered" = "This login is already registered.";
+"AuthService_error_registration_disabled" = "Registration is temporarily unavailable.";
+"AuthService_error_server_unavailable" = "Server is unavailable. Please try again later.";
+"AuthService_error_too_many_requests" = "Too many requests.";
+"AuthService_error_invalid_request" = "Invalid request (400).";
+"AuthService_error_registration_forbidden" = "Registration is forbidden.";
+"AuthService_error_server_error" = "Server error: %@";
+"AuthService_error_network" = "Network error: %@";
+"AuthService_error_invalid_response" = "Invalid server response.";
+"AuthService_error_invalid_credentials" = "Invalid username or password.";
+"AuthService_error_empty_response" = "Empty server response.";
+"AuthService_error_parsing_response" = "Failed to parse server response.";
+"AuthService_error_serialization" = "Failed to serialize request data.";
+"AuthService_login_success_but_failed" = "Registration succeeded, but login failed.";
diff --git a/Shared/Resources/ru.lproj/Localizable.strings b/Shared/Resources/ru.lproj/Localizable.strings
index 70d9123..9c0803d 100644
--- a/Shared/Resources/ru.lproj/Localizable.strings
+++ b/Shared/Resources/ru.lproj/Localizable.strings
@@ -5,10 +5,54 @@
   Created by cheykrym on 10/06/2025.
   
 */
+"ok" = "OK";
 "loading_placeholder" = "Загрузка...";
+
+/* LoginView */
 "LoginView_change_language" = "Язык";
-"LoginView_title" = "Вход";
 "LoginView_login" = "Логин";
 "LoginView_password" = "Пароль";
 "LoginView_button_login" = "Войти";
+"LoginView_error" = "Ошибка авторизации";
 "LoginView_button_register" = "Регистрация";
+"LoginView_error_username_invalid" = "Логин должен быть от 3 до 32 символов (английские буквы, цифры, _)";
+"LoginView_error_password_invalid" = "Пароль должен быть от 6 до 32 символов";
+
+/* RegistrationView */
+"RegistrationView_title" = "Регистрация";
+"RegistrationView_fullname" = "Имя";
+"RegistrationView_login" = "Логин";
+"RegistrationView_error_username_invalid" = "Логин должен быть от 3 до 32 символов (английские буквы, цифры, _)";
+"RegistrationView_password" = "Пароль";
+"RegistrationView_error_password_invalid" = "Пароль должен быть от 6 до 32 символов";
+"RegistrationView_confirm_password" = "Подтверждение пароля";
+"RegistrationView_error_confirm_password_invalid" = "Пароли не совпадают";
+"RegistrationView_invite" = "Инвайт-код (необязательно)";
+"RegistrationView_button_register" = "Зарегистрироваться";
+"RegistrationView_close" = "Закрыть";
+"RegistrationView_error" = "Ошибка регистрация";
+
+/* AuthService */
+"AuthService_error_invalid_invitation_code" = "Неверный код приглашения.";
+"AuthService_error_invitation_not_active" = "Приглашение не активно.";
+"AuthService_error_invitation_usage_limit" = "Приглашение достигло лимита использования.";
+"AuthService_error_invitation_expired" = "Приглашение истекло.";
+"AuthService_error_login_already_registered" = "Логин уже занят.";
+"AuthService_error_registration_disabled" = "Регистрация временно недоступна.";
+"AuthService_error_server_unavailable" = "Сервер не отвечает. Попробуйте позже.";
+"AuthService_error_too_many_requests" = "Слишком много запросов.";
+"AuthService_error_invalid_request" = "Неверный запрос (400).";
+"AuthService_error_registration_forbidden" = "Регистрация запрещена.";
+"AuthService_error_server_error" = "Ошибка сервера: %@";
+"AuthService_error_network" = "Ошибка сети: %@";
+"AuthService_error_invalid_response" = "Некорректный ответ от сервера.";
+"AuthService_error_invalid_credentials" = "Неверный логин или пароль.";
+"AuthService_error_empty_response" = "Пустой ответ от сервера.";
+"AuthService_error_parsing_response" = "Не удалось обработать ответ сервера.";
+"AuthService_error_serialization" = "Не удалось сериализовать данные запроса.";
+"AuthService_login_success_but_failed" = "Регистрация выполнена, но вход не удался.";
+
+/* MainView */
+"MainView_contacts" = "Контакты";
+"MainView_chats" = "Чаты";
+"MainView_settings" = "Настройки";
diff --git a/Shared/ViewModels/LoginViewModel.swift b/Shared/ViewModels/LoginViewModel.swift
index 8348f96..ad32f91 100644
--- a/Shared/ViewModels/LoginViewModel.swift
+++ b/Shared/ViewModels/LoginViewModel.swift
@@ -11,28 +11,39 @@ import Combine
 class LoginViewModel: ObservableObject {
     @Published var username: String = ""
     @Published var password: String = ""
-    @Published var isLoading: Bool = true    // сразу true, чтобы вызывался автологин
+    @Published var isLoading: Bool = true    // сразу true, чтобы показать спиннер при автологине
     @Published var showError: Bool = false
     @Published var errorMessage: String = ""
     @Published var isLoggedIn: Bool = false
 
     private let authService = AuthService()
-    
+
     init() {
+        // Если username сохранён, подставим его сразу
+        if let savedUsername = UserDefaults.standard.string(forKey: "currentUser") {
+            username = savedUsername
+        }
+        
+        // Запускаем автологин
         autoLogin()
     }
-    
+
     func autoLogin() {
-        authService.autoLogin { [weak self] success in
+        authService.autoLogin { [weak self] success, error in
             DispatchQueue.main.async {
                 self?.isLoading = false
                 if success {
                     self?.isLoggedIn = true
+                } else {
+                    self?.isLoggedIn = false
+                    self?.errorMessage = error ?? "Произошла ошибка."
+                    self?.showError = false
                 }
             }
         }
     }
-    
+
+
     func login() {
         isLoading = true
         showError = false
@@ -50,10 +61,42 @@ class LoginViewModel: ObservableObject {
         }
     }
     
-    func logout() {
-        username = ""
-        password = ""
-        isLoggedIn = false
+    func registerUser(username: String, password: String, invite: String?, completion: @escaping (Bool, String?) -> Void) {
+        authService.register(username: username, password: password, invite: invite) { [weak self] success, message in
+            DispatchQueue.main.async {
+                if success {
+                    self?.isLoggedIn = true // 👈 переключаем на главный экран после автологина
+                }
+                completion(success, message)
+            }
+        }
     }
 
+    func logoutCurrentUser() {
+        authService.logoutCurrentUser { [weak self] success, error in
+            DispatchQueue.main.async {
+                if success {
+                    self?.username = UserDefaults.standard.string(forKey: "currentUser") ?? ""
+                    self?.password = ""
+                    self?.isLoggedIn = true
+                    self?.showError = false
+                } else {
+                    self?.username = ""
+                    self?.password = ""
+                    self?.isLoggedIn = false
+                    self?.errorMessage = error ?? "Ошибка при деавторизации."
+                    self?.showError = false
+                }
+            }
+        }
+    }
+
+    
+//    func logout() {
+//        username = ""
+//        password = ""
+//        isLoggedIn = false
+//        showError = false
+//        errorMessage = ""
+//    }
 }
diff --git a/Shared/Views/CustomTextField.swift b/Shared/Views/CustomTextField.swift
new file mode 100644
index 0000000..f249cd1
--- /dev/null
+++ b/Shared/Views/CustomTextField.swift
@@ -0,0 +1,55 @@
+//
+//  CustomTextField.swift
+//  VolnahubApp
+//
+//  Created by cheykrym on 11/06/2025.
+//
+
+import SwiftUI
+
+struct CustomTextField: UIViewRepresentable {
+    class Coordinator: NSObject, UITextFieldDelegate {
+        var parent: CustomTextField
+
+        init(_ parent: CustomTextField) {
+            self.parent = parent
+        }
+
+        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+            parent.onReturn()
+            return false // предотвращаем автоматический переход на новую строку
+        }
+
+        @objc func textFieldDidChange(_ textField: UITextField) {
+            parent.text = textField.text ?? ""
+        }
+    }
+
+    var placeholder: String
+    @Binding var text: String
+    var isSecure: Bool = false
+    var onReturn: () -> Void
+
+    func makeUIView(context: Context) -> UITextField {
+        let textField = UITextField()
+        textField.placeholder = placeholder
+        textField.delegate = context.coordinator
+        textField.borderStyle = .roundedRect
+        textField.autocapitalizationType = .none
+        textField.autocorrectionType = .no
+        textField.isSecureTextEntry = isSecure
+        textField.returnKeyType = .next
+        textField.addTarget(context.coordinator, action: #selector(Coordinator.textFieldDidChange(_:)), for: .editingChanged)
+        return textField
+    }
+
+    func updateUIView(_ uiView: UITextField, context: Context) {
+        if uiView.text != text {
+            uiView.text = text
+        }
+    }
+
+    func makeCoordinator() -> Coordinator {
+        Coordinator(self)
+    }
+}
diff --git a/Shared/Views/LoginView.swift b/Shared/Views/LoginView.swift
index ba1ff8b..936b6fd 100644
--- a/Shared/Views/LoginView.swift
+++ b/Shared/Views/LoginView.swift
@@ -24,115 +24,128 @@ struct LoginView: View {
     
     var body: some View {
 
-        VStack {
-            HStack {
-
-                Button(action: openLanguageSettings) {
-                    Text("🌍 " + NSLocalizedString("LoginView_change_language", comment: ""))
-                        .padding()
+        ZStack {
+            Color.clear // чтобы поймать тап
+                .contentShape(Rectangle())
+                .onTapGesture {
+                    hideKeyboard()
                 }
-                Spacer()
-                Button(action: toggleTheme) {
-                    Image(systemName: isDarkMode ? "moon.fill" : "sun.max.fill")
-                        .padding()
-                }
-            }
 
-            Spacer()
+            VStack {
+                HStack {
 
-            
-//            Text(NSLocalizedString("LoginView_title", comment: ""))
-//                .font(.largeTitle)
-//                .bold()
-
-            TextField(NSLocalizedString("LoginView_login", comment: ""), text: $viewModel.username)
-                .padding()
-                .background(Color(.secondarySystemBackground))
-                .cornerRadius(8)
-                .autocapitalization(.none)
-                .disableAutocorrection(true)
-                .onChange(of: viewModel.username) { newValue in
-                    if newValue.count > 32 {
-                        viewModel.username = String(newValue.prefix(32))
+                    Button(action: openLanguageSettings) {
+                        Text("🌍")
+                            .padding()
+                    }
+                    Spacer()
+                    Button(action: toggleTheme) {
+                        Image(systemName: isDarkMode ? "moon.fill" : "sun.max.fill")
+                            .padding()
                     }
                 }
-
-            // Показываем ошибку для логина
-            if !isUsernameValid && !viewModel.username.isEmpty {
-                Text(NSLocalizedString("LoginView_error_username_invalid", comment: "Неверный логин"))
-                    .foregroundColor(.red)
-                    .font(.caption)
+                .onTapGesture {
+                hideKeyboard()
             }
 
-            // Показываем поле пароля (даже если оно невалидное) только если логин корректен
-            if isUsernameValid {
-                SecureField(NSLocalizedString("LoginView_password", comment: ""), text: $viewModel.password)
+                Spacer()
+
+                TextField(NSLocalizedString("LoginView_login", comment: ""), text: $viewModel.username)
                     .padding()
                     .background(Color(.secondarySystemBackground))
                     .cornerRadius(8)
                     .autocapitalization(.none)
-                    .onChange(of: viewModel.password) { newValue in
+                    .disableAutocorrection(true)
+                    .onChange(of: viewModel.username) { newValue in
                         if newValue.count > 32 {
-                            viewModel.password = String(newValue.prefix(32))
+                            viewModel.username = String(newValue.prefix(32))
                         }
                     }
 
-                // Показываем ошибку для пароля
-                if !isPasswordValid && !viewModel.password.isEmpty {
-                    Text(NSLocalizedString("LoginView_error_password_invalid", comment: "Неверный пароль"))
+                // Показываем ошибку для логина
+                if !isUsernameValid && !viewModel.username.isEmpty {
+                    Text(NSLocalizedString("LoginView_error_username_invalid", comment: "Неверный логин"))
                         .foregroundColor(.red)
                         .font(.caption)
                 }
-            }
-            
-            if isUsernameValid && isPasswordValid {
-                Button(action: {
-                    viewModel.login()
-                }) {
-                    if viewModel.isLoading {
-                        ProgressView()
-                            .progressViewStyle(CircularProgressViewStyle())
-                            .padding()
-                            .frame(maxWidth: .infinity)
-                            .background(Color.gray.opacity(0.6))
-                            .cornerRadius(8)
-                    } else {
-                        Text(NSLocalizedString("LoginView_button_login", comment: ""))
-                            .foregroundColor(.white)
-                            .padding()
-                            .frame(maxWidth: .infinity)
-                            .background(Color.blue)
-                            .cornerRadius(8)
+
+                // Показываем поле пароля (даже если оно невалидное) только если логин корректен
+                if isUsernameValid || !viewModel.password.isEmpty {
+                    SecureField(NSLocalizedString("LoginView_password", comment: ""), text: $viewModel.password)
+                        .padding()
+                        .background(Color(.secondarySystemBackground))
+                        .cornerRadius(8)
+                        .autocapitalization(.none)
+                        .onChange(of: viewModel.password) { newValue in
+                            if newValue.count > 32 {
+                                viewModel.password = String(newValue.prefix(32))
+                            }
+                        }
+
+                    // Показываем ошибку для пароля
+                    if !isPasswordValid && !viewModel.password.isEmpty {
+                        Text(NSLocalizedString("LoginView_error_password_invalid", comment: "Неверный пароль"))
+                            .foregroundColor(.red)
+                            .font(.caption)
                     }
                 }
-                .disabled(viewModel.isLoading)
-            }
+                
+                if isUsernameValid && isPasswordValid {
+                    Button(action: {
+                        viewModel.login()
+                    }) {
+                        if viewModel.isLoading {
+                            ProgressView()
+                                .progressViewStyle(CircularProgressViewStyle())
+                                .padding()
+                                .frame(maxWidth: .infinity)
+                                .background(Color.gray.opacity(0.6))
+                                .cornerRadius(8)
+                        } else {
+                            Text(NSLocalizedString("LoginView_button_login", comment: ""))
+                                .foregroundColor(.white)
+                                .padding()
+                                .frame(maxWidth: .infinity)
+                                .background(Color.blue)
+                                .cornerRadius(8)
+                        }
+                    }
+                    .disabled(viewModel.isLoading || !isUsernameValid || !isPasswordValid)
+                }
 
-            Spacer()
-            
-            // Кнопка регистрации
-            Button(action: {
-                isShowingRegistration = true
-            }) {
-                Text(NSLocalizedString("LoginView_button_register", comment: "Регистрация"))
-                    .foregroundColor(.blue)
+                Spacer()
+                
+                // Кнопка регистрации
+                Button(action: {
+                    isShowingRegistration = true
+                }) {
+                    Text(NSLocalizedString("LoginView_button_register", comment: "Регистрация"))
+                        .foregroundColor(.blue)
+                }
+                .padding(.top, 10)
+                .sheet(isPresented: $isShowingRegistration) {
+                    RegistrationView(viewModel: viewModel)
+                }
+                
             }
-            .padding(.top, 10)
-            .sheet(isPresented: $isShowingRegistration) {
-                RegistrationView()
+            .padding()
+            .alert(isPresented: $viewModel.showError) {
+                Alert(
+                    title: Text(NSLocalizedString("LoginView_error", comment: "")),
+                    message: Text(viewModel.errorMessage),
+                    dismissButton: .default(Text(NSLocalizedString("ok", comment: "")))
+                )
             }
-            
+            .onTapGesture {
+            hideKeyboard()
         }
-        .padding()
-        .alert(isPresented: $viewModel.showError) {
-            Alert(
-                title: Text(NSLocalizedString("LoginView_error", comment: "")),
-                message: Text(viewModel.errorMessage),
-                dismissButton: .default(Text("ОК"))
-            )
         }
     }
     
+    
+
+
+    
     private func toggleTheme() {
         isDarkMode.toggle()
     }
@@ -141,6 +154,10 @@ struct LoginView: View {
         guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
         UIApplication.shared.open(url)
     }
+    
+    private func hideKeyboard() {
+        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
+    }
 
 }
 
diff --git a/Shared/Views/MainView.swift b/Shared/Views/MainView.swift
index d285059..8f742fd 100644
--- a/Shared/Views/MainView.swift
+++ b/Shared/Views/MainView.swift
@@ -16,21 +16,21 @@ struct MainView: View {
             ContactsTab()
                 .tabItem {
                     Image(systemName: "person.2.fill")
-                    Text("Контакты")
+                    Text(NSLocalizedString("MainView_contacts", comment: ""))
                 }
                 .tag(0)
             
             ChatsTab()
                 .tabItem {
                     Image(systemName: "bubble.left.and.bubble.right.fill")
-                    Text("Чаты")
+                    Text(NSLocalizedString("MainView_chats", comment: ""))
                 }
                 .tag(1)
             
-            SettingsTab()
+            SettingsTab(viewModel: viewModel)
                 .tabItem {
                     Image(systemName: "gearshape.fill")
-                    Text("Настройки")
+                    Text(NSLocalizedString("MainView_settings", comment: ""))
                 }
                 .tag(2)
         }
diff --git a/Shared/Views/RegistrationView.swift b/Shared/Views/RegistrationView.swift
index ba60051..fe1aa7e 100644
--- a/Shared/Views/RegistrationView.swift
+++ b/Shared/Views/RegistrationView.swift
@@ -8,15 +8,19 @@
 import SwiftUI
 
 struct RegistrationView: View {
+    @ObservedObject var viewModel: LoginViewModel
     @Environment(\.presentationMode) private var presentationMode
-    
-    @State private var fullName: String = ""
+
     @State private var username: String = ""
     @State private var password: String = ""
     @State private var confirmPassword: String = ""
     @State private var inviteCode: String = ""
     @AppStorage("isDarkMode") private var isDarkMode: Bool = true
 
+    @State private var isLoading: Bool = false
+    @State private var showError: Bool = false
+    @State private var errorMessage: String = ""
+
     private var isUsernameValid: Bool {
         let pattern = "^[A-Za-z0-9_]{3,32}$"
         return username.range(of: pattern, options: .regularExpression) != nil
@@ -31,104 +35,179 @@ struct RegistrationView: View {
     }
 
     private var isFormValid: Bool {
-        !fullName.isEmpty && isUsernameValid && isPasswordValid && isConfirmPasswordValid
+        isUsernameValid && isPasswordValid && isConfirmPasswordValid
     }
 
     var body: some View {
         NavigationView {
-            VStack {
 
-                Text(NSLocalizedString("RegistrationView_title", comment: "Регистрация"))
-                    .font(.largeTitle)
-                    .bold()
+            ScrollView {
+                ZStack {
+                    Color.clear
+                        .contentShape(Rectangle())
+                        .onTapGesture {
+                            hideKeyboard()
+                        }
 
-//                Spacer()
+                VStack(alignment: .leading, spacing: 16) {
 
-                // Полное имя
-                TextField(NSLocalizedString("RegistrationView_fullname", comment: "Полное имя"), text: $fullName)
-                    .padding()
-                    .background(Color(.secondarySystemBackground))
-                    .cornerRadius(8)
-                    .autocapitalization(.words)
-                    .disableAutocorrection(true)
+                    Group {
 
-                // Логин
-                TextField(NSLocalizedString("RegistrationView_login", comment: "Логин"), text: $username)
-                    .padding()
-                    .background(Color(.secondarySystemBackground))
-                    .cornerRadius(8)
-                    .autocapitalization(.none)
-                    .disableAutocorrection(true)
-
-                if !isUsernameValid && !username.isEmpty {
-                    Text(NSLocalizedString("RegistrationView_error_username_invalid", comment: "Неверный логин"))
-                        .foregroundColor(.red)
-                        .font(.caption)
-                }
-
-                // Пароль
-                SecureField(NSLocalizedString("RegistrationView_password", comment: "Пароль"), text: $password)
-                    .padding()
-                    .background(Color(.secondarySystemBackground))
-                    .cornerRadius(8)
-                    .autocapitalization(.none)
-
-                if !isPasswordValid && !password.isEmpty {
-                    Text(NSLocalizedString("RegistrationView_error_password_invalid", comment: "Пароль должен быть от 6 до 32 символов"))
-                        .foregroundColor(.red)
-                        .font(.caption)
-                }
-
-                // Подтверждение пароля
-                SecureField(NSLocalizedString("RegistrationView_confirm_password", comment: "Подтверждение пароля"), text: $confirmPassword)
-                    .padding()
-                    .background(Color(.secondarySystemBackground))
-                    .cornerRadius(8)
-                    .autocapitalization(.none)
-
-                if !isConfirmPasswordValid && !confirmPassword.isEmpty {
-                    Text(NSLocalizedString("RegistrationView_error_confirm_password_invalid", comment: "Пароли не совпадают"))
-                        .foregroundColor(.red)
-                        .font(.caption)
-                }
-
-                // Инвайт-код
-                TextField(NSLocalizedString("RegistrationView_invite", comment: "Инвайт-код"), text: $inviteCode)
-                    .padding()
-                    .background(Color(.secondarySystemBackground))
-                    .cornerRadius(8)
-                    .autocapitalization(.none)
-                    .disableAutocorrection(true)
-
-                // Кнопка регистрации
-                Button(action: {
-                    print("Регистрация отправлена")
-                }) {
-                    Text(NSLocalizedString("RegistrationView_button_register", comment: "Зарегистрироваться"))
-                        .foregroundColor(.white)
+                        HStack {
+                            TextField(NSLocalizedString("RegistrationView_login", comment: "Логин"), text: $username)
+                                .autocapitalization(.none)
+                                .disableAutocorrection(true)
+                            Spacer()
+                            if !username.isEmpty {
+                                Image(systemName: isUsernameValid ? "checkmark.circle" : "xmark.circle")
+                                    .foregroundColor(isUsernameValid ? .green : .red)
+                            }
+                        }
                         .padding()
-                        .frame(maxWidth: .infinity)
-                        .background(isFormValid ? Color.blue : Color.gray.opacity(0.6))
+                        .background(Color(.secondarySystemBackground))
                         .cornerRadius(8)
-                }
-                .disabled(!isFormValid)
+                        .autocapitalization(.none)
+                        .disableAutocorrection(true)
+                        .onChange(of: username) { newValue in
+                            if newValue.count > 32 {
+                                username = String(newValue.prefix(32))
+                            }
+                        }
 
-            }
-            .padding()
-            .navigationBarItems(trailing:
-                Button(action: {
-                    presentationMode.wrappedValue.dismiss()
-                }) {
-                    Text(NSLocalizedString("RegistrationView_close", comment: "Закрыть"))
+                        if !isUsernameValid && !username.isEmpty {
+                            Text(NSLocalizedString("RegistrationView_error_username_invalid", comment: "Неверный логин"))
+                                .foregroundColor(.red)
+                                .font(.caption)
+                        }
+
+                        HStack {
+                            SecureField(NSLocalizedString("RegistrationView_password", comment: "Пароль"), text: $password)
+                                .autocapitalization(.none)
+                            Spacer()
+                            if !password.isEmpty {
+                                Image(systemName: isPasswordValid ? "checkmark.circle" : "xmark.circle")
+                                    .foregroundColor(isPasswordValid ? .green : .red)
+                            }
+                        }
+                        .padding()
+                        .background(Color(.secondarySystemBackground))
+                        .cornerRadius(8)
+                        .autocapitalization(.none)
+                        .onChange(of: password) { newValue in
+                            if newValue.count > 32 {
+                                password = String(newValue.prefix(32))
+                            }
+                        }
+
+                        if !isPasswordValid && !password.isEmpty {
+                            Text(NSLocalizedString("RegistrationView_error_password_invalid", comment: "Пароль должен быть от 6 до 32 символов"))
+                                .foregroundColor(.red)
+                                .font(.caption)
+                        }
+
+                        HStack {
+                            SecureField(NSLocalizedString("RegistrationView_confirm_password", comment: "Подтверждение пароля"), text: $confirmPassword)
+                                .autocapitalization(.none)
+                            Spacer()
+                            if !confirmPassword.isEmpty {
+                                Image(systemName: isConfirmPasswordValid ? "checkmark.circle" : "xmark.circle")
+                                    .foregroundColor(isConfirmPasswordValid ? .green : .red)
+                            }
+                        }
+                        .padding()
+                        .background(Color(.secondarySystemBackground))
+                        .cornerRadius(8)
+                        .autocapitalization(.none)
+                        .onChange(of: confirmPassword) { newValue in
+                            if newValue.count > 32 {
+                                confirmPassword = String(newValue.prefix(32))
+                            }
+                        }
+
+                        if !isConfirmPasswordValid && !confirmPassword.isEmpty {
+                            Text(NSLocalizedString("RegistrationView_error_confirm_password_invalid", comment: "Пароли не совпадают"))
+                                .foregroundColor(.red)
+                                .font(.caption)
+                        }
+
+                        TextField(NSLocalizedString("RegistrationView_invite", comment: "Инвайт-код"), text: $inviteCode)
+                            .padding()
+                            .background(Color(.secondarySystemBackground))
+                            .cornerRadius(8)
+                            .autocapitalization(.none)
+                            .disableAutocorrection(true)
+                    }
+
+                    Button(action: registerUser) {
+                        if isLoading {
+                            ProgressView()
+                                .padding()
+                                .frame(maxWidth: .infinity)
+                                .background(Color.gray.opacity(0.6))
+                                .cornerRadius(8)
+                        } else {
+                            Text(NSLocalizedString("RegistrationView_button_register", comment: "Зарегистрироваться"))
+                                .foregroundColor(.white)
+                                .padding()
+                                .frame(maxWidth: .infinity)
+                                .background(isFormValid ? Color.blue : Color.gray.opacity(0.6))
+                                .cornerRadius(8)
+                        }
+                    }
+                    .disabled(!isFormValid)
+                    .padding(.bottom)
                 }
-            )
+                .padding()
+                }
+                .navigationBarItems(trailing:
+                        Button(action: {
+                            presentationMode.wrappedValue.dismiss()
+                        }) {
+                            Text(NSLocalizedString("RegistrationView_close", comment: "Закрыть"))
+                        }
+                    )
+                .navigationTitle(Text(NSLocalizedString("RegistrationView_title", comment: "Регистрация")))
+                .alert(isPresented: $showError) {
+                    Alert(
+                        title: Text(NSLocalizedString("RegistrationView_error", comment: "Ошибка")),
+                        message: Text(errorMessage),
+                        dismissButton: .default(Text(NSLocalizedString("ok", comment: "")))
+                    )
+                }
+            }
+            .onTapGesture {
+            hideKeyboard()
+        }
+        }
+        .onTapGesture {
+        hideKeyboard()
+    }
+        }
+
+    private func registerUser() {
+        isLoading = true
+        errorMessage = ""
+        viewModel.registerUser(username: username, password: password, invite: inviteCode.isEmpty ? nil : inviteCode) { success, message in
+            isLoading = false
+            if success {
+                presentationMode.wrappedValue.dismiss()
+            } else {
+                errorMessage = message ?? "Неизвестная ошибка."
+                showError = true
+            }
         }
     }
 
+    private func hideKeyboard() {
+        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
+    }
 }
 
+
 struct RegistrationView_Previews: PreviewProvider {
     static var previews: some View {
-        RegistrationView()
+        let viewModel = LoginViewModel()
+        viewModel.isLoading = false // чтобы убрать спиннер
+        return RegistrationView(viewModel: viewModel)
     }
 }
diff --git a/Shared/Views/SettingsTab.swift b/Shared/Views/SettingsTab.swift
index e014cc8..777e34f 100644
--- a/Shared/Views/SettingsTab.swift
+++ b/Shared/Views/SettingsTab.swift
@@ -8,6 +8,8 @@
 import SwiftUI
 
 struct SettingsTab: View {
+    @ObservedObject var viewModel: LoginViewModel
+
     var body: some View {
         NavigationView {
             VStack {
@@ -17,6 +19,15 @@ struct SettingsTab: View {
                     .padding()
                 
                 Spacer()
+                
+                Button(action: {
+                    viewModel.logoutCurrentUser()
+                }) {
+                    Text("Выйти из текущего пользователя")
+                        .foregroundColor(.red)
+                }
+                .padding()
+                
             }
             .navigationTitle("Настройки")
         }
diff --git a/Shared/config.swift b/Shared/config.swift
index a098dfb..f0c30c8 100644
--- a/Shared/config.swift
+++ b/Shared/config.swift
@@ -1,9 +1,12 @@
 import SwiftUI
 
 struct AppConfig {
-    static var DEBUG: Bool = false
+    static var DEBUG: Bool = true
     static let SERVICE = Bundle.main.bundleIdentifier ?? "default.service"
     static let PROTOCOL = "https"
     static let API_SERVER = "\(PROTOCOL)://api.volnahub.ru"
     static let SERVER_TIMEZONE = "GMT+3"
+    static let USER_AGENT = "volnahub ios"
+    static let APP_BUILD = "freestore"
+    static let APP_VERSION = "0.1"
 }
diff --git a/Shared/volnahubApp.swift b/Shared/volnahubApp.swift
index 5218d59..fa5ad06 100644
--- a/Shared/volnahubApp.swift
+++ b/Shared/volnahubApp.swift
@@ -15,7 +15,7 @@ import SwiftUI
 struct volnahubApp: App {
     @AppStorage("isDarkMode") private var isDarkMode: Bool = true
     @StateObject private var viewModel = LoginViewModel()
-
+    
     var body: some Scene {
         WindowGroup {
             ZStack {
diff --git a/iOS/Info.plist b/iOS/Info.plist
index 8cec9d0..bb81a82 100644
--- a/iOS/Info.plist
+++ b/iOS/Info.plist
@@ -15,7 +15,7 @@
 	CFBundlePackageType
 	$(PRODUCT_BUNDLE_PACKAGE_TYPE)
 	CFBundleShortVersionString
-	1.0
+	$(MARKETING_VERSION)
 	CFBundleVersion
 	$(CURRENT_PROJECT_VERSION)
 	LSRequiresIPhoneOS
diff --git a/volnahub.xcodeproj/project.pbxproj b/volnahub.xcodeproj/project.pbxproj
index 5eefaad..817ffd8 100644
--- a/volnahub.xcodeproj/project.pbxproj
+++ b/volnahub.xcodeproj/project.pbxproj
@@ -7,6 +7,8 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		1A0276032DF909F900D8BC53 /* refreshtokenex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0276022DF909F900D8BC53 /* refreshtokenex.swift */; };
+		1A0276112DF9247000D8BC53 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A0276102DF9247000D8BC53 /* CustomTextField.swift */; };
 		1A79408D2DF77BC3002569DA /* volnahubApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A79407A2DF77BC2002569DA /* volnahubApp.swift */; };
 		1A79408F2DF77BC3002569DA /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A79407B2DF77BC2002569DA /* ContentView.swift */; };
 		1A7940902DF77BC3002569DA /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A79407B2DF77BC2002569DA /* ContentView.swift */; };
@@ -28,6 +30,8 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		1A0276022DF909F900D8BC53 /* refreshtokenex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = refreshtokenex.swift; sourceTree = ""; };
+		1A0276102DF9247000D8BC53 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = ""; };
 		1A79407A2DF77BC2002569DA /* volnahubApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = volnahubApp.swift; sourceTree = ""; };
 		1A79407B2DF77BC2002569DA /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
 		1A79407C2DF77BC3002569DA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
@@ -133,6 +137,7 @@
 				1A7940CD2DF7A9AA002569DA /* SettingsTab.swift */,
 				1A7940E62DF7B5E5002569DA /* SplashScreenView.swift */,
 				1A79410B2DF7C81D002569DA /* RegistrationView.swift */,
+				1A0276102DF9247000D8BC53 /* CustomTextField.swift */,
 			);
 			path = Views;
 			sourceTree = "";
@@ -157,6 +162,7 @@
 			isa = PBXGroup;
 			children = (
 				1A7940A12DF77DE9002569DA /* AuthService.swift */,
+				1A0276022DF909F900D8BC53 /* refreshtokenex.swift */,
 			);
 			path = Network;
 			sourceTree = "";
@@ -280,8 +286,10 @@
 				1A7940E72DF7B5E5002569DA /* SplashScreenView.swift in Sources */,
 				1A7940B02DF77E26002569DA /* LoginView.swift in Sources */,
 				1A79410C2DF7C81D002569DA /* RegistrationView.swift in Sources */,
+				1A0276112DF9247000D8BC53 /* CustomTextField.swift in Sources */,
 				1A7940CE2DF7A9AA002569DA /* SettingsTab.swift in Sources */,
 				1A7940DE2DF7B0D7002569DA /* config.swift in Sources */,
+				1A0276032DF909F900D8BC53 /* refreshtokenex.swift in Sources */,
 				1A7940B62DF77F21002569DA /* MainView.swift in Sources */,
 				1A7940E22DF7B1C5002569DA /* KeychainService.swift in Sources */,
 				1A7940A62DF77DF5002569DA /* User.swift in Sources */,
@@ -434,8 +442,10 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1337;
+				DEVELOPMENT_TEAM = V22H44W47J;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = iOS/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
@@ -443,8 +453,10 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				PRODUCT_BUNDLE_IDENTIFIER = ckp.volnahub;
+				MARKETING_VERSION = 0.1;
+				PRODUCT_BUNDLE_IDENTIFIER = ckp2.volnahub;
 				PRODUCT_NAME = volnahub;
+				PROVISIONING_PROFILE_SPECIFIER = "";
 				SDKROOT = iphoneos;
 				SWIFT_VERSION = 5.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
@@ -456,8 +468,10 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1337;
+				DEVELOPMENT_TEAM = V22H44W47J;
 				ENABLE_PREVIEWS = YES;
 				INFOPLIST_FILE = iOS/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
@@ -465,8 +479,10 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				PRODUCT_BUNDLE_IDENTIFIER = ckp.volnahub;
+				MARKETING_VERSION = 0.1;
+				PRODUCT_BUNDLE_IDENTIFIER = ckp2.volnahub;
 				PRODUCT_NAME = volnahub;
+				PROVISIONING_PROFILE_SPECIFIER = "";
 				SDKROOT = iphoneos;
 				SWIFT_VERSION = 5.0;
 				TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/volnahub.xcodeproj/xcuserdata/cheykrym.xcuserdatad/xcschemes/xcschememanagement.plist b/volnahub.xcodeproj/xcuserdata/cheykrym.xcuserdatad/xcschemes/xcschememanagement.plist
index 6cdd854..32667f1 100644
--- a/volnahub.xcodeproj/xcuserdata/cheykrym.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/volnahub.xcodeproj/xcuserdata/cheykrym.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -7,12 +7,12 @@
 		volnahub (iOS).xcscheme_^#shared#^_
 		
 			orderHint
-			1
+			0
 		
 		volnahub (macOS).xcscheme_^#shared#^_
 		
 			orderHint
-			0
+			1