瀏覽代碼

MasterKey, Database With Key, and Encrypted UserDefaults

alqindiirsyam 8 月之前
父節點
當前提交
7f40103b29
共有 55 個文件被更改,包括 1604 次插入886 次删除
  1. 8 7
      appbuilder-ios/NexilisLite/NexilisLite.podspec
  2. 56 56
      appbuilder-ios/NexilisLite/NexilisLite.xcodeproj/project.pbxproj
  3. 3 3
      appbuilder-ios/NexilisLite/NexilisLite/Source/APIS.swift
  4. 113 113
      appbuilder-ios/NexilisLite/NexilisLite/Source/CoreMessage_TMessageBank.swift
  5. 19 4
      appbuilder-ios/NexilisLite/NexilisLite/Source/Database.swift
  6. 8 9
      appbuilder-ios/NexilisLite/NexilisLite/Source/Extension.swift
  7. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/FloatingButton/FloatingButton.swift
  8. 24 25
      appbuilder-ios/NexilisLite/NexilisLite/Source/IncomingThread.swift
  9. 143 0
      appbuilder-ios/NexilisLite/NexilisLite/Source/MasterKeyUtil.swift
  10. 4 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/Model/User.swift
  11. 54 50
      appbuilder-ios/NexilisLite/NexilisLite/Source/Nexilis.swift
  12. 385 131
      appbuilder-ios/NexilisLite/NexilisLite/Source/Utils.swift
  13. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/BNIView/BNIBookingWebView.swift
  14. 23 27
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioConference.swift
  15. 30 31
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioViewController.swift
  16. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraCallContactViewController.swift
  17. 24 24
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift
  18. 1 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/VideoViewController.swift
  19. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/WhiteboardViewController.swift
  20. 21 22
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/ChatGPTBotView.swift
  21. 41 38
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift
  22. 70 70
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift
  23. 6 6
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorStarMessages.swift
  24. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/FormEditor.swift
  25. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/ListGroupImages.swift
  26. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/MessageInfo.swift
  27. 1 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Contact/ContactCallViewController.swift
  28. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/BackupRestoreView.swift
  29. 3 3
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/BroadcastMembersTableViewController.swift
  30. 1 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/BroadcastViewController.swift
  31. 3 3
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangeDeviceViewController.swift
  32. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangeNamePassswordViewController.swift
  33. 1 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangePasswordViewController.swift
  34. 9 9
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ContactChatViewController.swift
  35. 9 9
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/GroupDetailViewController.swift
  36. 1 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/HistoryBroadcastViewController.swift
  37. 1 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/HistoryCCViewController.swift
  38. 4 4
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/NotificationSound.swift
  39. 13 14
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ProfileViewController.swift
  40. 18 18
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SettingTableViewController.swift
  41. 5 5
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SignUpSignIn.swift
  42. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/CreateSeminarViewController.swift
  43. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/CreateViewController.swift
  44. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraCreateStreamingViewController.swift
  45. 1 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraGroupChooserViewController.swift
  46. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraStreamingViewController.swift
  47. 2 2
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraUserChooserViewController.swift
  48. 6 6
      appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/SeminarViewController.swift
  49. 1 1
      appbuilder-ios/NexilisLite/NexilisLite/Source/Whiteboard.swift
  50. 4 4
      appbuilder-ios/NexilisLite/NexilisLite/Source/WhiteboardCanvas.swift
  51. 2 1
      appbuilder-ios/NexilisLite/Podfile
  52. 16 12
      appbuilder-ios/NexilisLite/Podfile.lock
  53. 20 20
      appbuilder-ios/StreamShield/StreamShield.xcodeproj/project.pbxproj
  54. 二進制
      appbuilder-ios/StreamShield/StreamShield.xcworkspace/xcuserdata/akhmadalqindiirsyam.xcuserdatad/UserInterfaceState.xcuserstate
  55. 424 124
      appbuilder-ios/StreamShield/StreamShield/Source/SecurityShield.swift

+ 8 - 7
appbuilder-ios/NexilisLite/NexilisLite.podspec

@@ -8,7 +8,7 @@
 
 Pod::Spec.new do |spec|
   spec.name         = "NexilisLite"
-  spec.version      = "3.1.6"
+  spec.version      = "3.3.1"
   spec.summary      = "NexilisLite Framework"
   spec.description  = <<-DESC
   NexilisLite Framework, embed Contact Center, Live Streaming, Push Notifications, Instant Messaging, Video and VoIP Calling features into your mobile apps within minutes...
@@ -23,14 +23,15 @@ Pod::Spec.new do |spec|
   spec.source_files = 'NexilisLite/Source/**/*'
   spec.resource_bundles = { 'NexilisLite' => ['NexilisLite/Resource/**/*']}
   spec.swift_version = '5.5.1'
-  spec.dependency 'FMDB', '~> 2.7.5'
+  spec.dependency 'FMDB', '~> 2.7.12'
   spec.dependency 'nuSDKService', '~> 3.0.1'
-  spec.dependency 'NotificationBannerSwift', '3.1.0'
-  spec.dependency 'Alamofire', '~> 5.8.1'
-  spec.dependency 'SDWebImage', '~> 5.15.7'
-  spec.dependency 'Toast-Swift', '~> 5.0.1'
-  spec.dependency 'ZIPFoundation', '~> 0.9.16'
+  spec.dependency 'NotificationBannerSwift', '~> 3.1.0'
+  spec.dependency 'Alamofire', '~> 5.10.1'
+  spec.dependency 'SDWebImage', '~> 5.20.0'
+  spec.dependency 'Toast-Swift', '~> 5.1.1'
+  spec.dependency 'ZIPFoundation', '~> 0.9.19'
   spec.dependency 'SwiftLinkPreview', '~> 3.4.0'
+  spec.dependency 'KeychainAccess'
   spec.dependency 'Popover'
 #  spec.static_framework = true
 # spec.dependency 'iOS-WebP'

+ 56 - 56
appbuilder-ios/NexilisLite/NexilisLite.xcodeproj/project.pbxproj

@@ -7,8 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		03B4662CEBCF58FDF38A8E03 /* Pods_NexilisLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA5A58797C1F42C0AF05CC63 /* Pods_NexilisLite.framework */; };
-		1D663CCEB57353A1875FB047 /* Pods_NexilisLite_NexilisLiteTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DFB9938109BC9A5747759EC3 /* Pods_NexilisLite_NexilisLiteTests.framework */; };
+		0E0CBC6D2A8644203AA0DB5C /* Pods_NexilisLite_NexilisLiteTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC7278BDB36CCEF632B12110 /* Pods_NexilisLite_NexilisLiteTests.framework */; };
 		CD1E6E6D2A0B7C3600BF871F /* NexilisLite.docc in Sources */ = {isa = PBXBuildFile; fileRef = CD1E6E6C2A0B7C3600BF871F /* NexilisLite.docc */; };
 		CD1E6E732A0B7C3600BF871F /* NexilisLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD1E6E682A0B7C3600BF871F /* NexilisLite.framework */; };
 		CD1E6E782A0B7C3600BF871F /* NexilisLiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1E6E772A0B7C3600BF871F /* NexilisLiteTests.swift */; };
@@ -218,6 +217,7 @@
 		CDDF467A2A2EF0A700049A19 /* ScreenSharingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDF46792A2EF0A700049A19 /* ScreenSharingViewController.swift */; };
 		CDE3BED92C86E3A000B0BF36 /* pb_call_in.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = CDE3BED62C86E3A000B0BF36 /* pb_call_in.mp3 */; };
 		CDE3BEDA2C86E3A000B0BF36 /* pb_call_out.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = CDE3BED72C86E3A000B0BF36 /* pb_call_out.mp3 */; };
+		D7C555033B5169B92C3E5655 /* Pods_NexilisLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D25E4968C9AB01451C6FEA4 /* Pods_NexilisLite.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -251,10 +251,11 @@
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
-		28DA4E41B94B8260294E9BBE /* Pods-NexilisLite-NexilisLiteTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite-NexilisLiteTests.debug.xcconfig"; path = "Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests.debug.xcconfig"; sourceTree = "<group>"; };
-		8B2F53106B50A1EDC6FBE37D /* Pods-NexilisLite-NexilisLiteTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite-NexilisLiteTests.release.xcconfig"; path = "Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests.release.xcconfig"; sourceTree = "<group>"; };
-		968C735E00583050852FAEED /* Pods-NexilisLite.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite.release.xcconfig"; path = "Target Support Files/Pods-NexilisLite/Pods-NexilisLite.release.xcconfig"; sourceTree = "<group>"; };
-		AA5A58797C1F42C0AF05CC63 /* Pods_NexilisLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NexilisLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		2286875318512FECCF9DD2D5 /* Pods-NexilisLite-NexilisLiteTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite-NexilisLiteTests.debug.xcconfig"; path = "Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests.debug.xcconfig"; sourceTree = "<group>"; };
+		3BF74C8A0491A2D9CFD5036F /* Pods-NexilisLite.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite.debug.xcconfig"; path = "Target Support Files/Pods-NexilisLite/Pods-NexilisLite.debug.xcconfig"; sourceTree = "<group>"; };
+		5634B1BB53E714D616AC0339 /* Pods-NexilisLite.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite.release.xcconfig"; path = "Target Support Files/Pods-NexilisLite/Pods-NexilisLite.release.xcconfig"; sourceTree = "<group>"; };
+		759E699FA5E58242CC4AD45F /* Pods-NexilisLite-NexilisLiteTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite-NexilisLiteTests.release.xcconfig"; path = "Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests.release.xcconfig"; sourceTree = "<group>"; };
+		7D25E4968C9AB01451C6FEA4 /* Pods_NexilisLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NexilisLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		CD1E6E682A0B7C3600BF871F /* NexilisLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NexilisLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		CD1E6E6B2A0B7C3600BF871F /* NexilisLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NexilisLite.h; sourceTree = "<group>"; };
 		CD1E6E6C2A0B7C3600BF871F /* NexilisLite.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = NexilisLite.docc; sourceTree = "<group>"; };
@@ -475,8 +476,7 @@
 		CDDF46792A2EF0A700049A19 /* ScreenSharingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScreenSharingViewController.swift; sourceTree = "<group>"; };
 		CDE3BED62C86E3A000B0BF36 /* pb_call_in.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = pb_call_in.mp3; sourceTree = "<group>"; };
 		CDE3BED72C86E3A000B0BF36 /* pb_call_out.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = pb_call_out.mp3; sourceTree = "<group>"; };
-		DFB9938109BC9A5747759EC3 /* Pods_NexilisLite_NexilisLiteTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NexilisLite_NexilisLiteTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-		FF91DFACFEA41C6EE68BC56B /* Pods-NexilisLite.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NexilisLite.debug.xcconfig"; path = "Target Support Files/Pods-NexilisLite/Pods-NexilisLite.debug.xcconfig"; sourceTree = "<group>"; };
+		FC7278BDB36CCEF632B12110 /* Pods_NexilisLite_NexilisLiteTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NexilisLite_NexilisLiteTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -484,7 +484,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				03B4662CEBCF58FDF38A8E03 /* Pods_NexilisLite.framework in Frameworks */,
+				D7C555033B5169B92C3E5655 /* Pods_NexilisLite.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -493,7 +493,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				CD1E6E732A0B7C3600BF871F /* NexilisLite.framework in Frameworks */,
-				1D663CCEB57353A1875FB047 /* Pods_NexilisLite_NexilisLiteTests.framework in Frameworks */,
+				0E0CBC6D2A8644203AA0DB5C /* Pods_NexilisLite_NexilisLiteTests.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -517,8 +517,8 @@
 				CD1E79142A0CA43600BF871F /* SDWebImage.framework */,
 				CD1E79152A0CA43600BF871F /* SnapKit.framework */,
 				CD1E79162A0CA43600BF871F /* Toast_Swift.framework */,
-				AA5A58797C1F42C0AF05CC63 /* Pods_NexilisLite.framework */,
-				DFB9938109BC9A5747759EC3 /* Pods_NexilisLite_NexilisLiteTests.framework */,
+				7D25E4968C9AB01451C6FEA4 /* Pods_NexilisLite.framework */,
+				FC7278BDB36CCEF632B12110 /* Pods_NexilisLite_NexilisLiteTests.framework */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -527,10 +527,10 @@
 			isa = PBXGroup;
 			children = (
 				CD46A0BE2A0CE4FD009E4C87 /* NexilisLite.podspec */,
-				FF91DFACFEA41C6EE68BC56B /* Pods-NexilisLite.debug.xcconfig */,
-				968C735E00583050852FAEED /* Pods-NexilisLite.release.xcconfig */,
-				28DA4E41B94B8260294E9BBE /* Pods-NexilisLite-NexilisLiteTests.debug.xcconfig */,
-				8B2F53106B50A1EDC6FBE37D /* Pods-NexilisLite-NexilisLiteTests.release.xcconfig */,
+				3BF74C8A0491A2D9CFD5036F /* Pods-NexilisLite.debug.xcconfig */,
+				5634B1BB53E714D616AC0339 /* Pods-NexilisLite.release.xcconfig */,
+				2286875318512FECCF9DD2D5 /* Pods-NexilisLite-NexilisLiteTests.debug.xcconfig */,
+				759E699FA5E58242CC4AD45F /* Pods-NexilisLite-NexilisLiteTests.release.xcconfig */,
 			);
 			path = Pods;
 			sourceTree = "<group>";
@@ -916,13 +916,13 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = CD1E6E7C2A0B7C3600BF871F /* Build configuration list for PBXNativeTarget "NexilisLite" */;
 			buildPhases = (
-				E2138675F38346294A61B64E /* [CP] Check Pods Manifest.lock */,
+				04BA19F1F3328DB84CA3450C /* [CP] Check Pods Manifest.lock */,
 				CD1E6E632A0B7C3600BF871F /* Headers */,
 				CD1E6E642A0B7C3600BF871F /* Sources */,
 				CD1E6E652A0B7C3600BF871F /* Frameworks */,
 				CD1E6E662A0B7C3600BF871F /* Resources */,
 				CD469E162A0CA6C9009E4C87 /* Embed Frameworks */,
-				89627462B0C7D391D4203DDF /* [CP] Copy Pods Resources */,
+				6CBA06F8A3EDD9E9F4E3E3F0 /* [CP] Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -938,12 +938,12 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = CD1E6E7F2A0B7C3600BF871F /* Build configuration list for PBXNativeTarget "NexilisLiteTests" */;
 			buildPhases = (
-				DAB99E64D381E189F7AA8408 /* [CP] Check Pods Manifest.lock */,
+				3FE251F6F0AD0D52A6241402 /* [CP] Check Pods Manifest.lock */,
 				CD1E6E6E2A0B7C3600BF871F /* Sources */,
 				CD1E6E6F2A0B7C3600BF871F /* Frameworks */,
 				CD1E6E702A0B7C3600BF871F /* Resources */,
-				24F1D99E322B2ABCB5F41ABF /* [CP] Embed Pods Frameworks */,
-				EDCEED0C3660AFE2F761DACF /* [CP] Copy Pods Resources */,
+				8BBEF7E204C8A2B6A2ED4970 /* [CP] Embed Pods Frameworks */,
+				8DCAA429A19A02EFDE64AEEA /* [CP] Copy Pods Resources */,
 			);
 			buildRules = (
 			);
@@ -1144,85 +1144,85 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		24F1D99E322B2ABCB5F41ABF /* [CP] Embed Pods Frameworks */ = {
+		04BA19F1F3328DB84CA3450C /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputFileListPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
 			);
-			name = "[CP] Embed Pods Frameworks";
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
 			outputFileListPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-NexilisLite-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests-frameworks.sh\"\n";
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		89627462B0C7D391D4203DDF /* [CP] Copy Pods Resources */ = {
+		3FE251F6F0AD0D52A6241402 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputFileListPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite/Pods-NexilisLite-resources-${CONFIGURATION}-input-files.xcfilelist",
 			);
-			name = "[CP] Copy Pods Resources";
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
 			outputFileListPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite/Pods-NexilisLite-resources-${CONFIGURATION}-output-files.xcfilelist",
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-NexilisLite-NexilisLiteTests-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NexilisLite/Pods-NexilisLite-resources.sh\"\n";
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		DAB99E64D381E189F7AA8408 /* [CP] Check Pods Manifest.lock */ = {
+		6CBA06F8A3EDD9E9F4E3E3F0 /* [CP] Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite/Pods-NexilisLite-resources-${CONFIGURATION}-input-files.xcfilelist",
 			);
-			inputPaths = (
-				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
-				"${PODS_ROOT}/Manifest.lock",
-			);
-			name = "[CP] Check Pods Manifest.lock";
+			name = "[CP] Copy Pods Resources";
 			outputFileListPaths = (
-			);
-			outputPaths = (
-				"$(DERIVED_FILE_DIR)/Pods-NexilisLite-NexilisLiteTests-checkManifestLockResult.txt",
+				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite/Pods-NexilisLite-resources-${CONFIGURATION}-output-files.xcfilelist",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NexilisLite/Pods-NexilisLite-resources.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		E2138675F38346294A61B64E /* [CP] Check Pods Manifest.lock */ = {
+		8BBEF7E204C8A2B6A2ED4970 /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputFileListPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
 			);
-			inputPaths = (
-				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
-				"${PODS_ROOT}/Manifest.lock",
-			);
-			name = "[CP] Check Pods Manifest.lock";
+			name = "[CP] Embed Pods Frameworks";
 			outputFileListPaths = (
-			);
-			outputPaths = (
-				"$(DERIVED_FILE_DIR)/Pods-NexilisLite-checkManifestLockResult.txt",
+				"${PODS_ROOT}/Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NexilisLite-NexilisLiteTests/Pods-NexilisLite-NexilisLiteTests-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		EDCEED0C3660AFE2F761DACF /* [CP] Copy Pods Resources */ = {
+		8DCAA429A19A02EFDE64AEEA /* [CP] Copy Pods Resources */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -1517,7 +1517,7 @@
 		};
 		CD1E6E7D2A0B7C3600BF871F /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = FF91DFACFEA41C6EE68BC56B /* Pods-NexilisLite.debug.xcconfig */;
+			baseConfigurationReference = 3BF74C8A0491A2D9CFD5036F /* Pods-NexilisLite.debug.xcconfig */;
 			buildSettings = {
 				BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
 				CODE_SIGN_STYLE = Automatic;
@@ -1557,7 +1557,7 @@
 		};
 		CD1E6E7E2A0B7C3600BF871F /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 968C735E00583050852FAEED /* Pods-NexilisLite.release.xcconfig */;
+			baseConfigurationReference = 5634B1BB53E714D616AC0339 /* Pods-NexilisLite.release.xcconfig */;
 			buildSettings = {
 				BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
 				CODE_SIGN_STYLE = Automatic;
@@ -1597,7 +1597,7 @@
 		};
 		CD1E6E802A0B7C3600BF871F /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 28DA4E41B94B8260294E9BBE /* Pods-NexilisLite-NexilisLiteTests.debug.xcconfig */;
+			baseConfigurationReference = 2286875318512FECCF9DD2D5 /* Pods-NexilisLite-NexilisLiteTests.debug.xcconfig */;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
 				CODE_SIGN_STYLE = Automatic;
@@ -1615,7 +1615,7 @@
 		};
 		CD1E6E812A0B7C3600BF871F /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 8B2F53106B50A1EDC6FBE37D /* Pods-NexilisLite-NexilisLiteTests.release.xcconfig */;
+			baseConfigurationReference = 759E699FA5E58242CC4AD45F /* Pods-NexilisLite-NexilisLiteTests.release.xcconfig */;
 			buildSettings = {
 				ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)";
 				CODE_SIGN_STYLE = Automatic;

+ 3 - 3
appbuilder-ios/NexilisLite/NexilisLite/Source/APIS.swift

@@ -87,7 +87,7 @@ public class APIS: NSObject {
                     }
                 }
             }
