Duplicate Code Opportunity
Summary
- Pattern: The "store token + compute refresh delay + schedule next refresh" block is copy-pasted verbatim into every OIDC token provider subclass
- Locations:
anthropic-oidc-token-provider.js lines 90–101, gcp-oidc-token-provider.js lines 161–172, oidc-token-provider.js (Azure) lines 144–155, aws-oidc-token-provider.js lines 168–178
- Impact: 9–11 lines × 4 copies = ~40 duplicate lines; the
REFRESH_FACTOR / MIN_REFRESH_MARGIN_SECS math appears four times — a single arithmetic fix or tuning change must be applied to every provider separately
Evidence
The following block (modulo variable name for the cached value) is identical across all four providers:
anthropic-oidc-token-provider.js lines 90–101:
const now = Math.floor(Date.now() / 1000);
this._cachedToken = access_token;
this._expiresAt = now + expires_in;
const refreshInSecs = Math.max(
0,
Math.min(
expires_in * REFRESH_FACTOR,
expires_in - MIN_REFRESH_MARGIN_SECS
)
);
this._scheduleRefresh(Math.floor(refreshInSecs * 1000));
gcp-oidc-token-provider.js lines 161–172: identical (variable named accessToken / expiresIn).
oidc-token-provider.js (Azure) lines 144–155: identical.
aws-oidc-token-provider.js lines 168–178: identical except cached field is this._cachedCredentials.
BaseOidcTokenProvider already owns _expiresAt, REFRESH_FACTOR, and _scheduleRefresh(), making this an obvious base-class responsibility.
Suggested Refactoring
Add a protected helper to oidc-token-provider-base.js:
/**
* Stores the new cached value, records expiry, and schedules the next refresh.
* `@param` {unknown} value - token string or credentials object to cache
* `@param` {number} expiresIn - token lifetime in seconds
*/
_storeAndScheduleRefresh(value, expiresIn) {
const now = Math.floor(Date.now() / 1000);
this._storeCachedValue(value); // new abstract hook, or inline per subclass
this._expiresAt = now + expiresIn;
const refreshInSecs = Math.max(
0,
Math.min(
expiresIn * REFRESH_FACTOR,
expiresIn - MIN_REFRESH_MARGIN_SECS
)
);
this._scheduleRefresh(Math.floor(refreshInSecs * 1000));
}
Because each subclass stores the value in a differently named field (_cachedToken vs _cachedCredentials), the simplest approach is to pass an assignment callback, or simply move the field assignment into an abstract _storeCachedValue(value) that each subclass implements. The _expiresAt update and the scheduling math move entirely to the base class.
Affected Files
containers/api-proxy/oidc-token-provider-base.js — add _storeAndScheduleRefresh() helper
containers/api-proxy/anthropic-oidc-token-provider.js — lines 90–101, replace with helper call
containers/api-proxy/gcp-oidc-token-provider.js — lines 161–172, replace with helper call
containers/api-proxy/oidc-token-provider.js — lines 144–155, replace with helper call
containers/api-proxy/aws-oidc-token-provider.js — lines 168–178, replace with helper call
Effort Estimate
Low–Medium
Detected by Duplicate Code Detector workflow. Run date: 2026-05-26
Generated by Duplicate Code Detector · sonnet46 2.8M · ◷
Duplicate Code Opportunity
Summary
anthropic-oidc-token-provider.jslines 90–101,gcp-oidc-token-provider.jslines 161–172,oidc-token-provider.js(Azure) lines 144–155,aws-oidc-token-provider.jslines 168–178REFRESH_FACTOR/MIN_REFRESH_MARGIN_SECSmath appears four times — a single arithmetic fix or tuning change must be applied to every provider separatelyEvidence
The following block (modulo variable name for the cached value) is identical across all four providers:
anthropic-oidc-token-provider.jslines 90–101:gcp-oidc-token-provider.jslines 161–172: identical (variable namedaccessToken/expiresIn).oidc-token-provider.js(Azure) lines 144–155: identical.aws-oidc-token-provider.jslines 168–178: identical except cached field isthis._cachedCredentials.BaseOidcTokenProvideralready owns_expiresAt,REFRESH_FACTOR, and_scheduleRefresh(), making this an obvious base-class responsibility.Suggested Refactoring
Add a protected helper to
oidc-token-provider-base.js:Because each subclass stores the value in a differently named field (
_cachedTokenvs_cachedCredentials), the simplest approach is to pass an assignment callback, or simply move the field assignment into an abstract_storeCachedValue(value)that each subclass implements. The_expiresAtupdate and the scheduling math move entirely to the base class.Affected Files
containers/api-proxy/oidc-token-provider-base.js— add_storeAndScheduleRefresh()helpercontainers/api-proxy/anthropic-oidc-token-provider.js— lines 90–101, replace with helper callcontainers/api-proxy/gcp-oidc-token-provider.js— lines 161–172, replace with helper callcontainers/api-proxy/oidc-token-provider.js— lines 144–155, replace with helper callcontainers/api-proxy/aws-oidc-token-provider.js— lines 168–178, replace with helper callEffort Estimate
Low–Medium
Detected by Duplicate Code Detector workflow. Run date: 2026-05-26