mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
`campaignJsonMutationRoute` now builds every JSON POST route under /campanha — `isSameOriginRequest` had been copied into five of them, so the CSRF policy was failing open by omission; a convention guard sweeps all of `src/app` and names its three exceptions. `postCampaignJson` is the only place that spells `credentials: 'same-origin'`, and `useCampaignCellAutosave` is the debounce / abort / revert / flush-on-close machine the quick-edit cells shipped three times. The shell keeps the `aria-live` region outside the Popover/Drawer, since closing is what commits and it was unmounting the node that would announce the result; `variant="sheet"` took a `footer` slot, which let the signal control drop the overlay it only kept for one button. Two bugs the extraction made visible: a revert issued while a different payload was in flight was dropped silently, and `change()` never cleared a past failure, which outranks everything the live region would otherwise say.
17 lines
727 B
TypeScript
17 lines
727 B
TypeScript
/**
|
|
* CSRF guard for cookie-authenticated JSON route handlers (auto-save popovers):
|
|
* a same-origin browser request either omits `Origin` (same-site navigation)
|
|
* or sends one matching the request URL; anything else is rejected before the
|
|
* body is even parsed. Its single consumer is `campaignJsonMutationRoute`,
|
|
* which is how every `POST /campanha/**` endpoint gets it: applying the policy
|
|
* here and the sharing there is what stops a new route from omitting it.
|
|
*/
|
|
export const isSameOriginRequest = (request: Request): boolean => {
|
|
const origin = request.headers.get('origin')
|
|
if (!origin) return true
|
|
try {
|
|
return new URL(origin).origin === new URL(request.url).origin
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|