function Cookies(request, response, options) { if (!(this instanceof Cookies)) return new Cookies(request, response, options) this.secure = undefined this.request = request this.response = response if (options) { if (Array.isArray(options)) { // array of key strings deprecate('"keys" argument; provide using options {"keys": [...]}') this.keys = new Keygrip(options) } else if (options.constructor && options.constructor.name === 'Keygrip') { // any keygrip constructor to allow different versions deprecate('"keys" argument; provide using options {"keys": keygrip}') this.keys = options } else { this.keys = Array.isArray(options.keys) ? new Keygrip(options.keys) : options.keys this.secure = options.secure } } }
n/a
function Cookie(name, value, attrs) { if (!fieldContentRegExp.test(name)) { throw new TypeError('argument name is invalid'); } if (value && !fieldContentRegExp.test(value)) { throw new TypeError('argument value is invalid'); } value || (this.expires = new Date(0)) this.name = name this.value = value || "" for (var name in attrs) { this[name] = attrs[name] } if (this.path && !fieldContentRegExp.test(this.path)) { throw new TypeError('option path is invalid'); } if (this.domain && !fieldContentRegExp.test(this.domain)) { throw new TypeError('option domain is invalid'); } if (this.sameSite && this.sameSite !== true && !sameSiteRegExp.test(this.sameSite)) { throw new TypeError('option sameSite is invalid') } }
n/a
connect = function (keys) { return function(req, res, next) { req.cookies = res.cookies = new Cookies(req, res, { keys: keys }) next() } }
n/a
express = function (keys) { return function(req, res, next) { req.cookies = res.cookies = new Cookies(req, res, { keys: keys }) next() } }
...
A [Keygrip](https://www.npmjs.com/package/keygrip) object or an array of keys can optionally be passed as _options.keys_ to enable
cryptographic signing based on SHA1 HMAC, using rotated credentials.
A Boolean can optionally be passed as _options.secure_ to explicitally specify if the connection is secure, rather than this module
examining _request_.
Note that since this only saves parameters without any other processing, it is very lightweight. Cookies are only parsed on demand
when they are accessed.
### express.createServer( Cookies.express( keys ) )
This adds cookie support as a Connect middleware layer for use in Express apps, allowing inbound cookies to be read using `req.cookies
.get` and outbound cookies to be set using `res.cookies.set`.
### cookies.get( name, [ options ] )
This extracts the cookie with the given name from the `Cookie` header in the request. If such a cookie exists, its value is returned
. Otherwise, nothing is returned.
...
function Cookies(request, response, options) { if (!(this instanceof Cookies)) return new Cookies(request, response, options) this.secure = undefined this.request = request this.response = response if (options) { if (Array.isArray(options)) { // array of key strings deprecate('"keys" argument; provide using options {"keys": [...]}') this.keys = new Keygrip(options) } else if (options.constructor && options.constructor.name === 'Keygrip') { // any keygrip constructor to allow different versions deprecate('"keys" argument; provide using options {"keys": keygrip}') this.keys = options } else { this.keys = Array.isArray(options.keys) ? new Keygrip(options.keys) : options.keys this.secure = options.secure } } }
...
if (!opts || !signed) return value
remote = this.get(sigName)
if (!remote) return
data = name + "=" + value
if (!this.keys) throw new Error('.keys required for signed cookies');
index = this.keys.index(data, remote)
if (index < 0) {
this.set(sigName, null, {path: "/", signed: false })
} else {
index && this.set(sigName, this.keys.sign(data), { signed: false })
return value
}
...
function Cookie(name, value, attrs) { if (!fieldContentRegExp.test(name)) { throw new TypeError('argument name is invalid'); } if (value && !fieldContentRegExp.test(value)) { throw new TypeError('argument value is invalid'); } value || (this.expires = new Date(0)) this.name = name this.value = value || "" for (var name in attrs) { this[name] = attrs[name] } if (this.path && !fieldContentRegExp.test(this.path)) { throw new TypeError('option path is invalid'); } if (this.domain && !fieldContentRegExp.test(this.domain)) { throw new TypeError('option domain is invalid'); } if (this.sameSite && this.sameSite !== true && !sameSiteRegExp.test(this.sameSite)) { throw new TypeError('option sameSite is invalid') } }
n/a
toHeader = function () { var header = this.toString() if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge); if (this.path ) header += "; path=" + this.path if (this.expires ) header += "; expires=" + this.expires.toUTCString() if (this.domain ) header += "; domain=" + this.domain if (this.sameSite ) header += "; samesite=" + (this.sameSite === true ? 'strict' : this.sameSite.toLowerCase()) if (this.secure ) header += "; secure" if (this.httpOnly ) header += "; httponly" return header }
...
)
}
function pushCookie(cookies, cookie) {
if (cookie.overwrite) {
cookies = cookies.filter(function(c) { return c.indexOf(cookie.name+'=') !== 0 })
}
cookies.push(cookie.toHeader())
return cookies
}
Cookies.connect = Cookies.express = function(keys) {
return function(req, res, next) {
req.cookies = res.cookies = new Cookies(req, res, {
keys: keys
...
toString = function () { return this.name + "=" + this.value }
...
cookie.secure = opts.secureProxy
}
headers = pushCookie(headers, cookie)
if (opts && signed) {
if (!this.keys) throw new Error('.keys required for signed cookies');
cookie.value = this.keys.sign(cookie.toString())
cookie.name += ".sig"
headers = pushCookie(headers, cookie)
}
var setHeader = res.set ? http.OutgoingMessage.prototype.setHeader : res.setHeader
setHeader.call(res, 'Set-Cookie', headers)
return this
...
function Cookies(request, response, options) { if (!(this instanceof Cookies)) return new Cookies(request, response, options) this.secure = undefined this.request = request this.response = response if (options) { if (Array.isArray(options)) { // array of key strings deprecate('"keys" argument; provide using options {"keys": [...]}') this.keys = new Keygrip(options) } else if (options.constructor && options.constructor.name === 'Keygrip') { // any keygrip constructor to allow different versions deprecate('"keys" argument; provide using options {"keys": keygrip}') this.keys = options } else { this.keys = Array.isArray(options.keys) ? new Keygrip(options.keys) : options.keys this.secure = options.secure } } }
...
if (!opts || !signed) return value
remote = this.get(sigName)
if (!remote) return
data = name + "=" + value
if (!this.keys) throw new Error('.keys required for signed cookies');
index = this.keys.index(data, remote)
if (index < 0) {
this.set(sigName, null, {path: "/", signed: false })
} else {
index && this.set(sigName, this.keys.sign(data), { signed: false })
return value
}
...
function Cookie(name, value, attrs) { if (!fieldContentRegExp.test(name)) { throw new TypeError('argument name is invalid'); } if (value && !fieldContentRegExp.test(value)) { throw new TypeError('argument value is invalid'); } value || (this.expires = new Date(0)) this.name = name this.value = value || "" for (var name in attrs) { this[name] = attrs[name] } if (this.path && !fieldContentRegExp.test(this.path)) { throw new TypeError('option path is invalid'); } if (this.domain && !fieldContentRegExp.test(this.domain)) { throw new TypeError('option domain is invalid'); } if (this.sameSite && this.sameSite !== true && !sameSiteRegExp.test(this.sameSite)) { throw new TypeError('option sameSite is invalid') } }
n/a
connect = function (keys) { return function(req, res, next) { req.cookies = res.cookies = new Cookies(req, res, { keys: keys }) next() } }
n/a
express = function (keys) { return function(req, res, next) { req.cookies = res.cookies = new Cookies(req, res, { keys: keys }) next() } }
...
A [Keygrip](https://www.npmjs.com/package/keygrip) object or an array of keys can optionally be passed as _options.keys_ to enable
cryptographic signing based on SHA1 HMAC, using rotated credentials.
A Boolean can optionally be passed as _options.secure_ to explicitally specify if the connection is secure, rather than this module
examining _request_.
Note that since this only saves parameters without any other processing, it is very lightweight. Cookies are only parsed on demand
when they are accessed.
### express.createServer( Cookies.express( keys ) )
This adds cookie support as a Connect middleware layer for use in Express apps, allowing inbound cookies to be read using `req.cookies
.get` and outbound cookies to be set using `res.cookies.set`.
### cookies.get( name, [ options ] )
This extracts the cookie with the given name from the `Cookie` header in the request. If such a cookie exists, its value is returned
. Otherwise, nothing is returned.
...
get = function (name, opts) { var sigName = name + ".sig" , header, match, value, remote, data, index , signed = opts && opts.signed !== undefined ? opts.signed : !!this.keys header = this.request.headers["cookie"] if (!header) return match = header.match(getPattern(name)) if (!match) return value = match[1] if (!opts || !signed) return value remote = this.get(sigName) if (!remote) return data = name + "=" + value if (!this.keys) throw new Error('.keys required for signed cookies'); index = this.keys.index(data, remote) if (index < 0) { this.set(sigName, null, {path: "/", signed: false }) } else { index && this.set(sigName, this.keys.sign(data), { signed: false }) return value } }
...
match = header.match(getPattern(name))
if (!match) return
value = match[1]
if (!opts || !signed) return value
remote = this.get(sigName)
if (!remote) return
data = name + "=" + value
if (!this.keys) throw new Error('.keys required for signed cookies');
index = this.keys.index(data, remote)
if (index < 0) {
...
set = function (name, value, opts) { var res = this.response , req = this.request , headers = res.getHeader("Set-Cookie") || [] , secure = this.secure !== undefined ? !!this.secure : req.protocol === 'https' || req.connection.encrypted , cookie = new Cookie(name, value, opts) , signed = opts && opts.signed !== undefined ? opts.signed : !!this.keys if (typeof headers == "string") headers = [headers] if (!secure && opts && opts.secure) { throw new Error('Cannot send secure cookie over unencrypted connection') } cookie.secure = secure if (opts && "secure" in opts) cookie.secure = opts.secure if (opts && "secureProxy" in opts) { deprecate('"secureProxy" option; use "secure" option, provide "secure" to constructor if needed') cookie.secure = opts.secureProxy } headers = pushCookie(headers, cookie) if (opts && signed) { if (!this.keys) throw new Error('.keys required for signed cookies'); cookie.value = this.keys.sign(cookie.toString()) cookie.name += ".sig" headers = pushCookie(headers, cookie) } var setHeader = res.set ? http.OutgoingMessage.prototype.setHeader : res.setHeader setHeader.call(res, 'Set-Cookie', headers) return this }
...
if (!remote) return
data = name + "=" + value
if (!this.keys) throw new Error('.keys required for signed cookies');
index = this.keys.index(data, remote)
if (index < 0) {
this.set(sigName, null, {path: "/", signed: false })
} else {
index && this.set(sigName, this.keys.sign(data), { signed: false })
return value
}
};
Cookies.prototype.set = function(name, value, opts) {
...