UNPKG

@europeana/portal

Version:
105 lines (85 loc) 3.43 kB
// @see https://github.com/nuxt-community/auth-module/blob/v4.9.1/lib/schemes/oauth2.js#L157-L201 const refreshAccessToken = async({ $auth, $axios, redirect, route }, requestConfig) => { let refreshAccessTokenResponse; try { refreshAccessTokenResponse = await $auth.request(refreshAccessTokenRequestOptions($auth)); } catch { // Refresh token is no longer valid; clear tokens and try again $auth.logout(); delete requestConfig.headers['Authorization']; return $axios.request(requestConfig); } if (!updateAccessToken($auth, requestConfig, refreshAccessTokenResponse)) { // No new access token; redirect to login URL return redirect($auth.options.redirect.login, { redirect: route.path }); } updateRefreshToken($auth, refreshAccessTokenResponse); // Retry request with new access token return $axios.request(requestConfig); }; const updateRefreshToken = ($auth, refreshAccessTokenResponse) => { const options = $auth.strategy.options; let newRefreshToken = refreshAccessTokenResponse[options.refresh_token_key]; if (!newRefreshToken) { return false; } if (options.token_type) { newRefreshToken = `${options.token_type} ${newRefreshToken}`; } // Store refresh token $auth.setRefreshToken($auth.strategy.name, newRefreshToken); return newRefreshToken; }; const updateAccessToken = ($auth, requestConfig, refreshAccessTokenResponse) => { const options = $auth.strategy.options; let newAccessToken = refreshAccessTokenResponse[options.token_key]; if (!newAccessToken) { return false; } if (options.token_type) { newAccessToken = `${options.token_type} ${newAccessToken}`; } // Store token $auth.setToken($auth.strategy.name, newAccessToken); // Set axios token $auth.strategy._setToken(newAccessToken); // eslint-disable-line no-underscore-dangle delete requestConfig.headers['Authorization']; return newAccessToken; }; const refreshAccessTokenRequestOptions = ($auth) => { const refreshToken = $auth.getRefreshToken($auth.strategy.name); const options = $auth.strategy.options; // Nuxt Auth stores token type e.g. "Bearer " with token, but refresh_token // grant does not need it; remove it before sending to OIDC. const refreshTokenWithoutType = refreshToken.replace(new RegExp(`^${options.token_type} `), ''); return { method: 'post', url: options.access_token_endpoint, headers: { 'content-type': 'application/x-www-form-urlencoded' }, data: new URLSearchParams({ 'client_id': options.client_id, 'refresh_token': refreshTokenWithoutType, 'grant_type': 'refresh_token' }).toString() }; }; export const keycloakResponseErrorHandler = (context, error) => { if (error.response.status === 401) { return keycloakUnauthorizedResponseErrorHandler(context, error); } else { return Promise.reject(error); } }; const keycloakUnauthorizedResponseErrorHandler = ({ $auth, $axios, redirect, route }, error) => { if ($auth.getRefreshToken($auth.strategy.name)) { // User has previously logged in, and we have a refresh token, e.g. // access token has expired return refreshAccessToken({ $auth, $axios, redirect, route }, error.config); } else { // User has not already logged in, or we have no refresh token: // redirect to OIDC login URL return redirect($auth.options.redirect.login, { redirect: route.path }); } };