fix(front-end): fix current actor not being set on first access when relogging

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2023-12-12 11:39:27 +01:00
parent 820d4adb69
commit ae466b879c
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
4 changed files with 35 additions and 30 deletions

View file

@ -70,6 +70,7 @@ import { CONFIG } from "@/graphql/config";
import { IConfig } from "@/types/config.model"; import { IConfig } from "@/types/config.model";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import RouteName from "@/router/name"; import RouteName from "@/router/name";
import { useLazyCurrentUserIdentities } from "./composition/apollo/actor";
const { result: configResult } = useQuery<{ config: IConfig }>( const { result: configResult } = useQuery<{ config: IConfig }>(
CONFIG, CONFIG,
@ -138,11 +139,15 @@ interval.value = window.setInterval(async () => {
} }
}, 60000) as unknown as number; }, 60000) as unknown as number;
const { load: loadIdentities } = useLazyCurrentUserIdentities();
onBeforeMount(async () => { onBeforeMount(async () => {
console.debug("Before mount App"); console.debug("Before mount App");
if (initializeCurrentUser()) { if (initializeCurrentUser()) {
try { try {
await initializeCurrentActor(); const result = await loadIdentities();
if (!result) return;
await initializeCurrentActor(result.loggedUser.actors);
} catch (err) { } catch (err) {
if (err instanceof NoIdentitiesException) { if (err instanceof NoIdentitiesException) {
await router.push({ await router.push({
@ -223,7 +228,7 @@ const initializeCurrentUser = () => {
console.debug("Initialized current user", userData); console.debug("Initialized current user", userData);
return true; return true;
} }
console.debug("Failed to initialize current user"); console.debug("We don't seem to have a currently logged-in user");
return false; return false;
}; };

View file

@ -6,7 +6,7 @@ import {
} from "@/graphql/actor"; } from "@/graphql/actor";
import { IPerson } from "@/types/actor"; import { IPerson } from "@/types/actor";
import { ICurrentUser } from "@/types/current-user.model"; import { ICurrentUser } from "@/types/current-user.model";
import { useQuery } from "@vue/apollo-composable"; import { useLazyQuery, useQuery } from "@vue/apollo-composable";
import { computed, Ref, unref } from "vue"; import { computed, Ref, unref } from "vue";
import { useCurrentUserClient } from "./user"; import { useCurrentUserClient } from "./user";
@ -22,6 +22,12 @@ export function useCurrentActorClient() {
return { currentActor, error, loading }; return { currentActor, error, loading };
} }
export function useLazyCurrentUserIdentities() {
return useLazyQuery<{
loggedUser: Pick<ICurrentUser, "actors">;
}>(IDENTITIES);
}
export function useCurrentUserIdentities() { export function useCurrentUserIdentities() {
const { currentUser } = useCurrentUserClient(); const { currentUser } = useCurrentUserClient();

View file

@ -1,14 +1,8 @@
import { AUTH_USER_ACTOR_ID } from "@/constants"; import { AUTH_USER_ACTOR_ID } from "@/constants";
import { UPDATE_CURRENT_ACTOR_CLIENT, IDENTITIES } from "@/graphql/actor"; import { UPDATE_CURRENT_ACTOR_CLIENT } from "@/graphql/actor";
import { IPerson } from "@/types/actor"; import { IPerson } from "@/types/actor";
import { ICurrentUser } from "@/types/current-user.model";
import { apolloClient } from "@/vue-apollo"; import { apolloClient } from "@/vue-apollo";
import { import { provideApolloClient, useMutation } from "@vue/apollo-composable";
provideApolloClient,
useLazyQuery,
useMutation,
} from "@vue/apollo-composable";
import { computed } from "vue";
export class NoIdentitiesException extends Error {} export class NoIdentitiesException extends Error {}
@ -38,38 +32,31 @@ export async function changeIdentity(identity: IPerson): Promise<void> {
}); });
} }
const { load: loadIdentities } = provideApolloClient(apolloClient)(() =>
useLazyQuery<{ loggedUser: Pick<ICurrentUser, "actors"> }>(IDENTITIES)
);
/** /**
* We fetch from localStorage the latest actor ID used, * We fetch from localStorage the latest actor ID used,
* then fetch the current identities to set in cache * then fetch the current identities to set in cache
* the current identity used * the current identity used
*/ */
export async function initializeCurrentActor(): Promise<void> { export async function initializeCurrentActor(
identities: IPerson[] | undefined
): Promise<void> {
const actorId = localStorage.getItem(AUTH_USER_ACTOR_ID); const actorId = localStorage.getItem(AUTH_USER_ACTOR_ID);
console.debug("Initializing current actor", actorId); console.debug("Initializing current actor", actorId);
try { try {
const result = await loadIdentities(); if (!identities) {
if (!result) return; console.debug("Failed to load user's identities", identities);
return;
}
console.debug("got identities", result); if (identities && identities.length < 1) {
const identities = computed(() => result.loggedUser?.actors);
console.debug(
"initializing current actor based on identities",
identities.value
);
if (identities.value && identities.value.length < 1) {
console.warn("Logged user has no identities!"); console.warn("Logged user has no identities!");
throw new NoIdentitiesException(); throw new NoIdentitiesException();
} }
const activeIdentity = const activeIdentity =
(identities.value || []).find( (identities || []).find(
(identity: IPerson | undefined) => identity?.id === actorId (identity: IPerson | undefined) => identity?.id === actorId
) || ((identities.value || [])[0] as IPerson); ) || ((identities || [])[0] as IPerson);
if (activeIdentity) { if (activeIdentity) {
await changeIdentity(activeIdentity); await changeIdentity(activeIdentity);

View file

@ -143,6 +143,7 @@ import { LoginError, LoginErrorCode } from "@/types/enums";
import { useCurrentUserClient } from "@/composition/apollo/user"; import { useCurrentUserClient } from "@/composition/apollo/user";
import { useHead } from "@unhead/vue"; import { useHead } from "@unhead/vue";
import { enumTransformer, useRouteQuery } from "vue-use-route-query"; import { enumTransformer, useRouteQuery } from "vue-use-route-query";
import { useLazyCurrentUserIdentities } from "@/composition/apollo/actor";
const { t } = useI18n({ useScope: "global" }); const { t } = useI18n({ useScope: "global" });
const router = useRouter(); const router = useRouter();
@ -235,12 +236,17 @@ const loginAction = (e: Event) => {
}); });
}; };
const { load: loadIdentities } = useLazyCurrentUserIdentities();
const { onDone: onCurrentUserMutationDone, mutate: updateCurrentUserMutation } = const { onDone: onCurrentUserMutationDone, mutate: updateCurrentUserMutation } =
useMutation(UPDATE_CURRENT_USER_CLIENT); useMutation(UPDATE_CURRENT_USER_CLIENT);
onCurrentUserMutationDone(async () => { onCurrentUserMutationDone(async () => {
console.debug("Current user mutation done, now setuping actors…");
try { try {
await initializeCurrentActor(); const result = await loadIdentities();
if (!result) return;
await initializeCurrentActor(result.loggedUser.actors);
} catch (err: any) { } catch (err: any) {
if (err instanceof NoIdentitiesException && currentUser.value) { if (err instanceof NoIdentitiesException && currentUser.value) {
await router.push({ await router.push({
@ -257,6 +263,7 @@ onCurrentUserMutationDone(async () => {
}); });
const setupClientUserAndActors = async (login: ILogin): Promise<void> => { const setupClientUserAndActors = async (login: ILogin): Promise<void> => {
console.debug("Setuping client user and actors");
updateCurrentUserMutation({ updateCurrentUserMutation({
id: login.user.id, id: login.user.id,
email: credentials.email, email: credentials.email,
@ -298,7 +305,7 @@ onMounted(() => {
if (currentUser.value?.isLoggedIn) { if (currentUser.value?.isLoggedIn) {
console.debug( console.debug(
"Current user is already logged-in, redirecting to Homepage", "Current user is already logged-in, redirecting to Homepage",
currentUser currentUser.value
); );
router.push("/"); router.push("/");
} }