Skip to content

Commit 0247464

Browse files
committed
update env basic auth
1 parent 51851de commit 0247464

2 files changed

Lines changed: 35 additions & 84 deletions

File tree

Sources/PlayolaPlayer/Player/ListeningSessionReporter.swift

Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public class ListeningSessionReporter {
5151
return DeviceInfoProvider.identifierForVendor?.uuidString
5252
}
5353
var timer: Timer?
54-
let basicToken = "aW9zQXBwOnNwb3RpZnlTdWNrc0FCaWcx" // TODO: De-hard-code this
5554
var currentSessionStationId: String?
5655
var disposeBag = Set<AnyCancellable>()
5756
weak var stationPlayer: PlayolaStationPlayer?
@@ -239,17 +238,15 @@ public class ListeningSessionReporter {
239238

240239
// Check if we've exceeded retry limits
241240
if refreshAttempts >= maxRefreshAttempts {
241+
let error = ListeningSessionError.authenticationFailed("Max refresh attempts exceeded")
242242
Task {
243243
await errorReporter.reportError(
244-
ListeningSessionError.authenticationFailed("Max refresh attempts exceeded"),
244+
error,
245245
context: "Exceeded maximum refresh attempts (\(maxRefreshAttempts))",
246246
level: .warning
247247
)
248248
}
249-
250-
// Fall back to Basic auth
251-
try await attemptWithBasicAuth(url: url, requestBody: requestBody)
252-
return
249+
throw error
253250
}
254251

255252
// Attempt token refresh
@@ -276,43 +273,7 @@ public class ListeningSessionReporter {
276273
"HTTP status code after refresh: \(retryHttpResponse.statusCode)")
277274
}
278275
} else {
279-
// Refresh failed - try with Basic auth as fallback
280-
try await attemptWithBasicAuth(url: url, requestBody: requestBody)
281-
}
282-
}
283-
284-
private func attemptWithBasicAuth(url: URL, requestBody: ListeningSessionRequest) async throws {
285-
// Create request with Basic auth (bypassing the auth provider)
286-
var request = URLRequest(url: url)
287-
request.httpMethod = "POST"
288-
289-
do {
290-
request.httpBody = try JSONEncoder().encode(requestBody)
291-
} catch {
292-
throw ListeningSessionError.encodingError(
293-
"Failed to encode request body: \(error.localizedDescription)")
294-
}
295-
296-
request.addValue("Basic \(basicToken)", forHTTPHeaderField: "Authorization")
297-
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
298-
299-
let (_, response) = try await urlSession.data(for: request)
300-
301-
guard let httpResponse = response as? HTTPURLResponse else {
302-
throw ListeningSessionError.invalidResponse("Invalid HTTP response with Basic auth")
303-
}
304-
305-
if (200...299).contains(httpResponse.statusCode) {
306-
// Success with Basic auth
307-
Task {
308-
await errorReporter.reportError(
309-
ListeningSessionError.authenticationFailed("Fell back to Basic auth"),
310-
context: "Authentication failed, using Basic auth fallback",
311-
level: .warning
312-
)
313-
}
314-
} else {
315-
throw ListeningSessionError.authenticationFailed("Both Bearer token and Basic auth failed")
276+
throw ListeningSessionError.authenticationFailed("Token refresh failed")
316277
}
317278
}
318279

@@ -333,12 +294,10 @@ public class ListeningSessionReporter {
333294
"Failed to encode request body: \(error.localizedDescription)")
334295
}
335296

336-
// Use Bearer token if user is authenticated, otherwise fall back to Basic auth
337-
if let userToken = await authProvider?.getCurrentToken() {
338-
request.addValue("Bearer \(userToken)", forHTTPHeaderField: "Authorization")
339-
} else {
340-
request.addValue("Basic \(basicToken)", forHTTPHeaderField: "Authorization")
297+
guard let userToken = await authProvider?.getCurrentToken() else {
298+
throw ListeningSessionError.authenticationFailed("No authentication token available")
341299
}
300+
request.addValue("Bearer \(userToken)", forHTTPHeaderField: "Authorization")
342301

343302
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
344303
return request

Tests/PlayolaPlayerTests/ListeningSessionTests.swift

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,29 @@ struct ListeningSessionTests {
3030
#expect(authHeader == "Bearer valid.jwt.token")
3131
}
3232

33-
@Test("Uses Basic auth when no token available")
34-
func testUsesBasicAuthWhenNoToken() async throws {
33+
@Test("Throws when no token available")
34+
func testThrowsWhenNoToken() async throws {
3535
let mockAuth = MockAuthProvider(currentToken: nil)
3636
let reporter = await ListeningSessionReporter(authProvider: mockAuth)
3737

3838
let requestBody = ["test": "data"]
3939
let url = URL(string: "https://test.com")!
4040

41-
let request = try await reporter.createPostRequest(url: url, requestBody: requestBody)
42-
43-
// Check that Authorization header contains Basic auth
44-
let authHeader = request.value(forHTTPHeaderField: "Authorization")
45-
#expect(authHeader == "Basic aW9zQXBwOnNwb3RpZnlTdWNrc0FCaWcx")
41+
await #expect(throws: ListeningSessionError.self) {
42+
_ = try await reporter.createPostRequest(url: url, requestBody: requestBody)
43+
}
4644
}
4745

48-
@Test("Uses Basic auth when auth provider is nil")
49-
func testUsesBasicAuthWhenProviderIsNil() async throws {
46+
@Test("Throws when auth provider is nil")
47+
func testThrowsWhenProviderIsNil() async throws {
5048
let reporter = await ListeningSessionReporter(authProvider: nil)
5149

5250
let requestBody = ["test": "data"]
5351
let url = URL(string: "https://test.com")!
5452

55-
let request = try await reporter.createPostRequest(url: url, requestBody: requestBody)
56-
57-
// Check that Authorization header contains Basic auth
58-
let authHeader = request.value(forHTTPHeaderField: "Authorization")
59-
#expect(authHeader == "Basic aW9zQXBwOnNwb3RpZnlTdWNrc0FCaWcx")
53+
await #expect(throws: ListeningSessionError.self) {
54+
_ = try await reporter.createPostRequest(url: url, requestBody: requestBody)
55+
}
6056
}
6157
}
6258

