release v2.0.0 #4

Merged
crimsen merged 481 commits from develop into master 2024-01-18 15:15:08 +00:00
2 changed files with 120 additions and 21 deletions
Showing only changes of commit 69e68b92f9 - Show all commits

View File

@ -16,22 +16,42 @@
{{ session.platform }} {{ session.platform }}
</div> </div>
</div> </div>
<div class="row"> <div class="row" v-if="!isEdit">
<div class="col-xs-12 col-sm-6"> <div class="col-xs-12 col-sm-6">
Lebenszeit: Lebenszeit:
{{ session.lifetime }} {{ session.lifetime }}
</div> </div>
<div class="col-xs-12 col-sm-6">Läuft aus: {{ session.expires | dateTime(true) }}</div> <div class="col-xs-12 col-sm-6">Läuft aus: {{ session.expires | dateTime(true) }}</div>
</div> </div>
<div class="row q-my-sm" v-else>
<q-input
class="col-xs-12 col-sm-6 q-px-sm"
v-model="computedLifetime"
type="number"
label="Zeit"
filled
/>
<q-select
class="col-xs-12 col-sm-6 q-px-sm"
:options="options"
v-model="option"
filled
/>
</div>
</q-card-section> </q-card-section>
<q-card-actions align="right"> <q-card-actions align="right" v-if="!isEdit">
<q-btn flat round dense icon="mdi-pencil" @click="edit(true)" />
<q-btn flat round dense icon="mdi-delete" @click="deleteSession(session.token)" /> <q-btn flat round dense icon="mdi-delete" @click="deleteSession(session.token)" />
</q-card-actions> </q-card-actions>
<q-card-actions align="right" v-else>
<q-btn flat dense label="Abbrechen" @click="edit(false)" />
<q-btn flat dense label="Speichern" @click="save" />
</q-card-actions>
</q-card> </q-card>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from '@vue/composition-api'; import { defineComponent, ref, computed } from '@vue/composition-api';
import { Store } from 'vuex'; import { Store } from 'vuex';
import { StateInterface } from 'src/store'; import { StateInterface } from 'src/store';
@ -39,12 +59,14 @@ export default defineComponent({
name: 'Sessions', name: 'Sessions',
props: { props: {
session: { session: {
required: true required: true,
}
}, },
setup(_, { root }) { },
setup(props: {session: FG.Session}, { root }) {
const store = <Store<StateInterface>>root.$store; const store = <Store<StateInterface>>root.$store;
const options = ref(['Minuten', 'Stunden', 'Tage']);
const option = ref<string>(options.value[0]);
const lifetime = ref(0);
function getBrowserIcon(browser: string) { function getBrowserIcon(browser: string) {
return browser == 'firefox' return browser == 'firefox'
? 'mdi-firefox' ? 'mdi-firefox'
@ -70,7 +92,7 @@ export default defineComponent({
} }
function deleteSession(token: string) { function deleteSession(token: string) {
store.dispatch('session/deleteSession', token).catch(error => { store.dispatch('session/deleteSession', token).catch((error) => {
console.warn(error); console.warn(error);
}); });
} }
@ -78,12 +100,67 @@ export default defineComponent({
return store.state.session.currentSession?.token === token; return store.state.session.currentSession?.token === token;
} }
const isEdit = ref(false);
const computedLifetime = computed({
get: () => {
switch (option.value) {
case options.value[0]:
return (lifetime.value / 60).toFixed(2);
case options.value[1]:
return (lifetime.value / (60 * 60)).toFixed(2);
case options.value[2]:
return (lifetime.value / (60 * 60 * 24)).toFixed(2);
}
},
set: (val) => {
if (val) {
switch (option.value) {
case options.value[0]:
lifetime.value = parseFloat(val) * 60;
break;
case options.value[1]:
lifetime.value = parseFloat(val) * 60 * 60;
break;
case options.value[2]:
lifetime.value = parseFloat(val) * 60 * 60 * 24;
break;
}
}
},
});
function edit(value: boolean) {
lifetime.value = props.session.lifetime;
isEdit.value = value;
}
function save() {
console.log(lifetime.value);
isEdit.value = false;
void store
.dispatch(
'session/updateSession',
{lifetime: lifetime.value, token: props.session.token}
)
.catch((error) => {
console.log(error);
});
}
return { return {
getBrowserIcon, getBrowserIcon,
getPlatformIcon, getPlatformIcon,
isThisSession, isThisSession,
deleteSession deleteSession,
isEdit,
edit,
options,
option,
lifetime,
computedLifetime,
save,
}; };
} },
}); });
</script> </script>

View File

