/ * !
* cookie - parser
* Copyright ( c ) 2014 TJ Holowaychuk
* Copyright ( c ) 2015 Douglas Christopher Wilson
* MIT Licensed
* /
'use strict'
/ * *
* Module dependencies .
* @ private
* /
var cookie = require ( 'cookie' )
var signature = require ( 'cookie-signature' )
/ * *
* Module exports .
* @ public
* /
module . exports = cookieParser
module . exports . JSONCookie = JSONCookie
module . exports . JSONCookies = JSONCookies
module . exports . signedCookie = signedCookie
module . exports . signedCookies = signedCookies
/ * *
* Parse Cookie header and populate ` req.cookies `
* with an object keyed by the cookie names .
*
* @ param { string | array } [ secret ] A string ( or array of strings ) representing cookie signing secret ( s ) .
* @ param { Object } [ options ]
* @ return { Function }
* @ public
* /
function cookieParser ( secret , options ) {
var secrets = ! secret || Array . isArray ( secret )
? ( secret || [ ] )
: [ secret ]
return function cookieParser ( req , res , next ) {
if ( req . cookies ) {
return next ( )
}
var cookies = req . headers . cookie
req . secret = secrets [ 0 ]
req . cookies = Object . create ( null )
req . signedCookies = Object . create ( null )
// no cookies
if ( ! cookies ) {
return next ( )
}
req . cookies = cookie . parse ( cookies , options )
// parse signed cookies
if ( secrets . length !== 0 ) {
req . signedCookies = signedCookies ( req . cookies , secrets )
req . signedCookies = JSONCookies ( req . signedCookies )
}
// parse JSON cookies
req . cookies = JSONCookies ( req . cookies )
next ( )
}
}
/ * *
* Parse JSON cookie string .
*
* @ param { String } str
* @ return { Object } Parsed object or undefined if not json cookie
* @ public
* /
function JSONCookie ( str ) {
if ( typeof str !== 'string' || str . substr ( 0 , 2 ) !== 'j:' ) {
return undefined
}
try {
return JSON . parse ( str . slice ( 2 ) )
} catch ( err ) {
return undefined
}
}
/ * *
* Parse JSON cookies .
*
* @ param { Object } obj
* @ return { Object }
* @ public
* /
function JSONCookies ( obj ) {
var cookies = Object . keys ( obj )
var key
var val
for ( var i = 0 ; i < cookies . length ; i ++ ) {
key = cookies [ i ]
val = JSONCookie ( obj [ key ] )
if ( val ) {
obj [ key ] = val
}
}
return obj
}
/ * *
* Parse a signed cookie string , return the decoded value .
*
* @ param { String } str signed cookie string
* @ param { string | array } secret
* @ return { String } decoded value
* @ public
* /
function signedCookie ( str , secret ) {
if ( typeof str !== 'string' ) {
return undefined
}
if ( str . substr ( 0 , 2 ) !== 's:' ) {
return str
}
var secrets = ! secret || Array . isArray ( secret )
? ( secret || [ ] )
: [ secret ]
for ( var i = 0 ; i < secrets . length ; i ++ ) {
var val = signature . unsign ( str . slice ( 2 ) , secrets [ i ] )
if ( val !== false ) {
return val
}
}
return false
}
/ * *
* Parse signed cookies , returning an object containing the decoded key / value
* pairs , while removing the signed key from obj .
*
* @ param { Object } obj
* @ param { string | array } secret
* @ return { Object }
* @ public
* /
function signedCookies ( obj , secret ) {
var cookies = Object . keys ( obj )
var dec
var key
var ret = Object . create ( null )
var val
for ( var i = 0 ; i < cookies . length ; i ++ ) {
key = cookies [ i ]
val = obj [ key ]
dec = signedCookie ( val , secret )
if ( val !== dec ) {
ret [ key ] = dec
delete obj [ key ]
}
}
return ret
}