@@ -82,7 +82,6 @@ public enum Token {
82
82
}
83
83
}
84
84
85
- public typealias Options = Request
86
85
public typealias Literal = Response
87
86
}
88
87
@@ -91,18 +90,22 @@ public enum Token {
91
90
/// Protocol for types that can provide connection credentials.
92
91
/// Implement this protocol to create custom credential providers (e.g., fetching from your backend API).
93
92
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.
96
97
/// - Returns: A token response containing the server URL and participant token
97
98
/// - 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
99
100
}
100
101
101
102
/// `Token.Literal` contains a single set of credentials, hard-coded or acquired from a static source.
102
103
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 }
106
109
}
107
110
108
111
// MARK: - Endpoint
@@ -123,17 +126,19 @@ public extension TokenEndpoint {
123
126
var method : String { " POST " }
124
127
var headers : [ String : String ] { [ : ] }
125
128
126
- func fetch ( _ request : Token . Request ) async throws -> Token . Response {
129
+ func generate ( ) async throws -> Token . Response {
127
130
var urlRequest = URLRequest ( url: url)
128
131
129
132
urlRequest. httpMethod = method
130
133
for (key, value) in headers {
131
134
urlRequest. addValue ( value, forHTTPHeaderField: key)
132
135
}
133
- urlRequest. httpBody = try JSONEncoder ( ) . encode ( request)
136
+ urlRequest. httpBody = try await JSONEncoder ( ) . encode ( request)
134
137
135
138
let ( data, response) = try await URLSession . shared. data ( for: urlRequest)
136
139
140
+ try Task . checkCancellation ( )
141
+
137
142
guard let httpResponse = response as? HTTPURLResponse else {
138
143
throw LiveKitError ( . network, message: " Error generating token from the token server, no response " )
139
144
}
@@ -159,7 +164,19 @@ public actor CachingTokenSource: TokenSource, Loggable {
159
164
/// - Returns: `true` if the cached credentials are still valid, `false` otherwise
160
165
public typealias TokenValidator = ( Token . Request , Token . Response ) -> Bool
161
166
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
163
180
private let store : TokenStore
164
181
private let validator : TokenValidator
165
182
@@ -178,17 +195,23 @@ public actor CachingTokenSource: TokenSource, Loggable {
178
195
self . validator = validator
179
196
}
180
197
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,
184
202
validator ( cachedRequest, cachedResponse)
185
203
{
186
204
log ( " Using cached credentials " , . debug)
187
205
return cachedResponse
188
206
}
189
207
190
208
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
+
192
215
await store. store ( ( request, response) )
193
216
return response
194
217
}
0 commit comments