Merge branch 'session-issues' into 'master'
Various issues Closes #809 See merge request framasoft/mobilizon!1030
This commit is contained in:
commit
b4d1252ece
@ -104,6 +104,11 @@ export async function refreshAccessToken(
|
|||||||
|
|
||||||
const refreshToken = localStorage.getItem(AUTH_REFRESH_TOKEN);
|
const refreshToken = localStorage.getItem(AUTH_REFRESH_TOKEN);
|
||||||
|
|
||||||
|
if (!refreshToken) {
|
||||||
|
console.debug("Refresh token not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
console.log("Refreshing access token.");
|
console.log("Refreshing access token.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -118,6 +123,7 @@ export async function refreshAccessToken(
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.debug("Failed to refresh token");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import LazyImageWrapper from "../Image/LazyImageWrapper.vue";
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class EventBanner extends Vue {
|
export default class EventBanner extends Vue {
|
||||||
@Prop({ required: true, default: null, type: Object as PropType<IMedia> })
|
@Prop({ default: null, type: Object as PropType<IMedia> })
|
||||||
picture!: IMedia | null;
|
picture!: IMedia | null;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -216,7 +216,7 @@ import RouteName from "../router/name";
|
|||||||
loggedUser: {
|
loggedUser: {
|
||||||
query: USER_SETTINGS,
|
query: USER_SETTINGS,
|
||||||
skip() {
|
skip() {
|
||||||
return this.currentUser.isLoggedIn === false;
|
return !this.currentUser || this.currentUser.isLoggedIn === false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { ServerParseError } from "@apollo/client/link/http";
|
|
||||||
import { ServerError } from "@apollo/client/link/utils";
|
|
||||||
|
|
||||||
function isServerError(
|
|
||||||
err: Error | ServerError | ServerParseError | undefined
|
|
||||||
): err is ServerError {
|
|
||||||
return !!err && (err as ServerError).statusCode !== undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { isServerError };
|
|
@ -95,14 +95,17 @@ export async function initializeCurrentActor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function logout(
|
export async function logout(
|
||||||
apollo: ApolloClient<NormalizedCacheObject>
|
apollo: ApolloClient<NormalizedCacheObject>,
|
||||||
|
performServerLogout = true
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
if (performServerLogout) {
|
||||||
await apollo.mutate({
|
await apollo.mutate({
|
||||||
mutation: LOGOUT,
|
mutation: LOGOUT,
|
||||||
variables: {
|
variables: {
|
||||||
refreshToken: localStorage.getItem(AUTH_REFRESH_TOKEN),
|
refreshToken: localStorage.getItem(AUTH_REFRESH_TOKEN),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await apollo.mutate({
|
await apollo.mutate({
|
||||||
mutation: UPDATE_CURRENT_USER_CLIENT,
|
mutation: UPDATE_CURRENT_USER_CLIENT,
|
||||||
|
@ -592,6 +592,7 @@ import { eventMetaDataList } from "../../services/EventMetadata";
|
|||||||
},
|
},
|
||||||
skip() {
|
skip() {
|
||||||
return (
|
return (
|
||||||
|
!this.currentActor.id ||
|
||||||
!this.event?.attributedTo ||
|
!this.event?.attributedTo ||
|
||||||
!this.event?.attributedTo?.preferredUsername
|
!this.event?.attributedTo?.preferredUsername
|
||||||
);
|
);
|
||||||
|
@ -372,7 +372,9 @@ import Subtitle from "../components/Utils/Subtitle.vue";
|
|||||||
currentUser: CURRENT_USER_CLIENT,
|
currentUser: CURRENT_USER_CLIENT,
|
||||||
loggedUser: {
|
loggedUser: {
|
||||||
query: USER_SETTINGS,
|
query: USER_SETTINGS,
|
||||||
fetchPolicy: "no-cache",
|
skip() {
|
||||||
|
return !this.currentUser || this.currentUser.isLoggedIn === false;
|
||||||
|
},
|
||||||
error() {
|
error() {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
<!-- The following should just be replaced with the SearchField component but it fails for some reason -->
|
<!-- The following should just be replaced with the SearchField component but it fails for some reason -->
|
||||||
<form @submit="enter">
|
<form @submit.prevent="enter">
|
||||||
<b-field class="search">
|
<b-field class="search">
|
||||||
<b-input
|
<b-input
|
||||||
expanded
|
expanded
|
||||||
|
@ -11,8 +11,8 @@ import {
|
|||||||
NormalizedCacheObject,
|
NormalizedCacheObject,
|
||||||
split,
|
split,
|
||||||
} from "@apollo/client/core";
|
} from "@apollo/client/core";
|
||||||
|
import { RetryLink } from "@apollo/client/link/retry";
|
||||||
import buildCurrentUserResolver from "@/apollo/user";
|
import buildCurrentUserResolver from "@/apollo/user";
|
||||||
import { isServerError } from "@/types/apollo";
|
|
||||||
import { AUTH_ACCESS_TOKEN } from "@/constants";
|
import { AUTH_ACCESS_TOKEN } from "@/constants";
|
||||||
import { logout } from "@/utils/auth";
|
import { logout } from "@/utils/auth";
|
||||||
import { Socket as PhoenixSocket } from "phoenix";
|
import { Socket as PhoenixSocket } from "phoenix";
|
||||||
@ -61,9 +61,17 @@ const authMiddleware = new ApolloLink((operation, forward) => {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const customFetch = async (uri: string, options: any) => {
|
||||||
|
const response = await fetch(uri, options);
|
||||||
|
if (response.status >= 400) {
|
||||||
|
return Promise.reject(response.status);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
const uploadLink = createLink({
|
const uploadLink = createLink({
|
||||||
uri: httpEndpoint,
|
uri: httpEndpoint,
|
||||||
fetch,
|
fetch: customFetch,
|
||||||
});
|
});
|
||||||
|
|
||||||
const phoenixSocket = new PhoenixSocket(wsEndpoint, {
|
const phoenixSocket = new PhoenixSocket(wsEndpoint, {
|
||||||
@ -97,17 +105,35 @@ const resolvePendingRequests = () => {
|
|||||||
pendingRequests = [];
|
pendingRequests = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isAuthError = (graphQLError: GraphQLError | undefined) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
return graphQLError && [403, 401].includes(graphQLError.status_code);
|
||||||
|
};
|
||||||
|
|
||||||
const errorLink = onError(
|
const errorLink = onError(
|
||||||
({ graphQLErrors, networkError, forward, operation }) => {
|
({ graphQLErrors, networkError, forward, operation }) => {
|
||||||
if (isServerError(networkError) && networkError?.statusCode === 401) {
|
console.debug("We have an apollo error", [graphQLErrors, networkError]);
|
||||||
|
if (
|
||||||
|
graphQLErrors?.some((graphQLError) => isAuthError(graphQLError)) ||
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
networkError === 401
|
||||||
|
) {
|
||||||
|
console.debug("It's a authorization error (statusCode 401)");
|
||||||
let forwardOperation;
|
let forwardOperation;
|
||||||
|
|
||||||
if (!isRefreshing) {
|
if (!isRefreshing) {
|
||||||
|
console.debug("Setting isRefreshing to true");
|
||||||
isRefreshing = true;
|
isRefreshing = true;
|
||||||
|
|
||||||
forwardOperation = fromPromise(
|
forwardOperation = fromPromise(
|
||||||
refreshAccessToken(apolloClient)
|
refreshAccessToken(apolloClient)
|
||||||
.then(() => {
|
.then((res) => {
|
||||||
|
if (res !== true) {
|
||||||
|
// failed to refresh the token
|
||||||
|
throw "Failed to refresh the token";
|
||||||
|
}
|
||||||
resolvePendingRequests();
|
resolvePendingRequests();
|
||||||
|
|
||||||
const context = operation.getContext();
|
const context = operation.getContext();
|
||||||
@ -121,9 +147,11 @@ const errorLink = onError(
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch((e) => {
|
||||||
|
console.debug("Something failed, let's logout", e);
|
||||||
pendingRequests = [];
|
pendingRequests = [];
|
||||||
logout(apolloClient);
|
// don't perform a logout since we don't have any working access/refresh tokens
|
||||||
|
logout(apolloClient, false);
|
||||||
return;
|
return;
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@ -161,7 +189,12 @@ const errorLink = onError(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const fullLink = authMiddleware.concat(errorLink).concat(link);
|
const retryLink = new RetryLink();
|
||||||
|
|
||||||
|
const fullLink = authMiddleware
|
||||||
|
.concat(retryLink)
|
||||||
|
.concat(errorLink)
|
||||||
|
.concat(link);
|
||||||
|
|
||||||
const cache = new InMemoryCache({
|
const cache = new InMemoryCache({
|
||||||
addTypename: true,
|
addTypename: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user