From 9d907a2acd507e2ea99b15fd55b39275ac7bf7e2 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 07:59:25 +0800 Subject: [PATCH 01/10] add content-type check to enhance --- .changeset/witty-spies-occur.md | 5 +++++ packages/kit/src/runtime/app/forms.js | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .changeset/witty-spies-occur.md diff --git a/.changeset/witty-spies-occur.md b/.changeset/witty-spies-occur.md new file mode 100644 index 000000000000..97151ac6a25c --- /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 diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js index 7a0f97539f1f..636e63d852a8 100644 --- a/packages/kit/src/runtime/app/forms.js +++ b/packages/kit/src/runtime/app/forms.js @@ -1,4 +1,5 @@ import * as devalue from 'devalue'; +import { error } from '../../exports/index.js'; import { client } from '../client/singletons.js'; import { invalidateAll } from './navigation.js'; @@ -103,7 +104,13 @@ export function enhance(form, submit = () => {}) { signal: controller.signal }); - result = deserialize(await response.text()); + const response_text = await response.text(); + + if (response.headers.get('content-type') !== 'application/json') { + throw error(response.status, response_text); + } + + result = deserialize(response_text); } catch (error) { if (/** @type {any} */ (error)?.name === 'AbortError') return; result = { type: 'error', error }; From b25ab296e689c686c295feacc6d89e7785488ab3 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 18:33:27 +0800 Subject: [PATCH 02/10] revert content-type check for form enhance --- packages/kit/src/runtime/app/forms.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js index 636e63d852a8..d4f22e7955ab 100644 --- a/packages/kit/src/runtime/app/forms.js +++ b/packages/kit/src/runtime/app/forms.js @@ -104,13 +104,7 @@ export function enhance(form, submit = () => {}) { signal: controller.signal }); - const response_text = await response.text(); - - if (response.headers.get('content-type') !== 'application/json') { - throw error(response.status, response_text); - } - - result = deserialize(response_text); + result = deserialize(await response.text()); } catch (error) { if (/** @type {any} */ (error)?.name === 'AbortError') return; result = { type: 'error', error }; From 067a8ef74a0fa456b926446131cbde14a6f7370a Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 18:46:56 +0800 Subject: [PATCH 03/10] jsonify 'no actions exist' error response --- packages/kit/src/runtime/server/page/actions.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index ccc312c533e9..ccde085d4013 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -26,14 +26,17 @@ export async function handle_action_json_request(event, options, server) { if (!actions) { 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' + return new Response( + JSON.stringify({ message: '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' + } } - }); + ); } check_named_default_separate(actions); From 37f71ea50537c8fd32ddc21958fca7905faa0e47 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 19:20:50 +0800 Subject: [PATCH 04/10] handle missing server file for action request --- packages/kit/src/runtime/server/page/actions.js | 12 +++++++----- packages/kit/src/runtime/server/page/index.js | 5 ++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index ccde085d4013..52ac5932e375 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -18,16 +18,18 @@ 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( - JSON.stringify({ message: 'POST method not allowed. No actions exist for this page' }), + return json( + { message: 'POST method not allowed. No actions exist for this page' }, { status: 405, headers: { diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 1305d684bacd..e9aa2d5fc8ea 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -1,3 +1,4 @@ +import { json } from '../../../exports/index.js'; import { compact } from '../../../utils/array.js'; import { normalize_error } from '../../../utils/error.js'; import { add_data_suffix } from '../../../utils/url.js'; @@ -40,9 +41,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 { From 746ea2e0ae6ed945d3126b67936cb3fa4f1a9902 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 19:33:03 +0800 Subject: [PATCH 05/10] remove unused imports --- packages/kit/src/runtime/app/forms.js | 1 - packages/kit/src/runtime/server/page/index.js | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js index d4f22e7955ab..7a0f97539f1f 100644 --- a/packages/kit/src/runtime/app/forms.js +++ b/packages/kit/src/runtime/app/forms.js @@ -1,5 +1,4 @@ import * as devalue from 'devalue'; -import { error } from '../../exports/index.js'; import { client } from '../client/singletons.js'; import { invalidateAll } from './navigation.js'; diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index e9aa2d5fc8ea..c4e62dfc6d7d 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -1,4 +1,3 @@ -import { json } from '../../../exports/index.js'; import { compact } from '../../../utils/array.js'; import { normalize_error } from '../../../utils/error.js'; import { add_data_suffix } from '../../../utils/url.js'; From c87a2c2505c3dfcccd2012915179298e03d332ac Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 19:46:45 +0800 Subject: [PATCH 06/10] jsonify csrf error response --- packages/kit/src/runtime/server/index.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index c64894c8caa8..ab39923b539d 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 { json } from '../../exports/index.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ @@ -40,9 +41,12 @@ 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 - }); + return json( + { message: `Cross-site ${request.method} form submissions are forbidden` }, + { + status: 403 + } + ); } } From cd40d9e822dacc95de03f850131a7a10a851b1bc Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 19:54:16 +0800 Subject: [PATCH 07/10] revert jsonify --- packages/kit/src/runtime/server/index.js | 10 +++------- packages/kit/src/runtime/server/page/actions.js | 17 +++++++---------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index ab39923b539d..c64894c8caa8 100644 --- a/packages/kit/src/runtime/server/index.js +++ b/packages/kit/src/runtime/server/index.js @@ -17,7 +17,6 @@ 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 { json } from '../../exports/index.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ @@ -41,12 +40,9 @@ export async function respond(request, options, state) { is_form_content_type(request); if (forbidden) { - return json( - { message: `Cross-site ${request.method} form submissions are forbidden` }, - { - status: 403 - } - ); + return new Response(`Cross-site ${request.method} form submissions are forbidden`, { + status: 403 + }); } } diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 52ac5932e375..21073937b830 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -28,17 +28,14 @@ export async function handle_action_json_request(event, options, server) { maybe_throw_migration_error(server); } // TODO should this be a different error altogether? - return json( - { message: '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' - } + 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' } - ); + }); } check_named_default_separate(actions); From b8f8ca819d56acf73926f9191f969ee26f32fa5a Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 20:48:02 +0800 Subject: [PATCH 08/10] add handle_error_and_jsonify --- .../kit/src/runtime/server/page/actions.js | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 21073937b830..7b57e58eedb6 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -28,14 +28,21 @@ export async function handle_action_json_request(event, options, 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); From dea4b80fbfa95255c858bce0badd1a3dbdb79638 Mon Sep 17 00:00:00 2001 From: Tee Ming Date: Tue, 6 Dec 2022 21:37:16 +0800 Subject: [PATCH 09/10] add case for jsonifying csrf error response --- packages/kit/src/runtime/server/index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 }); } } From 8491ba0bb50597a3b12948d8c6bbfb12b6285e2d Mon Sep 17 00:00:00 2001 From: Tee Ming <54401897+s3812497@users.noreply.github.com> Date: Tue, 6 Dec 2022 21:41:04 +0800 Subject: [PATCH 10/10] update changeset patch note --- .changeset/witty-spies-occur.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/witty-spies-occur.md b/.changeset/witty-spies-occur.md index 97151ac6a25c..1c717000ecba 100644 --- a/.changeset/witty-spies-occur.md +++ b/.changeset/witty-spies-occur.md @@ -2,4 +2,4 @@ '@sveltejs/kit': patch --- -fix `enhance` error message when form action doesn't exist +fix `enhance` error message when form action doesn't exist or csrf is enabled