web/satellite: clear vuex state on session timeout

We have to clear vuex app state on session timeout because user's session gets invalidated and user is redirected to login screen.

Issue:
https://github.com/storj/storj/issues/5370

Change-Id: Id654056331c81fac0b46ed90eccea0a044e4e1c9
This commit is contained in:
Vitalii 2022-12-15 13:15:09 +02:00 committed by Storj Robot
parent bb170a9d57
commit 92a757cf3f
8 changed files with 102 additions and 15 deletions

View File

@ -143,17 +143,20 @@ export default class AccountArea extends Vue {
return; return;
} }
await this.$store.dispatch(PM_ACTIONS.CLEAR); await Promise.all([
await this.$store.dispatch(PROJECTS_ACTIONS.CLEAR); this.$store.dispatch(PM_ACTIONS.CLEAR),
await this.$store.dispatch(USER_ACTIONS.CLEAR); this.$store.dispatch(PROJECTS_ACTIONS.CLEAR),
await this.$store.dispatch(ACCESS_GRANTS_ACTIONS.CLEAR); this.$store.dispatch(USER_ACTIONS.CLEAR),
await this.$store.dispatch(ACCESS_GRANTS_ACTIONS.STOP_ACCESS_GRANTS_WEB_WORKER); this.$store.dispatch(ACCESS_GRANTS_ACTIONS.STOP_ACCESS_GRANTS_WEB_WORKER),
await this.$store.dispatch(NOTIFICATION_ACTIONS.CLEAR); this.$store.dispatch(ACCESS_GRANTS_ACTIONS.CLEAR),
await this.$store.dispatch(BUCKET_ACTIONS.CLEAR); this.$store.dispatch(NOTIFICATION_ACTIONS.CLEAR),
await this.$store.dispatch(OBJECTS_ACTIONS.CLEAR); this.$store.dispatch(BUCKET_ACTIONS.CLEAR),
await this.$store.dispatch(APP_STATE_ACTIONS.CLOSE_POPUPS); this.$store.dispatch(OBJECTS_ACTIONS.CLEAR),
await this.$store.dispatch(PAYMENTS_ACTIONS.CLEAR_PAYMENT_INFO); this.$store.dispatch(APP_STATE_ACTIONS.CLOSE_POPUPS),
await this.$store.dispatch(AB_TESTING_ACTIONS.RESET); this.$store.dispatch(PAYMENTS_ACTIONS.CLEAR_PAYMENT_INFO),
this.$store.dispatch(AB_TESTING_ACTIONS.RESET),
this.$store.dispatch('files/clear'),
]);
LocalData.removeUserId(); LocalData.removeUserId();
} }

View File

