@@ -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).
9392public 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.
102103extension 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,20 @@ 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+ await store. clear ( )
178+ }
179+
180+ private var source : TokenSource
163181 private let store : TokenStore
164182 private let validator : TokenValidator
165183
@@ -178,30 +196,29 @@ public actor CachingTokenSource: TokenSource, Loggable {
178196 self . validator = validator
179197 }
180198
181- public func fetch( _ request: Token . Request ) async throws -> Token . Response {
182- if let ( cachedRequest, cachedResponse) = await store. retrieve ( ) ,
183- cachedRequest == request,
199+ public func generate( ) async throws -> Token . Response {
200+ let request = await request ?? . init( )
201+
202+ if let ( cachedRequest, cachedResponse) = await store. retrieve ( ) , cachedRequest == request,
184203 validator ( cachedRequest, cachedResponse)
185204 {
186205 log ( " Using cached credentials " , . debug)
187206 return cachedResponse
188207 }
189208
190209 log ( " Requesting new credentials " , . debug)
191- let response = try await source. fetch ( request)
210+ let response = try await source. generate ( )
211+
212+ guard validator ( request, response) else {
213+ throw LiveKitError ( . network, message: " Invalid credentials " )
214+ }
215+
192216 await store. store ( ( request, response) )
193217 return response
194218 }
195219
196- /// Invalidate the cached credentials, forcing a fresh fetch on the next request.
197- public func invalidate( ) async {
198- await store. clear ( )
199- }
200-
201- /// Get the cached credentials
202- /// - Returns: The cached token if found, nil otherwise
203- public func cachedToken( ) async -> Token . Response ? {
204- await store. retrieve ( ) ? . 1
220+ var cachedResponse : Token . Response ? {
221+ get async { await store. retrieve ( ) ? . 1 }
205222 }
206223}
207224
0 commit comments