@ -25,7 +25,7 @@ function loadCurrentSession() {
const state: SessionInterface = { const state: SessionInterface = {
sessions: [], sessions: [],
currentSession: loadCurrentSession() || undefined, currentSession: loadCurrentSession() || undefined,
loading: false loading: false,
}; };
const mutations: MutationTree<SessionInterface> = { const mutations: MutationTree<SessionInterface> = {
@ -42,7 +42,13 @@ const mutations: MutationTree<SessionInterface> = {
}, },
setLoading(state, value: boolean) { setLoading(state, value: boolean) {
state.loading = value; state.loading = value;
},
updateSession(state, session: FG.Session) {
const index = state.sessions.findIndex((x) => x.token == session.token);
if (index > -1) {
state.sessions[index] = session;
} }
},
}; };
const actions: ActionTree<SessionInterface, StateInterface> = { const actions: ActionTree<SessionInterface, StateInterface> = {
@ -59,7 +65,7 @@ const actions: ActionTree<SessionInterface, StateInterface> = {
commit('setCurrentSession', response.data.session); commit('setCurrentSession', response.data.session);
commit('user/setCurrentUser', response.data.user, { root: true }); commit('user/setCurrentUser', response.data.user, { root: true });
commit('user/setCurrentPermissions', response.data.permissions, { commit('user/setCurrentPermissions', response.data.permissions, {
root: true root: true,
}); });
}) })
.catch((error: AxiosError) => { .catch((error: AxiosError) => {
@ -72,7 +78,7 @@ const actions: ActionTree<SessionInterface, StateInterface> = {
*/ */
logout({ dispatch, rootState }) { logout({ dispatch, rootState }) {
if (rootState.session.currentSession) { if (rootState.session.currentSession) {
dispatch('deleteSession', rootState.session.currentSession.token).catch(error => { dispatch('deleteSession', rootState.session.currentSession.token).catch((error) => {
console.log(error); console.log(error);
void dispatch('clearCurrent', false); void dispatch('clearCurrent', false);
}); });
@ -91,7 +97,7 @@ const actions: ActionTree<SessionInterface, StateInterface> = {
if (token === rootState.session.currentSession?.token) { if (token === rootState.session.currentSession?.token) {
void dispatch('clearCurrent', false); void dispatch('clearCurrent', false);
} else { } else {
dispatch('getSessions').catch(error => { dispatch('getSessions').catch((error) => {
throw error; throw error;
}); });
} }
@ -110,7 +116,7 @@ const actions: ActionTree<SessionInterface, StateInterface> = {
void Router.push({ void Router.push({
name: 'login', name: 'login',
query: redirect ? { redirect: Router.currentRoute.fullPath } : {}, query: redirect ? { redirect: Router.currentRoute.fullPath } : {},
params: { logout: 'true' } params: { logout: 'true' },
}).then(() => { }).then(() => {
commit('clearCurrentSession'); commit('clearCurrentSession');
commit('user/clearCurrentUser', null, { root: true }); commit('user/clearCurrentUser', null, { root: true });
@ -126,7 +132,7 @@ const actions: ActionTree<SessionInterface, StateInterface> = {
axios axios
.get('/auth') .get('/auth')
.then((response: AxiosResponse<FG.Session[]>) => { .then((response: AxiosResponse<FG.Session[]>) => {
response.data.forEach(session => { response.data.forEach((session) => {
session.expires = new Date(session.expires); session.expires = new Date(session.expires);
}); });
commit('setSessions', response.data); commit('setSessions', response.data);
@ -137,13 +143,29 @@ const actions: ActionTree<SessionInterface, StateInterface> = {
commit('setCurrentSession', currentSession); commit('setCurrentSession', currentSession);
} }
}) })
.catch(error => { .catch((error) => {
throw error; throw error;
}) })
.finally(() => { .finally(() => {
commit('setLoading', false); commit('setLoading', false);
}); });
}, },
updateSession({ commit, state }, data: { lifetime: number; token: string }) {
commit('setLoading', true);
axios
.put(`auth/${data.token}`, { value: data.lifetime })
.then((response: AxiosResponse<FG.Session>) => {
response.data.expires = new Date(response.data.expires);
if (state.currentSession?.token == response.data.token) {
commit('setCurrentSession', response.data);
}
})
.catch((err) => console.log(err))
.finally(() => {
commit('setLoading', false);
});
console.log('updateSession', data);
},
requestPasswordReset({}, data) { requestPasswordReset({}, data) {
return axios.post('/auth/reset', data); return axios.post('/auth/reset', data);
}, },
@ -151,7 +173,7 @@ const actions: ActionTree<SessionInterface, StateInterface> = {
return axios.post('/auth/reset', data).catch((error: AxiosError) => { return axios.post('/auth/reset', data).catch((error: AxiosError) => {
return Promise.reject(error.response); return Promise.reject(error.response);
}); });
} },
}; };
const getters: GetterTree<SessionInterface, StateInterface> = { const getters: GetterTree<SessionInterface, StateInterface> = {
@ -163,7 +185,7 @@ const getters: GetterTree<SessionInterface, StateInterface> = {
}, },
loading(state) { loading(state) {
return state.loading; return state.loading;
} },
}; };
const sessions: Module<SessionInterface, StateInterface> = { const sessions: Module<SessionInterface, StateInterface> = {
@ -171,7 +193,7 @@ const sessions: Module<SessionInterface, StateInterface> = {
state, state,
mutations, mutations,
actions, actions,
getters getters,
}; };
export default sessions; export default sessions;