From 28f99a9de29556b6e0309e6337101f039b36409f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Poussard?= <tpoussard@neogeo.fr> Date: Tue, 12 Mar 2024 18:48:04 +0100 Subject: [PATCH] Call SSO login with a redirect url and open it after login --- src/router/index.js | 15 ++++++--- src/store/index.js | 76 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index ee401ccc..ab3b4f44 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -130,11 +130,16 @@ const routes = [ query['feature_type_slug'] = slug_type_signal; // set feature_type slug in query } const offset = await featureAPI.getFeaturePosition(slug, slug_signal, query); - next({ - name: 'details-signalement-filtre', - params: { slug }, - query: { ...query, offset } - }); + if (offset) { + next({ + name: 'details-signalement-filtre', + params: { slug }, + query: { ...query, offset } + }); + } else { + store.commit('DISPLAY_MESSAGE', { comment: 'Désolé, une erreur est survenue pendant la recherche du signalement', level: 'negative' }); + next({ path: '/' }); + } } catch (error) { console.error('error', error); store.commit('DISPLAY_MESSAGE', { comment: `Désolé, une erreur est survenue pendant la recherche du signalement - ${error}`, level: 'negative' }); diff --git a/src/store/index.js b/src/store/index.js index 0ec31562..becf00ef 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -183,33 +183,71 @@ export default new Vuex.Store({ }); } }, - + /** + * Action to retrieve user information. + * - If a token is present in the URL, it indicates a Single Sign-On (SSO) attempt, + * in which case it logs out the user (if logged in) and connects via SSO with the token. + * Otherwise, it fetches user information from the Django API endpoint: + * - If no user is logged AND if the login should be done through SSO with a redirect, + * it naviguates to the login plateform, afterwards the user will be redirected with the token and the original url to open in geocontrib + * - Else it displays a message that the user is not logged but can still access the app as an anonymous user. + */ async GET_USER_INFO({ state, commit, dispatch }) { - const token = new URLSearchParams(window.location.search).get('token'); - if (token && this.state.configuration.VUE_APP_LOGIN_URL) { - // if user was previously connected through SSO, make sure he's logout before connecting through SSO, in case user changed + // Extract token from URL query parameters + const searchParams = new URLSearchParams(window.location.search); + const token = searchParams.get('token'); + const url_redirect = searchParams.get('url_redirect'); + // Check if token exists and SSO login URL is configured + if (token && state.configuration.VUE_APP_LOGIN_URL) { + // If user was previously connected through SSO, ensure they are logged out before reconnecting through SSO, in case user changed await dispatch('LOGOUT'); - dispatch('CONNECT_SSO_WITH_TOKEN', token); + dispatch('CONNECT_SSO_WITH_TOKEN', { token, url_redirect }); } else if (!state.user) { + // If user infos are not set, try to fetch them axios - .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user_info/`) + .get(`${state.configuration.VUE_APP_DJANGO_API_BASE}user_info/`) .then((response) => { + // Update the user state with received user data if (response && response.status === 200) { const user = response.data.user; commit('SET_USER', user); } }) - .catch((err) => { - console.error(err); - commit('DISPLAY_MESSAGE', { - comment: `Vous n'êtes pas connecté actuellement. - Vous pouvez accéder à l'application en tant qu'utilisateur anonyme` - }); + .catch(() => { + // If the instance is set to accept login with redirection + if (state.configuration.VUE_APP_SSO_LOGIN_URL_WITH_REDIRECT) { + commit('DISPLAY_MESSAGE', { + comment: 'Vous allez être redirigé vers la plateforme de connexion.' + }); + // Prepare the url to redirect with vue-router that prefix the url with DOMAIN+BASE_URL + let urlRedirect = window.location.href; + let substringToRemove = state.configuration.BASE_URL; + // Find the index of the string to remove + let index = urlRedirect.indexOf(substringToRemove); + // If found, keep only the remaining part after the substring to remove + if (index !== -1) { + urlRedirect = urlRedirect.substring(index + substringToRemove.length); + } + // Call the SSO login plateform with url to redirect after login + window.open(`${state.configuration.VUE_APP_SSO_LOGIN_URL_WITH_REDIRECT}/?url_redirect=${urlRedirect}`, '_self'); + } else { + // If the user is not logged in, display an info message + commit('DISPLAY_MESSAGE', { + comment: `Vous n'êtes pas connecté actuellement. + Vous pouvez accéder à l'application en tant qu'utilisateur anonyme` + }); + } }); } }, - - async CONNECT_SSO_WITH_TOKEN({ state, commit, dispatch }, token) { + /** + * Action to connect user through SSO with a token. + * If the app was opened with a token in the url, it attempts a login, + * if the login is succesfull, it set the user in the state + * and retrieve information that would have been retrieved in GET_USER_INFO when logged. + * If the url contained a url to redirect, it calls the router to open this page. + */ + async CONNECT_SSO_WITH_TOKEN({ state, commit, dispatch }, { token, url_redirect }) { axios .get(`${state.configuration.VUE_APP_DJANGO_API_BASE}login-token/?token=${token}`) .then((response) => { @@ -219,15 +257,21 @@ export default new Vuex.Store({ dispatch('GET_USER_LEVEL_PROJECTS'); dispatch('GET_USER_LEVEL_PERMISSIONS'); commit('DISPLAY_MESSAGE', { - comment: `Vous êtes maintenant connecté ${ user.first_name} ${ user.last_name}`, level: 'positive' + comment: `Vous êtes maintenant connecté ${user.first_name} ${user.last_name}`, + level: 'positive' }); dispatch('projects/GET_PROJECTS'); + if (url_redirect) { + // catch error from the router, because of second redirection to feature when call with a feature's id + router.push(url_redirect).catch((e) => e); + } } }) .catch((err) => { console.error(err); commit('DISPLAY_MESSAGE', { - comment: 'La connexion a échoué.', level: 'negative' + comment: 'La connexion a échoué.', + level: 'negative' }); }); }, -- GitLab