Skip to content

Commit c9e13ee

Browse files
committed
✨(frontend) store and retrieve user token in sessionStorage
Ensure the user's token is saved to `sessionStorage` during login and retrieved as needed. Improves token handling for authenticated API calls.
1 parent aa57b18 commit c9e13ee

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

src/frontend/js/api/auth/keycloak.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ const mockKeycloakInit = jest.fn().mockResolvedValue(true);
55
const mockKeycloakLogout = jest.fn().mockResolvedValue(undefined);
66
const mockKeycloakLogin = jest.fn().mockResolvedValue(undefined);
77
const mockKeycloakLoadUserProfile = jest.fn();
8+
const mockIdToken = 'mock-id-token-12345';
89

910
jest.mock('keycloak-js', () => {
1011
return jest.fn().mockImplementation(() => ({
1112
init: mockKeycloakInit,
1213
logout: mockKeycloakLogout,
1314
login: mockKeycloakLogin,
1415
loadUserProfile: mockKeycloakLoadUserProfile,
16+
idToken: 'mock-id-token-12345',
1517
}));
1618
});
1719

@@ -50,6 +52,7 @@ describe('Keycloak API', () => {
5052

5153
beforeEach(() => {
5254
jest.clearAllMocks();
55+
sessionStorage.clear();
5356
keycloakApi = API(authConfig);
5457
});
5558

@@ -71,7 +74,23 @@ describe('Keycloak API', () => {
7174
expect(response).toEqual({
7275
username: 'John Doe',
7376
email: 'johndoe@example.com',
77+
access_token: mockIdToken,
7478
});
79+
expect(sessionStorage.getItem('RICHIE_USER_TOKEN')).toEqual(mockIdToken);
80+
});
81+
});
82+
83+
describe('user.accessToken', () => {
84+
it('returns null when no token is stored', () => {
85+
sessionStorage.removeItem('RICHIE_USER_TOKEN');
86+
const token = keycloakApi.user.accessToken();
87+
expect(token).toBeNull();
88+
});
89+
90+
it('returns the token from sessionStorage when available', () => {
91+
sessionStorage.setItem('RICHIE_USER_TOKEN', 'stored-token');
92+
const token = keycloakApi.user.accessToken();
93+
expect(token).toEqual('stored-token');
7594
});
7695
});
7796

src/frontend/js/api/auth/keycloak.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { AuthenticationBackend } from 'types/commonDataProps';
33
import { APIAuthentication } from 'types/api';
44
import { location } from 'utils/indirection/window';
55
import { handle } from 'utils/errors/handle';
6+
import { RICHIE_USER_TOKEN } from '../../settings';
67

78
const API = (APIConf: AuthenticationBackend): { user: APIAuthentication } => {
89
const keycloak = new Keycloak({
@@ -22,13 +23,18 @@ const API = (APIConf: AuthenticationBackend): { user: APIAuthentication } => {
2223

2324
return {
2425
user: {
26+
accessToken: () => {
27+
return sessionStorage.getItem(RICHIE_USER_TOKEN);
28+
},
2529
me: async () => {
2630
return keycloak
2731
.loadUserProfile()
2832
.then((userProfile) => {
33+
sessionStorage.setItem(RICHIE_USER_TOKEN, keycloak.idToken!);
2934
return {
3035
username: `${userProfile.firstName} ${userProfile.lastName}`,
3136
email: userProfile.email,
37+
access_token: keycloak.idToken,
3238
};
3339
})
3440
.catch((error) => {

0 commit comments

Comments
 (0)