summaryrefslogtreecommitdiff
path: root/packages/integrations/netlify/src
diff options
context:
space:
mode:
authorGravatar Arsh <69170106+lilnasy@users.noreply.github.com> 2024-02-06 17:02:25 +0000
committerGravatar GitHub <noreply@github.com> 2024-02-06 22:32:25 +0530
commitd68681b0606c9e0af79407ddab8dea5bbe18e557 (patch)
treeb7a2b225b8bc4ca28261ab0ce2f94c54befc9f95 /packages/integrations/netlify/src
parentd06f2b2f4936dfc2738807271bc5a01531cc9ae2 (diff)
downloadastro-d68681b0606c9e0af79407ddab8dea5bbe18e557.tar.gz
astro-d68681b0606c9e0af79407ddab8dea5bbe18e557.tar.zst
astro-d68681b0606c9e0af79407ddab8dea5bbe18e557.zip
feat(netlify): verification for edge middleware (#152)
* feat(netlify): verification for edge middleware * add changeset * remove unused folder
Diffstat (limited to 'packages/integrations/netlify/src')
-rw-r--r--packages/integrations/netlify/src/index.ts9
-rw-r--r--packages/integrations/netlify/src/ssr-function.ts12
2 files changed, 18 insertions, 3 deletions
diff --git a/packages/integrations/netlify/src/index.ts b/packages/integrations/netlify/src/index.ts
index e634c4ecc..63a17e7ab 100644
--- a/packages/integrations/netlify/src/index.ts
+++ b/packages/integrations/netlify/src/index.ts
@@ -6,6 +6,7 @@ import type { AstroConfig, AstroIntegration, RouteData } from 'astro';
import { AstroError } from 'astro/errors';
import { build } from 'esbuild';
import { appendFile, mkdir, readFile, rm, writeFile } from 'fs/promises';
+import type { Args } from "./ssr-function.js"
const { version: packageVersion } = JSON.parse(
await readFile(new URL('../package.json', import.meta.url), 'utf8')
@@ -75,6 +76,8 @@ export default function netlifyIntegration(
let outDir: URL;
let rootDir: URL;
let astroMiddlewareEntryPoint: URL | undefined = undefined;
+ // Secret used to verify that the caller is the astro-generated edge middleware and not a third-party
+ const middlewareSecret = crypto.randomUUID();
const ssrOutputDir = () => new URL('./.netlify/functions-internal/ssr/', rootDir);
const middlewareOutputDir = () => new URL('.netlify/edge-functions/middleware/', rootDir);
@@ -136,6 +139,7 @@ export default function netlifyIntegration(
const next = () => {
const { netlify, ...otherLocals } = ctx.locals;
request.headers.set("x-astro-locals", trySerializeLocals(otherLocals));
+ request.headers.set("x-astro-middleware-secret", "${middlewareSecret}");
return context.next();
};
@@ -270,6 +274,8 @@ export default function netlifyIntegration(
'See https://github.com/withastro/adapters/tree/main/packages/netlify#image-cdn for more.'
);
}
+
+ const edgeMiddleware = integrationConfig?.edgeMiddleware ?? false;
setAdapter({
name: '@astrojs/netlify',
@@ -277,8 +283,9 @@ export default function netlifyIntegration(
exports: ['default'],
adapterFeatures: {
functionPerRoute: false,
- edgeMiddleware: integrationConfig?.edgeMiddleware ?? false,
+ edgeMiddleware,
},
+ args: { middlewareSecret } satisfies Args,
supportedAstroFeatures: {
hybridOutput: 'stable',
staticOutput: 'stable',
diff --git a/packages/integrations/netlify/src/ssr-function.ts b/packages/integrations/netlify/src/ssr-function.ts
index 57d945a3c..d6067fac1 100644
--- a/packages/integrations/netlify/src/ssr-function.ts
+++ b/packages/integrations/netlify/src/ssr-function.ts
@@ -6,11 +6,13 @@ import { applyPolyfills } from 'astro/app/node';
applyPolyfills();
// biome-ignore lint/complexity/noBannedTypes: safe to use in this case
-export type Args = {};
+export interface Args {
+ middlewareSecret: string;
+};
const clientAddressSymbol = Symbol.for('astro.clientAddress');
-export const createExports = (manifest: SSRManifest, _args: Args) => {
+export const createExports = (manifest: SSRManifest, { middlewareSecret }: Args) => {
const app = new App(manifest);
function createHandler(integrationConfig: {
@@ -27,7 +29,13 @@ export const createExports = (manifest: SSRManifest, _args: Args) => {
let locals: Record<string, unknown> = {};
const astroLocalsHeader = request.headers.get('x-astro-locals');
+ const middlewareSecretHeader = request.headers.get('x-astro-middleware-secret');
if (astroLocalsHeader) {
+ if (middlewareSecretHeader !== middlewareSecret) {
+ return new Response("Forbidden", { status: 403 })
+ }
+ // hide the secret from the rest of user and library code
+ request.headers.delete('x-astro-middleware-secret');
locals = JSON.parse(astroLocalsHeader);
}