(
refreshToken: string,
)
| 2175 | } |
| 2176 | |
| 2177 | private async _doRefresh( |
| 2178 | refreshToken: string, |
| 2179 | ): Promise<OAuthTokens | undefined> { |
| 2180 | const MAX_ATTEMPTS = 3 |
| 2181 | |
| 2182 | const mcpServerBaseUrl = getLoggingSafeMcpBaseUrl(this.serverConfig) |
| 2183 | const emitRefreshEvent = ( |
| 2184 | outcome: 'success' | 'failure', |
| 2185 | reason?: MCPRefreshFailureReason, |
| 2186 | ): void => { |
| 2187 | logEvent( |
| 2188 | outcome === 'success' |
| 2189 | ? 'tengu_mcp_oauth_refresh_success' |
| 2190 | : 'tengu_mcp_oauth_refresh_failure', |
| 2191 | { |
| 2192 | transportType: this.serverConfig |
| 2193 | .type as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 2194 | ...(mcpServerBaseUrl |
| 2195 | ? { |
| 2196 | mcpServerBaseUrl: |
| 2197 | mcpServerBaseUrl as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 2198 | } |
| 2199 | : {}), |
| 2200 | ...(reason |
| 2201 | ? { |
| 2202 | reason: |
| 2203 | reason as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 2204 | } |
| 2205 | : {}), |
| 2206 | }, |
| 2207 | ) |
| 2208 | } |
| 2209 | |
| 2210 | for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) { |
| 2211 | try { |
| 2212 | logMCPDebug(this.serverName, `Starting token refresh`) |
| 2213 | const authFetch = createAuthFetch() |
| 2214 | |
| 2215 | // Reuse cached metadata from the initial OAuth flow if available, |
| 2216 | // since metadata (token endpoint URL, etc.) is static per auth server. |
| 2217 | // Priority: |
| 2218 | // 1. In-memory cache (same-session refreshes) |
| 2219 | // 2. Persisted discovery state from initial auth (cross-session) — |
| 2220 | // avoids re-running RFC 9728 discovery on every refresh. |
| 2221 | // 3. Full RFC 9728 → RFC 8414 re-discovery via fetchAuthServerMetadata. |
| 2222 | let metadata = this._metadata |
| 2223 | if (!metadata) { |
| 2224 | const cached = await this.discoveryState() |
| 2225 | if (cached?.authorizationServerMetadata) { |
| 2226 | logMCPDebug( |
| 2227 | this.serverName, |
| 2228 | `Using persisted auth server metadata for refresh`, |
| 2229 | ) |
| 2230 | metadata = cached.authorizationServerMetadata |
| 2231 | } else if (cached?.authorizationServerUrl) { |
| 2232 | logMCPDebug( |
| 2233 | this.serverName, |
| 2234 | `Re-discovering metadata from persisted auth server URL: ${cached.authorizationServerUrl}`, |
no test coverage detected