108 lines
3.3 KiB
TypeScript
108 lines
3.3 KiB
TypeScript
import axios from 'axios';
|
|
import { dev } from '$app/environment';
|
|
import { goto } from '$app/navigation';
|
|
import { get } from 'svelte/store';
|
|
import { persistentSettings, clearLoginState } from '$lib/persistent_store';
|
|
|
|
if (dev) {
|
|
axios.defaults.baseURL = "http://localhost:8000/api/v1"
|
|
} else {
|
|
axios.defaults.baseURL = "/api/v1"
|
|
}
|
|
|
|
// Get access token from local storage
|
|
axios.defaults.headers.common['Authorization'] = "Bearer " + get(persistentSettings).accessToken;
|
|
|
|
function createTokenRefreshInterceptor() {
|
|
const interceptor = axios.interceptors.response.use(
|
|
(response) => response,
|
|
(error) => {
|
|
// Reject promise if usual error
|
|
if (error.response.status !== 401) {
|
|
return Promise.reject(error);
|
|
}
|
|
|
|
/*
|
|
* When response code is 401, try to refresh the token.
|
|
* Eject the interceptor so it doesn't loop in case
|
|
* token refresh causes the 401 response.
|
|
*
|
|
* Must be re-attached later on or the token refresh will only happen once
|
|
*/
|
|
axios.interceptors.response.eject(interceptor);
|
|
|
|
return axios
|
|
.post("/auth/refresh", {
|
|
refresh_token: get(persistentSettings).refreshToken,
|
|
})
|
|
.then((response) => {
|
|
// Save new tokens
|
|
persistentSettings.update(settings => {
|
|
settings.accessToken = response.data.access_token
|
|
settings.refreshToken = response.data.refresh_token;
|
|
return settings;
|
|
})
|
|
|
|
// Update access token
|
|
const authHeader = "Bearer " + response.data.access_token;
|
|
axios.defaults.headers.common['Authorization'] = authHeader;
|
|
error.response.config.headers["Authorization"] = authHeader;
|
|
|
|
// Retry initial request with new token
|
|
return axios(error.response.config);
|
|
})
|
|
.catch((retryError) => {
|
|
// Retry failed, clean up and reject the promise
|
|
clearLoginState();
|
|
axios.defaults.headers.common['Authorization'] = "";
|
|
goto('/login?reauth')
|
|
return Promise.reject(retryError);
|
|
})
|
|
.finally(createTokenRefreshInterceptor); // Re-attach interceptor for future requests
|
|
}
|
|
);
|
|
}
|
|
|
|
createTokenRefreshInterceptor();
|
|
|
|
export const login = async function(email: string, password: string) {
|
|
await axios
|
|
.post('/auth/login', {
|
|
email,
|
|
password,
|
|
})
|
|
.then((response) => {
|
|
persistentSettings.update(settings => {
|
|
settings.loggedIn = true
|
|
settings.accessToken = response.data.access_token
|
|
settings.refreshToken = response.data.refresh_token
|
|
return settings;
|
|
})
|
|
axios.defaults.headers.common['Authorization'] = 'Bearer ' + response.data.access_token
|
|
axios.get('/me').then((response) => {
|
|
persistentSettings.update(settings => {
|
|
settings.email = response.data.email
|
|
settings.friendlyName = response.data.friendly_name
|
|
settings.role = response.data.role
|
|
return settings;
|
|
})
|
|
})
|
|
goto('/')
|
|
return Promise.resolve();
|
|
})
|
|
.catch((error) => {
|
|
return Promise.reject(error);
|
|
})
|
|
}
|
|
|
|
export const logout = function() {
|
|
axios
|
|
.post('/auth/logout')
|
|
.then(() => {
|
|
clearLoginState();
|
|
axios.defaults.headers.common['Authorization'] = "";
|
|
goto('/login?logout')
|
|
});
|
|
}
|
|
|
|
export default axios;
|