├── .editorconfig ├── .gitattributes ├── .gitignore ├── .npmrc ├── .travis.yml ├── index.js ├── license ├── package.json ├── readme.md └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.yml] 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.js text eol=lf 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn.lock 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '8' 4 | - '6' 5 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = opts => (req, res) => { 4 | opts = Object.assign({}, opts); 5 | 6 | const allowCredentials = process.env.ACCESS_ALLOW_CREDENTIALS || opts.allowCredentials; 7 | const allowHeaders = process.env.ACCESS_ALLOW_HEADERS || opts.allowHeaders; 8 | const allowMethods = process.env.ACCESS_ALLOW_METHODS || opts.allowMethods; 9 | const allowOrigin = process.env.ACCESS_ALLOW_ORIGIN || opts.allowOrigin; 10 | const exposeHeaders = process.env.ACCESS_EXPOSE_HEADERS || opts.exposeHeaders; 11 | const maxAge = process.env.ACCESS_MAX_AGE || opts.maxAge; 12 | 13 | if (allowCredentials) { 14 | const val = typeof allowCredentials === 'string' ? Number(allowCredentials) : allowCredentials; 15 | 16 | if (val) { 17 | res.setHeader('access-control-allow-credentials', Boolean(val)); 18 | } 19 | } 20 | 21 | if (allowHeaders) { 22 | const val = Array.isArray(allowHeaders) ? allowHeaders.join(',') : allowHeaders; 23 | res.setHeader('access-control-allow-headers', val); 24 | } 25 | 26 | if (allowMethods) { 27 | const val = Array.isArray(allowMethods) ? allowMethods.join(',') : allowMethods; 28 | res.setHeader('access-control-allow-methods', val); 29 | } 30 | 31 | if (allowOrigin) { 32 | res.setHeader('access-control-allow-origin', allowOrigin); 33 | 34 | if (allowOrigin !== '*') { 35 | res.setHeader('vary', 'origin'); 36 | } 37 | } 38 | 39 | if (exposeHeaders) { 40 | const val = Array.isArray(exposeHeaders) ? exposeHeaders.join(',') : exposeHeaders; 41 | res.setHeader('Access-Control-Expose-Headers', val); 42 | } 43 | 44 | if (maxAge) { 45 | res.setHeader('access-control-max-age', String(maxAge)); 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Kevin Mårtensson (github.com/kevva) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "control-access", 3 | "version": "0.1.1", 4 | "description": "Easy CORS handling", 5 | "license": "MIT", 6 | "repository": "kevva/control-access", 7 | "author": { 8 | "name": "Kevin Mårtensson", 9 | "email": "kevinmartensson@gmail.com", 10 | "url": "github.com/kevva" 11 | }, 12 | "engines": { 13 | "node": ">=4" 14 | }, 15 | "scripts": { 16 | "test": "xo && ava" 17 | }, 18 | "files": [ 19 | "index.js" 20 | ], 21 | "keywords": [ 22 | "access", 23 | "allow", 24 | "control", 25 | "cors", 26 | "headers", 27 | "http", 28 | "https", 29 | "methods", 30 | "maxage", 31 | "middleware", 32 | "origin" 33 | ], 34 | "devDependencies": { 35 | "ava": "^*", 36 | "got": "^7.1.0", 37 | "micro": "^9.0.0", 38 | "test-listen": "^1.0.2", 39 | "xo": "*" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # control-access [![Build Status](https://travis-ci.org/kevva/control-access.svg?branch=master)](https://travis-ci.org/kevva/control-access) 2 | 3 | > Easy CORS handling 4 | 5 | 6 | ## Install 7 | 8 | ``` 9 | $ npm install control-access 10 | ``` 11 | 12 | 13 | ## Usage 14 | 15 | ```js 16 | const controlAccess = require('control-access'); 17 | 18 | module.exports = (req, res) => { 19 | controlAccess()(req, res); 20 | res.end('unicorns'); 21 | }; 22 | ``` 23 | 24 | 25 | ## API 26 | 27 | ### controlAccess([options])(request, response) 28 | 29 | #### options 30 | 31 | Type: `Object` 32 | 33 | ##### allowCredentials 34 | 35 | Type: `boolean` 36 | 37 | [`Access-Control-Allow-Credentials`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials) indicates whether or not the response to the request can be exposed when the credentials flag is true. 38 | 39 | Can be set globally with the `ACCESS_ALLOW_CREDENTIALS` environment variable. Possible values are `1` and `0`. 40 | 41 | ##### allowHeaders 42 | 43 | Type: `Array` `string` 44 | 45 | [`Access-Control-Allow-Headers`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. 46 | 47 | Can be set globally with the `ACCESS_ALLOW_HEADERS` environment variable using a comma delimited string. 48 | 49 | ##### allowMethods 50 | 51 | Type: `Array` `string` 52 | 53 | [`Access-Control-Allow-Methods`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods) specifies the method or methods allowed when accessing the resource. 54 | 55 | Can be set globally with the `ACCESS_ALLOW_METHODS` environment variable using a comma delimited string. 56 | 57 | ##### allowOrigin 58 | 59 | Type: `string` 60 | 61 | [`Access-Control-Allow-Origin`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) specifies a URI that may access the resource. 62 | 63 | Can be set globally with the `ACCESS_ALLOW_ORIGIN` environment variable. 64 | 65 | ##### exposeHeaders 66 | 67 | Type: `Array` `string` 68 | 69 | [`Access-Control-Expose-Headers`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers) response header indicates which headers can be exposed as part of the response. 70 | 71 | Can be set globally with the `ACCESS_EXPOSE_HEADERS` environment variable using a comma delimited string. 72 | 73 | ##### maxAge 74 | 75 | Type: `number` 76 | 77 | [`Access-Control-Max-Age`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age) indicates how long the results of a preflight request can be cached. 78 | 79 | Can be set globally with the `ACCESS_MAX_AGE` environment variable. 80 | 81 | #### request 82 | 83 | Type: `http.IncomingMessage` 84 | 85 | Incoming HTTP request. 86 | 87 | #### response 88 | 89 | Type: `http.ServerResponse` 90 | 91 | Response object. 92 | 93 | 94 | ## Related 95 | 96 | * [micro-access](https://github.com/kevva/micro-access) - Easy CORS handling for `micro` 97 | 98 | 99 | ## License 100 | 101 | MIT © [Kevin Mårtensson](https://github.com/kevva) 102 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | import {serial as test} from 'ava'; 2 | import got from 'got'; 3 | import micro from 'micro'; 4 | import testListen from 'test-listen'; 5 | import m from '.'; 6 | 7 | const macro = async (t, {header, opts}, expected) => { 8 | const handler = (req, res) => { 9 | m(opts)(req, res); 10 | return {}; 11 | }; 12 | 13 | const url = await testListen(micro(handler)); 14 | t.is((await got(url, {json: true})).headers[header], expected); 15 | }; 16 | 17 | const envMacro = async (t, {env, header}, expected) => { 18 | const ENV = process.env[env.key]; 19 | process.env[env.key] = env.value; 20 | 21 | const handler = (req, res) => { 22 | m()(req, res); 23 | return {}; 24 | }; 25 | 26 | const url = await testListen(micro(handler)); 27 | t.is((await got(url, {json: true})).headers[header], expected); 28 | process.env[env.key] = ENV; 29 | }; 30 | 31 | test('set allowCredentials', [macro, envMacro], { 32 | opts: {allowCredentials: true}, 33 | header: 'access-control-allow-credentials', 34 | env: { 35 | key: 'ACCESS_ALLOW_CREDENTIALS', 36 | value: '1' 37 | } 38 | }, 'true'); 39 | 40 | test('omit setting allowCredentials if value is falsy', [macro, envMacro], { 41 | opts: {allowCredentials: false}, 42 | header: 'access-control-allow-credentials', 43 | env: { 44 | key: 'ACCESS_ALLOW_CREDENTIALS', 45 | value: '0' 46 | } 47 | }, undefined); 48 | 49 | test('set allowHeaders', [macro, envMacro], { 50 | opts: {allowHeaders: ['Foo', 'Bar']}, 51 | header: 'access-control-allow-headers', 52 | env: { 53 | key: 'ACCESS_ALLOW_HEADERS', 54 | value: 'Foo,Bar' 55 | } 56 | }, 'Foo,Bar'); 57 | 58 | test('set allowMethods', [macro, envMacro], { 59 | opts: {allowMethods: ['GET', 'POST']}, 60 | header: 'access-control-allow-methods', 61 | env: { 62 | key: 'ACCESS_ALLOW_METHODS', 63 | value: 'GET,POST' 64 | } 65 | }, 'GET,POST'); 66 | 67 | test('set allowOrigin', [macro, envMacro], { 68 | opts: {allowOrigin: '*'}, 69 | header: 'access-control-allow-origin', 70 | env: { 71 | key: 'ACCESS_ALLOW_ORIGIN', 72 | value: '*' 73 | } 74 | }, '*'); 75 | 76 | test('set exposeHeaders', [macro, envMacro], { 77 | opts: {exposeHeaders: ['Foo', 'Bar']}, 78 | header: 'access-control-expose-headers', 79 | env: { 80 | key: 'ACCESS_EXPOSE_HEADERS', 81 | value: 'Foo,Bar' 82 | } 83 | }, 'Foo,Bar'); 84 | 85 | test('set maxAge', [macro, envMacro], { 86 | opts: {maxAge: 1024}, 87 | header: 'access-control-max-age', 88 | env: { 89 | key: 'ACCESS_MAX_AGE', 90 | value: '1024' 91 | } 92 | }, '1024'); 93 | --------------------------------------------------------------------------------