mirror of
https://github.com/GLEGram/GLEGram-iOS.git
synced 2026-04-23 11:26:54 +02:00
4647310322
Based on Swiftgram 12.5 (Telegram iOS 12.5). All GLEGram features ported and organized in GLEGram/ folder. Features: Ghost Mode, Saved Deleted Messages, Content Protection Bypass, Font Replacement, Fake Profile, Chat Export, Plugin System, and more. See CHANGELOG_12.5.md for full details.
127 lines
4.3 KiB
Swift
127 lines
4.3 KiB
Swift
// MARK: Swiftgram - Password for selected chats/folders
|
|
import Foundation
|
|
import Security
|
|
|
|
private let enabledKey = "sg_protected_chats_enabled"
|
|
private let peerIdsKey = "sg_protected_chat_peer_ids"
|
|
private let folderIdsKey = "sg_protected_folder_ids"
|
|
private let useDevicePasscodeKey = "sg_protected_chats_use_device_passcode"
|
|
private let serviceName = "SwiftgramProtectedChats"
|
|
private let customPasscodeAccount = "chats"
|
|
|
|
public enum ProtectedChatsStore {
|
|
public static var isEnabled: Bool {
|
|
get { UserDefaults.standard.bool(forKey: enabledKey) }
|
|
set { UserDefaults.standard.set(newValue, forKey: enabledKey) }
|
|
}
|
|
|
|
public static var useDevicePasscode: Bool {
|
|
get { UserDefaults.standard.object(forKey: useDevicePasscodeKey) as? Bool ?? true }
|
|
set { UserDefaults.standard.set(newValue, forKey: useDevicePasscodeKey) }
|
|
}
|
|
|
|
public static var protectedPeerIds: Set<Int64> {
|
|
get {
|
|
let list = UserDefaults.standard.array(forKey: peerIdsKey) as? [Int64] ?? []
|
|
return Set(list)
|
|
}
|
|
set {
|
|
UserDefaults.standard.set(Array(newValue), forKey: peerIdsKey)
|
|
}
|
|
}
|
|
|
|
public static var protectedFolderIds: Set<Int32> {
|
|
get {
|
|
let list = UserDefaults.standard.array(forKey: folderIdsKey) as? [Int32] ?? []
|
|
return Set(list)
|
|
}
|
|
set {
|
|
UserDefaults.standard.set(Array(newValue), forKey: folderIdsKey)
|
|
}
|
|
}
|
|
|
|
public static func addProtectedPeer(_ peerId: Int64) {
|
|
var set = protectedPeerIds
|
|
set.insert(peerId)
|
|
protectedPeerIds = set
|
|
}
|
|
|
|
public static func removeProtectedPeer(_ peerId: Int64) {
|
|
var set = protectedPeerIds
|
|
set.remove(peerId)
|
|
protectedPeerIds = set
|
|
}
|
|
|
|
public static func addProtectedFolder(_ folderId: Int32) {
|
|
var set = protectedFolderIds
|
|
set.insert(folderId)
|
|
protectedFolderIds = set
|
|
}
|
|
|
|
public static func removeProtectedFolder(_ folderId: Int32) {
|
|
var set = protectedFolderIds
|
|
set.remove(folderId)
|
|
protectedFolderIds = set
|
|
}
|
|
|
|
public static func isProtected(peerId: Int64) -> Bool {
|
|
isEnabled && protectedPeerIds.contains(peerId)
|
|
}
|
|
|
|
public static func isProtected(folderId: Int32) -> Bool {
|
|
isEnabled && protectedFolderIds.contains(folderId)
|
|
}
|
|
|
|
// MARK: - Custom passcode (when not using device passcode)
|
|
|
|
public static func setCustomPasscode(_ passcode: String) {
|
|
let data = passcode.data(using: .utf8)!
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassGenericPassword,
|
|
kSecAttrService as String: serviceName,
|
|
kSecAttrAccount as String: customPasscodeAccount
|
|
]
|
|
var addQuery = query
|
|
addQuery[kSecValueData as String] = data
|
|
var status = SecItemAdd(addQuery as CFDictionary, nil)
|
|
if status == errSecDuplicateItem {
|
|
SecItemDelete(query as CFDictionary)
|
|
status = SecItemAdd(addQuery as CFDictionary, nil)
|
|
}
|
|
}
|
|
|
|
public static func customPasscodeMatches(_ passcode: String) -> Bool {
|
|
guard let stored = getCustomPasscode() else { return false }
|
|
return stored == passcode
|
|
}
|
|
|
|
public static func hasCustomPasscode() -> Bool {
|
|
getCustomPasscode() != nil
|
|
}
|
|
|
|
public static func removeCustomPasscode() {
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassGenericPassword,
|
|
kSecAttrService as String: serviceName,
|
|
kSecAttrAccount as String: customPasscodeAccount
|
|
]
|
|
SecItemDelete(query as CFDictionary)
|
|
}
|
|
|
|
private static func getCustomPasscode() -> String? {
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassGenericPassword,
|
|
kSecAttrService as String: serviceName,
|
|
kSecAttrAccount as String: customPasscodeAccount,
|
|
kSecReturnData as String: true,
|
|
kSecMatchLimit as String: kSecMatchLimitOne
|
|
]
|
|
var result: AnyObject?
|
|
let status = SecItemCopyMatching(query as CFDictionary, &result)
|
|
guard status == errSecSuccess, let data = result as? Data, let string = String(data: data, encoding: .utf8) else {
|
|
return nil
|
|
}
|
|
return string
|
|
}
|
|
}
|