@lenne.tech/nuxt-extensions 1.8.3 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2,10 +2,17 @@
|
|
|
2
2
|
* Auth Interceptor Plugin
|
|
3
3
|
*
|
|
4
4
|
* This plugin intercepts all API responses and handles session expiration.
|
|
5
|
-
* When a 401 (Unauthorized) response is received, it
|
|
5
|
+
* When a 401 (Unauthorized) response is received, it verifies against the
|
|
6
|
+
* session endpoint that the session is genuinely dead and then automatically:
|
|
6
7
|
* 1. Clears the user session state
|
|
7
8
|
* 2. Redirects to the login page
|
|
8
9
|
*
|
|
10
|
+
* The verification step exists because a 401 from a domain endpoint is not
|
|
11
|
+
* proof of an expired session: backends may mislabel permission errors
|
|
12
|
+
* (authenticated user, missing rights — semantically 403) as 401. Logging out
|
|
13
|
+
* on those would kick a logged-in user out of the app for a mere missing
|
|
14
|
+
* right. Only a dead session may clear state.
|
|
15
|
+
*
|
|
9
16
|
* Note: This is a client-only plugin (.client.ts) since auth state
|
|
10
17
|
* management only makes sense in the browser context.
|
|
11
18
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useLtAuth } from "../composables/auth/use-lt-auth.js";
|
|
2
|
+
import { getLtApiBase } from "../lib/auth-state.js";
|
|
2
3
|
export default (nuxtApp) => {
|
|
3
4
|
if (import.meta.server) return;
|
|
4
5
|
let _authInstance = null;
|
|
@@ -42,6 +43,19 @@ export default (nuxtApp) => {
|
|
|
42
43
|
];
|
|
43
44
|
return authEndpoints.some((endpoint) => url.includes(endpoint));
|
|
44
45
|
}
|
|
46
|
+
async function isSessionStillAlive() {
|
|
47
|
+
try {
|
|
48
|
+
const { fetchWithAuth } = getAuth();
|
|
49
|
+
const response = await fetchWithAuth(`${getLtApiBase()}/get-session`, { method: "GET" });
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const data = await response.json().catch(() => null);
|
|
54
|
+
return Boolean(data && (data.user || data.session));
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
45
59
|
async function handleUnauthorized(requestUrl) {
|
|
46
60
|
if (isHandling401) {
|
|
47
61
|
return;
|
|
@@ -56,6 +70,13 @@ export default (nuxtApp) => {
|
|
|
56
70
|
try {
|
|
57
71
|
const { clearUser, isAuthenticated } = getAuth();
|
|
58
72
|
if (isAuthenticated.value) {
|
|
73
|
+
const sessionAlive = await isSessionStillAlive();
|
|
74
|
+
if (sessionAlive !== false) {
|
|
75
|
+
console.debug(
|
|
76
|
+
sessionAlive ? `[LtAuth Interceptor] 401 from ${requestUrl ?? "unknown URL"} but session is still valid \u2014 treating it as a permission error, not logging out` : "[LtAuth Interceptor] 401 received but session state could not be verified \u2014 not logging out"
|
|
77
|
+
);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
59
80
|
console.debug("[LtAuth Interceptor] Session expired, logging out...");
|
|
60
81
|
clearUser();
|
|
61
82
|
const router = nuxtApp.$router;
|