Socket
Socket
Sign inDemoInstall

egg-cookies

Package Overview
Dependencies
3
Maintainers
5
Versions
35
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0 to 2.0.0

lib/cookie.js

6

History.md
2.0.0 / 2016-11-22
==================
* refactor: rewrite keygrip and cookies for egg/koa (#1)
* chore: add zh-CN readme
1.0.0 / 2016-07-15

@@ -3,0 +9,0 @@ ==================

142

lib/cookies.js
'use strict';
const Cookies = require('cookies');
const assert = require('assert');
const utility = require('utility');
const Keygrip = require('./keygrip');
const Cookie = require('./cookie');
const KEYS_ARRAY = Symbol('eggCookies:keysArray');
const KEYS = Symbol('eggCookies:keys');
/**

@@ -10,50 +15,125 @@ * cookies for egg

*/
class EggCookies extends Cookies {
class Cookies {
constructor(ctx, keys) {
super(ctx.req, ctx.res, {
keys,
secure: ctx.secure,
});
this[KEYS_ARRAY] = keys;
this._keys = keys;
this.ctx = ctx;
this.secure = this.ctx.secure;
}
get keys() {
if (this[KEYS]) return this[KEYS];
if (!this[KEYS]) {
assert(Array.isArray(this[KEYS_ARRAY]), '.keys required for encrypt/sign cookies');
this[KEYS] = new Keygrip(this[KEYS_ARRAY]);
}
return this[KEYS];
}
/**
* get cookie value by name
* @param {String} name - cookie's name
* @param {Object} opts - cookies' options
* - {Boolean} signed - defualt to true
* - {Boolean} encrypt - defualt to false
* @return {String} value - cookie's value
*/
get(name, opts) {
// 默认不开启 encrypt
const encrypt = opts && opts.encrypt;
opts = encryptOrSigned(opts);
// signed 和 encrypt 不同时开启
if (encrypt) {
opts.signed = false;
}
const header = this.ctx.get('cookie');
if (!header) return;
let value = super.get(name, opts);
const match = header.match(getPattern(name));
if (!match) return;
if (value && encrypt) {
this.assertKeys();
value = utility.base64decode(value, true, 'buffer');
const msg = this.keys.decrypt(value);
value = msg ? msg[0].toString('utf8') : undefined;
let value = match[1];
if (!opts.encrypt && !opts.signed) return value;
// signed
if (opts.signed) {
const sigName = name + '.sig';
const sigValue = this.get(sigName, { signed: false });
if (!sigValue) return;
const raw = name + '=' + value;
const index = this.keys.verify(raw, sigValue);
if (index < 0) {
// can not match any key, remove ${name}.sig
this.set(sigName, null, { path: '/', signed: false });
return;
}
if (index > 0) {
// not signed by the first key, update sigValue
this.set(sigName, this.keys.sign(raw), { signed: false });
}
return value;
}
return value;
// encrypt
value = utility.base64decode(value, true, 'buffer');
const res = this.keys.decrypt(value);
return res ? res.value.toString() : undefined;
}
set(name, value, opts) {
const encrypt = opts && opts.encrypt;
opts = encryptOrSigned(opts);
value = value || '';
if (!this.secure && opts.secure) {
throw new Error('Cannot send secure cookie over unencrypted connection');
}
if (opts.secure === undefined) opts.secure = this.secure;
// signed 和 encrypt 不需要同时开启
if (value && encrypt) {
opts.signed = false;
this.assertKeys();
value = utility.base64encode(this.keys.encrypt(value), true);
let headers = this.ctx.response.get('set-cookie') || [];
// encrypt
if (opts.encrypt) {
value = value && utility.base64encode(this.keys.encrypt(value), true);
}
return super.set(name, value, opts);
}
const cookie = new Cookie(name, value, opts);
headers = pushCookie(headers, cookie);
assertKeys() {
if (!this.keys) {
throw new TypeError('.keys required for encrypt cookies');
// signed
if (opts.signed) {
cookie.value = value && this.keys.sign(cookie.toString());
cookie.name += '.sig';
headers = pushCookie(headers, cookie);
}
this.ctx.set('set-cookie', headers);
return this;
}
}
module.exports = EggCookies;
const cache = new Map();
function getPattern(name) {
const cachePattern = cache.get(name);
if (cachePattern) return cachePattern;
const reg = new RegExp(
'(?:^|;) *' +
name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +
'=([^;]*)'
);
cache.set(name, reg);
return reg;
}
function encryptOrSigned(opts) {
opts = opts || {};
// encrypt default to false, signed default to true.
// disable singed when encrypt is true.
if (opts.encrypt) opts.signed = false;
if (opts.signed !== false) opts.signed = true;
return opts;
}
function pushCookie(cookies, cookie) {
if (cookie.attrs.overwrite) {
cookies = cookies.filter(c => !c.startsWith(cookie.name + '='));
}
cookies.push(cookie.toHeader());
return cookies;
}
module.exports = Cookies;
{
"name": "egg-cookies",
"version": "1.0.0",
"description": "cookies module for egg, base on pillarjs/cookies",
"version": "2.0.0",
"description": "cookies module for egg",
"files": [

@@ -10,11 +10,17 @@ "lib"

"dependencies": {
"cookies": "~0.6.1",
"debug": "^2.2.0",
"scmp": "^1.0.0",
"utility": "^1.8.0"
"debug": "^2.3.3",
"scmp": "^2.0.0",
"utility": "^1.9.0"
},
"devDependencies": {
"egg-bin": "1",
"eslint": "3",
"eslint-config-egg": "3"
"autod": "^2.7.1",
"beautify-benchmark": "^0.2.4",
"benchmark": "^2.1.2",
"cookies": "^0.6.2",
"egg-bin": "^1.7.0",
"egg-ci": "^1.1.0",
"eslint": "^3.10.2",
"eslint-config-egg": "^3.2.0",
"intelli-espower-loader": "^1.0.1",
"power-assert": "^1.4.2"
},

@@ -28,6 +34,7 @@ "repository": {

"scripts": {
"test": "npm run lint && npm run test-local",
"test-local": "egg-bin test",
"lint": "eslint --fix lib test",
"ci": "npm run lint && egg-bin cov"
"test": "egg-bin test --require intelli-espower-loader",
"cov": "egg-bin cov --require intelli-espower-loader",
"lint": "eslint index.js test",
"ci": "npm run lint && npm run cov",
"autod": "autod"
},

@@ -38,4 +45,4 @@ "engines": {

"ci": {
"version": "4, 6"
"version": "4, 6, 7"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc