Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ module.exports = function(opts, app){
throw new TypeError('app instance required: `session(opts, app)`');
}

// setup encoding/decoding
if (!(typeof opts.encode === 'function')) {
opts.encode = encode
}
if (!(typeof opts.decode === 'function')) {
opts.decode = decode
}

// to pass to Session()
app.context.sessionKey = opts.key;

Expand All @@ -63,7 +71,7 @@ module.exports = function(opts, app){
try {
// make sure sessionOptions exists
initSessionOptions(this, opts);
var obj = decode(json);
var obj = opts.decode(json);
if (typeof opts.valid === 'function' && !opts.valid(this, obj)) {
// valid session value fail, ignore this session
sess = new Session(this);
Expand All @@ -72,7 +80,7 @@ module.exports = function(opts, app){
} else {
sess = new Session(this, obj);
// make prev a different object from sess
json = decode(json);
json = opts.decode(json);
}
} catch (err) {
// backwards compatibility:
Expand Down Expand Up @@ -278,9 +286,14 @@ Session.prototype.save = function(){
json._expire = maxAge + Date.now();
json._maxAge = maxAge;

json = encode(json);
debug('save %s', json);
ctx.cookies.set(key, json, opts);
try {
json = opts.encode(json);
debug('save %s', json);
ctx.cookies.set(key, json, opts);
} catch (e) {
debug('encode %j error: %s', json, err);
ctx.cookies.set(key, '', opts);
}
};

/**
Expand Down
49 changes: 49 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,55 @@ describe('Koa Session', function(){
});
})
})

describe('when options.encode and options.decode are functions', function () {
describe('they are used to encode/decode stored cookie values', function () {
it('should work', function (done) {
var encodeCallCount = 0
var decodeCallCount = 0

function encode(data) {
++encodeCallCount
return JSON.stringify({enveloped: data})
}
function decode(data) {
++decodeCallCount
return JSON.parse(data).enveloped
}

var app = koa();
app.keys = ['a', 'b'];
app.use(session({
encode: encode,
decode: decode
}, app));

app.use(function * () {
this.session.counter = (this.session.counter || 0) + 1
this.body = this.session
return
})

request(app.callback())
.get('/')
.expect(function () { encodeCallCount.should.above(0, 'encode was not called'); })
.expect(200, function (err, res) {
should.not.exist(err)
res.body.counter.should.equal(1, 'expected body to be equal to session.counter')
var cookies = res.headers['set-cookie'].join(';');
request(app.callback())
.get('/')
.set('Cookie', cookies)
.expect(function () { decodeCallCount.should.be.above(1, 'decode was not called'); })
.expect(200, function (err, res) {
should.not.exist(err);
res.body.counter.should.equal(2);
done();
})
})
})
})
})
})

function App(options) {
Expand Down