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
14 changes: 7 additions & 7 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,13 @@ export function Layout() {
const role = getUserRole();
const state = store.getState();
const privilegedRoles = state.config.settings.privilegedRoles;

dispatch(
setAuthorisation({
role,
isAdminUser: privilegedRoles.includes(role),
})
);
if (typeof role === 'string')
dispatch(
setAuthorisation({
role,
isAdminUser: privilegedRoles.includes(role),
})
);
});
}, [dispatch]);
// We need to call forceUpdate if SciGateway tells us to rerender
Expand Down
17 changes: 15 additions & 2 deletions src/parseTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,25 @@ export const readSciGatewayToken = (): SciGatewayToken => {
return null;
};

export const getUserRole = (): string => {
/**
* Retrieves the user's role from the JWT stored in localStorage.
*
* If the user is authenticated, the JWT should contain a `role` claim.
* In that case, the function returns the role value. If the token is
* missing or cannot be parsed, the function returns `undefined`.
*
* If a token exists but the `role` field is not present in the decoded
* payload, the function returns the fallback role `"default"`.
*
* @returns {string | undefined} The user's role, "default" if no role
* exists in the token, or `undefined` if the user is not authenticated.
*/
export const getUserRole = (): string | undefined => {
const token = localStorage.getItem(MicroFrontendToken);
if (token) {
const parsedToken = JSON.parse(parseJwt(token));
return parsedToken.role ?? 'default';
}

return 'default';
return undefined;
};
16 changes: 8 additions & 8 deletions src/state/middleware/authorisationMiddleware.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { setAuthorisation, setIsAdminMode } from '../slices/authorisationSlice';
import { RootState, StorageRegistry } from '../store';

export const createAuthListenerMiddleware = (
getUserRoleFn: () => string,
getUserRoleFn: () => string | undefined,
storageRegistryDict: StorageRegistry
) => {
const middleware = createListenerMiddleware();
Expand All @@ -16,13 +16,13 @@ export const createAuthListenerMiddleware = (
const privilegedRoles = state.config.settings.privilegedRoles;

const role = getUserRoleFn();

listenerApi.dispatch(
setAuthorisation({
role,
isAdminUser: privilegedRoles.includes(role),
})
);
if (typeof role === 'string')
listenerApi.dispatch(
setAuthorisation({
role,
isAdminUser: privilegedRoles.includes(role),
})
);
},
});

Expand Down
8 changes: 6 additions & 2 deletions src/state/slices/authorisationSlice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ export const authSlice = createSlice({
state.isAdminUser = action.payload.isAdminUser;

if (!state.isAdminUser) {
state.isAdminMode = false;
state.isAdminMode = initialState.isAdminMode;
} else {
state.isAdminMode = state.isAdminMode ?? initialState.isAdminMode;
}
},
setIsAdminMode(state, action: PayloadAction<boolean>) {
state.isAdminMode = state.isAdminUser ? action.payload : false;
state.isAdminMode = state.isAdminUser
? action.payload
: initialState.isAdminMode;
},
},
});
Expand Down
10 changes: 5 additions & 5 deletions src/state/store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const rootReducer = combineReducers({

export function configureAppStore(
preloadedState?: Partial<RootState>,
getUserRoleFn: () => string = getUserRole,
getUserRoleFn: () => string | undefined = getUserRole,
storageRegistryDict: StorageRegistry = storageRegistry
) {
const authListenerMiddleware = createAuthListenerMiddleware(
Expand All @@ -44,16 +44,16 @@ export function configureAppStore(
const mergedPreloaded: Partial<RootState> = {
...preloadedState,
authorisation: {
...(preloadedState?.authorisation ?? {}),
...(hydratedIsAdminMode !== undefined
? { isAdminMode: hydratedIsAdminMode }
: {}),
: initialAuthSlice),
...(preloadedState?.authorisation ?? {}),
} as typeof initialAuthSlice,
criticality: {
...(preloadedState?.criticality ?? {}),
...((hydratedIsCriticalMode !== undefined
? { isCriticalMode: hydratedIsCriticalMode }
: {}) as typeof initialCriticalState),
: initialCriticalState) as typeof initialCriticalState),
...(preloadedState?.criticality ?? {}),
},
};

Expand Down