diff --git a/TraccarClient.xcodeproj/project.pbxproj b/TraccarClient.xcodeproj/project.pbxproj
index e92893d0a4ea2bfb666bd1f56a2a962b10997463..157c2ef546b59b85fca786fbcb3380ea288b9893 100644
--- a/TraccarClient.xcodeproj/project.pbxproj
+++ b/TraccarClient.xcodeproj/project.pbxproj
@@ -31,6 +31,9 @@
 		53157EDC2AEE5841003C9B6A /* UIWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53157EDB2AEE5841003C9B6A /* UIWindow.swift */; };
 		53200CE82B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53200CE62B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.swift */; };
 		53200CE92B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53200CE72B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.xib */; };
+		53200CF22B60FB5800D1445D /* LeaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53200CF02B60FB5800D1445D /* LeaderViewController.swift */; };
+		53200CF32B60FB5800D1445D /* LeaderViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53200CF12B60FB5800D1445D /* LeaderViewController.xib */; };
+		53200CF52B60FBE400D1445D /* SecurityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53200CF42B60FBE400D1445D /* SecurityManager.swift */; };
 		5326833C2AE9175900A364C0 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5326833A2AE9175900A364C0 /* LoginViewController.swift */; };
 		5326833D2AE9175900A364C0 /* LoginViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5326833B2AE9175900A364C0 /* LoginViewController.xib */; };
 		532683512AE91A6F00A364C0 /* Montserrat-ExtraLightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 5326833F2AE91A6E00A364C0 /* Montserrat-ExtraLightItalic.ttf */; };
@@ -105,9 +108,11 @@
 		53554AE52AED1BF10018BAEE /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53554AE42AED1BF10018BAEE /* UIButton.swift */; };
 		5370B4702AEFB8A900AE08CC /* splash.json in Resources */ = {isa = PBXBuildFile; fileRef = 5370B46F2AEFB8A900AE08CC /* splash.json */; };
 		5392C4232B037942004EF18A /* ShiftsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5392C4222B037942004EF18A /* ShiftsModel.swift */; };
-		5392C4252B04A760004EF18A /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5392C4242B04A760004EF18A /* GoogleService-Info.plist */; };
 		53A306212B0CA92900FAEA00 /* TrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A306202B0CA92900FAEA00 /* TrackingView.swift */; };
 		53A306232B0CAF7800FAEA00 /* TrackingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53A306222B0CAF7800FAEA00 /* TrackingView.xib */; };
+		53B6DB792B6113E6000C1083 /* FirebaseRemoteConfig in Frameworks */ = {isa = PBXBuildFile; productRef = 53B6DB782B6113E6000C1083 /* FirebaseRemoteConfig */; };
+		53B6DB7B2B6113E6000C1083 /* FirebaseRemoteConfigSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 53B6DB7A2B6113E6000C1083 /* FirebaseRemoteConfigSwift */; };
+		53B6DB7D2B611C12000C1083 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 53B6DB7C2B611C12000C1083 /* GoogleService-Info.plist */; };
 		53D62E3F2AEFA31200C80BAC /* InitialViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D62E3D2AEFA31200C80BAC /* InitialViewController.swift */; };
 		53D62E402AEFA31200C80BAC /* InitialViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53D62E3E2AEFA31200C80BAC /* InitialViewController.xib */; };
 		53D62E432AEFA4DC00C80BAC /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 53D62E422AEFA4DC00C80BAC /* Lottie */; };
@@ -212,6 +217,10 @@
 		53157EDB2AEE5841003C9B6A /* UIWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIWindow.swift; sourceTree = "<group>"; };
 		53200CE62B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsPrivacyPolicyTableViewCell.swift; sourceTree = "<group>"; };
 		53200CE72B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SettingsPrivacyPolicyTableViewCell.xib; sourceTree = "<group>"; };
+		53200CEA2B60F8FF00D1445D /* TraccarClient.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TraccarClient.entitlements; sourceTree = "<group>"; };
+		53200CF02B60FB5800D1445D /* LeaderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeaderViewController.swift; sourceTree = "<group>"; };
+		53200CF12B60FB5800D1445D /* LeaderViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LeaderViewController.xib; sourceTree = "<group>"; };
+		53200CF42B60FBE400D1445D /* SecurityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityManager.swift; sourceTree = "<group>"; };
 		5326833A2AE9175900A364C0 /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = "<group>"; };
 		5326833B2AE9175900A364C0 /* LoginViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LoginViewController.xib; sourceTree = "<group>"; };
 		5326833F2AE91A6E00A364C0 /* Montserrat-ExtraLightItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Montserrat-ExtraLightItalic.ttf"; sourceTree = "<group>"; };
@@ -283,9 +292,9 @@
 		53554AE42AED1BF10018BAEE /* UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = "<group>"; };
 		5370B46F2AEFB8A900AE08CC /* splash.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = splash.json; sourceTree = "<group>"; };
 		5392C4222B037942004EF18A /* ShiftsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShiftsModel.swift; sourceTree = "<group>"; };
-		5392C4242B04A760004EF18A /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
 		53A306202B0CA92900FAEA00 /* TrackingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackingView.swift; sourceTree = "<group>"; };
 		53A306222B0CAF7800FAEA00 /* TrackingView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TrackingView.xib; sourceTree = "<group>"; };
+		53B6DB7C2B611C12000C1083 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
 		53D62E3D2AEFA31200C80BAC /* InitialViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialViewController.swift; sourceTree = "<group>"; };
 		53D62E3E2AEFA31200C80BAC /* InitialViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InitialViewController.xib; sourceTree = "<group>"; };
 		53EBC5FC2AF199FF00601AA7 /* SettingsTextTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTextTableViewCell.swift; sourceTree = "<group>"; };
@@ -386,6 +395,8 @@
 				CEDB048717ED50C1000E7EDF /* CoreLocation.framework in Frameworks */,
 				CED4879917DB1DF4007FCF57 /* MessageUI.framework in Frameworks */,
 				532683812AE923DE00A364C0 /* Alamofire in Frameworks */,
