Skip to content

Commit b8db250

Browse files
committed
Remove JSON encoding from cookies
1 parent 6f1d7fb commit b8db250

File tree

2 files changed

+16
-34
lines changed

2 files changed

+16
-34
lines changed

packages/cookie/src/lib/cookie.test.ts

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@ describe('cookies', () => {
2424
assert.equal(value, 'hello world')
2525
})
2626

27-
it('parses/serializes unsigned boolean values', async () => {
28-
let cookie = new Cookie('my-cookie')
29-
let setCookie = await cookie.serialize(true)
30-
let value = await cookie.parse(getCookieFromSetCookie(setCookie))
31-
32-
assert.equal(value, true)
33-
})
34-
3527
it('parses/serializes signed string values', async () => {
3628
let cookie = new Cookie('my-cookie', {
3729
secrets: ['secret1'],
@@ -81,33 +73,20 @@ describe('cookies', () => {
8173
let cookie = new Cookie('my-cookie', {
8274
secrets: ['secret1'],
8375
})
84-
let setCookie = await cookie.serialize({ hello: 'mjackson' })
85-
let value = await cookie.parse(getCookieFromSetCookie(setCookie))
76+
let setCookie = await cookie.serialize(JSON.stringify({ hello: 'mjackson' }))
77+
let value = JSON.parse((await cookie.parse(getCookieFromSetCookie(setCookie)))!)
8678

8779
assert.deepEqual(value, { hello: 'mjackson' })
8880
})
8981

90-
it('fails to parse signed object values with invalid signature', async () => {
91-
let cookie = new Cookie('my-cookie', {
92-
secrets: ['secret1'],
93-
})
94-
let setCookie = await cookie.serialize({ hello: 'mjackson' })
95-
let cookie2 = new Cookie('my-cookie', {
96-
secrets: ['secret2'],
97-
})
98-
let value = await cookie2.parse(getCookieFromSetCookie(setCookie))
99-
100-
assert.equal(value, null)
101-
})
102-
10382
it('supports secret rotation', async () => {
10483
let cookie = new Cookie('my-cookie', {
10584
secrets: ['secret1'],
10685
})
107-
let setCookie = await cookie.serialize({ hello: 'mjackson' })
86+
let setCookie = await cookie.serialize('mjackson')
10887
let value = await cookie.parse(getCookieFromSetCookie(setCookie))
10988

110-
assert.deepEqual(value, { hello: 'mjackson' })
89+
assert.deepEqual(value, 'mjackson')
11190

11291
// A new secret enters the rotation...
11392
cookie = new Cookie('my-cookie', {
@@ -121,6 +100,9 @@ describe('cookies', () => {
121100
// New Set-Cookie should be different, it uses a different secret.
122101
let setCookie2 = await cookie.serialize(value)
123102
assert.notEqual(setCookie, setCookie2)
103+
104+
let newValue = await cookie.parse(getCookieFromSetCookie(setCookie2))
105+
assert.deepEqual(oldValue, newValue)
124106
})
125107

126108
it('makes the default secrets to be an empty array', async () => {

packages/cookie/src/lib/cookie.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class Cookie {
7171
* Parses a raw `Cookie` header and returns the value of this cookie or
7272
* `null` if it's not present.
7373
*/
74-
async parse(cookieHeader: string | null, parseOptions?: ParseOptions): Promise<unknown> {
74+
async parse(cookieHeader: string | null, parseOptions?: ParseOptions): Promise<string | null> {
7575
if (!cookieHeader) return null
7676
let cookies = parse(cookieHeader, { ...this.#options, ...parseOptions })
7777
if (this.name in cookies) {
@@ -91,15 +91,15 @@ export class Cookie {
9191
* Serializes the given value to a string and returns the `Set-Cookie`
9292
* header.
9393
*/
94-
async serialize(value: unknown, serializeOptions?: SerializeOptions): Promise<string> {
94+
async serialize(value: string, serializeOptions?: SerializeOptions): Promise<string> {
9595
return serialize(this.name, value === '' ? '' : await encodeCookieValue(value, this.#secrets), {
9696
...this.#options,
9797
...serializeOptions,
9898
})
9999
}
100100
}
101101

102-
async function encodeCookieValue(value: unknown, secrets: string[]): Promise<string> {
102+
async function encodeCookieValue(value: string, secrets: string[]): Promise<string> {
103103
let encoded = encodeData(value)
104104

105105
if (secrets.length > 0) {
@@ -109,7 +109,7 @@ async function encodeCookieValue(value: unknown, secrets: string[]): Promise<str
109109
return encoded
110110
}
111111

112-
async function decodeCookieValue(value: string, secrets: string[]): Promise<unknown> {
112+
async function decodeCookieValue(value: string, secrets: string[]): Promise<string | null> {
113113
if (secrets.length > 0) {
114114
for (let secret of secrets) {
115115
let unsignedValue = await unsign(value, secret)
@@ -124,15 +124,15 @@ async function decodeCookieValue(value: string, secrets: string[]): Promise<unkn
124124
return decodeData(value)
125125
}
126126

127-
function encodeData(value: unknown): string {
128-
return btoa(myUnescape(encodeURIComponent(JSON.stringify(value))))
127+
function encodeData(value: string): string {
128+
return btoa(myUnescape(encodeURIComponent(value)))
129129
}
130130

131-
function decodeData(value: string): unknown {
131+
function decodeData(value: string): string | null {
132132
try {
133-
return JSON.parse(decodeURIComponent(myEscape(atob(value))))
133+
return decodeURIComponent(myEscape(atob(value)))
134134
} catch {
135-
return {}
135+
return null
136136
}
137137
}
138138

0 commit comments

Comments
 (0)