Skip to content

Commit

Permalink
Clear account idb table on logout (#28996)
Browse files Browse the repository at this point in the history
* Clear account idb table on logout

to remove old deactivated refresh token when logging out

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Simplify code

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix test

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
  • Loading branch information
t3chguy authored Jan 14, 2025
1 parent 5882b00 commit 2559cba
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1049,9 +1049,9 @@ async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void
window.localStorage.clear();

try {
await StorageAccess.idbDelete("account", ACCESS_TOKEN_STORAGE_KEY);
await StorageAccess.idbClear("account");
} catch (e) {
logger.error("idbDelete failed for account:mx_access_token", e);
logger.error("idbClear failed for account", e);
}

// now restore those invites, registration time and previously set device language
Expand Down
70 changes: 38 additions & 32 deletions src/utils/StorageAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ async function idbInit(): Promise<void> {
});
}

async function idbTransaction(
table: string,
mode: IDBTransactionMode,
fn: (objectStore: IDBObjectStore) => IDBRequest<any>,
): Promise<any> {
if (!idb) {
await idbInit();
}
return new Promise((resolve, reject) => {
const txn = idb!.transaction([table], mode);
txn.onerror = reject;

const objectStore = txn.objectStore(table);
const request = fn(objectStore);
request.onerror = reject;
request.onsuccess = (): void => {
resolve(request.result);
};
});
}

/**
* Loads an item from an IndexedDB table within the underlying `matrix-react-sdk` database.
*
Expand All @@ -57,17 +78,7 @@ export async function idbLoad(table: string, key: string | string[]): Promise<an
if (!idb) {
await idbInit();
}
return new Promise((resolve, reject) => {
const txn = idb!.transaction([table], "readonly");
txn.onerror = reject;

const objectStore = txn.objectStore(table);
const request = objectStore.get(key);
request.onerror = reject;
request.onsuccess = (event): void => {
resolve(request.result);
};
});
return idbTransaction(table, "readonly", (objectStore) => objectStore.get(key));
}

/**
Expand All @@ -84,17 +95,7 @@ export async function idbSave(table: string, key: string | string[], data: any):
if (!idb) {
await idbInit();
}
return new Promise((resolve, reject) => {
const txn = idb!.transaction([table], "readwrite");
txn.onerror = reject;

const objectStore = txn.objectStore(table);
const request = objectStore.put(data, key);
request.onerror = reject;
request.onsuccess = (event): void => {
resolve();
};
});
return idbTransaction(table, "readwrite", (objectStore) => objectStore.put(data, key));
}

/**
Expand All @@ -110,15 +111,20 @@ export async function idbDelete(table: string, key: string | string[]): Promise<
if (!idb) {
await idbInit();
}
return new Promise((resolve, reject) => {
const txn = idb!.transaction([table], "readwrite");
txn.onerror = reject;
return idbTransaction(table, "readwrite", (objectStore) => objectStore.delete(key));
}

const objectStore = txn.objectStore(table);
const request = objectStore.delete(key);
request.onerror = reject;
request.onsuccess = (): void => {
resolve();
};
});
/**
* Clears all records from an IndexedDB table within the underlying `matrix-react-sdk` database.
*
* If IndexedDB access is not supported in the environment, an error is thrown.
*
* @param {string} table The name of the object store where the records are stored.
* @returns {Promise<void>} A Promise that resolves when the record(s) have been successfully deleted.
*/
export async function idbClear(table: string): Promise<void> {
if (!idb) {
await idbInit();
}
return idbTransaction(table, "readwrite", (objectStore) => objectStore.clear());
}
7 changes: 6 additions & 1 deletion test/unit-tests/Lifecycle-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ describe("Lifecycle", () => {
const table = mockStore[tableKey];
delete table?.[key as string];
});
jest.spyOn(StorageAccess, "idbClear")
.mockClear()
.mockImplementation(async (tableKey: string) => {
mockStore[tableKey] = {};
});
};

const homeserverUrl = "https://server.org";
Expand Down Expand Up @@ -613,7 +618,7 @@ describe("Lifecycle", () => {
it("should clear stores", async () => {
await setLoggedIn(credentials);

expect(StorageAccess.idbDelete).toHaveBeenCalledWith("account", "mx_access_token");
expect(StorageAccess.idbClear).toHaveBeenCalledWith("account");
expect(sessionStorage.clear).toHaveBeenCalled();
expect(mockClient.clearStores).toHaveBeenCalled();
});
Expand Down

0 comments on commit 2559cba

Please sign in to comment.