feat(client): qrcode checkin dialog

Signed-off-by: Noa Virellia <noa@requiem.garden>
This commit is contained in:
2025-12-28 01:20:13 +08:00
parent f89a483380
commit a48f5ad2fa
16 changed files with 524 additions and 119 deletions

View File

@@ -1,7 +1,7 @@
import type { AxiosError } from 'axios';
import axios from 'axios';
import type { AxiosRequestConfig } from 'axios';
import axios, { AxiosError } from 'axios';
import { router } from '@/lib/router';
import { getToken, hasToken } from './token';
import { doRefreshToken, getRefreshToken, getToken, setRefreshToken, setToken } from './token';
export const axiosClient = axios.create({
baseURL: '/api/v1/',
@@ -10,19 +10,35 @@ export const axiosClient = axios.create({
axiosClient.interceptors.request.use((config) => {
const token = getToken();
if (token !== null) {
config.headers = config.headers ?? {};
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
type RetryConfig = AxiosRequestConfig & { _retry?: boolean };
axiosClient.interceptors.response.use(undefined, async (error: AxiosError) => {
if (error.response && error?.response.status === 401) {
// TODO: refresh token
if (!hasToken()) {
await router.navigate({ to: '/login' });
return;
}
else { return Promise.reject(error); }
const originalRequest = error.config as RetryConfig | undefined;
if (!error.response || error.response.status !== 401 || !originalRequest) {
return Promise.reject(error);
}
if (error.response.status === 401 && getRefreshToken() !== null) {
try {
const maybeRefreshTokenValue = await doRefreshToken();
const { access_token, refresh_token } = maybeRefreshTokenValue.data;
originalRequest.headers = originalRequest.headers ?? {};
originalRequest.headers.Authorization = `Bearer ${access_token}`;
setToken(access_token);
setRefreshToken(refresh_token);
return await axiosClient(originalRequest);
}
catch (e) {
if (e instanceof AxiosError && e.status === 401) {
await router.navigate({ to: '/login' });
return Promise.reject(error);
}
}
}
return Promise.reject(error);
});

View File

@@ -1,3 +1,5 @@
import axios from 'axios';
export function setToken(token: string) {
localStorage.setItem('token', token);
}
@@ -13,3 +15,20 @@ export function removeToken() {
export function hasToken() {
return getToken() !== null;
}
export function setRefreshToken(refreshToken: string) {
localStorage.setItem('refreshToken', refreshToken);
}
export function getRefreshToken() {
return localStorage.getItem('refreshToken');
}
export function clearTokens() {
removeToken();
setRefreshToken('');
}
export async function doRefreshToken() {
return axios.post<{ access_token: string; refresh_token: string }>('/api/v1/auth/refresh', { refresh_token: getRefreshToken() });
}