yattee/Model/Accounts/AccountValidator.swift

159 lines
4.4 KiB
Swift
Raw Normal View History

2021-09-25 08:18:22 +00:00
import Foundation
import Siesta
import SwiftUI
final class AccountValidator: Service {
2021-10-20 22:21:50 +00:00
let app: Binding<VideosApp>
2021-09-25 08:18:22 +00:00
let url: String
let account: Account!
2021-09-25 08:18:22 +00:00
var formObjectID: Binding<String>
var isValid: Binding<Bool>
var isValidated: Binding<Bool>
var isValidating: Binding<Bool>
2021-09-25 08:18:22 +00:00
var error: Binding<String?>?
init(
2021-10-20 22:21:50 +00:00
app: Binding<VideosApp>,
2021-09-25 08:18:22 +00:00
url: String,
2021-10-20 22:21:50 +00:00
account: Account? = nil,
id: Binding<String>,
isValid: Binding<Bool>,
isValidated: Binding<Bool>,
isValidating: Binding<Bool>,
2021-09-25 08:18:22 +00:00
error: Binding<String?>? = nil
) {
2021-10-16 22:48:58 +00:00
self.app = app
2021-09-25 08:18:22 +00:00
self.url = url
self.account = account
formObjectID = id
self.isValid = isValid
self.isValidated = isValidated
self.isValidating = isValidating
2021-09-25 08:18:22 +00:00
self.error = error
super.init(baseURL: url)
configure()
}
func configure() {
2021-10-16 22:48:58 +00:00
configure {
$0.pipeline[.parsing].add(SwiftyJSONTransformer, contentTypes: ["*/json"])
}
2021-09-25 08:18:22 +00:00
configure("/api/v1/auth/feed", requestMethods: [.get]) {
guard self.account != nil else {
return
}
$0.headers["Cookie"] = self.invidiousCookieHeader
}
configure("/login", requestMethods: [.post]) {
$0.headers["Content-Type"] = "application/json"
2021-09-25 08:18:22 +00:00
}
}
func validateInstance() {
reset()
2021-11-07 21:39:28 +00:00
neverGonnaGiveYouUp
2021-09-25 08:18:22 +00:00
.load()
2021-10-16 22:48:58 +00:00
.onSuccess { response in
2021-09-25 08:18:22 +00:00
guard self.url == self.formObjectID.wrappedValue else {
return
}
2021-11-07 21:39:28 +00:00
let json = response.json.dictionaryValue
let author = self.app.wrappedValue == .invidious ? json["author"] : json["uploader"]
if author == "Rick Astley" {
2021-10-16 22:48:58 +00:00
self.isValid.wrappedValue = true
self.error?.wrappedValue = nil
} else {
self.isValid.wrappedValue = false
}
2021-09-25 08:18:22 +00:00
}
.onFailure { error in
guard self.url == self.formObjectID.wrappedValue else {
return
}
self.isValid.wrappedValue = false
2021-09-25 08:18:22 +00:00
self.error?.wrappedValue = error.userMessage
}
.onCompletion { _ in
self.isValidated.wrappedValue = true
self.isValidating.wrappedValue = false
2021-09-25 08:18:22 +00:00
}
}
func validateAccount() {
2021-09-25 08:18:22 +00:00
reset()
accountRequest
.onSuccess { response in
guard self.account!.username == self.formObjectID.wrappedValue else {
2021-09-25 08:18:22 +00:00
return
}
switch self.app.wrappedValue {
case .invidious:
self.isValid.wrappedValue = true
case .piped:
let error = response.json.dictionaryValue["error"]?.string
let token = response.json.dictionaryValue["token"]?.string
self.isValid.wrappedValue = error?.isEmpty ?? !(token?.isEmpty ?? true)
self.error!.wrappedValue = error
}
2021-09-25 08:18:22 +00:00
}
.onFailure { _ in
guard self.account!.username == self.formObjectID.wrappedValue else {
2021-09-25 08:18:22 +00:00
return
}
self.isValid.wrappedValue = false
}
.onCompletion { _ in
self.isValidated.wrappedValue = true
self.isValidating.wrappedValue = false
2021-09-25 08:18:22 +00:00
}
}
var accountRequest: Request {
switch app.wrappedValue {
case .invidious:
return feed.load()
case .piped:
return login.request(.post, json: ["username": account.username, "password": account.password])
}
}
2021-09-25 08:18:22 +00:00
func reset() {
isValid.wrappedValue = false
isValidated.wrappedValue = false
isValidating.wrappedValue = false
2021-09-25 08:18:22 +00:00
error?.wrappedValue = nil
}
var invidiousCookieHeader: String {
"SID=\(account.username)"
}
var login: Resource {
resource("/login")
2021-09-25 08:18:22 +00:00
}
var feed: Resource {
resource("/api/v1/auth/feed")
}
2021-11-07 21:39:28 +00:00
var videoResourceBasePath: String {
app.wrappedValue == .invidious ? "/api/v1/videos" : "/streams"
}
var neverGonnaGiveYouUp: Resource {
resource("\(videoResourceBasePath)/dQw4w9WgXcQ")
}
2021-09-25 08:18:22 +00:00
}