Skip to content

Commit 62bd071

Browse files
authored
fix: try to get session id from cookie when destroying an unloaded session (#14167)
1 parent 67e2f60 commit 62bd071

File tree

3 files changed

+35
-19
lines changed

3 files changed

+35
-19
lines changed

.changeset/soft-rabbits-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fixes a bug that prevented destroyed sessions from being deleted from storage unless the session had been loaded

packages/astro/src/core/session.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,16 @@ export class AstroSession<TDriver extends SessionDriverName = any> {
214214
/**
215215
* Destroys the session, clearing the cookie and storage if it exists.
216216
*/
217-
218217
destroy() {
219-
this.#destroySafe();
218+
// We don't use #ensureSessionID here because we don't want to create a new session ID if it doesn't exist.
219+
const sessionId = this.#sessionID ?? this.#cookies.get(this.#cookieName)?.value;
220+
if (sessionId) {
221+
this.#toDestroy.add(sessionId);
222+
}
223+
this.#cookies.delete(this.#cookieName, this.#cookieConfig);
224+
this.#sessionID = undefined;
225+
this.#data = undefined;
226+
this.#dirty = true;
220227
}
221228

222229
/**
@@ -351,7 +358,7 @@ export class AstroSession<TDriver extends SessionDriverName = any> {
351358
try {
352359
const storedMap = unflatten(raw);
353360
if (!(storedMap instanceof Map)) {
354-
await this.#destroySafe();
361+
await this.destroy();
355362
throw new AstroError({
356363
...SessionStorageInitError,
357364
message: SessionStorageInitError.message(
@@ -377,7 +384,7 @@ export class AstroSession<TDriver extends SessionDriverName = any> {
377384
this.#partial = false;
378385
return this.#data;
379386
} catch (err) {
380-
await this.#destroySafe();
387+
await this.destroy();
381388
if (err instanceof AstroError) {
382389
throw err;
383390
}
@@ -393,20 +400,6 @@ export class AstroSession<TDriver extends SessionDriverName = any> {
393400
);
394401
}
395402
}
396-
/**
397-
* Safely destroys the session, clearing the cookie and storage if it exists.
398-
*/
399-
#destroySafe() {
400-
if (this.#sessionID) {
401-
this.#toDestroy.add(this.#sessionID);
402-
}
403-
if (this.#cookieName) {
404-
this.#cookies.delete(this.#cookieName, this.#cookieConfig);
405-
}
406-
this.#sessionID = undefined;
407-
this.#data = undefined;
408-
this.#dirty = true;
409-
}
410403

411404
/**
412405
* Returns the session ID, generating a new one if it does not exist.

packages/astro/test/units/sessions/astro-session.test.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { AstroSession, PERSIST_SYMBOL } from '../../../dist/core/session.js';
77
const defaultMockCookies = {
88
set: () => {},
99
delete: () => {},
10-
get: () => 'sessionid',
10+
get: () => ({ value: 'sessionid' }),
1111
};
1212

1313
const stringify = (data) => JSON.parse(devalueStringify(data));
@@ -360,6 +360,24 @@ test('AstroSession - Cleanup Operations', async (t) => {
360360

361361
assert.ok(removedKeys.has(oldId), `Session ${oldId} should be removed`);
362362
});
363+
364+
await t.test("should destroy sessions that haven't been loaded", async () => {
365+
const removedKeys = new Set();
366+
const mockStorage = {
367+
get: async () => stringify(new Map([['key', 'value']])),
368+
setItem: async () => {},
369+
removeItem: async (key) => {
370+
removedKeys.add(key);
371+
},
372+
};
373+
374+
const session = createSession(defaultConfig, defaultMockCookies, mockStorage);
375+
session.destroy();
376+
377+
// Simulate end of request
378+
await session[PERSIST_SYMBOL]();
379+
assert.equal(removedKeys.size, 1, `Session should be removed`);
380+
});
363381
});
364382

365383
test('AstroSession - Cookie Security', async (t) => {

0 commit comments

Comments
 (0)