mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into 1794-feature-event-protocol-1-implement-the-basics-of-the-business-event-protocol
This commit is contained in:
commit
e4fc2cce6d
15
CHANGELOG.md
15
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).
|
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)
|
#### [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)
|
- frontend redeem contribution link [`#1988`](https://github.com/gradido/gradido/pull/1988)
|
||||||
- change new start picture [`#1990`](https://github.com/gradido/gradido/pull/1990)
|
- change new start picture [`#1990`](https://github.com/gradido/gradido/pull/1990)
|
||||||
- feat: Redeem Contribution Link [`#1987`](https://github.com/gradido/gradido/pull/1987)
|
- feat: Redeem Contribution Link [`#1987`](https://github.com/gradido/gradido/pull/1987)
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
"description": "Administraion Interface for Gradido",
|
"description": "Administraion Interface for Gradido",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"author": "Moriz Wahl",
|
"author": "Moriz Wahl",
|
||||||
"version": "1.10.0",
|
"version": "1.10.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ CONFIG_VERSION=v8.2022-06-20
|
|||||||
# Server
|
# Server
|
||||||
PORT=4000
|
PORT=4000
|
||||||
JWT_SECRET=secret123
|
JWT_SECRET=secret123
|
||||||
JWT_EXPIRES_IN=30m
|
JWT_EXPIRES_IN=10m
|
||||||
GRAPHIQL=false
|
GRAPHIQL=false
|
||||||
GDT_API_URL=https://gdt.gradido.net
|
GDT_API_URL=https://gdt.gradido.net
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gradido-backend",
|
"name": "gradido-backend",
|
||||||
"version": "1.10.0",
|
"version": "1.10.1",
|
||||||
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
|
"description": "Gradido unified backend providing an API-Service for Gradido Transactions",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": "https://github.com/gradido/gradido/backend",
|
"repository": "https://github.com/gradido/gradido/backend",
|
||||||
|
|||||||
@ -25,7 +25,7 @@ const constants = {
|
|||||||
const server = {
|
const server = {
|
||||||
PORT: process.env.PORT || 4000,
|
PORT: process.env.PORT || 4000,
|
||||||
JWT_SECRET: process.env.JWT_SECRET || 'secret123',
|
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,
|
GRAPHIQL: process.env.GRAPHIQL === 'true' || false,
|
||||||
GDT_API_URL: process.env.GDT_API_URL || 'https://gdt.gradido.net',
|
GDT_API_URL: process.env.GDT_API_URL || 'https://gdt.gradido.net',
|
||||||
PRODUCTION: process.env.NODE_ENV === 'production' || false,
|
PRODUCTION: process.env.NODE_ENV === 'production' || false,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gradido-database",
|
"name": "gradido-database",
|
||||||
"version": "1.10.0",
|
"version": "1.10.1",
|
||||||
"description": "Gradido Database Tool to execute database migrations",
|
"description": "Gradido Database Tool to execute database migrations",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"repository": "https://github.com/gradido/gradido/database",
|
"repository": "https://github.com/gradido/gradido/database",
|
||||||
|
|||||||
@ -28,7 +28,7 @@ COMMUNITY_DESCRIPTION="Gradido Development Stage1 Test Community"
|
|||||||
# backend
|
# backend
|
||||||
BACKEND_CONFIG_VERSION=v8.2022-06-20
|
BACKEND_CONFIG_VERSION=v8.2022-06-20
|
||||||
|
|
||||||
JWT_EXPIRES_IN=30m
|
JWT_EXPIRES_IN=10m
|
||||||
GDT_API_URL=https://gdt.gradido.net
|
GDT_API_URL=https://gdt.gradido.net
|
||||||
|
|
||||||
TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log
|
TYPEORM_LOGGING_RELATIVE_PATH=../deployment/bare_metal/log/typeorm.backend.log
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "bootstrap-vue-gradido-wallet",
|
"name": "bootstrap-vue-gradido-wallet",
|
||||||
"version": "1.10.0",
|
"version": "1.10.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node run/server.js",
|
"start": "node run/server.js",
|
||||||
@ -45,6 +45,7 @@
|
|||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"jest-canvas-mock": "^2.3.1",
|
"jest-canvas-mock": "^2.3.1",
|
||||||
"jest-environment-jsdom-sixteen": "^2.0.0",
|
"jest-environment-jsdom-sixteen": "^2.0.0",
|
||||||
|
"jwt-decode": "^3.1.2",
|
||||||
"portal-vue": "^2.1.7",
|
"portal-vue": "^2.1.7",
|
||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
"qrcanvas-vue": "2.1.1",
|
"qrcanvas-vue": "2.1.1",
|
||||||
@ -59,6 +60,7 @@
|
|||||||
"vue-loading-overlay": "^3.4.2",
|
"vue-loading-overlay": "^3.4.2",
|
||||||
"vue-moment": "^4.1.0",
|
"vue-moment": "^4.1.0",
|
||||||
"vue-router": "^3.0.6",
|
"vue-router": "^3.0.6",
|
||||||
|
"vue-timers": "^2.0.4",
|
||||||
"vue2-transitions": "^0.2.3",
|
"vue2-transitions": "^0.2.3",
|
||||||
"vuex": "^3.6.0",
|
"vuex": "^3.6.0",
|
||||||
"vuex-persistedstate": "^4.0.0-beta.3"
|
"vuex-persistedstate": "^4.0.0-beta.3"
|
||||||
|
|||||||
99
frontend/src/components/SessionLogoutTimeout.spec.js
Normal file
99
frontend/src/components/SessionLogoutTimeout.spec.js
Normal file
@ -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()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
100
frontend/src/components/SessionLogoutTimeout.vue
Normal file
100
frontend/src/components/SessionLogoutTimeout.vue
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<div class="session-logout-timeout">
|
||||||
|
<b-modal
|
||||||
|
id="modalSessionTimeOut"
|
||||||
|
class="bg-variant-danger"
|
||||||
|
hide-header-close
|
||||||
|
hide-header
|
||||||
|
hide-footer
|
||||||
|
no-close-on-backdrop
|
||||||
|
>
|
||||||
|
<b-card header-tag="header" footer-tag="footer">
|
||||||
|
<b-card-text>
|
||||||
|
<div class="p-3 h2">{{ $t('session.warningText') }}</div>
|
||||||
|
<div class="p-3">
|
||||||
|
{{ $t('session.lightText') }}
|
||||||
|
</div>
|
||||||
|
<div class="p-3 h2 text-warning">
|
||||||
|
{{ $t('session.logoutIn') }}
|
||||||
|
<b>{{ tokenExpiresInSeconds }}</b>
|
||||||
|
{{ $t('time.seconds') }}
|
||||||
|
</div>
|
||||||
|
</b-card-text>
|
||||||
|
<b-row>
|
||||||
|
<b-col class="text-center">
|
||||||
|
<b-button size="lg" variant="success" @click="handleOk">
|
||||||
|
{{ $t('session.extend') }}
|
||||||
|
</b-button>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</b-card>
|
||||||
|
<template #modal-footer>
|
||||||
|
<b-button size="sm" variant="danger" @click="$emit('logout')">
|
||||||
|
{{ $t('navigation.logout') }}
|
||||||
|
</b-button>
|
||||||
|
<b-button size="lg" variant="success" @click="handleOk">
|
||||||
|
{{ $t('session.extend') }}
|
||||||
|
</b-button>
|
||||||
|
</template>
|
||||||
|
</b-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { verifyLogin } from '@/graphql/queries'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SessionLogoutTimeout',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
now: new Date().getTime(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timers: {
|
||||||
|
tokenExpires: {
|
||||||
|
time: 15000,
|
||||||
|
autostart: true,
|
||||||
|
repeat: true,
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
tokenExpires() {
|
||||||
|
this.now = new Date().getTime()
|
||||||
|
if (this.tokenExpiresInSeconds < 75 && this.timers.tokenExpires.time !== 1000) {
|
||||||
|
this.timers.tokenExpires.time = 1000
|
||||||
|
this.$timer.restart('tokenExpires')
|
||||||
|
this.$bvModal.show('modalSessionTimeOut')
|
||||||
|
}
|
||||||
|
if (this.tokenExpiresInSeconds <= 0) {
|
||||||
|
this.$timer.stop('tokenExpires')
|
||||||
|
this.$emit('logout')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleOk(bvModalEvent) {
|
||||||
|
bvModalEvent.preventDefault()
|
||||||
|
this.$apollo
|
||||||
|
.query({
|
||||||
|
query: verifyLogin,
|
||||||
|
fetchPolicy: 'network-only',
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
this.timers.tokenExpires.time = 15000
|
||||||
|
this.$timer.restart('tokenExpires')
|
||||||
|
this.$bvModal.hide('modalSessionTimeOut')
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.$timer.stop('tokenExpires')
|
||||||
|
this.$emit('logout')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tokenExpiresInSeconds() {
|
||||||
|
return Math.floor((new Date(this.$store.state.tokenTime * 1000).getTime() - this.now) / 1000)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.$timer.stop('tokenExpires')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -92,6 +92,17 @@ describe('TransactionLink', () => {
|
|||||||
expect(toastSuccessSpy).toBeCalledWith('gdd_per_link.link-copied')
|
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', () => {
|
describe('qr code modal', () => {
|
||||||
|
|||||||
@ -35,9 +35,10 @@ describe('AuthLayout', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = Wrapper()
|
wrapper = Wrapper()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Mobile Version Start', () => {
|
describe('Mobile Version Start', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper.vm.mobileStart = true
|
wrapper.findComponent({ name: 'AuthMobileStart' }).vm.$emit('set-mobile-start', true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('has Component AuthMobileStart', () => {
|
it('has Component AuthMobileStart', () => {
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
</fade-transition>
|
</fade-transition>
|
||||||
</div>
|
</div>
|
||||||
<content-footer v-if="!$route.meta.hideFooter"></content-footer>
|
<content-footer v-if="!$route.meta.hideFooter"></content-footer>
|
||||||
|
<session-logout-timeout @logout="logout"></session-logout-timeout>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -39,6 +40,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Navbar from '@/components/Menu/Navbar.vue'
|
import Navbar from '@/components/Menu/Navbar.vue'
|
||||||
import Sidebar from '@/components/Menu/Sidebar.vue'
|
import Sidebar from '@/components/Menu/Sidebar.vue'
|
||||||
|
import SessionLogoutTimeout from '@/components/SessionLogoutTimeout.vue'
|
||||||
import { logout, transactionsQuery } from '@/graphql/queries'
|
import { logout, transactionsQuery } from '@/graphql/queries'
|
||||||
import ContentFooter from '@/components/ContentFooter.vue'
|
import ContentFooter from '@/components/ContentFooter.vue'
|
||||||
import { FadeTransition } from 'vue2-transitions'
|
import { FadeTransition } from 'vue2-transitions'
|
||||||
@ -49,6 +51,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
Navbar,
|
Navbar,
|
||||||
Sidebar,
|
Sidebar,
|
||||||
|
SessionLogoutTimeout,
|
||||||
ContentFooter,
|
ContentFooter,
|
||||||
FadeTransition,
|
FadeTransition,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -201,6 +201,12 @@
|
|||||||
"qrCode": "QR Code",
|
"qrCode": "QR Code",
|
||||||
"send_gdd": "GDD versenden",
|
"send_gdd": "GDD versenden",
|
||||||
"send_per_link": "GDD versenden per Link",
|
"send_per_link": "GDD versenden per Link",
|
||||||
|
"session": {
|
||||||
|
"extend": "Angemeldet bleiben",
|
||||||
|
"lightText": "Wenn du länger als 10 Minuten keine Aktion getätigt hast, wirst du aus Sicherheitsgründen abgemeldet.",
|
||||||
|
"logoutIn": "Abmelden in ",
|
||||||
|
"warningText": "Bist du noch da?"
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"language": {
|
"language": {
|
||||||
"changeLanguage": "Sprache ändern",
|
"changeLanguage": "Sprache ändern",
|
||||||
|
|||||||
@ -201,6 +201,12 @@
|
|||||||
"qrCode": "QR Code",
|
"qrCode": "QR Code",
|
||||||
"send_gdd": "GDD send",
|
"send_gdd": "GDD send",
|
||||||
"send_per_link": "GDD send via link",
|
"send_per_link": "GDD send via link",
|
||||||
|
"session": {
|
||||||
|
"extend": "Stay logged in",
|
||||||
|
"lightText": "If you have not performed any action for more than 10 minutes, you will be logged out for security reasons.",
|
||||||
|
"logoutIn": "Log out in ",
|
||||||
|
"warningText": "Are you still there?"
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"language": {
|
"language": {
|
||||||
"changeLanguage": "Change language",
|
"changeLanguage": "Change language",
|
||||||
|
|||||||
@ -18,6 +18,8 @@ import 'vue-loading-overlay/dist/vue-loading.css'
|
|||||||
|
|
||||||
import VueApollo from 'vue-apollo'
|
import VueApollo from 'vue-apollo'
|
||||||
|
|
||||||
|
import VueTimers from 'vue-timers'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install(Vue) {
|
install(Vue) {
|
||||||
Vue.use(GlobalComponents)
|
Vue.use(GlobalComponents)
|
||||||
@ -29,5 +31,6 @@ export default {
|
|||||||
Vue.use(FlatPickr)
|
Vue.use(FlatPickr)
|
||||||
Vue.use(Loading)
|
Vue.use(Loading)
|
||||||
Vue.use(VueApollo)
|
Vue.use(VueApollo)
|
||||||
|
Vue.use(VueTimers)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import Vuex from 'vuex'
|
|||||||
import createPersistedState from 'vuex-persistedstate'
|
import createPersistedState from 'vuex-persistedstate'
|
||||||
import { localeChanged } from 'vee-validate'
|
import { localeChanged } from 'vee-validate'
|
||||||
import i18n from '@/i18n.js'
|
import i18n from '@/i18n.js'
|
||||||
|
import jwtDecode from 'jwt-decode'
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
@ -26,6 +27,11 @@ export const mutations = {
|
|||||||
},
|
},
|
||||||
token: (state, token) => {
|
token: (state, token) => {
|
||||||
state.token = token
|
state.token = token
|
||||||
|
if (token) {
|
||||||
|
state.tokenTime = jwtDecode(token).exp
|
||||||
|
} else {
|
||||||
|
state.tokenTime = null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
newsletterState: (state, newsletterState) => {
|
newsletterState: (state, newsletterState) => {
|
||||||
state.newsletterState = newsletterState
|
state.newsletterState = newsletterState
|
||||||
@ -85,6 +91,7 @@ try {
|
|||||||
lastName: '',
|
lastName: '',
|
||||||
// username: '',
|
// username: '',
|
||||||
token: null,
|
token: null,
|
||||||
|
tokenTime: null,
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
newsletterState: null,
|
newsletterState: null,
|
||||||
hasElopage: false,
|
hasElopage: false,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import Vuex from 'vuex'
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import i18n from '@/i18n.js'
|
import i18n from '@/i18n.js'
|
||||||
import { localeChanged } from 'vee-validate'
|
import { localeChanged } from 'vee-validate'
|
||||||
|
import jwtDecode from 'jwt-decode'
|
||||||
|
|
||||||
jest.mock('vuex')
|
jest.mock('vuex')
|
||||||
jest.mock('@/i18n.js')
|
jest.mock('@/i18n.js')
|
||||||
@ -11,6 +12,11 @@ jest.mock('vee-validate', () => {
|
|||||||
localeChanged: jest.fn(),
|
localeChanged: jest.fn(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
jest.mock('jwt-decode', () => {
|
||||||
|
return jest.fn(() => {
|
||||||
|
return { exp: '1234' }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
i18n.locale = 'blubb'
|
i18n.locale = 'blubb'
|
||||||
|
|
||||||
@ -59,6 +65,25 @@ describe('Vuex store', () => {
|
|||||||
token(state, '1234')
|
token(state, '1234')
|
||||||
expect(state.token).toEqual('1234')
|
expect(state.token).toEqual('1234')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('token has a value', () => {
|
||||||
|
it('sets the state of tokenTime', () => {
|
||||||
|
const state = { token: null, tokenTime: null }
|
||||||
|
token(state, 'token')
|
||||||
|
expect(jwtDecode).toBeCalledWith('token')
|
||||||
|
expect(state.tokenTime).toEqual('1234')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('token has null value', () => {
|
||||||
|
it('sets the state of tokenTime to null', () => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
const state = { token: null, tokenTime: '123' }
|
||||||
|
token(state, null)
|
||||||
|
expect(jwtDecode).not.toBeCalled()
|
||||||
|
expect(state.tokenTime).toEqual(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('firstName', () => {
|
describe('firstName', () => {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import * as rules from 'vee-validate/dist/rules'
|
|||||||
import { messages } from 'vee-validate/dist/locale/en.json'
|
import { messages } from 'vee-validate/dist/locale/en.json'
|
||||||
|
|
||||||
import RegeneratorRuntime from 'regenerator-runtime'
|
import RegeneratorRuntime from 'regenerator-runtime'
|
||||||
|
import VueTimers from 'vue-timers'
|
||||||
|
|
||||||
import VueMoment from 'vue-moment'
|
import VueMoment from 'vue-moment'
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ global.localVue.use(Vuex)
|
|||||||
global.localVue.use(IconsPlugin)
|
global.localVue.use(IconsPlugin)
|
||||||
global.localVue.use(RegeneratorRuntime)
|
global.localVue.use(RegeneratorRuntime)
|
||||||
global.localVue.use(VueMoment)
|
global.localVue.use(VueMoment)
|
||||||
|
global.localVue.use(VueTimers)
|
||||||
global.localVue.component('validation-provider', ValidationProvider)
|
global.localVue.component('validation-provider', ValidationProvider)
|
||||||
global.localVue.component('validation-observer', ValidationObserver)
|
global.localVue.component('validation-observer', ValidationObserver)
|
||||||
// global.localVue.directive('click-outside', clickOutside)
|
// global.localVue.directive('click-outside', clickOutside)
|
||||||
|
|||||||
@ -9821,6 +9821,11 @@ jsprim@^1.2.2:
|
|||||||
json-schema "0.2.3"
|
json-schema "0.2.3"
|
||||||
verror "1.10.0"
|
verror "1.10.0"
|
||||||
|
|
||||||
|
jwt-decode@^3.1.2:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
|
||||||
|
integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==
|
||||||
|
|
||||||
killable@^1.0.1:
|
killable@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
|
||||||
@ -14472,6 +14477,11 @@ vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
|
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
|
||||||
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
|
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
|
||||||
|
|
||||||
|
vue-timers@^2.0.4:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-timers/-/vue-timers-2.0.4.tgz#7e1c443abf2109db5eeab6e62b0f5a47e94cf70b"
|
||||||
|
integrity sha512-QOEVdO4V4o9WjFG6C0Kn9tfdTeeECjqvEQozcQlfL1Tn8v0qx4uUPhTYoc1+s6qoJnSbu8f68x8+nm1ZEir0kw==
|
||||||
|
|
||||||
vue2-transitions@^0.2.3:
|
vue2-transitions@^0.2.3:
|
||||||
version "0.2.3"
|
version "0.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/vue2-transitions/-/vue2-transitions-0.2.3.tgz#69c9d75b1db05f231b80980c03459d68490ba27d"
|
resolved "https://registry.yarnpkg.com/vue2-transitions/-/vue2-transitions-0.2.3.tgz#69c9d75b1db05f231b80980c03459d68490ba27d"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gradido",
|
"name": "gradido",
|
||||||
"version": "1.10.0",
|
"version": "1.10.1",
|
||||||
"description": "Gradido",
|
"description": "Gradido",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"repository": "git@github.com:gradido/gradido.git",
|
"repository": "git@github.com:gradido/gradido.git",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user