Skip to content

Commit 12561ae

Browse files
authored
feat(admin-ui): sessions not revoked after password/role/ user activation status change (#2592)
* feat: sessions not revoked after password/role/ user activation status change Signed-off-by: duttarnab <arnab.bdutta@gmail.com> * feat: address code-rabbit comments Signed-off-by: duttarnab <arnab.bdutta@gmail.com> --------- Signed-off-by: duttarnab <arnab.bdutta@gmail.com>
1 parent 5d4f4c3 commit 12561ae

31 files changed

+259
-163
lines changed

admin-ui/api-client.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Axios, { AxiosRequestConfig, AxiosHeaders } from 'axios'
22
import store from './app/redux/store'
3+
import { fetchApiTokenWithDefaultScopes, deleteAdminUiSession } from './app/redux/api/backend-api'
34

45
const baseUrl =
56
(typeof window !== 'undefined' && (window as any).configApiBaseUrl) ||
@@ -33,6 +34,23 @@ AXIOS_INSTANCE.interceptors.request.use((config) => {
3334
return config
3435
})
3536

37+
AXIOS_INSTANCE.interceptors.response.use(
38+
(response) => response,
39+
async (error) => {
40+
if (error.response?.status === 403) {
41+
try {
42+
const response = await fetchApiTokenWithDefaultScopes()
43+
await deleteAdminUiSession(response?.access_token)
44+
window.location.href = '/admin/logout'
45+
} catch (e) {
46+
console.error('Failed to cleanup session on 403:', e)
47+
}
48+
}
49+
50+
return Promise.reject(error)
51+
},
52+
)
53+
3654
// React Query compatible instance
3755
export const customInstance = <T>(
3856
config: AxiosRequestConfig,

admin-ui/app/helpers/navigation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ const ROUTES = {
154154
// ========== Core app pages ==========
155155

156156
PROFILE: '/profile',
157-
LOGOUT: '/logout',
157+
LOGOUT: '/admin/logout',
158158
ERROR_404: '/error-404',
159159

160160
// ========== Wildcard routes ==========

admin-ui/app/redux/api/backend-api.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export const fetchApiAccessToken = (jwt: any, permissionTag: any) => {
8484

8585
export const fetchApiTokenWithDefaultScopes = () => {
8686
return axios
87-
.post('/app/admin-ui/oauth2/api-protection-token', {})
87+
.post('/app/admin-ui/oauth2/api-protection-token', {}, { withCredentials: false })
8888
.then((response) => response.data)
8989
.catch((error) => {
9090
console.error('Problems getting API access token in order to process api calls.', error)
@@ -118,9 +118,12 @@ export const createAdminUiSession = (ujwt: string, apiProtectionToken: string) =
118118
}
119119

120120
// Delete Admin UI session (logout)
121-
export const deleteAdminUiSession = () => {
121+
export const deleteAdminUiSession = (token?: string) => {
122+
const config = token
123+
? { headers: { Authorization: `Bearer ${token}` } }
124+
: { withCredentials: true }
122125
return axios
123-
.delete('/app/admin-ui/oauth2/session', { withCredentials: true })
126+
.delete('/app/admin-ui/oauth2/session', config)
124127
.then((response) => response.data)
125128
.catch((error) => {
126129
console.error('Problems deleting Admin UI session.', error)

admin-ui/app/redux/sagas/AttributesSaga.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-nocheck
22
import { call, all, put, fork, takeLatest, select } from 'redux-saga/effects'
3-
import { isFourZeroOneError, addAdditionalData } from 'Utils/TokenController'
3+
import { isFourZeroThreeError, addAdditionalData } from 'Utils/TokenController'
44
import { getAttributesResponseRoot, toggleInitAttributeLoader } from '../features/attributesSlice'
55
import { postUserAction } from 'Redux/api/backend-api'
66
import { FETCH } from '../../audit/UserActionType'
@@ -31,7 +31,7 @@ export function* getAttributesRoot({ payload }) {
3131
yield call(postUserAction, audit)
3232
} catch (e) {
3333
yield put(getAttributesResponseRoot({ data: [] }))
34-
if (isFourZeroOneError(e)) {
34+
if (isFourZeroThreeError(e)) {
3535
yield* redirectToLogout()
3636
return
3737
}

admin-ui/app/redux/sagas/AuthSaga.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
createAdminUiSessionResponse,
2424
deleteAdminUiSessionResponse,
2525
} from 'Redux/features/authSlice'
26-
import { isFourZeroOneError } from 'Utils/TokenController'
26+
import { isFourZeroThreeError } from 'Utils/TokenController'
2727
import { redirectToLogout } from 'Redux/sagas/SagaUtils'
2828

2929
function* getApiTokenWithDefaultScopes() {
@@ -69,7 +69,7 @@ function* getOAuth2ConfigWorker({ payload }) {
6969
}
7070
} catch (error) {
7171
console.error('Problems getting OAuth2 configuration.', error?.response?.data || error)
72-
if (isFourZeroOneError(error)) {
72+
if (isFourZeroThreeError(error)) {
7373
yield* redirectToLogout()
7474
return
7575
}
@@ -93,7 +93,7 @@ export function* putConfigWorker({ payload }) {
9393
}
9494
} catch (error) {
9595
yield put(updateToast(true, 'error'))
96-
if (isFourZeroOneError(error)) {
96+
if (isFourZeroThreeError(error)) {
9797
yield* redirectToLogout()
9898
return
9999
}
@@ -136,8 +136,9 @@ function* getAPIAccessTokenWorker(jwt) {
136136
statusCode: error?.response?.status,
137137
}),
138138
)
139-
if (isFourZeroOneError(error)) {
139+
if (isFourZeroThreeError(error)) {
140140
yield* redirectToLogout()
141+
return
141142
}
142143
}
143144
}
@@ -163,7 +164,7 @@ function* createAdminUiSessionWorker({ payload }) {
163164
const errorMessage =
164165
error?.response?.data?.message || error?.response?.data?.responseMessage || error?.message
165166
console.error('Problems creating Admin UI session.', error?.response?.data || error)
166-
if (isFourZeroOneError(error)) {
167+
if (isFourZeroThreeError(error)) {
167168
yield* redirectToLogout()
168169
return
169170
}

admin-ui/app/redux/sagas/HealthSaga.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// @ts-nocheck
22
import { call, all, put, fork, takeLatest, select } from 'redux-saga/effects'
3-
import { isFourZeroOneError, addAdditionalData } from 'Utils/TokenController'
3+
import { isFourZeroThreeError, addAdditionalData } from 'Utils/TokenController'
44
import { getHealthStatusResponse, getHealthServerStatusResponse } from '../features/healthSlice'
55
import { postUserAction } from '../api/backend-api'
66
import HealthApi from '../api/HealthApi'
77
import { getClient } from '../api/base'
8-
import { initAudit } from '../sagas/SagaUtils'
98
import HealthCheckApi from '../api/HealthCheckApi'
9+
import { initAudit, redirectToLogout } from '../sagas/SagaUtils'
1010
const JansConfigApi = require('jans_config_api')
1111

1212
function* newFunction() {
@@ -32,9 +32,10 @@ export function* getHealthStatus({ payload }) {
3232
yield call(postUserAction, audit)
3333
} catch (e) {
3434
yield put(getHealthStatusResponse(null))
35-
if (isFourZeroOneError(e)) {
35+
if (isFourZeroThreeError(e)) {
3636
// Session expired - redirect to login
37-
window.location.href = '/logout'
37+
yield* redirectToLogout()
38+
return
3839
}
3940
}
4041
}

admin-ui/app/redux/sagas/InitSaga.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-nocheck
22
import { call, all, put, fork, takeLatest, select } from 'redux-saga/effects'
3-
import { isFourZeroOneError, addAdditionalData } from 'Utils/TokenController'
3+
import { isFourZeroThreeError, addAdditionalData } from 'Utils/TokenController'
44
import {
55
getAttributesResponse,
66
getScriptsResponse,
@@ -47,7 +47,7 @@ export function* getScripts({ payload }) {
4747
yield call(postUserAction, audit)
4848
} catch (e) {
4949
yield put(getScriptsResponse(null))
50-
if (isFourZeroOneError(e)) {
50+
if (isFourZeroThreeError(e)) {
5151
yield* redirectToLogout()
5252
return
5353
}
@@ -65,7 +65,7 @@ export function* getClients({ payload }) {
6565
yield call(postUserAction, audit)
6666
} catch (e) {
6767
yield put(getClientsResponse(null))
68-
if (isFourZeroOneError(e)) {
68+
if (isFourZeroThreeError(e)) {
6969
yield* redirectToLogout()
7070
return
7171
}
@@ -82,7 +82,7 @@ export function* getScopes({ payload }) {
8282
yield call(postUserAction, audit)
8383
} catch (e) {
8484
yield put(getScopesResponse(null))
85-
if (isFourZeroOneError(e)) {
85+
if (isFourZeroThreeError(e)) {
8686
yield* redirectToLogout()
8787
return
8888
}
@@ -99,7 +99,7 @@ export function* getAttributes({ payload }) {
9999
yield call(postUserAction, audit)
100100
} catch (e) {
101101
yield put(getAttributesResponse(null))
102-
if (isFourZeroOneError(e)) {
102+
if (isFourZeroThreeError(e)) {
103103
yield* redirectToLogout()
104104
return
105105
}

admin-ui/app/redux/sagas/LicenseDetailsSaga.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import {
88
} from '../features/licenseDetailsSlice'
99
import { getClient } from 'Redux/api/base'
1010
import LicenseDetailsApi from '../api/LicenseDetailsApi'
11-
import { initAudit } from 'Redux/sagas/SagaUtils'
11+
import { initAudit, redirectToLogout } from 'Redux/sagas/SagaUtils'
1212
import { postUserAction } from 'Redux/api/backend-api'
13-
import { addAdditionalData, isFourZeroOneError } from 'Utils/TokenController'
13+
import { addAdditionalData, isFourZeroThreeError } from 'Utils/TokenController'
1414
import { API_LICENSE } from '../../audit/Resources'
1515
import { DELETION } from '@/audit/UserActionType'
1616
const JansConfigApi = require('jans_config_api')
@@ -42,9 +42,10 @@ export function* resetLicenseConfigWorker(action: ResetLicenseAction) {
4242
yield put(setLicenseResetFailure())
4343
}
4444
} catch (error) {
45-
if (isFourZeroOneError(error)) {
45+
if (isFourZeroThreeError(error)) {
4646
// Session expired - redirect to login
47-
window.location.href = '/logout'
47+
yield* redirectToLogout()
48+
return
4849
}
4950
}
5051
}
@@ -60,9 +61,10 @@ export function* getLicenseDetailsWorker() {
6061
} catch (e) {
6162
console.log('error in getting license details: ', e)
6263
yield put(getLicenseDetailsResponse(null))
63-
if (isFourZeroOneError(e)) {
64+
if (isFourZeroThreeError(e)) {
6465
// Session expired - redirect to login
65-
window.location.href = '/logout'
66+
yield* redirectToLogout()
67+
return
6668
}
6769
}
6870
}
@@ -77,9 +79,10 @@ export function* updateLicenseDetailsWorker({ payload }) {
7779
yield call(postUserAction, audit)
7880
} catch (e) {
7981
yield put(updateLicenseDetailsResponse(null))
80-
if (isFourZeroOneError(e)) {
82+
if (isFourZeroThreeError(e)) {
8183
// Session expired - redirect to login
82-
window.location.href = '/logout'
84+
yield* redirectToLogout()
85+
return
8386
}
8487
}
8588
}

admin-ui/app/redux/sagas/LockSaga.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// @ts-nocheck
22
import { call, all, put, fork, select, takeLatest } from 'redux-saga/effects'
3-
import { isFourZeroOneError } from 'Utils/TokenController'
3+
import { isFourZeroThreeError } from 'Utils/TokenController'
44

55
import { getClient } from '../api/base'
6-
import { initAudit } from '../sagas/SagaUtils'
6+
import { initAudit, redirectToLogout } from '../sagas/SagaUtils'
77
import LockApi from '../api/LockApi'
88
import { getLockStatusResponse } from '../features/lockSlice'
99
const JansConfigApi = require('jans_config_api')
@@ -22,9 +22,10 @@ export function* getLockMau({ payload }) {
2222
yield put(getLockStatusResponse({ data }))
2323
} catch (e) {
2424
yield put(getLockStatusResponse(null))
25-
if (isFourZeroOneError(e)) {
25+
if (isFourZeroThreeError(e)) {
2626
// Session expired - redirect to login
27-
window.location.href = '/logout'
27+
yield* redirectToLogout()
28+
return
2829
}
2930
}
3031
}

admin-ui/app/redux/sagas/MauSaga.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-nocheck
22
import { call, all, put, fork, takeLatest, select } from 'redux-saga/effects'
3-
import { isFourZeroOneError, addAdditionalData } from 'Utils/TokenController'
3+
import { isFourZeroThreeError, addAdditionalData } from 'Utils/TokenController'
44
import { getMauResponse } from 'Plugins/admin/redux/features/mauSlice'
55
import { postUserAction } from '../api/backend-api'
66
import MauApi from '../api/MauApi'
@@ -26,7 +26,7 @@ export function* getMau({ payload }) {
2626
return data
2727
} catch (e) {
2828
yield put(getMauResponse(null))
29-
if (isFourZeroOneError(e)) {
29+
if (isFourZeroThreeError(e)) {
3030
yield* redirectToLogout()
3131
return
3232
}

0 commit comments

Comments
 (0)