Nextcloud login flow v2 support (not in working state yet)

This commit is contained in:
Vicnet
2023-09-19 12:04:59 +02:00
parent 154cd9a51f
commit 0f16b164d6
6 changed files with 233 additions and 49 deletions

View File

@@ -54,6 +54,12 @@ struct WelcomeTab: View {
struct LoginTab: View {
@ObservedObject var userSettings: UserSettings
enum LoginMethod {
case v2, token
}
@State var selectedLoginMethod: LoginMethod = .v2
@State var loginRequest: LoginV2Request? = nil
enum Field {
case server
case username
@@ -73,43 +79,96 @@ struct LoginTab: View {
.padding()
Spacer()
}
LoginLabel(text: "Server address")
LoginTextField(example: "e.g.: example.com", text: $userSettings.serverAddress)
.focused($focusedField, equals: .server)
.textContentType(.URL)
.submitLabel(.next)
.padding(.bottom)
LoginLabel(text: "User name")
LoginTextField(example: "username", text: $userSettings.username)
.focused($focusedField, equals: .username)
.textContentType(.username)
.submitLabel(.next)
.padding(.bottom)
Picker("Login Method", selection: $selectedLoginMethod) {
Text("Nextcloud Login").tag(LoginMethod.v2)
Text("App Token Login").tag(LoginMethod.token)
}
.pickerStyle(.segmented)
.foregroundColor(.white)
if selectedLoginMethod == .token {
LoginLabel(text: "Server address")
LoginTextField(example: "e.g.: example.com", text: $userSettings.serverAddress)
.focused($focusedField, equals: .server)
.textContentType(.URL)
.submitLabel(.next)
.padding(.bottom)
LoginLabel(text: "App Token")
LoginTextField(example: "can be generated in security settings of your nextcloud", text: $userSettings.token)
.focused($focusedField, equals: .token)
.textContentType(.password)
.submitLabel(.join)
HStack{
Spacer()
Button {
userSettings.onboarding = false
} label: {
Text("Submit")
.foregroundColor(.white)
.font(.headline)
.padding()
.background(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.white, lineWidth: 2)
.foregroundColor(.clear)
)
LoginLabel(text: "User name")
LoginTextField(example: "username", text: $userSettings.username)
.focused($focusedField, equals: .username)
.textContentType(.username)
.submitLabel(.next)
.padding(.bottom)
LoginLabel(text: "App Token")
LoginTextField(example: "can be generated in security settings of your nextcloud", text: $userSettings.token)
.focused($focusedField, equals: .token)
.textContentType(.password)
.submitLabel(.join)
HStack{
Spacer()
Button {
userSettings.onboarding = false
} label: {
Text("Submit")
.foregroundColor(.white)
.font(.headline)
.padding()
.background(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.white, lineWidth: 2)
.foregroundColor(.clear)
)
}
.padding()
Spacer()
}
}
else if selectedLoginMethod == .v2 {
LoginLabel(text: "Server address")
LoginTextField(example: "e.g.: example.com", text: $userSettings.serverAddress)
.focused($focusedField, equals: .server)
.textContentType(.URL)
.submitLabel(.done)
.padding(.bottom)
.onSubmit {
if userSettings.serverAddress == "" { return }
Task {
await sendLoginV2Request()
if let loginRequest = loginRequest {
await UIApplication.shared.open(URL(string: loginRequest.login)!)
}
}
}
Text("Submitting will open a web browser. Please follow the login instructions provided there.\nAfter a successfull login, return to this application and press 'Done'.")
.font(.subheadline)
.padding(.bottom)
.tint(.white)
HStack{
Spacer()
Button {
// fetch login v2 response
Task {
guard let res = await fetchLoginV2Response() else { return }
print(res.loginName)
}
} label: {
Text("Done")
.foregroundColor(.white)
.font(.headline)
.padding()
.background(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.white, lineWidth: 2)
.foregroundColor(.clear)
)
}
.disabled(loginRequest == nil ? true : false)
.padding()
Spacer()
}
.padding()
Spacer()
}
Spacer()
}
@@ -127,6 +186,26 @@ struct LoginTab: View {
.padding()
}
}
func sendLoginV2Request() async {
let request = RequestWrapper(
method: .POST,
path: "https://\(userSettings.serverAddress)/index.php/login/v2"
)
let (loginReq, _): (LoginV2Request?, Error?) = await NetworkHandler.sendDataRequest(request)
self.loginRequest = loginReq
}
func fetchLoginV2Response() async -> LoginV2Response? {
guard let loginRequest = loginRequest else { return nil }
let request = RequestWrapper(
method: .POST,
path: loginRequest.poll.endpoint,
body: "token=\(loginRequest.poll.token)"
)
let (loginRes, _): (LoginV2Response?, Error?) = await NetworkHandler.sendDataRequest(request)
return loginRes
}
}
struct LoginLabel: View {