-            let isWaitingRequestCC = UserDefaults.standard.bool(forKey: "waitingRequestCC")
+            let isWaitingRequestCC: Bool = SecureUserDefaults.shared.value(forKey: "waitingRequestCC") ?? false
             if isWaitingRequestCC {
                 let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
                 imageView.tintColor = .white
@@ -485,7 +485,7 @@ public class APIS: NSObject {
             return
         }
         let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
-        controller.data = UserDefaults.standard.string(forKey: "me")!
+        controller.data = User.getMyPin()!
         controller.flag = .me
         controller.fromAPI = true
         controller.dismissImage = { image, imageName in
@@ -653,7 +653,7 @@ public class APIS: NSObject {
     
     private static func signInAdmin(password: String, completion: @escaping (Bool) -> ()) {
         DispatchQueue.global().async {
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let p_password = password
             let md5Hex = p_password
             var result: Bool = false

文件差異過大導致無法顯示
+ 113 - 113
appbuilder-ios/NexilisLite/NexilisLite/Source/CoreMessage_TMessageBank.swift


+ 19 - 4
appbuilder-ios/NexilisLite/NexilisLite/Source/Database.swift

@@ -8,6 +8,8 @@
 
 import Foundation
 import FMDB
+import Security
+import KeychainAccess
 
 public class Database {
     
@@ -15,23 +17,36 @@ public class Database {
     
     public static let shared = Database()
     
-    public let database = FMDatabaseQueue(path: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/PalioLite.sqlite")
+    public let database = FMDatabaseQueue(path: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/encrypted_db_es.db")
+
     
     func openDatabase() {
         database?.inDatabase({(fmdb) in
-            fmdb.setKey("lumia")
-            //print("Open Done")
+            fmdb.setKey(Utils.getPasswordDB() ?? "Lumia")
+//            print("Open Done")
         })
         database?.inTransaction({(fmdb, rollback) in
             do {
                 try createDatabase(fmdb: fmdb)
-                //print("Create Done")
+//                print("Create Done")
             } catch {
             }
         })
     }
     
     func createDatabase(fmdb:FMDatabase) throws -> Void{
+        let pragmas = [
+            "PRAGMA cipher_page_size = 1024;",
+            "PRAGMA kdf_iter = 64000;",
+            "PRAGMA cipher_hmac_algorithm = 'HMAC_SHA512';",
+            "PRAGMA cipher_kdf_algorithm = 'PBKDF2_HMAC_SHA512';",
+            "PRAGMA cipher = 'aes-256-gcm';"
+        ]
+        
+        for pragma in pragmas {
+            fmdb.executeUpdate(pragma, withArgumentsIn: [])
+        }
+        
         try fmdb.executeUpdate("CREATE TABLE IF NOT EXISTS 'BUDDY' (" +
                                 "'_id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
                                 "'f_pin' text NOT NULL UNIQUE," +

+ 8 - 9
appbuilder-ios/NexilisLite/NexilisLite/Source/Extension.swift

@@ -537,18 +537,18 @@ extension UIView {
 extension String {
     
     public func localized(uppercased: Bool = false) -> String {
-        if let _ = UserDefaults.standard.string(forKey: "i18n_language") {} else {
+        if let _ : String = SecureUserDefaults.shared.value(forKey: "i18n_language") {} else {
             // we set a default, just in case
             let langDefault = UserDefaults.standard.stringArray(forKey: "AppleLanguages")
             if langDefault![0].contains("id") {
-                UserDefaults.standard.set("id", forKey: "i18n_language")
-                UserDefaults.standard.synchronize()
+                SecureUserDefaults.shared.set("id", forKey: "i18n_language")
+                SecureUserDefaults.shared.sync()
             } else {
-                UserDefaults.standard.set("en", forKey: "i18n_language")
-                UserDefaults.standard.synchronize()
+                SecureUserDefaults.shared.set("en", forKey: "i18n_language")
+                SecureUserDefaults.shared.sync()
             }
         }
-        let lang = UserDefaults.standard.string(forKey: "i18n_language")
+        let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? ""
         let bundle = Bundle.resourceBundle(for: Nexilis.self).path(forResource: lang, ofType: "lproj")
         let bundlePath = Bundle(path: bundle!)
         let result = NSLocalizedString(
@@ -1309,7 +1309,6 @@ public class ImageCache {
 
     private init() {
         loadCache()
-//        UserDefaults.standard.removeObject(forKey: "imageCache")
         NotificationCenter.default.addObserver(self, selector: #selector(saveCache), name: UIApplication.didEnterBackgroundNotification, object: nil)
     }
 
@@ -1334,7 +1333,7 @@ public class ImageCache {
     
     private var cacheKeys: [String] = []
     private func loadCache() {
-        if let cachedData = UserDefaults.standard.object(forKey: "imageCache") as? Data {
+        if let cachedData: Data = SecureUserDefaults.shared.value(forKey: "imageCache") {
             if let decodedCache = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(cachedData) as? [String: Data] {
                 for (key, valueData) in decodedCache {
                     if let image = UIImage(data: valueData) {
@@ -1363,7 +1362,7 @@ public class ImageCache {
             }
         }
         let encodedData = try? NSKeyedArchiver.archivedData(withRootObject: cacheDictionary, requiringSecureCoding: false)
-        UserDefaults.standard.set(encodedData, forKey: "imageCache")
+        SecureUserDefaults.shared.set(encodedData, forKey: "imageCache")
     }
 }
 

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/FloatingButton/FloatingButton.swift

@@ -531,8 +531,8 @@ public class FloatingButton: UIView {
         if lastPosY != nil {
             lastPosY = nil
         }
-        UserDefaults.standard.set(center.x, forKey: "xlastPosFB")
-        UserDefaults.standard.set(center.y, forKey: "ylastPosFB")
+        SecureUserDefaults.shared.set(center.x, forKey: "xlastPosFB")
+        SecureUserDefaults.shared.set(center.y, forKey: "ylastPosFB")
     }
     
     @objc func imageFBUpdate(notification: NSNotification) {

+ 24 - 25
appbuilder-ios/NexilisLite/NexilisLite/Source/IncomingThread.swift

@@ -239,12 +239,12 @@ class IncomingThread {
                 id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                 if(!id.isEmpty){
 //                            Nexilis.changeUser(f_pin: id)
-                    UserDefaults.standard.setValue(id, forKey: "me")
+                    SecureUserDefaults.shared.set(id, forKey: "me")
                     Utils.setProfile(value: false)
-                    UserDefaults.standard.synchronize()
+                    SecureUserDefaults.shared.sync()
                     if Utils.getForceAnonymous() {
                         viewController?.deleteAllRecordDatabase()
-                        UserDefaults.standard.removeObject(forKey: "device_id")
+                        SecureUserDefaults.shared.removeValue(forKey: "device_id")
                         Nexilis.destroyAll()
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                     }
@@ -375,8 +375,8 @@ class IncomingThread {
         }
         ack(message: message)
         DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
-            let channelCC = UserDefaults.standard.string(forKey: "channelCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
+            let channelCC: String = SecureUserDefaults.shared.value(forKey: "channelCC") ?? ""
             let complaintId = onGoingCC.components(separatedBy: ",")[2]
             let fPinCC = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
             if fPinCC == User.getMyPin() {
@@ -514,7 +514,7 @@ class IncomingThread {
                         if (firstname + " " + lastname).trimmingCharacters(in: .whitespaces) == "USR\(f_pin)" {
                             return
                         }
-                        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                         if !onGoingCC.isEmpty {
                             return
                         }
@@ -654,7 +654,7 @@ class IncomingThread {
     }
     
     private func onApproveForm(message: TMessage) {
-        if let me = UserDefaults.standard.string(forKey: "me") {
+        if let me = User.getMyPin() {
             _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: me))
         }
         ack(message: message)
@@ -898,7 +898,7 @@ class IncomingThread {
     private func exitGroup(message: TMessage) -> Void {
         let f_pin = message.getBody(key: CoreMessage_TMessageKey.F_PIN)
         let group_id = message.getBody(key: CoreMessage_TMessageKey.GROUP_ID)
-        if let me = UserDefaults.standard.string(forKey: "me"), me == f_pin {
+        if let me = User.getMyPin(), me == f_pin {
             Database.shared.database?.inTransaction({ (fmdb, rollback) in
                 if let cursorIsEducation = Database.shared.getRecords(fmdb: fmdb, query: "select is_education from GROUPZ where group_id='\(group_id)'"), cursorIsEducation.next() {
                     let is_education = Int(cursorIsEducation.int(forColumnIndex: 0))
@@ -1206,7 +1206,7 @@ class IncomingThread {
     
     private func receiveMessage(message: TMessage) -> Void {
         let message_id = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_ID)
-        guard let _ = UserDefaults.standard.string(forKey: "status") else {
+        guard let _: String = SecureUserDefaults.shared.value(forKey: "status") else {
             //print("App not ready!!! skip receive message \(message_id)")
             ack(message: message)
             return
@@ -1229,7 +1229,6 @@ class IncomingThread {
                 //print("write thumb \(url.path)")
                 try data.write(to: url, options: .atomic)
 //                let image = UIImage(data: data)
-//                let save = UserDefaults.standard.bool(forKey: "saveToGallery")
 //                if save {
 //                    UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
 //                }
@@ -1255,7 +1254,7 @@ class IncomingThread {
     
     private func receiveMessageStatus(message: TMessage) -> Void {
         let message_id = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_ID)
-        guard let _ = UserDefaults.standard.string(forKey: "status") else {
+        guard let _: String = SecureUserDefaults.shared.value(forKey: "status") else {
             //print("App not ready!!! skip receive message \(message_id)")
             return
         }
@@ -1357,9 +1356,9 @@ class IncomingThread {
                             "f_display_name" : (CoreMessage_TMessageUtil.getString(json: json, key: CoreMessage_TMessageKey.FIRST_NAME) + " " + CoreMessage_TMessageUtil.getString(json: json, key: CoreMessage_TMessageKey.LAST_NAME)).trimmingCharacters(in: .whitespaces)
                         ], _where: "f_pin = '\(CoreMessage_TMessageUtil.getString(json: json, key: CoreMessage_TMessageKey.F_PIN))'")
                     }
-                    let device_id = UserDefaults.standard.string(forKey: "device_id") ?? ""
+                    let device_id: String = SecureUserDefaults.shared.value(forKey: "device_id") ?? ""
                     if !device_id.isEmpty, let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin FROM BUDDY where device_id='\(device_id)'"), cursorUser.next() {
-                        UserDefaults.standard.setValue(cursorUser.string(forColumnIndex: 0), forKey: "me")
+                        SecureUserDefaults.shared.set(cursorUser.string(forColumnIndex: 0), forKey: "me")
                         cursorUser.close()
                     }
                     if let delegate = Nexilis.shared.personInfoDelegate {
@@ -1376,7 +1375,7 @@ class IncomingThread {
     
     private func deleteBuddy(message: TMessage) -> Void {
         var l_pin = message.getBody(key: CoreMessage_TMessageKey.L_PIN)
-        l_pin = (l_pin == UserDefaults.standard.string(forKey: "me")) ? message.mPIN : l_pin
+        l_pin = (l_pin == User.getMyPin()) ? message.mPIN : l_pin
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             do {
                 if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select * from BUDDY where f_pin = '\(l_pin)'"), cursor.next() {
@@ -1461,20 +1460,20 @@ class IncomingThread {
                     "area" : message.getBody(key: CoreMessage_TMessageKey.WORKING_AREA),
                     "is_second_layer" : message.getBody(key: CoreMessage_TMessageKey.IS_SECOND_LAYER),
                 ], replace: true)
-                let device_id = UserDefaults.standard.string(forKey: "device_id") ?? ""
+                let device_id: String = SecureUserDefaults.shared.value(forKey: "device_id") ?? ""
                 if !device_id.isEmpty, let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin FROM BUDDY where device_id='\(device_id)'"), cursorUser.next() {
-                    UserDefaults.standard.setValue(cursorUser.string(forColumnIndex: 0), forKey: "me")
+                    SecureUserDefaults.shared.set(cursorUser.string(forColumnIndex: 0), forKey: "me")
                     cursorUser.close()
                 }
                 ack(message: message)
-                let idMe = UserDefaults.standard.string(forKey: "me")!
+                let idMe = User.getMyPin()!
                 if message.getBody(key: CoreMessage_TMessageKey.USER_TYPE) != "24" && message.getBody(key: CoreMessage_TMessageKey.F_PIN) == idMe {
-                    let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                    let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                     if !onGoingCC.isEmpty {
                         let requester = onGoingCC.components(separatedBy: ",")[0]
                         let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                         let complaintId = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2]
-                        let startTimeCC = UserDefaults.standard.string(forKey: "startTimeCC") ?? ""
+                        let startTimeCC: String = SecureUserDefaults.shared.value(forKey: "startTimeCC") ?? ""
                         let date = "\(Date().currentTimeMillis())"
                         if officer == idMe {
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.endCallCenter(complaint_id: complaintId, l_pin: requester))
@@ -1496,9 +1495,9 @@ class IncomingThread {
                             "members" : "",
                             "requester": requester
                         ], replace: true)
-                        UserDefaults.standard.removeObject(forKey: "onGoingCC")
-                        UserDefaults.standard.removeObject(forKey: "membersCC")
-                        UserDefaults.standard.removeObject(forKey: "startTimeCC")
+                        SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+                        SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+                        SecureUserDefaults.shared.removeValue(forKey: "startTimeCC")
                         DispatchQueue.main.async {
                             let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
                             imageView.tintColor = .white
@@ -1698,7 +1697,7 @@ class IncomingThread {
                 if let delegate = Nexilis.shared.loginDelegate {
                     delegate.onProgress(code: message.getCode(), progress: 100)
                 }
-                UserDefaults.standard.set("READY", forKey: "status")
+                SecureUserDefaults.shared.set("READY", forKey: "status")
             }
         }
         else {
@@ -1945,7 +1944,7 @@ class IncomingThread {
     private func signInOTP(message: TMessage) -> Void {
         if (message.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "00") == "00") {
             let f_pin = message.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "00")
-            UserDefaults.standard.set(f_pin, forKey: "me")
+            SecureUserDefaults.shared.set(f_pin, forKey: "me")
             if let delegate = Nexilis.shared.loginDelegate {
                 delegate.onProcess(message: f_pin, status: message.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "00"))
             }
@@ -2132,7 +2131,7 @@ class IncomingThread {
             //                        "official_account" : message.getBody(key: CoreMessage_TMessageKey.OFFICIAL_ACCOUNT),
             Database.shared.database?.inTransaction({ (fmdb,rollback) in
                 do {
-                    if let me = UserDefaults.standard.string(forKey: "me"), me == message.mPIN, !cvalues.isEmpty {
+                    if let me = User.getMyPin(), me == message.mPIN, !cvalues.isEmpty {
                         let update = Database.shared.updateRecord(fmdb: fmdb, table: "BUDDY", cvalues: cvalues, _where: "f_pin = '\(message.mPIN)'")
                         if(update > 0){
                             if let delegate = Nexilis.shared.personInfoDelegate {

+ 143 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/MasterKeyUtil.swift

@@ -0,0 +1,143 @@
+//
+//  SecureStorage.swift
+//  Pods
+//
+//  Created by Qindi on 02/12/24.
+//
+
+import CryptoKit
+
+
+public class MasterKeyUtil {
+    static let shared = MasterKeyUtil()
+    private let keyAlias = "_iosx_security_master_key"
+    private let prefsKeyAlias = "_iosx_security_master_key_easysoft_"
+
+    private init() {}
+    
+    func generateAndStoreKey() throws {
+        if try isKeyExists(keyAliasCode: keyAlias) {
+//            print("Master Key already exists, skipping generation.")
+            return
+        }
+        let key = SymmetricKey(size: .bits256)
+        let keyData = key.withUnsafeBytes { Data($0) }
+        
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: keyAlias,
+            kSecValueData as String: keyData,
+            kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
+        ]
+        
+        SecItemDelete(query as CFDictionary) // Remove if it exists
+        let status = SecItemAdd(query as CFDictionary, nil)
+        guard status == errSecSuccess else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+    }
+    
+    func generateAndStorePrefsKey() throws {
+        if try isKeyExists(keyAliasCode: prefsKeyAlias) {
+//            print("Prefs Key already exists, skipping generation.")
+            return
+        }
+        let key = SymmetricKey(size: .bits256)
+        let keyData = key.withUnsafeBytes { Data($0) }
+        
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: prefsKeyAlias,
+            kSecValueData as String: keyData,
+            kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
+        ]
+        
+        SecItemDelete(query as CFDictionary) // Remove if it exists
+        let status = SecItemAdd(query as CFDictionary, nil)
+        guard status == errSecSuccess else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+    }
+    
+    func isKeyExists(keyAliasCode: String) throws -> Bool {
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: keyAliasCode,
+            kSecReturnData as String: false // We only check existence, not retrieve data
+        ]
+
+        let status = SecItemCopyMatching(query as CFDictionary, nil)
+        if status == errSecItemNotFound {
+            return false
+        } else if status == errSecSuccess {
+            return true
+        } else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+    }
+    
+    func getMasterKey() throws -> SymmetricKey {
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: keyAlias,
+            kSecReturnData as String: true
+        ]
+        
+        var item: CFTypeRef?
+        let status = SecItemCopyMatching(query as CFDictionary, &item)
+        guard status == errSecSuccess else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+        
+        guard let keyData = item as? Data else {
+            throw NSError(domain: "KeyRetrievalError", code: -1, userInfo: nil)
+        }
+        
+        return SymmetricKey(data: keyData)
+    }
+    
+    func getPrefsKey() throws -> SymmetricKey {
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: prefsKeyAlias,
+            kSecReturnData as String: true
+        ]
+        
+        var item: CFTypeRef?
+        let status = SecItemCopyMatching(query as CFDictionary, &item)
+        guard status == errSecSuccess else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+        
+        guard let keyData = item as? Data else {
+            throw NSError(domain: "KeyRetrievalError", code: -1, userInfo: nil)
+        }
+        
+        return SymmetricKey(data: keyData)
+    }
+    
+    func encryptP(data: Data) throws -> Data {
+        let key = try getPrefsKey()
+        let sealedBox = try AES.GCM.seal(data, using: key)
+        return sealedBox.combined!
+    }
+    
+    func decryptP(data: Data) throws -> Data {
+        let key = try getPrefsKey()
+        let sealedBox = try AES.GCM.SealedBox(combined: data)
+        return try AES.GCM.open(sealedBox, using: key)
+    }
+    
+    func encryptD(data: Data) throws -> Data {
+        let key = try getMasterKey()
+        let sealedBox = try AES.GCM.seal(data, using: key)
+        return sealedBox.combined!
+    }
+    
+    // Decrypt data
+    func decryptD(data: Data) throws -> Data {
+        let key = try getMasterKey()
+        let sealedBox = try AES.GCM.SealedBox(combined: data)
+        return try AES.GCM.open(sealedBox, using: key)
+    }
+}

+ 4 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/Model/User.swift

@@ -112,7 +112,10 @@ public class User: Model {
     }
     
     public static func getMyPin() -> String? {
-        return UserDefaults.standard.string(forKey: "me")
+        if let value: String = SecureUserDefaults.shared.value(forKey: "me") {
+            return value
+        }
+        return nil
     }
     
     public static func getData(pin: String?, fmdb: FMDatabase? = nil) -> User? {

+ 54 - 50
appbuilder-ios/NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -139,6 +139,12 @@ public class Nexilis: NSObject {
         
         Nexilis.showButtonFB = showButton
         
+        do {
+            try MasterKeyUtil.shared.generateAndStoreKey()
+            try MasterKeyUtil.shared.generateAndStorePrefsKey()
+        } catch {
+        }
+        
         Database.shared.openDatabase()
         
         IncomingThread.default.run()
@@ -153,15 +159,13 @@ public class Nexilis: NSObject {
                 if address.isEmpty {
                     return
                 }
-    //            UserDefaults.standard.set(address, forKey: "address")
-    //            UserDefaults.standard.set(address[0], forKey: "server")
+    //            SecureUserDefaults.shared.set(address, forKey: "address")
+    //            SecureUserDefaults.shared.set(address[0], forKey: "server")
     //
                 Nexilis.dispatch = DispatchGroup()
                 Nexilis.dispatch?.enter()
-    //            var server = UserDefaults.standard.string(forKey: "server")
-    //            if let s = server, let a = UserDefaults.standard.stringArray(forKey: "address"), s != a[0] {
     //                server = a[0]
-    //                UserDefaults.standard.set(server, forKey: "server")
+    //                SecureUserDefaults.shared.set(server, forKey: "server")
     //            }
     //            var ip = ""
     //            var port = 0
@@ -177,9 +181,8 @@ public class Nexilis: NSObject {
 //                print("sGetVersion \(API.sGetVersion())")
 //                print("IP PORT \(Nexilis.ADDRESS) <> \(Nexilis.PORT)")
                 var id = Utils.getConnectionID()
-//                if let device_id = UserDefaults.standard.string(forKey: "device_id") {
 //                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: device_id, sStartWH: "09:00")
-//                } else if let me = UserDefaults.standard.string(forKey: "me") {
+//                } else if let me = User.getMyPin() {
 //                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: me, sStartWH: "09:00")
 //                } else {
 //                    let uuid = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
@@ -198,25 +201,26 @@ public class Nexilis: NSObject {
                 Nexilis.dispatch = nil
                 
     //            Nexilis.initiateAudio()
-                if(UserDefaults.standard.string(forKey: "me") == nil){
+                if(User.getMyPin() == nil){
                     if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000){
                         id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         let enable_signup = (response.getBody(key: CoreMessage_TMessageKey.IS_ENABLED_ANONYMOUS, default_value: "0")) == "1"
                         Utils.setForceAnonymous(value: enable_signup)
                         if(!id.isEmpty) {
 //                            Nexilis.changeUser(f_pin: id)
-                            UserDefaults.standard.setValue(id, forKey: "me")
+                            SecureUserDefaults.shared.set(id, forKey: "me")
                         }
                     }
                 }
 
-                if UserDefaults.standard.string(forKey: "apiKey") == nil {
-                    UserDefaults.standard.setValue(apiKey, forKey: "apiKey")
+                let api: String? = SecureUserDefaults.shared.value(forKey: "apiKey") ?? nil
+                if api == nil {
+                    SecureUserDefaults.shared.set(apiKey, forKey: "apiKey")
                 }
                 
                 getFeatureAccess()
                 
-                if let me = UserDefaults.standard.string(forKey: "me") {
+                if let me = User.getMyPin() {
                     if Utils.getForceAnonymous() || (!Utils.getForceAnonymous() && Utils.getSetProfile()) {
                         Database.shared.database?.inTransaction({ (fmdb, rollback) in
                             if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT * FROM BUDDY where f_pin = '\(me)' ") {
@@ -363,7 +367,7 @@ public class Nexilis: NSObject {
     
     private static func getPrefs(key: String) -> TMessage {
         let tMessage = NexilisLite.TMessage()
-        let me = UserDefaults.standard.string(forKey: "me")
+        let me = User.getMyPin()
         tMessage.mCode = "PPR"
         tMessage.mStatus = CoreMessage_TMessageUtil.getTID()
         tMessage.mBodies[CoreMessage_TMessageKey.F_PIN] = me
@@ -638,13 +642,13 @@ public class Nexilis: NSObject {
     }
     
     public static func destroyAll() {
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
         if !onGoingCC.isEmpty {
             let requester = onGoingCC.components(separatedBy: ",")[0]
             let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
             let complaintId = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2]
-            let idMe = UserDefaults.standard.string(forKey: "me")!
-            let startTimeCC = UserDefaults.standard.string(forKey: "startTimeCC") ?? ""
+            let idMe = User.getMyPin()!
+            let startTimeCC: String = SecureUserDefaults.shared.value(forKey: "startTimeCC") ?? ""
             let date = "\(Date().currentTimeMillis())"
             Database.shared.database?.inTransaction({ (fmdb, rollback) in
                 do {
@@ -673,9 +677,9 @@ public class Nexilis: NSObject {
                     _ = Nexilis.write(message: CoreMessage_TMessageBank.leaveCCRoomInvite(ticket_id: complaintId))
                 }
             }
-            UserDefaults.standard.removeObject(forKey: "onGoingCC")
-            UserDefaults.standard.removeObject(forKey: "membersCC")
-            UserDefaults.standard.removeObject(forKey: "startTimeCC")
+            SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+            SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+            SecureUserDefaults.shared.removeValue(forKey: "startTimeCC")
             if UIApplication.shared.applicationState == .active {
                 DispatchQueue.main.async {
                     let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
@@ -690,9 +694,9 @@ public class Nexilis: NSObject {
                 _ = Nexilis.write(message: CoreMessage_TMessageBank.timeOutRequestCallCenter(channel: Nexilis.onGoingPushCC["channel"]!, l_pin: Nexilis.onGoingPushCC["l_pin"]!))
             }
         }
-        UserDefaults.standard.removeObject(forKey: "inEditorPersonal")
-        UserDefaults.standard.removeObject(forKey: "inEditorGroup")
-        UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+        SecureUserDefaults.shared.removeValue(forKey: "inEditorPersonal")
+        SecureUserDefaults.shared.removeValue(forKey: "inEditorGroup")
+        SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
     }
     
     public static func changeUser(f_pin: String){
@@ -865,12 +869,12 @@ public class Nexilis: NSObject {
             }
 
             let dataEncode = String(data: data, encoding: .utf8)!
-            print("dataEncode \(dataEncode.trimmingCharacters(in: .whitespacesAndNewlines))")
+//            print("dataEncode \(dataEncode.trimmingCharacters(in: .whitespacesAndNewlines))")
 //            //print("decrypt \(Utils.decrypt(str: "4=sm<wmpm1ir==>wtxxl"))")
             if !dataEncode.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
                 let dataDecodeBase64 = String(data: Data(base64Encoded: dataEncode)!, encoding: .utf8)!
                 let dataRealDecode = Utils.decrypt(str: dataDecodeBase64)
-                print("dataRealDecode \(dataRealDecode)")
+//                print("dataRealDecode \(dataRealDecode)")
                 do {
                     if let jsonData = dataRealDecode.data(using: .utf8), let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
                         var newDomain = jsonObject["domain"] as! String
@@ -936,7 +940,7 @@ public class Nexilis: NSObject {
     }
     
     static func getCLMUserId() -> String {
-        guard let me = UserDefaults.standard.string(forKey: "me") else {
+        guard let me = User.getMyPin() else {
             return ""
         }
         return me
@@ -1349,7 +1353,7 @@ public class Nexilis: NSObject {
     }
     
     static func saveMessage(message: TMessage, withStatus: Bool = true) {
-        guard let me = UserDefaults.standard.string(forKey: "me") else {
+        guard let me = User.getMyPin() else {
             return
         }
         let message_id = message.getBody(key : CoreMessage_TMessageKey.MESSAGE_ID, default_value : "")
@@ -1500,7 +1504,7 @@ public class Nexilis: NSObject {
     }
     
     public static func saveMessageBot(textMessage: String, blog_id: String, attachment_type:String)->Void{
-        guard let me = UserDefaults.standard.string(forKey: "me") else {
+        guard let me = User.getMyPin() else {
             return
         }
         
@@ -1708,7 +1712,7 @@ public class Nexilis: NSObject {
     }
     
     static func initFollowing() -> Void {
-        if let me = UserDefaults.standard.string(forKey: "me") {
+        if let me = User.getMyPin() {
             if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getListFollowing(l_pin: me)) {
                 let data = response.getBody(key: CoreMessage_TMessageKey.DATA)
                 if !data.isEmpty {
@@ -2189,9 +2193,9 @@ extension Nexilis: CallDelegate {
     
     public func onIncomingCall(state: Int, message: String) {
         DispatchQueue.main.async {
-            let idMe = UserDefaults.standard.string(forKey: "me")!
+            let idMe = User.getMyPin()!
             let myData = User.getData(pin: idMe)
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 return
             }
@@ -2872,9 +2876,9 @@ extension Nexilis: MessageDelegate {
                                 let complaintId = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
                                 if !complaintId.isEmpty {
                                     alert.dismiss(animated: true, completion: nil)
-                                    let idMe = UserDefaults.standard.string(forKey: "me")!
-                                    UserDefaults.standard.set("\(message.getBody(key: CoreMessage_TMessageKey.L_PIN)),\(idMe),\(complaintId)", forKey: "onGoingCC")
-                                    UserDefaults.standard.set("\(message.getBody(key: CoreMessage_TMessageKey.L_PIN))", forKey: "membersCC")
+                                    let idMe = User.getMyPin()!
+                                    SecureUserDefaults.shared.set("\(message.getBody(key: CoreMessage_TMessageKey.L_PIN)),\(idMe),\(complaintId)", forKey: "onGoingCC")
+                                    SecureUserDefaults.shared.set("\(message.getBody(key: CoreMessage_TMessageKey.L_PIN))", forKey: "membersCC")
                                     if message.getBody(key: CoreMessage_TMessageKey.CHANNEL) == "0" {
                                         let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
                                         editorPersonalVC.isContactCenter = true
@@ -2900,7 +2904,7 @@ extension Nexilis: MessageDelegate {
                                             UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
                                         }
                                     } else {
-                                        UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
+                                        SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
                                         DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                                             if message.getBody(key: CoreMessage_TMessageKey.CHANNEL) == "1" {
                                                 let pin = message.getBody(key: CoreMessage_TMessageKey.L_PIN)
@@ -3073,8 +3077,8 @@ extension Nexilis: MessageDelegate {
             let requester = message.getBody(key: CoreMessage_TMessageKey.UPLINE_PIN)
             let complaintId = message.getBody(key: CoreMessage_TMessageKey.DATA)
             if !requester.isEmpty {
-                UserDefaults.standard.set("\(requester),\(fPinContacCenter),\(complaintId)", forKey: "onGoingCC")
-                UserDefaults.standard.set("\(fPinContacCenter)", forKey: "membersCC")
+                SecureUserDefaults.shared.set("\(requester),\(fPinContacCenter),\(complaintId)", forKey: "onGoingCC")
+                SecureUserDefaults.shared.set("\(fPinContacCenter)", forKey: "membersCC")
             }
         } else if message.getCode() == CoreMessage_TMessageCode.INVITE_TO_ROOM_CONTACT_CENTER {
             if listCCIdInv.contains(message.getBody(key: CoreMessage_TMessageKey.CALL_CENTER_ID)) {
@@ -3241,13 +3245,13 @@ extension Nexilis: MessageDelegate {
                                 let officer = result.getBody(key: CoreMessage_TMessageKey.FRIEND_FPIN)
                                 let data = result.getBody(key: CoreMessage_TMessageKey.DATA)
                                 let complaintId = message.getBody(key: CoreMessage_TMessageKey.CALL_CENTER_ID)
-                                UserDefaults.standard.set("\(requester),\(officer),\(complaintId)", forKey: "onGoingCC")
-                                UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
+                                SecureUserDefaults.shared.set("\(requester),\(officer),\(complaintId)", forKey: "onGoingCC")
+                                SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
                                 if !data.isEmpty {
                                     if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
                                         var members = ""
                                         var user : [User] = []
-                                        let idMe = UserDefaults.standard.string(forKey: "me")!
+                                        let idMe = User.getMyPin()!
                                         for json in jsonArray {
                                             if "\(json)" != idMe {
                                                 if members.isEmpty {
@@ -3267,7 +3271,7 @@ extension Nexilis: MessageDelegate {
                                                 }
                                             }
                                         }
-                                        UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                                        SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                                         if message.getBody(key: CoreMessage_TMessageKey.CHANNEL) == "0" {
                                             let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
                                             editorPersonalVC.hidesBottomBarWhenPushed = true
@@ -3296,7 +3300,7 @@ extension Nexilis: MessageDelegate {
                                                 UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
                                             }
                                         } else {
-                                            UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
+                                            SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
                                             DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                                                 if message.getBody(key: CoreMessage_TMessageKey.CHANNEL) == "1" {
                                                     let pin = officer
@@ -3470,10 +3474,10 @@ extension Nexilis: MessageDelegate {
                 return
             }
             let sender = message.getBody(key: CoreMessage_TMessageKey.F_PIN)
-            let me = UserDefaults.standard.string(forKey: "me")!
+            let me = User.getMyPin()!
             if(sender != me) {
-                let inEditorPersonal = UserDefaults.standard.string(forKey: "inEditorPersonal")
-                let inEditorGroup = UserDefaults.standard.stringArray(forKey: "inEditorGroup")
+                let inEditorPersonal: String? = SecureUserDefaults.shared.value(forKey: "inEditorPersonal") ?? nil
+                let inEditorGroup: [String]? = SecureUserDefaults.shared.value(forKey: "inEditorGroup") ?? nil
                 var text = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_TEXT)
                 let imageId = CoreMessage_TMessageKey.IMAGE_ID
                 let videoId = CoreMessage_TMessageKey.VIDEO_ID
@@ -3513,7 +3517,7 @@ extension Nexilis: MessageDelegate {
                 var nameUser: String?
                 var profile = ""
                 var threadIdentifier = sender
-                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                 if !onGoingCC.isEmpty {
                     return
                 }
@@ -3689,10 +3693,10 @@ extension Nexilis: MessageDelegate {
                     }
                     
                     floating.show(queuePosition: .front, bannerPosition: .top, queue: NotificationBannerQueue(maxBannersOnScreenSimultaneously: 1), on: nil, edgeInsets: UIEdgeInsets(top: 8.0, left: 8.0, bottom: 0, right: 8.0), cornerRadius: 8.0, shadowColor: .clear, shadowOpacity: .zero, shadowBlurRadius: .zero, shadowCornerRadius: .zero, shadowOffset: .zero, shadowEdgeInsets: nil)
-                    let vibrateMode = UserDefaults.standard.bool(forKey: "vibrateMode")
-                    var soundId = UserDefaults.standard.string(forKey: "notifSoundPersonal") ?? ""
+                    let vibrateMode: Bool = SecureUserDefaults.shared.value(forKey: "vibrateMode") ?? false
+                    var soundId: String = SecureUserDefaults.shared.value(forKey: "notifSoundPersonal") ?? ""
                     if message.getBody(key: CoreMessage_TMessageKey.MESSAGE_SCOPE_ID) == "4" {
-                        soundId = UserDefaults.standard.string(forKey: "notifSoundGroup") ?? ""
+                        soundId = SecureUserDefaults.shared.value(forKey: "notifSoundGroup") ?? ""
                     }
                     var systemSoundID: SystemSoundID!
                     if soundId.isEmpty {
@@ -3740,8 +3744,8 @@ extension Nexilis: MessageDelegate {
                             floating.dismiss()
                         }
                         Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                            if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT first_name, last_name FROM BUDDY where f_pin = '\(UserDefaults.standard.string(forKey: "me")!)'"), cursorData.next() {
-                                if (cursorData.string(forColumnIndex: 0)! + " " + cursorData.string(forColumnIndex: 1)!).trimmingCharacters(in: .whitespaces) == "USR\(UserDefaults.standard.string(forKey: "me")!)" {
+                            if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT first_name, last_name FROM BUDDY where f_pin = '\(User.getMyPin()!)'"), cursorData.next() {
+                                if (cursorData.string(forColumnIndex: 0)! + " " + cursorData.string(forColumnIndex: 1)!).trimmingCharacters(in: .whitespaces) == "USR\(User.getMyPin()!)" {
                                     let alert = LibAlertController(title: "Change Profile".localized(), message: "You must change your name to use this feature".localized(), preferredStyle: .alert)
                                     alert.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {(_) in
                                         let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "signupsignin") as! SignUpSignIn

+ 385 - 131
appbuilder-ios/NexilisLite/NexilisLite/Source/Utils.swift

@@ -11,6 +11,7 @@ import UIKit
 import NotificationBannerSwift
 import nuSDKService
 import CoreLocation
+import CryptoKit
 //import var CommonCrypto.CC_MD5_DIGEST_LENGTH
 //import func CommonCrypto.CC_MD5
 //import typealias CommonCrypto.CC_LONG
@@ -44,221 +45,287 @@ public final class Utils {
     }
     
     public static func getForceAnonymous() -> Bool {
-        return UserDefaults.standard.bool(forKey: "force_anonymous")
+        if let value: Bool = SecureUserDefaults.shared.value(forKey: "force_anonymous") {
+            return value
+        }
+        return false
     }
     
     public static func setForceAnonymous(value: Bool){
-        UserDefaults.standard.set(value, forKey: "force_anonymous")
+        SecureUserDefaults.shared.set(value, forKey: "force_anonymous")
     }
     
     public static func getSetProfile() -> Bool {
-        return UserDefaults.standard.bool(forKey: "is_change_profile")
+        if let value: Bool = SecureUserDefaults.shared.value(forKey: "is_change_profile") {
+            return value
+        }
+        return false
     }
     
     public static func setProfile(value: Bool){
-        UserDefaults.standard.set(value, forKey: "is_change_profile")
+        SecureUserDefaults.shared.set(value, forKey: "is_change_profile")
     }
     
     static func setIconCenterAnim2(value: String){
-        UserDefaults.standard.set(value, forKey: "pb_fb_icon_center_self_mode2")
+        SecureUserDefaults.shared.set(value, forKey: "pb_fb_icon_center_self_mode2")
     }
     
     static func getIconCenterAnim2() -> String {
-        UserDefaults.standard.string(forKey: "pb_fb_icon_center_self_mode2") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "pb_fb_icon_center_self_mode2") {
+            return value
+        }
+        return ""
     }
     
     static func setIconCenterAnim4(value: String){
-        UserDefaults.standard.set(value, forKey: "pb_fb_icon_center_self_mode4")
+        SecureUserDefaults.shared.set(value, forKey: "pb_fb_icon_center_self_mode4")
     }
     
     static func getIconCenterAnim4() -> String {
-        UserDefaults.standard.string(forKey: "pb_fb_icon_center_self_mode4") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "pb_fb_icon_center_self_mode4") {
+            return value
+        }
+        return ""
     }
     
     static func setURLFirstTab(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_first_tab")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_first_tab")
     }
     
     static func setURLThirdTab(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_third_tab")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_third_tab")
     }
     
     static func setURLBase(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_base")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_base")
     }
     
     static func setURLQMS(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_qms")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_qms")
     }
     
     static func setIconDock(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_icon_dock")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_icon_dock")
     }
     
     static func setIconSS(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_icon_ss")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_icon_ss")
     }
     
     static func setBackground(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background")
     }
     
     static func setURLPrivacyPolicy(value: String){
-        UserDefaults.standard.set(value, forKey: "app_builder_url_privacy_policy")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_privacy_policy")
     }
     
     static func setEnablePrivacyPolicy(value: Bool){
-        UserDefaults.standard.set(value, forKey: "app_builder_enable_privacy_policy")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_enable_privacy_policy")
     }
     
     static func setCustomTab(cust: String){
-        UserDefaults.standard.set(cust, forKey: "custom_tab")
+        SecureUserDefaults.shared.set(cust, forKey: "custom_tab")
     }
     
     static func setACTheme(value: String){
-        UserDefaults.standard.set(value, forKey: "app_builder_ac_theme")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_ac_theme")
     }
     
     static func setButtonURL(value: String){
-        UserDefaults.standard.set(value, forKey: "app_builder_button_url")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_button_url")
     }
     
     static func setCustomButtons(value: String){
-        UserDefaults.standard.set(value, forKey: "app_builder_custom_buttons")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_custom_buttons")
     }
     
     public static func getCustomButtons() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_custom_buttons") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_custom_buttons") {
+            return value
+        }
+        return ""
     }
     
     static func setCustomFBIcon(value: String){
-        UserDefaults.standard.set(value, forKey: "app_builder_button_icon")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_button_icon")
     }
     
     static func getCustomFBIcon() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_button_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_button_icon") {
+            return value
+        }
+        return ""
     }
     
     static func setEnableMobileBuilder(value: String){
-        UserDefaults.standard.set(value, forKey: "app_builder_enable_mobile_builder")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_enable_mobile_builder")
     }
     public static func getEnableMobileBuilder() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_enable_mobile_builder") ?? "0"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_enable_mobile_builder") {
+            return value
+        }
+        return "0"
     }
     
     static func setFinishInitPrefs(value: Bool){
-        UserDefaults.standard.set(value, forKey: "finish_init_prefs")
+        SecureUserDefaults.shared.set(value, forKey: "finish_init_prefs")
     }
     
     public static func getFinishInitPrefsr() -> Bool {
-        UserDefaults.standard.bool(forKey: "finish_init_prefs")
+        if let value: Bool = SecureUserDefaults.shared.value(forKey: "finish_init_prefs") {
+            return value
+        }
+        return false
     }
     
     static func setConfigModeFB(value: String) {
-        UserDefaults.standard.set(value, forKey: "fb_config_mode")
+        SecureUserDefaults.shared.set(value, forKey: "fb_config_mode")
     }
     
     static func getConfigModeFB() -> String {
-        UserDefaults.standard.string(forKey: "fb_config_mode") ?? "1"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "fb_config_mode") {
+            return value
+        }
+        return "1"
     }
     
     static func setAfterConfigFB(value: Bool) {
-        UserDefaults.standard.set(value, forKey: "after_fb_config_mode")
+        SecureUserDefaults.shared.set(value, forKey: "after_fb_config_mode")
     }
     
     static func getAfterConfigFB() -> Bool {
-        UserDefaults.standard.bool(forKey: "after_fb_config_mode")
+        if let value: Bool = SecureUserDefaults.shared.value(forKey: "after_fb_config_mode") {
+            return value
+        }
+        return false
     }
     
     static func setCookiesMobile(value: String) {
-        UserDefaults.standard.set(value, forKey: "cookies_mobile")
+        SecureUserDefaults.shared.set(value, forKey: "cookies_mobile")
     }
 
     public static func getCookiesMobile() -> String {
-        UserDefaults.standard.string(forKey: "cookies_mobile") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "cookies_mobile") {
+            return value
+        }
+        return ""
     }
     
     static func getBackground() -> String {
-        return UserDefaults.standard.string(forKey: "app_builder_background") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background") {
+            return value
+        }
+        return ""
     }
     
     static func setBackgroundLight(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_light")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_light")
     }
 
     static func getBackgroundLight() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_light") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_light") {
+            return value
+        }
+        return ""
     }
     
     static func setBackgroundDark(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_dark")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_dark")
     }
 
     static func getBackgroundDark() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_dark") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_dark") {
+            return value
+        }
+        return ""
     }
     
     static func setMaxRetryUpload(value: String) {
-        UserDefaults.standard.set(value, forKey: "max_retry_upload")
+        SecureUserDefaults.shared.set(value, forKey: "max_retry_upload")
     }
 
     static func getMaxRetryUpload() -> String {
-        UserDefaults.standard.string(forKey: "max_retry_upload") ?? "5"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "max_retry_upload") {
+            return value
+        }
+        return "5"
     }
     
     static func setMaxRetryTimeUpload(value: String) {
-        UserDefaults.standard.set(value, forKey: "max_retry_time_upload")
+        SecureUserDefaults.shared.set(value, forKey: "max_retry_time_upload")
     }
 
     static func getMaxRetryTimeUpload() -> String {
-        UserDefaults.standard.string(forKey: "max_retry_time_upload") ?? "60000"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "max_retry_time_upload") {
+            return value
+        }
+        return "60000"
     }
     
     static func setWhatsappCenter(value: String) {
-        UserDefaults.standard.set(value, forKey: "whatsapp_center")
+        SecureUserDefaults.shared.set(value, forKey: "whatsapp_center")
     }
 
     static func getWhatsappCenter() -> String {
-        UserDefaults.standard.string(forKey: "whatsapp_center") ?? "08115881946"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "whatsapp_center") {
+            return value
+        }
+        return "08115881946"
     }
     
     static func setSMSCenter(value: String) {
-        UserDefaults.standard.set(value, forKey: "sms_center")
+        SecureUserDefaults.shared.set(value, forKey: "sms_center")
     }
 
     static func getSMSCenter() -> String {
-        UserDefaults.standard.string(forKey: "sms_center") ?? "081290009799"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "sms_center") {
+            return value
+        }
+        return "081290009799"
     }
     
     static func setCallCenter(value: String) {
-        UserDefaults.standard.set(value, forKey: "call_center")
+        SecureUserDefaults.shared.set(value, forKey: "call_center")
     }
 
     static func getCallCenter() -> String {
-        UserDefaults.standard.string(forKey: "call_center") ?? "1500046"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "call_center") {
+            return value
+        }
+        return "1500046"
     }
     
     static func setValidTrans(value: String) {
-        UserDefaults.standard.set(value, forKey: "enable_valid_trans")
+        SecureUserDefaults.shared.set(value, forKey: "enable_valid_trans")
     }
 
     static func getValidTrans() -> String {
-        UserDefaults.standard.string(forKey: "enable_valid_trans") ?? "0"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "enable_valid_trans") {
+            return value
+        }
+        return "0"
     }
     
     static func setFeatureAccess(value: String) {
-        UserDefaults.standard.set(value, forKey: "pb_feature_access")
+        SecureUserDefaults.shared.set(value, forKey: "pb_feature_access")
     }
 
     static func getFeatureAccess() -> String {
-        UserDefaults.standard.string(forKey: "pb_feature_access") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "pb_feature_access") {
+            return value
+        }
+        return ""
     }
     static func setChatbotGreetings(value: String) {
-        UserDefaults.standard.set(value, forKey: "chatbot_greetings")
+        SecureUserDefaults.shared.set(value, forKey: "chatbot_greetings")
     }
 
     static func getChatbotGreetings() -> String {
-        UserDefaults.standard.string(forKey: "chatbot_greetings") ?? "Welcome..."
+        if let value: String = SecureUserDefaults.shared.value(forKey: "chatbot_greetings") {
+            return value
+        }
+        return "Welcome..."
     }
     
     
@@ -333,11 +400,17 @@ public final class Utils {
     }
     
     static func getURLBase() -> String {
-        return UserDefaults.standard.string(forKey: "app_builder_url_base") ?? "https://nexilis.io/"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_url_base") {
+            return value
+        }
+        return "https://nexilis.io/"
     }
     
     static func getIconDock() -> String {
-        return UserDefaults.standard.string(forKey: "app_builder_icon_dock") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_icon_dock") {
+            return value
+        }
+        return ""
     }
     
     static func getUrlDock() -> String? {
@@ -345,67 +418,91 @@ public final class Utils {
     }
     
     static func setDefaultCC(value: String){
-        UserDefaults.standard.set(value, forKey: "default_cc")
+        SecureUserDefaults.shared.set(value, forKey: "default_cc")
     }
     
     static func getDefaultCC() -> String? {
-        return UserDefaults.standard.string(forKey: "default_cc")
+        if let value: String = SecureUserDefaults.shared.value(forKey: "default_cc") {
+            return value
+        }
+        return nil
     }
     
     static func setFloatingAnim(value: String){
-        UserDefaults.standard.set(value, forKey: "fb_floating_anim")
+        SecureUserDefaults.shared.set(value, forKey: "fb_floating_anim")
     }
     
     static func getFloatingAnim() -> String {
-        return UserDefaults.standard.string(forKey: "fb_floating_anim") ?? "1~1"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "fb_floating_anim") {
+            return value
+        }
+        return "1~1"
     }
     
     static func setFBIconBg(value: String){
-        UserDefaults.standard.set(value, forKey: "fb_icon_with_bg")
+        SecureUserDefaults.shared.set(value, forKey: "fb_icon_with_bg")
     }
     
     static func getFBIconBg() -> String {
-        return UserDefaults.standard.string(forKey: "fb_icon_with_bg") ?? "1"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "fb_icon_with_bg") {
+            return value
+        }
+        return "1"
     }
     
     static func setFBItemBg(value: String){
-        UserDefaults.standard.set(value, forKey: "fb_item_with_bg")
+        SecureUserDefaults.shared.set(value, forKey: "fb_item_with_bg")
     }
     
     static func getFBItemBg() -> String {
-        return UserDefaults.standard.string(forKey: "fb_item_with_bg") ?? "1"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "fb_item_with_bg") {
+            return value
+        }
+        return "1"
     }
     
     static func setDomainOpr(value: String){
-        UserDefaults.standard.set(value, forKey: "domain_opr")
+        SecureUserDefaults.shared.set(value, forKey: "domain_opr")
     }
     
     static func getDomainOpr() -> String {
-        return UserDefaults.standard.string(forKey: "domain_opr") ?? "https://nexilis.io/"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "domain_opr") {
+            return value
+        }
+        return "https://nexilis.io/"
     }
     
     static func setIpPortOpr(value: String){
-        UserDefaults.standard.set(value, forKey: "ip_opr")
+        SecureUserDefaults.shared.set(value, forKey: "ip_opr")
     }
     
     static func getIpOpr() -> String {
-        return UserDefaults.standard.string(forKey: "ip_opr") ?? "34.101.172.194:42823"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "ip_opr") {
+            return value
+        }
+        return "34.101.172.194:42823"
     }
     
     static func setHarcodedIp(value: String){
-        UserDefaults.standard.set(value, forKey: "harcoded_ip")
+        SecureUserDefaults.shared.set(value, forKey: "harcoded_ip")
     }
     
     static func getHarcodedIp() -> String {
-        return UserDefaults.standard.string(forKey: "harcoded_ip") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "harcoded_ip") {
+            return value
+        }
+        return ""
     }
     
     static func setUserAgent(value: String){
-        UserDefaults.standard.set(value, forKey: "user_agent")
+        SecureUserDefaults.shared.set(value, forKey: "user_agent")
     }
     
     public static func getUserAgent() -> String {
-        return UserDefaults.standard.string(forKey: "user_agent") ?? "easySoftIndonesia"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "user_agent") {
+            return value
+        }
+        return "easySoftIndonesia"
     }
     
     public static func fetchDataWithCookiesAndUserAgent(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
@@ -422,9 +519,11 @@ public final class Utils {
     }
     
     public static func postDataWithCookiesAndUserAgent(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
+        let apiKey: String = SecureUserDefaults.shared.value(forKey: "apiKey") ?? ""
+        let f_pin: String = User.getMyPin() ?? ""
         let parameters = [
-            "apikey": UserDefaults.standard.string(forKey: "apiKey") ?? "",
-            "f_pin": UserDefaults.standard.string(forKey: "me") ?? ""
+            "apikey": apiKey,
+            "f_pin": f_pin
         ]
         var jsonArray: [[String: Any]] = []
         jsonArray.append(parameters)
@@ -798,169 +897,283 @@ public final class Utils {
     public static let ERR84 = "84:Feature Disabled".localized()
     
     public static func setConnectionID(value: String) {
-        UserDefaults.standard.set(value, forKey: "connection_id")
+        SecureUserDefaults.shared.set(value, forKey: "connection_id")
     }
 
     public static func getConnectionID() -> String {
-        UserDefaults.standard.string(forKey: "connection_id") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "connection_id") {
+            return value
+        }
+        return ""
     }
     
     public static func setLimitValidTrans(value: String) {
-        UserDefaults.standard.set(value, forKey: "pb_set_valid_trans")
+        SecureUserDefaults.shared.set(value, forKey: "pb_set_valid_trans")
     }
 
     public static func getLimitValidTrans() -> String {
-        UserDefaults.standard.string(forKey: "pb_set_valid_trans") ?? "100000"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "pb_set_valid_trans") {
+            return value
+        }
+        return "100000"
     }
     
     public static func setLoginMultipleFPin(value: String) {
-        UserDefaults.standard.set(value, forKey: "pb_login_multiple_f_pin")
+        SecureUserDefaults.shared.set(value, forKey: "pb_login_multiple_f_pin")
     }
 
     public static func getLoginMultipleFPin() -> String {
-        UserDefaults.standard.string(forKey: "pb_login_multiple_f_pin") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "pb_login_multiple_f_pin") {
+            return value
+        }
+        return ""
     }
     
     public static func setPrefTheme(value: String) {
-        UserDefaults.standard.set(value, forKey: "first_pref_theme")
+        SecureUserDefaults.shared.set(value, forKey: "first_pref_theme")
     }
     public static func getPrefTheme() -> String {
-        UserDefaults.standard.string(forKey: "first_pref_theme") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "first_pref_theme") {
+            return value
+        }
+        return ""
     }
     public static func setMyTheme(value: String) {
-        UserDefaults.standard.set(value, forKey: "my_theme")
+        SecureUserDefaults.shared.set(value, forKey: "my_theme")
     }
     public static func getMyTheme() -> String {
-        UserDefaults.standard.string(forKey: "my_theme") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "my_theme") {
+            return value
+        }
+        return ""
     }
     public static func setIsLoadThemeFromOther(value: Bool) {
-        UserDefaults.standard.set(value, forKey: "load_theme_from_other")
+        SecureUserDefaults.shared.set(value, forKey: "load_theme_from_other")
     }
     public static func getIsLoadThemeFromOther() -> Bool {
-        UserDefaults.standard.bool(forKey: "load_theme_from_other")
+        if let value: Bool = SecureUserDefaults.shared.value(forKey: "load_theme_from_other") {
+            return value
+        }
+        return false
     }
     public static func setURLWv3(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_webview_3")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_webview_3")
     }
     public static func getURLWv3() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_url_webview_3") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_url_webview_3") {
+            return value
+        }
+        return ""
     }
     public static func setURLWv4(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_webview_4")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_webview_4")
     }
     public static func getURLWv4() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_url_webview_4") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_url_webview_4") {
+            return value
+        }
+        return ""
     }
     public static func setURLWv5(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_webview_5")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_webview_5")
     }
     public static func getURLWv5() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_url_webview_5") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_url_webview_5") {
+            return value
+        }
+        return ""
     }
     public static func setURLWv6(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_url_webview_6")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_url_webview_6")
     }
     public static func getURLWv6() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_url_webview_6") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_url_webview_6") {
+            return value
+        }
+        return ""
     }
     public static func setBackgroundTab1(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_1")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_1")
     }
     public static func getBackgroundTab1() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_1") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_1") {
+            return value
+        }
+        return ""
     }
     public static func setBackgroundTab2(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_2")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_2")
     }
     public static func getBackgroundTab2() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_2") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_2") {
+            return value
+        }
+        return ""
     }
     public static func setBackgroundTab3(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_3")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_3")
     }
     public static func getBackgroundTab3() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_3") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_3") {
+            return value
+        }
+        return ""
     }
     public static func setBackgroundTab4(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_4")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_4")
     }
     public static func getBackgroundTab4() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_4") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_4") {
+            return value
+        }
+        return ""
     }
     public static func setBackgroundTab5(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_5")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_5")
     }
     public static func getBackgroundTab5() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_5") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_5") {
+            return value
+        }
+        return ""
     }
     public static func setBackgroundTab6(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_background_6")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_background_6")
     }
     public static func getBackgroundTab6() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_background_6") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_background_6") {
+            return value
+        }
+        return ""
     }
     public static func setCpaasMode(mode: Int){
-        UserDefaults.standard.set(mode+1, forKey: "cpaas_mode")
+        SecureUserDefaults.shared.set(mode+1, forKey: "cpaas_mode")
     }
     public static func setTab1Icon(value: String) {
-        UserDefaults.standard.set(value, forKey: "tab1_icon")
+        SecureUserDefaults.shared.set(value, forKey: "tab1_icon")
     }
     public static func getTab1Icon() -> String {
-        UserDefaults.standard.string(forKey: "tab1_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "tab1_icon") {
+            return value
+        }
+        return ""
     }
     public static func setTab2Icon(value: String) {
-        UserDefaults.standard.set(value, forKey: "tab2_icon")
+        SecureUserDefaults.shared.set(value, forKey: "tab2_icon")
     }
     public static func getTab2Icon() -> String {
-        UserDefaults.standard.string(forKey: "tab2_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "tab2_icon") {
+            return value
+        }
+        return ""
     }
     public static func setTab3Icon(value: String) {
-        UserDefaults.standard.set(value, forKey: "tab3_icon")
+        SecureUserDefaults.shared.set(value, forKey: "tab3_icon")
     }
     public static func getTab3Icon() -> String {
-        UserDefaults.standard.string(forKey: "tab3_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "tab3_icon") {
+            return value
+        }
+        return ""
     }
     public static func setTab4Icon(value: String) {
-        UserDefaults.standard.set(value, forKey: "tab4_icon")
+        SecureUserDefaults.shared.set(value, forKey: "tab4_icon")
     }
     public static func getTab4Icon() -> String {
-        UserDefaults.standard.string(forKey: "tab4_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "tab4_icon") {
+            return value
+        }
+        return ""
     }
     public static func setTab5Icon(value: String) {
-        UserDefaults.standard.set(value, forKey: "tab5_icon")
+        SecureUserDefaults.shared.set(value, forKey: "tab5_icon")
     }
     public static func getTab5Icon() -> String {
-        UserDefaults.standard.string(forKey: "tab5_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "tab5_icon") {
+            return value
+        }
+        return ""
     }
     public static func setTab6Icon(value: String) {
-        UserDefaults.standard.set(value, forKey: "tab6_icon")
+        SecureUserDefaults.shared.set(value, forKey: "tab6_icon")
     }
     public static func getTab6Icon() -> String {
-        UserDefaults.standard.string(forKey: "tab6_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "tab6_icon") {
+            return value
+        }
+        return ""
     }
     public static func setButtonIcon(value: String) {
-        UserDefaults.standard.set(value, forKey: "app_builder_button_icon")
+        SecureUserDefaults.shared.set(value, forKey: "app_builder_button_icon")
     }
     public static func getButtonIcon() -> String {
-        UserDefaults.standard.string(forKey: "app_builder_button_icon") ?? ""
+        if let value: String = SecureUserDefaults.shared.value(forKey: "app_builder_button_icon") {
+            return value
+        }
+        return ""
     }
     public static func setReverseTab(value: String) {
-        UserDefaults.standard.set(value, forKey: "reverse_tab_color")
+        SecureUserDefaults.shared.set(value, forKey: "reverse_tab_color")
     }
     public static func getReverseTab() -> String {
-        UserDefaults.standard.string(forKey: "reverse_tab_color") ?? "0"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "reverse_tab_color") {
+            return value
+        }
+        return "0"
     }
     public static func setIconDockSize(value: String) {
-        UserDefaults.standard.set(value, forKey: "icon_size")
+        SecureUserDefaults.shared.set(value, forKey: "icon_size")
     }
     public static func getIconDockSize() -> String {
-        UserDefaults.standard.string(forKey: "icon_size") ?? "0"
+        if let value: String = SecureUserDefaults.shared.value(forKey: "icon_size") {
+            return value
+        }
+        return "0"
     }
     static func setDebugBC(value: [String: String]) {
-        UserDefaults.standard.set(value, forKey: "debugBc")
+        SecureUserDefaults.shared.set(value, forKey: "debugBc")
     }
     static func getDebugBC() -> [String: String]? {
-        UserDefaults.standard.object(forKey: "debugBc") as? [String : String]
+        if let value: [String: String] = SecureUserDefaults.shared.value(forKey: "debugBc") {
+            return value
+        }
+        return nil
+    }
+    
+    public static func setPassEncDB(value: String) {
+        SecureUserDefaults.shared.set(value, forKey: "pb_db_encrypt_pass")
+    }
+    public static func getPassEncDB() -> String {
+        if let value: String = SecureUserDefaults.shared.value(forKey: "pb_db_encrypt_pass") {
+            return value
+        }
+        return ""
+    }
+    
+    static func getPasswordDB() -> String? {
+        do {
+            let p = getPassEncDB()
+            if p.isEmpty {
+                var keyData = Data(count: 32) // 256-bit key
+                let result = keyData.withUnsafeMutableBytes {
+                    SecRandomCopyBytes(kSecRandomDefault, 32, $0.baseAddress!)
+                }
+                if result == errSecSuccess {
+                    let encrypt = try MasterKeyUtil.shared.encryptD(data: keyData)
+                    setPassEncDB(value: encrypt.base64EncodedString())
+                    return keyData.base64EncodedString()
+                    
+                } else {
+                    print("Error generating random bytes: \(result)")
+                    return nil
+                }
+            }
+            
+            let decrypt = try MasterKeyUtil.shared.decryptD(data: Data(base64Encoded: p)!)
+            return decrypt.base64EncodedString()
+        } catch {
+            return nil
+        }
     }
 }
 public extension UIImage {
@@ -1564,9 +1777,9 @@ public class DialogVerifyYou: UIViewController {
                     if(!fPin.isEmpty) {
 //                            Nexilis.changeUser(f_pin: device_id)
                         Utils.setLoginMultipleFPin(value: "")
-                        UserDefaults.standard.setValue(device_id, forKey: "device_id")
+                        SecureUserDefaults.shared.set(device_id, forKey: "device_id")
                         Utils.setProfile(value: true)
-                        UserDefaults.standard.synchronize()
+                        SecureUserDefaults.shared.sync()
                         // pos registration
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: fPin))
                         DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
@@ -1667,7 +1880,7 @@ public class DialogSignIn: UIViewController {
         container.addSubview(imageChat)
         imageChat.anchor(top: container.topAnchor, right: container.rightAnchor, paddingTop: 10, paddingRight: 20, width: 30, height: 30)
         
-        let lang = UserDefaults.standard.string(forKey: "i18n_language")
+        let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
         let sContent1 = "We detected a new Sign-In to your Account".localized()
         let sContent2 = "Device".localized()
         let sContent3 = "Time".localized()
@@ -2234,3 +2447,44 @@ class LocationManager: NSObject, CLLocationManagerDelegate {
         //print("Failed to find user's location: \(error.localizedDescription)")
     }
 }
+
+public class SecureUserDefaults {
+    static let shared = SecureUserDefaults()
+    private let defaults: UserDefaults
+
+    init(defaults: UserDefaults = .standard) {
+        self.defaults = defaults
+    }
+
+    // Save a value
+    func set<T: Codable>(_ value: T, forKey key: String) {
+        let encoder = JSONEncoder()
+        guard let encodedData = try? encoder.encode(value),
+              let encryptedData = try? MasterKeyUtil.shared.encryptP(data: encodedData) else {
+//            print("Failed to encrypt data")
+            return
+        }
+        defaults.set(encryptedData, forKey: key)
+    }
+
+    // Retrieve a value
+    func value<T: Codable>(forKey key: String) -> T? {
+        guard let encryptedData = defaults.data(forKey: key),
+              let decryptedData = try? MasterKeyUtil.shared.decryptP(data: encryptedData) else {
+//            print("Failed to decrypt data \(key)")
+            return nil
+        }
+        let decoder = JSONDecoder()
+        return try? decoder.decode(T.self, from: decryptedData)
+    }
+
+    // Remove a value
+    func removeValue(forKey key: String) {
+        defaults.removeObject(forKey: key)
+    }
+    
+    func sync() {
+        defaults.synchronize()
+    }
+}
+

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/BNIView/BNIBookingWebView.swift

@@ -100,7 +100,7 @@ public class BNIBookingWebView: UIViewController, WKNavigationDelegate, UIScroll
         if stringQMS.contains("<<f_pin>>") {
             stringQMS = stringQMS.replacingOccurrences(of: "<<f_pin>>", with: User.getMyPin()!)
         }
-        let lang = UserDefaults.standard.string(forKey: "i18n_language")
+        let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
         var intLang = 0
         if lang == "id" {
             intLang = 1
@@ -459,7 +459,7 @@ public class BNIBookingWebView: UIViewController, WKNavigationDelegate, UIScroll
             OperationQueue.main.addOperation() {
                 self.isAllowSpeech = isButtonEnabled
                 if isButtonEnabled {
-                    UserDefaults.standard.set(isButtonEnabled, forKey: "allowSpeech")
+                    SecureUserDefaults.shared.set(isButtonEnabled, forKey: "allowSpeech")
                     self.runVoice()
                 }
             }

+ 23 - 27
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioConference.swift

@@ -193,11 +193,11 @@ class QmeraAudioConference: UIViewController {
         NotificationCenter.default.addObserver(self, selector: #selector(onReceiveMessage(notification:)), name: NSNotification.Name(rawValue: Nexilis.listenerReceiveChat), object: nil)
         
         if isOutgoing {
-            users.append(User.getData(pin: UserDefaults.standard.string(forKey: "me")!)!)
+            users.append(User.getData(pin: User.getMyPin()!)!)
             API.initiateCR(sConfRoom: roomId)
             outgoingView()
         } else {
-            users.append(User.getData(pin: UserDefaults.standard.string(forKey: "me")!)!)
+            users.append(User.getData(pin: User.getMyPin()!)!)
             API.joinCR(sConfRoom: roomId)
             ongoingView()
         }
@@ -290,7 +290,7 @@ class QmeraAudioConference: UIViewController {
     @objc func didInvite(sender: Any?) {
         let controller = QmeraCallContactViewController()
         controller.isDismiss = { user in
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 DispatchQueue.global().async {
                     _ = Nexilis.write(message: CoreMessage_TMessageBank.getCCRoomInvite(l_pin: user.pin, ticket_id: onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2], channel: "1"))
@@ -309,14 +309,14 @@ class QmeraAudioConference: UIViewController {
     }
     
     @objc func didEnd(sender: Any?) {
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
         if !onGoingCC.isEmpty {
             if sender != nil && sender is Bool {
                 self.dismiss(animated: false, completion: nil)
                 let requester = onGoingCC.components(separatedBy: ",")[0]
                 let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                 let complaintId = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2]
-                let startTimeCC = UserDefaults.standard.string(forKey: "startTimeCC") ?? ""
+                let startTimeCC: String = SecureUserDefaults.shared.value(forKey: "startTimeCC") ?? ""
                 DispatchQueue.global().async {
                     let date = "\(Date().currentTimeMillis())"
                     Database.shared.database?.inTransaction({ (fmdb, rollback) in
@@ -337,10 +337,10 @@ class QmeraAudioConference: UIViewController {
                             //print(error)
                         }
                     })
-                    UserDefaults.standard.removeObject(forKey: "onGoingCC")
-                    UserDefaults.standard.removeObject(forKey: "membersCC")
-                    UserDefaults.standard.removeObject(forKey: "startTimeCC")
-                    UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "startTimeCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                 }
                 return
             }
@@ -351,8 +351,8 @@ class QmeraAudioConference: UIViewController {
                 let requester = onGoingCC.components(separatedBy: ",")[0]
                 let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                 let complaintId = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2]
-                let idMe = UserDefaults.standard.string(forKey: "me")!
-                let startTimeCC = UserDefaults.standard.string(forKey: "startTimeCC") ?? ""
+                let idMe = User.getMyPin()!
+                let startTimeCC: String = SecureUserDefaults.shared.value(forKey: "startTimeCC") ?? ""
                 DispatchQueue.global().async {
                     let date = "\(Date().currentTimeMillis())"
                     Database.shared.database?.inTransaction({ (fmdb, rollback) in
@@ -378,10 +378,10 @@ class QmeraAudioConference: UIViewController {
                     } else {
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.endCallCenter(complaint_id: complaintId, l_pin: requester))
                     }
-                    UserDefaults.standard.removeObject(forKey: "onGoingCC")
-                    UserDefaults.standard.removeObject(forKey: "membersCC")
-                    UserDefaults.standard.removeObject(forKey: "startTimeCC")
-                    UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "startTimeCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                 }
 //                if let user = self.user, let call = Nexilis.shared.callManager.call(with: user.pin) {
 //                    Nexilis.shared.callManager.end(call: call)
@@ -422,7 +422,7 @@ class QmeraAudioConference: UIViewController {
                     if !data.isEmpty {
                         if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
                             var members = ""
-                            let idMe = UserDefaults.standard.string(forKey: "me")!
+                            let idMe = User.getMyPin()!
                             for json in jsonArray {
                                 if "\(json)" != idMe {
                                     if members.isEmpty {
@@ -432,7 +432,7 @@ class QmeraAudioConference: UIViewController {
                                     }
                                 }
                             }
-                            UserDefaults.standard.set(members, forKey: "inEditorPersonal")
+                            SecureUserDefaults.shared.set(members, forKey: "inEditorPersonal")
                         }
                     }
                     self.users.append(User.getData(pin: dataMessage.getPIN())!)
@@ -444,12 +444,12 @@ class QmeraAudioConference: UIViewController {
     private func checkParticipant(fPin: String) {
         if let user = User.getData(pin: fPin), !self.users.contains(user) {
             self.users.append(user)
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 DispatchQueue.main.async {
                     var members = ""
                     for user in self.users {
-                        if user.pin == UserDefaults.standard.string(forKey: "me")! {
+                        if user.pin == User.getMyPin()! {
                             continue
                         } else if members.isEmpty {
                             members = "\(user.pin)"
@@ -457,7 +457,7 @@ class QmeraAudioConference: UIViewController {
                             members = ",\(user.pin)"
                         }
                     }
-                    UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                    SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                 }
             }
         }
@@ -523,7 +523,6 @@ class QmeraAudioConference: UIViewController {
 //                }
 //                if (!isOutgoing || !firstCall), users.count >= 1, let user = User.getData(pin: String(arrayMessage[1])), !users.contains(user) {
 //                    self.users.append(user)
-//                    let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
 //                    if !onGoingCC.isEmpty {
 //                        DispatchQueue.main.async {
 //                            var members = ""
@@ -534,12 +533,11 @@ class QmeraAudioConference: UIViewController {
 //                                    members = ",\(user.pin)"
 //                                }
 //                            }
-//                            UserDefaults.standard.set("\(members)", forKey: "membersCC")
+//                            SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
 //                        }
 //                    }
 //                }
 //            } else if state == Nexilis.AUDIO_CALL_END {
-//                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
 //                if let pin = arrayMessage.first, let index = users.firstIndex(of: User(pin: String(pin))) {
 //                    users.remove(at: index)
 //                    if !onGoingCC.isEmpty && users.count != 0 {
@@ -576,7 +574,6 @@ class QmeraAudioConference: UIViewController {
 //                    }
 //                }
 //            } else if state == Nexilis.OFFLINE { // Offline
-//                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
 //                if let pin = arrayMessage.first, let index = users.firstIndex(of: User(pin: String(pin))) {
 //                    users.remove(at: index)
 //                    if !onGoingCC.isEmpty && users.count != 0 {
@@ -589,7 +586,7 @@ class QmeraAudioConference: UIViewController {
 //                                    members = ",\(user.pin)"
 //                                }
 //                            }
-//                            UserDefaults.standard.set("\(members)", forKey: "membersCC")
+//                            SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
 //                        }
 //                    }
 //                }
@@ -603,7 +600,6 @@ class QmeraAudioConference: UIViewController {
 //                    }
 //                }
 //            } else if state == Nexilis.BUSY { // Busy
-//                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
 //                if let pin = arrayMessage.first, let index = users.firstIndex(of: User(pin: String(pin))) {
 //                    users.remove(at: index)
 //                    if !onGoingCC.isEmpty && users.count != 0 {
@@ -616,7 +612,7 @@ class QmeraAudioConference: UIViewController {
 //                                    members = ",\(user.pin)"
 //                                }
 //                            }
-//                            UserDefaults.standard.set("\(members)", forKey: "membersCC")
+//                            SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
 //                        }
 //                    }
 //                }

+ 30 - 31
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioViewController.swift

@@ -276,7 +276,6 @@ class QmeraAudioViewController: UIViewController {
         if let u = self.user {
             self.users.append(u)
             if isOutgoing && ticketId.isEmpty {
-//                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
 //                if onGoingCC.isEmpty {
 //                    Nexilis.shared.callManager.startCall(handle: u.pin)
 //                } else {
@@ -460,8 +459,8 @@ class QmeraAudioViewController: UIViewController {
     // MARK: - Action
     
     @objc func didTapChatButton(){
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
-        let members = UserDefaults.standard.string(forKey: "membersCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
+        let members: String = SecureUserDefaults.shared.value(forKey: "membersCC") ?? ""
         let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
         let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
         editorPersonalVC.hidesBottomBarWhenPushed = true
@@ -496,7 +495,7 @@ class QmeraAudioViewController: UIViewController {
         if(wbVC == nil){
             wbVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as? WhiteboardViewController
             if(wbRoomId.isEmpty){
-                let me = UserDefaults.standard.string(forKey: "me")!
+                let me = User.getMyPin()!
                 let tid = CoreMessage_TMessageUtil.getTID()
                 wbRoomId = "\(me)wbvc\(tid)"
                 wbVC!.roomId = wbRoomId
@@ -512,7 +511,7 @@ class QmeraAudioViewController: UIViewController {
                 }
                 wbVC!.destinations = destinations
                 wbVC!.sendInit()
-                UserDefaults.standard.set("\(me),\(destString)", forKey: "wb_vc")
+                SecureUserDefaults.shared.set("\(me),\(destString)", forKey: "wb_vc")
             }
             else {
                 self.wbTimer.invalidate()
@@ -573,7 +572,7 @@ class QmeraAudioViewController: UIViewController {
     @objc func didInvite(sender: Any?) {
         let controller = QmeraCallContactViewController()
         controller.isDismiss = { user in
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 DispatchQueue.global().async {
                     _ = Nexilis.write(message: CoreMessage_TMessageBank.getCCRoomInvite(l_pin: user.pin, ticket_id: onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2], channel: "1"))
@@ -593,7 +592,7 @@ class QmeraAudioViewController: UIViewController {
     }
     
     @objc func didPressEnd(sender: Any?) {
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
         if !onGoingCC.isEmpty {
             self.isEndByMe = true
             self.didEnd(sender: nil)
@@ -624,7 +623,7 @@ class QmeraAudioViewController: UIViewController {
             self.buttonChat.removeFromSuperview()
         }
         poweredByView.isHidden = true
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
         if !onGoingCC.isEmpty {
             if sender != nil && sender is Bool {
                 let controller = self.presentedViewController
@@ -635,7 +634,7 @@ class QmeraAudioViewController: UIViewController {
                 let requester = onGoingCC.components(separatedBy: ",")[0]
                 let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                 let complaintId = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2]
-                let startTimeCC = UserDefaults.standard.string(forKey: "startTimeCC") ?? ""
+                let startTimeCC: String = SecureUserDefaults.shared.value(forKey: "startTimeCC") ?? ""
                 DispatchQueue.global().async {
                     if sender as! Bool == true {
                         let date = "\(Date().currentTimeMillis())"
@@ -658,10 +657,10 @@ class QmeraAudioViewController: UIViewController {
                             }
                         })
                     }
-                    UserDefaults.standard.removeObject(forKey: "onGoingCC")
-                    UserDefaults.standard.removeObject(forKey: "membersCC")
-                    UserDefaults.standard.removeObject(forKey: "startTimeCC")
-                    UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "startTimeCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                 }
                 return
             }
@@ -672,8 +671,8 @@ class QmeraAudioViewController: UIViewController {
                 let requester = onGoingCC.components(separatedBy: ",")[0]
                 let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                 let complaintId = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2]
-                let idMe = UserDefaults.standard.string(forKey: "me")!
-                let startTimeCC = UserDefaults.standard.string(forKey: "startTimeCC") ?? ""
+                let idMe = User.getMyPin()!
+                let startTimeCC: String = SecureUserDefaults.shared.value(forKey: "startTimeCC") ?? ""
                 DispatchQueue.global().async {
                     let date = "\(Date().currentTimeMillis())"
                     Database.shared.database?.inTransaction({ (fmdb, rollback) in
@@ -703,10 +702,10 @@ class QmeraAudioViewController: UIViewController {
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.leaveCCRoomInvite(ticket_id: complaintId))
                         }
                     }
-                    UserDefaults.standard.removeObject(forKey: "onGoingCC")
-                    UserDefaults.standard.removeObject(forKey: "membersCC")
-                    UserDefaults.standard.removeObject(forKey: "startTimeCC")
-                    UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "startTimeCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                 }
 //                if let user = self.user, let call = Nexilis.shared.callManager.call(with: user.pin) {
 //                    Nexilis.shared.callManager.end(call: call)
@@ -776,7 +775,7 @@ class QmeraAudioViewController: UIViewController {
                     if !data.isEmpty {
                         if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
                             var members = ""
-                            let idMe = UserDefaults.standard.string(forKey: "me")!
+                            let idMe = User.getMyPin()!
                             for json in jsonArray {
                                 if "\(json)" != idMe {
                                     if members.isEmpty {
@@ -786,7 +785,7 @@ class QmeraAudioViewController: UIViewController {
                                     }
                                 }
                             }
-                            UserDefaults.standard.set(members, forKey: "inEditorPersonal")
+                            SecureUserDefaults.shared.set(members, forKey: "inEditorPersonal")
                         }
                     }
                     self.users.append(User.getData(pin: dataMessage.getPIN())!)
@@ -837,7 +836,7 @@ class QmeraAudioViewController: UIViewController {
                 }
                 if (!isOutgoing || !firstCall), users.count >= 1, let user = User.getData(pin: String(arrayMessage[1])), !users.contains(user) {
                     self.users.append(user)
-                    let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                    let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                     if !onGoingCC.isEmpty {
                         DispatchQueue.main.async {
                             var members = ""
@@ -848,7 +847,7 @@ class QmeraAudioViewController: UIViewController {
                                     members = ",\(user.pin)"
                                 }
                             }
-                            UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                            SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                         }
                     }
                 }
@@ -858,7 +857,7 @@ class QmeraAudioViewController: UIViewController {
                 } else {
                     Nexilis.ringtonePlayer?.stop()
                 }
-                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                 if let pin = arrayMessage.first, let index = users.firstIndex(of: User(pin: String(pin))) {
                     users.remove(at: index)
                     if !onGoingCC.isEmpty && users.count != 0 {
@@ -929,7 +928,7 @@ class QmeraAudioViewController: UIViewController {
                 } else {
                     Nexilis.ringtonePlayer?.stop()
                 }
-                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                 if let pin = arrayMessage.first, let index = users.firstIndex(of: User(pin: String(pin))) {
                     users.remove(at: index)
                     if !onGoingCC.isEmpty && users.count != 0 {
@@ -942,7 +941,7 @@ class QmeraAudioViewController: UIViewController {
                                     members = ",\(user.pin)"
                                 }
                             }
-                            UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                            SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                         }
                     }
                 }
@@ -961,7 +960,7 @@ class QmeraAudioViewController: UIViewController {
                 } else {
                     Nexilis.ringtonePlayer?.stop()
                 }
-                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                 if let pin = arrayMessage.first, let index = users.firstIndex(of: User(pin: String(pin))) {
                     users.remove(at: index)
                     if !onGoingCC.isEmpty && users.count != 0 {
@@ -974,7 +973,7 @@ class QmeraAudioViewController: UIViewController {
                                     members = ",\(user.pin)"
                                 }
                             }
-                            UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                            SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                         }
                     }
                 }
@@ -1003,7 +1002,7 @@ extension QmeraAudioViewController : WhiteboardReceiver {
             DispatchQueue.main.async {
                 self.wbTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runTimer), userInfo: nil, repeats: true)
             }
-            let me = UserDefaults.standard.string(forKey: "me")!
+            let me = User.getMyPin()!
             var destString = ""
             for d in users{
                 if d.pin == roomId.components(separatedBy: "wbvc")[0] {
@@ -1016,9 +1015,9 @@ extension QmeraAudioViewController : WhiteboardReceiver {
                 }
             }
             if destString.isEmpty {
-                UserDefaults.standard.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me)", forKey: "wb_vc")
+                SecureUserDefaults.shared.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me)", forKey: "wb_vc")
             } else {
-                UserDefaults.standard.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me),\(destString)", forKey: "wb_vc")
+                SecureUserDefaults.shared.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me),\(destString)", forKey: "wb_vc")
             }
             wbRoomId = roomId
         }

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraCallContactViewController.swift

@@ -95,9 +95,9 @@ class QmeraCallContactViewController: UITableViewController {
     private func getContacts(completion: @escaping ([User]) -> ()) {
         var contacts: [User] = []
         DispatchQueue.global().async {
-            var query = "SELECT f_pin, first_name, last_name, image_id, user_type, official_account, ex_offmp FROM BUDDY where f_pin <> '\(UserDefaults.standard.string(forKey: "me")!)' and official_account<>'1' order by 2 collate nocase asc"
+            var query = "SELECT f_pin, first_name, last_name, image_id, user_type, official_account, ex_offmp FROM BUDDY where f_pin <> '\(User.getMyPin()!)' and official_account<>'1' order by 2 collate nocase asc"
             if self.listFriends {
-                query = "SELECT f_pin, first_name, last_name, image_id, user_type, official_account, ex_offmp FROM BUDDY where f_pin <> '\(UserDefaults.standard.string(forKey: "me")!)' order by 2 collate nocase asc"
+                query = "SELECT f_pin, first_name, last_name, image_id, user_type, official_account, ex_offmp FROM BUDDY where f_pin <> '\(User.getMyPin()!)' order by 2 collate nocase asc"
             }
             Database.shared.database?.inTransaction({ (fmdb, rollback) in
                 if let cursor = Database.shared.getRecords(fmdb: fmdb, query: query) {

+ 24 - 24
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift

@@ -309,7 +309,7 @@ class QmeraVideoViewController: UIViewController {
             myImage.setImage(name: image)
             myImage.contentMode = .scaleAspectFill
         }
-//        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//        let idMe = User.getMyPin() as String?
 //        Database().database?.inTransaction({ fmdb, rollback in
 //            if let c = Database().getRecords(fmdb: fmdb, query: "select image_id from BUDDY where f_pin = '\(idMe!)'"), c.next() {
 //                let image = c.string(forColumnIndex: 0)!
@@ -482,7 +482,7 @@ class QmeraVideoViewController: UIViewController {
                     if !data.isEmpty {
                         if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
                             var members = ""
-                            let idMe = UserDefaults.standard.string(forKey: "me")!
+                            let idMe = User.getMyPin()!
                             for json in jsonArray {
                                 if "\(json)" != idMe {
                                     if members.isEmpty {
@@ -492,7 +492,7 @@ class QmeraVideoViewController: UIViewController {
                                     }
                                 }
                             }
-                            UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                            SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                         }
                     }
                 }
@@ -501,7 +501,7 @@ class QmeraVideoViewController: UIViewController {
     }
     
     @objc func didTapDeclineCallButton(sender: AnyObject){
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
         if !onGoingCC.isEmpty {
             let alert = LibAlertController(title: "Interaction with Call Center is in progress".localized(), message: "Are you sure you want to end the Call Center?".localized(), preferredStyle: .alert)
             alert.addAction(UIAlertAction(title: "No".localized(), style: UIAlertAction.Style.default, handler: nil))
@@ -621,8 +621,8 @@ class QmeraVideoViewController: UIViewController {
     }
     
     @objc func didTapChatButton(){
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
-        let members = UserDefaults.standard.string(forKey: "membersCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
+        let members: String = SecureUserDefaults.shared.value(forKey: "membersCC") ?? ""
         let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
         let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
         editorPersonalVC.hidesBottomBarWhenPushed = true
@@ -657,7 +657,7 @@ class QmeraVideoViewController: UIViewController {
         if(wbVC == nil){
             wbVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as? WhiteboardViewController
             if(wbRoomId.isEmpty){
-                let me = UserDefaults.standard.string(forKey: "me")!
+                let me = User.getMyPin()!
                 let tid = CoreMessage_TMessageUtil.getTID()
                 wbRoomId = "\(me)wbvc\(tid)"
                 wbVC!.roomId = wbRoomId
@@ -673,7 +673,7 @@ class QmeraVideoViewController: UIViewController {
                 }
                 wbVC!.destinations = destinations
                 wbVC!.sendInit()
-                UserDefaults.standard.set("\(me),\(destString)", forKey: "wb_vc")
+                SecureUserDefaults.shared.set("\(me),\(destString)", forKey: "wb_vc")
             }
             else {
                 self.wbTimer.invalidate()
@@ -848,13 +848,13 @@ class QmeraVideoViewController: UIViewController {
         } else {
             Nexilis.ringtonePlayer?.stop()
         }
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
         if !onGoingCC.isEmpty {
             let requester = onGoingCC.components(separatedBy: ",")[0]
             let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
             let complaintId = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2]
-            let idMe = UserDefaults.standard.string(forKey: "me")!
-            let startTimeCC = UserDefaults.standard.string(forKey: "startTimeCC") ?? ""
+            let idMe = User.getMyPin()!
+            let startTimeCC: String = SecureUserDefaults.shared.value(forKey: "startTimeCC") ?? ""
             DispatchQueue.global().async {
                 let date = "\(Date().currentTimeMillis())"
                 Database.shared.database?.inTransaction({ (fmdb, rollback) in
@@ -884,10 +884,10 @@ class QmeraVideoViewController: UIViewController {
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.leaveCCRoomInvite(ticket_id: complaintId))
                     }
                 }
-                UserDefaults.standard.removeObject(forKey: "onGoingCC")
-                UserDefaults.standard.removeObject(forKey: "membersCC")
-                UserDefaults.standard.removeObject(forKey: "startTimeCC")
-                UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+                SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+                SecureUserDefaults.shared.removeValue(forKey: "startTimeCC")
+                SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
             }
         }
         API.terminateCall(sParty: nil)
@@ -922,7 +922,7 @@ class QmeraVideoViewController: UIViewController {
             contactViewController.isAddParticipantVideo = true
             contactViewController.connectedCall = dataPerson
             contactViewController.isDismiss = { data in
-                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                 if !onGoingCC.isEmpty {
                     DispatchQueue.global().async {
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.getCCRoomInvite(l_pin: data["f_pin"]!!, ticket_id: onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[2], channel: "2"))
@@ -1124,7 +1124,7 @@ class QmeraVideoViewController: UIViewController {
             } else {
                 Nexilis.ringtonePlayer?.stop()
             }
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 let requester = onGoingCC.components(separatedBy: ",")[0]
                 let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
@@ -1266,7 +1266,7 @@ class QmeraVideoViewController: UIViewController {
             } else {
                 Nexilis.ringtonePlayer?.stop()
             }
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             DispatchQueue.main.async {
                 if (self.dataPerson.count == 1) {
                     if self.labelIncomingOutgoing.isDescendant(of: self.view) {
@@ -1313,7 +1313,7 @@ class QmeraVideoViewController: UIViewController {
                                             members = ",\(user.pin)"
                                         }
                                     }
-                                    UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                                    SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                                 }
                             }
                         }
@@ -1337,7 +1337,7 @@ class QmeraVideoViewController: UIViewController {
             } else {
                 Nexilis.ringtonePlayer?.stop()
             }
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             DispatchQueue.main.async { [self] in
                 if (self.dataPerson.count == 1) {
                     if self.labelIncomingOutgoing.isDescendant(of: self.view) {
@@ -1384,7 +1384,7 @@ class QmeraVideoViewController: UIViewController {
                                             members = ",\(user.pin)"
                                         }
                                     }
-                                    UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                                    SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                                 }
                             }
                         }
@@ -1477,7 +1477,7 @@ extension QmeraVideoViewController : WhiteboardReceiver {
             DispatchQueue.main.async {
                 self.wbTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runTimer), userInfo: nil, repeats: true)
             }
-            let me = UserDefaults.standard.string(forKey: "me")!
+            let me = User.getMyPin()!
             var destString = ""
             for d in dataPerson{
                 if d["f_pin"]!! == roomId.components(separatedBy: "wbvc")[0] {
@@ -1490,9 +1490,9 @@ extension QmeraVideoViewController : WhiteboardReceiver {
                 }
             }
             if destString.isEmpty {
-                UserDefaults.standard.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me)", forKey: "wb_vc")
+                SecureUserDefaults.shared.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me)", forKey: "wb_vc")
             } else {
-                UserDefaults.standard.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me),\(destString)", forKey: "wb_vc")
+                SecureUserDefaults.shared.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me),\(destString)", forKey: "wb_vc")
             }
             wbRoomId = roomId
         }

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/VideoViewController.swift

@@ -148,7 +148,7 @@ class VideoViewController: UIViewController {
         let message = (data?["message"] ?? "") as! String
         var remoteChannel = [String:String]()
         let arrayMessage = message.split(separator: ",")
-        //        let me = UserDefaults.standard.string(forKey: "me")!
+        //        let me = User.getMyPin()!
         if(state == Nexilis.VIDEO_CALL_ZOOM){
             DispatchQueue.main.async {
                 self.zoomView.transform   = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: (CGFloat.pi * 3)/2)

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/WhiteboardViewController.swift

@@ -211,7 +211,7 @@ class WhiteboardViewController: UIViewController, WhiteboardDelegate {
             self.constraintBottomButtonDecline
         ])
         self.initWhiteboard()
-        UserDefaults.standard.set("\(user!.pin),\(User.getMyPin() ?? "")", forKey: "wb_vc")
+        SecureUserDefaults.shared.set("\(user!.pin),\(User.getMyPin() ?? "")", forKey: "wb_vc")
     }
     
     @objc func wbSession(notification: NSNotification) {
@@ -239,7 +239,7 @@ class WhiteboardViewController: UIViewController, WhiteboardDelegate {
                         self.roomId = "\(f_pin)WB\(tid)"
                         self.destinations = [f_pin]
                         self.sendInit()
-                        UserDefaults.standard.set("\(User.getMyPin() ?? ""),\(f_pin)", forKey: "wb_vc")
+                        SecureUserDefaults.shared.set("\(User.getMyPin() ?? ""),\(f_pin)", forKey: "wb_vc")
                     }
                 case CoreMessage_TMessageCode.WB_REJECT_INCOMING,CoreMessage_TMessageCode.WB_END:
                     //print("WB_REJECT_INCOMING \(status)")

+ 21 - 22
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/ChatGPTBotView.swift

@@ -78,7 +78,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
     
     public override func viewDidDisappear(_ animated: Bool) {
         if self.isMovingFromParent {
-            UserDefaults.standard.removeObject(forKey: "inEditorPersonal")
+            SecureUserDefaults.shared.removeValue(forKey: "inEditorPersonal")
             NotificationCenter.default.removeObserver(self)
             super.viewDidDisappear(true)
             self.removeFromParent()
@@ -152,7 +152,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
     }
     
     private func addGreeting() {
-        guard let me = UserDefaults.standard.string(forKey: "me") else {
+        guard let me = User.getMyPin() else {
             return
         }
         var user_id:String? = ""
@@ -273,7 +273,6 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
 //                timer.invalidate()
 //            }
 //            self.timeoutCC.invalidate()
-//            UserDefaults.standard.removeObject(forKey: "inEditorPersonal")
 //            NotificationCenter.default.removeObserver(self)
 //            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "refreshView"), object: nil, userInfo: nil)
 //            self.dismiss(animated: true, completion: nil)
@@ -306,7 +305,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
         var chat_id = chat_id
         let message_text = message_text.trimmingCharacters(in: .whitespacesAndNewlines)
         
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         var opposite_pin = idMe ?? ""
         sendTyping(l_pin: l_pin, isTyping: true)
         let message = CoreMessage_TMessageBank.sendMessage(l_pin: l_pin, message_scope_id: message_scope_id, status: status, message_text: message_text, credential: credential, attachment_flag: attachment_flag, ex_blog_id: ex_blog_id, message_large_text: message_large_text, ex_format: ex_format, image_id: image_id, audio_id: audio_id, video_id: video_id, file_id: file_id, thumb_id: thumb_id, reff_id: reff_id, read_receipts: read_receipts, chat_id: chat_id, is_call_center: is_call_center, call_center_id: call_center_id, opposite_pin: opposite_pin)
@@ -396,7 +395,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
                                 gptRow["role"] = json["role"] as? String
                                 gptRow["content"] = json["content"] as? String
                                 self.chatGPTMessages.append(gptRow)
-                                guard let me = UserDefaults.standard.string(forKey: "me") else {
+                                guard let me = User.getMyPin() else {
                                     return
                                 }
                                 
@@ -567,7 +566,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
     }
     
     func loadData(){
-        UserDefaults.standard.set(dataPerson["f_pin"]!, forKey: "inEditorPersonal")
+        SecureUserDefaults.shared.set(dataPerson["f_pin"]!, forKey: "inEditorPersonal")
         UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [dataPerson["f_pin"]!!])
         
         if self.fromNotification {
@@ -591,7 +590,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
         tapGesture.cancelsTouchesInView = false
         tableChatView.addGestureRecognizer(tapGesture)
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         for i in 0..<dataMessages.count {
             if dataMessages[i]["f_pin"] as? String != idMe {
                 sendReadMessageStatus(chat_id: "", f_pin: dataPerson["f_pin"]!!, message_scope_id: "3", message_id: dataMessages[i]["message_id"] as! String)
@@ -727,7 +726,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
                     _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)'")
                     _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
                     let l_pin = self.dataPerson["f_pin"]!!
-                    UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
+                    SecureUserDefaults.shared.removeValue(forKey: "saved_\(l_pin)")
                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                     self.navigationController?.popViewController(animated: true)
                 })
@@ -939,9 +938,9 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
             let data:[AnyHashable : Any] = notification.userInfo!
             if let dataMessage = data["message"] as? TMessage {
                 let chatData = dataMessage.mBodies
-                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                 let requester = onGoingCC.components(separatedBy: ",")[0]
-                let idMe = UserDefaults.standard.string(forKey: "me")!
+                let idMe = User.getMyPin()!
                 if chatData[CoreMessage_TMessageKey.F_PIN] == self.dataPerson["f_pin"]!! || chatData[CoreMessage_TMessageKey.L_PIN] == self.dataPerson["f_pin"]!! || requester == idMe {
                     if (chatData.keys.contains(CoreMessage_TMessageKey.MESSAGE_ID) && !(chatData[CoreMessage_TMessageKey.MESSAGE_ID]!).contains("-2,")) {
                         var idx = self.dataMessages.firstIndex(where: { $0["message_id"] as? String == chatData[CoreMessage_TMessageKey.MESSAGE_ID]! })
@@ -1006,7 +1005,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
         DispatchQueue.main.async { [self] in
             let data:[AnyHashable : Any] = notification.userInfo!
             let message: TMessage = data["message"] as! TMessage
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                 if message.getBody(key: CoreMessage_TMessageKey.F_PIN) != officer {
@@ -1071,7 +1070,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
             } else if day < 7 {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EEEE"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -1082,7 +1081,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
             } else {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EE, dd MMM"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -1209,7 +1208,7 @@ class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
             var listData = dataMessages[0...currentIndexpath!.row]
             listData = listData.filter({$0["status"] as? String != "4" && $0["status"] as? String != "8"})
             if listData.count != 0 {
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 for i in 0...listData.count - 1 {
                     if listData[i]["f_pin"] as? String != idMe {
                         sendReadMessageStatus(chat_id: "", f_pin: dataPerson["f_pin"]!!, message_scope_id: "31", message_id: listData[i]["message_id"] as! String)
@@ -1314,7 +1313,7 @@ extension ChatGPTBotView: UIContextMenuInteractionDelegate {
         
         var children: [UIMenuElement] = [copy, delete]
 //        let copyOption = self.copyOption(indexPath: indexPath!)
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
 //        if (dataMessages[indexPath!.row]["lock"] != nil && dataMessages[indexPath!.row]["lock"] as! String == "1") || dataMessages[indexPath!.row]["message_scope_id"] as! String == "18" || dataPerson["f_pin"] == "-999" || dataMessages[indexPath!.row]["credential"] as! String == "1" {
 //            children = [delete]
 //        } else {
@@ -1538,7 +1537,7 @@ extension ChatGPTBotView: UIContextMenuInteractionDelegate {
             if let action = self.actionDelete(for: "me", title: "Delete".localized() + " \(countSelected) " + "For Me".localized(), dataMessages: dataMessages) {
                 alertController.addAction(action)
             }
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let dataFilterFpin = dataMessages.filter({ $0["l_pin"] as? String == idMe})
             let dataFilterLock = dataMessages.filter({ $0["lock"] as? String == "1" || $0["lock"] as? String == "2" })
             let statusDataRead = dataMessages.filter({ Int($0["status"] as! String)! >= 4})
@@ -1674,7 +1673,7 @@ extension ChatGPTBotView: UIContextMenuInteractionDelegate {
     }
     
     private func updateProfile() {
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         DispatchQueue.global().async {
             let message = CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: idMe!, last_update: 0)
             let _ = Nexilis.write(message: message)
@@ -1783,7 +1782,7 @@ extension ChatGPTBotView: UITableViewDelegate, UITableViewDataSource {
     }
     
     public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         let dataMessages = dataMessages.filter({$0["chat_date"] as! String == dataDates[indexPath.section]})
         let profileMessage = UIImageView()
         let cell = tableView.dequeueReusableCell(withIdentifier: "cellEditorPersonal", for: indexPath as IndexPath)
@@ -2148,7 +2147,7 @@ extension ChatGPTBotView: UITableViewDelegate, UITableViewDataSource {
 //            }
 //        }
 //        if x <= -(recognizer.view?.frame.size.width ?? 0) * 0.05 {
-//            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//            let idMe = User.getMyPin() as String?
 //            let indexPath = self.tableChatView.indexPath(for: recognizer.view! as! UITableViewCell)
 //            let dataMessages = self.dataMessages.filter({ $0["chat_date"] as! String == dataDates[indexPath!.section]})
 //            if (dataMessages[indexPath!.row]["f_pin"] as? String == idMe) {
@@ -2209,7 +2208,7 @@ extension ChatGPTBotView: UITableViewDelegate, UITableViewDataSource {
             DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                 if let cell = self.tableChatView.cellForRow(at: indexPath) {
                     let containerMessage = cell.contentView.subviews[0]
-                    let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                    let idMe = User.getMyPin() as String?
                     if (self.dataMessages[idx!]["f_pin"] as? String == idMe) {
                         containerMessage.backgroundColor = .blueBubbleColor.withAlphaComponent(0.3)
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
@@ -2295,7 +2294,7 @@ extension ChatGPTBotView: UITableViewDelegate, UITableViewDataSource {
 //        if copySession || forwardSession || deleteSession {
 //            return nil
 //        }
-//        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//        let idMe = User.getMyPin() as String?
 //        if (dataMessages[indexPath.row]["f_pin"] as? String != idMe) {
 //            return nil
 //        }
@@ -2345,7 +2344,7 @@ extension ChatGPTBotView: UITableViewDelegate, UITableViewDataSource {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                     if let cell = self.tableChatView.cellForRow(at: indexPath) {
                         let containerMessage = cell.contentView.subviews[0]
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if (messageTextForSearch[idx]["f_pin"] as? String == idMe) {
                             containerMessage.backgroundColor = .blueBubbleColor.withAlphaComponent(0.3)
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

+ 41 - 38
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift

@@ -101,7 +101,7 @@ public class EditorGroup: UIViewController {
     
     public override func viewDidDisappear(_ animated: Bool) {
         if self.isMovingFromParent {
-            UserDefaults.standard.removeObject(forKey: "inEditorGroup")
+            SecureUserDefaults.shared.removeValue(forKey: "inEditorGroup")
             NotificationCenter.default.removeObserver(self)
             super.viewDidDisappear(true)
             self.removeFromParent()
@@ -110,7 +110,7 @@ public class EditorGroup: UIViewController {
             if (self.dataTopic["chat_id"] as! String != "") {
                 l_pin = self.dataTopic["chat_id"] as! String
             }
-            UserDefaults.standard.set("\(textFieldSend.textColor != UIColor.lightGray ? textFieldSend.text! : ""),\(reffId ?? "")", forKey: "saved_\(l_pin)")
+            SecureUserDefaults.shared.set("\(textFieldSend.textColor != UIColor.lightGray ? textFieldSend.text! : ""),\(reffId ?? "")", forKey: "saved_\(l_pin)")
         }
     }
     
@@ -223,13 +223,13 @@ public class EditorGroup: UIViewController {
     
     public func afterUnfriend() {
         DispatchQueue.main.async {
-            UserDefaults.standard.removeObject(forKey: "inEditorGroup")
+            SecureUserDefaults.shared.removeValue(forKey: "inEditorGroup")
             NotificationCenter.default.removeObserver(self)
         }
     }
     
     private func updateProfile() {
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         DispatchQueue.global().async {
             let message = CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: idMe!, last_update: 0)
             let _ = Nexilis.write(message: message)
@@ -251,7 +251,7 @@ public class EditorGroup: UIViewController {
                         }
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(l_pin='\(self.dataGroup["group_id"]!!)' and chat_id='\(self.dataTopic["chat_id"]!!)') and message_scope_id='4'")
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(l_pin)'")
-                        UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
+                        SecureUserDefaults.shared.removeValue(forKey: "saved_\(l_pin)")
                         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                         if self.fromNotification {
                             self.didTapExit()
@@ -326,7 +326,10 @@ public class EditorGroup: UIViewController {
         }
         
         if !isHistoryCC {
-            UserDefaults.standard.set([dataGroup["group_id"], dataTopic["chat_id"]], forKey: "inEditorGroup")
+            let groupId = dataGroup["group_id"] as! String
+            let chatId = dataGroup["chat_id"] as! String
+            let dataGT: [String] = [groupId, chatId]
+            SecureUserDefaults.shared.set(dataGT, forKey: "inEditorGroup")
             
             if dataTopic["chat_id"] as! String == "" {
                 UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [dataGroup["group_id"] as! String])
@@ -375,7 +378,7 @@ public class EditorGroup: UIViewController {
             }
             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [self] in
                 if currentIndexpath == nil && counter != 0 {
-                    let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                    let idMe = User.getMyPin() as String?
                     if let idx = dataMessages.firstIndex(where: { $0["message_id"] as? String == markerCounter}) {
                         for i in idx..<dataMessages.count {
                             if dataMessages[i]["f_pin"] as? String != idMe {
@@ -392,7 +395,7 @@ public class EditorGroup: UIViewController {
             if (self.dataTopic["chat_id"] as! String != "") {
                 l_pin = self.dataTopic["chat_id"] as! String
             }
-            if let dataSaved = UserDefaults.standard.string(forKey: "saved_\(l_pin)") {
+            if let dataSaved: String = SecureUserDefaults.shared.value(forKey: "saved_\(l_pin)") {
                 let last_m = dataSaved.components(separatedBy: ",")[0]
                 let last_r = dataSaved.components(separatedBy: ",")[1]
                 if !last_m.isEmpty {
@@ -433,7 +436,7 @@ public class EditorGroup: UIViewController {
                             timer.invalidate()
                             self.listTimerCredential.removeValue(forKey: data.key)
                             self.timerCredential.removeValue(forKey: data.key)
-                            UserDefaults.standard.removeObject(forKey: data.key)
+                            SecureUserDefaults.shared.removeValue(forKey: data.key)
                             let idx = self.dataMessages.firstIndex(where: { $0["message_id"] as? String == data.key})
                             if idx != nil {
                                 self.dataMessages[idx!]["lock"] = "2"
@@ -540,7 +543,7 @@ public class EditorGroup: UIViewController {
                     row["credential"] = cursorData.string(forColumnIndex: 19)
                     row["isSelected"] = false
                     if row["credential"] != nil && row["credential"] as! String == "1" {
-                        let idMe = UserDefaults.standard.string(forKey: "me")!
+                        let idMe = User.getMyPin()!
                         if row["f_pin"] as! String == idMe {
                             let second = getSecondsDifferenceFromTwoDates(start: Date.init(milliseconds: Int64(row["server_date"] as! String)!), end: Date())
                             if second > 60 {
@@ -559,7 +562,7 @@ public class EditorGroup: UIViewController {
                                 listTimerCredential[row["message_id"] as! String] = second
                             }
                         } else {
-                            let hasMessageId = UserDefaults.standard.string(forKey: row["message_id"] as! String)
+                            let hasMessageId: String? = SecureUserDefaults.shared.value(forKey: row["message_id"] as! String) ?? nil
                             if hasMessageId != nil {
                                 let second = getSecondsDifferenceFromTwoDates(start: Date.init(milliseconds: Int64(hasMessageId!)!), end: Date())
                                 if second > 60 {
@@ -578,7 +581,7 @@ public class EditorGroup: UIViewController {
                                     listTimerCredential[row["message_id"] as! String] = second
                                 }
                             } else {
-                                UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
+                                SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
                                 listTimerCredential[row["message_id"] as! String] = 60
                             }
                         }
@@ -697,7 +700,7 @@ public class EditorGroup: UIViewController {
             } else if day < 7 {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EEEE"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -708,7 +711,7 @@ public class EditorGroup: UIViewController {
             } else {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EE, dd MMM"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -964,7 +967,7 @@ public class EditorGroup: UIViewController {
                         var timer = Timer()
                         var minute = 60
                         self.timerCredential[row["message_id"] as! String] = timer
-                        UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
+                        SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
                         timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: {_ in
                             minute -= 1
                             self.listTimerCredential[row["message_id"] as! String] = minute
@@ -972,7 +975,7 @@ public class EditorGroup: UIViewController {
                                 timer.invalidate()
                                 self.listTimerCredential.removeValue(forKey: row["message_id"] as! String)
                                 self.timerCredential.removeValue(forKey: row["message_id"] as! String)
-                                UserDefaults.standard.removeObject(forKey: row["message_id"] as! String)
+                                SecureUserDefaults.shared.removeValue(forKey: row["message_id"] as! String)
                                 let idx = self.dataMessages.firstIndex(where: { $0["message_id"] as? String == row["message_id"] as? String})
                                 if idx != nil {
                                     self.dataMessages[idx!]["lock"] = "2"
@@ -1049,7 +1052,7 @@ public class EditorGroup: UIViewController {
         DispatchQueue.main.async {
             let data:[AnyHashable : Any] = notification.userInfo!
             if let dataMessage = data["message"] as? TMessage {
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 let chatData = dataMessage.mBodies
                 if (chatData[CoreMessage_TMessageKey.F_PIN] == idMe || chatData[CoreMessage_TMessageKey.L_PIN] == self.dataGroup["group_id"] as? String || chatData[CoreMessage_TMessageKey.F_PIN] == self.dataGroup["group_id"] as? String) && chatData[CoreMessage_TMessageKey.MESSAGE_SCOPE_ID] == "4" {
                     if (chatData.keys.contains(CoreMessage_TMessageKey.MESSAGE_ID) && !(chatData[CoreMessage_TMessageKey.MESSAGE_ID]!).contains("-2,")) {
@@ -1152,7 +1155,7 @@ public class EditorGroup: UIViewController {
                 self.listTimerCredential.removeValue(forKey: self.dataMessages[idx!]["message_id"] as! String)
                 self.timerCredential[self.dataMessages[idx!]["message_id"] as! String]?.invalidate()
                 self.timerCredential.removeValue(forKey: self.dataMessages[idx!]["message_id"] as! String)
-                UserDefaults.standard.removeObject(forKey: self.dataMessages[idx!]["message_id"] as! String)
+                SecureUserDefaults.shared.removeValue(forKey: self.dataMessages[idx!]["message_id"] as! String)
             }
             if self.reffId != nil && self.reffId == chatData["message_id"]! {
                 self.deleteReplyView()
@@ -1179,7 +1182,7 @@ public class EditorGroup: UIViewController {
     @objc func onMemberTopic(notification: NSNotification) {
         let data:[AnyHashable : Any] = notification.userInfo!
         DispatchQueue.main.async { [self] in
-            if data["member"] == nil || data["code"] as! String == CoreMessage_TMessageCode.EXIT_GROUP && data["member"] as! String == UserDefaults.standard.string(forKey: "me")! && data["groupId"] as! String == self.dataGroup["group_id"] as! String && !containerActionGroup.isDescendant(of: self.view) {
+            if data["member"] == nil || data["code"] as! String == CoreMessage_TMessageCode.EXIT_GROUP && data["member"] as! String == User.getMyPin()! && data["groupId"] as! String == self.dataGroup["group_id"] as! String && !containerActionGroup.isDescendant(of: self.view) {
                 dismissKeyboard()
                 let labelKicked = UILabel()
                 if data["member"] == nil && data["code"] as! String == CoreMessage_TMessageCode.DELETE_CHAT && data["topicId"] as! String == dataTopic["chat_id"] as! String {
@@ -1363,7 +1366,7 @@ public class EditorGroup: UIViewController {
     }
     
     @objc func didTapExit() {
-        UserDefaults.standard.removeObject(forKey: "inEditorGroup")
+        SecureUserDefaults.shared.removeValue(forKey: "inEditorGroup")
         NotificationCenter.default.removeObserver(self)
         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "refreshView"), object: nil, userInfo: nil)
         self.dismiss(animated: true, completion: nil)
@@ -1373,7 +1376,7 @@ public class EditorGroup: UIViewController {
         if isHistoryCC {
             return
         }
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         if sender.message_id == idMe {
             let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
             controller.data = sender.message_id
@@ -1414,7 +1417,7 @@ public class EditorGroup: UIViewController {
                 var listData = self.dataMessages
                 listData = listData.filter({$0["status"] as! String != "4" && $0["status"] as! String != "8"})
                 if listData.count != 0 {
-                    let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                    let idMe = User.getMyPin() as String?
                     for i in 0...listData.count - 1 {
                         if listData[i]["f_pin"] as? String != idMe {
                             self.sendReadMessageStatus(chat_id: self.dataTopic["chat_id"] as! String, f_pin: listData[i]["f_pin"] as! String, message_scope_id: "4", message_id: listData[i]["message_id"] as! String)
@@ -1426,7 +1429,7 @@ public class EditorGroup: UIViewController {
                 var listData = dataMessages
                 listData = listData.filter({$0["status"] as! String != "4" && $0["status"] as! String != "8"})
                 if listData.count != 0 {
-                    let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                    let idMe = User.getMyPin() as String?
                     for i in 0...listData.count - 1 {
                         if listData[i]["f_pin"] as? String != idMe {
                             self.sendReadMessageStatus(chat_id: self.dataTopic["chat_id"] as! String, f_pin: listData[i]["f_pin"] as! String, message_scope_id: "4", message_id: listData[i]["message_id"] as! String)
@@ -1579,7 +1582,7 @@ public class EditorGroup: UIViewController {
             reff_id = reffId!
         }
         var message_text = message_text.trimmingCharacters(in: .whitespacesAndNewlines)
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         var opposite_pin = self.dataGroup["group_id"] as! String
         if (self.dataTopic["chat_id"] as! String != "") {
             opposite_pin = self.dataTopic["chat_id"] as! String
@@ -1851,7 +1854,7 @@ public class EditorGroup: UIViewController {
         }
         if let index = dataMessages.firstIndex(where: {$0["message_id"] as? String == message_id}) {
             dataMessages[index]["status"] = "4"
-            let auto = UserDefaults.standard.bool(forKey: "autoDownload")
+            let auto: Bool = SecureUserDefaults.shared.value(forKey: "autoDownload") ?? false
             if auto {
                 if dataMessages[index]["image_id"] as? String != nil && !((dataMessages[index]["image_id"] as? String)!.isEmpty) {
                     Download().startHTTP(forKey:dataMessages[index]["image_id"] as! String) { (name, progress) in
@@ -1864,7 +1867,7 @@ public class EditorGroup: UIViewController {
                         if let dirPath = paths.first {
                             let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(self.dataMessages[index]["image_id"] as! String)
                             let image    = UIImage(contentsOfFile: imageURL.path)
-                            let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                            let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                             if save {
                                 UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
                             }
@@ -1887,7 +1890,7 @@ public class EditorGroup: UIViewController {
                         let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
                         if let dirPath = paths.first {
                             let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(self.dataMessages[index]["video_id"] as! String)
-                            let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                            let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                             if save {
                                 PHPhotoLibrary.shared().performChanges({
                                     PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL)
@@ -1970,7 +1973,7 @@ public class EditorGroup: UIViewController {
             var listData = dataMessages[0...currentIndexpath!.row]
             listData = listData.filter({$0["status"] as! String != "4" && $0["status"] as! String != "8"})
             if listData.count != 0 {
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 for i in 0...listData.count - 1 {
                     if listData[i]["f_pin"] as? String != idMe {
                         sendReadMessageStatus(chat_id: self.dataTopic["chat_id"] as! String, f_pin: listData[i]["f_pin"] as! String, message_scope_id: "4", message_id: listData[i]["message_id"] as! String)
@@ -2213,7 +2216,7 @@ extension EditorGroup: UITextViewDelegate {
         }
         listMentionWithText.removeAll()
         Database.shared.database?.inTransaction({ fmdb, rollback in
-            let idMe = UserDefaults.standard.string(forKey: "me")!
+            let idMe = User.getMyPin()!
             if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name || ' ' || ifnull(last_name, '') name FROM GROUPZ_MEMBER where group_id='\(self.dataGroup["group_id"] as! String)' AND f_pin <> '\(idMe)' AND name LIKE '%\(text)%'") {
                 while cursor.next() {
                     let user = User(pin: "")
@@ -2722,7 +2725,7 @@ extension EditorGroup: UIContextMenuInteractionDelegate {
         
         var children: [UIMenuElement] = [star, reply, forward, copy, delete]
 //        let copyOption = self.copyOption(indexPath: indexPath!)
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         
         if dataMessages[indexPath!.row]["status"] as! String == "0" {
             children = [resend, delete]
@@ -3025,7 +3028,7 @@ extension EditorGroup: UIContextMenuInteractionDelegate {
             if let action = self.actionDelete(for: "me", title: "Delete".localized() + " \(countSelected) " + "For Me".localized(), dataMessages: dataMessages) {
                 alertController.addAction(action)
             }
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let dataFilterFpin = dataMessages.filter({ $0["f_pin"] as? String != idMe})
             let dataFilterLock = dataMessages.filter({ $0["lock"] as? String == "1"})
 //            let statusDataRead = dataMessages.filter({ Int($0["status"] as! String)! >= 4})
@@ -3508,7 +3511,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
             cellMention.contentConfiguration = content
             return cellMention
         }
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         let dataMessages = dataMessages.filter({$0["chat_date"] as! String == dataDates[indexPath.section]})
         
         let cellMessage = tableView.dequeueReusableCell(withIdentifier: "cellEditorGroup", for: indexPath as IndexPath)
@@ -4887,7 +4890,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                         
                         let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.image_id)
                         let image    = UIImage(contentsOfFile: imageURL.path)
-                        let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                        let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                         if save {
                             UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
                         }
@@ -4950,7 +4953,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                                 shapeLoading.strokeEnd = CGFloat(progress / 100)
                                 return
                             }
-                            let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                            let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                             if save {
                                 let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.video_id)
                                 PHPhotoLibrary.shared().performChanges({
@@ -5049,7 +5052,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                     if let cell = self.tableChatView.cellForRow(at: indexPath) {
                         let containerMessage = cell.contentView.subviews[1]
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if (self.dataMessages[idx!]["f_pin"] as? String == idMe) {
                             containerMessage.backgroundColor = .blueBubbleColor.withAlphaComponent(0.3)
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
@@ -5200,7 +5203,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
 //        if copySession || forwardSession || deleteSession {
 //            return nil
 //        }
-//        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//        let idMe = User.getMyPin() as String?
 //        if (dataMessages[indexPath.row]["f_pin"] as? String != idMe) {
 //            return nil
 //        }
@@ -5279,7 +5282,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
         titleReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
         titleReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor, constant: 10).isActive = true
         titleReply.font = UIFont.systemFont(ofSize: 12).bold
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         if (dataMessages[indexPath.row]["f_pin"] as? String == idMe) {
             titleReply.text = "You".localized()
         } else {
@@ -5418,7 +5421,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                     if let cell = self.tableChatView.cellForRow(at: indexPath) {
                         let containerMessage = cell.contentView.subviews[1]
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if (messageTextForSearch[idx]["f_pin"] as? String == idMe) {
                             containerMessage.backgroundColor = .blueBubbleColor.withAlphaComponent(0.3)
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

+ 70 - 70
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift

@@ -116,14 +116,14 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 timer.invalidate()
             }
             self.timeoutCC.invalidate()
-            UserDefaults.standard.removeObject(forKey: "inEditorPersonal")
+            SecureUserDefaults.shared.removeValue(forKey: "inEditorPersonal")
             NotificationCenter.default.removeObserver(self)
             super.viewDidDisappear(true)
             self.removeFromParent()
             self.dismiss(animated: true, completion: nil)
             if !isContactCenter {
                 let l_pin = self.dataPerson["f_pin"]!!
-                UserDefaults.standard.set("\(textFieldSend.textColor != UIColor.lightGray ? textFieldSend.text! : ""),\(reffId ?? "")", forKey: "saved_\(l_pin)")
+                SecureUserDefaults.shared.set("\(textFieldSend.textColor != UIColor.lightGray ? textFieldSend.text! : ""),\(reffId ?? "")", forKey: "saved_\(l_pin)")
             }
         }
     }
@@ -245,7 +245,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 }
             })
             self.dateStartCC = "\(Date().currentTimeMillis())"
-            let myName = User.getData(pin: UserDefaults.standard.string(forKey: "me") as String?)
+            let myName = User.getData(pin: User.getMyPin() as String?)
             sendChat(message_text: "Hi \(dataPerson["name"]!!), thank you for contacting \(companyName). My name is \(myName!.fullName.trimmingCharacters(in: .whitespaces)), how can I help you?".localized(), ex_format: "1", is_call_center: "1", call_center_id: complaintId, viewController: self, isAutoSendCC: true)
             if channelContactCenter == "1" {
                 if let pin = dataPerson["f_pin"] {
@@ -285,7 +285,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 timer.invalidate()
             }
             self.timeoutCC.invalidate()
-            UserDefaults.standard.removeObject(forKey: "inEditorPersonal")
+            SecureUserDefaults.shared.removeValue(forKey: "inEditorPersonal")
             NotificationCenter.default.removeObserver(self)
         }
     }
@@ -301,7 +301,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
                         let l_pin = self.dataPerson["f_pin"]!!
-                        UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
+                        SecureUserDefaults.shared.removeValue(forKey: "saved_\(l_pin)")
                         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                         if self.fromNotification {
                             self.didTapExit()
@@ -461,9 +461,9 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         }
         
         if onGoingCC {
-            UserDefaults.standard.set(self.fPinContacCenter, forKey: "inEditorPersonal")
+            SecureUserDefaults.shared.set(self.fPinContacCenter, forKey: "inEditorPersonal")
         } else {
-            UserDefaults.standard.set(dataPerson["f_pin"]!, forKey: "inEditorPersonal")
+            SecureUserDefaults.shared.set(dataPerson["f_pin"]!, forKey: "inEditorPersonal")
         }
         UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [dataPerson["f_pin"]!!])
         
@@ -516,7 +516,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 }
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [self] in
                     if currentIndexpath == nil && counter != 0 {
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if let idx = dataMessages.firstIndex(where: { $0["message_id"] as? String == markerCounter}) {
                             for i in idx..<dataMessages.count {
                                 if dataMessages[i]["f_pin"] as? String != idMe {
@@ -530,7 +530,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 }
             } else {
                 let l_pin = self.dataPerson["f_pin"]
-                if let dataSaved = UserDefaults.standard.string(forKey: "saved_\(l_pin)") {
+                if let dataSaved: String = SecureUserDefaults.shared.value(forKey: "saved_\(l_pin)") {
                     let last_m = dataSaved.components(separatedBy: ",")[0]
                     let last_r = dataSaved.components(separatedBy: ",")[1]
                     if !last_m.isEmpty {
@@ -545,7 +545,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 tableChatView.scrollToBottom(isAnimated: false)
             }
         } else if isContactCenter && onGoingCC {
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             for i in 0..<dataMessages.count {
                 if dataMessages[i]["f_pin"] as? String != idMe {
                     sendReadMessageStatus(chat_id: "", f_pin: dataPerson["f_pin"]!!, message_scope_id: "3", message_id: dataMessages[i]["message_id"] as! String)
@@ -578,7 +578,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                             timer.invalidate()
                             self.listTimerCredential.removeValue(forKey: data.key)
                             self.timerCredential.removeValue(forKey: data.key)
-                            UserDefaults.standard.removeObject(forKey: data.key)
+                            SecureUserDefaults.shared.removeValue(forKey: data.key)
                             let idx = self.dataMessages.firstIndex(where: { $0["message_id"] as? String == data.key})
                             if idx != nil {
                                 self.dataMessages[idx!]["lock"] = "2"
@@ -866,7 +866,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     row["chat_date"] = chatDate(stringDate: row["server_date"] as! String)
                     row["isSelected"] = false
                     if row["credential"] != nil && row["credential"] as! String == "1" {
-                        let idMe = UserDefaults.standard.string(forKey: "me")!
+                        let idMe = User.getMyPin()!
                         if row["f_pin"] as! String == idMe {
                             let second = getSecondsDifferenceFromTwoDates(start: Date.init(milliseconds: Int64(row["server_date"] as! String)!), end: Date())
                             if second > 60 {
@@ -885,7 +885,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                                 listTimerCredential[row["message_id"] as! String] = second
                             }
                         } else {
-                            let hasMessageId = UserDefaults.standard.string(forKey: row["message_id"] as! String)
+                            let hasMessageId: String? = SecureUserDefaults.shared.value(forKey: row["message_id"] as! String) ?? nil
                             if hasMessageId != nil {
                                 let second = getSecondsDifferenceFromTwoDates(start: Date.init(milliseconds: Int64(hasMessageId!)!), end: Date())
                                 if second > 60 {
@@ -904,7 +904,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                                     listTimerCredential[row["message_id"] as! String] = second
                                 }
                             } else {
-                                UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
+                                SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
                                 listTimerCredential[row["message_id"] as! String] = 60
                             }
                         }
@@ -1026,7 +1026,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     row["chat_date"] = chatDate(stringDate: row["server_date"] as! String)
                     row["isSelected"] = false
                     if row["credential"] != nil && row["credential"] as! String == "1" {
-                        let idMe = UserDefaults.standard.string(forKey: "me")!
+                        let idMe = User.getMyPin()!
                         if row["f_pin"] as! String == idMe {
                             let second = getSecondsDifferenceFromTwoDates(start: Date.init(milliseconds: Int64(row["server_date"] as! String)!), end: Date())
                             if second > 60 {
@@ -1045,7 +1045,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                                 listTimerCredential[row["message_id"] as! String] = second
                             }
                         } else {
-                            let hasMessageId = UserDefaults.standard.string(forKey: row["message_id"] as! String)
+                            let hasMessageId: String? = SecureUserDefaults.shared.value(forKey: row["message_id"] as! String) ?? nil
                             if hasMessageId != nil {
                                 let second = getSecondsDifferenceFromTwoDates(start: Date.init(milliseconds: Int64(hasMessageId!)!), end: Date())
                                 if second > 60 {
@@ -1064,7 +1064,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                                     listTimerCredential[row["message_id"] as! String] = second
                                 }
                             } else {
-                                UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
+                                SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
                                 listTimerCredential[row["message_id"] as! String] = 60
                             }
                         }
@@ -1140,7 +1140,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
             } else if day < 7 {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EEEE"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -1151,7 +1151,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
             } else {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EE, dd MMM"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -1282,7 +1282,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     if !data.isEmpty {
                         if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
                             var members = ""
-                            let idMe = UserDefaults.standard.string(forKey: "me")!
+                            let idMe = User.getMyPin()!
                             var user : [User] = []
                             for json in jsonArray {
                                 if "\(json)" != idMe {
@@ -1313,14 +1313,14 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                             self.users = user
                             self.fPinContacCenter = members
                             self.changeAppBar()
-                            UserDefaults.standard.set(members, forKey: "inEditorPersonal")
+                            SecureUserDefaults.shared.set(members, forKey: "inEditorPersonal")
                         }
                     }
                 } else if (dataMessage.getCode() == CoreMessage_TMessageCode.ACCEPT_CALL_CENTER) {
                     if !self.isRequestContactCenter || !isContactCenter {
                         return
                     }
-                    UserDefaults.standard.set(dataMessage.getBody(key: CoreMessage_TMessageKey.F_PIN), forKey: "inEditorPersonal")
+                    SecureUserDefaults.shared.set(dataMessage.getBody(key: CoreMessage_TMessageKey.F_PIN), forKey: "inEditorPersonal")
                     let date = Date()
                     let formatter = DateFormatter()
                     formatter.dateFormat = "HH:mm"
@@ -1340,10 +1340,10 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     self.dateStartCC = "\(Date().currentTimeMillis())"
                     self.tableChatView.insertRows(at: [IndexPath(row: self.dataMessages.count - 1, section: 0)], with: .none)
                     self.tableChatView.scrollToBottom()
-                    UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                    SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                     if dataMessage.getBody(key: CoreMessage_TMessageKey.CHANNEL) != "0" {
-                        UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
-                        UserDefaults.standard.set(dataMessage.getBody(key: CoreMessage_TMessageKey.CHANNEL), forKey: "channelCC")
+                        SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: "startTimeCC")
+                        SecureUserDefaults.shared.set(dataMessage.getBody(key: CoreMessage_TMessageKey.CHANNEL), forKey: "channelCC")
                         DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                             self.dismiss(animated: true, completion: nil)
                         })
@@ -1352,7 +1352,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         viewTextfield.isHidden = false
                     }
                 } else if (dataMessage.getCode() == CoreMessage_TMessageCode.INVITE_END_CONTACT_CENTER || dataMessage.getCode() == CoreMessage_TMessageCode.END_CALL_CENTER || dataMessage.getCode() == CoreMessage_TMessageCode.INVITE_EXIT_CONTACT_CENTER) && !fromVCAC {
-                    let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                    let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                     if onGoingCC.isEmpty || !isContactCenter {
                         return
                     }
@@ -1383,9 +1383,9 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         }
                         self.dismissKeyboard()
                         self.disableEditor()
-                        UserDefaults.standard.removeObject(forKey: "onGoingCC")
-                        UserDefaults.standard.removeObject(forKey: "membersCC")
-                        UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                        SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+                        SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+                        SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                         DispatchQueue.main.async {
                             let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
                             imageView.tintColor = .white
@@ -1411,7 +1411,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                                 members = ",\(user.pin)"
                             }
                         }
-                        UserDefaults.standard.set("\(members)", forKey: "membersCC")
+                        SecureUserDefaults.shared.set("\(members)", forKey: "membersCC")
                         self.fPinContacCenter = members
                         self.changeAppBar()
                     }
@@ -1486,7 +1486,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         var timer = Timer()
                         var minute = 60
                         self.timerCredential[row["message_id"] as! String] = timer
-                        UserDefaults.standard.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
+                        SecureUserDefaults.shared.set("\(Date().currentTimeMillis())", forKey: row["message_id"] as! String)
                         timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: {_ in
                             minute -= 1
                             self.listTimerCredential[row["message_id"] as! String] = minute
@@ -1494,7 +1494,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                                 timer.invalidate()
                                 self.listTimerCredential.removeValue(forKey: row["message_id"] as! String)
                                 self.timerCredential.removeValue(forKey: row["message_id"] as! String)
-                                UserDefaults.standard.removeObject(forKey: row["message_id"] as! String)
+                                SecureUserDefaults.shared.removeValue(forKey: row["message_id"] as! String)
                                 let idx = self.dataMessages.firstIndex(where: { $0["message_id"] as? String == row["message_id"] as? String})
                                 if idx != nil {
                                     self.dataMessages[idx!]["lock"] = "2"
@@ -1512,8 +1512,8 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         })
                     }
                     if self.isContactCenter {
-                        let idMe = UserDefaults.standard.string(forKey: "me")!
-                        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                        let idMe = User.getMyPin()!
+                        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                         let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                         if officer == idMe {
                             self.timeoutCC.invalidate()
@@ -1611,9 +1611,9 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
             let data:[AnyHashable : Any] = notification.userInfo!
             if let dataMessage = data["message"] as? TMessage {
                 let chatData = dataMessage.mBodies
-                let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+                let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
                 let requester = onGoingCC.components(separatedBy: ",")[0]
-                let idMe = UserDefaults.standard.string(forKey: "me")!
+                let idMe = User.getMyPin()!
                 if chatData[CoreMessage_TMessageKey.F_PIN] == self.dataPerson["f_pin"]!! || chatData[CoreMessage_TMessageKey.L_PIN] == self.dataPerson["f_pin"]!! || chatData[CoreMessage_TMessageKey.L_PIN] == self.fPinContacCenter || requester == idMe {
                     if (chatData.keys.contains(CoreMessage_TMessageKey.MESSAGE_ID) && !(chatData[CoreMessage_TMessageKey.MESSAGE_ID]!).contains("-2,")) {
                         var idx = self.dataMessages.firstIndex(where: { $0["message_id"] as? String == chatData[CoreMessage_TMessageKey.MESSAGE_ID]! })
@@ -1715,7 +1715,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 self.listTimerCredential.removeValue(forKey: self.dataMessages[idx!]["message_id"] as! String)
                 self.timerCredential[self.dataMessages[idx!]["message_id"] as! String]?.invalidate()
                 self.timerCredential.removeValue(forKey: self.dataMessages[idx!]["message_id"] as! String)
-                UserDefaults.standard.removeObject(forKey: self.dataMessages[idx!]["message_id"] as! String)
+                SecureUserDefaults.shared.removeValue(forKey: self.dataMessages[idx!]["message_id"] as! String)
             }
             if self.reffId != nil && self.reffId == chatData["message_id"]! {
                 self.deleteReplyView()
@@ -1743,7 +1743,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         DispatchQueue.main.async { [self] in
             let data:[AnyHashable : Any] = notification.userInfo!
             let message: TMessage = data["message"] as! TMessage
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
                 if message.getBody(key: CoreMessage_TMessageKey.F_PIN) != officer {
@@ -1868,7 +1868,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 var listData = self.dataMessages
                 listData = listData.filter({$0["status"] as! String != "4" && $0["status"] as! String != "8"})
                 if listData.count != 0 && !self.isContactCenter {
-                    let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                    let idMe = User.getMyPin() as String?
                     for i in 0...listData.count - 1 {
                         if listData[i]["f_pin"] as? String != idMe {
                             self.sendReadMessageStatus(chat_id: "", f_pin: self.dataPerson["f_pin"]!!, message_scope_id: "3", message_id: listData[i]["message_id"] as! String)
@@ -1880,7 +1880,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 var listData = dataMessages
                 listData = listData.filter({$0["status"] as! String != "4" && $0["status"] as! String != "8"})
                 if listData.count != 0 && !self.isContactCenter {
-                    let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                    let idMe = User.getMyPin() as String?
                     for i in 0...listData.count - 1 {
                         if listData[i]["f_pin"] as? String != idMe {
                             self.sendReadMessageStatus(chat_id: "", f_pin: self.dataPerson["f_pin"]!!, message_scope_id: "3", message_id: listData[i]["message_id"] as! String)
@@ -2163,7 +2163,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 timer.invalidate()
             }
             self.timeoutCC.invalidate()
-            UserDefaults.standard.removeObject(forKey: "inEditorPersonal")
+            SecureUserDefaults.shared.removeValue(forKey: "inEditorPersonal")
             NotificationCenter.default.removeObserver(self)
             NotificationCenter.default.post(name: NSNotification.Name(rawValue: "refreshView"), object: nil, userInfo: nil)
             self.dismiss(animated: true, completion: nil)
@@ -2180,8 +2180,8 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
     public func endCallCenter() {
         timeoutCC.invalidate()
         let complaintId = self.complaintId
-        let idMe = UserDefaults.standard.string(forKey: "me")!
-        let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+        let idMe = User.getMyPin()!
+        let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
         let requester = onGoingCC.components(separatedBy: ",")[0]
         let officer = onGoingCC.isEmpty ? "" : onGoingCC.components(separatedBy: ",")[1]
         DispatchQueue.global().async {
@@ -2213,9 +2213,9 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     _ = Nexilis.write(message: CoreMessage_TMessageBank.leaveCCRoomInvite(ticket_id: complaintId))
                 }
             }
-            UserDefaults.standard.removeObject(forKey: "onGoingCC")
-            UserDefaults.standard.removeObject(forKey: "membersCC")
-            UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+            SecureUserDefaults.shared.removeValue(forKey: "onGoingCC")
+            SecureUserDefaults.shared.removeValue(forKey: "membersCC")
+            SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
         }
         self.dismiss(animated: true, completion: nil)
     }
@@ -2322,7 +2322,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         }
         let message_text = message_text.trimmingCharacters(in: .whitespacesAndNewlines)
         
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         var opposite_pin = ""
         if isContactCenter {
             opposite_pin = ""
@@ -2650,7 +2650,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         let level = id!.substring(from: 5, to: 5)
         var row: [String: Any?] = [:]
         if id == "level\(Int(level)!)_0" {
-            UserDefaults.standard.set(true, forKey: "waitingRequestCC")
+            SecureUserDefaults.shared.set(true, forKey: "waitingRequestCC")
             DispatchQueue.global().async {
                 let message = CoreMessage_TMessageBank.getQueuingCallCenter(p_channel: Int(self.channelContactCenter)!)
                 message.mBodies[CoreMessage_TMessageKey.CATEGORY_ID] = "\(service_id!)"
@@ -2672,7 +2672,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
     }
     
     func requestEmailContactCenter(_ channel: Int){
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         let complaintId = "CMP_\(idMe!)_\(String(Date().currentTimeMillis()))EML"
         let message = CoreMessage_TMessageBank.getRequestEmailCallCenter(p_channel: channel)
         if let response = Nexilis.writeSync(message: message) {
@@ -2693,7 +2693,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
     }
     
     func requestSMSContactCenter(_ channel: Int){
-//        let idMe = UserDefaults.standard.string(forKey: "me")!
+//        let idMe = User.getMyPin()!
 //        let complaintId = "CMP_\(idMe)_\(String(Date().currentTimeMillis()))SMS"
 //        isRequestContactCenter = true
         var phone = Utils.getSMSCenter()
@@ -2750,10 +2750,10 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                 }
                 if (response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "00") {
                     DispatchQueue.main.async {
-                        UserDefaults.standard.set(true, forKey: "waitingRequestCC")
+                        SecureUserDefaults.shared.set(true, forKey: "waitingRequestCC")
                         let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
                         if data.isEmpty {
-                            UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                            SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                             var row: [String: Any?] = [:]
                             row["message_id"] = ""
                             row["chat_date"] = "Today".localized()
@@ -2774,7 +2774,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     }
                 } else {
                     DispatchQueue.main.async {
-                        UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                        SecureUserDefaults.shared.removeValue(forKey: "waitingRequestCC")
                         var row: [String: Any?] = [:]
                         row["message_id"] = ""
                         row["chat_date"] = "Today".localized()
@@ -2831,7 +2831,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         }
         if let index = dataMessages.firstIndex(where: {$0["message_id"] as? String == message_id}) {
             dataMessages[index]["status"] = "4"
-            let auto = UserDefaults.standard.bool(forKey: "autoDownload")
+            let auto: Bool = SecureUserDefaults.shared.value(forKey: "autoDownload") ?? false
             if auto {
                 if dataMessages[index]["image_id"] as? String != nil && !((dataMessages[index]["image_id"] as? String)!.isEmpty) {
                     if let listGroupImages = self.groupImages.first(where: { $0.key == message_id }) {
@@ -2847,7 +2847,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                                 if let dirPath = paths.first {
                                     let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(valueListGroupImages[i].imageId)
                                     let image    = UIImage(contentsOfFile: imageURL.path)
-                                    let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                                    let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                                     if save {
                                         UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
                                     }
@@ -2872,7 +2872,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                             if let dirPath = paths.first {
                                 let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(self.dataMessages[index]["image_id"] as! String)
                                 let image    = UIImage(contentsOfFile: imageURL.path)
-                                let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                                let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                                 if save {
                                     UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
                                 }
@@ -2896,7 +2896,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
                         if let dirPath = paths.first {
                             let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(self.dataMessages[index]["video_id"] as! String)
-                            let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                            let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                             if save {
                                 PHPhotoLibrary.shared().performChanges({
                                     PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL)
@@ -3069,7 +3069,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
             var listData = dataMessages[0...currentIndexpath!.row]
             listData = listData.filter({$0["status"] as? String != "4" && $0["status"] as? String != "8"})
             if listData.count != 0 && !isContactCenter {
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 for i in 0...listData.count - 1 {
                     if listData[i]["f_pin"] as? String != idMe {
                         sendReadMessageStatus(chat_id: "", f_pin: dataPerson["f_pin"]!!, message_scope_id: "3", message_id: listData[i]["message_id"] as! String)
@@ -3714,7 +3714,7 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
         
         var children: [UIMenuElement] = [star, reply, forward, copy, delete]
 //        let copyOption = self.copyOption(indexPath: indexPath!)
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         if dataMessages[indexPath!.row]["status"] as! String == "0" {
             children = [resend, delete]
         } else if isContactCenter {
@@ -4047,7 +4047,7 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
             if let action = self.actionDelete(for: "me", title: "Delete".localized() + " \(countSelected) " + "For Me".localized(), dataMessages: dataMessages) {
                 alertController.addAction(action)
             }
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let dataFilterFpin = dataMessages.filter({ $0["l_pin"] as? String == idMe})
             let dataFilterLock = dataMessages.filter({ $0["lock"] as? String == "1" || $0["lock"] as? String == "2" })
 //            let statusDataRead = dataMessages.filter({ Int($0["status"] as! String)! >= 4})
@@ -4252,7 +4252,7 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
     }
     
     private func updateProfile() {
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         DispatchQueue.global().async {
             let message = CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: idMe!, last_update: 0)
             let _ = Nexilis.write(message: message)
@@ -4417,7 +4417,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                             default:
                                 (streamingController as! CreateSeminarViewController).data = json
                         }
-                        if json["by"] as? String != UserDefaults.standard.string(forKey: "me") as String? {
+                        if json["by"] as? String != User.getMyPin() as String? {
                             switch(attachmentFlag){
                                 case "27":
                                     (streamingController as! QmeraCreateStreamingViewController).isJoin = true
@@ -4501,7 +4501,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
     }
     
     public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         let dataMessages = dataMessages.filter({$0["chat_date"] as! String == dataDates[indexPath.section]})
         let profileMessage = UIImageView()
         let cell = tableView.dequeueReusableCell(withIdentifier: "cellEditorPersonal", for: indexPath as IndexPath)
@@ -6041,7 +6041,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
 //            }
 //        }
 //        if x <= -(recognizer.view?.frame.size.width ?? 0) * 0.05 {
-//            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//            let idMe = User.getMyPin() as String?
 //            let indexPath = self.tableChatView.indexPath(for: recognizer.view! as! UITableViewCell)
 //            let dataMessages = self.dataMessages.filter({ $0["chat_date"] as! String == dataDates[indexPath!.section]})
 //            if (dataMessages[indexPath!.row]["f_pin"] as? String == idMe) {
@@ -6114,7 +6114,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                         }
                         let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.image_id)
                         let image    = UIImage(contentsOfFile: imageURL.path)
-                        let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                        let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                         if save {
                             UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
                         }
@@ -6176,7 +6176,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                                 shapeLoading.strokeEnd = CGFloat(progress / 100)
                                 return
                             }
-                            let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                            let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                             if save {
                                 let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.video_id)
                                 PHPhotoLibrary.shared().performChanges({
@@ -6275,7 +6275,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                     if let cell = self.tableChatView.cellForRow(at: indexPath) {
                         let containerMessage = cell.contentView.subviews[0]
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if (self.dataMessages[idx!]["f_pin"] as? String == idMe) {
                             containerMessage.backgroundColor = .blueBubbleColor.withAlphaComponent(0.3)
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
@@ -6426,7 +6426,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
 //        if copySession || forwardSession || deleteSession {
 //            return nil
 //        }
-//        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//        let idMe = User.getMyPin() as String?
 //        if (dataMessages[indexPath.row]["f_pin"] as? String != idMe) {
 //            return nil
 //        }
@@ -6503,7 +6503,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
         titleReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
         titleReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor, constant: 10).isActive = true
         titleReply.font = UIFont.systemFont(ofSize: 12).bold
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         if (dataMessages[indexPath.row]["f_pin"] as? String == idMe) {
             titleReply.text = "You".localized()
         } else {
@@ -6638,7 +6638,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                     if let cell = self.tableChatView.cellForRow(at: indexPath) {
                         let containerMessage = cell.contentView.subviews[0]
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if (messageTextForSearch[idx]["f_pin"] as? String == idMe) {
                             containerMessage.backgroundColor = .blueBubbleColor.withAlphaComponent(0.3)
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

+ 6 - 6
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorStarMessages.swift

@@ -171,7 +171,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
     }
     
     public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         let dataMessages = dataMessages.filter({$0["chat_date"] as! String == dataDates[indexPath.section]})
         
         let cellMessage = UITableViewCell()
@@ -1020,7 +1020,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
             } else if day < 7 {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EEEE"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -1031,7 +1031,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
             } else {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EE, dd MMM"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }
@@ -1079,7 +1079,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
                         
                         let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.image_id)
                         let image    = UIImage(contentsOfFile: imageURL.path)
-                        let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                        let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                         if save {
                             UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
                         }
@@ -1142,7 +1142,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
                                 shapeLoading.strokeEnd = CGFloat(progress / 100)
                                 return
                             }
-                            let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                            let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                             if save {
                                 let videoURL = URL(fileURLWithPath: dirPath).appendingPathComponent(sender.video_id)
                                 PHPhotoLibrary.shared().performChanges({
@@ -1241,7 +1241,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                     if let cell = self.tableChatView.cellForRow(at: indexPath) {
                         let containerMessage = cell.contentView.subviews[0]
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if (self.dataMessages[idx!]["f_pin"] as? String == idMe) {
                             containerMessage.backgroundColor = .mainColor.withAlphaComponent(0.3)
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/FormEditor.swift

@@ -139,7 +139,7 @@ class FormEditor: UIViewController {
             descAorR.anchor(top: clubFill.bottomAnchor, left: imageAorR.rightAnchor, right: containerView.rightAnchor, paddingTop: 10, paddingLeft: 10)
             
             let name = UILabel()
-            name.text = User.getData(pin: UserDefaults.standard.string(forKey: "me"))?.fullName
+            name.text = User.getData(pin: User.getMyPin())?.fullName
             name.font = .systemFont(ofSize: 14.0)
             name.textColor = .black
             containerView.addSubview(name)
@@ -304,7 +304,7 @@ class FormEditor: UIViewController {
             return
         }
         DispatchQueue.global().async { [self] in
-            let idMe = UserDefaults.standard.string(forKey: "me")!
+            let idMe = User.getMyPin()!
             let resp = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getFormApproval(p_f_pin: idMe, p_ref_id: refId ?? "", p_approve: "\(isApprove)", p_note: "", p_sign: ""))
             if resp != nil {
 //                Database.shared.database?.inTransaction({ (fmdb, rollback) in

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/ListGroupImages.swift

@@ -339,7 +339,7 @@ class ListGroupImages: UIViewController, UITableViewDataSource, UITableViewDeleg
                         
                         let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(self.listGroupingImages[indexPath.row].imageId)
                         let image    = UIImage(contentsOfFile: imageURL.path)
-                        let save = UserDefaults.standard.bool(forKey: "saveToGallery")
+                        let save: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
                         if save {
                             UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil)
                         }
@@ -565,7 +565,7 @@ class ListGroupImages: UIViewController, UITableViewDataSource, UITableViewDeleg
             if let action = self.actionDelete(for: "me", title: "Delete".localized() + " \(countSelected) " + "For Me".localized(), dataMessages: tempDataMessages) {
                 alertController.addAction(action)
             }
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let dataStatusRead = tempDataMessages.filter({ $0.status == "4" })
             if tempDataMessages[0].dataMessage["f_pin"] as? String == idMe && dataStatusRead.count == 0 {
                 if let action = self.actionDelete(for: "everyone", title: "Delete".localized() + " \(countSelected) " + "For Everyone".localized(), dataMessages: tempDataMessages) {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/MessageInfo.swift

@@ -182,7 +182,7 @@ class MessageInfo: UIViewController, UITableViewDelegate, UITableViewDataSource
     }
     
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         let cell = tableView.dequeueReusableCell(withIdentifier: "cellStatus", for: indexPath as IndexPath)
         cell.selectionStyle = .none
         cell.backgroundColor = .clear
@@ -1038,7 +1038,7 @@ class MessageInfo: UIViewController, UITableViewDelegate, UITableViewDataSource
             } else {
                 let formatter = DateFormatter()
                 formatter.dateFormat = "EE, dd MMM"
-                let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                 if lang == "id" {
                     formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                 }

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Contact/ContactCallViewController.swift

@@ -147,7 +147,7 @@ class ContactCallViewController: UIViewController {
     
     func getData() {
         dataPerson.removeAll()
-        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        let idMe = User.getMyPin() as String?
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, official_account, image_id, device_id, offline_mode, user_type, ex_block, ex_offmp FROM BUDDY where official_account<>'1' and f_pin <> '\(idMe!)' order by 4 desc, 2 collate nocase asc") {
                 while cursorData.next() {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/BackupRestoreView.swift

@@ -95,7 +95,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                         } else {
                             let formatter = DateFormatter()
                             formatter.dateFormat = "dd MMMM yyyy"
-                            let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                            let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                             if lang == "id" {
                                 formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                             }
@@ -912,7 +912,7 @@ public class BackupRestoreView: UIViewController, UITableViewDataSource, UITable
                                         } else {
                                             let formatter = DateFormatter()
                                             formatter.dateFormat = "dd MMMM yyyy"
-                                            let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                                            let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                                             if lang == "id" {
                                                 formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                                             }

+ 3 - 3
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/BroadcastMembersTableViewController.swift

@@ -145,7 +145,7 @@ class BroadcastMembersTableViewController: UITableViewController, UISearchContro
         DispatchQueue.global().async {
             Database.shared.database?.inTransaction({ (fmdb, rollback) in
                 do {
-                    if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, image_id, official_account, user_type FROM BUDDY where f_pin <> '\(UserDefaults.standard.string(forKey: "me")!)' order by 5 desc, 2 collate nocase asc") {
+                    if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, image_id, official_account, user_type FROM BUDDY where f_pin <> '\(User.getMyPin()!)' order by 5 desc, 2 collate nocase asc") {
                         while cursorData.next() {
                             let user = User(pin: cursorData.string(forColumnIndex: 0) ?? "",
                                             firstName: cursorData.string(forColumnIndex: 1) ?? "",
@@ -221,7 +221,7 @@ class BroadcastMembersTableViewController: UITableViewController, UISearchContro
 //                
 //                if !group.id.isEmpty {
 //                    if group.official == "1" {
-//                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//                        let idMe = User.getMyPin() as String?
 //                        if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type FROM BUDDY where f_pin='\(idMe!)'"), cursorUser.next() {
 //                            if cursorUser.string(forColumnIndex: 0) == "23" || cursorUser.string(forColumnIndex: 0) == "24" {
 //                                group.childs.append(contentsOf: getGroupRecursive(fmdb: fmdb, parent: group.id))
@@ -250,7 +250,7 @@ class BroadcastMembersTableViewController: UITableViewController, UISearchContro
     }
     
     private func pullBuddy() {
-        if let me = UserDefaults.standard.string(forKey: "me") {
+        if let me = User.getMyPin() {
             DispatchQueue.global().async {
                 let _ = Nexilis.write(message: CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: me, last_update: 0))
             }

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/BroadcastViewController.swift

@@ -102,7 +102,7 @@ class BroadcastViewController: UITableViewController, UITextFieldDelegate, UITex
         super.viewDidLoad()
         
         DispatchQueue.global().async {
-            let me = UserDefaults.standard.string(forKey: "me")!
+            let me = User.getMyPin()!
             _ = Nexilis.write(message: CoreMessage_TMessageBank.getFormList(p_pin: me, p_last_id: "0"))
         }
         

+ 3 - 3
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangeDeviceViewController.swift

@@ -136,7 +136,7 @@ public class ChangeDeviceViewController: UIViewController {
                         if(!id.isEmpty) {
 //                            Nexilis.changeUser(f_pin: id)
                             Utils.setProfile(value: true)
-                            UserDefaults.standard.synchronize()
+                            SecureUserDefaults.shared.sync()
                             // pos registration
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                             DispatchQueue.main.async {
@@ -256,9 +256,9 @@ public class ChangeDeviceViewController: UIViewController {
                     //print("last sign: \(last_sign)")
                     if(!id.isEmpty) {
 //                        Nexilis.changeUser(f_pin: device_id)
-                        UserDefaults.standard.setValue(device_id, forKey: "device_id")
+                        SecureUserDefaults.shared.set(device_id, forKey: "device_id")
                         Utils.setProfile(value: true)
-                        UserDefaults.standard.synchronize()
+                        SecureUserDefaults.shared.sync()
                         // pos registration
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                         DispatchQueue.main.async {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangeNamePassswordViewController.swift

@@ -125,7 +125,7 @@ public class ChangeNamePassswordViewController: UIViewController {
             return
         }
         
-        let idMe = UserDefaults.standard.string(forKey: "me")!
+        let idMe = User.getMyPin()!
         
         if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
             let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
@@ -159,7 +159,7 @@ public class ChangeNamePassswordViewController: UIViewController {
                                 _ = Database.shared.updateRecord(fmdb: fmdb, table: "BUDDY", cvalues: ["first_name": first , "last_name": last], _where: "f_pin = '\(idMe)'")
                             })
                             Utils.setProfile(value: true)
-                            UserDefaults.standard.synchronize()
+                            SecureUserDefaults.shared.sync()
         //                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                             DispatchQueue.main.async {
                                 Nexilis.hideLoader(completion: {

+ 1 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangePasswordViewController.swift

@@ -60,7 +60,6 @@ class ChangePasswordViewController: UIViewController {
             banner.show()
             return
         }
-//        if odlPassword != UserDefaults.standard.string(forKey: "pwd"){
 //            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
 //            imageView.tintColor = .white
 //            let banner = FloatingNotificationBanner(title: "Incorrect old password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
@@ -81,7 +80,7 @@ class ChangePasswordViewController: UIViewController {
             banner.show()
             return
         }
-        let idMe = UserDefaults.standard.string(forKey: "me")!
+        let idMe = User.getMyPin()!
         DispatchQueue.global().async {
             let tMessage = CoreMessage_TMessageBank.getChangePersonInfo_New(p_f_pin: idMe)
             let md5HexOld = oldPassword

+ 9 - 9
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ContactChatViewController.swift

@@ -83,7 +83,7 @@ class ContactChatViewController: UITableViewController {
     
     override func viewDidLoad() {
         super.viewDidLoad()
-        let me = UserDefaults.standard.string(forKey: "me")!
+        let me = User.getMyPin()!
         Database.shared.database?.inTransaction({ fmdb, rollback in
             if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select FIRST_NAME, LAST_NAME, IMAGE_ID, USER_TYPE from BUDDY where F_PIN = '\(me)'"), cursor.next() {
                 isAdmin = cursor.string(forColumnIndex: 3) == "23" || cursor.string(forColumnIndex: 3) == "24"
@@ -278,7 +278,7 @@ class ContactChatViewController: UITableViewController {
     
     @objc func onReload(notification: NSNotification) {
         let data:[AnyHashable : Any] = notification.userInfo!
-        if data["member"] as? String == UserDefaults.standard.string(forKey: "me") {
+        if data["member"] as? String == User.getMyPin() {
             DispatchQueue.main.async {
                 self.getData()
             }
@@ -408,7 +408,7 @@ class ContactChatViewController: UITableViewController {
         contacts.append(gptUser)
         DispatchQueue.global().async {
             Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, image_id, official_account, user_type FROM BUDDY where f_pin <> '\(UserDefaults.standard.string(forKey: "me")!)' order by 5 desc, 2 collate nocase asc") {
+                if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, image_id, official_account, user_type FROM BUDDY where f_pin <> '\(User.getMyPin()!)' order by 5 desc, 2 collate nocase asc") {
                     while cursorData.next() {
                         let user = User(pin: cursorData.string(forColumnIndex: 0) ?? "",
                                         firstName: cursorData.string(forColumnIndex: 1) ?? "",
@@ -483,7 +483,7 @@ class ContactChatViewController: UITableViewController {
                 
                 if !group.id.isEmpty {
 //                    if group.official == "1" {
-//                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//                        let idMe = User.getMyPin() as String?
 //                        if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type FROM BUDDY where f_pin='\(idMe!)'"), cursorUser.next() {
 ////                            if cursorUser.string(forColumnIndex: 0) == "23" || cursorUser.string(forColumnIndex: 0) == "24" {
 ////                                group.childs.append(contentsOf: getGroupRecursive(fmdb: fmdb, parent: group.id))
@@ -550,7 +550,7 @@ class ContactChatViewController: UITableViewController {
     }
     
     private func pullBuddy() {
-        if let me = UserDefaults.standard.string(forKey: "me") {
+        if let me = User.getMyPin() {
             DispatchQueue.global().async {
                 let _ = Nexilis.write(message: CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: me, last_update: 0))
             }
@@ -560,7 +560,7 @@ class ContactChatViewController: UITableViewController {
     private func joinOpenGroup(groupId: String, flagMember: String = "0", completion: @escaping (Bool) -> ()) {
         DispatchQueue.global().async {
             var result: Bool = false
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getAddGroupMember(p_group_id: groupId, p_member_pin: idMe!, p_position: "0")), response.isOk() {
                 result = true
             }
@@ -765,7 +765,7 @@ extension ContactChatViewController {
         }
         if group.childs.count == 0 {
             Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 if let cursorMember = Database.shared.getRecords(fmdb: fmdb, query: "select f_pin from GROUPZ_MEMBER where group_id = '\(group.id)' and f_pin = '\(idMe!)'"), cursorMember.next() {
                     let groupId = group.chatId.isEmpty ? group.id : group.chatId
                     if let chooser = isChooser {
@@ -1085,7 +1085,7 @@ extension ContactChatViewController {
                     data.messageText = data.messageText.trimmingCharacters(in: .whitespacesAndNewlines)
                 }
                 let text = Utils.previewMessageText(chat: data)
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 if let attributeText = text as? NSMutableAttributedString {
                     let stringMessage = NSMutableAttributedString(string: "")
                     if data.fpin == idMe {
@@ -1162,7 +1162,7 @@ extension ContactChatViewController {
                         if day < 7 {
                             let formatter = DateFormatter()
                             formatter.dateFormat = "EEEE"
-                            let lang = UserDefaults.standard.string(forKey: "i18n_language")
+                            let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
                             if lang == "id" {
                                 formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
                             }

+ 9 - 9
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/GroupDetailViewController.swift

@@ -103,7 +103,7 @@ class GroupDetailViewController: UITableViewController {
         getData { group in
             self.group = group
             if let myData = self.group?.members.first(where: { member in
-                return member.pin == UserDefaults.standard.string(forKey: "me")!
+                return member.pin == User.getMyPin()!
             }) {
                 if myData.position == "1" {
                     self.isAdmin = true
@@ -209,11 +209,11 @@ class GroupDetailViewController: UITableViewController {
     
     @objc func updateData(notification: NSNotification) {
         let data:[AnyHashable : Any] = notification.userInfo!
-        if data["code"] as! String == "A008" && data["member"] as! String == UserDefaults.standard.string(forKey: "me")! {
+        if data["code"] as! String == "A008" && data["member"] as! String == User.getMyPin()! {
             DispatchQueue.main.async {
                 self.navigationController?.popViewController(animated: true)
             }
-        } else if data["f_pin"] as! String != UserDefaults.standard.string(forKey: "me")! || data["code"] as! String == "BD" {
+        } else if data["f_pin"] as! String != User.getMyPin()! || data["code"] as! String == "BD" {
             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                 self.reload()
             }
@@ -446,7 +446,7 @@ class GroupDetailViewController: UITableViewController {
                                 })
                                 var data: [AnyHashable : Any] = [:]
                                 data["code"] = CoreMessage_TMessageCode.DELETE_CHAT
-                                data["f_pin"] = UserDefaults.standard.string(forKey: "me")!
+                                data["f_pin"] = User.getMyPin()!
                                 data["topicId"] = topic.chatId
                                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onTopic"), object: nil, userInfo: data)
                                 DispatchQueue.main.async {
@@ -522,7 +522,7 @@ class GroupDetailViewController: UITableViewController {
                 navigationController?.present(navController, animated: true)
             } else if let g = group, isAdmin {
                 let member = g.members[indexPath.row - 1]
-                if member.pin != UserDefaults.standard.string(forKey: "me")! {
+                if member.pin != User.getMyPin()! {
                     if member.pin == g.by {
                         let data = User.getDataCanNil(pin: member.pin)
                         let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
@@ -595,7 +595,7 @@ class GroupDetailViewController: UITableViewController {
                 }
             } else if let g = group {
                 let member = g.members[indexPath.row]
-                if member.pin == UserDefaults.standard.string(forKey: "me") {
+                if member.pin == User.getMyPin() {
                     // skip self profile
                     return
                 }
@@ -613,7 +613,7 @@ class GroupDetailViewController: UITableViewController {
             }
         case .exit:
             if let g = group {
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 let admins = g.members.filter { member in
                     return member.position == "1"
                 }
@@ -633,7 +633,7 @@ class GroupDetailViewController: UITableViewController {
                 }
                 let alert = LibAlertController(title: nil, message: message, preferredStyle: .actionSheet)
                 alert.addAction(UIAlertAction(title: isDeleted ? "Delete Group".localized() : "Exit Group".localized(), style: .destructive, handler: { action in
-                    self.exitGroup(pin: isDeleted ? "ALL": UserDefaults.standard.string(forKey: "me")!) { result in
+                    self.exitGroup(pin: isDeleted ? "ALL": User.getMyPin()!) { result in
                         if result {
                             DispatchQueue.main.async {
                                 self.navigationController?.popToRootViewController(animated: true)
@@ -906,7 +906,7 @@ class GroupDetailViewController: UITableViewController {
         case .exit:
             let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
             if let g = group {
-                let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                let idMe = User.getMyPin() as String?
                 let admins = g.members.filter { member in
                     return member.position == "1"
                 }

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/HistoryBroadcastViewController.swift

@@ -38,7 +38,7 @@ class HistoryBroadcastViewController: UIViewController, UITableViewDelegate, UIT
         navigationController?.navigationBar.standardAppearance = navBarAppearance
         navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
         
-        let me = UserDefaults.standard.string(forKey: "me")!
+        let me = User.getMyPin()!
         Database.shared.database?.inTransaction({ fmdb, rollback in
             if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select FIRST_NAME, LAST_NAME, IMAGE_ID, USER_TYPE from BUDDY where F_PIN = '\(me)'"), cursor.next() {
                 isAdmin = cursor.string(forColumnIndex: 3) == "23" || cursor.string(forColumnIndex: 3) == "24"

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/HistoryCCViewController.swift

@@ -196,7 +196,7 @@ public class HistoryCCViewController: UITableViewController, QLPreviewController
         let date = Date(milliseconds: Int64(stringDate) ?? 0)
         let formatter = DateFormatter()
         formatter.dateFormat = "dd MMMM yyyy"
-        let lang = UserDefaults.standard.string(forKey: "i18n_language")
+        let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
         if lang == "id" {
             formatter.locale = NSLocale(localeIdentifier: "id") as Locale?
         }

+ 4 - 4
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/NotificationSound.swift

@@ -51,9 +51,9 @@ public class NotificationSound: UIViewController, UITableViewDelegate, UITableVi
         data.append(NotifSound(id: 1010, name: "sms-received4", isSelected: false))
         data.append(NotifSound(id: 1013, name: "sms-received5", isSelected: false))
         data.append(NotifSound(id: 1014, name: "sms-received6", isSelected: false))
-        var selectedSound = UserDefaults.standard.string(forKey: "notifSoundPersonal") ?? ""
+        var selectedSound: String = SecureUserDefaults.shared.value(forKey: "notifSoundPersonal") ?? ""
         if !isPersonal {
-            selectedSound = UserDefaults.standard.string(forKey: "notifSoundGroup") ?? ""
+            selectedSound = SecureUserDefaults.shared.value(forKey: "notifSoundGroup") ?? ""
         }
         if !selectedSound.isEmpty {
             let selectedSoundId = Int(selectedSound.components(separatedBy: ":")[0])
@@ -78,9 +78,9 @@ public class NotificationSound: UIViewController, UITableViewDelegate, UITableVi
     @objc func save(sender: Any) {
         let idx = data.firstIndex(where: {$0.id == isSelectedSound})
         if isPersonal {
-            UserDefaults.standard.set("\(data[idx!].id):\(data[idx!].name)", forKey: "notifSoundPersonal")
+            SecureUserDefaults.shared.set("\(data[idx!].id):\(data[idx!].name)", forKey: "notifSoundPersonal")
         } else {
-            UserDefaults.standard.set("\(data[idx!].id):\(data[idx!].name)", forKey: "notifSoundGroup")
+            SecureUserDefaults.shared.set("\(data[idx!].id):\(data[idx!].name)", forKey: "notifSoundGroup")
         }
         navigationController?.dismiss(animated: true, completion: nil)
     }

+ 13 - 14
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ProfileViewController.swift

@@ -85,9 +85,9 @@ public class ProfileViewController: UITableViewController {
                     guard let user = user else {
                         return
                     }
-                    if let me = UserDefaults.standard.string(forKey: "me"), me == self.data || self.flag == Flag.me {
+                    if let me = User.getMyPin(), me == self.data || self.flag == Flag.me {
                         Database.shared.database?.inTransaction({ fmdb, rollback in
-                            let idMe = UserDefaults.standard.string(forKey: "me")!
+                            let idMe = User.getMyPin()!
                             if let cursorCount = Database.shared.getRecords(fmdb: fmdb, query: "select COUNT(*) from BUDDY where f_pin <> '\(idMe)' and first_name NOT LIKE 'USR%' "), cursorCount.next() {
                                 let count = cursorCount.string(forColumnIndex: 0)!
                                 self.countFriend.text = count + " " + "Friends".localized()
@@ -140,7 +140,7 @@ public class ProfileViewController: UITableViewController {
                 var r: User?
                 r = User.getData(pin: self.data)
                 Database.shared.database?.inTransaction({ fmdb, rollback in
-                    let idMe = UserDefaults.standard.string(forKey: "me")!
+                    let idMe = User.getMyPin()!
                     if let cursorCount = Database.shared.getRecords(fmdb: fmdb, query: "select COUNT(*) from BUDDY where f_pin <> '\(idMe)' and first_name NOT LIKE 'USR%' "), cursorCount.next() {
                         DispatchQueue.main.async {
                             self.countFriend.text = cursorCount.string(forColumnIndex: 0) ?? "" + " " + "Friends".localized()
@@ -172,9 +172,9 @@ public class ProfileViewController: UITableViewController {
 //            navigationItem.rightBarButtonItem?.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: .normal)
 //        }
         if fromListFriend {
-            if let me = UserDefaults.standard.string(forKey: "me"), me == self.data || self.flag == Flag.me {
+            if let me = User.getMyPin(), me == self.data || self.flag == Flag.me {
                 Database.shared.database?.inTransaction({ fmdb, rollback in
-                    let idMe = UserDefaults.standard.string(forKey: "me")!
+                    let idMe = User.getMyPin()!
                     if let cursorCount = Database.shared.getRecords(fmdb: fmdb, query: "select COUNT(*) from BUDDY where f_pin <> '\(idMe)' and first_name NOT LIKE 'USR%'"), cursorCount.next() {
                         let count = cursorCount.string(forColumnIndex: 0)!
                         self.countFriend.text = count + " " + "Friends".localized()
@@ -190,7 +190,7 @@ public class ProfileViewController: UITableViewController {
     }
     
     public override func viewDidAppear(_ animated: Bool) {
-        if let me = UserDefaults.standard.string(forKey: "me"), me == data || flag == Flag.me || flag == Flag.friend {
+        if let me = User.getMyPin(), me == data || flag == Flag.me || flag == Flag.friend {
             reload()
         }
     }
@@ -236,7 +236,7 @@ public class ProfileViewController: UITableViewController {
         buttonEditpass.tintColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .black
         buttonHistoryCC.tintColor = self.traitCollection.userInterfaceStyle == .dark ? .secondaryColor : .black
         
-        if let me = UserDefaults.standard.string(forKey: "me"), me == data || flag == Flag.me {
+        if let me = User.getMyPin(), me == data || flag == Flag.me {
             buttonGroup.removeFromSuperview()
             navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Edit".localized(), style: .plain, target: self, action: #selector(didTapEdit(sender:)))
             imageVideoPicker = ImageVideoPicker(presentationController: self, delegate: self)
@@ -506,7 +506,7 @@ public class ProfileViewController: UITableViewController {
                 }))
                 firstAlert.addAction(UIAlertAction(title: "Remove Profile Picture".localized(), style: .default, handler: { action in
                     if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getChangePersonImage(thumb_id: "")), response.isOk() {
-                        guard let me = UserDefaults.standard.string(forKey: "me") else {
+                        guard let me = User.getMyPin() else {
                             return
                         }
                         Database.shared.database?.inTransaction({ fmdb, rollback in
@@ -669,13 +669,13 @@ public class ProfileViewController: UITableViewController {
     }
     
     @objc func profileTapped() {
-        if let me = UserDefaults.standard.string(forKey: "me"), me == data || flag == Flag.me {
+        if let me = User.getMyPin(), me == data || flag == Flag.me {
             didTapProfile()
         }
     }
     
     @objc func friendsTapped() {
-        if let me = UserDefaults.standard.string(forKey: "me"), me == data || flag == Flag.me {
+        if let me = User.getMyPin(), me == data || flag == Flag.me {
             let controller = QmeraCallContactViewController()
             controller.isInviteCC = true
             controller.listFriends = true
@@ -686,7 +686,7 @@ public class ProfileViewController: UITableViewController {
     
     public override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
         if indexPath.section == 1 {
-            if let me = UserDefaults.standard.string(forKey: "me"), me == data || flag == Flag.me {
+            if let me = User.getMyPin(), me == data || flag == Flag.me {
                 return 170
             }
             return 56
@@ -696,7 +696,7 @@ public class ProfileViewController: UITableViewController {
     }
     
     private func pullBuddy() {
-        if let me = UserDefaults.standard.string(forKey: "me") {
+        if let me = User.getMyPin() {
             DispatchQueue.global().async {
                 let _ = Nexilis.write(message: CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: me, last_update: 0))
             }
@@ -708,7 +708,7 @@ extension ProfileViewController: ImageVideoPickerDelegate {
     
     public func didSelect(imagevideo: Any?) {
         if let info = imagevideo as? [UIImagePickerController.InfoKey: Any], let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
-            guard let me = UserDefaults.standard.string(forKey: "me") else {
+            guard let me = User.getMyPin() else {
                 return
             }
             DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
@@ -768,7 +768,6 @@ extension ProfileViewController: ImageVideoPickerDelegate {
     
 }
 
-//let auto = UserDefaults.standard.bool(forKey: "autoDownload")
 //if auto {
 //    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
 //        let objectTapAuto = ObjectGesture()

+ 18 - 18
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SettingTableViewController.swift

@@ -47,9 +47,9 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
         switchVibrateMode.onTintColor = .mainColor
         switchSaveToGallery.onTintColor = .mainColor
         switchAutoDownload.onTintColor = .mainColor
-        let vibrateMode = UserDefaults.standard.bool(forKey: "vibrateMode")
-        let saveGallery = UserDefaults.standard.bool(forKey: "saveToGallery")
-        let autoDownload = UserDefaults.standard.bool(forKey: "autoDownload")
+        let vibrateMode: Bool = SecureUserDefaults.shared.value(forKey: "vibrateMode") ?? false
+        let saveGallery: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
+        let autoDownload: Bool = SecureUserDefaults.shared.value(forKey: "autoDownload") ?? false
         if vibrateMode {
             switchVibrateMode.setOn(true, animated: false)
         }
@@ -74,7 +74,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
     }
     
     @objc func vibrateModeSwitch() {
-        UserDefaults.standard.set(switchVibrateMode.isOn, forKey: "vibrateMode")
+        SecureUserDefaults.shared.set(switchVibrateMode.isOn, forKey: "vibrateMode")
     }
     
     @objc func saveToGallerySwitch() {
@@ -82,25 +82,25 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
             PHPhotoLibrary.requestAuthorization({status in
                 DispatchQueue.main.async {
                     if status == .authorized {
-                        UserDefaults.standard.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
+                        SecureUserDefaults.shared.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
                     } else {
                         self.switchSaveToGallery.setOn(false, animated: true)
                     }
                 }
             })
         } else {
-            UserDefaults.standard.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
+            SecureUserDefaults.shared.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
         }
     }
     
     @objc func autoDownloadSwitch() {
-        UserDefaults.standard.set(switchAutoDownload.isOn, forKey: "autoDownload")
+        SecureUserDefaults.shared.set(switchAutoDownload.isOn, forKey: "autoDownload")
     }
     
     func makeMenu(imageSignIn: String = ""){
         let isChangeProfile = Utils.getSetProfile()
         Database.shared.database?.inTransaction({ fmdb, rollback in
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type, image_id, official_account FROM BUDDY where f_pin='\(idMe!)'"), cursorUser.next() {
                 if (User.isInternal(userType: cursorUser.string(forColumnIndex: 0) ?? "") && User.isAdmin(fmdb: fmdb)) || User.isOfficial(official_account: cursorUser.string(forColumnIndex: 2) ?? "") || User.isOfficial(official_account: cursorUser.string(forColumnIndex: 2) ?? "") {
                     Item.menus["Personal"] = [
@@ -408,7 +408,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
         if item.title == "Personal Information".localized() {
             if(Nexilis.checkIsChangePerson()){
                 let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
-                controller.data = UserDefaults.standard.string(forKey: "me")!
+                controller.data = User.getMyPin()!
                 controller.flag = .me
                 controller.dismissImage = { image, imageName in
                     var dataImage: [AnyHashable : Any] = [:]
@@ -455,7 +455,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
             pickerView.dataSource = self
             pickerView.delegate = self
             
-            let lang = UserDefaults.standard.string(forKey: "i18n_language")
+            let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
             var index = 1
             if lang == "id" {
                 index = 0
@@ -476,7 +476,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
             alert.addAction(UIAlertAction(title: "Select".localized(), style: .default, handler: { (UIAlertAction) in
                 let selectedIndex = pickerView.selectedRow(inComponent: 0)
                 let lang = self.language[selectedIndex].values.first
-                UserDefaults.standard.set(lang, forKey: "i18n_language")
+                SecureUserDefaults.shared.set(lang, forKey: "i18n_language")
                 self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
                 self.navigationController?.navigationBar.setNeedsLayout()
                 self.makeMenu()
@@ -516,12 +516,12 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                         id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         if(!id.isEmpty){
 //                            Nexilis.changeUser(f_pin: id)
-                            UserDefaults.standard.setValue(id, forKey: "me")
+                            SecureUserDefaults.shared.set(id, forKey: "me")
                             Utils.setProfile(value: false)
-                            UserDefaults.standard.synchronize()
+                            SecureUserDefaults.shared.sync()
                             if Utils.getForceAnonymous() {
                                 self.deleteAllRecordDatabase()
-                                UserDefaults.standard.removeObject(forKey: "device_id")
+                                SecureUserDefaults.shared.removeValue(forKey: "device_id")
                                 Nexilis.destroyAll()
                                 _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                             }
@@ -905,7 +905,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
     
     private func signInAdmin(password: String, completion: @escaping (Bool) -> ()) {
         DispatchQueue.global().async {
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let p_password = password
             let md5Hex = p_password
             var result: Bool = false
@@ -940,7 +940,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
     
     private func signInInternal(password: String, completion: @escaping (Bool) -> ()) {
         DispatchQueue.global().async {
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let p_password = password
             let md5Hex = p_password
             var result: Bool = false
@@ -975,7 +975,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
     
     private func changePasswordAdmin(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
         DispatchQueue.global().async {
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let p_password = oldPassword
             let n_password = newPassword
             let md5Hex = p_password
@@ -1012,7 +1012,7 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
     
     private func changePasswordInternal(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
         DispatchQueue.global().async {
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+            let idMe = User.getMyPin() as String?
             let p_password = oldPassword
             let n_password = newPassword
             let md5Hex = p_password

+ 5 - 5
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SignUpSignIn.swift

@@ -157,7 +157,7 @@ public class SignUpSignIn: UIViewController {
                         if(!id.isEmpty) {
 //                            Nexilis.changeUser(f_pin: id)
                             Utils.setProfile(value: true)
-                            UserDefaults.standard.synchronize()
+                            SecureUserDefaults.shared.sync()
                             // pos registration
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                             DispatchQueue.main.async {
@@ -234,7 +234,7 @@ public class SignUpSignIn: UIViewController {
             return
         }
         
-        let idMe = UserDefaults.standard.string(forKey: "me")!
+        let idMe = User.getMyPin()!
         
         if isValidEmail(name) {
             checkEmail(email: name)
@@ -359,9 +359,9 @@ public class SignUpSignIn: UIViewController {
                         self.deleteAllRecordDatabase()
                         if(!id.isEmpty) {
 //                            Nexilis.changeUser(f_pin: device_id)
-                            UserDefaults.standard.setValue(device_id, forKey: "device_id")
+                            SecureUserDefaults.shared.set(device_id, forKey: "device_id")
                             Utils.setProfile(value: true)
-                            UserDefaults.standard.synchronize()
+                            SecureUserDefaults.shared.sync()
                             // pos registration
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                             DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
@@ -405,7 +405,7 @@ public class SignUpSignIn: UIViewController {
                             }
                         })
                         Utils.setProfile(value: true)
-                        UserDefaults.standard.synchronize()
+                        SecureUserDefaults.shared.sync()
     //                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                         DispatchQueue.main.async {
                             Nexilis.hideLoader(completion: {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/CreateSeminarViewController.swift

@@ -229,7 +229,7 @@ public class CreateSeminarViewController: UITableViewController {
                 
                 data["title"] = streamingTitle
                 data["description"] = streamingDesc
-                data["by"] = UserDefaults.standard.string(forKey: "me") ?? ""
+                data["by"] = User.getMyPin() ?? ""
                 data["time"] = Date().currentTimeMillis()
                 data["blog"] = id
                 
@@ -301,7 +301,7 @@ public class CreateSeminarViewController: UITableViewController {
 //                Nexilis.saveMessageBot(textMessage: json, blog_id: data["blog"] as? String ?? "", attachment_type: "26")
                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
             }
-            controller.data = UserDefaults.standard.string(forKey: "me")!
+            controller.data = User.getMyPin()!
             controller.streamingData = data
         }
         navigationController?.show(controller, sender: nil)

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/CreateViewController.swift

@@ -91,7 +91,7 @@ class CreateViewController: UITableViewController {
             var data: [String: Any] = [:]
             data["title"] = streamingTitle
             data["description"] = streamingDesc
-            data["by"] = UserDefaults.standard.string(forKey: "me") ?? ""
+            data["by"] = User.getMyPin() ?? ""
             data["tagline"] = streamingTag.text ?? ""
             data["time"] = Date().currentTimeMillis()
             data["blog"] = id
@@ -139,7 +139,7 @@ class CreateViewController: UITableViewController {
             } else {
                 showToast(message: "No Network. Please try again.".localized(), font: UIFont.systemFont(ofSize: 12), controller: self)
             }
-            controller.data = UserDefaults.standard.string(forKey: "me")!
+            controller.data = User.getMyPin()!
             controller.streamingData = data
         }
         navigationController?.show(controller, sender: nil)

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraCreateStreamingViewController.swift

@@ -255,7 +255,7 @@ public class QmeraCreateStreamingViewController: UITableViewController {
                 
                 data["title"] = streamingTitle
                 data["description"] = streamingDesc
-                data["by"] = UserDefaults.standard.string(forKey: "me") ?? ""
+                data["by"] = User.getMyPin() ?? ""
                 data["tagline"] = taglineView.text ?? ""
                 data["time"] = Date().currentTimeMillis()
                 data["blog"] = id
@@ -342,7 +342,7 @@ public class QmeraCreateStreamingViewController: UITableViewController {
                 Nexilis.saveMessageBot(textMessage: json, blog_id: data["blog"] as? String ?? "", attachment_type: "27")
                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
             }
-            controller.data = UserDefaults.standard.string(forKey: "me")!
+            controller.data = User.getMyPin()!
             controller.streamingData = data
         }
         navigationController?.show(controller, sender: nil)

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraGroupChooserViewController.swift

@@ -103,7 +103,7 @@ class QmeraGroupStreamingViewController: UITableViewController {
                             isOpen: cursor.string(forColumnIndex: 8) ?? "",
                             official: cursor.string(forColumnIndex: 9) ?? "",
                             isEducation: cursor.string(forColumnIndex: 10) ?? "")
-                        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+                        let idMe = User.getMyPin() as String?
                         if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type FROM BUDDY where f_pin='\(idMe!)'"), cursorUser.next() {
                             if cursorUser.string(forColumnIndex: 0) != "23" && cursorUser.string(forColumnIndex: 0) != "24" {
                                 if !group.parent.isEmpty && group.official == "1" {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraStreamingViewController.swift

@@ -334,7 +334,7 @@ class QmeraStreamingViewController: UIViewController {
     }
     
     @objc func liked(sender: Any?) {
-        guard let me = User.getDataCanNil(pin: UserDefaults.standard.string(forKey: "me")) else {
+        guard let me = User.getDataCanNil(pin: User.getMyPin()) else {
             return
         }
         if liked {
@@ -354,7 +354,7 @@ class QmeraStreamingViewController: UIViewController {
         guard let text = textView.text, !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
             return
         }
-        guard let me = User.getDataCanNil(pin: UserDefaults.standard.string(forKey: "me")) else {
+        guard let me = User.getDataCanNil(pin: User.getMyPin()) else {
             return
         }
         chats.append(StreamingChat(name: "You".localized(), thumb: me.thumb, messageText: text.trimmingCharacters(in: .whitespacesAndNewlines)))

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/QmeraUserChooserViewController.swift

@@ -90,7 +90,7 @@ class QmeraUserChooserViewController: UITableViewController {
     }
     
     private func pullBuddy() {
-        if let me = UserDefaults.standard.string(forKey: "me") {
+        if let me = User.getMyPin() {
             DispatchQueue.global().async {
                 let _ = Nexilis.write(message: CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: me, last_update: 0))
             }
@@ -103,7 +103,7 @@ class QmeraUserChooserViewController: UITableViewController {
         DispatchQueue.global().async {
             Database.shared.database?.inTransaction({ (fmdb, rollback) in
                 var r: [User] = []
-                if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, image_id FROM BUDDY where f_pin not in (\(self.ignored.map{ "'\($0.pin)'" }.joined(separator: ","))) and f_pin <> '\(UserDefaults.standard.string(forKey: "me")!)' and official_account <> 1 order by 2 collate nocase asc") {
+                if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, image_id FROM BUDDY where f_pin not in (\(self.ignored.map{ "'\($0.pin)'" }.joined(separator: ","))) and f_pin <> '\(User.getMyPin()!)' and official_account <> 1 order by 2 collate nocase asc") {
                     while cursorData.next() {
                         let user = User(pin: cursorData.string(forColumnIndex: 0) ?? "",
                                             firstName: cursorData.string(forColumnIndex: 1) ?? "",

+ 6 - 6
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Streaming/SeminarViewController.swift

@@ -422,7 +422,7 @@ class SeminarViewController: UIViewController {
         guard let text = textView.text, !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
             return
         }
-        guard let me = User.getDataCanNil(pin: UserDefaults.standard.string(forKey: "me")) else {
+        guard let me = User.getDataCanNil(pin: User.getMyPin()) else {
             return
         }
         chats.append(SeminarChat(name: "You".localized(), thumb: me.thumb, messageText: text.trimmingCharacters(in: .whitespacesAndNewlines)))
@@ -518,7 +518,7 @@ class SeminarViewController: UIViewController {
     }
     
     @objc func raiseHand(sender: Any?) {
-        guard let me = User.getDataCanNil(pin: UserDefaults.standard.string(forKey: "me")) else {
+        guard let me = User.getDataCanNil(pin: User.getMyPin()) else {
             return
         }
         let status = hasRaiseHand ? "0" : "1"
@@ -562,7 +562,7 @@ class SeminarViewController: UIViewController {
                 return
             }
             mIsSwitch = !mIsSwitch
-            let me = UserDefaults.standard.string(forKey: "me")
+            let me = User.getMyPin()
             if currentSpeakingVW == me {
                 if mIsSwitch {
                     adjust(viewOnFront: ivRemoteViewM, viewOnBack: tvCameraPreviewS)
@@ -587,7 +587,7 @@ class SeminarViewController: UIViewController {
             adjust(viewOnFront: ivRemoteViewS, viewOnBack: tvCameraPreviewB)
             mIsSwitch = false
         } else {
-            let me = UserDefaults.standard.string(forKey: "me")
+            let me = User.getMyPin()
             if currentSpeakingVW == me {
                 adjust(viewOnFront: tvCameraPreviewS, viewOnBack: ivRemoteViewS)
             } else {
@@ -844,7 +844,7 @@ extension SeminarViewController: SeminarDelegate {
         } else if state == 43 { // startAudience (4* is from Audience PoV)
             let m = message.split(separator: ",")
             let f_pin = String(m[0])
-            let me = UserDefaults.standard.string(forKey: "me")
+            let me = User.getMyPin()
             DispatchQueue.main.async {
                 self.tvCameraPreviewS.removeConstraints(self.tvCameraPreviewS.constraints)
                 self.tvCameraPreviewS.anchor(top: self.view.topAnchor, left: self.view.leftAnchor, bottom: self.view.bottomAnchor, right: self.view.rightAnchor)
@@ -881,7 +881,7 @@ extension SeminarViewController: SeminarDelegate {
                     if self.mIsSwitch {
                         self.forceRevertSwitch()
                     }
-                    let me = UserDefaults.standard.string(forKey: "me")
+                    let me = User.getMyPin()
                     if me == f_pin {
                         self.currentSpeakingVW = "-666"
                     }

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/Whiteboard.swift

@@ -60,7 +60,7 @@ public class Whiteboard: WhiteboardDelegate {
     
     public func sendInit(destinations: String){
         canvas?.setLineColor(color: UIColor(hexString: "FF000000"))
-        let me = UserDefaults.standard.string(forKey: "me")!
+        let me = User.getMyPin()!
         let tid = CoreMessage_TMessageUtil.getTID()
         roomId = "\(me)wbvc\(tid)"
         _ = Nexilis.writeDraw(data: "WB/0/\(roomId)/\(destinations)")

+ 4 - 4
appbuilder-ios/NexilisLite/NexilisLite/Source/WhiteboardCanvas.swift

@@ -105,11 +105,11 @@ public class WhiteboardCanvas: UIView {
         let dx = abs(touchPoint.x - startingPoint.x)
         let dy = abs(touchPoint.x - startingPoint.x)
         if (dx >= fRThreshold || dy >= fRThreshold) {
-            let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
+            let onGoingCC: String = SecureUserDefaults.shared.value(forKey: "onGoingCC") ?? ""
             if !onGoingCC.isEmpty {
                 var colorDraw = UIColor.red
                 let requester = onGoingCC.components(separatedBy: ",")[0]
-                let idMe = UserDefaults.standard.string(forKey: "me")!
+                let idMe = User.getMyPin()!
                 if requester == idMe {
                     colorDraw = UIColor.blue
                 }
@@ -124,11 +124,11 @@ public class WhiteboardCanvas: UIView {
                 startingPoint = touchPoint
                 drawShapeLayer(color: colorDraw)
             } else {
-                let dataWB = UserDefaults.standard.string(forKey: "wb_vc")!
+                let dataWB: String! = SecureUserDefaults.shared.value(forKey: "wb_vc")
                 //print("DATA WB \(dataWB)")
                 var colorDraw = UIColor.red
                 let requester = dataWB.components(separatedBy: ",")[0]
-                let idMe = UserDefaults.standard.string(forKey: "me")!
+                let idMe = User.getMyPin()!
                 if requester == idMe {
                     colorDraw = UIColor.blue
                 }

+ 2 - 1
appbuilder-ios/NexilisLite/Podfile

@@ -9,13 +9,14 @@ target 'NexilisLite' do
 
   pod 'nuSDKService', '~> 3.0.1'
   pod 'FMDB', '~> 2.7.12'
-  pod 'NotificationBannerSwift', '3.2.1'
+  pod 'NotificationBannerSwift', '3.1.0'
   pod 'Alamofire', '~> 5.10.1'
   pod 'SDWebImage', '~> 5.20.0'
   pod 'Toast-Swift', '~> 5.1.1'
   pod 'ZIPFoundation', '~> 0.9.19'
   pod 'SwiftLinkPreview', '~> 3.4.0'
   pod 'Popover'
+  pod 'KeychainAccess'
 
   target 'NexilisLiteTests' do
     # Pods for testing

+ 16 - 12
appbuilder-ios/NexilisLite/Podfile.lock

@@ -1,20 +1,21 @@
 PODS:
-  - Alamofire (5.10.1)
+  - Alamofire (5.10.2)
   - FMDB (2.7.12):
     - FMDB/standard (= 2.7.12)
   - FMDB/Core (2.7.12)
   - FMDB/standard (2.7.12):
     - FMDB/Core
-  - MarqueeLabel (4.3.2)
-  - NotificationBannerSwift (3.2.1):
-    - MarqueeLabel (~> 4.3.0)
-    - SnapKit (~> 5.6.0)
+  - KeychainAccess (4.2.2)
+  - MarqueeLabel (4.0.5)
+  - NotificationBannerSwift (3.1.0):
+    - MarqueeLabel (~> 4.0.5)
+    - SnapKit (~> 5.0.1)
   - nuSDKService (3.0.1)
   - Popover (1.3.0)
   - SDWebImage (5.20.0):
     - SDWebImage/Core (= 5.20.0)
   - SDWebImage/Core (5.20.0)
-  - SnapKit (5.6.0)
+  - SnapKit (5.0.1)
   - SwiftLinkPreview (3.4.0)
   - Toast-Swift (5.1.1)
   - ZIPFoundation (0.9.19)
@@ -22,7 +23,8 @@ PODS:
 DEPENDENCIES:
   - Alamofire (~> 5.10.1)
   - FMDB (~> 2.7.12)
-  - NotificationBannerSwift (= 3.2.1)
+  - KeychainAccess
+  - NotificationBannerSwift (= 3.1.0)
   - nuSDKService (~> 3.0.1)
   - Popover
   - SDWebImage (~> 5.20.0)
@@ -34,6 +36,7 @@ SPEC REPOS:
   trunk:
     - Alamofire
     - FMDB
+    - KeychainAccess
     - MarqueeLabel
     - NotificationBannerSwift
     - nuSDKService
@@ -45,18 +48,19 @@ SPEC REPOS:
     - ZIPFoundation
 
 SPEC CHECKSUMS:
-  Alamofire: 840d2a1ad82355b536ec6ba5f97e5bfa54600ca3
+  Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
   FMDB: 728731dd336af3936ce00f91d9d8495f5718a0e6
-  MarqueeLabel: 15e524a6762552bb279cb17438b8a94990269fb9
-  NotificationBannerSwift: dce54ded532b26e30cd8e7f4d80e124a0f2ba7d1
+  KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51
+  MarqueeLabel: 00cc0bcd087111dca575878b3531af980559707d
+  NotificationBannerSwift: 49912a48b37e2f55d1cef4e8a38f15394f66a70a
   nuSDKService: a7474746d0d867bf9e5c1bc8cf93ecbb2600bd86
   Popover: 10e1d9528f81d9504df984b7b3f491292bc1822d
   SDWebImage: 73c6079366fea25fa4bb9640d5fb58f0893facd8
-  SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25
+  SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
   SwiftLinkPreview: c1bc5b2cb3cd42f2865137c1a61f5d788dcf5c9c
   Toast-Swift: 7a03a532afe3a560d4044bc7c237e2864d295173
   ZIPFoundation: b8c29ea7ae353b309bc810586181fd073cb3312c
 
-PODFILE CHECKSUM: 968e928d0bdc86bc9bbebf260e0625c87d87c451
+PODFILE CHECKSUM: 7778eb750b2e354257b3a9eeedb6698d021a3e93
 
 COCOAPODS: 1.16.2

+ 20 - 20
appbuilder-ios/StreamShield/StreamShield.xcodeproj/project.pbxproj

@@ -7,13 +7,13 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		E5299C46943A01BDD66A98D2 /* Pods_StreamShield.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B15FD771801E3D1ED9B344E5 /* Pods_StreamShield.framework */; };
+		4CA3A8D13EA830BD06994857 /* Pods_StreamShield.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97DA666C9445DC5537AF51DD /* Pods_StreamShield.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
-		3F590AD4DEEC6AD526F612B2 /* Pods-StreamShield.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StreamShield.release.xcconfig"; path = "Target Support Files/Pods-StreamShield/Pods-StreamShield.release.xcconfig"; sourceTree = "<group>"; };
-		9601438A561370957F2F3D83 /* Pods-StreamShield.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StreamShield.debug.xcconfig"; path = "Target Support Files/Pods-StreamShield/Pods-StreamShield.debug.xcconfig"; sourceTree = "<group>"; };
-		B15FD771801E3D1ED9B344E5 /* Pods_StreamShield.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StreamShield.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		1918273257E8197A5D8252B7 /* Pods-StreamShield.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StreamShield.release.xcconfig"; path = "Target Support Files/Pods-StreamShield/Pods-StreamShield.release.xcconfig"; sourceTree = "<group>"; };
+		699A8C56FF5DC7FA59223CC2 /* Pods-StreamShield.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StreamShield.debug.xcconfig"; path = "Target Support Files/Pods-StreamShield/Pods-StreamShield.debug.xcconfig"; sourceTree = "<group>"; };
+		97DA666C9445DC5537AF51DD /* Pods_StreamShield.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_StreamShield.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		CDB6D7EC2CD3553900615C4D /* StreamShield.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StreamShield.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 /* End PBXFileReference section */
 
@@ -43,18 +43,26 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				E5299C46943A01BDD66A98D2 /* Pods_StreamShield.framework in Frameworks */,
+				4CA3A8D13EA830BD06994857 /* Pods_StreamShield.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		407A271A712B5439E6100999 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				97DA666C9445DC5537AF51DD /* Pods_StreamShield.framework */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
 		4DE9A009F0C99904D2388707 /* Pods */ = {
 			isa = PBXGroup;
 			children = (
-				9601438A561370957F2F3D83 /* Pods-StreamShield.debug.xcconfig */,
-				3F590AD4DEEC6AD526F612B2 /* Pods-StreamShield.release.xcconfig */,
+				699A8C56FF5DC7FA59223CC2 /* Pods-StreamShield.debug.xcconfig */,
+				1918273257E8197A5D8252B7 /* Pods-StreamShield.release.xcconfig */,
 			);
 			path = Pods;
 			sourceTree = "<group>";
@@ -65,7 +73,7 @@
 				CDB6D7EE2CD3553900615C4D /* StreamShield */,
 				CDB6D7ED2CD3553900615C4D /* Products */,
 				4DE9A009F0C99904D2388707 /* Pods */,
-				D950F4A0DF82B73D5E24D6BD /* Frameworks */,
+				407A271A712B5439E6100999 /* Frameworks */,
 			);
 			sourceTree = "<group>";
 		};
@@ -77,14 +85,6 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
-		D950F4A0DF82B73D5E24D6BD /* Frameworks */ = {
-			isa = PBXGroup;
-			children = (
-				B15FD771801E3D1ED9B344E5 /* Pods_StreamShield.framework */,
-			);
-			name = Frameworks;
-			sourceTree = "<group>";
-		};
 /* End PBXGroup section */
 
 /* Begin PBXHeadersBuildPhase section */
@@ -102,7 +102,7 @@
 			isa = PBXNativeTarget;
 			buildConfigurationList = CDB6D7F42CD3553900615C4D /* Build configuration list for PBXNativeTarget "StreamShield" */;
 			buildPhases = (
-				520EEEDB8A8B98B209F0F430 /* [CP] Check Pods Manifest.lock */,
+				6399416B993E04BF06C8F1CD /* [CP] Check Pods Manifest.lock */,
 				CDB6D7E72CD3553900615C4D /* Headers */,
 				CDB6D7E82CD3553900615C4D /* Sources */,
 				CDB6D7E92CD3553900615C4D /* Frameworks */,
@@ -164,7 +164,7 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		520EEEDB8A8B98B209F0F430 /* [CP] Check Pods Manifest.lock */ = {
+		6399416B993E04BF06C8F1CD /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -201,7 +201,7 @@
 /* Begin XCBuildConfiguration section */
 		CDB6D7F52CD3553900615C4D /* Debug */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 9601438A561370957F2F3D83 /* Pods-StreamShield.debug.xcconfig */;
+			baseConfigurationReference = 699A8C56FF5DC7FA59223CC2 /* Pods-StreamShield.debug.xcconfig */;
 			buildSettings = {
 				BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
 				CODE_SIGN_STYLE = Automatic;
@@ -240,7 +240,7 @@
 		};
 		CDB6D7F62CD3553900615C4D /* Release */ = {
 			isa = XCBuildConfiguration;
-			baseConfigurationReference = 3F590AD4DEEC6AD526F612B2 /* Pods-StreamShield.release.xcconfig */;
+			baseConfigurationReference = 1918273257E8197A5D8252B7 /* Pods-StreamShield.release.xcconfig */;
 			buildSettings = {
 				BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
 				CODE_SIGN_STYLE = Automatic;

二進制
appbuilder-ios/StreamShield/StreamShield.xcworkspace/xcuserdata/akhmadalqindiirsyam.xcuserdatad/UserInterfaceState.xcuserstate


+ 424 - 124
appbuilder-ios/StreamShield/StreamShield/Source/SecurityShield.swift

@@ -11,6 +11,7 @@ import nuSDKService
 import AVFoundation
 import AVKit
 import CoreTelephony
+import CryptoKit
 
 public class SecurityShield: NSObject {
     
@@ -23,7 +24,7 @@ public class SecurityShield: NSObject {
     }
     
     private static func pull() {
-        let me = UserDefaults.standard.string(forKey: "me")!
+        let me: String! = SecureUserDefaultsSS.shared.value(forKey: "me")!
         let tmessage = TMessageSS()
         tmessage.mCode = "SS01"
         tmessage.mStatus = CoreMessage_TMessageUtil.getTID()
@@ -778,9 +779,9 @@ private class Process: NSObject {
     }
     
     private static func isSimSwap() -> Bool {
-        guard let savedSimInfo = UserDefaults.standard.dictionary(forKey: "SavedSIMInfo") as? [String: [String: String]] else {
+        guard let savedSimInfo: [String: [String: String]]? = SecureUserDefaultsSS.shared.value(forKey: "SavedSIMInfo") else {
             let simInfo = getSIMInfo()
-            UserDefaults.standard.set(simInfo, forKey: "SavedSIMInfo")
+            SecureUserDefaultsSS.shared.set(simInfo, forKey: "SavedSIMInfo")
             return false
         }
         let currentSimInfo = getSIMInfo()
@@ -836,480 +837,663 @@ private class Service {
 
 private class Preference {
     static func getAppId() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_USER_APP_ID) ?? ""
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_USER_APP_ID) {
+            return value
+        }
+        return ""
     }
     
     static func setAppId(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_USER_APP_ID)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_USER_APP_ID)
     }
     
     static func getAccount() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_USER_ACCOUNT) ?? ""
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_USER_ACCOUNT) {
+            return value
+        }
+        return ""
     }
     
     static func setAccount(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_USER_ACCOUNT)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_USER_ACCOUNT)
     }
     
     static func getDomainOpr() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_DOMAIN_OPR) ?? "https://nexilis.io/"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_DOMAIN_OPR) {
+            return value
+        }
+        return "https://nexilis.io/"
     }
     
     static func getIpOpr() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_IP_PORT_OPR) ?? "34.101.172.194:42823"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_IP_PORT_OPR) {
+            return value
+        }
+        return "34.101.172.194:42823"
     }
     
     /**
      * Keylogger
      */
     static func setPreventKeylogger(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER)
     }
     
     static func getPreventKeylogger() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_KEYLOGGER)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_KEYLOGGER) {
+            return value
+        }
+        return false
     }
     static func setPreventKeyloggerAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ACTION)
     }
     
     static func getPreventKeyloggerAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setKeyloggerAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_TITLE)
     }
     
     static func getKeyloggerAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_TITLE) ?? PreferencesKey.ss_screenshare_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_screenshare_title
     }
     static func setKeyloggerAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_MESSAGE)
     }
     
     static func getKeyloggerAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_MESSAGE) ?? PreferencesKey.ss_screenshare_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_KEYLOGGER_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_screenshare_warning
     }
     /**
      * Screen Capture
      */
     static func setPreventScreenCapture(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE)
     }
     
     static func getPreventScreenCapture() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE) {
+            return value
+        }
+        return false
     }
     static func setPreventScreenCaptureAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ACTION)
     }
     
     static func getPreventScreenCaptureAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckScreenCaptureAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_TITLE)
     }
     
     static func getCheckScreenCaptureAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_TITLE) ?? PreferencesKey.ss_screenshare_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_screenshare_title
     }
     static func setScreenCaptureAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_MESSAGE)
     }
     
     static func getScreenCaptureAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_MESSAGE) ?? PreferencesKey.ss_screenshare_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CAPTURE_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_screenshare_warning
     }
     /**
      * Emulator
      */
     static func setCheckEmulator(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR)
     }
     
     static func getCheckEmulator() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_EMULATOR)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_EMULATOR) {
+            return value
+        }
+        return false
     }
     static func setCheckEmulatorAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR_ACTION)
     }
     
     static func getCheckEmulatorAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_EMULATOR_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_EMULATOR_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckEmulatorAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_TITLE)
     }
     
     static func getCheckEmulatorAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_TITLE) ?? PreferencesKey.ss_emulator_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_emulator_title
     }
     static func setCheckEmulatorAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_MESSAGE)
     }
     
     static func getCheckEmulatorAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_MESSAGE) ?? PreferencesKey.ss_emulator_continue
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_EMULATOR_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_emulator_continue
     }
     
     /**
      * Root/Jailbreak Detection
      */
     static func setCheckRooted(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED)
     }
     
     static func getCheckRooted() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_ROOTED)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_ROOTED) {
+            return value
+        }
+        return false
     }
     static func setCheckRootedAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION)
     }
     
     static func getCheckRootedAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckRootedAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_TITLE)
     }
     
     static func getCheckRootedAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_TITLE) ?? PreferencesKey.ss_rooted_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_rooted_title
     }
     static func setCheckRootedAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_MESSAGE)
     }
     
     static func getCheckRootedAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_MESSAGE) ?? PreferencesKey.ss_rooted_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_ROOTED_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_rooted_warning
     }
     
     /**
      * Outdated OS Detection
      */
     static func setCheckOutdatedOs(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_OUTDATED_OS)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_OUTDATED_OS)
     }
     
     static func getCheckOutdatedOs() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_OUTDATED_OS)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_OUTDATED_OS) {
+            return value
+        }
+        return false
     }
     static func setCheckOutdatedOsAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION)
     }
     
     static func getCheckOutdatedOsAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_ROOTED_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckOutdatedOsAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_TITLE)
     }
     
     static func getCheckOutdatedOsAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_TITLE) ?? PreferencesKey.ss_os_not_supported_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_os_not_supported_title
     }
     static func setCheckOutdatedOsAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_MESSAGE)
     }
     
     static func getCheckOutdatedOsAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_MESSAGE) ?? PreferencesKey.ss_os_not_supported_continue
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_OUTDATED_OS_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_os_not_supported_continue
     }
     static func setMinimumOsVersion(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_MINIMUM_OS_VERSION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_MINIMUM_OS_VERSION)
     }
     
     static func getMinimumOsVersion() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_MINIMUM_OS_VERSION) ?? "14"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_MINIMUM_OS_VERSION) {
+            return value
+        }
+        return "14"
     }
     
     /**
      * Tempering Detection
      */
     static func setCheckTempering(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING)
     }
     
     static func getCheckTempering() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_TEMPERING)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_TEMPERING) {
+            return value
+        }
+        return false
     }
     static func setCheckTemperingAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING_ACTION)
     }
     
     static func getCheckTemperingAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_TEMPERING_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_TEMPERING_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckTemperingAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_TITLE)
     }
     
     static func getCheckTemperingAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_TITLE) ?? PreferencesKey.ss_tempering_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_tempering_title
     }
     static func setCheckTemperingAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_MESSAGE)
     }
     
     static func getCheckTemperingAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_MESSAGE) ?? PreferencesKey.ss_tempering_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_TEMPERING_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_tempering_warning
     }
     
     /**
      * Debugging Detection
      */
     static func setCheckDebugging(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING)
     }
     
     static func getCheckDebugging() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_DEBUGGING)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_DEBUGGING) {
+            return value
+        }
+        return false
     }
     static func setCheckDebuggingAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING_ACTION)
     }
     
     static func getCheckDebuggingAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_DEBUGGING_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_DEBUGGING_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckDebuggingAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_TITLE)
     }
     
     static func getCheckDebuggingAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_TITLE) ?? PreferencesKey.ss_debugging_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_debugging_title
     }
     static func setCheckDebuggingAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_MESSAGE)
     }
     
     static func getCheckDebuggingAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_MESSAGE) ?? PreferencesKey.ss_debugging_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_DEBUGGING_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_debugging_warning
     }
     
     /**
      * Screen Casting
      */
     static func setCheckScreenCasting(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING)
     }
     
     static func getCheckScreenCasting() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING) {
+            return value
+        }
+        return false
     }
     static func setCheckScreenCastingAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ACTION)
     }
     
     static func getCheckScreenCastingAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckScreenCastingAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_TITLE)
     }
     
     static func getCheckScreenCastingAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_TITLE) ?? PreferencesKey.ss_debugging_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_debugging_title
     }
     static func setCheckScreenCastingAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_MESSAGE)
     }
     
     static func getCheckScreenCastingAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_MESSAGE) ?? PreferencesKey.ss_debugging_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_CASTING_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_debugging_warning
     }
     
     /**
      * Screen Overlay
      */
     static func setCheckScreenOverlay(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY)
     }
     
     static func getCheckScreenOverlay() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY) {
+            return value
+        }
+        return false
     }
     static func setCheckScreenOverlayAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ACTION)
     }
     
     static func getCheckScreenOverlayAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckScreenOverlayAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_TITLE)
     }
     
     static func getCheckScreenOverlayAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_TITLE) ?? PreferencesKey.ss_screenoverlay_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_screenoverlay_title
     }
     static func setCheckScreenOverlayAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_MESSAGE)
     }
     
     static func getCheckScreenOverlayAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_MESSAGE) ?? PreferencesKey.ss_screenoverlay_continue
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SCREEN_OVERLAY_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_screenoverlay_continue
     }
     
     /**
      * Call Redirection Detection
      */
     static func setCheckCallForward(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD)
     }
     
     static func getCheckCallForward() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD) {
+            return value
+        }
+        return false
     }
     static func setCheckCallForwardAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ACTION)
     }
     
     static func getCheckCallForwardAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckCallForwardAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_TITLE)
     }
     
     static func getCheckCallForwardAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_TITLE) ?? PreferencesKey.ss_callforward_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_callforward_title
     }
     static func setCheckCallForwardAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_MESSAGE)
     }
     
     static func getCheckCallForwardAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_MESSAGE) ?? PreferencesKey.ss_callforward_continue
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_CALL_FORWARD_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_callforward_continue
     }
     
     /**
      * Multiple Login Detection
      */
     static func setCheckMultipleLogin(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN)
     }
     
     static func getCheckMultipleLogin() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN) {
+            return value
+        }
+        return false
     }
     static func setCheckMultipleLoginAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ACTION)
     }
     
     static func getCheckMultipleLoginAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckMultipleLoginAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_TITLE)
     }
     
     static func getCheckMultipleLoginAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_TITLE) ?? PreferencesKey.ss_multiple_login_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_multiple_login_title
     }
     static func setCheckMultipleLoginAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_MESSAGE)
     }
     
     static func getCheckMultipleLoginAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_MESSAGE) ?? PreferencesKey.ss_multiple_login_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_MULTIPLE_LOGIN_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_multiple_login_warning
     }
     
     /**
      * SIM Swap Detection
      */
     static func setCheckSimSwap(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP)
     }
     
     static func getCheckSimSwap() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_SIM_SWAP)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SIM_SWAP) {
+            return value
+        }
+        return false
     }
     static func setCheckSimSwapAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ACTION)
     }
     
     static func getCheckSimSwapAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckSimSwapAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_TITLE)
     }
     
     static func getCheckSimSwapAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_TITLE) ?? PreferencesKey.ss_simswap_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_simswap_title
     }
     static func setCheckSimSwapAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_MESSAGE)
     }
     
     static func getCheckSimSwapAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_MESSAGE) ?? PreferencesKey.ss_simswap_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_SIM_SWAP_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_simswap_warning
     }
     
     /**
      * Geo-Velocity Checks
      */
     static func setCheckGeoVelocity(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY)
     }
     
     static func getCheckGeoVelocity() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY) {
+            return value
+        }
+        return false
     }
     static func setCheckGeoVelocityAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ACTION)
     }
     
     static func getCheckGeoVelocityAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckGeoVelocityAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_TITLE)
     }
     
     static func getCheckGeoVelocityAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_TITLE) ?? PreferencesKey.ss_geo_velocity_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_geo_velocity_title
     }
     static func setCheckGeoVelocityAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_MESSAGE)
     }
     
     static func getCheckGeoVelocityAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_MESSAGE) ?? PreferencesKey.ss_geo_velocity_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_GEO_VELOCITY_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_geo_velocity_warning
     }
     
     /**
      * Behavioral Anomaly Detection
      */
     static func setCheckBehaviourAnalysis(value: Bool){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS)
     }
     
     static func getCheckBehaviourAnalysis() -> Bool {
-        return UserDefaults.standard.bool(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS)
+        if let value: Bool = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS) {
+            return value
+        }
+        return false
     }
     static func setCheckBehaviourAnalysisAction(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ACTION)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ACTION)
     }
     
     static func getCheckBehaviourAnalysisAction() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ACTION) ?? "0"
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ACTION) {
+            return value
+        }
+        return "0"
     }
     static func setCheckBehaviourAnalysisAlertTitle(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_TITLE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_TITLE)
     }
     
     static func getCheckBehaviourAnalysisAlertTitle() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_TITLE) ?? PreferencesKey.ss_behaviour_anomaly_title
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_TITLE) {
+            return value
+        }
+        return PreferencesKey.ss_behaviour_anomaly_title
     }
     static func setCheckBehaviourAnalysisAlertMessage(value: String){
-        UserDefaults.standard.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_MESSAGE)
+        SecureUserDefaultsSS.shared.set(value, forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_MESSAGE)
     }
     
     static func getCheckBehaviourAnalysisAlertMessage() -> String {
-        return UserDefaults.standard.string(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_MESSAGE) ?? PreferencesKey.ss_behaviour_anomaly_warning
+        if let value: String = SecureUserDefaultsSS.shared.value(forKey: PreferencesKey.SS_CHECK_BEHAVIOUR_ANALYSIS_ALERT_MESSAGE) {
+            return value
+        }
+        return PreferencesKey.ss_behaviour_anomaly_warning
     }
 }
 
@@ -1692,7 +1876,7 @@ public class TMessageSS {
     let VERCOD = "Bd"
     
     func getCLMUserId() -> String {
-        guard let me = UserDefaults.standard.string(forKey: "me") else {
+        guard let me: String = SecureUserDefaultsSS.shared.value(forKey: "me") else {
             return ""
         }
         return me
@@ -2052,3 +2236,119 @@ public class SSLibAlertController: UIAlertController {
 
     }
 }
+
+public class SecureUserDefaultsSS {
+    static let shared = SecureUserDefaultsSS()
+    private let defaults: UserDefaults
+    private let prefsKeyAlias = "_iosx_security_master_key_easysoft_"
+
+    // Initialization with a SymmetricKey
+    init(defaults: UserDefaults = .standard) {
+        self.defaults = defaults
+        do {
+            try generateAndStorePrefsKey()
+        } catch {
+            
+        }
+    }
+    
+    func generateAndStorePrefsKey() throws {
+        if try isKeyExists(keyAliasCode: prefsKeyAlias) {
+            return
+        }
+        let key = SymmetricKey(size: .bits256)
+        let keyData = key.withUnsafeBytes { Data($0) }
+        
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: prefsKeyAlias,
+            kSecValueData as String: keyData,
+            kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock
+        ]
+        
+        SecItemDelete(query as CFDictionary) // Remove if it exists
+        let status = SecItemAdd(query as CFDictionary, nil)
+        guard status == errSecSuccess else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+    }
+    
+    func isKeyExists(keyAliasCode: String) throws -> Bool {
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: keyAliasCode,
+            kSecReturnData as String: false // We only check existence, not retrieve data
+        ]
+
+        let status = SecItemCopyMatching(query as CFDictionary, nil)
+        if status == errSecItemNotFound {
+            return false
+        } else if status == errSecSuccess {
+            return true
+        } else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+    }
+    
+    func getPrefsKey() throws -> SymmetricKey {
+        let query: [String: Any] = [
+            kSecClass as String: kSecClassKey,
+            kSecAttrApplicationTag as String: prefsKeyAlias,
+            kSecReturnData as String: true
+        ]
+        
+        var item: CFTypeRef?
+        let status = SecItemCopyMatching(query as CFDictionary, &item)
+        guard status == errSecSuccess else {
+            throw NSError(domain: "KeychainError", code: Int(status), userInfo: nil)
+        }
+        
+        guard let keyData = item as? Data else {
+            throw NSError(domain: "KeyRetrievalError", code: -1, userInfo: nil)
+        }
+        
+        return SymmetricKey(data: keyData)
+    }
+
+    func encrypt(data: Data) throws -> Data {
+        let key = try getPrefsKey()
+        let sealedBox = try AES.GCM.seal(data, using: key)
+        return sealedBox.combined!
+    }
+    
+    func decrypt(data: Data) throws -> Data {
+        let key = try getPrefsKey()
+        let sealedBox = try AES.GCM.SealedBox(combined: data)
+        return try AES.GCM.open(sealedBox, using: key)
+    }
+
+    func set<T: Codable>(_ value: T, forKey key: String) {
+        let encoder = JSONEncoder()
+        guard let encodedData = try? encoder.encode(value),
+              let encryptedData = try? encrypt(data: encodedData) else {
+            print("Failed to encrypt data")
+            return
+        }
+        defaults.set(encryptedData, forKey: key)
+    }
+
+    // Retrieve a value
+    func value<T: Codable>(forKey key: String) -> T? {
+        guard let encryptedData = defaults.data(forKey: key),
+              let decryptedData = try? decrypt(data: encryptedData) else {
+            print("Failed to decrypt data")
+            return nil
+        }
+        let decoder = JSONDecoder()
+        return try? decoder.decode(T.self, from: decryptedData)
+    }
+
+    // Remove a value
+    func removeValue(forKey key: String) {
+        defaults.removeObject(forKey: key)
+    }
+    
+    func sync() {
+        defaults.synchronize()
+    }
+}

部分文件因文件數量過多而無法顯示