From 74b4be198494d982bfa6c59171cc7e63a88a0009 Mon Sep 17 00:00:00 2001 From: Shane Mander Date: Sat, 12 Apr 2025 20:56:33 -0700 Subject: [PATCH 1/2] jwt auth header --- .../Services/API/APIService.swift | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift b/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift index 83aed16..98a6066 100644 --- a/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift +++ b/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift @@ -234,7 +234,7 @@ class APIService: IAPIService { request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = encodedData - + setAuthHeaders(request: &request, url: finalURL) let (data, response) = try await URLSession.shared.data(for: request) guard let httpResponse = response as? HTTPURLResponse else { @@ -512,6 +512,33 @@ class APIService: IAPIService { } } + fileprivate func setAuthHeaders(request: inout URLRequest, url: URL) { + // Check if auth headers are needed + let whitelistedEndpoints = [ + "auth/sign-in", + "auth/make-user" + ] + if whitelistedEndpoints.contains(where: { url.absoluteString.contains($0) }) { + // Don't set auth headers for these endpoints + return + } + // Get the access token from keychain + guard if + let accessToken = KeychainService.load("accessToken") as? String, + let refreshToken = KeychainService.load("refreshToken") as? String + else { + print("❌ ERROR: Missing access or refresh token in Keychain") + return + } + + // Set the auth headers + request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization") + request.addValue('Bearer \(refreshToken)', forHTTPHeaderField: "X-Refresh-Token") + print("🔑 Auth headers set") + + return + } + internal func patchData( from url: URL, with object: T From dd6e9d0e3b06d05182582f8a0c469ec4fa82ad8f Mon Sep 17 00:00:00 2001 From: Shane Mander Date: Sat, 12 Apr 2025 23:22:09 -0700 Subject: [PATCH 2/2] Call setAuthHeaders from every API calling method --- .../Services/API/APIService.swift | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift b/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift index 98a6066..c060c02 100644 --- a/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift +++ b/Spawn-App-iOS-SwiftUI/Services/API/APIService.swift @@ -104,8 +104,11 @@ class APIService: IAPIService { print(errorMessage ?? "no error message to log") throw APIError.URLError } + var request = URLRequest(url: finalURL) + request.httpMethod = "GET" + setAuthHeaders(request: &request) - let (data, response) = try await URLSession.shared.data(from: finalURL) + let (data, response) = try await URLSession.shared.data(from: request) guard let httpResponse = response as? HTTPURLResponse else { errorMessage = "HTTP request failed for \(finalURL)" @@ -234,7 +237,7 @@ class APIService: IAPIService { request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = encodedData - setAuthHeaders(request: &request, url: finalURL) + setAuthHeaders(request: &request) let (data, response) = try await URLSession.shared.data(for: request) guard let httpResponse = response as? HTTPURLResponse else { @@ -304,7 +307,7 @@ class APIService: IAPIService { request.httpMethod = "PUT" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = encodedData - + setAuthHeaders(request: &request) let (data, response) = try await URLSession.shared.data(for: request) guard let httpResponse = response as? HTTPURLResponse else { @@ -332,7 +335,7 @@ class APIService: IAPIService { var request = URLRequest(url: url) request.httpMethod = "DELETE" // Set the HTTP method to DELETE - + setAuthHeaders(request: &request) // Set auth headers if needed let (_, response) = try await URLSession.shared.data(for: request) guard let httpResponse = response as? HTTPURLResponse else { @@ -512,7 +515,12 @@ class APIService: IAPIService { } } - fileprivate func setAuthHeaders(request: inout URLRequest, url: URL) { + fileprivate func setAuthHeaders(request: inout URLRequest) { + guard if let url = request.url else { + print("❌ ERROR: URL is nil") + return + } + // Check if auth headers are needed let whitelistedEndpoints = [ "auth/sign-in", @@ -556,7 +564,7 @@ class APIService: IAPIService { request.httpMethod = "PATCH" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = encodedData - + setAuthHeaders(request: &request) let (data, response) = try await URLSession.shared.data(for: request) // Debug: Log the response details @@ -640,7 +648,7 @@ class APIService: IAPIService { request.httpMethod = "PATCH" request.setValue("image/jpeg", forHTTPHeaderField: "Content-Type") request.httpBody = imageData - + sendAuthHeaders(request: &request) // Set auth headers if needed // Log request headers print("🔍 REQUEST HEADERS: \(request.allHTTPHeaderFields ?? [:])") @@ -695,7 +703,7 @@ class APIService: IAPIService { var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") - + setAuthHeaders(request: &request) // Set auth headers if needed // Create the body var body = Data()