Skip to content

Commit

Permalink
✨[RUM-2436] add partitioned support for third party cookies (#2535)
Browse files Browse the repository at this point in the history
* Update rum-events-format

* Introduce usePartitionedCrossSiteSessionCookie config parameter
  • Loading branch information
bcaudan authored Dec 20, 2023
1 parent d7f2131 commit 672c52f
Show file tree
Hide file tree
Showing 9 changed files with 488 additions and 417 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/browser/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { findCommaSeparatedValue, findCommaSeparatedValues, generateUUID } from
export interface CookieOptions {
secure?: boolean
crossSite?: boolean
partitioned?: boolean
domain?: string
}

Expand All @@ -15,7 +16,8 @@ export function setCookie(name: string, value: string, expireDelay: number, opti
const sameSite = options && options.crossSite ? 'none' : 'strict'
const domain = options && options.domain ? `;domain=${options.domain}` : ''
const secure = options && options.secure ? ';secure' : ''
document.cookie = `${name}=${value};${expires};path=/;samesite=${sameSite}${domain}${secure}`
const partitioned = options && options.partitioned ? ';partitioned' : ''
document.cookie = `${name}=${value};${expires};path=/;samesite=${sameSite}${domain}${secure}${partitioned}`
}

export function getCookie(name: string) {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/domain/configuration/configuration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,15 @@ describe('validateAndBuildConfiguration', () => {
const configuration = validateAndBuildConfiguration({ clientToken, allowFallbackToLocalStorage: false })
expect(configuration?.sessionStoreStrategyType).toEqual({
type: 'Cookie',
cookieOptions: { secure: false, crossSite: false },
cookieOptions: { secure: false, crossSite: false, partitioned: false },
})
})

it('should contain cookie in the configuration when fallback is enabled and cookies are available', () => {
const configuration = validateAndBuildConfiguration({ clientToken, allowFallbackToLocalStorage: true })
expect(configuration?.sessionStoreStrategyType).toEqual({
type: 'Cookie',
cookieOptions: { secure: false, crossSite: false },
cookieOptions: { secure: false, crossSite: false, partitioned: false },
})
})

Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/domain/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ export interface InitConfiguration {
version?: string | undefined

// cookie options
/**
* @deprecated use usePartitionedCrossSiteSessionCookie instead
*/
useCrossSiteSessionCookie?: boolean | undefined
usePartitionedCrossSiteSessionCookie?: boolean | undefined
useSecureSessionCookie?: boolean | undefined
trackSessionAcrossSubdomains?: boolean | undefined

Expand Down Expand Up @@ -169,6 +173,7 @@ export function serializeConfiguration(initConfiguration: InitConfiguration): Pa
telemetry_configuration_sample_rate: initConfiguration.telemetryConfigurationSampleRate,
use_before_send: !!initConfiguration.beforeSend,
use_cross_site_session_cookie: initConfiguration.useCrossSiteSessionCookie,
use_partitioned_cross_site_session_cookie: initConfiguration.usePartitionedCrossSiteSessionCookie,
use_secure_session_cookie: initConfiguration.useSecureSessionCookie,
use_proxy: !!initConfiguration.proxy,
silent_multiple_init: initConfiguration.silentMultipleInit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,32 @@ describe('session in cookie strategy', () => {

it('should not be secure nor crossSite by default', () => {
const cookieOptions = buildCookieOptions({ clientToken })!
expect(cookieOptions).toEqual({ secure: false, crossSite: false })
expect(cookieOptions).toEqual({ secure: false, crossSite: false, partitioned: false })
})

it('should be secure when `useSecureSessionCookie` is truthy', () => {
const cookieOptions = buildCookieOptions({ clientToken, useSecureSessionCookie: true })!
expect(cookieOptions).toEqual({ secure: true, crossSite: false })
expect(cookieOptions).toEqual({ secure: true, crossSite: false, partitioned: false })
})

it('should be secure and crossSite when `useCrossSiteSessionCookie` is truthy', () => {
const cookieOptions = buildCookieOptions({ clientToken, useCrossSiteSessionCookie: true })!
expect(cookieOptions).toEqual({ secure: true, crossSite: true })
expect(cookieOptions).toEqual({ secure: true, crossSite: true, partitioned: false })
})

it('should be secure, crossSite and partitioned when `usePartitionedCrossSiteSessionCookie` is truthy', () => {
const cookieOptions = buildCookieOptions({ clientToken, usePartitionedCrossSiteSessionCookie: true })!
expect(cookieOptions).toEqual({ secure: true, crossSite: true, partitioned: true })
})

it('should have domain when `trackSessionAcrossSubdomains` is truthy', () => {
const cookieOptions = buildCookieOptions({ clientToken, trackSessionAcrossSubdomains: true })!
expect(cookieOptions).toEqual({ secure: false, crossSite: false, domain: jasmine.any(String) })
expect(cookieOptions).toEqual({
secure: false,
crossSite: false,
partitioned: false,
domain: jasmine.any(String),
})
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,13 @@ function deleteSessionCookie(options: CookieOptions) {
export function buildCookieOptions(initConfiguration: InitConfiguration) {
const cookieOptions: CookieOptions = {}

cookieOptions.secure = !!initConfiguration.useSecureSessionCookie || !!initConfiguration.useCrossSiteSessionCookie
cookieOptions.crossSite = !!initConfiguration.useCrossSiteSessionCookie
cookieOptions.secure =
!!initConfiguration.useSecureSessionCookie ||
!!initConfiguration.usePartitionedCrossSiteSessionCookie ||
!!initConfiguration.useCrossSiteSessionCookie
cookieOptions.crossSite =
!!initConfiguration.usePartitionedCrossSiteSessionCookie || !!initConfiguration.useCrossSiteSessionCookie
cookieOptions.partitioned = !!initConfiguration.usePartitionedCrossSiteSessionCookie

if (initConfiguration.trackSessionAcrossSubdomains) {
cookieOptions.domain = getCurrentSite()
Expand Down
14 changes: 13 additions & 1 deletion packages/core/src/domain/telemetry/telemetryEvent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,13 @@ export type TelemetryConfigurationEvent = CommonTelemetryProperties & {
*/
track_long_task?: boolean
/**
* Whether a secure cross-site session cookie is used
* Whether a secure cross-site session cookie is used (deprecated)
*/
use_cross_site_session_cookie?: boolean
/**
* Whether a partitioned secure cross-site session cookie is used
*/
use_partitioned_cross_site_session_cookie?: boolean
/**
* Whether a secure session cookie is used
*/
Expand Down Expand Up @@ -285,6 +289,14 @@ export type TelemetryConfigurationEvent = CommonTelemetryProperties & {
* The upload frequency of batches (in milliseconds)
*/
batch_upload_frequency?: number
/**
* Maximum number of batches processed sequencially without a delay
*/
batch_processing_level?: number
/**
* Whether UIApplication background tasks are enabled
*/
background_tasks_enabled?: boolean
/**
* The version of React used in a ReactNative application
*/
Expand Down
Loading

0 comments on commit 672c52f

Please sign in to comment.