fix(auth): fenced oauth refresh writes
- Fenced final OAuth refresh update and terminal-disable CAS statements by row id, serialized credential data, active lease owner, and unexpired lease time. - Passed an AbortSignal through MCP OAuth token refresh and bounded owned refresh operations below the lease TTL while awaiting the aborted fetch to settle. - Added regressions for stolen-lease update/disable attempts and timed-out MCP token fetch abort behavior. Fixes #5081
This commit is contained in:
@@ -1238,7 +1238,7 @@ export class MCPManager {
|
||||
const material = selectMcpOAuthRefreshMaterial(current, auth);
|
||||
return Boolean(current.refresh && material?.tokenUrl);
|
||||
},
|
||||
refresh: current => {
|
||||
refresh: (current, signal) => {
|
||||
if (current.refresh === REMOTE_REFRESH_SENTINEL) {
|
||||
throw new Error("MCP OAuth refresh token is broker-redacted; local refresh is unavailable");
|
||||
}
|
||||
@@ -1257,6 +1257,7 @@ export class MCPManager {
|
||||
return refreshMCPOAuthToken(tokenUrl, current.refresh, clientId, clientSecret, resource, {
|
||||
authorizationUrl,
|
||||
stripSameOriginResource: resourceIsFallback,
|
||||
signal,
|
||||
});
|
||||
},
|
||||
mergeRefreshedCredential: (current, refreshed) => {
|
||||
|
||||
@@ -715,6 +715,7 @@ export class MCPOAuthFlow extends OAuthCallbackFlow {
|
||||
*/
|
||||
export interface RefreshMCPOAuthTokenOptions {
|
||||
fetch?: FetchImpl;
|
||||
signal?: AbortSignal;
|
||||
/**
|
||||
* Authorization-server URL the original grant was minted against. Used to
|
||||
* filter same-origin resource indicators on refresh. Defaults to `tokenUrl`'s
|
||||
@@ -766,6 +767,7 @@ export async function refreshMCPOAuthToken(
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: params.toString(),
|
||||
signal: optsFromTrailing?.signal,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
|
||||
Reference in New Issue
Block a user