second
[josuexyz/.git] / node_modules / cookie-parser / index.js
1 /*!
2  * cookie-parser
3  * Copyright(c) 2014 TJ Holowaychuk
4  * Copyright(c) 2015 Douglas Christopher Wilson
5  * MIT Licensed
6  */
7
8 'use strict'
9
10 /**
11  * Module dependencies.
12  * @private
13  */
14
15 var cookie = require('cookie')
16 var signature = require('cookie-signature')
17
18 /**
19  * Module exports.
20  * @public
21  */
22
23 module.exports = cookieParser
24 module.exports.JSONCookie = JSONCookie
25 module.exports.JSONCookies = JSONCookies
26 module.exports.signedCookie = signedCookie
27 module.exports.signedCookies = signedCookies
28
29 /**
30  * Parse Cookie header and populate `req.cookies`
31  * with an object keyed by the cookie names.
32  *
33  * @param {string|array} [secret] A string (or array of strings) representing cookie signing secret(s).
34  * @param {Object} [options]
35  * @return {Function}
36  * @public
37  */
38
39 function cookieParser (secret, options) {
40   var secrets = !secret || Array.isArray(secret)
41     ? (secret || [])
42     : [secret]
43
44   return function cookieParser (req, res, next) {
45     if (req.cookies) {
46       return next()
47     }
48
49     var cookies = req.headers.cookie
50
51     req.secret = secrets[0]
52     req.cookies = Object.create(null)
53     req.signedCookies = Object.create(null)
54
55     // no cookies
56     if (!cookies) {
57       return next()
58     }
59
60     req.cookies = cookie.parse(cookies, options)
61
62     // parse signed cookies
63     if (secrets.length !== 0) {
64       req.signedCookies = signedCookies(req.cookies, secrets)
65       req.signedCookies = JSONCookies(req.signedCookies)
66     }
67
68     // parse JSON cookies
69     req.cookies = JSONCookies(req.cookies)
70
71     next()
72   }
73 }
74
75 /**
76  * Parse JSON cookie string.
77  *
78  * @param {String} str
79  * @return {Object} Parsed object or undefined if not json cookie
80  * @public
81  */
82
83 function JSONCookie (str) {
84   if (typeof str !== 'string' || str.substr(0, 2) !== 'j:') {
85     return undefined
86   }
87
88   try {
89     return JSON.parse(str.slice(2))
90   } catch (err) {
91     return undefined
92   }
93 }
94
95 /**
96  * Parse JSON cookies.
97  *
98  * @param {Object} obj
99  * @return {Object}
100  * @public
101  */
102
103 function JSONCookies (obj) {
104   var cookies = Object.keys(obj)
105   var key
106   var val
107
108   for (var i = 0; i < cookies.length; i++) {
109     key = cookies[i]
110     val = JSONCookie(obj[key])
111
112     if (val) {
113       obj[key] = val
114     }
115   }
116
117   return obj
118 }
119
120 /**
121  * Parse a signed cookie string, return the decoded value.
122  *
123  * @param {String} str signed cookie string
124  * @param {string|array} secret
125  * @return {String} decoded value
126  * @public
127  */
128
129 function signedCookie (str, secret) {
130   if (typeof str !== 'string') {
131     return undefined
132   }
133
134   if (str.substr(0, 2) !== 's:') {
135     return str
136   }
137
138   var secrets = !secret || Array.isArray(secret)
139     ? (secret || [])
140     : [secret]
141
142   for (var i = 0; i < secrets.length; i++) {
143     var val = signature.unsign(str.slice(2), secrets[i])
144
145     if (val !== false) {
146       return val
147     }
148   }
149
150   return false
151 }
152
153 /**
154  * Parse signed cookies, returning an object containing the decoded key/value
155  * pairs, while removing the signed key from obj.
156  *
157  * @param {Object} obj
158  * @param {string|array} secret
159  * @return {Object}
160  * @public
161  */
162
163 function signedCookies (obj, secret) {
164   var cookies = Object.keys(obj)
165   var dec
166   var key
167   var ret = Object.create(null)
168   var val
169
170   for (var i = 0; i < cookies.length; i++) {
171     key = cookies[i]
172     val = obj[key]
173     dec = signedCookie(val, secret)
174
175     if (val !== dec) {
176       ret[key] = dec
177       delete obj[key]
178     }
179   }
180
181   return ret
182 }