Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions .changeset/honest-loops-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes a bug that caused cookies to ignore custom decode function if has() had been called before
28 changes: 16 additions & 12 deletions packages/astro/src/core/cookies/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const DELETED_EXPIRATION = new Date(0);
const DELETED_VALUE = 'deleted';
const responseSentSymbol = Symbol.for('astro.responseSent');

const identity = (value: string) => value;

class AstroCookie implements AstroCookieInterface {
constructor(public value: string) {}
json() {
Expand Down Expand Up @@ -117,11 +119,13 @@ class AstroCookies implements AstroCookiesInterface {
}
}

const values = this.#ensureParsed(options);
const decode = options?.decode ?? decodeURIComponent

const values = this.#ensureParsed();
if (key in values) {
const value = values[key];
if (value) {
return new AstroCookie(value);
return new AstroCookie(decode(value));
}
}
}
Expand All @@ -130,15 +134,16 @@ class AstroCookies implements AstroCookiesInterface {
* Astro.cookies.has(key) returns a boolean indicating whether this cookie is either
* part of the initial request or set via Astro.cookies.set(key)
* @param key The cookie to check for.
* @param _options This parameter is no longer used.
* @returns
*/
has(key: string, options: AstroCookieGetOptions | undefined = undefined): boolean {
has(key: string, _options?: AstroCookieGetOptions): boolean {
if (this.#outgoing?.has(key)) {
let [, , isSetValue] = this.#outgoing.get(key)!;
return isSetValue;
}
const values = this.#ensureParsed(options);
return !!values[key];
const values = this.#ensureParsed();
return values[key] !== undefined;
Comment on lines -141 to +146
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously it would return false for has() when the cookie had a falsy value, even if it existed

}

/**
Expand Down Expand Up @@ -227,11 +232,9 @@ class AstroCookies implements AstroCookiesInterface {
return cookies.headers();
}

#ensureParsed(
options: AstroCookieGetOptions | undefined = undefined,
): Record<string, string | undefined> {
#ensureParsed(): Record<string, string | undefined> {
if (!this.#requestValues) {
this.#parse(options);
this.#parse();
}
if (!this.#requestValues) {
this.#requestValues = {};
Expand All @@ -246,13 +249,14 @@ class AstroCookies implements AstroCookiesInterface {
return this.#outgoing;
}

#parse(options: AstroCookieGetOptions | undefined = undefined) {
#parse() {
const raw = this.#request.headers.get('cookie');
if (!raw) {
return;
}

this.#requestValues = parse(raw, options);
// Pass identity function for decoding so it doesn't use the default.
// We'll do the actual decoding when we read the value.
this.#requestValues = parse(raw, { decode: identity });
}
}

Expand Down