Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename Action query param to _action #12510

Open
wants to merge 2 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/sixty-fishes-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@astrojs/react': minor
'astro': minor
---

Changes the generated URL query param from `_astroAction` to `_action` when submitting a form using Actions. This avoids leaking the framework name into the URL bar, which may be considered a security issue.
2 changes: 1 addition & 1 deletion packages/astro/e2e/actions-blog.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ test.describe('Astro Actions - Blog', () => {
await page.goto(astro.resolveUrl('/sum'));
const submitButton = page.getByTestId('submit');
await submitButton.click();
await expect(page).toHaveURL(astro.resolveUrl('/sum?_astroAction=sum'));
await expect(page).toHaveURL(astro.resolveUrl('/sum?_action=sum'));
const p = page.locator('p').nth(0);
await expect(p).toContainText('Form result: {"data":3}');
});
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/actions/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = '\0astro:internal-actions';
export const NOOP_ACTIONS = '\0noop-actions';

export const ACTION_QUERY_PARAMS = {
actionName: '_astroAction',
actionName: '_action',
actionPayload: '_astroActionPayload',
};

Expand Down
12 changes: 6 additions & 6 deletions packages/astro/test/actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ describe('Astro Actions', () => {
});

it('Response middleware fallback - POST', async () => {
const req = new Request('http://example.com/user?_astroAction=getUser', {
const req = new Request('http://example.com/user?_action=getUser', {
method: 'POST',
body: new FormData(),
headers: {
Expand All @@ -237,7 +237,7 @@ describe('Astro Actions', () => {

it('Response middleware fallback - cookie forwarding', async () => {
const req = new Request(
'http://example.com/user?_astroAction=getUser&actionCookieForwarding=true',
'http://example.com/user?_action=getUser&actionCookieForwarding=true',
{
method: 'POST',
body: new FormData(),
Expand All @@ -255,7 +255,7 @@ describe('Astro Actions', () => {
});

it('Respects custom errors - POST', async () => {
const req = new Request('http://example.com/user-or-throw?_astroAction=getUserOrThrow', {
const req = new Request('http://example.com/user-or-throw?_action=getUserOrThrow', {
method: 'POST',
body: new FormData(),
headers: {
Expand All @@ -273,7 +273,7 @@ describe('Astro Actions', () => {

it('Respects custom errors - cookie forwarding', async () => {
const req = new Request(
'http://example.com/user-or-throw?_astroAction=getUserOrThrow&actionCookieForwarding=true',
'http://example.com/user-or-throw?_action=getUserOrThrow&actionCookieForwarding=true',
{
method: 'POST',
body: new FormData(),
Expand Down Expand Up @@ -320,8 +320,8 @@ describe('Astro Actions', () => {
assert.equal('safe' in data, true);
});

it('Ignores `_astroAction` name for GET requests', async () => {
const req = new Request('http://example.com/user-or-throw?_astroAction=getUserOrThrow', {
it('Ignores action name for GET requests', async () => {
const req = new Request('http://example.com/user-or-throw?_action=getUserOrThrow', {
method: 'GET',
});
const res = await app.render(req);
Expand Down
6 changes: 1 addition & 5 deletions packages/integrations/react/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,7 @@ async function getFormState({ result }) {
* This matches the endpoint path.
* @example "/_actions/blog.like"
*/
const actionName =
searchParams.get('_astroAction') ??
/* Legacy. TODO: remove for stable */ formData
.get('_astroAction')
?.toString();
const actionName = searchParams.get('_action');

if (!actionKey || !actionName) return undefined;

Expand Down
6 changes: 4 additions & 2 deletions packages/integrations/react/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function experimental_withState<T>(action: FormFn<T>) {
// Called by React when form state is passed from the server.
// If the action names match, React returns this state from `useActionState()`.
callback.$$IS_SIGNATURE_EQUAL = (incomingActionName: string) => {
const actionName = new URLSearchParams(action.toString()).get('_astroAction');
const actionName = new URLSearchParams(action.toString()).get('_action');
return actionName === incomingActionName;
};

Expand All @@ -46,7 +46,9 @@ export function experimental_withState<T>(action: FormFn<T>) {
*/
export async function experimental_getActionState<T>({
request,
}: { request: Request }): Promise<T> {
}: {
request: Request;
}): Promise<T> {
const contentType = request.headers.get('Content-Type');
if (!contentType || !isFormRequest(contentType)) {
throw new AstroError(
Expand Down
Loading