+				53B6DB7B2B6113E6000C1083 /* FirebaseRemoteConfigSwift in Frameworks */,
+				53B6DB792B6113E6000C1083 /* FirebaseRemoteConfig in Frameworks */,
 				CED4871C17DB1BF6007FCF57 /* UIKit.framework in Frameworks */,
 				532683C82AEA631800A364C0 /* IQKeyboardManagerSwift in Frameworks */,
 				5EE3CA39299894B9002C86E4 /* InAppSettingsKit in Frameworks */,
@@ -483,6 +494,16 @@
 			path = SettingsPrivacyPolicyTableViewCell;
 			sourceTree = "<group>";
 		};
+		53200CEB2B60F94300D1445D /* Leader */ = {
+			isa = PBXGroup;
+			children = (
+				53200CF02B60FB5800D1445D /* LeaderViewController.swift */,
+				53200CF12B60FB5800D1445D /* LeaderViewController.xib */,
+				53200CF42B60FBE400D1445D /* SecurityManager.swift */,
+			);
+			name = Leader;
+			sourceTree = "<group>";
+		};
 		532683392AE9174700A364C0 /* Views */ = {
 			isa = PBXGroup;
 			children = (
@@ -837,6 +858,8 @@
 		CED4872117DB1BF6007FCF57 /* TraccarClient */ = {
 			isa = PBXGroup;
 			children = (
+				53200CEB2B60F94300D1445D /* Leader */,
+				53200CEA2B60F8FF00D1445D /* TraccarClient.entitlements */,
 				CB7ED0831F662BAF00A33FCF /* AppDelegate.swift */,
 				532683C42AEA5DB000A364C0 /* Controllers */,
 				532683632AE91CAC00A364C0 /* helpers */,
@@ -862,7 +885,7 @@
 		CED4872217DB1BF6007FCF57 /* Supporting Files */ = {
 			isa = PBXGroup;
 			children = (
-				5392C4242B04A760004EF18A /* GoogleService-Info.plist */,
+				53B6DB7C2B611C12000C1083 /* GoogleService-Info.plist */,
 				5326833E2AE91A6200A364C0 /* Fonts */,
 				CED4872317DB1BF6007FCF57 /* TraccarClient-Info.plist */,
 				5370B46F2AEFB8A900AE08CC /* splash.json */,
@@ -919,6 +942,8 @@
 				53D62E422AEFA4DC00C80BAC /* Lottie */,
 				5300F2C12AF3BC4E003F2C5F /* FirebaseAnalytics */,
 				5300F2C32AF3BC4E003F2C5F /* FirebaseMessaging */,
+				53B6DB782B6113E6000C1083 /* FirebaseRemoteConfig */,
+				53B6DB7A2B6113E6000C1083 /* FirebaseRemoteConfigSwift */,
 			);
 			productName = TraccarClient;
 			productReference = CED4871817DB1BF6007FCF57 /* TraccarClient.app */;
@@ -1024,6 +1049,7 @@
 				532683522AE91A6F00A364C0 /* Montserrat-Light.ttf in Resources */,
 				53EBC60C2AF1A5C200601AA7 /* SettingsSegmentTableViewCell.xib in Resources */,
 				CEF643271B919FFA00195CEA /* LaunchScreen.xib in Resources */,
+				53B6DB7D2B611C12000C1083 /* GoogleService-Info.plist in Resources */,
 				53EBC6072AF1A43900601AA7 /* SettingsSwitchTableViewCell.xib in Resources */,
 				532683592AE91A6F00A364C0 /* Montserrat-SemiBold.ttf in Resources */,
 				CED4879B17DB1E61007FCF57 /* InAppSettings.bundle in Resources */,
@@ -1048,7 +1074,7 @@
 				53200CE92B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.xib in Resources */,
 				532683512AE91A6F00A364C0 /* Montserrat-ExtraLightItalic.ttf in Resources */,
 				530080392AF15CE000A05E04 /* TransactionsViewController.xib in Resources */,
-				5392C4252B04A760004EF18A /* GoogleService-Info.plist in Resources */,
+				53200CF32B60FB5800D1445D /* LeaderViewController.xib in Resources */,
 				53A306232B0CAF7800FAEA00 /* TrackingView.xib in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1120,6 +1146,7 @@
 				CB4197991F67724F008F301C /* NetworkManager.swift in Sources */,
 				532683B32AE98D0000A364C0 /* UILabel.swift in Sources */,
 				5326838D2AE92D9900A364C0 /* CGFLoat.swift in Sources */,
+				53200CF52B60FBE400D1445D /* SecurityManager.swift in Sources */,
 				CB7ED0841F662BAF00A33FCF /* AppDelegate.swift in Sources */,
 				53F10AE82AF05EB5004D0529 /* Coordinatable.swift in Sources */,
 				53D62E3F2AEFA31200C80BAC /* InitialViewController.swift in Sources */,
@@ -1128,6 +1155,7 @@
 				5E394EBE28A9CC7600396F33 /* BatteryStatus.swift in Sources */,
 				53157ED32AEE56FE003C9B6A /* Globals.swift in Sources */,
 				53F10AF02AF06906004D0529 /* UIImageView.swift in Sources */,
+				53200CF22B60FB5800D1445D /* LeaderViewController.swift in Sources */,
 				53200CE82B59461800D1445D /* SettingsPrivacyPolicyTableViewCell.swift in Sources */,
 				532683872AE9295500A364C0 /* Nameable.swift in Sources */,
 				5326837E2AE923A500A364C0 /* KNFieldDropdownObjectProtocol.swift in Sources */,
@@ -1301,6 +1329,7 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
@@ -1477,6 +1506,7 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CURRENT_PROJECT_VERSION = 9;
@@ -1513,6 +1543,7 @@
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
@@ -1735,6 +1766,16 @@
 			package = 532683C62AEA631800A364C0 /* XCRemoteSwiftPackageReference "IQKeyboardManager" */;
 			productName = IQKeyboardManagerSwift;
 		};
+		53B6DB782B6113E6000C1083 /* FirebaseRemoteConfig */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = 5300F2C02AF3BC4E003F2C5F /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
+			productName = FirebaseRemoteConfig;
+		};
+		53B6DB7A2B6113E6000C1083 /* FirebaseRemoteConfigSwift */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = 5300F2C02AF3BC4E003F2C5F /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
+			productName = FirebaseRemoteConfigSwift;
+		};
 		53D62E422AEFA4DC00C80BAC /* Lottie */ = {
 			isa = XCSwiftPackageProductDependency;
 			package = 53D62E412AEFA4DC00C80BAC /* XCRemoteSwiftPackageReference "lottie-ios" */;
diff --git a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate
index 8cfa6510cfbcd4a47da9ed08747c9b0ab73be433..ca2ee36d332c6991f58bfd543fe228feb8d49282 100644
Binary files a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate and b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/TraccarClient/AppDelegate.swift b/TraccarClient/AppDelegate.swift
index faff30640639480a9538a915f879801829b3d5af..ba0b093f5041b905767b5f4ce2f5fa29abf66be7 100644
--- a/TraccarClient/AppDelegate.swift
+++ b/TraccarClient/AppDelegate.swift
@@ -19,6 +19,8 @@ import CoreData
 import FirebaseMessaging
 import FirebaseCore
 import IQKeyboardManagerSwift
+import Firebase
+import FirebaseRemoteConfig
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate {
@@ -38,18 +40,40 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate
     }
     
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
+//#if FIREBASE
+        
         FirebaseApp.configure()
+        Messaging.messaging().delegate = self
+        
+        if #available(iOS 10.0, *) {
+            UNUserNotificationCenter.current().delegate = self
+            
+            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
+            UNUserNotificationCenter.current().requestAuthorization(
+                options: authOptions,
+                completionHandler: {_, _ in })
+        } else {
+            let settings: UIUserNotificationSettings =
+            UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
+            application.registerUserNotificationSettings(settings)
+        }
+        
+        application.registerForRemoteNotifications()
+        
+//#endif
         
         UNUserNotificationCenter.current().delegate = self
-
+        
         let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
         UNUserNotificationCenter.current().requestAuthorization(
-          options: authOptions,
-          completionHandler: { _, _ in }
+            options: authOptions,
+            completionHandler: { _, _ in }
         )
-
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(onReceive(_:)), name: LeaderViewController.eventLogin, object: nil)
+        
         application.registerForRemoteNotifications()
-
+        
         IQKeyboardManager.shared.enable = true
         IQKeyboardManager.shared.shouldResignOnTouchOutside = true
         IQKeyboardManager.shared.previousNextDisplayMode = .alwaysShow
@@ -65,8 +89,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate
         
         registerDefaultsFromSettingsBundle()
         
-        Messaging.messaging().delegate = self
-
         migrateLegacyDefaults()
         
         let modelUrl = Bundle.main.url(forResource: "TraccarClient", withExtension: "momd")
@@ -85,6 +107,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate
         return true
     }
     
