diff --git a/config/default.js b/config/default.js index 5781d8d6d..734b78906 100644 --- a/config/default.js +++ b/config/default.js @@ -79,12 +79,6 @@ export default { google: null, }, - authSessions: { - reissueIntervalSec: 3600, - localStorageCheckIntervalSec: 60, - lockIntervalSec: 60, - }, - eslint: { // By default the eslint-linebreak-style directive requires "windows" linebreaks // on Windows platform and "unix" linebreaks otherwise. diff --git a/package.json b/package.json index 9c7747bb7..6c95d0452 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,6 @@ "mini-css-extract-plugin": "~0.11.3", "mocha": "~8.2.1", "mochapack": "~2.0.6", - "nanoid": "~3.1.20", "node-noop": "^1.0.0", "node-sass": "~5.0.0", "npm-run-all": "~4.1.5", diff --git a/src/redux/middlewares.js b/src/redux/middlewares.js index 20962081e..62787a0ee 100644 --- a/src/redux/middlewares.js +++ b/src/redux/middlewares.js @@ -1,10 +1,9 @@ -/* global CONFIG */ import { browserHistory } from 'react-router'; import _ from 'lodash'; import * as Sentry from '@sentry/react'; import { getPost } from '../services/api'; -import { getToken, onStorageChange, scheduleTokenReissue, setToken } from '../services/auth'; +import { setToken } from '../services/auth'; import { Connection } from '../services/realtime'; import { delay } from '../utils'; import * as FeedOptions from '../utils/feed-options'; @@ -228,27 +227,6 @@ function shouldGoToSignIn(pathname) { export const authMiddleware = (store) => { let firstUnauthenticated = true; - scheduleTokenReissue(store); - - // Periodically check for token change in local storage - setInterval(() => { - const cachedToken = getToken(); - const actualToken = getToken(true); - if (actualToken !== cachedToken) { - authDebug('token changed in local storage (by periodic check)'); - setToken(actualToken, false); - store.dispatch(ActionCreators.authTokenUpdated()); - scheduleTokenReissue(store); - } - }, CONFIG.authSessions.localStorageCheckIntervalSec * 1000); - - onStorageChange((newToken) => { - authDebug('token changed in local storage'); - setToken(newToken, false); - store.dispatch(ActionCreators.authTokenUpdated()); - scheduleTokenReissue(store); - }); - return (next) => (action) => { //stop action propagation if it should be authed and user is not authed if (requiresAuth(action) && !store.getState().authenticated) { diff --git a/src/services/auth.js b/src/services/auth.js index b8fe4da70..bfa8338a4 100644 --- a/src/services/auth.js +++ b/src/services/auth.js @@ -1,65 +1,22 @@ /* global CONFIG */ import storage from 'local-storage-fallback'; -import { nanoid } from 'nanoid'; -import { reissueAuthSession } from '../redux/action-creators'; import { authDebug } from '../utils/debug'; -import { Lock } from '../utils/storage-lock'; const { tokenPrefix } = CONFIG.auth; const NAME = `${tokenPrefix}authToken`; -let token; - -export function getToken(force = false) { - if (token === undefined || force) { - authDebug('loading token from the storage'); - token = storage.getItem(NAME); - } - return token; +export function getToken() { + authDebug('loading token from the storage'); + return storage.getItem(NAME); } -export function setToken(newToken = null, save = true) { - if (save) { - if (!newToken) { - authDebug('cleaning token up'); - storage.removeItem(NAME); - } else { - authDebug('saving token to the storage'); - storage.setItem(NAME, newToken); - } +export function setToken(newToken = null) { + if (!newToken) { + authDebug('cleaning token up'); + storage.removeItem(NAME); + } else { + authDebug('saving token to the storage'); + storage.setItem(NAME, newToken); } - authDebug('updating token in memory'); - token = newToken; -} - -export function onStorageChange(callback) { - window?.addEventListener('storage', (e) => e.key === NAME && callback(e.newValue)); -} - -const lock = new Lock( - storage, - `${tokenPrefix}lock`, - nanoid(), - CONFIG.authSessions.lockIntervalSec * 1000, -); - -let tokenReissueTimer = 0; - -export function scheduleTokenReissue(store) { - const interval = CONFIG.authSessions.reissueIntervalSec * 1000 * (1 + Math.random() / 3); - authDebug(`scheduling token reissue at ${interval / 1000} seconds`); - clearTimeout(tokenReissueTimer); - tokenReissueTimer = setTimeout(() => { - if (store.getState().authenticated) { - authDebug('trying to reissue token'); - if (lock.try()) { - authDebug('start token reissue'); - store.dispatch(reissueAuthSession()); - } else { - authDebug('lock detecting, skipping reissue'); - } - } - scheduleTokenReissue(store); - }, interval); } diff --git a/src/utils/storage-lock.js b/src/utils/storage-lock.js deleted file mode 100644 index 198d4fe4e..000000000 --- a/src/utils/storage-lock.js +++ /dev/null @@ -1,45 +0,0 @@ -// Loosely based on Lamport's Fast Mutual Exclusion Algorithm -// https://www.microsoft.com/en-us/research/publication/fast-mutual-exclusion-algorithm/ -// https://www.cs.rochester.edu/research/synchronization/pseudocode/fastlock.html - -export class Lock { - /** - * @param {Storage} storage - * @param {string} keyPrefix - * @param {string} thisId - * @param {number} lockInterval - */ - constructor(storage, keyPrefix, thisId, lockInterval) { - this.storage = storage; - this.keyPrefix = keyPrefix; - this.id = thisId; - this.lockInterval = lockInterval; - } - - try() { - this._write('X'); - if (this._isLockedByOther('Y')) { - return false; - } - this._write('Y'); - return !this._isLockedByOther('X'); - } - - _isLockedByOther(key) { - const lk = this._read(key); - return lk && lk.tab !== this.id && lk.time > Date.now() - this.lockInterval; - } - - _read(key) { - const data = this.storage.getItem(this.keyPrefix + key) || 'null'; - try { - return JSON.parse(data); - } catch { - return null; - } - } - - _write(key) { - this.storage.setItem(this.keyPrefix + key, JSON.stringify({ time: Date.now(), tab: this.id })); - } -} diff --git a/yarn.lock b/yarn.lock index bc7992f4c..70c009e52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8902,15 +8902,6 @@ fsevents@~2.1.2: languageName: node linkType: hard -"nanoid@npm:~3.1.20": - version: 3.1.20 - resolution: "nanoid@npm:3.1.20" - bin: - nanoid: bin/nanoid.cjs - checksum: 4788d36edcfec7bb32ddf33ed8f1f46df2867f70e9b1993bb131f7677e04ead2b621e5d614d2736308be18db1d54208d8ab207b4586bd5b052f71fb9d4c0ebea - languageName: node - linkType: hard - "nanomatch@npm:^1.2.9": version: 1.2.13 resolution: "nanomatch@npm:1.2.13" @@ -11349,7 +11340,6 @@ fsevents@~2.1.2: mocha: ~8.2.1 mochapack: ~2.0.6 mousetrap: ^1.6.5 - nanoid: ~3.1.20 node-noop: ^1.0.0 node-sass: ~5.0.0 npm-run-all: ~4.1.5