Skip to content

Commit bbba9f1

Browse files
committed
Fix JWKS endpoint headers
1 parent 677bba3 commit bbba9f1

3 files changed

Lines changed: 12 additions & 9 deletions

File tree

apps/backend/src/app/api/latest/projects/[project_id]/.well-known/jwks.json/route.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { yupArray, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields";
1+
import { yupArray, yupNumber, yupObject, yupString, yupTuple } from "@stackframe/stack-shared/dist/schema-fields";
22
import { StatusError } from "@stackframe/stack-shared/dist/utils/errors";
33
import { deindent } from "@stackframe/stack-shared/dist/utils/strings";
44
import { getProject } from "../../../../../../../lib/projects";
@@ -27,7 +27,9 @@ export const GET = createSmartRouteHandler({
2727
body: yupObject({
2828
keys: yupArray().defined(),
2929
}).defined(),
30-
30+
headers: yupObject({
31+
"Cache-Control": yupTuple([yupString().defined()]).defined(),
32+
}).defined(),
3133
}),
3234
async handler({ params, query }) {
3335
const project = await getProject(params.project_id);
@@ -42,7 +44,7 @@ export const GET = createSmartRouteHandler({
4244
body: await getPublicProjectJwkSet(params.project_id, query.include_anonymous === "true"),
4345
headers: {
4446
// Cache for 1 hour
45-
"Cache-Control": "public, max-age=3600",
47+
"Cache-Control": ["public, max-age=3600"] as const,
4648
},
4749
};
4850
},

apps/backend/src/route-handlers/smart-response.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,16 +122,16 @@ export async function createResponse<T extends SmartResponse>(req: NextRequest |
122122
headers.set("x-stack-actual-status", [obj.statusCode.toString()]);
123123
}
124124

125+
// set all headers from the smart response (considering case insensitivity)
126+
for (const [key, values] of Object.entries(obj.headers ?? {})) {
127+
headers.set(key.toLowerCase(), values);
128+
}
129+
125130
return new Response(
126131
arrayBufferBody,
127132
{
128133
status,
129-
headers: [
130-
...Object.entries({
131-
...Object.fromEntries(headers),
132-
...obj.headers ?? {}
133-
}).flatMap(([key, values]) => values.map(v => [key.toLowerCase(), v!] as [string, string])),
134-
],
134+
headers: [...headers].flatMap(([key, values]) => values.map(v => [key, v] satisfies [string, string])),
135135
},
136136
);
137137
});

apps/e2e/tests/backend/endpoints/api/v1/projects.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,7 @@ it("has a correctly formatted JWKS endpoint", async ({ expect }) => {
14771477
const response = await niceBackendFetch("/api/v1/projects/internal/.well-known/jwks.json");
14781478
expect(response.status).toBe(200);
14791479
expect(response.headers.get("content-type")).includes("application/json");
1480+
expect(response.headers.get("cache-control")).toBe("public, max-age=3600");
14801481
expect(response.body).toEqual({
14811482
keys: [
14821483
{

0 commit comments

Comments
 (0)