From fae06855093345df7321ae128933a5c66992f5f8 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 22 Jun 2022 22:41:26 +0200 Subject: [PATCH 01/25] step 1 automatic logout of session after 10 minutes, last 60 seconds warning modal --- backend/src/config/index.ts | 2 +- frontend/package.json | 2 + frontend/src/layouts/DashboardLayout.vue | 62 ++++++++++++++++++++++++ frontend/src/locales/de.json | 4 ++ frontend/src/locales/en.json | 4 ++ frontend/src/plugins/dashboard-plugin.js | 3 ++ frontend/src/store/store.js | 7 +++ frontend/yarn.lock | 10 ++++ 8 files changed, 93 insertions(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index a9cae6770..aa4197a43 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -25,7 +25,7 @@ const constants = { const server = { PORT: process.env.PORT || 4000, JWT_SECRET: process.env.JWT_SECRET || 'secret123', - JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || '30m', + JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN || '10m', GRAPHIQL: process.env.GRAPHIQL === 'true' || false, GDT_API_URL: process.env.GDT_API_URL || 'https://gdt.gradido.net', PRODUCTION: process.env.NODE_ENV === 'production' || false, diff --git a/frontend/package.json b/frontend/package.json index 0aeb7c353..7bf370802 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -45,6 +45,7 @@ "jest": "^26.6.3", "jest-canvas-mock": "^2.3.1", "jest-environment-jsdom-sixteen": "^2.0.0", + "jwt-decode": "^3.1.2", "portal-vue": "^2.1.7", "prettier": "^2.2.1", "qrcanvas-vue": "2.1.1", @@ -59,6 +60,7 @@ "vue-loading-overlay": "^3.4.2", "vue-moment": "^4.1.0", "vue-router": "^3.0.6", + "vue-timers": "^2.0.4", "vue2-transitions": "^0.2.3", "vuex": "^3.6.0", "vuex-persistedstate": "^4.0.0-beta.3" diff --git a/frontend/src/layouts/DashboardLayout.vue b/frontend/src/layouts/DashboardLayout.vue index cd8794c40..a2adb7de6 100755 --- a/frontend/src/layouts/DashboardLayout.vue +++ b/frontend/src/layouts/DashboardLayout.vue @@ -32,6 +32,22 @@ + + + +
{{ $t('session.warningText') }}
+
+ {{ $t('session.lightText') }} + {{ closeTime }} + {{ $t('time.seconds') }} +
+
+
+ +
@@ -43,6 +59,7 @@ import { logout, transactionsQuery } from '@/graphql/queries' import ContentFooter from '@/components/ContentFooter.vue' import { FadeTransition } from 'vue2-transitions' import CONFIG from '@/config' +import { verifyLogin } from '../graphql/queries' export default { name: 'DashboardLayout', @@ -62,6 +79,10 @@ export default { pending: true, visible: false, tunneledEmail: null, + time: 0, + millisecondsShowModal: 75000, + millisecondsCheckTokenInterval: 15000, + closeTime: 60, } }, provide() { @@ -70,6 +91,41 @@ export default { } }, methods: { + timeout() { + if (this.closeTime > 0) { + this.closeTime = this.closeTime - 1 + } else { + this.logout() + } + }, + handleOk(bvModalEvent) { + // Prevent modal from closing + bvModalEvent.preventDefault() + this.$apollo + .query({ + query: verifyLogin, + fetchPolicy: 'network-only', + }) + .then((result) => { + clearInterval(this.$options.interval2) + this.$bvModal.hide('modalSessionTimeOut') + this.closeTime = 60 + }) + .catch(() => { + this.logout() + }) + }, + async log() { + if (this.$route.meta.requiresAuth) { + const now = new Date().getTime() + const exp = new Date(this.$store.state.tokenTime * 1000).getTime() + const diff = exp - now + if (diff < this.millisecondsShowModal) { + this.$bvModal.show('modalSessionTimeOut') + this.$options.interval2 = setInterval(this.timeout, 1000) + } + } + }, async logout() { this.$apollo .query({ @@ -139,6 +195,12 @@ export default { ) }, }, + created() { + this.$options.interval = setInterval(this.log, this.millisecondsCheckTokenInterval) + }, + beforeDestroy() { + clearInterval(this.$options.interval) + }, }