Skip to content

Commit

Permalink
feat: add removeUnpartitioned
Browse files Browse the repository at this point in the history
  • Loading branch information
czy88840616 committed Dec 28, 2023
1 parent 971f5b5 commit 5404e4a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,30 @@ export class Cookies {
}
}

// remove unpartitioned same name cookie first
if (opts.partitioned && opts.removeUnpartitioned) {
const overwrite = opts.overwrite;
if (overwrite) {
opts.overwrite = false;
headers = ignoreCookiesByName(headers, name);
}
const removeCookieOpts = Object.assign({}, opts, {
partitioned: false,
});
const removeUnpartitionedCookie = new Cookie(name, '', removeCookieOpts);
// if user not set secure, reset secure to ctx.secure
if (opts.secure === undefined)
removeUnpartitionedCookie.attrs.secure = this.secure;

headers = pushCookie(headers, removeUnpartitionedCookie);
// signed
if (signed) {
removeUnpartitionedCookie.name += '.sig';
headers = ignoreCookiesByName(headers, removeUnpartitionedCookie.name);
headers = pushCookie(headers, removeUnpartitionedCookie);
}
}

if (opts.priority) {
if (!userAgent || (userAgent && !this.isPriorityCompatible(userAgent))) {
// ignore priority when not secure or incompatible clients
Expand Down Expand Up @@ -253,12 +277,17 @@ function computeSigned(opts) {

function pushCookie(cookies, cookie) {
if (cookie.attrs.overwrite) {
cookies = cookies.filter(c => !c.startsWith(cookie.name + '='));
cookies = ignoreCookiesByName(cookies, cookie.name);
}
cookies.push(cookie.toHeader());
return cookies;
}

function ignoreCookiesByName(cookies, name) {
const prefix = `${name}=`;
return cookies.filter(c => !c.startsWith(prefix));
}

export function urlSafeEncode(encode: string): string {
return encode.replace(/\+/g, '-').replace(/\//g, '_');
}
Expand Down
4 changes: 4 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,8 @@ export interface CookieSetOptions {
* If this is true, Cookies from embedded sites will be partitioned and only readable from the same top level site from which it was created.
*/
partitioned?: boolean;
/**
* Remove unpartitioned same name cookie or not.
*/
removeUnpartitioned?: boolean;
}
46 changes: 46 additions & 0 deletions test/cookies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,5 +557,51 @@ describe('test/cookies.test.ts', () => {
assert(str.includes('; path=/; httponly'));
}
});

it('should remove unpartitioned property first', () => {
const cookies = CreateCookie({
secure: true,
headers: {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.3945.29 Safari/537.36',
},
}, { secure: true }, { partitioned: true, removeUnpartitioned: true });
const opts = {
signed: 1,
} as any;
cookies.set('foo', 'hello', opts);

assert(opts.signed === 1);
assert(opts.secure === undefined);
const headers = cookies.ctx.response.headers['set-cookie'];
// console.log(headers);
assert.equal(headers.length, 4);
assert.equal(headers[0], 'foo=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure; httponly');
assert.equal(headers[1], 'foo.sig=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure; httponly');
assert.equal(headers[2], 'foo=hello; path=/; secure; httponly; partitioned');
assert.equal(headers[3], 'foo.sig=ZWbaA4bWk8ByBuYVgfmJ2DMvhhS3sOctMbfXAQ2vnwI; path=/; secure; httponly; partitioned');
});

it('should remove unpartitioned property first with overwrite = true', () => {
const cookies = CreateCookie({
secure: true,
headers: {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.3945.29 Safari/537.36',
},
}, { secure: true }, { partitioned: true, removeUnpartitioned: true, overwrite: true });
const opts = {
signed: 1,
} as any;
cookies.set('foo', 'hello2222', opts);
cookies.set('foo', 'hello', opts);

assert(opts.signed === 1);
assert(opts.secure === undefined);
const headers = cookies.ctx.response.headers['set-cookie'];
assert.equal(headers.length, 4);
assert.equal(headers[0], 'foo=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure; httponly');
assert.equal(headers[1], 'foo.sig=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure; httponly');
assert.equal(headers[2], 'foo=hello; path=/; secure; httponly; partitioned');
assert.equal(headers[3], 'foo.sig=ZWbaA4bWk8ByBuYVgfmJ2DMvhhS3sOctMbfXAQ2vnwI; path=/; secure; httponly; partitioned');
});
});
});

0 comments on commit 5404e4a

Please sign in to comment.