mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-11 02:13:41 +02:00
Update Ghostgram features
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "SGKeychainBackupManager",
|
||||
module_name = "SGKeychainBackupManager",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
copts = [
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,131 @@
|
||||
import Foundation
|
||||
import Security
|
||||
|
||||
public enum KeychainError: Error {
|
||||
case duplicateEntry
|
||||
case unknown(OSStatus)
|
||||
case itemNotFound
|
||||
case invalidItemFormat
|
||||
}
|
||||
|
||||
public class KeychainBackupManager {
|
||||
public static let shared = KeychainBackupManager()
|
||||
private let service = "\(Bundle.main.bundleIdentifier!).sessionsbackup"
|
||||
|
||||
private init() {}
|
||||
|
||||
// MARK: - Save Credentials
|
||||
public func saveSession(id: String, _ session: Data) throws {
|
||||
// Create query dictionary
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrService as String: service,
|
||||
kSecAttrAccount as String: id,
|
||||
kSecValueData as String: session,
|
||||
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
|
||||
]
|
||||
|
||||
// Add to keychain
|
||||
let status = SecItemAdd(query as CFDictionary, nil)
|
||||
|
||||
if status == errSecDuplicateItem {
|
||||
// Item already exists, update it
|
||||
let updateQuery: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrService as String: service,
|
||||
kSecAttrAccount as String: id
|
||||
]
|
||||
|
||||
let attributesToUpdate: [String: Any] = [
|
||||
kSecValueData as String: session
|
||||
]
|
||||
|
||||
let updateStatus = SecItemUpdate(updateQuery as CFDictionary,
|
||||
attributesToUpdate as CFDictionary)
|
||||
|
||||
if updateStatus != errSecSuccess {
|
||||
throw KeychainError.unknown(updateStatus)
|
||||
}
|
||||
} else if status != errSecSuccess {
|
||||
throw KeychainError.unknown(status)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Retrieve Credentials
|
||||
public func retrieveSession(for id: String) throws -> Data {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrService as String: service,
|
||||
kSecAttrAccount as String: id,
|
||||
kSecReturnData as String: true
|
||||
]
|
||||
|
||||
var result: AnyObject?
|
||||
let status = SecItemCopyMatching(query as CFDictionary, &result)
|
||||
|
||||
guard status == errSecSuccess, let sessionData = result as? Data else {
|
||||
throw KeychainError.itemNotFound
|
||||
}
|
||||
|
||||
return sessionData
|
||||
}
|
||||
|
||||
// MARK: - Delete Credentials
|
||||
public func deleteSession(for id: String) throws {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrService as String: service,
|
||||
kSecAttrAccount as String: id
|
||||
]
|
||||
|
||||
let status = SecItemDelete(query as CFDictionary)
|
||||
|
||||
if status != errSecSuccess && status != errSecItemNotFound {
|
||||
throw KeychainError.unknown(status)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Retrieve All Accounts
|
||||
public func getAllSessons() throws -> [Data] {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrService as String: service,
|
||||
kSecReturnData as String: true,
|
||||
kSecMatchLimit as String: kSecMatchLimitAll
|
||||
]
|
||||
|
||||
var result: AnyObject?
|
||||
let status = SecItemCopyMatching(query as CFDictionary, &result)
|
||||
|
||||
if status == errSecItemNotFound {
|
||||
return []
|
||||
}
|
||||
|
||||
guard status == errSecSuccess,
|
||||
let credentialsDataArray = result as? [Data] else {
|
||||
throw KeychainError.unknown(status)
|
||||
}
|
||||
|
||||
return credentialsDataArray
|
||||
}
|
||||
|
||||
// MARK: - Delete All Sessions
|
||||
public func deleteAllSessions() throws {
|
||||
let query: [String: Any] = [
|
||||
kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrService as String: service
|
||||
]
|
||||
|
||||
let status = SecItemDelete(query as CFDictionary)
|
||||
|
||||
// If no items were found, that's fine - just return
|
||||
if status == errSecItemNotFound {
|
||||
return
|
||||
}
|
||||
|
||||
// For any other error, throw
|
||||
if status != errSecSuccess {
|
||||
throw KeychainError.unknown(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user