Skip to content

Commit

Permalink
fix: add content type header middleware (#303)
Browse files Browse the repository at this point in the history
* fix: add content type header middleware

* feat: move content type validation to own middleware

* feat: remove temp console.log

* feat: update session tests to always have content-type header
  • Loading branch information
karrui authored Jun 27, 2024
1 parent 73621d9 commit 2e15005
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
16 changes: 16 additions & 0 deletions src/server/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ const loggerWithVersionMiddleware = loggerMiddleware.unstable_pipe(
},
)

const contentTypeHeaderMiddleware = t.middleware(async ({ ctx, next }) => {
if (
ctx.req.body &&
!ctx.req.headers['content-type']?.startsWith('application/json')
) {
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Invalid Content-Type',
})
}
return next()
})

const baseMiddleware = t.middleware(async ({ ctx, next }) => {
if (ctx.session === undefined) {
throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR' })
Expand Down Expand Up @@ -157,17 +170,20 @@ export const router = t.router
**/
export const publicProcedure = t.procedure
.use(loggerWithVersionMiddleware)
.use(contentTypeHeaderMiddleware)
.use(baseMiddleware)

/**
* Create a protected procedure
**/
export const protectedProcedure = t.procedure
.use(loggerWithVersionMiddleware)
.use(contentTypeHeaderMiddleware)
.use(authMiddleware)

export const agnosticProcedure = t.procedure
.use(loggerWithVersionMiddleware)
.use(contentTypeHeaderMiddleware)
.use(nonStrictAuthMiddleware)

/**
Expand Down
13 changes: 11 additions & 2 deletions tests/integration/helpers/iron-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,20 @@ class MockIronStore {
export const createMockRequest = async (
session: Session,
reqOptions: RequestOptions = { method: 'GET' },
resOptions?: ResponseOptions
resOptions?: ResponseOptions,
): Promise<Context> => {
const innerContext = await createContextInner({ session })

const { req, res } = createMocks(reqOptions, resOptions)
const { req, res } = createMocks(
{
...reqOptions,
headers: {
'content-type': 'application/json', // will always be application/json
...reqOptions.headers,
},
},
resOptions,
)

return {
...innerContext,
Expand Down

0 comments on commit 2e15005

Please sign in to comment.