Code coverage report for esecurity/lib/middleware/cors.js

Statements: 100% (47 / 47)      Branches: 95.45% (42 / 44)      Functions: 100% (4 / 4)      Lines: 100% (47 / 47)      Ignored: none     

All files » esecurity/lib/middleware/ » cors.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89  1   16 16 16 16 16 16 16   16 16 16     16 43     16     16 2   14     14 2     12 4     8     5 1     4 4 4 3 3       4 1       3 2 2     1     3 3   3 3   3 3   3     3 2 2     1     3      
 
module.exports = function CorsConstructor(opts) {
 
    opts = opts || {};
    opts.origin = opts.origin || '*';
    opts.credentials = opts.credentials || false;
    opts.methods = opts.methods || ['GET', 'PUT', 'POST', 'DELETE'];
    opts.headers = opts.headers || ['Origin', 'X-Requested-With', 'Content-Type', 'Accept'];
    opts.exposeHeaders = opts.exposeHeaders || false;
    opts.maxAge = opts.maxAge || 0;
    
    'string' === typeof opts.methods && (opts.methods = opts.methods.split(','));
    'string' === typeof opts.headers && (opts.headers = opts.headers.split(','));
    'string' === typeof opts.exposeHeaders && (opts.exposeHeaders = opts.exposeHeaders.split(','));
    
    // ensure methods are in uppercase
    opts.methods.forEach(function (method, key) {
        opts.methods[key] = String(method).toUpperCase();
    });
    
    return function cors(req, res, next) {
        
        // self-awareness
        if (req._esecurity_cors)
            return next();
 
        req._esecurity_cors = true;
        
        // Exit if it is a same-origin request
        if (!req.get('origin'))
            return next();
            
        // check allowed origin
        if ('*' !== opts.origin && req.get('origin') !== opts.origin)
            return next();
            
        // handle preflight requests
        if ('OPTIONS' === req.method) {
        
            // check allowed methods
            if (!~opts.methods.indexOf(req.get('access-control-request-method')))
                return next();
                
            // check allowed headers
            var headersAllowed = false;
            req.get('access-control-request-headers').split(',').some(function (header) {
                if (~opts.headers.indexOf(header)) {
                    headersAllowed = true;
                    return true;
                }
            });
            
            if (!headersAllowed)
                return next();
                
            // add CORS headers
            
            if (opts.credentials) {
                res.set('Access-Control-Allow-Origin', req.headers.origin);
                res.set('Access-Control-Allow-Credentials', 'true');
            }
            else {
                res.set('Access-Control-Allow-Origin', opts.origin);
            }
            
            Eif (opts.maxAge)
                res.set('Access-Control-Max-Age', opts.maxAge);
            
            res.set('Access-Control-Allow-Methods', opts.methods.join(','));
            res.set('Access-Control-Allow-Headers', opts.headers.join(','));
            
            Eif (opts.exposeHeaders)
                res.set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','));
            
            return res.status(204).end();
        }
        
        if (opts.credentials) {
            res.set('Access-Control-Allow-Origin', req.headers.origin);
            res.set('Access-Control-Allow-Credentials', 'true');
        }
        else {
            res.set('Access-Control-Allow-Origin', opts.origin);
        }
        
        return next();
    };
};