@kawaiininja/fetch 1.0.60 โ 1.1.0
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.
- package/dist/hooks/useCsrf.js +42 -16
- package/package.json +1 -1
package/dist/hooks/useCsrf.js
CHANGED
|
@@ -7,8 +7,9 @@ const getFromStorage = (debug) => {
|
|
|
7
7
|
if (typeof window === "undefined")
|
|
8
8
|
return null;
|
|
9
9
|
const stored = localStorage.getItem("csrf_token");
|
|
10
|
-
if (stored && debug)
|
|
11
|
-
console.log("[useCsrf]
|
|
10
|
+
if (stored && debug) {
|
|
11
|
+
console.log("%c[useCsrf] ๐พ SUCCESS: Found token in localStorage", "color: #add8e6");
|
|
12
|
+
}
|
|
12
13
|
return stored || null;
|
|
13
14
|
};
|
|
14
15
|
const saveToStorage = (token) => {
|
|
@@ -18,7 +19,7 @@ const saveToStorage = (token) => {
|
|
|
18
19
|
};
|
|
19
20
|
const fetchFromNetwork = async (apiUrl, debug) => {
|
|
20
21
|
if (debug)
|
|
21
|
-
console.log("[useCsrf]
|
|
22
|
+
console.log("%c[useCsrf] ๐ NETWORK: Requesting fresh token from server...", "color: #ffa500");
|
|
22
23
|
const csrfUrl = apiUrl("auth/csrf-token");
|
|
23
24
|
const controller = new AbortController();
|
|
24
25
|
const timeoutId = setTimeout(() => controller.abort(), 15000);
|
|
@@ -29,17 +30,26 @@ const fetchFromNetwork = async (apiUrl, debug) => {
|
|
|
29
30
|
credentials: "include",
|
|
30
31
|
signal: controller.signal,
|
|
31
32
|
});
|
|
32
|
-
if (!res.ok)
|
|
33
|
-
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const errText = `CSRF HTTP Error: ${res.status}`;
|
|
35
|
+
if (debug)
|
|
36
|
+
console.error(`%c[useCsrf] โ NETWORK FAIL: ${errText}`, "color: #ff0000");
|
|
37
|
+
throw new Error(errText);
|
|
38
|
+
}
|
|
34
39
|
const json = await res.json();
|
|
35
40
|
const token = json?.csrfToken;
|
|
36
|
-
if (!token)
|
|
41
|
+
if (!token) {
|
|
42
|
+
if (debug)
|
|
43
|
+
console.error("%c[useCsrf] โ RESPONSE FAIL: No token in JSON", "color: #ff0000");
|
|
37
44
|
throw new Error("Missing CSRF token in response");
|
|
45
|
+
}
|
|
46
|
+
if (debug)
|
|
47
|
+
console.log("%c[useCsrf] โ
NETWORK SUCCESS: Received new token", "color: #00ff00");
|
|
38
48
|
return token;
|
|
39
49
|
}
|
|
40
50
|
catch (error) {
|
|
41
51
|
if (debug)
|
|
42
|
-
console.error("[useCsrf]
|
|
52
|
+
console.error("%c[useCsrf] โ FATAL ERROR:", "color: #ff0000", error);
|
|
43
53
|
throw error;
|
|
44
54
|
}
|
|
45
55
|
finally {
|
|
@@ -55,8 +65,9 @@ export function useCsrf() {
|
|
|
55
65
|
if (isNative() || disableCsrf)
|
|
56
66
|
return;
|
|
57
67
|
if (debug)
|
|
58
|
-
console.log("[useCsrf]
|
|
68
|
+
console.log("%c[useCsrf] ๐งน CLEARING: Token and promises wiped.", "color: #ff69b4");
|
|
59
69
|
csrfRef.current = null;
|
|
70
|
+
csrfPromiseRef.current = null;
|
|
60
71
|
if (typeof window !== "undefined")
|
|
61
72
|
localStorage.removeItem("csrf_token");
|
|
62
73
|
}, [debug, disableCsrf]);
|
|
@@ -64,16 +75,31 @@ export function useCsrf() {
|
|
|
64
75
|
const { force = false } = options || {};
|
|
65
76
|
if (isNative() || disableCsrf) {
|
|
66
77
|
if (debug)
|
|
67
|
-
console.log(
|
|
78
|
+
console.log("[useCsrf] โญ๏ธ Skipped (Native or Disabled)");
|
|
68
79
|
return "";
|
|
69
80
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
if (debug) {
|
|
82
|
+
console.log(`%c[useCsrf] ๐ FETCH: Force=${force} | HasMemory=${!!csrfRef.current} | HasPromise=${!!csrfPromiseRef.current}`, "font-weight: bold; color: #888");
|
|
83
|
+
}
|
|
84
|
+
// 1. Return Memory/Pending (ONLY IF NOT FORCED)
|
|
85
|
+
if (!force) {
|
|
86
|
+
if (csrfRef.current) {
|
|
87
|
+
if (debug)
|
|
88
|
+
console.log("%c[useCsrf] ๐ง CACHE: Using Memory Token", "color: #add8e6");
|
|
89
|
+
return csrfRef.current;
|
|
90
|
+
}
|
|
91
|
+
if (csrfPromiseRef.current) {
|
|
92
|
+
if (debug)
|
|
93
|
+
console.log("%c[useCsrf] โณ PENDING: Joining existing fetch...", "color: #add8e6");
|
|
94
|
+
return csrfPromiseRef.current;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
if (debug)
|
|
99
|
+
console.log("%c[useCsrf] ๐ FORCED: Bypassing ALL caches", "font-weight: bold; color: #ffa500");
|
|
100
|
+
}
|
|
75
101
|
const task = async () => {
|
|
76
|
-
// 2. Storage
|
|
102
|
+
// 2. Check Storage (ONLY IF NOT FORCED)
|
|
77
103
|
if (!force) {
|
|
78
104
|
const stored = getFromStorage(debug);
|
|
79
105
|
if (stored) {
|
|
@@ -88,7 +114,7 @@ export function useCsrf() {
|
|
|
88
114
|
return newToken;
|
|
89
115
|
};
|
|
90
116
|
const promise = task();
|
|
91
|
-
//
|
|
117
|
+
// Reset promise ref once done so next call starts fresh or uses memory
|
|
92
118
|
const chained = promise.finally(() => {
|
|
93
119
|
if (csrfPromiseRef.current === chained) {
|
|
94
120
|
csrfPromiseRef.current = null;
|