+    @objc func onReceive(_ notification:Notification) {
+        
+        Messaging.messaging().token { (token, _) in
+            if let token = token {
+                NotificationCenter.default.post(
+                    name: LeaderViewController.eventToken, object: nil, userInfo: [LeaderViewController.keyToken: token])
+            }
+        }
+    }
+    
     func login() {
         window = UIWindow(frame: UIScreen.main.bounds)
         
@@ -168,7 +200,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate
         trackingController = nil
         let userDefaults = UserDefaults.standard
         userDefaults.set(false, forKey: "service_status_preference")
-
+        
         if let context = managedObjectContext {
             if context.hasChanges {
                 try! context.save()
@@ -215,69 +247,77 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate
 }
 // MARK: - UNUserNotificationCenterDelegate
 extension AppDelegate: UNUserNotificationCenterDelegate {
-  // Receive displayed notifications for iOS 10 devices.
-  func userNotificationCenter(_ center: UNUserNotificationCenter,
-                              willPresent notification: UNNotification) async
+    // Receive displayed notifications for iOS 10 devices.
+    func userNotificationCenter(_ center: UNUserNotificationCenter,
+                                willPresent notification: UNNotification) async
     -> UNNotificationPresentationOptions {
-    let userInfo = notification.request.content.userInfo
-
-    // With swizzling disabled you must let Messaging know about the message, for Analytics
-    // Messaging.messaging().appDidReceiveMessage(userInfo)
-
-    // ...
-
-    // Print full message.
-    print(userInfo)
-
-    // Change this to your preferred presentation option
-    return [[.alert, .sound]]
-  }
-
-  func userNotificationCenter(_ center: UNUserNotificationCenter,
-                              didReceive response: UNNotificationResponse) async {
-    let userInfo = response.notification.request.content.userInfo
-
-    // ...
-
-    // With swizzling disabled you must let Messaging know about the message, for Analytics
-    // Messaging.messaging().appDidReceiveMessage(userInfo)
-
-    // Print full message.
-    print(userInfo)
-  }
+        let userInfo = notification.request.content.userInfo
+        
+        // With swizzling disabled you must let Messaging know about the message, for Analytics
+        // Messaging.messaging().appDidReceiveMessage(userInfo)
+        
+        // ...
+        
+        // Print full message.
+        print(userInfo)
+        
+        // Change this to your preferred presentation option
+        return [[.alert, .sound]]
+    }
+    
+    func userNotificationCenter(_ center: UNUserNotificationCenter,
+                                didReceive response: UNNotificationResponse) async {
+        let userInfo = response.notification.request.content.userInfo
+        if let eventId = response.notification.request.content.userInfo["eventId"] {
+            NotificationCenter.default.post(
+                name: LeaderViewController.eventEvent, object: nil, userInfo: [LeaderViewController.keyEventId: eventId])
+        }
+        // ...
+        
+        // With swizzling disabled you must let Messaging know about the message, for Analytics
+        // Messaging.messaging().appDidReceiveMessage(userInfo)
+        
+        // Print full message.
+        print(userInfo)
+    }
     func application(_ application: UIApplication,
                      didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
-      -> UIBackgroundFetchResult {
-      // If you are receiving a notification message while your app is in the background,
-      // this callback will not be fired till the user taps on the notification launching the application.
-      // TODO: Handle data of notification
-
-      // With swizzling disabled you must let Messaging know about the message, for Analytics
-      // Messaging.messaging().appDidReceiveMessage(userInfo)
-
-      // Print message ID.
-      if let messageID = userInfo[gcmMessageIDKey] {
-        print("Message ID: \(messageID)")
-      }
-
-      // Print full message.
-      print(userInfo)
-
-      return UIBackgroundFetchResult.newData
+    -> UIBackgroundFetchResult {
+        // If you are receiving a notification message while your app is in the background,
+        // this callback will not be fired till the user taps on the notification launching the application.
+        // TODO: Handle data of notification
+        
+        // With swizzling disabled you must let Messaging know about the message, for Analytics
+        // Messaging.messaging().appDidReceiveMessage(userInfo)
+        
+        // Print message ID.
+        if let messageID = userInfo[gcmMessageIDKey] {
+            print("Message ID: \(messageID)")
+        }
+        
+        // Print full message.
+        print(userInfo)
+        
+        return UIBackgroundFetchResult.newData
     }
-
+    
 }
 
 // MARK: - MessagingDelegate
 extension AppDelegate: MessagingDelegate {
     func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
-      print("Firebase registration token: \(String(describing: fcmToken))")
-
-      let dataDict: [String: String] = ["token": fcmToken ?? ""]
-      NotificationCenter.default.post(
-        name: Notification.Name("FCMToken"),
-        object: nil,
-        userInfo: dataDict
-      )
+        print("Firebase registration token: \(String(describing: fcmToken))")
+        
+        if let fcmToken = fcmToken {
+            NotificationCenter.default.post(
+                name: LeaderViewController.eventToken, object: nil, userInfo: [LeaderViewController.keyToken: fcmToken])
+        }
+        
+        let dataDict: [String: String] = ["token": fcmToken ?? ""]
+        NotificationCenter.default.post(
+            name: Notification.Name("FCMToken"),
+            object: nil,
+            userInfo: dataDict
+        )
     }
 }
diff --git a/TraccarClient/AppManager.swift b/TraccarClient/AppManager.swift
index c6b751cecf53048e4d88654cd0266c84a0f299e3..ecb4bead906c4349d62856ce4c5fa00515f0747d 100644
--- a/TraccarClient/AppManager.swift
+++ b/TraccarClient/AppManager.swift
@@ -39,7 +39,7 @@ final class AppManager {
     ]
     
     // MARK: - Data
-    var environment: KNEnvironment = .sandbox
+    var environment: KNEnvironment = .production
     var delegate: AppDelegate!
     var isUpdatingProfile: Bool = false
     var isLoggedIn: Bool {
diff --git a/TraccarClient/Globals.swift b/TraccarClient/Globals.swift
index 7e39a69802888fd5f1159337905d985947eebb26..bc7292cf32839d7350c9d617948231baaabce42e 100644
--- a/TraccarClient/Globals.swift
+++ b/TraccarClient/Globals.swift
@@ -33,6 +33,17 @@ var fleetUrl: String {
     }
 }
 
+var leaderServerURL: String {
+    switch app.environment {
+    case .development, .sandbox:
+        return "https://dev-fleet-app.nmo.ai/"
+    case .production:
+        return "https://fleet-app.nmo.ai/"
+    }
+}
+
+var showLeaderButton: Bool = false
+
 // MARK: - Global Custom AlertView
 typealias AlertViewClosure = () -> ()
 
diff --git a/TraccarClient/GoogleService-Info.plist b/TraccarClient/GoogleService-Info.plist
index 03227aada837c33da3318334f010409c5d6fb6f1..e0871c27faa68ab7fb6fb75f43f3d9b06c3cbef0 100644
--- a/TraccarClient/GoogleService-Info.plist
+++ b/TraccarClient/GoogleService-Info.plist
@@ -3,17 +3,17 @@
 <plist version="1.0">
 <dict>
 	<key>API_KEY</key>
-	<string>AIzaSyCwlmc957R6tpX0vrbVFgKWfmrFytU2foI</string>
+	<string>AIzaSyDm8-DBs0Q9_R4MgcVX69Ngrj74-4IuFYE</string>
 	<key>GCM_SENDER_ID</key>
-	<string>139516981582</string>
+	<string>954155337904</string>
 	<key>PLIST_VERSION</key>
 	<string>1</string>
 	<key>BUNDLE_ID</key>
 	<string>com.nmo.ai.teams</string>
 	<key>PROJECT_ID</key>
-	<string>nmo-teams</string>
+	<string>tracker-member-aca18</string>
 	<key>STORAGE_BUCKET</key>
-	<string>nmo-teams.appspot.com</string>
+	<string>tracker-member-aca18.appspot.com</string>
 	<key>IS_ADS_ENABLED</key>
 	<false></false>
 	<key>IS_ANALYTICS_ENABLED</key>
@@ -25,6 +25,6 @@
 	<key>IS_SIGNIN_ENABLED</key>
 	<true></true>
 	<key>GOOGLE_APP_ID</key>
-	<string>1:139516981582:ios:eb22608153a000308e6e1f</string>
+	<string>1:954155337904:ios:c6fd46b328919e5cfc1375</string>
 </dict>
 </plist>
\ No newline at end of file
diff --git a/TraccarClient/InitialViewController/Controller/InitialViewController.swift b/TraccarClient/InitialViewController/Controller/InitialViewController.swift
index f047571f3afc67d56e0c737c2f09e9bdbcf08944..462c4e50d963818e3828d90053a01de2716cf879 100644
--- a/TraccarClient/InitialViewController/Controller/InitialViewController.swift
+++ b/TraccarClient/InitialViewController/Controller/InitialViewController.swift
@@ -8,6 +8,9 @@
 
 import UIKit
 import Lottie
+import Firebase
+import FirebaseCore
+import FirebaseRemoteConfig
 
 enum shiftStatus: String {
     case notStart
@@ -26,10 +29,26 @@ final class InitialViewController: KNViewController {
     var window: UIWindow?
     private var shift: ShiftModel?
     let userDefaults = UserDefaults.standard
+    private var remoteConfig = RemoteConfig.remoteConfig()
 
     // MARK: - LifeCycle
     override func viewDidLoad() {
         super.viewDidLoad()
+        let defaults: [String: NSObject] = ["welcome_message": "Hello, world!" as NSObject]
+        remoteConfig.setDefaults(defaults)
+        
+        remoteConfig.fetch(withExpirationDuration: TimeInterval(1)) { (status, error) -> Void in
+          if status == .success {
+            print("Config fetched!")
+            self.remoteConfig.activate(completion: { (changed, error) in
+                let leaderButton = self.remoteConfig.configValue(forKey: "leader_appear").boolValue
+                showLeaderButton = leaderButton
+            })
+          } else {
+            print("Config not fetched")
+            print("Error: \(error?.localizedDescription ?? "No error available.")")
+          }
+        }
         view.backgroundColor = .white
         animationView.backgroundColor = .white
         animationView.contentMode = .scaleAspectFill
diff --git a/TraccarClient/LeaderViewController.swift b/TraccarClient/LeaderViewController.swift
new file mode 100644
index 0000000000000000000000000000000000000000..a03216a747392aaf55ad8cf302c1897770dc244e
--- /dev/null
+++ b/TraccarClient/LeaderViewController.swift
@@ -0,0 +1,206 @@
+//
+//  LeaderViewController.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 24/01/2024.
+//  Copyright © 2024 Traccar. All rights reserved.
+//
+
+import UIKit
+import WebKit
+
+class LeaderViewController: KNViewController, WKUIDelegate {
+    
+    static let eventLogin = Notification.Name("eventLogin")
+    static let eventToken = Notification.Name("eventToken")
+    static let eventEvent = Notification.Name("eventEvent")
+    static let keyToken = "keyToken"
+    static let keyEventId = "keyEventId"
+    
+    var window: UIWindow?
+    var webView: WKWebView!
+    var initialized = false
+    var pendingEventId: String? = nil
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        self.isBackButtonHidden = true
+        hasCustomNavigation = true
+        onStart()
+    }
+    
+    private func onStart() {
+        
+        var urlString = leaderServerURL
+        if !urlString.hasSuffix("/") {
+            urlString += "/"
+        }
+        urlString += "api/server"
+        
+        if let url = URL(string: urlString) {
+            let task = URLSession.shared.dataTask(with: url) { data, response, error in
+                if error == nil {
+                    do {
+                        try JSONSerialization.jsonObject(with: data!, options: [])
+                        DispatchQueue.main.async {
+                            self.onSuccess()
+                        }
+                    } catch _ as NSError {
+                        DispatchQueue.main.async {
+                            self.onError()
+                        }
+                    }
+                } else {
+                    DispatchQueue.main.async {
+                        self.onError()
+                    }
+                }
+            }
+            task.resume()
+        } else {
+            self.onError()
+        }
+    }
+    
+    private func onSuccess() {
+        UserDefaults.standard.set(leaderServerURL, forKey: "url")
+        let userDefaults = UserDefaults.standard
+
+        let statusFrame = UIApplication.shared.statusBarFrame
+        var viewFrame = view.frame
+        viewFrame.origin.y = statusFrame.size.height
+        viewFrame.size.height -= statusFrame.size.height
+
+        let userContentController = WKUserContentController()
+        userContentController.add(self, name: "appInterface")
+
+        let webConfiguration = WKWebViewConfiguration()
+        webConfiguration.userContentController = userContentController
+
+        var processPool: WKProcessPool
+        if let encodedPool = userDefaults.value(forKey: "pool") as? Data,
+           let decodedPool = try? NSKeyedUnarchiver.unarchivedObject(ofClass: WKProcessPool.self, from: encodedPool) {
+            processPool = decodedPool
+        } else {
+            processPool = WKProcessPool()
+            let encodedPool = try? NSKeyedArchiver.archivedData(withRootObject: processPool, requiringSecureCoding: true)
+            userDefaults.set(encodedPool, forKey: "pool")
+        }
+        webConfiguration.processPool = processPool
+
+        let group = DispatchGroup()
+        if let encodedCookies = userDefaults.value(forKey: "cookies") as? Data,
+           let cookies = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, HTTPCookie.self], from: encodedCookies) as? [HTTPCookie] {
+            if #available(iOS 11.0, *) {
+                cookies.forEach { cookie in
+                    group.enter()
+                    webConfiguration.websiteDataStore.httpCookieStore.setCookie(cookie) {
+                        group.leave()
+                    }
+                }
+            }
+        }
+        
+        self.webView = WKWebView(frame: viewFrame, configuration: webConfiguration)
+        self.webView.uiDelegate = self
+        self.webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        
+        view.addSubview(self.webView)
+        
+        group.notify(queue: DispatchQueue.main) {
+            self.initialized = true
+            self.loadPage()
+        }
+        
+        NotificationCenter.default.addObserver(self, selector: #selector(onTerminate(_:)), name: UIApplication.willResignActiveNotification, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(onReceive(_:)), name: LeaderViewController.eventToken, object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(onEvent(_:)), name: LeaderViewController.eventEvent, object: nil)
+    }
+    
+    
+    private func onError() {
+        let alert = UIAlertController(title: "Error", message: "Server connection failed", preferredStyle: UIAlertController.Style.alert)
+        alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default))
+        present(alert, animated: true)
+    }
+    
+    private func loadPage() {
+        if let urlString = UserDefaults.standard.object(forKey: "url") as? String {
+            var urlComponents = URLComponents(string: urlString)
+            if let eventId = pendingEventId {
+                urlComponents?.queryItems = [URLQueryItem(name: "eventId", value: eventId)]
+                pendingEventId = nil
+            }
+            if let url = urlComponents?.url {
+                print("URL***: \(url)")
+                self.webView.load(URLRequest(url: url))
+            }
+        }
+    }
+    
+    override func viewWillDisappear(_ animated: Bool) {
+        super.viewWillDisappear(animated)
+        NotificationCenter.default.removeObserver(self, name: LeaderViewController.eventEvent, object: nil)
+        NotificationCenter.default.removeObserver(self, name: LeaderViewController.eventToken, object: nil)
+        NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
+    }
+
+    @objc func onTerminate(_ notification: Notification) {
+        if #available(iOS 11.0, *) {
+            self.webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in
+                let encodedCookies = try? NSKeyedArchiver.archivedData(withRootObject: cookies, requiringSecureCoding: true)
+                UserDefaults.standard.set(encodedCookies, forKey: "cookies")
+            }
+        }
+    }
+
+    @objc func onReceive(_ notification: Notification) {
+        if let token = notification.userInfo?[LeaderViewController.keyToken] {
+            let code = "updateNotificationToken && updateNotificationToken('\(token)')"
+            webView.evaluateJavaScript(code, completionHandler: nil)
+        }
+    }
+
+    @objc func onEvent(_ notification: Notification) {
+        if let eventId = notification.userInfo?[LeaderViewController.keyEventId] as? String {
+            pendingEventId = eventId
+            if initialized {
+                loadPage()
+            }
+        }
+    }
+
+}
+
+extension LeaderViewController : WKScriptMessageHandler {
+    
+    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
+        if let body = message.body as? String {
+            if body.starts(with: "login") {
+                if body.count > 6 {
+                    let token = String(body[body.index(body.startIndex, offsetBy: 6)...])
+                    print("token: \(token)")
+                    SecurityManager.shared.saveToken(token)
+                }
+                NotificationCenter.default.post(name: LeaderViewController.eventLogin, object: nil)
+            } else if body.starts(with: "authentication") {
+                if let token = SecurityManager.shared.readToken() {
+                    let code = "handleLoginToken && handleLoginToken('\(token)')"
+                    webView.evaluateJavaScript(code, completionHandler: nil)
+                }
+            } else if body.starts(with: "logout") {
+                SecurityManager.shared.deleteToken()
+                self.navigationController?.popViewController(animated: true)
+            } else if body.starts(with: "server") {
+                let urlString = String(body[body.index(body.startIndex, offsetBy: 7)...])
+                UserDefaults.standard.set(urlString, forKey: "url")
+                if let url = URL(string: urlString) {
+                    print("***URL***: \(url)")
+                    self.webView.load(URLRequest(url: url))
+                }
+            }
+        }
+    }
+    
+}
+
diff --git a/TraccarClient/LeaderViewController.xib b/TraccarClient/LeaderViewController.xib
new file mode 100644
index 0000000000000000000000000000000000000000..c644d130f734a8328361c03098788f3e5290bc33
--- /dev/null
+++ b/TraccarClient/LeaderViewController.xib
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LeaderViewController" customModuleProvider="target">
+            <connections>
+                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
+            </connections>
+        </placeholder>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
+            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+            <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
+        </view>
+    </objects>
+</document>
diff --git a/TraccarClient/LoginViewController/Controller/LoginViewController.swift b/TraccarClient/LoginViewController/Controller/LoginViewController.swift
index c1408df3ad49d61dc41da2f0fa3f593e97757a81..19286e3b9016530f6e6e3e1a2af88f54927dd0eb 100644
--- a/TraccarClient/LoginViewController/Controller/LoginViewController.swift
+++ b/TraccarClient/LoginViewController/Controller/LoginViewController.swift
@@ -26,6 +26,20 @@ final class LoginViewController: KNViewController {
         setupUI()
     }
     
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+        hasCustomNavigation = false
+        
+    }
+    
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        if let token = SecurityManager.shared.readToken() {
+            let vc = LeaderViewController()
+            self.navigationController?.pushViewController(vc, animated: false)
+        }
+    }
+    
 }
 // MARK: - UI
 extension LoginViewController {
diff --git a/TraccarClient/LoginViewController/Model/LoginDataProvider.swift b/TraccarClient/LoginViewController/Model/LoginDataProvider.swift
index ad2b10cb608df5ddce6ee2778a5260605024c6e8..ee49a317387d8d86e85ebf5d61928eb74cbd85dd 100644
--- a/TraccarClient/LoginViewController/Model/LoginDataProvider.swift
+++ b/TraccarClient/LoginViewController/Model/LoginDataProvider.swift
@@ -64,9 +64,12 @@ final class LoginDataProvider {
             password,
             space,
             loginButton,
-//            space1,
-//            leaderLogin
         ]
+         
+         if showLeaderButton == true {
+             fields.append(space1)
+             fields.append(leaderLogin)
+         }
         return fields
     }
 }
