LibreCharge/frontend/src/lib/axios.svelte.ts

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;