Comparing version 0.5.1 to 0.6.0
@@ -0,1 +1,11 @@ | ||
0.6.0 / 2016-02-29 | ||
================== | ||
* Add `secure` constructor option for secure connection checking | ||
* Change constructor to signature `new Cookies(req, res, [options])` | ||
- Replace `new Cookies(req, res, key)` with `new Cookies(req, res, {'keys': keys})` | ||
* Change prototype construction for proper "constructor" property | ||
* Deprecate `secureProxy` option in `.set`; use `secure` option instead | ||
- If `secure: true` throws even over SSL, use the `secure` constructor option | ||
0.5.1 / 2014-07-27 | ||
@@ -2,0 +12,0 @@ ================== |
@@ -0,1 +1,2 @@ | ||
var deprecate = require('depd')('cookies') | ||
var Keygrip = require('keygrip') | ||
@@ -15,79 +16,90 @@ var http = require('http') | ||
function Cookies(request, response, keys) { | ||
if (!(this instanceof Cookies)) return new Cookies(request, response, keys) | ||
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 (keys) { | ||
// array of key strings | ||
if (Array.isArray(keys)) | ||
this.keys = new Keygrip(keys) | ||
// any keygrip constructor to allow different versions | ||
else if (keys.constructor && keys.constructor.name === 'Keygrip') | ||
this.keys = keys | ||
if (options) { | ||
if (Array.isArray(options)) { | ||
// array of key strings | ||
deprecate('"keys" argument; provide using options {"key": [...]}') | ||
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 {"key": keygrip}') | ||
this.keys = options | ||
} else { | ||
this.keys = options.keys | ||
this.secure = options.secure | ||
} | ||
} | ||
} | ||
Cookies.prototype = { | ||
get: function(name, opts) { | ||
var sigName = name + ".sig" | ||
, header, match, value, remote, data, index | ||
, signed = opts && opts.signed !== undefined ? opts.signed : !!this.keys | ||
Cookies.prototype.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 | ||
header = this.request.headers["cookie"] | ||
if (!header) return | ||
match = header.match(getPattern(name)) | ||
if (!match) return | ||
match = header.match(getPattern(name)) | ||
if (!match) return | ||
value = match[1] | ||
if (!opts || !signed) return value | ||
value = match[1] | ||
if (!opts || !signed) return value | ||
remote = this.get(sigName) | ||
if (!remote) return | ||
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) | ||
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 | ||
} | ||
}, | ||
if (index < 0) { | ||
this.set(sigName, null, {path: "/", signed: false }) | ||
} else { | ||
index && this.set(sigName, this.keys.sign(data), { signed: false }) | ||
return value | ||
} | ||
}; | ||
set: function(name, value, opts) { | ||
var res = this.response | ||
, req = this.request | ||
, headers = res.getHeader("Set-Cookie") || [] | ||
, secure = req.protocol === 'https' || req.connection.encrypted | ||
, cookie = new Cookie(name, value, opts) | ||
, signed = opts && opts.signed !== undefined ? opts.signed : !!this.keys | ||
Cookies.prototype.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 (typeof headers == "string") headers = [headers] | ||
if (!secure && opts && opts.secure) { | ||
throw new Error('Cannot send secure cookie over unencrypted connection') | ||
} | ||
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) cookie.secure = opts.secureProxy | ||
headers = pushCookie(headers, cookie) | ||
cookie.secure = secure | ||
if (opts && "secure" in opts) cookie.secure = opts.secure | ||
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) | ||
} | ||
if (opts && "secureProxy" in opts) { | ||
deprecate('"secureProxy" option; use "secure" option, provide "secure" to constructor if needed') | ||
cookie.secure = opts.secureProxy | ||
} | ||
var setHeader = res.set ? http.OutgoingMessage.prototype.setHeader : res.setHeader | ||
setHeader.call(res, 'Set-Cookie', headers) | ||
return this | ||
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 Cookie(name, value, attrs) { | ||
@@ -120,28 +132,26 @@ if (!fieldContentRegExp.test(name)) { | ||
Cookie.prototype = { | ||
path: "/", | ||
expires: undefined, | ||
domain: undefined, | ||
httpOnly: true, | ||
secure: false, | ||
overwrite: false, | ||
Cookie.prototype.path = "/"; | ||
Cookie.prototype.expires = undefined; | ||
Cookie.prototype.domain = undefined; | ||
Cookie.prototype.httpOnly = true; | ||
Cookie.prototype.secure = false; | ||
Cookie.prototype.overwrite = false; | ||
toString: function() { | ||
return this.name + "=" + this.value | ||
}, | ||
Cookie.prototype.toString = function() { | ||
return this.name + "=" + this.value | ||
}; | ||
toHeader: function() { | ||
var header = this.toString() | ||
Cookie.prototype.toHeader = function() { | ||
var header = this.toString() | ||
if (this.maxAge) this.expires = new Date(Date.now() + this.maxAge); | ||
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.secure ) header += "; secure" | ||
if (this.httpOnly ) header += "; httponly" | ||
if (this.path ) header += "; path=" + this.path | ||
if (this.expires ) header += "; expires=" + this.expires.toUTCString() | ||
if (this.domain ) header += "; domain=" + this.domain | ||
if (this.secure ) header += "; secure" | ||
if (this.httpOnly ) header += "; httponly" | ||
return header | ||
} | ||
} | ||
return header | ||
}; | ||
@@ -176,3 +186,6 @@ // back-compat so maxage mirrors maxAge | ||
return function(req, res, next) { | ||
req.cookies = res.cookies = new Cookies(req, res, keys) | ||
req.cookies = res.cookies = new Cookies(req, res, { | ||
keys: keys | ||
}) | ||
next() | ||
@@ -179,0 +192,0 @@ } |
{ | ||
"name": "cookies", | ||
"version": "0.5.1", | ||
"version": "0.6.0", | ||
"description": "Cookies, optionally signed using Keygrip.", | ||
"main": "./lib/cookies", | ||
"dependencies": { | ||
"depd": "~1.1.0", | ||
"keygrip": "~1.0.0" | ||
@@ -15,11 +16,17 @@ }, | ||
}, | ||
"engines": { | ||
"node": ">= 0.8.0" | ||
}, | ||
"license": "MIT", | ||
"author": "Jed Schmidt <tr@nslator.jp> (http://jed.is)", | ||
"repository": "pillarjs/cookies", | ||
"files": [ | ||
"lib/", | ||
"History.md", | ||
"LICENSE.txt", | ||
"README.md" | ||
], | ||
"engines": { | ||
"node": ">= 0.8" | ||
}, | ||
"scripts": { | ||
"test": "mocha --reporter spec" | ||
"test": "mocha --require test/support/env --reporter spec" | ||
} | ||
} |
Cookies | ||
======= | ||
[![NPM Version](https://badge.fury.io/js/cookies.svg)](https://badge.fury.io/js/cookies) | ||
[![Build Status](https://travis-ci.org/pillarjs/cookies.svg?branch=master)](https://travis-ci.org/pillarjs/cookies) | ||
[![NPM Version][npm-image]][npm-url] | ||
[![NPM Downloads][downloads-image]][downloads-url] | ||
[![Node.js Version][node-version-image]][node-version-url] | ||
[![Build Status][travis-image]][travis-url] | ||
@@ -29,6 +31,10 @@ Cookies is a [node.js](http://nodejs.org/) module for getting and setting HTTP(S) cookies. Cookies can be signed to prevent tampering, using [Keygrip](https://www.npmjs.com/package/keygrip). It can be used with the built-in node.js HTTP library, or as Connect/Express middleware. | ||
### cookies = new Cookies( request, response, [ keys ] ) | ||
### cookies = new Cookies( request, response, [ options ] ) | ||
This creates a cookie jar corresponding to the current _request_ and _response_. A [Keygrip](https://www.npmjs.com/package/keygrip) object or an array of keys can optionally be passed as the third argument _keygrip_ to enable cryptographic signing based on SHA1 HMAC, using rotated credentials. | ||
This creates a cookie jar corresponding to the current _request_ and _response_, additionally passing an object _options_. | ||
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. | ||
@@ -65,3 +71,2 @@ | ||
* `secure`: a boolean indicating whether the cookie is only to be sent over HTTPS (`false` by default for HTTP, `true` by default for HTTPS). | ||
* `secureProxy`: a boolean indicating whether the cookie is only to be sent over HTTPS (use this if you handle SSL not in your node process). | ||
* `httpOnly`: a boolean indicating whether the cookie is only to be sent over HTTP(S), and not made available to client JavaScript (`true` by default). | ||
@@ -78,3 +83,3 @@ * `signed`: a boolean indicating whether the cookie is to be signed (`false` by default). If this is true, another cookie of the same name with the `.sig` suffix appended will also be sent, with a 27-byte url-safe base64 SHA1 value representing the hash of _cookie-name_=_cookie-value_ against the first [Keygrip](https://www.npmjs.com/package/keygrip) key. This signature key is used to detect tampering the next time a cookie is received. | ||
server = http.createServer( function( req, res ) { | ||
var cookies = new Cookies( req, res, keys ) | ||
var cookies = new Cookies( req, res, { "keys": keys } ) | ||
, unsigned, signed, tampered | ||
@@ -125,1 +130,10 @@ | ||
Send any questions or comments [here](http://twitter.com/jedschmidt). | ||
[npm-image]: https://img.shields.io/npm/v/cookies.svg | ||
[npm-url]: https://npmjs.org/package/cookies | ||
[downloads-image]: https://img.shields.io/npm/dm/cookies.svg | ||
[downloads-url]: https://npmjs.org/package/cookies | ||
[node-version-image]: https://img.shields.io/node/v/cookies.svg | ||
[node-version-url]: https://nodejs.org/en/download/ | ||
[travis-image]: https://img.shields.io/travis/pillarjs/cookies/master.svg | ||
[travis-url]: https://travis-ci.org/pillarjs/cookies |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16149
153
136
2
5
+ Addeddepd@~1.1.0
+ Addeddepd@1.1.2(transitive)