Compare commits

...

2 Commits

Author SHA1 Message Date
Shadowfacts 8a339ec171 Reregister client when adding push scope 2024-04-11 22:19:29 -04:00
Shadowfacts c7d79422bd Fix clean build failures 2024-04-11 21:48:41 -04:00
5 changed files with 62 additions and 10 deletions

View File

@ -14,11 +14,17 @@ let package = Package(
name: "PushNotifications",
targets: ["PushNotifications"]),
],
dependencies: [
.package(path: "../UserAccounts"),
.package(path: "../Pachyderm"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "PushNotifications"),
name: "PushNotifications",
dependencies: ["UserAccounts", "Pachyderm"]
),
.testTarget(
name: "PushNotificationsTests",
dependencies: ["PushNotifications"]),

View File

@ -11,8 +11,8 @@ import CryptoKit
public struct UserAccountInfo: Equatable, Hashable, Identifiable, Sendable {
public let id: String
public let instanceURL: URL
public let clientID: String
public let clientSecret: String
public internal(set) var clientID: String
public internal(set) var clientSecret: String
public let username: String!
public internal(set) var accessToken: String
public internal(set) var scopes: [String]?

View File

@ -148,12 +148,14 @@ public class UserAccountsManager: ObservableObject {
accounts[index] = account
}
public func updateAccessToken(_ account: UserAccountInfo, token: String, scopes: [String]) {
public func updateCredentials(_ account: UserAccountInfo, clientID: String, clientSecret: String, accessToken: String, scopes: [String]) {
guard let index = accounts.firstIndex(where: { $0.id == account.id }) else {
return
}
var account = account
account.accessToken = token
account.clientID = clientID
account.clientSecret = clientSecret
account.accessToken = accessToken
account.scopes = scopes
accounts[index] = account
}

View File

@ -173,8 +173,9 @@ final class MastodonController: ObservableObject, Sendable {
}
/// - Returns: A tuple of client ID and client secret.
func registerApp() async throws -> (String, String) {
if let clientID = client.clientID,
func registerApp(reregister: Bool = false) async throws -> (String, String) {
if !reregister,
let clientID = client.clientID,
let clientSecret = client.clientSecret {
return (clientID, clientSecret)
} else {

View File

@ -121,13 +121,54 @@ class PreferencesNavigationController: UINavigationController {
guard let account = notification.object as? UserAccountInfo else {
return
}
let dimmingView = UIView()
dimmingView.translatesAutoresizingMaskIntoConstraints = false
dimmingView.backgroundColor = .black.withAlphaComponent(0.1)
let blur = UIBlurEffect(style: .prominent)
let blurView = UIVisualEffectView(effect: blur)
blurView.translatesAutoresizingMaskIntoConstraints = false
blurView.layer.cornerRadius = 15
blurView.layer.masksToBounds = true
let spinner = UIActivityIndicatorView(style: .large)
spinner.translatesAutoresizingMaskIntoConstraints = false
spinner.startAnimating()
blurView.contentView.addSubview(spinner)
dimmingView.addSubview(blurView)
view.addSubview(dimmingView)
NSLayoutConstraint.activate([
dimmingView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
dimmingView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
dimmingView.topAnchor.constraint(equalTo: view.topAnchor),
dimmingView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
blurView.widthAnchor.constraint(equalToConstant: 100),
blurView.heightAnchor.constraint(equalToConstant: 100),
blurView.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
blurView.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor),
spinner.centerXAnchor.constraint(equalTo: blurView.contentView.centerXAnchor),
spinner.centerYAnchor.constraint(equalTo: blurView.contentView.centerYAnchor),
])
dimmingView.layer.opacity = 0
blurView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseInOut) {
dimmingView.layer.opacity = 1
blurView.transform = .identity
}
Task {
do {
let service = GetAuthorizationTokenService(instanceURL: account.instanceURL, clientID: account.clientID, presentationContextProvider: self)
let code = try await service.run()
let mastodonController = MastodonController.getForAccount(account)
let (clientID, clientSecret) = try await mastodonController.registerApp(reregister: true)
let service = GetAuthorizationTokenService(instanceURL: account.instanceURL, clientID: clientID, presentationContextProvider: self)
let code = try await service.run()
let token = try await mastodonController.authorize(authorizationCode: code)
UserAccountsManager.shared.updateAccessToken(account, token: token, scopes: MastodonController.oauthScopes.map(\.rawValue))
UserAccountsManager.shared.updateCredentials(account, clientID: clientID, clientSecret: clientSecret, accessToken: token, scopes: MastodonController.oauthScopes.map(\.rawValue))
// try to revoke the old token
try? await Client(baseURL: account.instanceURL, accessToken: account.accessToken, clientID: account.clientID, clientSecret: account.clientSecret).revokeAccessToken()
} catch {
@ -135,6 +176,8 @@ class PreferencesNavigationController: UINavigationController {
alert.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alert, animated: true)
}
dimmingView.removeFromSuperview()
}
}