basant307/AI_Governance_Project
048
1(function () {2 3 'use strict';4 5 var assign = require('object-assign');6 var vary = require('vary');7 8 var defaults = {9 origin: '*',10 methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',11 preflightContinue: false,12 optionsSuccessStatus: 20413 };14 15 function isString(s) {16 return typeof s === 'string' || s instanceof String;17 }18 19 function isOriginAllowed(origin, allowedOrigin) {20 if (Array.isArray(allowedOrigin)) {21 for (var i = 0; i < allowedOrigin.length; ++i) {22 if (isOriginAllowed(origin, allowedOrigin[i])) {23 return true;24 }25 }26 return false;27 } else if (isString(allowedOrigin)) {28 return origin === allowedOrigin;29 } else if (allowedOrigin instanceof RegExp) {30 return allowedOrigin.test(origin);31 } else {32 return !!allowedOrigin;33 }34 }35 36 function configureOrigin(options, req) {37 var requestOrigin = req.headers.origin,38 headers = [],39 isAllowed;40 41 if (!options.origin || options.origin === '*') {42 // allow any origin43 headers.push([{44 key: 'Access-Control-Allow-Origin',45 value: '*'46 }]);47 } else if (isString(options.origin)) {48 // fixed origin49 headers.push([{50 key: 'Access-Control-Allow-Origin',51 value: options.origin52 }]);53 headers.push([{54 key: 'Vary',55 value: 'Origin'56 }]);57 } else {58 isAllowed = isOriginAllowed(requestOrigin, options.origin);59 // reflect origin60 headers.push([{61 key: 'Access-Control-Allow-Origin',62 value: isAllowed ? requestOrigin : false63 }]);64 headers.push([{65 key: 'Vary',66 value: 'Origin'67 }]);68 }69 70 return headers;71 }72 73 function configureMethods(options) {74 var methods = options.methods;75 if (methods.join) {76 methods = options.methods.join(','); // .methods is an array, so turn it into a string77 }78 return {79 key: 'Access-Control-Allow-Methods',80 value: methods81 };82 }83 84 function configureCredentials(options) {85 if (options.credentials === true) {86 return {87 key: 'Access-Control-Allow-Credentials',88 value: 'true'89 };90 }91 return null;92 }93 94 function configureAllowedHeaders(options, req) {95 var allowedHeaders = options.allowedHeaders || options.headers;96 var headers = [];97 98 if (!allowedHeaders) {99 allowedHeaders = req.headers['access-control-request-headers']; // .headers wasn't specified, so reflect the request headers100 headers.push([{101 key: 'Vary',102 value: 'Access-Control-Request-Headers'103 }]);104 } else if (allowedHeaders.join) {105 allowedHeaders = allowedHeaders.join(','); // .headers is an array, so turn it into a string106 }107 if (allowedHeaders && allowedHeaders.length) {108 headers.push([{109 key: 'Access-Control-Allow-Headers',110 value: allowedHeaders111 }]);112 }113 114 return headers;115 }116 117 function configureExposedHeaders(options) {118 var headers = options.exposedHeaders;119 if (!headers) {120 return null;121 } else if (headers.join) {122 headers = headers.join(','); // .headers is an array, so turn it into a string123 }124 if (headers && headers.length) {125 return {126 key: 'Access-Control-Expose-Headers',127 value: headers128 };129 }130 return null;131 }132 133 function configureMaxAge(options) {134 var maxAge = (typeof options.maxAge === 'number' || options.maxAge) && options.maxAge.toString()135 if (maxAge && maxAge.length) {136 return {137 key: 'Access-Control-Max-Age',138 value: maxAge139 };140 }141 return null;142 }143 144 function applyHeaders(headers, res) {145 for (var i = 0, n = headers.length; i < n; i++) {146 var header = headers[i];147 if (header) {148 if (Array.isArray(header)) {149 applyHeaders(header, res);150 } else if (header.key === 'Vary' && header.value) {151 vary(res, header.value);152 } else if (header.value) {153 res.setHeader(header.key, header.value);154 }155 }156 }157 }158 159 function cors(options, req, res, next) {160 var headers = [],161 method = req.method && req.method.toUpperCase && req.method.toUpperCase();162 163 if (method === 'OPTIONS') {164 // preflight165 headers.push(configureOrigin(options, req));166 headers.push(configureCredentials(options, req));167 headers.push(configureMethods(options, req));168 headers.push(configureAllowedHeaders(options, req));169 headers.push(configureMaxAge(options, req));170 headers.push(configureExposedHeaders(options, req));171 applyHeaders(headers, res);172 173 if (options.preflightContinue) {174 next();175 } else {176 // Safari (and potentially other browsers) need content-length 0,177 // for 204 or they just hang waiting for a body178 res.statusCode = options.optionsSuccessStatus;179 res.setHeader('Content-Length', '0');180 res.end();181 }182 } else {183 // actual response184 headers.push(configureOrigin(options, req));185 headers.push(configureCredentials(options, req));186 headers.push(configureExposedHeaders(options, req));187 applyHeaders(headers, res);188 next();189 }190 }191 192 function middlewareWrapper(o) {193 // if options are static (either via defaults or custom options passed in), wrap in a function194 var optionsCallback = null;195 if (typeof o === 'function') {196 optionsCallback = o;197 } else {198 optionsCallback = function (req, cb) {199 cb(null, o);200 };201 }202 203 return function corsMiddleware(req, res, next) {204 optionsCallback(req, function (err, options) {205 if (err) {206 next(err);207 } else {208 var corsOptions = assign({}, defaults, options);209 var originCallback = null;210 if (corsOptions.origin && typeof corsOptions.origin === 'function') {211 originCallback = corsOptions.origin;212 } else if (corsOptions.origin) {213 originCallback = function (origin, cb) {214 cb(null, corsOptions.origin);215 };216 }217 218 if (originCallback) {219 originCallback(req.headers.origin, function (err2, origin) {220 if (err2 || !origin) {221 next(err2);222 } else {223 corsOptions.origin = origin;224 cors(corsOptions, req, res, next);225 }226 });227 } else {228 next();229 }230 }231 });232 };233 }234 235 // can pass either an options hash, an options delegate, or nothing236 module.exports = middlewareWrapper;237 238}());239 