Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
let requestInterceptor: number | null = null;
let responseInterceptor: number | null = null;

let pendingRequests: any[] = [];

Check warning on line 112 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View workflow job for this annotation

GitHub Actions / lint-src

Unexpected any. Specify a different type

type AuthContextType = {
onLoginHandler: () => void;
Expand Down Expand Up @@ -381,7 +381,7 @@
} catch (error) {
const err = error as AxiosError;
if (err?.response?.status === 404) {
if (!authConfig?.enableSelfSignup) {

Check warning on line 384 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View check run for this annotation

SonarQubeCloud / [open-metadata-ui] SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=open-metadata-ui&issues=AZ1paimJpOvr1TFDHZQC&open=AZ1paimJpOvr1TFDHZQC&pullRequest=27140
resetUserDetails();
navigate(ROUTES.UNAUTHORISED);
showErrorToast(err);
Expand Down Expand Up @@ -461,7 +461,7 @@
}

requestInterceptor = axiosClient.interceptors.request.use(async function (
config: InternalAxiosRequestConfig<any>

Check warning on line 464 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View workflow job for this annotation

GitHub Actions / lint-src

Unexpected any. Specify a different type
) {
// Need to read token from local storage as it might have been updated with refresh
const token: string = await getOidcToken();
Expand Down Expand Up @@ -501,7 +501,7 @@
handleStoreProtectedRedirectPath();

// If 401 error and refresh is not in progress, trigger the refresh
if (!tokenService.current?.isTokenUpdateInProgress()) {

Check warning on line 504 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View check run for this annotation

SonarQubeCloud / [open-metadata-ui] SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=open-metadata-ui&issues=AZ1paimJpOvr1TFDHZQD&open=AZ1paimJpOvr1TFDHZQD&pullRequest=27140
// Start the refresh process
return new Promise((resolve, reject) => {
// Add this request to the pending queue
Expand All @@ -514,10 +514,10 @@
// Refresh the token and retry the requests in the queue
tokenService.current
.refreshToken()
.then((token) => {
.then(async (token) => {

Check failure on line 517 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View check run for this annotation

SonarQubeCloud / [open-metadata-ui] SonarCloud Code Analysis

Refactor this code to not nest functions more than 4 levels deep.

See more on https://sonarcloud.io/project/issues?id=open-metadata-ui&issues=AZ1paimJpOvr1TFDHZQE&open=AZ1paimJpOvr1TFDHZQE&pullRequest=27140
if (token) {
// Retry the pending requests
initializeAxiosInterceptors();
await initializeAxiosInterceptors();
pendingRequests.forEach(({ resolve, reject, config }) => {
Comment on lines +517 to 521
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The retry path treats a falsy refreshToken() result as a refresh failure (resetUserDetails(true)), but some authenticators intentionally return void for silent refresh (e.g., OidcAuthenticator’s renewIdToken resolves with no token and persists it via the silent-callback). In those cases this branch will force-logout and will never retry queued requests even though the token may have been refreshed. Consider basing the decision to retry on the persisted token (e.g., re-read getOidcToken() / compare against the previous token) or adjust TokenService.refreshToken() to resolve with the persisted token once it’s available.

Copilot uses AI. Check for mistakes.
axiosClient.request(config).then(resolve).catch(reject);
});
Expand All @@ -528,10 +528,10 @@
resetUserDetails(true);
}
})
.catch((error) => {

Check failure on line 531 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View check run for this annotation

SonarQubeCloud / [open-metadata-ui] SonarCloud Code Analysis

Refactor this code to not nest functions more than 4 levels deep.

See more on https://sonarcloud.io/project/issues?id=open-metadata-ui&issues=AZ1paimJpOvr1TFDHZQF&open=AZ1paimJpOvr1TFDHZQF&pullRequest=27140
resetUserDetails(true);

return Promise.reject(error);

Check failure on line 534 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View check run for this annotation

SonarQubeCloud / [open-metadata-ui] SonarCloud Code Analysis

Prefer `throw error` over `return Promise.reject(error)`.

See more on https://sonarcloud.io/project/issues?id=open-metadata-ui&issues=AZ1paimJpOvr1TFDHZQG&open=AZ1paimJpOvr1TFDHZQG&pullRequest=27140
});
});
} else {
Expand All @@ -558,7 +558,7 @@
fetchAuthenticationConfig(),
fetchAuthorizerConfig(),
]);
if (!isNil(authConfig)) {

Check warning on line 561 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View check run for this annotation

SonarQubeCloud / [open-metadata-ui] SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=open-metadata-ui&issues=AZ1paimJpOvr1TFDHZQH&open=AZ1paimJpOvr1TFDHZQH&pullRequest=27140
const provider = authConfig.provider;
// show an error toast if provider is null or not supported
if (provider && Object.values(AuthProviderEnum).includes(provider)) {
Expand All @@ -571,7 +571,7 @@
// RDF enabled status is already set from system config in App.tsx
updateAuthInstance(configJson);
const oidcToken = await getOidcToken();
if (!oidcToken) {

Check warning on line 574 in openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/AuthProvider.tsx

View check run for this annotation

SonarQubeCloud / [open-metadata-ui] SonarCloud Code Analysis

Unexpected negated condition.

See more on https://sonarcloud.io/project/issues?id=open-metadata-ui&issues=AZ1paimJpOvr1TFDHZQI&open=AZ1paimJpOvr1TFDHZQI&pullRequest=27140
handleStoreProtectedRedirectPath();
setApplicationLoading(false);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ class TokenService {
this.setRefreshInProgress();

try {
const token = await getOidcToken();
const { isExpired, timeoutExpiry } = extractDetailsFromToken(token);
const oldToken = await getOidcToken();
const { isExpired, timeoutExpiry } = extractDetailsFromToken(oldToken);

// If token is expired or timeoutExpiry is less than 0 then try to silent signIn
if (isExpired || timeoutExpiry <= 0) {
Expand Down Expand Up @@ -160,6 +160,21 @@ class TokenService {
isTokenUpdateInProgress() {
return localStorage.getItem(REFRESH_IN_PROGRESS_KEY) === 'true';
}

private async waitForTokenPersistence(oldToken: string) {
const maxAttempts = 20;
const delayMs = 50;

for (let attempt = 0; attempt < maxAttempts; attempt++) {
await new Promise((resolve) => setTimeout(resolve, delayMs));

const currentToken = await getOidcToken();

if (currentToken && currentToken !== oldToken) {
return;
}
}
}
Comment on lines +164 to +177
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

waitForTokenPersistence is introduced but never called. As a result, the refresh flow still relies on the existing fixed delay and does not actually wait for the refreshed token to be persisted (as described in the PR). Either wire this into refreshToken() (e.g., using the captured oldToken) or remove the unused method. Also consider returning a boolean / throwing on timeout so callers can handle the persistence not completing instead of silently continuing after max attempts.

Copilot uses AI. Check for mistakes.
}

export default TokenService;
Loading