Skip to content

Commit e27bd11

Browse files
committed
Mutable variant with setRequest
1 parent 507a6d1 commit e27bd11

File tree

3 files changed

+47
-16
lines changed

3 files changed

+47
-16
lines changed

Sources/LiveKit/Auth/Sandbox.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ public struct Sandbox: TokenEndpoint {
2525
["X-Sandbox-ID": id]
2626
}
2727

28+
public var request: Token.Request?
29+
public mutating func setRequest(_ request: Token.Request) {
30+
self.request = request
31+
}
32+
33+
public mutating func clearRequest() {
34+
request = nil
35+
}
36+
2837
/// The sandbox ID provided by LiveKit Cloud.
2938
public let id: String
3039

Sources/LiveKit/Auth/TokenSource.swift

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ public enum Token {
8282
}
8383
}
8484

85-
public typealias Options = Request
8685
public typealias Literal = Response
8786
}
8887

@@ -91,18 +90,22 @@ public enum Token {
9190
/// Protocol for types that can provide connection credentials.
9291
/// Implement this protocol to create custom credential providers (e.g., fetching from your backend API).
9392
public protocol TokenSource: Sendable {
94-
/// Fetch connection credentials for the given request.
95-
/// - Parameter request: The token request containing room and participant information
93+
var request: Token.Request? { get async }
94+
mutating func setRequest(_ request: Token.Request) async
95+
mutating func clearRequest() async
96+
/// Get connection credentials for the given request.
9697
/// - Returns: A token response containing the server URL and participant token
9798
/// - Throws: An error if the token generation fails
98-
func fetch(_ request: Token.Request) async throws -> Token.Response
99+
func generate() async throws -> Token.Response
99100
}
100101

101102
/// `Token.Literal` contains a single set of credentials, hard-coded or acquired from a static source.
102103
extension Token.Literal: TokenSource {
103-
public func fetch(_: Token.Request) async throws -> Token.Response {
104-
self
105-
}
104+
public var request: Token.Request? { nil }
105+
public func setRequest(_: Token.Request) {}
106+
public func clearRequest() {}
107+
108+
public func generate() async throws -> Token.Response { self }
106109
}
107110

108111
// MARK: - Endpoint
@@ -123,17 +126,19 @@ public extension TokenEndpoint {
123126
var method: String { "POST" }
124127
var headers: [String: String] { [:] }
125128

126-
func fetch(_ request: Token.Request) async throws -> Token.Response {
129+
func generate() async throws -> Token.Response {
127130
var urlRequest = URLRequest(url: url)
128131

129132
urlRequest.httpMethod = method
130133
for (key, value) in headers {
131134
urlRequest.addValue(value, forHTTPHeaderField: key)
132135
}
133-
urlRequest.httpBody = try JSONEncoder().encode(request)
136+
urlRequest.httpBody = try await JSONEncoder().encode(request)
134137

135138
let (data, response) = try await URLSession.shared.data(for: urlRequest)
136139

140+
try Task.checkCancellation()
141+
137142
guard let httpResponse = response as? HTTPURLResponse else {
138143
throw LiveKitError(.network, message: "Error generating token from the token server, no response")
139144
}
@@ -159,7 +164,19 @@ public actor CachingTokenSource: TokenSource, Loggable {
159164
/// - Returns: `true` if the cached credentials are still valid, `false` otherwise
160165
public typealias TokenValidator = (Token.Request, Token.Response) -> Bool
161166

162-
private let source: TokenSource
167+
public var request: Token.Request? {
168+
get async { await source.request }
169+
}
170+
171+
public func setRequest(_ request: Token.Request) async {
172+
await source.setRequest(request)
173+
}
174+
175+
public func clearRequest() async {
176+
await source.clearRequest()
177+
}
178+
179+
private var source: TokenSource
163180
private let store: TokenStore
164181
private let validator: TokenValidator
165182

@@ -178,17 +195,23 @@ public actor CachingTokenSource: TokenSource, Loggable {
178195
self.validator = validator
179196
}
180197

181-
public func fetch(_ request: Token.Request) async throws -> Token.Response {
182-
if let (cachedRequest, cachedResponse) = await store.retrieve(),
183-
cachedRequest == request,
198+
public func generate() async throws -> Token.Response {
199+
let request = await request ?? .init()
200+
201+
if let (cachedRequest, cachedResponse) = await store.retrieve(), cachedRequest == request,
184202
validator(cachedRequest, cachedResponse)
185203
{
186204
log("Using cached credentials", .debug)
187205
return cachedResponse
188206
}
189207

190208
log("Requesting new credentials", .debug)
191-
let response = try await source.fetch(request)
209+
let response = try await source.generate()
210+
211+
guard validator(request, response) else {
212+
throw LiveKitError(.network, message: "Invalid credentials")
213+
}
214+
192215
await store.store((request, response))
193216
return response
194217
}

Sources/LiveKit/Core/Room.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,12 @@ public class Room: NSObject, @unchecked Sendable, ObservableObject, Loggable {
412412
}
413413

414414
public func connect(tokenSource: TokenSource,
415-
tokenOptions: Token.Options = .init(),
416415
connectOptions: ConnectOptions? = nil,
417416
roomOptions: RoomOptions? = nil) async throws
418417
{
419418
self.tokenSource = tokenSource
420419

421-
let token = try await tokenSource.fetch(tokenOptions)
420+
let token = try await tokenSource.generate()
422421
try await connect(url: token.serverURL.absoluteString, token: token.participantToken, connectOptions: connectOptions, roomOptions: roomOptions)
423422
}
424423

0 commit comments

Comments
 (0)