Support missing session storage (Fix Firefox Private Mode)

This commit is contained in:
Alexander Zinchuk 2021-04-29 18:24:10 +03:00
parent bedd3d2119
commit 426ca7549b
5 changed files with 84 additions and 48 deletions

View File

@ -3,10 +3,10 @@ const StorageSession = require('./StorageSession')
const CACHE_NAME = 'GramJs' const CACHE_NAME = 'GramJs'
class CacheApiSession extends StorageSession { class CacheApiSession extends StorageSession {
async delete() { async _delete() {
const request = new Request(this._storageKey) const request = new Request(this._storageKey)
const cache = await self.caches.open(CACHE_NAME) const cache = await self.caches.open(CACHE_NAME)
await cache.delete(request) return cache.delete(request)
} }
async _fetchFromCache() { async _fetchFromCache() {

View File

@ -4,7 +4,7 @@ const idb = require('idb-keyval')
const CACHE_NAME = 'GramJs' const CACHE_NAME = 'GramJs'
class IdbSession extends StorageSession { class IdbSession extends StorageSession {
async delete() { async _delete() {
return idb.del(`${CACHE_NAME}:${this._storageKey}`) return idb.del(`${CACHE_NAME}:${this._storageKey}`)
} }

View File

@ -1,7 +1,7 @@
const StorageSession = require('./StorageSession') const StorageSession = require('./StorageSession')
class LocalStorageSession extends StorageSession { class LocalStorageSession extends StorageSession {
async delete() { async _delete() {
return localStorage.removeItem(this._storageKey) return localStorage.removeItem(this._storageKey)
} }

View File

@ -32,7 +32,8 @@ class StorageSession extends MemorySession {
} }
}) })
} catch (err) { } catch (err) {
throw new Error(`Failed to retrieve or parse JSON from Cache for key ${this._storageKey}`) console.warn('Failed to retrieve or parse session from storage')
console.warn(err)
} }
} }
@ -93,17 +94,34 @@ class StorageSession extends MemorySession {
sessionData.hashes[dcId] = authKey._hash sessionData.hashes[dcId] = authKey._hash
}) })
try {
await this._saveToCache(JSON.stringify(sessionData)) await this._saveToCache(JSON.stringify(sessionData))
} catch (err) {
console.warn('Failed to update session in storage')
console.warn(err)
}
} }
async delete() { async delete() {
try {
return await this._delete()
} catch (err) {
console.warn('Failed to delete session from storage')
console.warn(err)
}
}
// @abstract
async _delete() {
throw new Error('Not Implemented') throw new Error('Not Implemented')
} }
// @abstract
async _fetchFromCache() { async _fetchFromCache() {
throw new Error('Not Implemented') throw new Error('Not Implemented')
} }
// @abstract
async _saveToCache(data) { async _saveToCache(data) {
throw new Error('Not Implemented') throw new Error('Not Implemented')
} }

View File

@ -12,6 +12,7 @@ export async function fetch(cacheName: string, key: string, type: Type) {
return undefined; return undefined;
} }
try {
const request = new Request(key); const request = new Request(key);
const cache = await cacheApi.open(cacheName); const cache = await cacheApi.open(cacheName);
const response = await cache.match(request); const response = await cache.match(request);
@ -21,7 +22,7 @@ export async function fetch(cacheName: string, key: string, type: Type) {
switch (type) { switch (type) {
case Type.Text: case Type.Text:
return response.text(); return await response.text();
case Type.Blob: { case Type.Blob: {
const blob = await response.blob(); const blob = await response.blob();
@ -41,10 +42,15 @@ export async function fetch(cacheName: string, key: string, type: Type) {
return blob; return blob;
} }
case Type.Json: case Type.Json:
return response.json(); return await response.json();
default: default:
return undefined; return undefined;
} }
} catch (err) {
// eslint-disable-next-line no-console
console.warn(err);
return undefined;
}
} }
export async function save(cacheName: string, key: string, data: AnyLiteral | Blob | string) { export async function save(cacheName: string, key: string, data: AnyLiteral | Blob | string) {
@ -52,17 +58,29 @@ export async function save(cacheName: string, key: string, data: AnyLiteral | Bl
return undefined; return undefined;
} }
try {
const cacheData = typeof data === 'string' || data instanceof Blob ? data : JSON.stringify(data); const cacheData = typeof data === 'string' || data instanceof Blob ? data : JSON.stringify(data);
const request = new Request(key); const request = new Request(key);
const response = new Response(cacheData); const response = new Response(cacheData);
const cache = await cacheApi.open(cacheName); const cache = await cacheApi.open(cacheName);
return cache.put(request, response); return await cache.put(request, response);
} catch (err) {
// eslint-disable-next-line no-console
console.warn(err);
return undefined;
}
} }
export function clear(cacheName: string) { export async function clear(cacheName: string) {
try {
if (!cacheApi) { if (!cacheApi) {
return undefined; return undefined;
} }
return cacheApi.delete(cacheName); return await cacheApi.delete(cacheName);
} catch (err) {
// eslint-disable-next-line no-console
console.warn(err);
return undefined;
}
} }