UNPKG

3.4 kBJavaScriptView Raw
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
15var cookie = require('cookie')
16var signature = require('cookie-signature')
17
18/**
19 * Module exports.
20 * @public
21 */
22
23module.exports = cookieParser
24module.exports.JSONCookie = JSONCookie
25module.exports.JSONCookies = JSONCookies
26module.exports.signedCookie = signedCookie
27module.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
39function 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
83function 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
103function 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
129function 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
163function 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}