mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-05 09:14:58 +03:00
🐛 fix(frontend): read the C01 __Host-prefixed CSRF cookie name
C01 (settings_app) renamed the CSRF cookie to __Host-custocrm-app-csrf under SESSION_COOKIE_SECURE, but the API client still read the legacy 'csrftoken' cookie, so mutating requests (login, etc.) sent an empty/short X-CSRFToken and got 403. Read the matching cookie name; extract it to a named constant.
This commit is contained in:
1 parent
13e714e1be
commit
62bac47a31
1 file changed
+6
-2
@@ -1,6 +1,10 @@
|
|||||||
const configuredApiBase = (import.meta.env.VITE_API_BASE_URL ?? "").replace(/\/+$/, "");
|
const configuredApiBase = (import.meta.env.VITE_API_BASE_URL ?? "").replace(/\/+$/, "");
|
||||||
let activeOrganizationPublicId: string | null = null;
|
let activeOrganizationPublicId: string | null = null;
|
||||||
|
|
||||||
|
// Имя CSRF-cookie должно совпадать с backend CSRF_COOKIE_NAME (settings_app):
|
||||||
|
// production (SESSION_COOKIE_SECURE) → "__Host-custocrm-app-csrf".
|
||||||
|
const CSRF_COOKIE_NAME = "__Host-custocrm-app-csrf";
|
||||||
|
|
||||||
const tenantNamespaces = [
|
const tenantNamespaces = [
|
||||||
"access-profiles",
|
"access-profiles",
|
||||||
"ai",
|
"ai",
|
||||||
@@ -62,7 +66,7 @@ export async function api<T>(path: string, init: RequestInit = {}): Promise<T> {
|
|||||||
headers.set("Accept", "application/json");
|
headers.set("Accept", "application/json");
|
||||||
if (method !== "GET") {
|
if (method !== "GET") {
|
||||||
headers.set("Content-Type", "application/json");
|
headers.set("Content-Type", "application/json");
|
||||||
headers.set("X-CSRFToken", getCookie("csrftoken"));
|
headers.set("X-CSRFToken", getCookie(CSRF_COOKIE_NAME));
|
||||||
}
|
}
|
||||||
const response = await fetch(resolveApiUrl(path), {
|
const response = await fetch(resolveApiUrl(path), {
|
||||||
...init,
|
...init,
|
||||||
@@ -79,7 +83,7 @@ export async function api<T>(path: string, init: RequestInit = {}): Promise<T> {
|
|||||||
|
|
||||||
// Multipart-загрузка (вложения знаний): Content-Type выставляет браузер (boundary).
|
// Multipart-загрузка (вложения знаний): Content-Type выставляет браузер (boundary).
|
||||||
export async function apiUpload<T>(path: string, form: FormData): Promise<T> {
|
export async function apiUpload<T>(path: string, form: FormData): Promise<T> {
|
||||||
const headers = new Headers({ Accept: "application/json", "X-CSRFToken": getCookie("csrftoken") });
|
const headers = new Headers({ Accept: "application/json", "X-CSRFToken": getCookie(CSRF_COOKIE_NAME) });
|
||||||
const response = await fetch(resolveApiUrl(path), { method: "POST", body: form, credentials: "include", headers });
|
const response = await fetch(resolveApiUrl(path), { method: "POST", body: form, credentials: "include", headers });
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const payload = await response.json().catch(() => ({ detail: "Ошибка запроса" }));
|
const payload = await response.json().catch(() => ({ detail: "Ошибка запроса" }));
|
||||||
|
|||||||
Reference in new issue
Block a user