Jonas Björkert 1 год назад
Родитель
Сommit
c9f8fcd88f

+ 20 - 6
LoopFollow/Helpers/NightscoutUtils.swift

@@ -373,12 +373,26 @@ class NightscoutUtils {
         return responseString
     }
 
-    static func extractTitle(from response: String) -> String? {
-        guard let startRange = response.range(of: "<title>"),
-              let endRange = response.range(of: "</title>") else {
-            return nil
+    static func extractErrorReason(from responseString: String) -> String {
+        // 1) Try to parse the entire string as JSON and return the "message"
+        if let data = responseString.data(using: .utf8) {
+            if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
+               let message = json["message"] as? String {
+                return message
+            }
         }
-        let titleRange = startRange.upperBound..<endRange.lowerBound
-        return String(response[titleRange]).trimmingCharacters(in: .whitespacesAndNewlines)
+
+        // 2) If not valid JSON (or no "message"), try to parse it as HTML <title>
+        if let startRange = responseString.range(of: "<title>"),
+           let endRange = responseString.range(of: "</title>") {
+            let titleRange = startRange.upperBound..<endRange.lowerBound
+            let titleContent = responseString[titleRange].trimmingCharacters(in: .whitespacesAndNewlines)
+            if !titleContent.isEmpty {
+                return titleContent
+            }
+        }
+
+        // 3) Fallback: just return the entire raw string
+        return responseString
     }
 }

+ 6 - 0
LoopFollow/Remote/Loop/LoopOverrideView.swift

@@ -14,6 +14,7 @@ struct LoopOverrideView: View {
 
     @ObservedObject var device = ObservableUserDefaults.shared.device
     @ObservedObject var overrideNote = Observable.shared.override
+    @ObservedObject var nsAdmin = ObservableUserDefaults.shared.nsWriteAuth
 
     @StateObject private var viewModel = LoopOverrideViewModel()
 
@@ -46,7 +47,12 @@ struct LoopOverrideView: View {
                     ErrorMessageView(
                         message: "Remote commands are currently only available for Loop."
                     )
+                } else if !nsAdmin.value {
+                    ErrorMessageView(
+                        message: "Please update your token to include the 'admin' role in order to do remote commands."
+                    )
                 } else {
+
                     Form {
                         if let activeNote = overrideNote.value {
                             Section(header: Text("Active Override")) {

+ 16 - 5
LoopFollow/Remote/Loop/LoopOverrideViewModel.swift

@@ -8,7 +8,7 @@
 
 import Foundation
 
-class LoopOverrideViewModel: ObservableObject {
+final class LoopOverrideViewModel: ObservableObject, Sendable {
     func sendActivateOverrideRequest(
         override: ProfileManager.LoopOverride,
         completion: @escaping (Bool, String?) -> Void
@@ -29,8 +29,9 @@ class LoopOverrideViewModel: ObservableObject {
                         NotificationCenter.default.post(name: NSNotification.Name("refresh"), object: nil)
                         completion(true, response)
                     } else {
-                        let errorTitle = NightscoutUtils.extractTitle(from: response) ?? response
-                        completion(false, errorTitle)
+                        let errorTitle = NightscoutUtils.extractErrorReason(from: response)
+                        let formattedError = self.formatErrorMessage(errorTitle)
+                        completion(false, formattedError)
                     }
                 }
             } catch {
@@ -55,8 +56,9 @@ class LoopOverrideViewModel: ObservableObject {
                         NotificationCenter.default.post(name: NSNotification.Name("refresh"), object: nil)
                         completion(true, response)
                     } else {
-                        let errorTitle = NightscoutUtils.extractTitle(from: response) ?? response
-                        completion(false, errorTitle)
+                        let errorTitle = NightscoutUtils.extractErrorReason(from: response)
+                        let formattedError = self.formatErrorMessage(errorTitle)
+                        completion(false, formattedError)
                     }
                 }
             } catch {
@@ -66,4 +68,13 @@ class LoopOverrideViewModel: ObservableObject {
             }
         }
     }
+
+    func formatErrorMessage(_ errorTitle: String) -> String {
+        switch errorTitle {
+        case "Unauthorized":
+            return "Unauthorized, verify that your token is correct and has admin auth"
+        default:
+            return errorTitle
+        }
+    }
 }