forked from potsda.mn/mobilizon
Merge branch 'refactor-refreshing-token' into 'master'
Refactor refreshing token See merge request framasoft/mobilizon!1005
This commit is contained in:
commit
d0ac3de354
|
@ -129,6 +129,7 @@ import RouteName from "../../router/name";
|
||||||
import { changeIdentity } from "../../utils/auth";
|
import { changeIdentity } from "../../utils/auth";
|
||||||
import identityEditionMixin from "../../mixins/identityEdition";
|
import identityEditionMixin from "../../mixins/identityEdition";
|
||||||
import { ApolloCache, FetchResult } from "@apollo/client/core";
|
import { ApolloCache, FetchResult } from "@apollo/client/core";
|
||||||
|
import { ActorType } from "@/types/enums";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
apollo: {
|
apollo: {
|
||||||
|
@ -180,8 +181,18 @@ export default class Register extends mixins(identityEditionMixin) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (identitiesData && localData) {
|
if (identitiesData && localData) {
|
||||||
identitiesData.identities.push(localData.registerPerson);
|
const newPersonData = {
|
||||||
store.writeQuery({ query: IDENTITIES, data: identitiesData });
|
...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;
|
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>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -259,7 +259,7 @@ export default class Login extends Vue {
|
||||||
await initializeCurrentActor(this.$apollo.provider.defaultClient);
|
await initializeCurrentActor(this.$apollo.provider.defaultClient);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof NoIdentitiesException) {
|
if (err instanceof NoIdentitiesException) {
|
||||||
this.$router.push({
|
await this.$router.push({
|
||||||
name: RouteName.REGISTER_PROFILE,
|
name: RouteName.REGISTER_PROFILE,
|
||||||
params: {
|
params: {
|
||||||
email: this.currentUser.email,
|
email: this.currentUser.email,
|
||||||
|
|
|
@ -6,9 +6,9 @@ import {
|
||||||
ApolloClient,
|
ApolloClient,
|
||||||
ApolloLink,
|
ApolloLink,
|
||||||
defaultDataIdFromObject,
|
defaultDataIdFromObject,
|
||||||
|
fromPromise,
|
||||||
InMemoryCache,
|
InMemoryCache,
|
||||||
NormalizedCacheObject,
|
NormalizedCacheObject,
|
||||||
Observable,
|
|
||||||
split,
|
split,
|
||||||
} from "@apollo/client/core";
|
} from "@apollo/client/core";
|
||||||
import buildCurrentUserResolver from "@/apollo/user";
|
import buildCurrentUserResolver from "@/apollo/user";
|
||||||
|
@ -31,8 +31,8 @@ import { GraphQLError } from "graphql";
|
||||||
// Install the vue plugin
|
// Install the vue plugin
|
||||||
Vue.use(VueApollo);
|
Vue.use(VueApollo);
|
||||||
|
|
||||||
let refreshingTokenPromise: Promise<boolean> | undefined;
|
let isRefreshing = false;
|
||||||
let alreadyRefreshedToken = false;
|
let pendingRequests: any[] = [];
|
||||||
|
|
||||||
// Endpoints
|
// Endpoints
|
||||||
const httpServer = GRAPHQL_API_ENDPOINT || "http://localhost:4000";
|
const httpServer = GRAPHQL_API_ENDPOINT || "http://localhost:4000";
|
||||||
|
@ -92,32 +92,55 @@ const link = split(
|
||||||
uploadLink
|
uploadLink
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const resolvePendingRequests = () => {
|
||||||
|
pendingRequests.map((callback) => callback());
|
||||||
|
pendingRequests = [];
|
||||||
|
};
|
||||||
|
|
||||||
const errorLink = onError(
|
const errorLink = onError(
|
||||||
({ graphQLErrors, networkError, forward, operation }) => {
|
({ graphQLErrors, networkError, forward, operation }) => {
|
||||||
if (
|
if (isServerError(networkError) && networkError?.statusCode === 401) {
|
||||||
isServerError(networkError) &&
|
let forwardOperation;
|
||||||
networkError?.statusCode === 401 &&
|
|
||||||
!alreadyRefreshedToken
|
|
||||||
) {
|
|
||||||
if (!refreshingTokenPromise)
|
|
||||||
refreshingTokenPromise = refreshAccessToken(apolloClient);
|
|
||||||
|
|
||||||
return promiseToObservable(refreshingTokenPromise).flatMap(() => {
|
if (!isRefreshing) {
|
||||||
refreshingTokenPromise = undefined;
|
isRefreshing = true;
|
||||||
alreadyRefreshedToken = true;
|
|
||||||
|
|
||||||
const context = operation.getContext();
|
forwardOperation = fromPromise(
|
||||||
const oldHeaders = context.headers;
|
refreshAccessToken(apolloClient)
|
||||||
|
.then(() => {
|
||||||
|
resolvePendingRequests();
|
||||||
|
|
||||||
operation.setContext({
|
const context = operation.getContext();
|
||||||
headers: {
|
const oldHeaders = context.headers;
|
||||||
...oldHeaders,
|
|
||||||
authorization: generateTokenHeader(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
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) {
|
if (graphQLErrors) {
|
||||||
|
@ -171,41 +194,3 @@ export default new VueApollo({
|
||||||
console.error(error);
|
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 ->
|
||||||
:ok
|
:ok
|
||||||
|
|
||||||
|
{:error, :tls_already_started} ->
|
||||||
|
:ok
|
||||||
|
|
||||||
error ->
|
error ->
|
||||||
Logger.error("Could not start TLS: #{inspect(error)}")
|
Logger.error("Could not start TLS: #{inspect(error)}")
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue