Files
ghostgram/submodules/PasscodeCore/Sources/AccountManagerIntegration.swift
T
ichmagmaus111andClaude Opus 5.5 0622057a4f Ghostgram: open-source release
Ghostgram for iOS, rebuilt from scratch on Telegram iOS 13.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:57:09 +01:00

95 lines
3.5 KiB
Swift

import TelegramCore
#if os(macOS)
import PasscodeCore
#endif
public func passcodeKind(from kind: PostboxAccessChallengeData.Kind) -> PasscodeKind {
switch kind {
case .digits4:
return .digits4
case .digits6:
return .digits6
case .alphanumeric:
return .alphanumeric
}
}
public func passcodeCredentialReference(from challenge: PostboxAccessChallengeData) -> PasscodeCredentialReference? {
guard case let .secured(id, kind) = challenge else {
return nil
}
return PasscodeCredentialReference(id: id, kind: passcodeKind(from: kind))
}
public func accessChallengeData(reference: PasscodeCredentialReference) -> PostboxAccessChallengeData {
let kind: PostboxAccessChallengeData.Kind
switch reference.kind {
case .digits4:
kind = .digits4
case .digits6:
kind = .digits6
case .alphanumeric:
kind = .alphanumeric
}
return .secured(id: reference.id, kind: kind)
}
/// nil input requests authority without migrating legacy metadata. A nil result
/// means no managed credential exists; .some(.none) is an authoritative removal.
@available(macOS 10.15, *)
private func resolveAccessChallenge(_ current: PostboxAccessChallengeData?, allowMigration: Bool) throws -> PostboxAccessChallengeData? {
let credentials = PasscodeCredentialStore.shared
if let current, case .secured = current {
credentials.requireExistingCredential()
}
if let reference = try credentials.managedReference() {
return .some(reference.map { accessChallengeData(reference: $0) } ?? .none)
}
guard allowMigration, let current else {
return nil
}
switch current {
case let .numericalPassword(code):
let kind: PasscodeKind = code.count == 6 ? .digits6 : .digits4
let reference = try credentials.migrateLegacy(code: code, kind: kind)
return .some(reference.map { accessChallengeData(reference: $0) } ?? .none)
case let .plaintextPassword(code):
let reference = try credentials.migrateLegacy(code: code, kind: .alphanumeric)
return .some(reference.map { accessChallengeData(reference: $0) } ?? .none)
case .none, .secured:
return nil
}
}
@available(macOS 10.15, *)
public func setupAccountManager<Types: AccountManagerTypes>(basePath: String, isTemporary: Bool, isReadOnly: Bool, useCaches: Bool, removeDatabaseOnError: Bool, resetLocalSecrets: (() throws -> Void)? = nil) -> AccountManager<Types> {
let isMainProcess = PasscodeEnvironment.shared.isMainApp
let canReset = isMainProcess && !isTemporary && !isReadOnly
precondition(!canReset || resetLocalSecrets != nil)
return AccountManager(
basePath: basePath,
isTemporary: isTemporary,
isReadOnly: isReadOnly,
useCaches: useCaches,
removeDatabaseOnError: removeDatabaseOnError,
accessChallenge: AccountManagerAccessChallenge(
prepare: { isFreshInstallation in
let _ = try PasscodeEnvironment.shared.sharedAccessGroup()
PasscodeCredentialStore.shared.configureLock(directory: basePath)
if canReset && isFreshInstallation {
try resetLocalSecrets?()
}
},
resolve: { current, allowMigration in
return try resolveAccessChallenge(current, allowMigration: allowMigration)
},
finishInitialization: {
if isMainProcess {
try PasscodeCredentialStore.shared.resumeCleanup()
}
}
)
)
}