Skip to content

Commit

Permalink
Make createCors({ origins }) to accept function (#157)
Browse files Browse the repository at this point in the history
* Make createCors({ origins }) to accept function

* Cosmetic

* Update createCors.spec.ts

* Update createCors.spec.ts

* Update createCors.spec.ts

* createCors.ts should export CorsOptions

---------

Co-authored-by: Yuji Sugiura <[email protected]>
Co-authored-by: Kevin R. Whitley <[email protected]>
  • Loading branch information
3 people authored Nov 25, 2023
1 parent a20651e commit 80f89b2
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
46 changes: 46 additions & 0 deletions src/createCors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,52 @@ describe('createCors(options)', () => {

expect(response.headers.get('Access-Control-Max-Age')).toBe('60')
})

it('origins should be array of string', async () => {
const { preflight } = createCors({
origins: ['http://localhost:3000', 'http://localhost:4000']
})
const router = Router().all('*', preflight)

const generateRequest = (origin: string) => new Request('https://foo.bar', {
method: 'OPTIONS',
headers: {
'Access-Control-Request-Method': 'GET',
'Access-Control-Request-Headers': 'content-type',
origin,
}
})

const response1 = await router.handle(generateRequest('http://localhost:3000'))
expect(response1.headers.get('Access-Control-Allow-Origin')).toBe('http://localhost:3000')
const response2 = await router.handle(generateRequest('http://localhost:4000'))
expect(response2.headers.get('Access-Control-Allow-Origin')).toBe('http://localhost:4000')
const response3 = await router.handle(generateRequest('http://localhost:5000'))
expect(response3.headers.get('Access-Control-Allow-Origin')).toBe(null)
})

it('origins should be function returns boolean', async () => {
const { preflight } = createCors({
origins: (origin) => origin.startsWith('https://') && origin.endsWith('.example.com')
})
const router = Router().all('*', preflight)

const generateRequest = (origin: string) => new Request('https://foo.bar', {
method: 'OPTIONS',
headers: {
'Access-Control-Request-Method': 'GET',
'Access-Control-Request-Headers': 'content-type',
origin,
}
})

const response1 = await router.handle(generateRequest('https://secure.example.com'))
expect(response1.headers.get('Access-Control-Allow-Origin')).toBe('https://secure.example.com')
const response2 = await router.handle(generateRequest('https://another-secure.example.com'))
expect(response2.headers.get('Access-Control-Allow-Origin')).toBe('https://another-secure.example.com')
const response3 = await router.handle(generateRequest('http://unsecure.example.com'))
expect(response3.headers.get('Access-Control-Allow-Origin')).toBe(null)
})
})

describe('preflight (middleware)', () => {
Expand Down
13 changes: 7 additions & 6 deletions src/createCors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IRequest } from './Router'

export interface CorsOptions {
origins?: string[]
export type CorsOptions = {
origins?: string[] | ((origin: string) => boolean)
maxAge?: number
methods?: string[]
headers?: any
Expand All @@ -13,6 +13,9 @@ export const createCors = (options: CorsOptions = {}) => {
const { origins = ['*'], maxAge, methods = ['GET'], headers = {} } = options

let allowOrigin: any
const isAllowOrigin = typeof origins === 'function'
? origins
: (origin: string) => (origins.includes(origin) || origins.includes('*'))

// Initial response headers.
const rHeaders = {
Expand All @@ -30,10 +33,8 @@ export const createCors = (options: CorsOptions = {}) => {
const useMethods = [...new Set(['OPTIONS', ...methods])]
const origin = r.headers.get('origin') || ''

// Set allowOrigin globally.
allowOrigin = (origins.includes(origin) || origins.includes('*')) && {
'Access-Control-Allow-Origin': origin,
}
// set allowOrigin globally
allowOrigin = isAllowOrigin(origin) && { 'Access-Control-Allow-Origin': origin }

// Check if method is OPTIONS.
if (r.method === 'OPTIONS') {
Expand Down

0 comments on commit 80f89b2

Please sign in to comment.