@@ -90,8 +86,8 @@ struct ListeningSessionTests {
9086
#expect(mockURLSession.requestCallCount == 2)
9187
}
9288

93-
@Test("Handles failed token refresh gracefully")
94-
func testHandlesFailedRefresh() async throws {
89+
@Test("Throws when token refresh fails")
90+
func testThrowsWhenRefreshFails() async throws {
9591
let mockAuth = MockAuthProvider(
9692
currentToken: "expired.token",
9793
refreshedToken: nil // Refresh fails
@@ -102,24 +98,22 @@ struct ListeningSessionTests {
10298
let testURL = URL(string: "https://admin-api.playola.fm/v1/listeningSessions")!
10399
mockURLSession.addResponse(statusCode: 401, url: testURL)
104100

105-
// Basic auth fallback returns 200
106-
mockURLSession.addResponse(statusCode: 200, url: testURL)
107-
108101
let reporter = await ListeningSessionReporter(
109102
authProvider: mockAuth, urlSession: mockURLSession)
110103

111-
// This should fall back to Basic auth
112-
try await reporter.reportOrExtendListeningSession("test-station-id")
104+
await #expect(throws: ListeningSessionError.self) {
105+
try await reporter.reportOrExtendListeningSession("test-station-id")
106+
}
113107

114-
// Verify that refresh was called
108+
// Verify that refresh was attempted
115109
#expect(mockAuth.refreshCallCount == 1)
116110

117-
// Verify that two HTTP requests were made (initial + Basic auth fallback)
118-
#expect(mockURLSession.requestCallCount == 2)
111+
// Verify only the initial request was made (no fallback)
112+
#expect(mockURLSession.requestCallCount == 1)
119113
}
120114

121-
@Test("Exceeds max refresh attempts and falls back to Basic auth")
122-
func testExceedsMaxRefreshAttempts() async throws {
115+
@Test("Throws after exceeding max refresh attempts")
116+
func testThrowsAfterMaxRefreshAttempts() async throws {
123117
let mockAuth = MockAuthProvider(
124118
currentToken: "expired.token",
125119
refreshedToken: "still.expired.token" // Refresh returns token but still gets 401
@@ -136,21 +130,19 @@ struct ListeningSessionTests {
136130
mockURLSession.addResponse(statusCode: 401, url: testURL)
137131
}
138132

139-
// Final Basic auth fallback returns 200
140-
mockURLSession.addResponse(statusCode: 200, url: testURL)
141-
142133
let reporter = await ListeningSessionReporter(
143134
authProvider: mockAuth, urlSession: mockURLSession)
144135

145-
// This should exhaust refresh attempts and fall back to Basic auth
146-
try await reporter.reportOrExtendListeningSession("test-station-id")
136+
await #expect(throws: ListeningSessionError.self) {
137+
try await reporter.reportOrExtendListeningSession("test-station-id")
138+
}
147139

148140
// Verify that refresh was called 3 times (max attempts)
149141
#expect(mockAuth.refreshCallCount == 3)
150142

151143
// Verify correct number of HTTP requests:
152-
// 1 initial + 3 refresh attempts + 1 Basic auth fallback = 5
153-
#expect(mockURLSession.requestCallCount == 5)
144+
// 1 initial + 3 refresh attempts = 4 (no fallback)
145+
#expect(mockURLSession.requestCallCount == 4)
154146
}
155147

156148
@Test("Resets retry counter after successful request")
@@ -216,7 +208,7 @@ struct ListeningSessionTests {
216208
func testUsesCustomBaseURL() async throws {
217209
let customBaseURL = URL(string: "http://localhost:3000")!
218210
let mockSession = MockURLSession()
219-
let mockAuth = MockAuthProvider()
211+
let mockAuth = MockAuthProvider(currentToken: "test.token")
220212

221213
let reporter = await ListeningSessionReporter(
222214
authProvider: mockAuth,
@@ -237,7 +229,7 @@ struct ListeningSessionTests {
237229
@Test("Uses default production URL when not specified")
238230
func testUsesDefaultProductionURL() async throws {
239231
let mockSession = MockURLSession()
240-
let mockAuth = MockAuthProvider()
232+
let mockAuth = MockAuthProvider(currentToken: "test.token")
241233

242234
let reporter = await ListeningSessionReporter(
243235
authProvider: mockAuth,
@@ -258,7 +250,7 @@ struct ListeningSessionTests {
258250
func testEndSessionUsesCustomBaseURL() async throws {
259251
let customBaseURL = URL(string: "http://localhost:8080")!
260252
let mockSession = MockURLSession()
261-
let mockAuth = MockAuthProvider()
253+
let mockAuth = MockAuthProvider(currentToken: "test.token")
262254

263255
let reporter = await ListeningSessionReporter(
264256
authProvider: mockAuth,

0 commit comments

Comments
 (0)