Skip to content

Commit

Permalink
Merge pull request #2811 from Gaurav0/gaurav/feat/support_partitioned…
Browse files Browse the repository at this point in the history
…_cookies

feat: support partitioned cookies
  • Loading branch information
BobrImperator authored Nov 18, 2024
2 parents 2898b40 + 73ea01b commit f751300
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 23 deletions.
2 changes: 1 addition & 1 deletion packages/ember-simple-auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@embroider/addon-shim": "^1.0.0",
"@embroider/macros": "^1.0.0",
"ember-cli-is-package-missing": "^1.0.0",
"ember-cookies": "^1.0.0",
"ember-cookies": "^1.2.0",
"silent-error": "^1.0.0"
},
"devDependencies": {
Expand Down
21 changes: 20 additions & 1 deletion packages/ember-simple-auth/src/session-stores/adaptive.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,24 @@ export default Base.extend({
_sameSite: null,
sameSite: proxyToInternalStore(),

/**
Allows servers to assert that a cookie should opt in to partitioned storage,
i.e. use a separate cookie per top level site if the cookie is used in a
third party context
Available options:
- null
- true
@memberof AdaptiveStore
@property partitioned
@type Boolean
@default null
@public
*/
_partitioned: null,
partitioned: proxyToInternalStore(),

/**
The name of the cookie to use if `localStorage` is not available.
Expand Down Expand Up @@ -158,7 +176,8 @@ export default Base.extend({
'cookieName',
'cookieExpirationTime',
'cookiePath',
'sameSite'
'sameSite',
'partitioned'
);

cookieStorage.setProperties(options);
Expand Down
19 changes: 19 additions & 0 deletions packages/ember-simple-auth/src/session-stores/cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,24 @@ export default BaseStore.extend({
}
}),

/**
Allows servers to assert that a cookie should opt in to partitioned storage,
i.e. use a separate cookie per top level site if the cookie is used in a
third party context
Available options:
- null
- true
@memberof CookieStore
@property partitioned
@type Boolean
@default null
@public
*/
_partitioned: null,
partitioned: persistingProperty(),

_cookies: service('cookies'),

_secureCookies() {
Expand Down Expand Up @@ -272,6 +290,7 @@ export default BaseStore.extend({
path: this.get('cookiePath'),
secure: this._secureCookies(),
sameSite: this.get('sameSite'),
partitioned: this.get('partitioned'),
};
if (this._oldCookieName) {
A([this._oldCookieName, `${this._oldCookieName}-expiration_time`]).forEach(oldCookie => {
Expand Down
2 changes: 1 addition & 1 deletion packages/test-esa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"ember-maybe-import-regenerator": "1.0.0",
"ember-qunit": "7.0.0",
"ember-resolver": "11.0.1",
"ember-simple-auth": "6.1.0",
"ember-simple-auth": "workspace:*",
"ember-source": "5.12.0",
"ember-source-channel-url": "3.0.0",
"ember-try": "3.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ export default function (options) {
let cookieService = store.get('_cookies');
await store.persist({ key: 'value' });

assert.ok(
assert.true(
cookieService.write.calledWith('test:session', JSON.stringify({ key: 'value' }), {
domain: null,
expires: null,
path: '/',
sameSite: null,
secure: false,
partitioned: null,
})
);
});
Expand All @@ -65,13 +66,14 @@ export default function (options) {
});
await store.persist({ key: 'value' });

assert.ok(
assert.true(
cookieService.write.calledWith('session-cookie-domain', JSON.stringify({ key: 'value' }), {
domain: 'example.com',
expires: null,
path: '/',
sameSite: null,
secure: false,
partitioned: null,
})
);
});
Expand All @@ -85,13 +87,14 @@ export default function (options) {
let cookieService = store.get('_cookies');
await store.persist({ key: 'value' });

assert.ok(
assert.true(
cookieService.write.calledWith('session-cookie-domain', JSON.stringify({ key: 'value' }), {
domain: 'example.com',
expires: null,
path: '/hello-world',
sameSite: null,
secure: false,
partitioned: null,
})
);
});
Expand All @@ -104,17 +107,42 @@ export default function (options) {
});
let cookieService = store.get('_cookies');
await store.persist({ key: 'value' });
assert.ok(
assert.true(
cookieService.write.calledWith('session-cookie-domain', JSON.stringify({ key: 'value' }), {
domain: 'example.com',
expires: null,
path: '/',
sameSite: 'Strict',
secure: false,
partitioned: null,
})
);
});

test('respects the configured partitioned', async function (assert) {
run(() => {
store.set('cookieName', 'session-cookie-partitioned');
store.set('cookieDomain', 'example.com');
store.set('partitioned', true);
});
let cookieService = store.get('_cookies');
await store.persist({ key: 'value' });
assert.true(
cookieService.write.calledWith(
'session-cookie-partitioned',
JSON.stringify({ key: 'value' }),
{
domain: 'example.com',
expires: null,
path: '/',
sameSite: null,
secure: false,
partitioned: true,
}
)
);
});

test('sends a warning when `cookieExpirationTime` is less than 90 seconds', async function (assert) {
assert.expect(2);
run(() => {
Expand Down Expand Up @@ -155,7 +183,7 @@ export default function (options) {
});

test('stores the expiration time in a cookie named "test-session-expiration_time"', function (assert) {
assert.ok(
assert.true(
cookieService.write.calledWith(
'test-session-expiration_time',
60,
Expand Down Expand Up @@ -212,7 +240,7 @@ export default function (options) {
await new Promise(resolve => {
next(() => {
next(() => {
assert.ok(triggered);
assert.true(triggered);
resolve();
});
});
Expand Down Expand Up @@ -264,11 +292,11 @@ export default function (options) {
});
await store.persist({ key: 'value' });

assert.ok(cookieService.clear.calledWith('session-foo'));
assert.true(cookieService.clear.calledWith('session-foo'));

assert.ok(cookieService.clear.calledWith('session-foo-expiration_time'));
assert.true(cookieService.clear.calledWith('session-foo-expiration_time'));

assert.ok(
assert.true(
cookieService.write.calledWith(
'session-bar',
JSON.stringify({ key: 'value' }),
Expand All @@ -283,7 +311,7 @@ export default function (options) {
)
);

assert.ok(
assert.true(
cookieService.write.calledWith(
'session-bar-expiration_time',
1000,
Expand All @@ -307,11 +335,11 @@ export default function (options) {
});
await store.persist({ key: 'value' });

assert.ok(cookieService.clear.calledWith(defaultName));
assert.true(cookieService.clear.calledWith(defaultName));

assert.ok(cookieService.clear.calledWith(`${defaultName}-expiration_time`));
assert.true(cookieService.clear.calledWith(`${defaultName}-expiration_time`));

assert.ok(
assert.true(
cookieService.write.calledWith(
'session-bar',
JSON.stringify({ key: 'value' }),
Expand All @@ -336,11 +364,11 @@ export default function (options) {
});
await store.persist({ key: 'value' });

assert.ok(cookieService.clear.calledWith(defaultName));
assert.true(cookieService.clear.calledWith(defaultName));

assert.ok(cookieService.clear.calledWith(`${defaultName}-expiration_time`));
assert.true(cookieService.clear.calledWith(`${defaultName}-expiration_time`));

assert.ok(
assert.true(
cookieService.write.calledWith(
'session-bar',
JSON.stringify({ key: 'value' }),
Expand All @@ -364,7 +392,7 @@ export default function (options) {

await new Promise(resolve => {
next(() => {
assert.ok(cookieService.clear.calledWith('session-foo-expiration_time'));
assert.true(cookieService.clear.calledWith('session-foo-expiration_time'));
resolve();
});
});
Expand All @@ -379,7 +407,7 @@ export default function (options) {

await new Promise(resolve => {
next(() => {
assert.ok(cookieSpy.calledOnce);
assert.true(cookieSpy.calledOnce);
resolve();
});
});
Expand Down
14 changes: 12 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f751300

Please sign in to comment.