Skip to content

Commit 8660c25

Browse files
committed
Extract storage
1 parent ac4f130 commit 8660c25

File tree

1 file changed

+50
-7
lines changed

1 file changed

+50
-7
lines changed

Sources/LiveKit/Auth/ConnectionCredentials.swift

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public struct SandboxTokenServer: TokenServer {
146146

147147
// MARK: - Cache
148148

149-
/// `CachingCredentialsProvider` handles in-memory caching of credentials from any other `CredentialsProvider`.
149+
/// `CachingCredentialsProvider` handles caching of credentials from any other `CredentialsProvider` using configurable storage.
150150
public actor CachingCredentialsProvider: CredentialsProvider, Loggable {
151151
/// A tuple containing the request and response that were cached.
152152
public typealias Cached = (ConnectionCredentials.Request, ConnectionCredentials.Response)
@@ -155,31 +155,74 @@ public actor CachingCredentialsProvider: CredentialsProvider, Loggable {
155155

156156
private let provider: CredentialsProvider
157157
private let validator: Validator
158-
159-
private var cached: Cached?
158+
private let storage: CredentialsStorage
160159

161160
/// Initialize a caching wrapper around any credentials provider.
162161
/// - Parameters:
163162
/// - provider: The underlying credentials provider to wrap
163+
/// - storage: The storage implementation to use for caching (defaults to in-memory storage)
164164
/// - validator: A closure to determine if cached credentials are still valid (defaults to JWT expiration check)
165-
public init(_ provider: CredentialsProvider, validator: @escaping Validator = { _, res in res.hasValidToken() }) {
165+
public init(
166+
_ provider: CredentialsProvider,
167+
storage: CredentialsStorage = InMemoryCredentialsStorage(),
168+
validator: @escaping Validator = { _, res in res.hasValidToken() }
169+
) {
166170
self.provider = provider
171+
self.storage = storage
167172
self.validator = validator
168173
}
169174

170175
public func fetch(_ request: ConnectionCredentials.Request) async throws -> ConnectionCredentials.Response {
171-
if let (cachedRequest, cachedResponse) = cached, cachedRequest == request, validator(cachedRequest, cachedResponse) {
176+
if let (cachedRequest, cachedResponse) = await storage.retrieve(),
177+
cachedRequest == request,
178+
validator(cachedRequest, cachedResponse)
179+
{
172180
log("Using cached credentials", .debug)
173181
return cachedResponse
174182
}
175183

176184
let response = try await provider.fetch(request)
177-
cached = (request, response)
185+
try await storage.store((request, response))
178186
return response
179187
}
180188

181189
/// Invalidate the cached credentials, forcing a fresh fetch on the next request.
182-
public func invalidate() {
190+
public func invalidate() async {
191+
await storage.clear()
192+
}
193+
}
194+
195+
// MARK: - Storage
196+
197+
/// Protocol for abstract storage that can persist and retrieve a single cached credential pair.
198+
/// Implement this protocol to create custom storage implementations e.g. for Keychain.
199+
public protocol CredentialsStorage: Sendable {
200+
/// Store credentials in the storage (replaces any existing credentials)
201+
func store(_ credentials: CachingCredentialsProvider.Cached) async throws
202+
203+
/// Retrieve the cached credentials
204+
/// - Returns: The cached credentials if found, nil otherwise
205+
func retrieve() async -> CachingCredentialsProvider.Cached?
206+
207+
/// Clear the stored credentials
208+
func clear() async
209+
}
210+
211+
/// Simple in-memory storage implementation
212+
public actor InMemoryCredentialsStorage: CredentialsStorage {
213+
private var cached: CachingCredentialsProvider.Cached?
214+
215+
public init() {}
216+
217+
public func store(_ credentials: CachingCredentialsProvider.Cached) async throws {
218+
cached = credentials
219+
}
220+
221+
public func retrieve() async -> CachingCredentialsProvider.Cached? {
222+
cached
223+
}
224+
225+
public func clear() async {
183226
cached = nil
184227
}
185228
}

0 commit comments

Comments
 (0)