core, ios: unhiding user profiles always requires password (#2101)
This commit is contained in:
committed by
GitHub
parent
a8c8137ade
commit
935d826a21
@@ -162,16 +162,16 @@ func apiHideUser(_ userId: Int64, viewPwd: String) async throws -> User {
|
||||
try await setUserPrivacy_(.apiHideUser(userId: userId, viewPwd: viewPwd))
|
||||
}
|
||||
|
||||
func apiUnhideUser(_ userId: Int64, viewPwd: String?) async throws -> User {
|
||||
func apiUnhideUser(_ userId: Int64, viewPwd: String) async throws -> User {
|
||||
try await setUserPrivacy_(.apiUnhideUser(userId: userId, viewPwd: viewPwd))
|
||||
}
|
||||
|
||||
func apiMuteUser(_ userId: Int64, viewPwd: String?) async throws -> User {
|
||||
try await setUserPrivacy_(.apiMuteUser(userId: userId, viewPwd: viewPwd))
|
||||
func apiMuteUser(_ userId: Int64) async throws -> User {
|
||||
try await setUserPrivacy_(.apiMuteUser(userId: userId))
|
||||
}
|
||||
|
||||
func apiUnmuteUser(_ userId: Int64, viewPwd: String?) async throws -> User {
|
||||
try await setUserPrivacy_(.apiUnmuteUser(userId: userId, viewPwd: viewPwd))
|
||||
func apiUnmuteUser(_ userId: Int64) async throws -> User {
|
||||
try await setUserPrivacy_(.apiUnmuteUser(userId: userId))
|
||||
}
|
||||
|
||||
func setUserPrivacy_(_ cmd: ChatCommand) async throws -> User {
|
||||
|
||||
@@ -44,10 +44,12 @@ struct UserProfilesView: View {
|
||||
|
||||
private enum UserProfileAction: Identifiable {
|
||||
case deleteUser(user: User, delSMPQueues: Bool)
|
||||
case unhideUser(user: User)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
case let .deleteUser(user, delSMPQueues): return "deleteUser \(user.userId) \(delSMPQueues)"
|
||||
case let .unhideUser(user): return "unhideUser \(user.userId)"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,43 +209,58 @@ struct UserProfilesView: View {
|
||||
|
||||
@ViewBuilder private func profileActionView(_ action: UserProfileAction) -> some View {
|
||||
let passwordValid = actionPassword == actionPassword.trimmingCharacters(in: .whitespaces)
|
||||
switch action {
|
||||
case let .deleteUser(user, delSMPQueues):
|
||||
let actionEnabled = actionPassword != "" && passwordValid && correctPassword(user, actionPassword)
|
||||
List {
|
||||
Text("Delete user")
|
||||
.font(.title)
|
||||
.bold()
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
.listRowBackground(Color.clear)
|
||||
|
||||
Section() {
|
||||
ProfilePreview(profileOf: user).padding(.leading, -8)
|
||||
}
|
||||
|
||||
let passwordField = PassphraseField(key: $actionPassword, placeholder: "Profile password", valid: passwordValid)
|
||||
let actionEnabled: (User) -> Bool = { user in actionPassword != "" && passwordValid && correctPassword(user, actionPassword) }
|
||||
List {
|
||||
switch action {
|
||||
case let .deleteUser(user, delSMPQueues):
|
||||
actionHeader("Delete user", user)
|
||||
Section {
|
||||
PassphraseField(key: $actionPassword, placeholder: "Profile password", valid: passwordValid)
|
||||
passwordField
|
||||
settingsRow("trash") {
|
||||
Button("Delete user", role: .destructive) {
|
||||
profileAction = nil
|
||||
Task { await removeUser(user, delSMPQueues, viewPwd: actionPassword) }
|
||||
}
|
||||
.disabled(!actionEnabled)
|
||||
.disabled(!actionEnabled(user))
|
||||
}
|
||||
} footer: {
|
||||
if actionEnabled {
|
||||
if actionEnabled(user) {
|
||||
Text("All chats and messages will be deleted - this cannot be undone!")
|
||||
.font(.callout)
|
||||
}
|
||||
}
|
||||
case let .unhideUser(user):
|
||||
actionHeader("Unhide user", user)
|
||||
Section {
|
||||
passwordField
|
||||
settingsRow("lock.open") {
|
||||
Button("Unhide user") {
|
||||
profileAction = nil
|
||||
setUserPrivacy(user) { try await apiUnhideUser(user.userId, viewPwd: actionPassword) }
|
||||
}
|
||||
.disabled(!actionEnabled(user))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func actionHeader(_ title: LocalizedStringKey, _ user: User) -> some View {
|
||||
Text(title)
|
||||
.font(.title)
|
||||
.bold()
|
||||
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
|
||||
.listRowBackground(Color.clear)
|
||||
Section() {
|
||||
ProfilePreview(profileOf: user).padding(.leading, -8)
|
||||
}
|
||||
}
|
||||
|
||||
private func deleteModeButton(_ title: LocalizedStringKey, _ delSMPQueues: Bool) -> some View {
|
||||
Button(title, role: .destructive) {
|
||||
if let user = userToDelete {
|
||||
if user.hidden && user.activeUser && !correctPassword(user, searchTextOrPassword) {
|
||||
if passwordEntryRequired(user) {
|
||||
profileAction = .deleteUser(user: user, delSMPQueues: delSMPQueues)
|
||||
} else {
|
||||
alert = .deleteUser(user: user, delSMPQueues: delSMPQueues)
|
||||
@@ -252,6 +269,10 @@ struct UserProfilesView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func passwordEntryRequired(_ user: User) -> Bool {
|
||||
user.hidden && user.activeUser && !correctPassword(user, searchTextOrPassword)
|
||||
}
|
||||
|
||||
private func removeUser(_ user: User, _ delSMPQueues: Bool, viewPwd: String?) async {
|
||||
do {
|
||||
if user.activeUser {
|
||||
@@ -307,7 +328,11 @@ struct UserProfilesView: View {
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
if user.hidden {
|
||||
Button("Unhide") {
|
||||
setUserPrivacy(user) { try await apiUnhideUser(user.userId, viewPwd: userViewPassword(user)) }
|
||||
if passwordEntryRequired(user) {
|
||||
profileAction = .unhideUser(user: user)
|
||||
} else {
|
||||
setUserPrivacy(user) { try await apiUnhideUser(user.userId, viewPwd: searchTextOrPassword) }
|
||||
}
|
||||
}
|
||||
.tint(.green)
|
||||
} else {
|
||||
@@ -321,12 +346,12 @@ struct UserProfilesView: View {
|
||||
if user.showNtfs {
|
||||
Button("Mute") {
|
||||
setUserPrivacy(user, successAlert: showMuteProfileAlert ? .muteProfileAlert : nil) {
|
||||
try await apiMuteUser(user.userId, viewPwd: userViewPassword(user))
|
||||
try await apiMuteUser(user.userId)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Button("Unmute") {
|
||||
setUserPrivacy(user) { try await apiUnmuteUser(user.userId, viewPwd: userViewPassword(user)) }
|
||||
setUserPrivacy(user) { try await apiUnmuteUser(user.userId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ public enum ChatCommand {
|
||||
case listUsers
|
||||
case apiSetActiveUser(userId: Int64, viewPwd: String?)
|
||||
case apiHideUser(userId: Int64, viewPwd: String)
|
||||
case apiUnhideUser(userId: Int64, viewPwd: String?)
|
||||
case apiMuteUser(userId: Int64, viewPwd: String?)
|
||||
case apiUnmuteUser(userId: Int64, viewPwd: String?)
|
||||
case apiUnhideUser(userId: Int64, viewPwd: String)
|
||||
case apiMuteUser(userId: Int64)
|
||||
case apiUnmuteUser(userId: Int64)
|
||||
case apiDeleteUser(userId: Int64, delSMPQueues: Bool, viewPwd: String?)
|
||||
case startChat(subscribe: Bool, expire: Bool)
|
||||
case apiStopChat
|
||||
@@ -111,9 +111,9 @@ public enum ChatCommand {
|
||||
case .listUsers: return "/users"
|
||||
case let .apiSetActiveUser(userId, viewPwd): return "/_user \(userId)\(maybePwd(viewPwd))"
|
||||
case let .apiHideUser(userId, viewPwd): return "/_hide user \(userId) \(encodeJSON(viewPwd))"
|
||||
case let .apiUnhideUser(userId, viewPwd): return "/_unhide user \(userId)\(maybePwd(viewPwd))"
|
||||
case let .apiMuteUser(userId, viewPwd): return "/_mute user \(userId)\(maybePwd(viewPwd))"
|
||||
case let .apiUnmuteUser(userId, viewPwd): return "/_unmute user \(userId)\(maybePwd(viewPwd))"
|
||||
case let .apiUnhideUser(userId, viewPwd): return "/_unhide user \(userId) \(encodeJSON(viewPwd))"
|
||||
case let .apiMuteUser(userId): return "/_mute user \(userId)"
|
||||
case let .apiUnmuteUser(userId): return "/_unmute user \(userId)"
|
||||
case let .apiDeleteUser(userId, delSMPQueues, viewPwd): return "/_delete user \(userId) del_smp=\(onOff(delSMPQueues))\(maybePwd(viewPwd))"
|
||||
case let .startChat(subscribe, expire): return "/_start subscribe=\(onOff(subscribe)) expire=\(onOff(expire))"
|
||||
case .apiStopChat: return "/_stop"
|
||||
@@ -332,10 +332,6 @@ public enum ChatCommand {
|
||||
return .apiHideUser(userId: userId, viewPwd: obfuscate(viewPwd))
|
||||
case let .apiUnhideUser(userId, viewPwd):
|
||||
return .apiUnhideUser(userId: userId, viewPwd: obfuscate(viewPwd))
|
||||
case let .apiMuteUser(userId, viewPwd):
|
||||
return .apiMuteUser(userId: userId, viewPwd: obfuscate(viewPwd))
|
||||
case let .apiUnmuteUser(userId, viewPwd):
|
||||
return .apiUnmuteUser(userId: userId, viewPwd: obfuscate(viewPwd))
|
||||
case let .apiDeleteUser(userId, delSMPQueues, viewPwd):
|
||||
return .apiDeleteUser(userId: userId, delSMPQueues: delSMPQueues, viewPwd: obfuscate(viewPwd))
|
||||
default: return self
|
||||
@@ -349,9 +345,8 @@ public enum ChatCommand {
|
||||
private func obfuscate(_ s: String?) -> String? {
|
||||
if let s = s {
|
||||
return obfuscate(s)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
private func onOff(_ b: Bool) -> String {
|
||||
|
||||
Reference in New Issue
Block a user