Fix refreshToken() undefined config, wrong axios.defaults, and missing re-throw
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,11 @@ export default defineStore('loginStore', {
|
|||||||
*/
|
*/
|
||||||
async refreshToken() {
|
async refreshToken() {
|
||||||
const api = '/api/oauth/token';
|
const api = '/api/oauth/token';
|
||||||
|
const config = {
|
||||||
|
headers: {
|
||||||
|
'Content-Type':'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
this.auth.grant_type = 'refresh_token';
|
this.auth.grant_type = 'refresh_token';
|
||||||
this.auth.refresh_token = getCookie("luciaRefreshToken");
|
this.auth.refresh_token = getCookie("luciaRefreshToken");
|
||||||
@@ -72,13 +77,14 @@ export default defineStore('loginStore', {
|
|||||||
const newRefreshToken = response.data.refresh_token;
|
const newRefreshToken = response.data.refresh_token;
|
||||||
|
|
||||||
document.cookie = `luciaToken=${newAccessToken}`;
|
document.cookie = `luciaToken=${newAccessToken}`;
|
||||||
document.cookie = `luciaRefreshToken=${newRefreshToken};expires=${this.expired}`;
|
document.cookie = `luciaRefreshToken=${newRefreshToken};expires=${new Date(this.expired)}`;
|
||||||
|
|
||||||
defaults.headers.common['Authorization'] = `Bearer ${newAccessToken}`;
|
axios.defaults.headers.common['Authorization'] = `Bearer ${newAccessToken}`;
|
||||||
}
|
}
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
// 若refresh token 失敗則導向至登入頁面
|
// 若refresh token 失敗則導向至登入頁面
|
||||||
this.$router.push('/login');
|
this.$router.push('/login');
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -144,6 +144,47 @@ describe('loginStore', () => {
|
|||||||
expect(store.isLoggedIn).toBe(true);
|
expect(store.isLoggedIn).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('refreshToken', () => {
|
||||||
|
it('sends request with correct config and updates tokens on success', async () => {
|
||||||
|
document.cookie = 'luciaRefreshToken=old-refresh-token';
|
||||||
|
|
||||||
|
axios.post.mockResolvedValue({
|
||||||
|
status: 200,
|
||||||
|
data: {
|
||||||
|
access_token: 'new-access-token',
|
||||||
|
refresh_token: 'new-refresh-token',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await store.refreshToken();
|
||||||
|
|
||||||
|
// Should call with content-type header (config must be defined)
|
||||||
|
expect(axios.post).toHaveBeenCalledWith(
|
||||||
|
'/api/oauth/token',
|
||||||
|
expect.objectContaining({
|
||||||
|
grant_type: 'refresh_token',
|
||||||
|
refresh_token: 'old-refresh-token',
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should update axios default Authorization header
|
||||||
|
expect(axios.defaults.headers.common['Authorization'])
|
||||||
|
.toBe('Bearer new-access-token');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('redirects to login and re-throws on failure', async () => {
|
||||||
|
document.cookie = 'luciaRefreshToken=old-refresh-token';
|
||||||
|
axios.post.mockRejectedValue(new Error('401'));
|
||||||
|
|
||||||
|
await expect(store.refreshToken()).rejects.toThrow('401');
|
||||||
|
|
||||||
|
expect(store.$router.push).toHaveBeenCalledWith('/login');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('expired', () => {
|
describe('expired', () => {
|
||||||
it('is approximately 6 months in the future', () => {
|
it('is approximately 6 months in the future', () => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|||||||
Reference in New Issue
Block a user