Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / csurf / index.js
1 /*!
2  * csurf
3  * Copyright(c) 2011 Sencha Inc.
4  * Copyright(c) 2014 Jonathan Ong
5  * Copyright(c) 2014-2015 Douglas Christopher Wilson
6  * MIT Licensed
7  */
8
9 /**
10  * Module dependencies.
11  * @private
12  */
13
14 var Cookie = require('cookie');
15 var createError = require('http-errors');
16 var sign = require('cookie-signature').sign;
17 var Tokens = require('csrf');
18
19 /**
20  * CSRF protection middleware.
21  *
22  * This middleware adds a `req.csrfToken()` function to make a token
23  * which should be added to requests which mutate
24  * state, within a hidden form field, query-string etc. This
25  * token is validated against the visitor's session.
26  *
27  * @param {Object} options
28  * @return {Function} middleware
29  * @api public
30  */
31
32 module.exports = function csurf(options) {
33   options = options || {};
34
35   // get cookie options
36   var cookie = getCookieOptions(options.cookie)
37
38   // get session options
39   var sessionKey = options.sessionKey || 'session'
40
41   // get value getter
42   var value = options.value || defaultValue
43
44   // token repo
45   var tokens = new Tokens(options);
46
47   // ignored methods
48   var ignoreMethods = options.ignoreMethods === undefined
49     ? ['GET', 'HEAD', 'OPTIONS']
50     : options.ignoreMethods
51
52   if (!Array.isArray(ignoreMethods)) {
53     throw new TypeError('option ignoreMethods must be an array')
54   }
55
56   // generate lookup
57   var ignoreMethod = getIgnoredMethods(ignoreMethods)
58
59   return function csrf(req, res, next) {
60     var secret = getsecret(req, sessionKey, cookie)
61     var token
62
63     // lazy-load token getter
64     req.csrfToken = function csrfToken() {
65       var sec = !cookie
66         ? getsecret(req, sessionKey, cookie)
67         : secret
68
69       // use cached token if secret has not changed
70       if (token && sec === secret) {
71         return token
72       }
73
74       // generate & set new secret
75       if (sec === undefined) {
76         sec = tokens.secretSync()
77         setsecret(req, res, sessionKey, sec, cookie)
78       }
79
80       // update changed secret
81       secret = sec
82
83       // create new token
84       token = tokens.create(secret)
85
86       return token
87     }
88
89     // generate & set secret
90     if (!secret) {
91       secret = tokens.secretSync()
92       setsecret(req, res, sessionKey, secret, cookie)
93     }
94
95     // verify the incoming token
96     if (!ignoreMethod[req.method]) {
97       verifytoken(req, tokens, secret, value(req))
98     }
99
100     next()
101   }
102 };
103
104 /**
105  * Default value function, checking the `req.body`
106  * and `req.query` for the CSRF token.
107  *
108  * @param {IncomingMessage} req
109  * @return {String}
110  * @api private
111  */
112
113 function defaultValue(req) {
114   return (req.body && req.body._csrf)
115     || (req.query && req.query._csrf)
116     || (req.headers['csrf-token'])
117     || (req.headers['xsrf-token'])
118     || (req.headers['x-csrf-token'])
119     || (req.headers['x-xsrf-token']);
120 }
121
122 /**
123  * Get options for cookie.
124  *
125  * @param {boolean|object} [options]
126  * @returns {object}
127  * @api private
128  */
129
130 function getCookieOptions(options) {
131   if (options !== true && typeof options !== 'object') {
132     return undefined
133   }
134
135   var opts = {
136     key: '_csrf',
137     path: '/'
138   }
139
140   if (options && typeof options === 'object') {
141     for (var prop in options) {
142       var val = options[prop]
143
144       if (val !== undefined) {
145         opts[prop] = val
146       }
147     }
148   }
149
150   return opts
151 }
152
153 /**
154  * Get a lookup of ignored methods.
155  *
156  * @param {array} methods
157  * @returns {object}
158  * @api private
159  */
160
161 function getIgnoredMethods(methods) {
162   var obj = Object.create(null)
163
164   for (var i = 0; i < methods.length; i++) {
165     var method = methods[i].toUpperCase()
166     obj[method] = true
167   }
168
169   return obj
170 }
171
172 /**
173  * Get the token secret from the request.
174  *
175  * @param {IncomingMessage} req
176  * @param {String} sessionKey
177  * @param {Object} [cookie]
178  * @api private
179  */
180
181 function getsecret(req, sessionKey, cookie) {
182   var secret
183
184   if (cookie) {
185     // get secret from cookie
186     var bag = cookie.signed
187       ? 'signedCookies'
188       : 'cookies'
189
190     secret = req[bag][cookie.key]
191   } else if (req[sessionKey]) {
192     // get secret from session
193     secret = req[sessionKey].csrfSecret
194   } else {
195     throw new Error('misconfigured csrf')
196   }
197
198   return secret
199 }
200
201 /**
202  * Set a cookie on the HTTP response.
203  *
204  * @param {OutgoingMessage} res
205  * @param {string} name
206  * @param {string} val
207  * @param {Object} [options]
208  * @api private
209  */
210
211 function setcookie(res, name, val, options) {
212   var data = Cookie.serialize(name, val, options);
213
214   var prev = res.getHeader('set-cookie') || [];
215   var header = Array.isArray(prev) ? prev.concat(data)
216     : Array.isArray(data) ? [prev].concat(data)
217     : [prev, data];
218
219   res.setHeader('set-cookie', header);
220 }
221
222 /**
223  * Set the token secret on the request.
224  *
225  * @param {IncomingMessage} req
226  * @param {OutgoingMessage} res
227  * @param {string} sessionKey
228  * @param {string} val
229  * @param {Object} [cookie]
230  * @api private
231  */
232
233 function setsecret(req, res, sessionKey, val, cookie) {
234   if (cookie) {
235     // set secret on cookie
236     if (cookie.signed) {
237       var secret = req.secret
238
239       if (!secret) {
240         throw new Error('cookieParser("secret") required for signed cookies')
241       }
242
243       val = 's:' + sign(val, secret)
244     }
245
246     setcookie(res, cookie.key, val, cookie);
247   } else if (req[sessionKey]) {
248     // set secret on session
249     req[sessionKey].csrfSecret = val
250   } else {
251     /* istanbul ignore next: should never actually run */
252     throw new Error('misconfigured csrf')
253   }
254 }
255
256 /**
257  * Verify the token.
258  *
259  * @param {IncomingMessage} req
260  * @param {Object} tokens
261  * @param {string} secret
262  * @param {string} val
263  * @api private
264  */
265
266 function verifytoken(req, tokens, secret, val) {
267   // valid token
268   if (!tokens.verify(secret, val)) {
269     throw createError(403, 'invalid csrf token', {
270       code: 'EBADCSRFTOKEN'
271     });
272   }
273 }