diff --git a/app/kubernetes/registries/kube-registry-access-view/kube-registry-access-view.html b/app/kubernetes/registries/kube-registry-access-view/kube-registry-access-view.html
index df999b9db..ee8474a2a 100644
--- a/app/kubernetes/registries/kube-registry-access-view/kube-registry-access-view.html
+++ b/app/kubernetes/registries/kube-registry-access-view/kube-registry-access-view.html
@@ -1,4 +1,4 @@
-
+
diff --git a/app/kubernetes/services/namespaceService.js b/app/kubernetes/services/namespaceService.js
index c888b5b88..a5ff56ca4 100644
--- a/app/kubernetes/services/namespaceService.js
+++ b/app/kubernetes/services/namespaceService.js
@@ -4,13 +4,11 @@ import { KubernetesCommonParams } from 'Kubernetes/models/common/params';
import KubernetesNamespaceConverter from 'Kubernetes/converters/namespace';
import { updateNamespaces } from 'Kubernetes/store/namespace';
import $allSettled from 'Portainer/services/allSettled';
-import { getSelfSubjectAccessReview } from '@/react/kubernetes/namespaces/getSelfSubjectAccessReview';
class KubernetesNamespaceService {
/* @ngInject */
- constructor($async, KubernetesNamespaces, LocalStorage, $state) {
+ constructor($async, KubernetesNamespaces, LocalStorage) {
this.$async = $async;
- this.$state = $state;
this.KubernetesNamespaces = KubernetesNamespaces;
this.LocalStorage = LocalStorage;
@@ -68,10 +66,8 @@ class KubernetesNamespaceService {
try {
// get the list of all namespaces (RBAC allows users to see the list of namespaces)
const data = await this.KubernetesNamespaces().get().$promise;
- // get the status of each namespace with accessReviews (to avoid failed forbidden responses, which aren't cached)
- const accessReviews = await Promise.all(data.items.map((namespace) => getSelfSubjectAccessReview(this.$state.params.endpointId, namespace.metadata.name)));
- const allowedNamespaceNames = accessReviews.filter((ar) => ar.status.allowed).map((ar) => ar.spec.resourceAttributes.namespace);
- const promises = allowedNamespaceNames.map((name) => this.KubernetesNamespaces().status({ id: name }).$promise);
+ // get the status of each namespace (RBAC will give permission denied for status of unauthorised namespaces)
+ const promises = data.items.map((item) => this.KubernetesNamespaces().status({ id: item.metadata.name }).$promise);
const namespaces = await $allSettled(promises);
// only return namespaces if the user has access to namespaces
const allNamespaces = namespaces.fulfilled.map((item) => {
diff --git a/app/kubernetes/views/resource-pools/resourcePoolsController.js b/app/kubernetes/views/resource-pools/resourcePoolsController.js
index 7899375fd..c9353812c 100644
--- a/app/kubernetes/views/resource-pools/resourcePoolsController.js
+++ b/app/kubernetes/views/resource-pools/resourcePoolsController.js
@@ -75,7 +75,7 @@ class KubernetesResourcePoolsController {
async getResourcePoolsAsync() {
try {
- this.resourcePools = await this.KubernetesResourcePoolService.get();
+ this.resourcePools = await this.KubernetesResourcePoolService.get('', { getQuota: true });
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to retreive namespaces');
}
diff --git a/app/portainer/components/theme/theme-settings.controller.js b/app/portainer/components/theme/theme-settings.controller.js
index 3b847ced6..c0d5b9922 100644
--- a/app/portainer/components/theme/theme-settings.controller.js
+++ b/app/portainer/components/theme/theme-settings.controller.js
@@ -1,5 +1,5 @@
import { notifyError, notifySuccess } from '@/portainer/services/notifications';
-import { userQueryKeys } from '@/portainer/users/queries/queryKeys';
+import { queryKeys } from '@/portainer/users/queries/queryKeys';
import { queryClient } from '@/react-tools/react-query';
import { options } from '@/react/portainer/account/AccountView/theme-options';
@@ -32,7 +32,7 @@ export default class ThemeSettingsController {
try {
if (!this.state.isDemo) {
await this.UserService.updateUserTheme(this.state.userId, theme);
- await queryClient.invalidateQueries(userQueryKeys.user(this.state.userId));
+ await queryClient.invalidateQueries(queryKeys.user(this.state.userId));
}
notifySuccess('Success', 'User theme settings successfully updated');
diff --git a/app/portainer/models/user.js b/app/portainer/models/user.js
index a8979a059..676d4f37a 100644
--- a/app/portainer/models/user.js
+++ b/app/portainer/models/user.js
@@ -12,7 +12,6 @@ export function UserViewModel(data) {
}
this.AuthenticationMethod = data.AuthenticationMethod;
this.Checked = false;
- this.UseCache = data.UseCache;
}
export function UserTokenModel(data) {
diff --git a/app/portainer/react/components/account.ts b/app/portainer/react/components/account.ts
deleted file mode 100644
index cb75d29c4..000000000
--- a/app/portainer/react/components/account.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import angular from 'angular';
-
-import { r2a } from '@/react-tools/react2angular';
-import { withCurrentUser } from '@/react-tools/withCurrentUser';
-import { withUIRouter } from '@/react-tools/withUIRouter';
-import { withReactQuery } from '@/react-tools/withReactQuery';
-import { ApplicationSettingsWidget } from '@/react/portainer/account/AccountView/ApplicationSettings';
-
-export const accountModule = angular
- .module('portainer.app.react.components.account', [])
- .component(
- 'applicationSettingsWidget',
- r2a(
- withUIRouter(withReactQuery(withCurrentUser(ApplicationSettingsWidget))),
- []
- )
- ).name;
diff --git a/app/portainer/react/components/index.ts b/app/portainer/react/components/index.ts
index 2730fc890..b80f456c4 100644
--- a/app/portainer/react/components/index.ts
+++ b/app/portainer/react/components/index.ts
@@ -45,7 +45,6 @@ import { accessControlModule } from './access-control';
import { environmentsModule } from './environments';
import { envListModule } from './environments-list-view-components';
import { registriesModule } from './registries';
-import { accountModule } from './account';
export const ngModule = angular
.module('portainer.app.react.components', [
@@ -56,7 +55,6 @@ export const ngModule = angular
gitFormModule,
registriesModule,
settingsModule,
- accountModule,
])
.component(
'tagSelector',
diff --git a/app/portainer/services/axios.ts b/app/portainer/services/axios.ts
index 62f6f0022..d2648ade2 100644
--- a/app/portainer/services/axios.ts
+++ b/app/portainer/services/axios.ts
@@ -1,5 +1,4 @@
import axiosOrigin, { AxiosError, AxiosRequestConfig } from 'axios';
-import { setupCache } from 'axios-cache-adapter';
import { loadProgressBar } from 'axios-progress-bar';
import 'axios-progress-bar/dist/nprogress.css';
@@ -7,48 +6,12 @@ import PortainerError from '@/portainer/error';
import { get as localStorageGet } from '@/react/hooks/useLocalStorage';
import {
- CACHE_DURATION,
- dispatchCacheRefreshEventIfNeeded,
portainerAgentManagerOperation,
portainerAgentTargetHeader,
} from './http-request.helper';
-export const cache = setupCache({
- maxAge: CACHE_DURATION,
- debug: false, // set to true to print cache hits/misses
- exclude: {
- query: false, // include urls with query params
- methods: ['put', 'patch', 'delete'],
- filter: (req: AxiosRequestConfig) => {
- // exclude caching get requests unless the path contains 'kubernetes'
- if (!req.url?.includes('kubernetes') && req.method === 'get') {
- return true;
- }
-
- // exclude caching post requests unless the path contains 'selfsubjectaccessreview'
- if (
- !req.url?.includes('selfsubjectaccessreview') &&
- req.method === 'post'
- ) {
- return true;
- }
- return false;
- },
- },
- // ask to clear cache on mutation
- invalidate: async (_, req) => {
- dispatchCacheRefreshEventIfNeeded(req);
- },
-});
-
-// by default don't use the cache adapter
const axios = axiosOrigin.create({ baseURL: 'api' });
-// when entering a kubernetes environment, or updating user settings, update the cache adapter
-export function updateAxiosAdapter(useCache: boolean) {
- axios.defaults.adapter = useCache ? cache.adapter : undefined;
-}
-
loadProgressBar(undefined, axios);
export default axios;
diff --git a/app/portainer/services/http-request.helper.ts b/app/portainer/services/http-request.helper.ts
index 19e244ccf..3c0c7552a 100644
--- a/app/portainer/services/http-request.helper.ts
+++ b/app/portainer/services/http-request.helper.ts
@@ -1,31 +1,3 @@
-import { AxiosRequestConfig } from 'axios';
-
-export const CACHE_DURATION = 5 * 60 * 1000; // 5m in ms
-// event emitted when cache need to be refreshed
-// used to sync $http + axios cache clear
-export const CACHE_REFRESH_EVENT = '__cache__refresh__event__';
-
-// utility function to dispatch catch refresh event
-export function dispatchCacheRefreshEvent() {
- dispatchEvent(new CustomEvent(CACHE_REFRESH_EVENT, {}));
-}
-
-// perform checks on config.method and config.url
-// to dispatch event in only specific scenarios
-export function dispatchCacheRefreshEventIfNeeded(req: AxiosRequestConfig) {
- if (
- req.method &&
- ['post', 'patch', 'put', 'delete'].includes(req.method.toLowerCase()) &&
- // don't clear cache when we try to check for namespaces accesses
- // otherwise we will clear it on every page
- req.url &&
- !req.url.includes('selfsubjectaccessreviews') &&
- req.url.includes('kubernetes')
- ) {
- dispatchCacheRefreshEvent();
- }
-}
-
interface Headers {
agentTargetQueue: string[];
agentManagerOperation: boolean;
diff --git a/app/portainer/users/queries/queryKeys.ts b/app/portainer/users/queries/queryKeys.ts
index ec14e11c7..c6f335d98 100644
--- a/app/portainer/users/queries/queryKeys.ts
+++ b/app/portainer/users/queries/queryKeys.ts
@@ -1,6 +1,6 @@
import { UserId } from '../types';
-export const userQueryKeys = {
+export const queryKeys = {
base: () => ['users'] as const,
- user: (id: UserId) => [...userQueryKeys.base(), id] as const,
+ user: (id: UserId) => [...queryKeys.base(), id] as const,
};
diff --git a/app/portainer/users/queries/useUser.ts b/app/portainer/users/queries/useUser.ts
index c43a7310e..8986270a6 100644
--- a/app/portainer/users/queries/useUser.ts
+++ b/app/portainer/users/queries/useUser.ts
@@ -6,13 +6,13 @@ import { withError } from '@/react-tools/react-query';
import { buildUrl } from '../user.service';
import { User, UserId } from '../types';
-import { userQueryKeys } from './queryKeys';
+import { queryKeys } from './queryKeys';
export function useUser(
id: UserId,
{ staleTime }: { staleTime?: number } = {}
) {
- return useQuery(userQueryKeys.user(id), () => getUser(id), {
+ return useQuery(queryKeys.user(id), () => getUser(id), {
...withError('Unable to retrieve user details'),
staleTime,
});
diff --git a/app/portainer/users/types.ts b/app/portainer/users/types.ts
index b505bbcc0..93bbdb9e8 100644
--- a/app/portainer/users/types.ts
+++ b/app/portainer/users/types.ts
@@ -20,7 +20,6 @@ export type User = {
EndpointAuthorizations: {
[endpointId: EnvironmentId]: AuthorizationMap;
};
- UseCache: boolean;
ThemeSettings: {
color: 'dark' | 'light' | 'highcontrast' | 'auto';
};
diff --git a/app/portainer/views/account/account.html b/app/portainer/views/account/account.html
index 589c34ad9..e19374908 100644
--- a/app/portainer/views/account/account.html
+++ b/app/portainer/views/account/account.html
@@ -1,4 +1,4 @@
-
+
@@ -16,16 +16,16 @@