Skip to content

Commit 8970a5b

Browse files
committed
Adding OIDC retry
1 parent 370f80f commit 8970a5b

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

server/services/OAuth2ProviderManager.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export class OAuth2ProviderManager {
5656
private providers: Map<string, OAuth2ClientWithConfig> = new Map()
5757
private providerStatus: Map<string, ProviderStatus> = new Map()
5858
private healthCheckInterval: NodeJS.Timeout | null = null
59+
private retryInterval: NodeJS.Timeout | null = null
5960
private factory: OAuth2ProviderFactory
6061
private obpClientService: OBPClientService
6162
private initialized: boolean = false
@@ -187,6 +188,12 @@ export class OAuth2ProviderManager {
187188
console.error(
188189
'OAuth2ProviderManager: Users will not be able to log in until at least one provider is available'
189190
)
191+
console.log('OAuth2ProviderManager: Will retry initialization every 30 seconds...')
192+
}
193+
194+
// Start retry interval for failed providers
195+
if (successCount < wellKnownUris.length) {
196+
this.startRetryInterval()
190197
}
191198

192199
return this.initialized
@@ -223,6 +230,87 @@ export class OAuth2ProviderManager {
223230
}
224231
}
225232

233+
/**
234+
* Start periodic retry for failed providers
235+
*
236+
* @param intervalMs - Retry interval in milliseconds (default: 30000 = 30 seconds)
237+
*/
238+
startRetryInterval(intervalMs: number = 30000): void {
239+
if (this.retryInterval) {
240+
console.log('OAuth2ProviderManager: Retry interval already running')
241+
return
242+
}
243+
244+
console.log(`OAuth2ProviderManager: Starting retry interval (every ${intervalMs / 1000}s)`)
245+
246+
this.retryInterval = setInterval(async () => {
247+
await this.retryFailedProviders()
248+
}, intervalMs)
249+
}
250+
251+
/**
252+
* Stop periodic retry interval
253+
*/
254+
stopRetryInterval(): void {
255+
if (this.retryInterval) {
256+
clearInterval(this.retryInterval)
257+
this.retryInterval = null
258+
console.log('OAuth2ProviderManager: Retry interval stopped')
259+
}
260+
}
261+
262+
/**
263+
* Retry all failed providers
264+
*/
265+
private async retryFailedProviders(): Promise<void> {
266+
const failedProviders: string[] = []
267+
268+
this.providerStatus.forEach((status, name) => {
269+
if (!status.available) {
270+
failedProviders.push(name)
271+
}
272+
})
273+
274+
// Also check if we have no providers at all (initial fetch may have failed)
275+
if (this.providerStatus.size === 0) {
276+
console.log(
277+
'OAuth2ProviderManager: No providers initialized yet, attempting full initialization...'
278+
)
279+
280+
// Temporarily stop retry to prevent duplicate calls
281+
this.stopRetryInterval()
282+
283+
const success = await this.initializeProviders()
284+
if (!success) {
285+
// Restart retry if initialization failed
286+
this.startRetryInterval()
287+
}
288+
return
289+
}
290+
291+
if (failedProviders.length === 0) {
292+
console.log('OAuth2ProviderManager: All providers healthy, stopping retry interval')
293+
this.stopRetryInterval()
294+
return
295+
}
296+
297+
console.log(`OAuth2ProviderManager: Retrying ${failedProviders.length} failed provider(s)...`)
298+
299+
for (const providerName of failedProviders) {
300+
const success = await this.retryProvider(providerName)
301+
if (success) {
302+
console.log(`OAuth2ProviderManager: Successfully recovered provider: ${providerName}`)
303+
}
304+
}
305+
306+
// Check if all providers are now healthy
307+
const stillFailed = Array.from(this.providerStatus.values()).filter((s) => !s.available)
308+
if (stillFailed.length === 0) {
309+
console.log('OAuth2ProviderManager: All providers recovered, stopping retry interval')
310+
this.stopRetryInterval()
311+
}
312+
}
313+
226314
/**
227315
* Perform health check on all providers
228316
*

0 commit comments

Comments
 (0)