mirror of
https://framagit.org/framasoft/mobilizon.git
synced 2024-12-30 11:55:26 +00:00
Merge branch 'refactor-refreshing-token' into 'master'
Refactor refreshing token See merge request framasoft/mobilizon!1005
This commit is contained in:
commit
d0ac3de354
5 changed files with 63 additions and 87 deletions
|
@ -129,6 +129,7 @@ import RouteName from "../../router/name";
|
|||
import { changeIdentity } from "../../utils/auth";
|
||||
import identityEditionMixin from "../../mixins/identityEdition";
|
||||
import { ApolloCache, FetchResult } from "@apollo/client/core";
|
||||
import { ActorType } from "@/types/enums";
|
||||
|
||||
@Component({
|
||||
apollo: {
|
||||
|
@ -180,8 +181,18 @@ export default class Register extends mixins(identityEditionMixin) {
|
|||
});
|
||||
|
||||
if (identitiesData && localData) {
|
||||
identitiesData.identities.push(localData.registerPerson);
|
||||
store.writeQuery({ query: IDENTITIES, data: identitiesData });
|
||||
const newPersonData = {
|
||||
...localData.registerPerson,
|
||||
type: ActorType.PERSON,
|
||||
};
|
||||
|
||||
store.writeQuery({
|
||||
query: IDENTITIES,
|
||||
data: {
|
||||
...identitiesData,
|
||||
identities: [...identitiesData.identities, newPersonData],
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1309,29 +1309,6 @@ export default class Event extends EventMixin {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get shouldShowParticipationButton(): boolean {
|
||||
// So that people can cancel their participation
|
||||
if (
|
||||
this.actorIsParticipant ||
|
||||
(this.config.anonymous.participation.allowed &&
|
||||
this.anonymousParticipation)
|
||||
)
|
||||
return true;
|
||||
|
||||
// You can participate to draft or cancelled events
|
||||
if (this.event.draft || this.event.status === EventStatus.CANCELLED)
|
||||
return false;
|
||||
|
||||
// Organizer can't participate
|
||||
if (this.actorIsOrganizer) return false;
|
||||
|
||||
// If capacity is OK
|
||||
if (this.eventCapacityOK) return true;
|
||||
|
||||
// Else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
@ -259,7 +259,7 @@ export default class Login extends Vue {
|
|||
await initializeCurrentActor(this.$apollo.provider.defaultClient);
|
||||
} catch (err) {
|
||||
if (err instanceof NoIdentitiesException) {
|
||||
this.$router.push({
|
||||
await this.$router.push({
|
||||
name: RouteName.REGISTER_PROFILE,
|
||||
params: {
|
||||
email: this.currentUser.email,
|
||||
|
|
|
@ -6,9 +6,9 @@ import {
|
|||
ApolloClient,
|
||||
ApolloLink,
|
||||
defaultDataIdFromObject,
|
||||
fromPromise,
|
||||
InMemoryCache,
|
||||
NormalizedCacheObject,
|
||||
Observable,
|
||||
split,
|
||||
} from "@apollo/client/core";
|
||||
import buildCurrentUserResolver from "@/apollo/user";
|
||||
|
@ -31,8 +31,8 @@ import { GraphQLError } from "graphql";
|
|||
// Install the vue plugin
|
||||
Vue.use(VueApollo);
|
||||
|
||||
let refreshingTokenPromise: Promise<boolean> | undefined;
|
||||
let alreadyRefreshedToken = false;
|
||||
let isRefreshing = false;
|
||||
let pendingRequests: any[] = [];
|
||||
|
||||
// Endpoints
|
||||
const httpServer = GRAPHQL_API_ENDPOINT || "http://localhost:4000";
|
||||
|
@ -92,32 +92,55 @@ const link = split(
|
|||
uploadLink
|
||||
);
|
||||
|
||||
const resolvePendingRequests = () => {
|
||||
pendingRequests.map((callback) => callback());
|
||||
pendingRequests = [];
|
||||
};
|
||||
|
||||
const errorLink = onError(
|
||||
({ graphQLErrors, networkError, forward, operation }) => {
|
||||
if (
|
||||
isServerError(networkError) &&
|
||||
networkError?.statusCode === 401 &&
|
||||
!alreadyRefreshedToken
|
||||
) {
|
||||
if (!refreshingTokenPromise)
|
||||
refreshingTokenPromise = refreshAccessToken(apolloClient);
|
||||
if (isServerError(networkError) && networkError?.statusCode === 401) {
|
||||
let forwardOperation;
|
||||
|
||||
return promiseToObservable(refreshingTokenPromise).flatMap(() => {
|
||||
refreshingTokenPromise = undefined;
|
||||
alreadyRefreshedToken = true;
|
||||
if (!isRefreshing) {
|
||||
isRefreshing = true;
|
||||
|
||||
const context = operation.getContext();
|
||||
const oldHeaders = context.headers;
|
||||
forwardOperation = fromPromise(
|
||||
refreshAccessToken(apolloClient)
|
||||
.then(() => {
|
||||
resolvePendingRequests();
|
||||
|
||||
operation.setContext({
|
||||
headers: {
|
||||
...oldHeaders,
|
||||
authorization: generateTokenHeader(),
|
||||
},
|
||||
});
|
||||
const context = operation.getContext();
|
||||
const oldHeaders = context.headers;
|
||||
|
||||
return forward(operation);
|
||||
});
|
||||
operation.setContext({
|
||||
headers: {
|
||||
...oldHeaders,
|
||||
authorization: generateTokenHeader(),
|
||||
},
|
||||
});
|
||||
return true;
|
||||
})
|
||||
.catch(() => {
|
||||
pendingRequests = [];
|
||||
logout(apolloClient);
|
||||
return;
|
||||
})
|
||||
.finally(() => {
|
||||
isRefreshing = false;
|
||||
})
|
||||
).filter((value) => Boolean(value));
|
||||
} else {
|
||||
forwardOperation = fromPromise(
|
||||
new Promise((resolve) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
pendingRequests.push(() => resolve());
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return forwardOperation.flatMap(() => forward(operation));
|
||||
}
|
||||
|
||||
if (graphQLErrors) {
|
||||
|
@ -171,41 +194,3 @@ export default new VueApollo({
|
|||
console.error(error);
|
||||
},
|
||||
});
|
||||
|
||||
// Thanks: https://github.com/apollographql/apollo-link/issues/747#issuecomment-502676676
|
||||
const promiseToObservable = <T>(promise: Promise<T>) =>
|
||||
new Observable<T>((subscriber) => {
|
||||
promise.then(
|
||||
(value) => {
|
||||
if (subscriber.closed) {
|
||||
return;
|
||||
}
|
||||
subscriber.next(value);
|
||||
subscriber.complete();
|
||||
},
|
||||
(err) => {
|
||||
console.error("Cannot refresh token.", err);
|
||||
|
||||
subscriber.error(err);
|
||||
logout(apolloClient);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// Manually call this when user log in
|
||||
// export function onLogin(apolloClient) {
|
||||
// if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient);
|
||||
// }
|
||||
|
||||
// Manually call this when user log out
|
||||
// export async function onLogout() {
|
||||
// if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient);
|
||||
// We don't reset store because we rely on currentUser & currentActor
|
||||
// which are in the cache (even null). Maybe try to rerun cache init after resetStore?
|
||||
// try {
|
||||
// await apolloClient.resetStore();
|
||||
// } catch (e) {
|
||||
// // eslint-disable-next-line no-console
|
||||
// console.log('%cError on cache reset (logout)', 'color: orange;', e.message);
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -215,6 +215,9 @@ defmodule Mobilizon.Service.Auth.LDAPAuthenticator do
|
|||
:ok ->
|
||||
:ok
|
||||
|
||||
{:error, :tls_already_started} ->
|
||||
:ok
|
||||
|
||||
error ->
|
||||
Logger.error("Could not start TLS: #{inspect(error)}")
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue