Improve session expiry handling

- Reload configuration and show login dialog when any request fails with "login required"
- Current map position etc is lost, more work needed here
This commit is contained in:
James Lyne 2021-09-30 20:13:23 +01:00
parent 31c1148c38
commit 6c0837deae
3 changed files with 31 additions and 16 deletions

View File

@ -39,9 +39,9 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import {defineComponent} from "@vue/runtime-core"; import {defineComponent, onMounted} from "@vue/runtime-core";
import {useStore} from "@/store"; import {useStore} from "@/store";
import {computed, ref, watch} from "vue"; import {computed, nextTick, ref, watchEffect} from "vue";
import {ActionTypes} from "@/store/action-types"; import {ActionTypes} from "@/store/action-types";
import {MutationTypes} from "@/store/mutation-types"; import {MutationTypes} from "@/store/mutation-types";
import {notify} from "@kyvg/vue3-notification"; import {notify} from "@kyvg/vue3-notification";
@ -68,13 +68,17 @@ export default defineComponent({
invalid = ref(false), invalid = ref(false),
error = ref(null); error = ref(null);
watch(loginModalVisible, (newValue) => { onMounted(() => {
if(newValue) { watchEffect(async () => {
requestAnimationFrame(() => usernameField.value!.focus()); await nextTick();
} else {
loginUsername.value = ''; if(loginModalVisible.value) {
loginPassword.value = ''; usernameField.value!.focus();
} } else {
loginUsername.value = '';
loginPassword.value = '';
}
});
}); });
const login = async () => { const login = async () => {

View File

@ -59,7 +59,7 @@ export default class DynmapMapProvider extends MapProvider {
this.markersAbort = new AbortController(); this.markersAbort = new AbortController();
const response = await DynmapMapProvider.getJSON(url, this.markersAbort.signal); const response = await this.getJSON(url, this.markersAbort.signal);
const sets: Map<string, LiveAtlasMarkerSet> = new Map(); const sets: Map<string, LiveAtlasMarkerSet> = new Map();
response.sets = response.sets || {}; response.sets = response.sets || {};
@ -94,11 +94,7 @@ export default class DynmapMapProvider extends MapProvider {
this.configurationAbort = new AbortController(); this.configurationAbort = new AbortController();
const response = await DynmapMapProvider.getJSON(this.config.dynmap!.configuration, this.configurationAbort.signal); const response = await this.getJSON(this.config.dynmap!.configuration, this.configurationAbort.signal);
if(response.error === 'login-required') {
this.store.commit(MutationTypes.SET_LOGIN_REQUIRED, true);
}
if (response.error) { if (response.error) {
throw new Error(response.error); throw new Error(response.error);
@ -134,7 +130,7 @@ export default class DynmapMapProvider extends MapProvider {
this.updateAbort = new AbortController(); this.updateAbort = new AbortController();
const response = await DynmapMapProvider.getJSON(url, this.updateAbort.signal); const response = await this.getJSON(url, this.updateAbort.signal);
const players: Set<LiveAtlasPlayer> = new Set(), const players: Set<LiveAtlasPlayer> = new Set(),
updates = buildUpdates(response.updates || [], this.updateTimestamp), updates = buildUpdates(response.updates || [], this.updateTimestamp),
worldState = { worldState = {
@ -389,4 +385,15 @@ export default class DynmapMapProvider extends MapProvider {
this.markersAbort.abort(); this.markersAbort.abort();
} }
} }
protected async getJSON(url: string, signal: AbortSignal) {
return MapProvider.fetchJSON(url, {signal, credentials: 'include'}).then(response => {
if(response.error === 'login-required') {
this.store.commit(MutationTypes.SET_LOGIN_REQUIRED, true);
throw new Error("Login required");
}
return response;
});
}
} }

View File

@ -616,6 +616,10 @@ export const mutations: MutationTree<State> & Mutations = {
}, },
[MutationTypes.SET_LOGIN_REQUIRED](state: State, payload: boolean): void { [MutationTypes.SET_LOGIN_REQUIRED](state: State, payload: boolean): void {
if(payload) {
state.loggedIn = false;
}
state.loginRequired = payload; state.loginRequired = payload;
}, },