diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eb3dab66..49fdfd07f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,23 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.10.1](https://github.com/gradido/gradido/compare/1.10.0...1.10.1) + +- automatic session logout with info modal [`#2001`](https://github.com/gradido/gradido/pull/2001) +- 1910 separate text for the slideshow images. [`#1998`](https://github.com/gradido/gradido/pull/1998) +- Origin/1921 additional parameter checks for createContributionLinks [`#1996`](https://github.com/gradido/gradido/pull/1996) +- add missing locales [`#1999`](https://github.com/gradido/gradido/pull/1999) +- 1906 feature concept for gdd creation per linkqr code [`#1907`](https://github.com/gradido/gradido/pull/1907) +- refactor: 🍰 Not Throwing An Error When Register With Existing Email [`#1962`](https://github.com/gradido/gradido/pull/1962) +- feat: 🍰 Set Role In Admin Interface [`#1974`](https://github.com/gradido/gradido/pull/1974) +- refactor mobile style step 1 [`#1977`](https://github.com/gradido/gradido/pull/1977) +- changed mobil stage picture [`#1995`](https://github.com/gradido/gradido/pull/1995) + #### [1.10.0](https://github.com/gradido/gradido/compare/1.9.0...1.10.0) +> 17 June 2022 + +- release: v1.10.0 [`#1993`](https://github.com/gradido/gradido/pull/1993) - frontend redeem contribution link [`#1988`](https://github.com/gradido/gradido/pull/1988) - change new start picture [`#1990`](https://github.com/gradido/gradido/pull/1990) - feat: Redeem Contribution Link [`#1987`](https://github.com/gradido/gradido/pull/1987) diff --git a/admin/package.json b/admin/package.json index 73d8dd879..50145d44a 100644 --- a/admin/package.json +++ b/admin/package.json @@ -3,7 +3,7 @@ "description": "Administraion Interface for Gradido", "main": "index.js", "author": "Moriz Wahl", - "version": "1.10.0", + "version": "1.10.1", "license": "Apache-2.0", "private": false, "scripts": { diff --git a/backend/.env.dist b/backend/.env.dist index aa44057e7..0d1a14d7c 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -3,7 +3,7 @@ CONFIG_VERSION=v8.2022-06-20 # Server PORT=4000 JWT_SECRET=secret123 -JWT_EXPIRES_IN=30m +JWT_EXPIRES_IN=10m GRAPHIQL=false GDT_API_URL=https://gdt.gradido.net diff --git a/backend/package.json b/backend/package.json index 3675a5eb0..50f26351d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "gradido-backend", - "version": "1.10.0", + "version": "1.10.1", "description": "Gradido unified backend providing an API-Service for Gradido Transactions", "main": "src/index.ts", "repository": "https://github.com/gradido/gradido/backend", diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index a92d20c57..5e0978f3b 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/database/package.json b/database/package.json index 88885b9fc..23ab63f2b 100644 --- a/database/package.json +++ b/database/package.json @@ -1,6 +1,6 @@ { "name": "gradido-database", - "version": "1.10.0", + "version": "1.10.1", "description": "Gradido Database Tool to execute database migrations", "main": "src/index.ts", "repository": "https://github.com/gradido/gradido/database", diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index 67c153661..edb878040 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -28,7 +28,7 @@ COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community" # backend BACKEND_CONFIG_VERSION=v8.2022-06-20 -JWT_EXPIRES_IN=30m +JWT_EXPIRES_IN=10m GDT_API_URL=https://gdt.gradido.net TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log diff --git a/frontend/package.json b/frontend/package.json index 0aeb7c353..f51dd8266 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap-vue-gradido-wallet", - "version": "1.10.0", + "version": "1.10.1", "private": true, "scripts": { "start": "node run/server.js", @@ -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/components/SessionLogoutTimeout.spec.js b/frontend/src/components/SessionLogoutTimeout.spec.js new file mode 100644 index 000000000..0f5d21d36 --- /dev/null +++ b/frontend/src/components/SessionLogoutTimeout.spec.js @@ -0,0 +1,99 @@ +import { mount } from '@vue/test-utils' +import SessionLogoutTimeout from './SessionLogoutTimeout' + +const localVue = global.localVue + +const apolloQueryMock = jest.fn() + +const setTokenTime = (seconds) => { + const now = new Date() + return Math.floor(new Date(now.setSeconds(now.getSeconds() + seconds)).getTime() / 1000) +} + +const mocks = { + $store: { + state: { + token: '1234', + tokenTime: setTokenTime(120), + }, + }, + $i18n: { + locale: 'en', + }, + $t: jest.fn((t) => t), + $apollo: { + query: apolloQueryMock, + }, + $route: { + meta: { + requiresAuth: true, + }, + }, +} + +describe('SessionLogoutTimeout', () => { + let wrapper, spy + + const Wrapper = () => { + return mount(SessionLogoutTimeout, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + jest.clearAllMocks() + wrapper = Wrapper() + }) + + it('renders the component div.session-logout-timeout', () => { + expect(wrapper.find('div.session-logout-timeout').exists()).toBe(true) + }) + + describe('timers', () => { + it('has a token expires timer', () => { + expect(wrapper.vm.$options.timers).toEqual({ + tokenExpires: expect.objectContaining({ + name: 'tokenExpires', + time: 15000, + repeat: true, + immediate: true, + autostart: true, + isSwitchTab: false, + }), + }) + }) + + describe('token is expired', () => { + beforeEach(() => { + mocks.$store.state.tokenTime = setTokenTime(-60) + wrapper = Wrapper() + }) + + it('emits logout', () => { + expect(wrapper.emitted('logout')).toBeTruthy() + }) + }) + + describe('token time less than 75 seconds', () => { + beforeEach(() => { + mocks.$store.state.tokenTime = setTokenTime(60) + jest.useFakeTimers() + wrapper = Wrapper() + spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') + spy.mockImplementation(() => Promise.resolve(true)) + }) + + it('sets the timer to 1000', () => { + expect(wrapper.vm.timers.tokenExpires.time).toBe(1000) + }) + + it.skip('opens the modal', () => { + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + jest.advanceTimersByTime(1000) + expect(spy).toBeCalled() + }) + }) + }) + }) +}) diff --git a/frontend/src/components/SessionLogoutTimeout.vue b/frontend/src/components/SessionLogoutTimeout.vue new file mode 100644 index 000000000..1e5a27998 --- /dev/null +++ b/frontend/src/components/SessionLogoutTimeout.vue @@ -0,0 +1,100 @@ + + diff --git a/frontend/src/components/TransactionLinks/TransactionLink.spec.js b/frontend/src/components/TransactionLinks/TransactionLink.spec.js index ad9e4860e..13aaea900 100644 --- a/frontend/src/components/TransactionLinks/TransactionLink.spec.js +++ b/frontend/src/components/TransactionLinks/TransactionLink.spec.js @@ -92,6 +92,17 @@ describe('TransactionLink', () => { expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-copied') }) }) + + describe('copy with error', () => { + beforeEach(async () => { + navigatorClipboardMock.mockRejectedValue() + await wrapper.find('.test-copy-link .dropdown-item').trigger('click') + }) + + it('toasts an error', () => { + expect(toastErrorSpy).toBeCalledWith('gdd_per_link.not-copied') + }) + }) }) describe('qr code modal', () => { diff --git a/frontend/src/layouts/AuthLayout.spec.js b/frontend/src/layouts/AuthLayout.spec.js index 2246793d5..30c858ea5 100644 --- a/frontend/src/layouts/AuthLayout.spec.js +++ b/frontend/src/layouts/AuthLayout.spec.js @@ -35,9 +35,10 @@ describe('AuthLayout', () => { beforeEach(() => { wrapper = Wrapper() }) + describe('Mobile Version Start', () => { beforeEach(() => { - wrapper.vm.mobileStart = true + wrapper.findComponent({ name: 'AuthMobileStart' }).vm.$emit('set-mobile-start', true) }) it('has Component AuthMobileStart', () => { diff --git a/frontend/src/layouts/DashboardLayout.vue b/frontend/src/layouts/DashboardLayout.vue index cd8794c40..8e778ab01 100755 --- a/frontend/src/layouts/DashboardLayout.vue +++ b/frontend/src/layouts/DashboardLayout.vue @@ -32,6 +32,7 @@ + @@ -39,6 +40,7 @@