Archived
feat: authorize iOS Hermes accounts and secure session isolation
This commit is contained in:
1 parent
9bdaea2408
commit
bebaf59466
23 files changed
+911
-185
No files matched your search
@@ -0,0 +1,43 @@
|
||||
import Foundation
|
||||
import Security
|
||||
|
||||
protocol TokenStore {
|
||||
func token(origin: String) throws -> String?
|
||||
func save(_ token: String?, origin: String) throws
|
||||
}
|
||||
struct KeychainTokenStore: TokenStore {
|
||||
private func query(_ origin: String) -> [String: Any] {
|
||||
[kSecClass as String: kSecClassGenericPassword,
|
||||
kSecAttrService as String: "dev.shane.voice.auth",
|
||||
kSecAttrAccount as String: origin]
|
||||
}
|
||||
func token(origin: String) throws -> String? {
|
||||
var q = query(origin)
|
||||
q[kSecReturnData as String] = true
|
||||
q[kSecMatchLimit as String] = kSecMatchLimitOne
|
||||
var result: CFTypeRef?
|
||||
let status = SecItemCopyMatching(q as CFDictionary, &result)
|
||||
if status == errSecItemNotFound { return nil }
|
||||
guard status == errSecSuccess, let data = result as? Data else { throw StoreError.failed }
|
||||
return String(data: data, encoding: .utf8)
|
||||
}
|
||||
func save(_ token: String?, origin: String) throws {
|
||||
let q = query(origin)
|
||||
let deletion = SecItemDelete(q as CFDictionary)
|
||||
guard deletion == errSecSuccess || deletion == errSecItemNotFound else { throw StoreError.failed }
|
||||
guard let token else { return }
|
||||
var item = q
|
||||
item[kSecValueData as String] = Data(token.utf8)
|
||||
item[kSecAttrAccessible as String] = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
|
||||
guard SecItemAdd(item as CFDictionary, nil) == errSecSuccess else { throw StoreError.failed }
|
||||
}
|
||||
enum StoreError: LocalizedError {
|
||||
case failed
|
||||
var errorDescription: String? { "Could not securely save the sign-in on this iPhone." }
|
||||
}
|
||||
}
|
||||
final class MemoryTokenStore: TokenStore {
|
||||
private var values: [String: String] = [:]
|
||||
func token(origin: String) throws -> String? { values[origin] }
|
||||
func save(_ token: String?, origin: String) throws { values[origin] = token }
|
||||
}
|
||||
Reference in new issue
Block a user