@ -206,6 +206,12 @@ export function makeAccessGrantsModule(api: AccessGrantsApi, workerFactory?: Acc
state.permissionNotBefore = null; state.permissionNotBefore = null;
state.permissionNotAfter = null; state.permissionNotAfter = null;
state.gatewayCredentials = new EdgeCredentials(); state.gatewayCredentials = new EdgeCredentials();
state.isDownload = true;
state.isUpload = true;
state.isList = true;
state.isDelete = true;
state.accessGrantsWebWorker = null;
state.isAccessGrantsWebWorkerReady = false;
}, },
}, },
actions: { actions: {

View File

@ -208,6 +208,35 @@ export const appStateModule = {
state.appState.isAGDatePickerShown = false; state.appState.isAGDatePickerShown = false;
state.appState.isChartsDatePickerShown = false; state.appState.isChartsDatePickerShown = false;
state.appState.isBucketNamesDropdownShown = false; state.appState.isBucketNamesDropdownShown = false;
state.appState.isAddTeamMembersModalShown = false;
state.appState.isEditProfileModalShown = false;
state.appState.isChangePasswordModalShown = false;
state.appState.isUploadCancelPopupVisible = false;
state.appState.isSuccessfulPasswordResetShown = false;
state.appState.isCreateProjectPromptModalShown = false;
state.appState.isCreateProjectModalShown = false;
state.appState.isAddPMModalShown = false;
state.appState.isOpenBucketModalShown = false;
state.appState.isMFARecoveryModalShown = false;
state.appState.isEnableMFAModalShown = false;
state.appState.isDisableMFAModalShown = false;
state.appState.isAddTokenFundsModalShown = false;
state.appState.isShareBucketModalShown = false;
state.appState.isShareObjectModalShown = false;
state.appState.isDeleteBucketModalShown = false;
state.appState.isNewFolderModalShown = false;
state.appState.isCreateProjectPassphraseModalShown = false;
state.appState.isManageProjectPassphraseModalShown = false;
state.appState.isObjectDetailsModalShown = false;
state.appState.isAddCouponModalShown = false;
state.appState.isNewBillingAddCouponModalShown = false;
state.appState.onbAGStepBackRoute = '';
state.appState.onbAPIKeyStepBackRoute = '';
state.appState.onbCleanApiKey = '';
state.appState.onbApiKey = '';
state.appState.setDefaultPaymentMethodID = '';
state.appState.deletePaymentMethodID = '';
state.appState.onbSelectedOs = null;
}, },
[APP_STATE_MUTATIONS.CHANGE_STATE](state: State, newFetchState: AppState): void { [APP_STATE_MUTATIONS.CHANGE_STATE](state: State, newFetchState: AppState): void {
state.appState.fetchState = newFetchState; state.appState.fetchState = newFetchState;

View File

@ -288,6 +288,29 @@ export const makeFilesModule = (): FilesModule => ({
addUploadToChain(state: FilesState, fn) { addUploadToChain(state: FilesState, fn) {
state.uploadChain = state.uploadChain.then(fn); state.uploadChain = state.uploadChain.then(fn);
}, },
clear(state: FilesState) {
state.s3 = null;
state.accessKey = null;
state.path = '';
state.bucket = '';
state.browserRoot = '/';
state.files = [];
state.uploadChain = Promise.resolve();
state.uploading = [];
state.selectedAnchorFile = null;
state.unselectedAnchorFile = null;
state.selectedFiles = [];
state.shiftSelectedFiles = [];
state.filesToBeDeleted = [];
state.fetchSharedLink = () => 'javascript:null';
state.fetchPreviewAndMapUrl = () => 'javascript:null';
state.openedDropdown = null;
state.headingSorted = 'name';
state.orderBy = 'asc';
state.openModalOnFirstUpload = false;
state.objectPathForModal = '';
},
}, },
actions: { actions: {
async list({ commit, state }, path = state.path) { async list({ commit, state }, path = state.path) {
@ -726,5 +749,9 @@ export const makeFilesModule = (): FilesModule => ({
dispatch('clearAllSelectedFiles'); dispatch('clearAllSelectedFiles');
} }
}, },
clear({ commit }) {
commit('clear');
},
}, },
}); });

View File