diff --git a/TraccarClient/LoginViewController/Model/LoginModelController.swift b/TraccarClient/LoginViewController/Model/LoginModelController.swift
index d42dad699b30efe6b4882253711122bb51547314..6439643383d6fc1335eb77aaecacb2cb2e423fcf 100644
--- a/TraccarClient/LoginViewController/Model/LoginModelController.swift
+++ b/TraccarClient/LoginViewController/Model/LoginModelController.swift
@@ -176,7 +176,8 @@ extension LoginModelController: LoginOutputProtocol {
             signin()
         }
         if action == .loginAsLeader {
-           print("hello")
+            let leader = LeaderViewController()
+            self.viewController.navigationController?.pushViewController(leader, animated: true)
         }
     }
     
diff --git a/TraccarClient/LoginViewController/View/LoginViewController.xib b/TraccarClient/LoginViewController/View/LoginViewController.xib
index cf0652b16f98ac15684ed15b365311206a8bf5ae..a803b089cf4820ee81825028a5b672504f2fc48a 100644
--- a/TraccarClient/LoginViewController/View/LoginViewController.xib
+++ b/TraccarClient/LoginViewController/View/LoginViewController.xib
@@ -29,26 +29,26 @@
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <subviews>
                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="DeliveryIcon" translatesAutoresizingMaskIntoConstraints="NO" id="rPb-N8-5pB">
