Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 4e68b91

Browse files
authored
Fix OIDC bugs due to amnesiac stores forgetting OIDC issuer & other data (#12166)
* Fix OIDC bugs due to amnesiac stores forgetting OIDC issuer & other data Signed-off-by: Michael Telatynski <[email protected]> * Fix tests Signed-off-by: Michael Telatynski <[email protected]> --------- Signed-off-by: Michael Telatynski <[email protected]>
1 parent 11096b2 commit 4e68b91

File tree

4 files changed

+33
-51
lines changed

4 files changed

+33
-51
lines changed

src/utils/oidc/persistOidcSettings.ts

+11-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const tokenIssuerStorageKey = "mx_oidc_token_issuer";
2121
const idTokenClaimsStorageKey = "mx_oidc_id_token_claims";
2222

2323
/**
24-
* Persists oidc clientId and issuer in session storage
24+
* Persists oidc clientId and issuer in local storage
2525
* Only set after successful authentication
2626
* @param clientId
2727
* @param issuer
@@ -31,39 +31,39 @@ export const persistOidcAuthenticatedSettings = (
3131
issuer: string,
3232
idTokenClaims: IdTokenClaims,
3333
): void => {
34-
sessionStorage.setItem(clientIdStorageKey, clientId);
35-
sessionStorage.setItem(tokenIssuerStorageKey, issuer);
36-
sessionStorage.setItem(idTokenClaimsStorageKey, JSON.stringify(idTokenClaims));
34+
localStorage.setItem(clientIdStorageKey, clientId);
35+
localStorage.setItem(tokenIssuerStorageKey, issuer);
36+
localStorage.setItem(idTokenClaimsStorageKey, JSON.stringify(idTokenClaims));
3737
};
3838

3939
/**
40-
* Retrieve stored oidc issuer from session storage
40+
* Retrieve stored oidc issuer from local storage
4141
* When user has token from OIDC issuer, this will be set
4242
* @returns issuer or undefined
4343
*/
4444
export const getStoredOidcTokenIssuer = (): string | undefined => {
45-
return sessionStorage.getItem(tokenIssuerStorageKey) ?? undefined;
45+
return localStorage.getItem(tokenIssuerStorageKey) ?? undefined;
4646
};
4747

4848
/**
49-
* Retrieves stored oidc client id from session storage
49+
* Retrieves stored oidc client id from local storage
5050
* @returns clientId
51-
* @throws when clientId is not found in session storage
51+
* @throws when clientId is not found in local storage
5252
*/
5353
export const getStoredOidcClientId = (): string => {
54-
const clientId = sessionStorage.getItem(clientIdStorageKey);
54+
const clientId = localStorage.getItem(clientIdStorageKey);
5555
if (!clientId) {
5656
throw new Error("Oidc client id not found in storage");
5757
}
5858
return clientId;
5959
};
6060

6161
/**
62-
* Retrieve stored id token claims from session storage
62+
* Retrieve stored id token claims from local storage
6363
* @returns idtokenclaims or undefined
6464
*/
6565
export const getStoredOidcIdTokenClaims = (): IdTokenClaims | undefined => {
66-
const idTokenClaims = sessionStorage.getItem(idTokenClaimsStorageKey);
66+
const idTokenClaims = localStorage.getItem(idTokenClaimsStorageKey);
6767
if (!idTokenClaims) {
6868
return;
6969
}

test/components/structures/MatrixChat-test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,8 @@ describe("<MatrixChat />", () => {
449449

450450
await flushPromises();
451451

452-
expect(sessionStorage.getItem("mx_oidc_client_id")).toEqual(clientId);
453-
expect(sessionStorage.getItem("mx_oidc_token_issuer")).toEqual(issuer);
452+
expect(localStorage.getItem("mx_oidc_client_id")).toEqual(clientId);
453+
expect(localStorage.getItem("mx_oidc_token_issuer")).toEqual(issuer);
454454
});
455455

456456
it("should set logged in and start MatrixClient", async () => {

test/stores/oidc/OidcClientStore-test.ts

+7-23
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,16 @@ describe("OidcClientStore", () => {
3434
const clientId = "test-client-id";
3535
const metadata = mockOpenIdConfiguration();
3636
const account = metadata.issuer + "account";
37-
const mockSessionStorage: Record<string, string> = {
38-
mx_oidc_client_id: clientId,
39-
mx_oidc_token_issuer: metadata.issuer,
40-
};
4137

4238
const mockClient = getMockClientWithEventEmitter({
4339
waitForClientWellKnown: jest.fn().mockResolvedValue({}),
4440
});
4541

4642
beforeEach(() => {
47-
jest.spyOn(sessionStorage.__proto__, "getItem")
48-
.mockClear()
49-
.mockImplementation((key) => mockSessionStorage[key as string] ?? null);
43+
localStorage.clear();
44+
localStorage.setItem("mx_oidc_client_id", clientId);
45+
localStorage.setItem("mx_oidc_token_issuer", metadata.issuer);
46+
5047
mocked(discoverAndValidateAuthenticationConfig).mockClear().mockResolvedValue({
5148
metadata,
5249
account,
@@ -71,7 +68,7 @@ describe("OidcClientStore", () => {
7168
});
7269

7370
it("should return false when no issuer is in session storage", () => {
74-
jest.spyOn(sessionStorage.__proto__, "getItem").mockReturnValue(null);
71+
localStorage.clear();
7572
const store = new OidcClientStore(mockClient);
7673

7774
expect(store.isUserAuthenticatedWithOidc).toEqual(false);
@@ -98,14 +95,7 @@ describe("OidcClientStore", () => {
9895
});
9996

10097
it("should log and return when no clientId is found in storage", async () => {
101-
const sessionStorageWithoutClientId: Record<string, string | null> = {
102-
...mockSessionStorage,
103-
mx_oidc_client_id: null,
104-
};
105-
jest.spyOn(sessionStorage.__proto__, "getItem").mockImplementation(
106-
(key) => sessionStorageWithoutClientId[key as string] ?? null,
107-
);
108-
98+
localStorage.removeItem("mx_oidc_client_id");
10999
const store = new OidcClientStore(mockClient);
110100

111101
// no oidc client
@@ -209,13 +199,7 @@ describe("OidcClientStore", () => {
209199
it("should throw when oidcClient could not be initialised", async () => {
210200
// make oidcClient initialisation fail
211201
mockClient.waitForClientWellKnown.mockResolvedValue(undefined as any);
212-
const sessionStorageWithoutIssuer: Record<string, string | null> = {
213-
...mockSessionStorage,
214-
mx_oidc_token_issuer: null,
215-
};
216-
jest.spyOn(sessionStorage.__proto__, "getItem").mockImplementation(
217-
(key) => sessionStorageWithoutIssuer[key as string] ?? null,
218-
);
202+
localStorage.removeItem("mx_oidc_token_issuer");
219203

220204
const store = new OidcClientStore(mockClient);
221205

test/utils/oidc/persistOidcSettings-test.ts

+13-15
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ import {
2424
} from "../../../src/utils/oidc/persistOidcSettings";
2525

2626
describe("persist OIDC settings", () => {
27-
beforeEach(() => {
28-
jest.spyOn(sessionStorage.__proto__, "getItem").mockClear().mockReturnValue(null);
27+
jest.spyOn(Storage.prototype, "getItem");
28+
jest.spyOn(Storage.prototype, "setItem");
2929

30-
jest.spyOn(sessionStorage.__proto__, "setItem").mockClear();
30+
beforeEach(() => {
31+
localStorage.clear();
3132
});
3233

3334
const clientId = "test-client-id";
@@ -45,20 +46,17 @@ describe("persist OIDC settings", () => {
4546
describe("persistOidcAuthenticatedSettings", () => {
4647
it("should set clientId and issuer in session storage", () => {
4748
persistOidcAuthenticatedSettings(clientId, issuer, idTokenClaims);
48-
expect(sessionStorage.setItem).toHaveBeenCalledWith("mx_oidc_client_id", clientId);
49-
expect(sessionStorage.setItem).toHaveBeenCalledWith("mx_oidc_token_issuer", issuer);
50-
expect(sessionStorage.setItem).toHaveBeenCalledWith(
51-
"mx_oidc_id_token_claims",
52-
JSON.stringify(idTokenClaims),
53-
);
49+
expect(localStorage.setItem).toHaveBeenCalledWith("mx_oidc_client_id", clientId);
50+
expect(localStorage.setItem).toHaveBeenCalledWith("mx_oidc_token_issuer", issuer);
51+
expect(localStorage.setItem).toHaveBeenCalledWith("mx_oidc_id_token_claims", JSON.stringify(idTokenClaims));
5452
});
5553
});
5654

5755
describe("getStoredOidcTokenIssuer()", () => {
5856
it("should return issuer from session storage", () => {
59-
jest.spyOn(sessionStorage.__proto__, "getItem").mockReturnValue(issuer);
57+
localStorage.setItem("mx_oidc_token_issuer", issuer);
6058
expect(getStoredOidcTokenIssuer()).toEqual(issuer);
61-
expect(sessionStorage.getItem).toHaveBeenCalledWith("mx_oidc_token_issuer");
59+
expect(localStorage.getItem).toHaveBeenCalledWith("mx_oidc_token_issuer");
6260
});
6361

6462
it("should return undefined when no issuer in session storage", () => {
@@ -68,9 +66,9 @@ describe("persist OIDC settings", () => {
6866

6967
describe("getStoredOidcClientId()", () => {
7068
it("should return clientId from session storage", () => {
71-
jest.spyOn(sessionStorage.__proto__, "getItem").mockReturnValue(clientId);
69+
localStorage.setItem("mx_oidc_client_id", clientId);
7270
expect(getStoredOidcClientId()).toEqual(clientId);
73-
expect(sessionStorage.getItem).toHaveBeenCalledWith("mx_oidc_client_id");
71+
expect(localStorage.getItem).toHaveBeenCalledWith("mx_oidc_client_id");
7472
});
7573
it("should throw when no clientId in session storage", () => {
7674
expect(() => getStoredOidcClientId()).toThrow("Oidc client id not found in storage");
@@ -79,9 +77,9 @@ describe("persist OIDC settings", () => {
7977

8078
describe("getStoredOidcIdTokenClaims()", () => {
8179
it("should return issuer from session storage", () => {
82-
jest.spyOn(sessionStorage.__proto__, "getItem").mockReturnValue(JSON.stringify(idTokenClaims));
80+
localStorage.setItem("mx_oidc_id_token_claims", JSON.stringify(idTokenClaims));
8381
expect(getStoredOidcIdTokenClaims()).toEqual(idTokenClaims);
84-
expect(sessionStorage.getItem).toHaveBeenCalledWith("mx_oidc_id_token_claims");
82+
expect(localStorage.getItem).toHaveBeenCalledWith("mx_oidc_id_token_claims");
8583
});
8684

8785
it("should return undefined when no issuer in session storage", () => {

0 commit comments

Comments
 (0)