From ad55f5b78744687d47ec2da183c882cc77a38cfc Mon Sep 17 00:00:00 2001 From: andy Date: Thu, 11 Aug 2022 20:53:09 +0100 Subject: [PATCH] adding delete account, closes #21 --- Mixonomer/Model/LiveUser.swift | 28 +++++++++++- Mixonomer/Network/UserApi.swift | 42 ++++++++++++++++++ Mixonomer/Views/Settings/SettingsList.swift | 49 ++++++++++++++++----- 3 files changed, 106 insertions(+), 13 deletions(-) diff --git a/Mixonomer/Model/LiveUser.swift b/Mixonomer/Model/LiveUser.swift index 6f60308..a321065 100644 --- a/Mixonomer/Model/LiveUser.swift +++ b/Mixonomer/Model/LiveUser.swift @@ -9,6 +9,7 @@ import Foundation import Alamofire import SwiftyJSON +import KeychainAccess class LiveUser: ObservableObject { @@ -34,6 +35,31 @@ class LiveUser: ObservableObject { self.loggedIn = loggedIn } + init(playlists: [Playlist], tags: [Tag], username: String, loggedIn: Bool, user: User) { + self.playlists = playlists + self.tags = tags + self.username = username + self.loggedIn = loggedIn + self.user = user + } + + func logout() { + let keychain = Keychain(service: "xyz.sarsoo.music.login") + + do { + try keychain.remove("username") + try keychain.remove("jwt") + + UserDefaults.standard.removeObject(forKey: "playlists") + UserDefaults.standard.removeObject(forKey: "tags") + + self.loggedIn = false + + } catch let error { + debugPrint("Could not clear keychain, \(error)") + } + } + func updatePlaylist(playlistIn: Playlist) { guard let index = self.playlists.firstIndex(of: playlistIn) else { fatalError("\(playlistIn) not found") @@ -166,7 +192,7 @@ class LiveUser: ObservableObject { if let statusCode = response.response?.statusCode { switch statusCode { case 401: // token has expired - self.loggedIn = false + self.logout() return false case 400..<500: return false diff --git a/Mixonomer/Network/UserApi.swift b/Mixonomer/Network/UserApi.swift index fb7f3c7..10c021c 100644 --- a/Mixonomer/Network/UserApi.swift +++ b/Mixonomer/Network/UserApi.swift @@ -12,6 +12,7 @@ import SwiftyJSON public enum UserApi { case getUser + case deleteUser } extension UserApi: ApiRequest { @@ -23,6 +24,8 @@ extension UserApi: ApiRequest { switch self { case .getUser: return "api/user" + case .deleteUser: + return "api/user" } } @@ -30,6 +33,8 @@ extension UserApi: ApiRequest { switch self { case .getUser: return .get + case .deleteUser: + return .delete } } @@ -49,5 +54,42 @@ extension UserApi: ApiRequest { return ApiRequestDefaults.authMethod } + static func fromJSON(user: Data) -> User? { + + let decoder = JSONDecoder() + do { + let user = try decoder.decode(User.self, from: user) + return user + } catch { + print(error) + } + return nil + } + static func fromJSON(user: JSON) -> User? { + + let _json = user.rawString()?.data(using: .utf8) + + if let data = _json { + let decoder = JSONDecoder() + do { + let user = try decoder.decode(User.self, from: data) + return user + } catch { + print(error) + } + } + return nil + } + + static func fromJSON(user: [JSON]) -> [User] { + var _users: [User] = [] + for dict in user { + let _iter = self.fromJSON(user: dict) + if let returned = _iter { + _users.append(returned) + } + } + return _users + } } diff --git a/Mixonomer/Views/Settings/SettingsList.swift b/Mixonomer/Views/Settings/SettingsList.swift index e9566c4..92e65c3 100644 --- a/Mixonomer/Views/Settings/SettingsList.swift +++ b/Mixonomer/Views/Settings/SettingsList.swift @@ -13,6 +13,8 @@ struct SettingsList: View { @EnvironmentObject var liveUser: LiveUser + @State private var deleteAlertShowing = false + var body: some View { NavigationView { List{ @@ -25,21 +27,43 @@ struct SettingsList: View { Text("Launch Web Version") } Button(action: { - let keychain = Keychain(service: "xyz.sarsoo.music.login") - do { - try keychain.remove("username") - try keychain.remove("password") - try keychain.remove("jwt") - - self.liveUser.loggedIn = false - - } catch let error { - debugPrint("Could not clear keychain, \(error)") - } + self.liveUser.logout() }) { Text("Log out") } } + Section { + Button(action: { + deleteAlertShowing = true + }) { + Text("Delete Account") + .foregroundColor(.red) + } + .alert("Delete Account", isPresented: $deleteAlertShowing, actions: { + Text("This will irreversibly delete all of your data, are you sure?") + Button("Delete", role: .destructive) { + + let api = UserApi.deleteUser + RequestBuilder.buildRequest(apiRequest: api).responseJSON{ response in + + if self.liveUser.checkNetworkResponse(response: response) { + + self.liveUser.logout() + } + else { + + } + } + + } + Button("Cancel", role: .cancel) { + deleteAlertShowing = false + } + }, message: { + Text("This is irreversible, are you sure you want to delete your account?") + + }) + } Section( header: Text("Development"), @@ -70,7 +94,7 @@ struct SettingsList: View { } } .listStyle(GroupedListStyle()) - .navigationBarTitle(Text("Settings ⚡️").font(.title)) + .navigationBarTitle(Text("Settings ⚡️")) } } } @@ -78,5 +102,6 @@ struct SettingsList: View { struct SettingsList_Previews: PreviewProvider { static var previews: some View { SettingsList() + .environmentObject(LiveUser(playlists: [], tags: [], username: "user", loggedIn: false)) } }