Skip to content

Commit

Permalink
Saves Tokens in Local Storage
Browse files Browse the repository at this point in the history
Sync storage can have issues such as quota overflowing and connectivity issues.

We don't need the tokens to be on sync storage, so instead it should be on local.
  • Loading branch information
Step7750 committed May 7, 2024
1 parent e0d4ad8 commit b036e3d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
13 changes: 9 additions & 4 deletions src/lib/alarms/access_token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface AccessToken {

export async function getAccessToken(): Promise<string | null> {
// Do we have a fresh local copy?
const tokenData = await gStore.get<AccessToken>(StorageKey.ACCESS_TOKEN);
const tokenData = await gStore.getWithStorage<AccessToken>(chrome.storage.local, StorageKey.ACCESS_TOKEN);
if (tokenData?.token && tokenData.updated_at > Date.now() - 30 * 60 * 1000) {
// Token refreshed within the last 30 min, we can re-use
return tokenData.token;
Expand All @@ -29,18 +29,23 @@ export async function getAccessToken(): Promise<string | null> {

const token = webAPITokenMatch[1];

await saveAccessToken(token);
try {
await saveAccessToken(token);
} catch (e) {
console.error('failed ot save access token to storage', e);
}

return token;
}

export function saveAccessToken(token: string): Promise<void> {
return gStore.set(StorageKey.ACCESS_TOKEN, {
// Explicitly use local storage to prevent issues with sync storage quota or connectivity issues
return gStore.setWithStorage(chrome.storage.local, StorageKey.ACCESS_TOKEN, {
token,
updated_at: Date.now(),
} as AccessToken);
}

export function clearAccessTokenFromStorage(): Promise<void> {
return gStore.remove(StorageKey.ACCESS_TOKEN);
return gStore.removeWithStorage(chrome.storage.local, StorageKey.ACCESS_TOKEN);
}
38 changes: 33 additions & 5 deletions src/lib/storage/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import {DynamicStorageKey, StorageKey} from './keys';

class Store {
// Prefer to use sync storage if possible
get storage(): chrome.storage.SyncStorageArea | chrome.storage.LocalStorageArea {
get defaultStorageLayer(): chrome.storage.SyncStorageArea | chrome.storage.LocalStorageArea {
return chrome.storage.sync ? chrome.storage.sync : chrome.storage.local;
}

async get<T>(key: StorageKey | DynamicStorageKey): Promise<T | null> {
const a = await this.storage.get(key);
// getWithStorage using a specified storage layer
async getWithStorage<T>(
storage: chrome.storage.SyncStorageArea | chrome.storage.LocalStorageArea,
key: StorageKey | DynamicStorageKey
): Promise<T | null> {
const a = await storage.get(key);
if (!a || !(key in a)) {
return null;
}
Expand All @@ -20,12 +24,36 @@ class Store {
}
}

// get using the default storage layer
async get<T>(key: StorageKey | DynamicStorageKey): Promise<T | null> {
return this.getWithStorage(this.defaultStorageLayer, key);
}

// setWithStorage using a specified storage layer
async setWithStorage<T>(
storage: chrome.storage.SyncStorageArea | chrome.storage.LocalStorageArea,
key: StorageKey | DynamicStorageKey,
value: T
): Promise<void> {
return storage.set({[key]: JSON.stringify(value)});
}

// set using the default storage layer
async set<T>(key: StorageKey | DynamicStorageKey, value: T): Promise<void> {
return this.storage.set({[key]: JSON.stringify(value)});
return this.setWithStorage(this.defaultStorageLayer, key, value);
}

// removeWithStorage using a specified storage layer
async removeWithStorage(
storage: chrome.storage.SyncStorageArea | chrome.storage.LocalStorageArea,
key: StorageKey | DynamicStorageKey
): Promise<void> {
return storage.remove([key]);
}

// remove using the default storage layer
async remove(key: StorageKey | DynamicStorageKey): Promise<void> {
return this.storage.remove([key]);
return this.removeWithStorage(this.defaultStorageLayer, key);
}
}

Expand Down

0 comments on commit b036e3d

Please sign in to comment.