Use keychain instead of DB in notification service

This commit is contained in:
Justin Mazzocchi 2021-02-25 19:21:06 -08:00
parent 2f0e35f343
commit 767e815f61
No known key found for this signature in database
GPG Key ID: E223E6937AAFB01C
6 changed files with 40 additions and 36 deletions

View File

@ -228,16 +228,6 @@ public extension IdentityDatabase {
return Identity(info: info)
}
// Only for use in notification extension
func identity(id: Identity.Id) throws -> Identity? {
guard let info = try databaseWriter.read(
IdentityInfo.request(IdentityRecord.filter(IdentityRecord.Columns.id == id))
.fetchOne)
else { return nil }
return Identity(info: info)
}
}
private extension IdentityDatabase {

View File

@ -49,23 +49,16 @@ final class NotificationService: UNNotificationServiceExtension {
bestAttemptContent.sound = .default
}
var identity: Identity?
if appPreferences.notificationAccountName {
identity = try? AllIdentitiesService(environment: Self.environment).identity(id: identityId)
if let handle = identity?.handle {
if appPreferences.notificationAccountName,
case let .success(handle) = parsingService.handle(identityId: identityId) {
bestAttemptContent.subtitle = handle
}
}
Self.attachment(imageURL: pushNotification.icon)
.map { [$0] }
.replaceError(with: [])
.handleEvents(receiveOutput: { bestAttemptContent.attachments = $0 })
.zip(parsingService.title(pushNotification: pushNotification,
identityId: identityId,
accountId: identity?.account?.id)
.zip(parsingService.title(pushNotification: pushNotification, identityId: identityId)
.replaceError(with: pushNotification.title)
.handleEvents(receiveOutput: { bestAttemptContent.title = $0 }))
.sink { _ in contentHandler(bestAttemptContent) }

View File

@ -35,6 +35,8 @@ public extension Secrets {
case databaseKey
case imageCacheKey
case identityDatabaseName
case accountId
case username
}
}
@ -165,6 +167,22 @@ public extension Secrets {
try set(accessToken, forItem: .accessToken)
}
func getAccountId() throws -> String {
try item(.accountId)
}
func setAccountId(_ accountId: String) throws {
try set(accountId, forItem: .accountId)
}
func getUsername() throws -> String {
try item(.username)
}
func setUsername(_ username: String) throws {
try set(username, forItem: .username)
}
func generatePushKeyAndReturnPublicKey() throws -> Data {
try keychain.generateKeyAndReturnPublicKey(
applicationTag: scopedKey(item: .pushKey),

View File

@ -136,11 +136,6 @@ public extension AllIdentitiesService {
.ignoreOutput()
.eraseToAnyPublisher()
}
// Only for use in notification extension
func identity(id: Identity.Id) throws -> Identity? {
try database.identity(id: id)
}
}
private extension AllIdentitiesService.IdentityCreation {

View File

@ -51,6 +51,10 @@ public extension IdentityService {
func verifyCredentials() -> AnyPublisher<Never, Error> {
mastodonAPIClient.request(AccountEndpoint.verifyCredentials)
.handleEvents(receiveOutput: {
try? secrets.setAccountId($0.id)
try? secrets.setUsername($0.username)
})
.flatMap { identityDatabase.updateAccount($0, id: id) }
.eraseToAnyPublisher()
}

View File

@ -51,9 +51,13 @@ public extension PushNotificationParsingService {
identityId)
}
func title(pushNotification: PushNotification,
identityId: Identity.Id,
accountId: Account.Id?) -> AnyPublisher<String, Error> {
func handle(identityId: Identity.Id) -> Result<String, Error> {
let secrets = Secrets(identityId: identityId, keychain: environment.keychain)
return Result { try secrets.getUsername().appending("@").appending(secrets.getInstanceURL().host ?? "") }
}
func title(pushNotification: PushNotification, identityId: Identity.Id) -> AnyPublisher<String, Error> {
switch pushNotification.notificationType {
case .poll, .status:
let secrets = Secrets(identityId: identityId, keychain: environment.keychain)
@ -79,15 +83,15 @@ public extension PushNotificationParsingService {
NSLocalizedString("notification.status-%@", comment: ""),
$0.account.displayName)
case .poll:
switch accountId ?? (try? AllIdentitiesService(environment: environment)
.identity(id: identityId)?.account?.id) {
case .some($0.account.id):
return NSLocalizedString("notification.poll.own", comment: "")
case .some:
return NSLocalizedString("notification.poll", comment: "")
default:
guard let accountId = try? secrets.getAccountId() else {
return NSLocalizedString("notification.poll.unknown", comment: "")
}
if $0.account.id == accountId {
return NSLocalizedString("notification.poll.own", comment: "")
} else {
return NSLocalizedString("notification.poll", comment: "")
}
default:
return pushNotification.title
}