()
| 55 | * Uses the native fetch to avoid wrapper loops and accepts rotated tokens via header. |
| 56 | */ |
| 57 | export async function loadCsrfToken() { |
| 58 | const res = await _nativeFetch(withBase('/api/auth/token.php'), { method: 'GET', credentials: 'include' }); |
| 59 | |
| 60 | // header-based rotation |
| 61 | const hdr = res.headers.get('X-CSRF-Token'); |
| 62 | if (hdr) setCsrfToken(hdr); |
| 63 | |
| 64 | // body (if provided) |
| 65 | let body = {}; |
| 66 | try { body = await res.json(); } catch (e) { /* token endpoint may return empty */ } |
| 67 | |
| 68 | const token = body.csrf_token || getCsrfToken(); |
| 69 | setCsrfToken(token); |
| 70 | |
| 71 | // share-url meta should reflect the actual origin + base path (e.g. https://host/fr) |
| 72 | const base = withBase('/').replace(/\/$/, ''); |
| 73 | const actualShare = window.location.origin + base; |
| 74 | let shareMeta = document.querySelector('meta[name="share-url"]'); |
| 75 | if (!shareMeta) { |
| 76 | shareMeta = document.createElement('meta'); |
| 77 | shareMeta.name = 'share-url'; |
| 78 | document.head.appendChild(shareMeta); |
| 79 | } |
| 80 | shareMeta.content = actualShare; |
| 81 | |
| 82 | return { csrf_token: token, share_url: actualShare }; |
| 83 | } |
| 84 | |
| 85 | /* ========================= |
| 86 | APP INIT (shared) |
nothing calls this directly
no test coverage detected