Skip to content

Commit

Permalink
Return Referrer-Policy header from /api/contact
Browse files Browse the repository at this point in the history
  • Loading branch information
paulshryock committed Jul 18, 2024
1 parent 0d679ae commit f4472ca
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 28 deletions.
36 changes: 21 additions & 15 deletions src/routes/api/contact.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import type { Context } from '@netlify/functions'
import site from '../../../src/data/site.js'

/**
* Default headers included in every response from this route.
*
* @since unreleased
*/
export const DEFAULT_HEADERS = {
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Origin': site.origin,
'Referrer-Policy': 'strict-origin-when-cross-origin',
} as const

/* eslint-disable */

/**
Expand All @@ -16,20 +27,15 @@ export default async function createMessage(
request: Request,
_context: Context,
): Promise<Response> {
const defaultHeaders = {
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Origin': site.origin,
}

if (request.method !== 'POST')
return new Response('Method Not Allowed', {
headers: new Headers({ ...defaultHeaders, Allow: 'POST' }),
headers: new Headers({ ...DEFAULT_HEADERS, Allow: 'POST' }),
status: 405,
})

if (request.headers.get('Origin') !== site.origin)
return new Response('Bad Request', {
headers: new Headers(defaultHeaders),
headers: new Headers(DEFAULT_HEADERS),
status: 400,
})

Expand All @@ -45,16 +51,16 @@ export default async function createMessage(
statusText: 'Bad Request',
}),
{
headers: new Headers(defaultHeaders),
headers: new Headers(DEFAULT_HEADERS),
status: 400,
},
)

const requiredFields = ['email', 'message', 'name'] as const
let fields: Record<(typeof requiredFields)[number], string>
let body: Record<(typeof requiredFields)[number], string>

try {
fields = await request.json()
body = await request.json()
} catch (error) {
console.error(error)
return new Response(
Expand All @@ -64,14 +70,14 @@ export default async function createMessage(
statusText: 'Bad Request',
}),
{
headers: new Headers(defaultHeaders),
headers: new Headers(DEFAULT_HEADERS),
status: 400,
},
)
}

for (const field of requiredFields) {
if (!(field in fields))
if (!(field in body))
return new Response(
JSON.stringify({
field,
Expand All @@ -80,7 +86,7 @@ export default async function createMessage(
statusText: 'Bad Request',
}),
{
headers: new Headers(defaultHeaders),
headers: new Headers(DEFAULT_HEADERS),
status: 400,
},
)
Expand All @@ -92,7 +98,7 @@ export default async function createMessage(
/* istanbul ignore next */
if (!messageWasCreated)
return new Response('Internal Server Error', {
headers: new Headers(defaultHeaders),
headers: new Headers(DEFAULT_HEADERS),
status: 500,
})

Expand All @@ -103,7 +109,7 @@ export default async function createMessage(
statusText: 'OK',
}),
{
headers: new Headers(defaultHeaders),
headers: new Headers(DEFAULT_HEADERS),
status: 200,
},
)
Expand Down
24 changes: 11 additions & 13 deletions tests/unit/routes/api/contact.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ import {
it,
jest,
} from '@jest/globals'
import createMessage, {
DEFAULT_HEADERS,
} from '../../../../src/routes/api/contact.ts'
import type { Context } from '@netlify/functions'
import createMessage from '../../../../src/routes/api/contact.ts'
import site from '../../../../src/data/site.js'

const PATH = '/api/contact'
const ROUTE = `${site.origin}${PATH}/`

const httpMethods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
const defaultHeaderFields = [
'Access-Control-Allow-Methods',
'Access-Control-Allow-Origin',
]

describe(PATH, () => {
describe.each(httpMethods.filter((method) => method !== 'POST'))(
Expand All @@ -28,7 +26,7 @@ describe(PATH, () => {
it('should return a 405 response status', async () =>
expect((await createMessage(request, {} as Context)).status).toBe(405))

it.each([...defaultHeaderFields, 'Allow'])(
it.each([...Object.keys(DEFAULT_HEADERS), 'Allow'])(
'should include an %s header',
async (header) =>
expect(
Expand All @@ -47,7 +45,7 @@ describe(PATH, () => {
it('should return a 400 response status', async () =>
expect((await createMessage(request, {} as Context)).status).toBe(400))

it.each(defaultHeaderFields)(
it.each(Object.keys(DEFAULT_HEADERS))(
'should include an %s header',
async (header) =>
expect(
Expand All @@ -63,7 +61,7 @@ describe(PATH, () => {
it('should return a 400 response status', async () =>
expect((await createMessage(request, {} as Context)).status).toBe(400))

it.each(defaultHeaderFields)(
it.each(Object.keys(DEFAULT_HEADERS))(
'should include an %s header',
async (header) =>
expect(
Expand All @@ -90,7 +88,7 @@ describe(PATH, () => {
400,
))

it.each(defaultHeaderFields)(
it.each(Object.keys(DEFAULT_HEADERS))(
'should include an %s header',
async (header) =>
expect(
Expand Down Expand Up @@ -132,7 +130,7 @@ describe(PATH, () => {
400,
))

it.each(defaultHeaderFields)(
it.each(Object.keys(DEFAULT_HEADERS))(
'should include an %s header',
async (header) =>
expect(
Expand Down Expand Up @@ -160,7 +158,7 @@ describe(PATH, () => {
)
})

it.each(defaultHeaderFields)(
it.each(Object.keys(DEFAULT_HEADERS))(
'should include an %s header',
async (header) => {
const request = new Request(ROUTE, { body, headers, method })
Expand Down Expand Up @@ -203,7 +201,7 @@ describe(PATH, () => {
)
})

it.each(defaultHeaderFields)(
it.each(Object.keys(DEFAULT_HEADERS))(
'should include an %s header',
async (header) => {
const request = new Request(ROUTE, { body, headers, method })
Expand All @@ -226,7 +224,7 @@ describe(PATH, () => {
)
})

it.each(defaultHeaderFields)(
it.each(Object.keys(DEFAULT_HEADERS))(
'should include an %s header',
async (header) => {
const request = new Request(ROUTE, { body, headers, method })
Expand Down

0 comments on commit f4472ca

Please sign in to comment.