{"version":3,"file":"account_login_csrf.js","sources":["../../../frontend/js/account_login_csrf.js"],"sourcesContent":["// Transparent CSRF token refresh for the login form.\n//\n// Django rotates the `csrftoken` cookie on every login and logout. A login page\n// rendered before that rotation (another tab, a restored history entry) carries\n// a token that no longer matches the cookie, so the POST fails CSRF. Here we\n// fetch a token matching the *current* cookie immediately before submit and swap\n// it into the form, so the first sign-in always succeeds with nothing shown to\n// the user. If the fetch fails we submit anyway and the server-side\n// CSRF_FAILURE_VIEW still recovers gracefully — defence in depth.\n\nconst form = document.getElementById('login-form')\n\n// Scoped to the login form, which has no captcha. Never attach to a captcha\n// form: bypassing its submit would drop the invisible reCAPTCHA token.\nif (form && !form.querySelector('[name=\"captcha\"], .g-recaptcha')) {\n  form.addEventListener('submit', (event) => {\n    // Second pass after requestSubmit(): token is fresh, let native submission proceed.\n    if (form.dataset.csrfRefreshed === 'true') return\n    // Concurrent user submit (double-click / double-Enter) while a refresh is in flight: swallow.\n    if (form.dataset.csrfRefreshing === 'true') {\n      event.preventDefault()\n      return\n    }\n    if (!form.checkValidity()) return\n\n    event.preventDefault()\n    form.dataset.csrfRefreshing = 'true'\n\n    const tokenField = form.querySelector('input[name=\"csrfmiddlewaretoken\"]')\n\n    window\n      .fetch('/accounts/csrf-token/', {\n        credentials: 'same-origin',\n        headers: { 'X-Requested-With': 'XMLHttpRequest' }\n      })\n      .then((response) => (response.ok ? response.json() : null))\n      .then((data) => {\n        if (data && data.csrfToken && tokenField) {\n          tokenField.value = data.csrfToken\n        }\n      })\n      .catch(() => {})\n      .finally(() => {\n        form.dataset.csrfRefreshed = 'true'\n        delete form.dataset.csrfRefreshing\n        if (form.requestSubmit) {\n          form.requestSubmit()\n        } else {\n          form.submit()\n        }\n      })\n  })\n}\n"],"names":["form","event","tokenField","response","data"],"mappings":"AAUA,MAAMA,EAAO,SAAS,eAAe,YAAY,EAI7CA,GAAQ,CAACA,EAAK,cAAc,gCAAgC,GAC9DA,EAAK,iBAAiB,SAAWC,GAAU,CAEzC,GAAID,EAAK,QAAQ,gBAAkB,OAAQ,OAE3C,GAAIA,EAAK,QAAQ,iBAAmB,OAAQ,CAC1CC,EAAM,eAAc,EACpB,MACF,CACA,GAAI,CAACD,EAAK,gBAAiB,OAE3BC,EAAM,eAAc,EACpBD,EAAK,QAAQ,eAAiB,OAE9B,MAAME,EAAaF,EAAK,cAAc,mCAAmC,EAEzE,OACG,MAAM,wBAAyB,CAC9B,YAAa,cACb,QAAS,CAAE,mBAAoB,gBAAgB,CACvD,CAAO,EACA,KAAMG,GAAcA,EAAS,GAAKA,EAAS,KAAI,EAAK,IAAK,EACzD,KAAMC,GAAS,CACVA,GAAQA,EAAK,WAAaF,IAC5BA,EAAW,MAAQE,EAAK,UAE5B,CAAC,EACA,MAAM,IAAM,CAAC,CAAC,EACd,QAAQ,IAAM,CACbJ,EAAK,QAAQ,cAAgB,OAC7B,OAAOA,EAAK,QAAQ,eAChBA,EAAK,cACPA,EAAK,cAAa,EAElBA,EAAK,OAAM,CAEf,CAAC,CACL,CAAC"}