mirror of
https://github.com/lumaa-dev/BubbleApp.git
synced 2025-01-29 01:39:16 +01:00
Warn when signing in to dangerous instances
This commit is contained in:
parent
d8bfc0a4c3
commit
97254d0829
@ -3,6 +3,45 @@
|
||||
import Foundation
|
||||
|
||||
public struct Instance: Codable, Sendable {
|
||||
static let blocklistUrl: URL? = URL(string: "https://codeberg.org/oliphant/blocklists/raw/branch/main/blocklists/_unified_tier2_blocklist.csv")
|
||||
|
||||
@MainActor
|
||||
static func getBlocklist() -> [String] {
|
||||
var final: [String] = []
|
||||
//locate the file you want to use
|
||||
guard let filelink = Instance.blocklistUrl else {
|
||||
return []
|
||||
}
|
||||
|
||||
//convert that file into one long string
|
||||
var data = ""
|
||||
do {
|
||||
data = try String(contentsOf: filelink)
|
||||
} catch {
|
||||
print(error)
|
||||
return []
|
||||
}
|
||||
|
||||
//now split that string into an array of "rows" of data. Each row is a string.
|
||||
var rows = data.components(separatedBy: "\n")
|
||||
|
||||
//if you have a header row, remove it here
|
||||
rows.removeFirst()
|
||||
|
||||
//now loop around each row, and split it into each of its columns
|
||||
for row in rows {
|
||||
let columns = row.components(separatedBy: ",")
|
||||
|
||||
//check that we have enough columns
|
||||
if columns.count > 0 {
|
||||
let instanceUrl = columns[0]
|
||||
final.append(instanceUrl)
|
||||
}
|
||||
}
|
||||
|
||||
return final
|
||||
}
|
||||
|
||||
public struct Stats: Codable, Sendable {
|
||||
public let userCount: Int
|
||||
public let statusCount: Int
|
||||
|
@ -383,6 +383,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"activity.messages.read" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Mark as read"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Marquer comme lu"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"activity.no-notifications" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@ -743,6 +759,70 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"login.instance.unsafe" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "This instance is dangerous"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cette instance est dangereuse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"login.instance.unsafe.agree" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "I agree"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Je suis d'accord"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"login.instance.unsafe.description" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "The instance has been detected to be dangerous, Threaded does not take responsibility for any content posted or seen on this instance and will not provide support. Do you agree to take FULL responsibility?"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cette instance a été détectée comme étant dangereuse, Threaded ne prend pas la responsabilité pour tout contenu posté ou vu dans cette instance et ne fournira pas d'aide. Êtes-vous d'accord pour prendre la TOTALE responsabilité ?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"login.instance.unsafe.disagree" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "I disagree"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Je suis pas d'accord"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"login.mastodon" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@ -1479,6 +1559,70 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"status.action.bookmark" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Bookmark"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Placer un signet"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"status.action.like" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Like"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Aimer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"status.action.unbookmark" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Unbookmark"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Enlever le signet"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"status.action.unlike" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Unlike"
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Plus aimer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"status.editing" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
|
@ -9,9 +9,16 @@ struct AddInstanceView: View {
|
||||
|
||||
// Instance URL and verify
|
||||
@State private var instanceUrl: String = ""
|
||||
|
||||
@State private var verifying: Bool = false
|
||||
@State private var verified: Bool = false
|
||||
@State private var verifyError: Bool = false
|
||||
|
||||
@State private var blockList: [String] = []
|
||||
@State private var responsability: Bool = false
|
||||
@State private var showingResponsability: Bool = false
|
||||
@State private var agreedResponsability: Bool = false
|
||||
|
||||
@State private var instanceInfo: Instance?
|
||||
|
||||
@State private var signInClient: Client?
|
||||
@ -87,6 +94,36 @@ struct AddInstanceView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.task {
|
||||
withAnimation {
|
||||
verifying = true
|
||||
}
|
||||
|
||||
blockList = Instance.getBlocklist()
|
||||
|
||||
withAnimation {
|
||||
verifying = false
|
||||
}
|
||||
}
|
||||
.alert("login.instance.unsafe", isPresented: $showingResponsability, actions: {
|
||||
Button(role: .destructive) {
|
||||
responsability = true
|
||||
agreedResponsability = true
|
||||
showingResponsability.toggle()
|
||||
} label: {
|
||||
Text("login.instance.unsafe.agree")
|
||||
}
|
||||
|
||||
Button(role: .cancel) {
|
||||
responsability = true
|
||||
agreedResponsability = false
|
||||
showingResponsability.toggle()
|
||||
} label: {
|
||||
Text("login.instance.unsafe.disagree")
|
||||
}
|
||||
}, message: {
|
||||
Text("login.instance.unsafe.description")
|
||||
})
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(Color.appBackground)
|
||||
.onChange(of: instanceUrl) { _, newValue in
|
||||
@ -106,6 +143,38 @@ struct AddInstanceView: View {
|
||||
.replacingOccurrences(of: "http://", with: "")
|
||||
.replacingOccurrences(of: "https://", with: "")
|
||||
|
||||
if !isInstanceSafe() {
|
||||
if responsability == false && agreedResponsability == false {
|
||||
responsability = true
|
||||
agreedResponsability = false
|
||||
showingResponsability = true
|
||||
|
||||
withAnimation {
|
||||
verifying = false
|
||||
verified = false
|
||||
verifyError = false
|
||||
}
|
||||
|
||||
return
|
||||
} else if responsability == true && agreedResponsability == true {
|
||||
showingResponsability = false
|
||||
} else if responsability == true && agreedResponsability == false {
|
||||
showingResponsability = true
|
||||
|
||||
withAnimation {
|
||||
verifying = false
|
||||
verified = false
|
||||
verifyError = false
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
} else {
|
||||
responsability = false
|
||||
agreedResponsability = false
|
||||
UserDefaults.standard.removeObject(forKey: "unsafe")
|
||||
}
|
||||
|
||||
let client = Client(server: cleanInstance)
|
||||
|
||||
Task {
|
||||
@ -147,6 +216,12 @@ struct AddInstanceView: View {
|
||||
return
|
||||
}
|
||||
|
||||
if agreedResponsability && responsability {
|
||||
UserDefaults.standard.setValue(true, forKey: "unsafe")
|
||||
} else {
|
||||
UserDefaults.standard.removeObject(forKey: "unsafe")
|
||||
}
|
||||
|
||||
do {
|
||||
let oauthToken = try await client.continueOauthFlow(url: url)
|
||||
let client = Client(server: client.server, oauthToken: oauthToken)
|
||||
@ -163,6 +238,13 @@ struct AddInstanceView: View {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
/// Is the user input instance URL a safe instance
|
||||
/// - returns: True, if the instance isn't consider as dangerous
|
||||
private func isInstanceSafe() -> Bool {
|
||||
let unsafe = blockList.contains(instanceUrl.trimmingCharacters(in: .whitespacesAndNewlines))
|
||||
return !unsafe
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
|
Loading…
x
Reference in New Issue
Block a user