Skip to content

Commit 53ce5dc

Browse files
authored
Avoid override set-cookie (#320)
1 parent 3016efd commit 53ce5dc

File tree

2 files changed

+61
-23
lines changed

2 files changed

+61
-23
lines changed

src/core.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,22 @@ const commitHead = (
2323
) => {
2424
if (res.headersSent || !session) return;
2525
if (session.isNew || touched) {
26-
res.setHeader(
27-
'Set-Cookie',
26+
const cookieArr = [
2827
serialize(name, encodeFn ? encodeFn(session.id) : session.id, {
2928
path: session.cookie.path,
3029
httpOnly: session.cookie.httpOnly,
3130
expires: session.cookie.expires,
3231
domain: session.cookie.domain,
3332
sameSite: session.cookie.sameSite,
3433
secure: session.cookie.secure,
35-
})
36-
);
34+
}),
35+
];
36+
const prevCookies = res.getHeader('set-cookie');
37+
if (prevCookies) {
38+
if (Array.isArray(prevCookies)) cookieArr.push(...prevCookies);
39+
else cookieArr.push(prevCookies as string);
40+
}
41+
res.setHeader('set-cookie', cookieArr);
3742
}
3843
};
3944

test/index.test.ts

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ describe('applySession', () => {
7474
expect(req.sessionStore).toBeInstanceOf(MemoryStore);
7575
const req2: any = {};
7676
await applySession(req2, res);
77-
expect(req2.sessionStore).toBe(req.sessionStore)
77+
expect(req2.sessionStore).toBe(req.sessionStore);
7878
});
7979

8080
test('should do nothing if req.session is defined', async () => {
@@ -148,7 +148,7 @@ describe('applySession', () => {
148148
}
149149
);
150150
const agent = request.agent(server);
151-
const res = (await agent.get('/'))
151+
const res = await agent.get('/');
152152
const originalExpires = res.text;
153153
expect(res.header).toHaveProperty('set-cookie');
154154
const res2 = await agent.get('/');
@@ -169,7 +169,7 @@ describe('applySession', () => {
169169
}
170170
);
171171
const agent = request.agent(server);
172-
const res = (await agent.get('/'))
172+
const res = await agent.get('/');
173173
const originalExpires = res.text;
174174
expect(res.header).toHaveProperty('set-cookie');
175175
const res2 = await agent.get('/');
@@ -179,7 +179,7 @@ describe('applySession', () => {
179179

180180
test('should touch if lifetime > touchAfter', async () => {
181181
const sessionStore = new MemoryStore();
182-
let sessId: string = ''
182+
let sessId: string = '';
183183
const server = setUpServer(
184184
(req, res) => {
185185
req.session.hello = 'world';
@@ -202,13 +202,15 @@ describe('applySession', () => {
202202
// Shift expires 10 seconds to simulate 10 seconds time fly
203203
const sess = await sessionStore.get(sessId as string);
204204
// Force 10 sec back in the past for cookie to expire
205-
sess!.cookie.expires! = new Date(sess!.cookie.expires!.valueOf() - 10 * 1000)
206-
await sessionStore.set(sessId as string, sess!)
205+
sess!.cookie.expires! = new Date(
206+
sess!.cookie.expires!.valueOf() - 10 * 1000
207+
);
208+
await sessionStore.set(sessId as string, sess!);
207209

208210
const res = await agent.get('/');
209211
expect(res.text).not.toStrictEqual(originalExpires);
210212
expect(res.header).toHaveProperty('set-cookie');
211-
})
213+
});
212214

213215
test('should not touch if lifetime < touchAfter', async () => {
214216
const server = setUpServer(
@@ -285,21 +287,27 @@ describe('applySession', () => {
285287
});
286288

287289
test('should define session.isNew that determines if session is new', async () => {
288-
const server = setUpServer((req, res) => {
289-
const isNew = req.session.isNew;
290-
req.session.foo = 'bar';
291-
res.end(String(isNew));
292-
}, {store: new MemoryStore()});
290+
const server = setUpServer(
291+
(req, res) => {
292+
const isNew = req.session.isNew;
293+
req.session.foo = 'bar';
294+
res.end(String(isNew));
295+
},
296+
{ store: new MemoryStore() }
297+
);
293298
const agent = request.agent(server);
294299
await agent.get('/').expect('true');
295300
await agent.get('/').expect('false');
296301
});
297302

298303
test('should works with writeHead and autoCommit', async () => {
299-
const server = setUpServer((req, res) => {
300-
req.session.foo = 'bar';
301-
res.writeHead(302, { Location: '/login' }).end();
302-
}, {store: new MemoryStore()});
304+
const server = setUpServer(
305+
(req, res) => {
306+
req.session.foo = 'bar';
307+
res.writeHead(302, { Location: '/login' }).end();
308+
},
309+
{ store: new MemoryStore() }
310+
);
303311
await request(server)
304312
.post('/')
305313
.then(({ header }) => expect(header).toHaveProperty('set-cookie'));
@@ -329,6 +337,31 @@ describe('applySession', () => {
329337

330338
expect(req.session.cookie.expires).toBeInstanceOf(Date);
331339
});
340+
341+
test('should not override existing set-cookie', async () => {
342+
// Single set-cookie
343+
const server = setUpServer(
344+
(req, res) => {
345+
res.setHeader('Set-Cookie', 'test=test');
346+
res.end();
347+
},
348+
{ store: new MemoryStore() }
349+
);
350+
await request(server)
351+
.post('/')
352+
.then(({ header }) => expect(header['set-cookie']).toHaveLength(2));
353+
// Multiple set-cookie
354+
const server2 = setUpServer(
355+
(req, res) => {
356+
res.setHeader('Set-Cookie', ['test=test', 'test2=test2']);
357+
res.end();
358+
},
359+
{ store: new MemoryStore() }
360+
);
361+
await request(server2)
362+
.post('/')
363+
.then(({ header }) => expect(header['set-cookie']).toHaveLength(3));
364+
});
332365
});
333366

334367
describe('withSession', () => {
@@ -451,7 +484,7 @@ describe('callback store', () => {
451484
.post('/')
452485
.then(({ header }) => expect(header).toHaveProperty('set-cookie'));
453486
await agent.get('/').expect('2');
454-
})
487+
});
455488
it('should work (without touch)', async () => {
456489
const store = (new CbStore() as unknown) as ExpressStore;
457490
delete store.touch;
@@ -525,8 +558,8 @@ describe('MemoryStore', () => {
525558

526559
const sess = await sessionStore.get(sessionId as string);
527560
// Force 10 sec back in the past for cookie to expire
528-
sess!.cookie.expires! = new Date(sess!.cookie.expires!.valueOf() - 10000)
529-
await sessionStore.set(sessionId as string, sess!)
561+
sess!.cookie.expires! = new Date(sess!.cookie.expires!.valueOf() - 10000);
562+
await sessionStore.set(sessionId as string, sess!);
530563

531564
await agent.get('/').expect('0');
532565
// Check in the store

0 commit comments

Comments
 (0)