-                    <rect key="frame" x="116.66666666666669" y="0.0" width="160" height="160"/>
+                    <rect key="frame" x="116.66666666666669" y="30" width="160" height="160"/>
                     <constraints>
                         <constraint firstAttribute="width" constant="160" id="eJs-0H-D6L"/>
                         <constraint firstAttribute="height" constant="160" id="xEg-fV-es4"/>
                     </constraints>
                 </imageView>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Dive into Fleet Tracking!" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jC6-Ly-QKC">
-                    <rect key="frame" x="81.666666666666671" y="170" width="229.66666666666663" height="22"/>
+                    <rect key="frame" x="81.666666666666671" y="200" width="229.66666666666663" height="22"/>
                     <fontDescription key="fontDescription" name="Montserrat-Bold" family="Montserrat" pointSize="18"/>
                     <nil key="textColor"/>
                     <nil key="highlightedColor"/>
                 </label>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stay connected, drive smart." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ejG-GP-Evp">
-                    <rect key="frame" x="111.33333333333333" y="199" width="170.33333333333337" height="14.666666666666657"/>
+                    <rect key="frame" x="111.33333333333333" y="229" width="170.33333333333337" height="14.666666666666657"/>
                     <fontDescription key="fontDescription" name="Montserrat-Regular" family="Montserrat" pointSize="12"/>
                     <nil key="textColor"/>
                     <nil key="highlightedColor"/>
                 </label>
                 <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="cqa-qG-jss">
