| |
| |
| |
| |
| |
| |
| |
| export async function callJsonApi(endpoint, data) { |
| const response = await fetchApi(endpoint, { |
| method: "POST", |
| headers: { |
| "Content-Type": "application/json", |
| }, |
| credentials: "same-origin", |
| body: JSON.stringify(data), |
| }); |
|
|
| if (!response.ok) { |
| const error = await response.text(); |
| throw new Error(error); |
| } |
| const jsonResponse = await response.json(); |
| return jsonResponse; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| export async function fetchApi(url, request) { |
| async function _wrap(retry) { |
| |
| const token = await getCsrfToken(); |
|
|
| |
| const finalRequest = request || {}; |
|
|
| |
| finalRequest.headers = finalRequest.headers || {}; |
|
|
| |
| finalRequest.headers["X-CSRF-Token"] = token; |
|
|
| |
| const response = await fetch(url, finalRequest); |
|
|
| |
| if (response.status === 403 && retry) { |
| |
| csrfToken = null; |
| return await _wrap(false); |
| } |
|
|
| |
| return response; |
| } |
|
|
| |
| const response = await _wrap(true); |
|
|
| |
| return response; |
| } |
|
|
| |
| let csrfToken = null; |
|
|
| |
| |
| |
| |
| |
| async function getCsrfToken() { |
| if (csrfToken) return csrfToken; |
| const tokenElement = document.querySelector('meta[name="csrf-token"]'); |
| if (tokenElement) { |
| csrfToken = tokenElement.content; |
| return csrfToken; |
| } |
| |
| const response = await fetch("/csrf_token", { |
| credentials: "same-origin", |
| }).then((r) => r.json()); |
| csrfToken = response.token; |
| document.cookie = `csrf_token_${response.runtime_id}=${csrfToken}; SameSite=Strict; Path=/`; |
| return csrfToken; |
| } |
|
|