diff --git a/.changeset/witty-spies-occur.md b/.changeset/witty-spies-occur.md new file mode 100644 index 000000000000..1c717000ecba --- /dev/null +++ b/.changeset/witty-spies-occur.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix `enhance` error message when form action doesn't exist or csrf is enabled diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index c64894c8caa8..699932b58aa1 100644 --- a/packages/kit/src/runtime/server/index.js +++ b/packages/kit/src/runtime/server/index.js @@ -17,6 +17,7 @@ import { redirect_json_response, render_data } from './data/index.js'; import { add_cookies_to_headers, get_cookies } from './cookie.js'; import { create_fetch } from './fetch.js'; import { Redirect } from '../control.js'; +import { error, json } from '../../exports/index.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ @@ -40,9 +41,11 @@ export async function respond(request, options, state) { is_form_content_type(request); if (forbidden) { - return new Response(`Cross-site ${request.method} form submissions are forbidden`, { - status: 403 - }); + const csrf_error = error(403, `Cross-site ${request.method} form submissions are forbidden`); + if (request.headers.get('accept') === 'application/json') { + return json(csrf_error.body, { status: csrf_error.status }); + } + return new Response(csrf_error.body.message, { status: csrf_error.status }); } } diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index ccc312c533e9..7b57e58eedb6 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -18,22 +18,31 @@ export function is_action_json_request(event) { /** * @param {import('types').RequestEvent} event * @param {import('types').SSROptions} options - * @param {import('types').SSRNode['server']} server + * @param {import('types').SSRNode['server'] | undefined} server */ export async function handle_action_json_request(event, options, server) { - const actions = server.actions; + const actions = server?.actions; if (!actions) { - maybe_throw_migration_error(server); + if (server) { + maybe_throw_migration_error(server); + } // TODO should this be a different error altogether? - return new Response('POST method not allowed. No actions exist for this page', { - status: 405, - headers: { - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405 - // "The server must generate an Allow header field in a 405 status code response" - allow: 'GET' + const no_actions_error = error(405, 'POST method not allowed. No actions exist for this page'); + return action_json( + { + type: 'error', + error: await handle_error_and_jsonify(event, options, no_actions_error) + }, + { + status: no_actions_error.status, + headers: { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405 + // "The server must generate an Allow header field in a 405 status code response" + allow: 'GET' + } } - }); + ); } check_named_default_separate(actions); diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 1305d684bacd..c4e62dfc6d7d 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -40,9 +40,7 @@ export async function render_page(event, route, page, options, state, resolve_op if (is_action_json_request(event)) { const node = await options.manifest._.nodes[page.leaf](); - if (node.server) { - return handle_action_json_request(event, options, node.server); - } + return handle_action_json_request(event, options, node?.server); } try {