-                    <rect key="frame" x="32" y="238.66666666666669" width="329" height="547.33333333333326"/>
+                    <rect key="frame" x="32" y="268.66666666666669" width="329" height="517.33333333333326"/>
                     <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                 </tableView>
             </subviews>
@@ -58,7 +58,7 @@
                 <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="cqa-qG-jss" secondAttribute="trailing" constant="32" id="3jQ-sI-aAm"/>
                 <constraint firstItem="rPb-N8-5pB" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="CJs-Qh-u3u"/>
                 <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="cqa-qG-jss" secondAttribute="bottom" constant="32" id="Dqf-I3-asf"/>
-                <constraint firstItem="rPb-N8-5pB" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="HjK-k3-B52"/>
+                <constraint firstItem="rPb-N8-5pB" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="30" id="HjK-k3-B52"/>
                 <constraint firstItem="cqa-qG-jss" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="32" id="bDg-CD-ZNz"/>
                 <constraint firstItem="ejG-GP-Evp" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="nuW-Lh-yVC"/>
                 <constraint firstItem="ejG-GP-Evp" firstAttribute="top" secondItem="jC6-Ly-QKC" secondAttribute="bottom" constant="7" id="o0G-Yj-sgP"/>
diff --git a/TraccarClient/SecurityManager.swift b/TraccarClient/SecurityManager.swift
new file mode 100644
index 0000000000000000000000000000000000000000..11f7f415c12fa11a55bcb49becc7f690e35fbbfe
--- /dev/null
+++ b/TraccarClient/SecurityManager.swift
@@ -0,0 +1,54 @@
+//
+//  SecurityManager.swift
+//  TraccarClient
+//
+//  Created by George Makhoul on 24/01/2024.
+//  Copyright © 2024 Traccar. All rights reserved.
+//
+
+import Foundation
+import LocalAuthentication
+
+class SecurityManager {
+    
+    private static let service = "traccar23"
+    private static let account = "traccar24"
+    
+    static let shared = SecurityManager()
+    
+    private init() {}
+    
+    func saveToken(_ token: String) {
+        let access = SecAccessControlCreateWithFlags(nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .userPresence, nil)
+        SecItemAdd([
+            kSecClass: kSecClassGenericPassword,
+            kSecAttrService: SecurityManager.service,
+            kSecAttrAccount: SecurityManager.account,
+            kSecAttrAccessControl: access as Any,
+            kSecValueData: Data(token.utf8),
+        ] as CFDictionary, nil)
+    }
+    
+    func readToken() -> String? {
+        var result: AnyObject?
+        SecItemCopyMatching([
+            kSecAttrService: SecurityManager.service,
+            kSecAttrAccount: SecurityManager.account,
+            kSecClass: kSecClassGenericPassword,
+            kSecReturnData: true
+        ] as CFDictionary, &result)
+        if let data = result as? Data {
+            return String(data: data, encoding: .utf8)
+        }
+        return nil
+    }
+    
+    func deleteToken() {
+        SecItemDelete([
+            kSecAttrService: SecurityManager.service,
+            kSecAttrAccount: SecurityManager.account,
+            kSecClass: kSecClassGenericPassword,
+        ] as CFDictionary)
+    }
+
+}
diff --git a/TraccarClient/TraccarClient.entitlements b/TraccarClient/TraccarClient.entitlements
new file mode 100644
index 0000000000000000000000000000000000000000..903def2af53062463744294d5ad4c4ef8d9a4381
--- /dev/null
+++ b/TraccarClient/TraccarClient.entitlements
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>aps-environment</key>
+	<string>development</string>
+</dict>
+</plist>