Skip to content

Commit f8f605a

Browse files
committed
chore: clean up tests
1 parent bd82a91 commit f8f605a

File tree

3 files changed

+146
-1
lines changed

3 files changed

+146
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { storageSettings } from "../index.js";
2+
import { SessionBase, StorageKeys, type SessionManager } from "../types.js";
3+
import { splitString } from "../utils.js";
4+
5+
/**
6+
* Provides a memory based session manager implementation for the browser.
7+
* @class MemoryStorage
8+
*/
9+
export class MemoryStorage<V extends string = StorageKeys>
10+
extends SessionBase<V>
11+
implements SessionManager<V>
12+
{
13+
private memCache: Record<string, unknown> = {};
14+
15+
/**
16+
* Clears all items from session store.
17+
* @returns {void}
18+
.04
19+
*/
20+
async destroySession(): Promise<void> {
21+
this.memCache = {};
22+
}
23+
24+
/**
25+
* Sets the provided key-value store to the memory cache.
26+
* @param {string} itemKey
27+
* @param {unknown} itemValue
28+
* @returns {void}
29+
*/
30+
async setSessionItem(
31+
itemKey: V | StorageKeys,
32+
itemValue: unknown,
33+
): Promise<void> {
34+
// clear items first
35+
await this.removeSessionItem(itemKey);
36+
37+
if (typeof itemValue === "string") {
38+
splitString(itemValue, storageSettings.maxLength).forEach(
39+
(splitValue, index) => {
40+
this.memCache[`${storageSettings.keyPrefix}${itemKey}${index}`] =
41+
splitValue;
42+
},
43+
);
44+
return;
45+
}
46+
this.memCache[`${storageSettings.keyPrefix}${String(itemKey)}0`] =
47+
itemValue;
48+
}
49+
50+
/**
51+
* Gets the item for the provided key from the memory cache.
52+
* @param {string} itemKey
53+
* @returns {unknown | null}
54+
*/
55+
async getSessionItem(itemKey: V | StorageKeys): Promise<unknown | null> {
56+
if (
57+
this.memCache[`${storageSettings.keyPrefix}${String(itemKey)}0`] ===
58+
undefined
59+
) {
60+
return null;
61+
}
62+
63+
let itemValue = "";
64+
let index = 0;
65+
let key = `${storageSettings.keyPrefix}${String(itemKey)}${index}`;
66+
while (this.memCache[key] !== undefined) {
67+
itemValue += this.memCache[key];
68+
index++;
69+
key = `${storageSettings.keyPrefix}${String(itemKey)}${index}`;
70+
}
71+
72+
return itemValue;
73+
}
74+
75+
/**
76+
* Removes the item for the provided key from the memory cache.
77+
* @param {string} itemKey
78+
* @returns {void}
79+
*/
80+
async removeSessionItem(itemKey: V | StorageKeys): Promise<void> {
81+
// Remove all items with the key prefix
82+
for (const key in this.memCache) {
83+
if (key.startsWith(`${storageSettings.keyPrefix}${String(itemKey)}`)) {
84+
delete this.memCache[key];
85+
}
86+
}
87+
}
88+
}

lib/utils/exhangeAuthCode._ts

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { getActiveStorage, StorageKeys } from "../main";
2+
3+
export const exchangeAuthCode = async ({
4+
domain,
5+
clientId,
6+
code,
7+
getCallbackURLParams} : {
8+
domain: string;
9+
clientId: string;
10+
code: string;
11+
getCallbackURLParams: URL;
12+
): Promise<OAuth2CodeExchangeResponse> {
13+
const activeStorage = getActiveStorage();
14+
activeStorage.getSessionItem(StorageKeys.state);
15+
16+
17+
const [code, state] = super.getCallbackURLParams(callbackURL);
18+
const storedStateKey = this.getCodeVerifierKey(state);
19+
if (!storedStateKey?.endsWith(state)) {
20+
throw new Error('Received state does not match stored state');
21+
}
22+
23+
const getItem = isBrowserEnvironment()
24+
? (sessionManager as unknown as BrowserSessionManager).getSessionItemBrowser
25+
: sessionManager.getSessionItem;
26+
27+
const storedState = (await getItem.call(sessionManager, storedStateKey)) as
28+
| string
29+
| null;
30+
if (!storedState) {
31+
throw new Error('Stored state not found');
32+
}
33+
34+
const authFlowState = JSON.parse(storedState);
35+
this.codeVerifier = authFlowState.codeVerifier;
36+
37+
const body = new URLSearchParams({
38+
redirect_uri: this.config.redirectURL,
39+
client_id: this.config.clientId,
40+
code_verifier: this.codeVerifier!,
41+
grant_type: 'authorization_code',
42+
code,
43+
});
44+
45+
const removeItem = isBrowserEnvironment()
46+
? (sessionManager as unknown as BrowserSessionManager).removeSessionItemBrowser
47+
: sessionManager.removeSessionItem;
48+
49+
activeStorage.removeSessionItem(StorageKeys.state);
50+
51+
52+
try {
53+
return await this.fetchTokensFor(sessionManager, body);
54+
} finally {
55+
await removeItem.call(sessionManager, this.getCodeVerifierKey(state));
56+
}
57+
}

lib/utils/token/index.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it, beforeEach, vi } from "vitest";
1+
import { describe, expect, it } from "vitest";
22
import { MemoryStorage } from "../../sessionManager";
33
import {
44
getActiveStorage,

0 commit comments

Comments
 (0)