fix(auth): Resolve lint regressions and add security regression test
This commit is contained in:
@@ -60,3 +60,17 @@ def test_refresh_token_wrong_type(client):
|
||||
response = client.post("/api/v1/auth/refresh")
|
||||
assert response.status_code == 401
|
||||
assert response.json()["detail"] == "Invalid token type"
|
||||
|
||||
def test_protected_endpoint_rejects_refresh_token(client):
|
||||
"""Regression test: Ensure refresh tokens cannot be used to access protected endpoints."""
|
||||
user_id = "test-user-id"
|
||||
refresh_token = create_refresh_token({"sub": user_id})
|
||||
|
||||
# Attempt to access /auth/me with a refresh token in the cookie
|
||||
client.cookies.set("access_token", refresh_token)
|
||||
|
||||
response = client.get("/api/v1/auth/me")
|
||||
|
||||
# Should be rejected with 401
|
||||
assert response.status_code == 401
|
||||
assert "Cannot use refresh token for this endpoint" in response.json()["detail"]
|
||||
|
||||
@@ -17,9 +17,9 @@ export const registerUnauthorizedCallback = (callback: () => void) => {
|
||||
// State to manage multiple concurrent refreshes
|
||||
let isRefreshing = false
|
||||
let refreshSubscribers: ((token: string) => void)[] = []
|
||||
let refreshErrorSubscribers: ((error: any) => void)[] = []
|
||||
let refreshErrorSubscribers: ((error: unknown) => void)[] = []
|
||||
|
||||
const subscribeTokenRefresh = (onSuccess: (token: string) => void, onError: (error: any) => void) => {
|
||||
const subscribeTokenRefresh = (onSuccess: (token: string) => void, onError: (error: unknown) => void) => {
|
||||
refreshSubscribers.push(onSuccess)
|
||||
refreshErrorSubscribers.push(onError)
|
||||
}
|
||||
@@ -30,7 +30,7 @@ const onRefreshed = (token: string) => {
|
||||
refreshErrorSubscribers = []
|
||||
}
|
||||
|
||||
const onRefreshFailed = (error: any) => {
|
||||
const onRefreshFailed = (error: unknown) => {
|
||||
refreshErrorSubscribers.forEach((callback) => callback(error))
|
||||
refreshSubscribers = []
|
||||
refreshErrorSubscribers = []
|
||||
@@ -52,7 +52,7 @@ api.interceptors.response.use(
|
||||
// Wait for the current refresh to complete
|
||||
return new Promise((resolve, reject) => {
|
||||
subscribeTokenRefresh(
|
||||
(_token) => resolve(api(originalRequest)),
|
||||
() => resolve(api(originalRequest)),
|
||||
(err) => reject(err)
|
||||
)
|
||||
})
|
||||
@@ -72,7 +72,7 @@ api.interceptors.response.use(
|
||||
|
||||
// Retry the original request
|
||||
return api(originalRequest)
|
||||
} catch (refreshError) {
|
||||
} catch (refreshError: unknown) {
|
||||
isRefreshing = false
|
||||
onRefreshFailed(refreshError)
|
||||
console.error("Reactive refresh failed:", refreshError)
|
||||
|
||||
Reference in New Issue
Block a user