@ -153,6 +153,7 @@ export function makeObjectsModule(): StoreModule<ObjectsState, ObjectsContext> {
}); });
state.bucketsList = []; state.bucketsList = [];
state.fileComponentBucketName = ''; state.fileComponentBucketName = '';
state.leaveRoute = '';
}, },
}, },
actions: { actions: {

View File

@ -188,6 +188,8 @@ export function makeProjectsModule(api: ProjectsApi): StoreModule<ProjectsState,
state.settledBandwidthChartData = []; state.settledBandwidthChartData = [];
state.chartDataSince = new Date(); state.chartDataSince = new Date();
state.chartDataBefore = new Date(); state.chartDataBefore = new Date();
state.cursor = new ProjectsCursor();
state.page = new ProjectsPage();
}, },
[SET_PAGE_NUMBER](state: ProjectsState, pageNumber: number) { [SET_PAGE_NUMBER](state: ProjectsState, pageNumber: number) {
state.cursor.page = pageNumber; state.cursor.page = pageNumber;

View File

@ -78,6 +78,8 @@ export function makeUsersModule(api: UsersApi): StoreModule<UsersState, UsersCon
[CLEAR](state: UsersState): void { [CLEAR](state: UsersState): void {
state.user = new User(); state.user = new User();
state.user.projectLimit = 1; state.user.projectLimit = 1;
state.userMFASecret = '';
state.userMFARecoveryCodes = [];
}, },
[UPDATE_USER](state: UsersState, user: UpdatedUser): void { [UPDATE_USER](state: UsersState, user: UpdatedUser): void {
state.user.fullName = user.fullName; state.user.fullName = user.fullName;

View File

@ -78,7 +78,7 @@ import { USER_ACTIONS } from '@/store/modules/users';
import { CouponType } from '@/types/coupons'; import { CouponType } from '@/types/coupons';
import { CreditCard } from '@/types/payments'; import { CreditCard } from '@/types/payments';
import { Project } from '@/types/projects'; import { Project } from '@/types/projects';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames'; import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS, PM_ACTIONS } from '@/utils/constants/actionNames';
import { APP_STATE_MUTATIONS } from '@/store/mutationConstants'; import { APP_STATE_MUTATIONS } from '@/store/mutationConstants';
import { AppState } from '@/utils/constants/appStateEnum'; import { AppState } from '@/utils/constants/appStateEnum';
import { LocalData } from '@/utils/localData'; import { LocalData } from '@/utils/localData';
@ -90,6 +90,8 @@ import eventBus from '@/utils/eventBus';
import { ABTestValues } from '@/types/abtesting'; import { ABTestValues } from '@/types/abtesting';
import { AB_TESTING_ACTIONS } from '@/store/modules/abTesting'; import { AB_TESTING_ACTIONS } from '@/store/modules/abTesting';
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames'; import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
import { BUCKET_ACTIONS } from '@/store/modules/buckets';
import { OBJECTS_ACTIONS } from '@/store/modules/objects';
import ProjectInfoBar from '@/components/infoBars/ProjectInfoBar.vue'; import ProjectInfoBar from '@/components/infoBars/ProjectInfoBar.vue';
import BillingNotification from '@/components/notifications/BillingNotification.vue'; import BillingNotification from '@/components/notifications/BillingNotification.vue';
@ -139,7 +141,7 @@ export default class DashboardArea extends Vue {
private inactivityModalShown = false; private inactivityModalShown = false;
private inactivityModalTime = 60000; private inactivityModalTime = 60000;
private ACTIVITY_REFRESH_TIME_LIMIT = 180000; private ACTIVITY_REFRESH_TIME_LIMIT = 180000;
private sessionRefreshInterval: number = this.sessionDuration/2; private sessionRefreshInterval: number = this.sessionDuration / 2;
private sessionRefreshTimerId: ReturnType<typeof setTimeout> | null; private sessionRefreshTimerId: ReturnType<typeof setTimeout> | null;
private isSessionActive = false; private isSessionActive = false;
private isSessionRefreshing = false; private isSessionRefreshing = false;
@ -217,7 +219,7 @@ export default class DashboardArea extends Vue {
*/ */
public async mounted(): Promise<void> { public async mounted(): Promise<void> {
this.$store.subscribeAction((action) => { this.$store.subscribeAction((action) => {
if (action.type == USER_ACTIONS.CLEAR) this.clearSessionTimers(); if (action.type === USER_ACTIONS.CLEAR) this.clearSessionTimers();
}); });
if (LocalData.getBillingNotificationAcknowledged()) { if (LocalData.getBillingNotificationAcknowledged()) {
@ -503,6 +505,21 @@ export default class DashboardArea extends Vue {
await this.$notify.error(error.message, AnalyticsErrorEventSource.OVERALL_SESSION_EXPIRED_ERROR); await this.$notify.error(error.message, AnalyticsErrorEventSource.OVERALL_SESSION_EXPIRED_ERROR);
} }
await Promise.all([
this.$store.dispatch(PM_ACTIONS.CLEAR),
this.$store.dispatch(PROJECTS_ACTIONS.CLEAR),
this.$store.dispatch(USER_ACTIONS.CLEAR),
this.$store.dispatch(ACCESS_GRANTS_ACTIONS.STOP_ACCESS_GRANTS_WEB_WORKER),
this.$store.dispatch(ACCESS_GRANTS_ACTIONS.CLEAR),
this.$store.dispatch(NOTIFICATION_ACTIONS.CLEAR),
this.$store.dispatch(BUCKET_ACTIONS.CLEAR),
this.$store.dispatch(OBJECTS_ACTIONS.CLEAR),
this.$store.dispatch(APP_STATE_ACTIONS.CLOSE_POPUPS),
this.$store.dispatch(PAYMENTS_ACTIONS.CLEAR_PAYMENT_INFO),
this.$store.dispatch(AB_TESTING_ACTIONS.RESET),
this.$store.dispatch('files/clear'),
]);
} }
/** /**
@ -511,7 +528,7 @@ export default class DashboardArea extends Vue {
private async onSessionActivity(): Promise<void> { private async onSessionActivity(): Promise<void> {
if (this.inactivityModalShown || this.isSessionActive) return; if (this.inactivityModalShown || this.isSessionActive) return;
if (this.sessionRefreshTimerId == null && !this.isSessionRefreshing) { if (this.sessionRefreshTimerId === null && !this.isSessionRefreshing) {
await this.refreshSession(); await this.refreshSession();
} }
this.isSessionActive = true; this.isSessionActive = true;