Merge branch 'main' into bare-standalone-paths
This commit is contained in:
commit
da08a0820a
7 changed files with 46 additions and 3 deletions
5
.changeset/curvy-owls-rest.md
Normal file
5
.changeset/curvy-owls-rest.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Ensure cookies are attached when middleware changes the Response
|
|
@ -1,2 +1,6 @@
|
||||||
export { AstroCookies } from './cookies.js';
|
export { AstroCookies } from './cookies.js';
|
||||||
export { attachCookiesToResponse, getSetCookiesFromResponse } from './response.js';
|
export {
|
||||||
|
attachCookiesToResponse,
|
||||||
|
getSetCookiesFromResponse,
|
||||||
|
responseHasCookies,
|
||||||
|
} from './response.js';
|
||||||
|
|
|
@ -6,6 +6,10 @@ export function attachCookiesToResponse(response: Response, cookies: AstroCookie
|
||||||
Reflect.set(response, astroCookiesSymbol, cookies);
|
Reflect.set(response, astroCookiesSymbol, cookies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function responseHasCookies(response: Response): boolean {
|
||||||
|
return Reflect.has(response, astroCookiesSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
function getFromResponse(response: Response): AstroCookies | undefined {
|
function getFromResponse(response: Response): AstroCookies | undefined {
|
||||||
let cookies = Reflect.get(response, astroCookiesSymbol);
|
let cookies = Reflect.get(response, astroCookiesSymbol);
|
||||||
if (cookies != null) {
|
if (cookies != null) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import type {
|
||||||
MiddlewareHandler,
|
MiddlewareHandler,
|
||||||
MiddlewareNext,
|
MiddlewareNext,
|
||||||
} from '../../@types/astro.js';
|
} from '../../@types/astro.js';
|
||||||
|
import { attachCookiesToResponse, responseHasCookies } from '../cookies/index.js';
|
||||||
import { AstroError, AstroErrorData } from '../errors/index.js';
|
import { AstroError, AstroErrorData } from '../errors/index.js';
|
||||||
import type { Environment } from '../render/index.js';
|
import type { Environment } from '../render/index.js';
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ export async function callMiddleware<R>(
|
||||||
if (value instanceof Response === false) {
|
if (value instanceof Response === false) {
|
||||||
throw new AstroError(AstroErrorData.MiddlewareNotAResponse);
|
throw new AstroError(AstroErrorData.MiddlewareNotAResponse);
|
||||||
}
|
}
|
||||||
return value as R;
|
return ensureCookiesAttached(apiContext, value as Response);
|
||||||
} else {
|
} else {
|
||||||
/**
|
/**
|
||||||
* Here we handle the case where `next` was called and returned nothing.
|
* Here we handle the case where `next` was called and returned nothing.
|
||||||
|
@ -105,11 +106,18 @@ export async function callMiddleware<R>(
|
||||||
throw new AstroError(AstroErrorData.MiddlewareNotAResponse);
|
throw new AstroError(AstroErrorData.MiddlewareNotAResponse);
|
||||||
} else {
|
} else {
|
||||||
// Middleware did not call resolve and returned a value
|
// Middleware did not call resolve and returned a value
|
||||||
return value as R;
|
return ensureCookiesAttached(apiContext, value as Response);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureCookiesAttached(apiContext: APIContext, response: Response): Response {
|
||||||
|
if (apiContext.cookies !== undefined && !responseHasCookies(response)) {
|
||||||
|
attachCookiesToResponse(response, apiContext.cookies);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
function isEndpointOutput(endpointResult: any): endpointResult is EndpointOutput {
|
function isEndpointOutput(endpointResult: any): endpointResult is EndpointOutput {
|
||||||
return (
|
return (
|
||||||
!(endpointResult instanceof Response) &&
|
!(endpointResult instanceof Response) &&
|
||||||
|
|
|
@ -24,6 +24,14 @@ const first = defineMiddleware(async (context, next) => {
|
||||||
const /** @type {string} */ html = await newResponse.text();
|
const /** @type {string} */ html = await newResponse.text();
|
||||||
const newhtml = html.replace('<h1>testing</h1>', '<h1>it works</h1>');
|
const newhtml = html.replace('<h1>testing</h1>', '<h1>it works</h1>');
|
||||||
return new Response(newhtml, { status: 200, headers: response.headers });
|
return new Response(newhtml, { status: 200, headers: response.headers });
|
||||||
|
} else if(context.url.pathname === '/return-response-cookies') {
|
||||||
|
const response = await next();
|
||||||
|
const html = await response.text();
|
||||||
|
|
||||||
|
return new Response(html, {
|
||||||
|
status: 200,
|
||||||
|
headers: response.headers
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
if (context.url.pathname === '/') {
|
if (context.url.pathname === '/') {
|
||||||
context.cookies.set('foo', 'bar');
|
context.cookies.set('foo', 'bar');
|
||||||
|
|
8
packages/astro/test/fixtures/middleware space/src/pages/return-response-cookies.astro
vendored
Normal file
8
packages/astro/test/fixtures/middleware space/src/pages/return-response-cookies.astro
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
Astro.cookies.set("astro", "cookie", {
|
||||||
|
httpOnly: true,
|
||||||
|
path: "/",
|
||||||
|
sameSite: "strict",
|
||||||
|
maxAge: 1704085200,
|
||||||
|
});
|
||||||
|
---
|
|
@ -79,6 +79,12 @@ describe('Middleware in DEV mode', () => {
|
||||||
let html = await res.text();
|
let html = await res.text();
|
||||||
expect(html).to.contain('<h1>it works</h1>');
|
expect(html).to.contain('<h1>it works</h1>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should forward cookies set in a component when the middleware returns a new response', async () => {
|
||||||
|
let res = await fixture.fetch('/return-response-cookies');
|
||||||
|
let headers = res.headers;
|
||||||
|
expect(headers.get('set-cookie')).to.not.equal(null);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Middleware in PROD mode, SSG', () => {
|
describe('Middleware in PROD mode, SSG', () => {
|
||||||
|
|
Loading…
Reference in a new issue