redis-cookie-store
Advanced tools
Comparing version 0.0.3 to 1.0.0
'use strict'; | ||
var tough = require('tough-cookie'); | ||
var Store = tough.Store; | ||
var permuteDomain = tough.permuteDomain; | ||
var permutePath = tough.permutePath; | ||
var util = require('util'); | ||
var async = require('async'); | ||
var _ = require('lodash'); | ||
var Cookie = tough.Cookie; | ||
// node core modules | ||
const util = require('util'); | ||
// 3rd party modules | ||
const async = require('async'); | ||
const _ = require('lodash'); | ||
const { | ||
Store, permuteDomain, permutePath, Cookie, | ||
} = require('tough-cookie'); | ||
// internal modules | ||
// putting id last to not break existing interface | ||
function RedisCookieStore(redisClient, id) { | ||
Store.call(this); | ||
this.idx = {}; | ||
this.id = id || 'default'; | ||
this.client = redisClient; | ||
this.synchronous = false; | ||
const self = this; | ||
Store.call(self); | ||
self.idx = {}; | ||
self.id = id || 'default'; | ||
self.client = redisClient; | ||
self.synchronous = false; | ||
} | ||
@@ -22,109 +28,138 @@ util.inherits(RedisCookieStore, Store); | ||
RedisCookieStore.prototype.getKeyName = function getKeyName(domain, path) { | ||
const self = this; | ||
if (path) { | ||
return "cookie-store:" + this.id + ":cookie:" + domain + ":" + path; | ||
} else { | ||
return "cookie-store:" + this.id + ":cookie:" + domain; | ||
return `cookie-store:${self.id}:cookie:${domain}:${path}`; | ||
} | ||
return `cookie-store:${self.id}:cookie:${domain}`; | ||
}; | ||
RedisCookieStore.prototype.findCookie = function(domain, path, key, cb) { | ||
return this.client.hget(this.getKeyName(domain, path), key, cb); | ||
RedisCookieStore.prototype.findCookie = function findCookie(domain, path, cookieName, cb) { | ||
const self = this; | ||
const { client } = self; | ||
const keyName = self.getKeyName(domain, path); | ||
client.hget(keyName, cookieName, cb); | ||
}; | ||
RedisCookieStore.prototype.findCookies = function(domain, path, cb) { | ||
const cookiePrefixRegexp = /(.*cookie:[^:]*:)/i; | ||
const pathMatcher = ({ domainKeys, paths, client }, cb) => { | ||
const [firstDomainKey] = domainKeys; | ||
const [, domainPrefix] = firstDomainKey.match(cookiePrefixRegexp); // get domain key prefix e.g. "cookie:www.example.com" | ||
const prefixedPaths = paths.map(path => domainPrefix + path); | ||
const keys = _.intersection(domainKeys, prefixedPaths).sort((a, b) => a.length - b.length); | ||
const jobs = keys.map(key => next => client.hgetall(key, next)); | ||
async.parallel(jobs, (err, results) => { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
cb(null, _.merge(...results)); | ||
}); | ||
}; | ||
RedisCookieStore.prototype.findCookies = function findCookies(domain, path, cb) { | ||
const self = this; | ||
const { client } = self; | ||
if (!domain) { | ||
return cb(null, []); | ||
cb(null, []); | ||
return; | ||
} | ||
var domains = permuteDomain(domain) || [domain]; | ||
var self = this; | ||
const permutedDomains = permuteDomain(domain) || [domain]; | ||
// sort permuted domains (length ascending) | ||
const sortedPermutedDomains = permutedDomains.sort((a, b) => a.length - b.length); | ||
var paths = permutePath(path) || [path]; | ||
var pathMatcher = function matchRFC(domainKeys, cb) { | ||
const paths = permutePath(path) || [path]; | ||
var domainPrefix = domainKeys[0].match(/(.*cookie:[^:]*:)/i)[1]; //get domain key prefix e.g. "cookie:www.example.com" | ||
var prefixedPaths = paths.map(function(path) { | ||
return domainPrefix + path; | ||
}); | ||
// console.log(prefixedPaths); | ||
var keys = _.intersection(domainKeys, prefixedPaths).sort(function(a, b) { | ||
return a.length - b.length; | ||
}); | ||
// prepare jobs to load cookie data from redis for each permuted domain | ||
const jobs = sortedPermutedDomains.map(permutedDomain => (next) => { | ||
const keyName = `${self.getKeyName(permutedDomain)}:*`; | ||
async.parallel(keys.map(function(key) { | ||
return function(callback) { | ||
self.client.hgetall(key, function(err, hash) { | ||
callback(err, hash); | ||
}); | ||
}; | ||
}), function(err, results) { | ||
client.keys(keyName, (err, domainKeys) => { | ||
if (err) { | ||
return cb(err); | ||
next(err, null); | ||
return; | ||
} | ||
cb(null, _.merge.apply(_, results)); | ||
if (!domainKeys || !domainKeys.length) { | ||
next(null, {}); | ||
return; | ||
} | ||
pathMatcher({ domainKeys, paths, client }, next); | ||
}); | ||
}; | ||
}); | ||
async.parallel(jobs, (err, results) => { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
cb( | ||
err, | ||
_.values(_.merge(...results)).map((cookieString) => { | ||
const cookie = Cookie.parse(cookieString); | ||
async.parallel(domains.sort(function(a, b) { | ||
return a.length - b.length; | ||
}).map(function(domain) { | ||
return function(callback) { | ||
self.client.keys(self.getKeyName(domain) + ":*", function(err, domainKeys) { | ||
if (err) { | ||
return callback(err, null); | ||
if (!cookie.domain) { | ||
cookie.domain = domain; | ||
} | ||
if (!domainKeys || !domainKeys.length) { | ||
return callback(null, {}); | ||
} | ||
pathMatcher(domainKeys, callback); | ||
}); | ||
}; | ||
}), function(err, results) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
cb(err, _.values(_.merge.apply(_, results)).map(function(cookieString) { | ||
var cookie = Cookie.parse(cookieString); | ||
if (!cookie.domain) { | ||
cookie.domain = domain; | ||
} | ||
return cookie; | ||
})); | ||
return cookie; | ||
}) | ||
); | ||
}); | ||
}; | ||
RedisCookieStore.prototype.putCookie = function(cookie, cb) { | ||
this.client.hset(this.getKeyName(cookie.domain, cookie.path), cookie.key, cookie.toString(), cb); | ||
RedisCookieStore.prototype.putCookie = function putCookie(cookie, cb) { | ||
const self = this; | ||
const { client } = self; | ||
const { key: cookieName, domain, path } = cookie; | ||
const keyName = self.getKeyName(domain, path); | ||
const cookieString = cookie.toString(); | ||
client.hset(keyName, cookieName, cookieString, cb); | ||
}; | ||
RedisCookieStore.prototype.updateCookie = function updateCookie(oldCookie, newCookie, cb) { | ||
const self = this; | ||
// updateCookie() may avoid updating cookies that are identical. For example, | ||
// lastAccessed may not be important to some stores and an equality | ||
// comparison could exclude that field. | ||
this.putCookie(newCookie, cb); | ||
self.putCookie(newCookie, cb); | ||
}; | ||
RedisCookieStore.prototype.removeCookie = function removeCookie(domain, path, key, cb) { | ||
this.client.hdel(this.getKeyName(domain, path), key, cb); | ||
RedisCookieStore.prototype.removeCookie = function removeCookie(domain, path, cookieName, cb) { | ||
const self = this; | ||
const { client } = self; | ||
const keyName = self.getKeyName(domain, path); | ||
client.hdel(keyName, cookieName, cb); | ||
}; | ||
RedisCookieStore.prototype.removeCookies = function removeCookies(domain, path, cb) { | ||
var self = this; | ||
const self = this; | ||
const { client } = self; | ||
if (path) { | ||
return self.client.del(self.getKeyName(domain, path), cb); | ||
} else { | ||
self.client.keys(self.getKeyName(domain) + ":*", function(err, keys) { | ||
if (err) { | ||
return cb(err); | ||
} | ||
async.each( | ||
keys, | ||
self.client.del, | ||
cb | ||
); | ||
}); | ||
const keyName = self.getKeyName(domain, path); | ||
client.del(keyName, cb); | ||
return; | ||
} | ||
const keyName = `${self.getKeyName(domain)}:*`; | ||
client.keys(keyName, (err, keys) => { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
async.each(keys, client.del, cb); | ||
}); | ||
}; | ||
module.exports = RedisCookieStore; |
{ | ||
"name": "redis-cookie-store", | ||
"version": "0.0.3", | ||
"version": "1.0.0", | ||
"description": "Redis cookie store for tough-cookie module", | ||
"main": "index.js", | ||
"files": [ | ||
"lib/" | ||
], | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"format": "prettier-eslint --write \"lib/**/*.js\"", | ||
"prelint": "npm run format", | ||
"lint": "eslint --ignore-path .gitignore .", | ||
"test": "ava --verbose", | ||
"test:watch": "npm test -- --watch", | ||
"coverage": "nyc npm test && nyc report --reporter=html" | ||
}, | ||
@@ -20,3 +28,3 @@ "repository": { | ||
], | ||
"author": "Artem Vovsya <avovsya@gmail.com>", | ||
"author": "Benjamin Kroeger <benjamin.kroeger@gmail.com>", | ||
"license": "MIT", | ||
@@ -28,6 +36,13 @@ "bugs": { | ||
"dependencies": { | ||
"async": "1.5.0", | ||
"lodash": "3.10.1", | ||
"tough-cookie": "2.2.0" | ||
"async": "^2.6.0", | ||
"lodash": "^4.17.10", | ||
"tough-cookie": "^2.3.4" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.25.0", | ||
"eslint": "^4.19.1", | ||
"eslint-config-oniyi": "^5.1.0", | ||
"nyc": "^11.8.0", | ||
"prettier-eslint-cli": "^4.7.1" | ||
} | ||
} |
# Redis Cookie Store | ||
redis-cookie-store is a Redis store for tough-cookie module. See | ||
[tough-cookie documentation](https://github.com/goinstant/tough-cookie#constructionstore--new-memorycookiestore-rejectpublicsuffixes) for more info. | ||
a Redis store for tough-cookie module. See [tough-cookie documentation](https://github.com/goinstant/tough-cookie#constructionstore--new-memorycookiestore-rejectpublicsuffixes) for more info. | ||
## Installation | ||
$ npm install redis-cookie-store | ||
```sh | ||
npm install --save redis-cookie-store | ||
``` | ||
@@ -13,17 +14,20 @@ ## Options | ||
* `client` An existing redis client object you normally get from `redis.createClient()` | ||
* `id` **optional** ID for each redis store so that we can use multiple stores with the same redis database [*default:* "default"] | ||
* `id` **optional** ID for each redis store so that we can use multiple stores with the same redis database [*default:* 'default'] | ||
## Usage | ||
var redis = require("redis"); | ||
var client = redis.createClient(); | ||
var CookieJar = require("tough-cookie").CookieJar; | ||
var RedisCookieStore = require("redis-cookie-store"); | ||
```js | ||
const redis = require('redis'); | ||
const { CookieJar } = require('tough-cookie'); | ||
const RedisCookieStore = require('redis-cookie-store'); | ||
var defaultJar = new CookieJar(new RedisCookieStore(client)); | ||
var myJar = new CookieJar(new RedisCookieStore(client, 'my-cookie-store')); | ||
const client = redis.createClient(); | ||
# License | ||
MIT | ||
const defaultJar = new CookieJar(new RedisCookieStore(client)); | ||
const myJar = new CookieJar(new RedisCookieStore(client, 'my-cookie-store')); | ||
``` | ||
# License | ||
MIT |
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
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
6492
136
0
33
5
+ Addedasync@2.6.4(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedpsl@1.13.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedtough-cookie@2.5.0(transitive)
- Removedasync@1.5.0(transitive)
- Removedlodash@3.10.1(transitive)
- Removedtough-cookie@2.2.0(transitive)
Updatedasync@^2.6.0
Updatedlodash@^4.17.10
Updatedtough-cookie@^2.3.4