From e4cd5da0ebd364f18f0446b3ebfc36f2e8a0e317 Mon Sep 17 00:00:00 2001 From: Yao Xiao Date: Tue, 14 Nov 2023 15:38:59 -0500 Subject: [PATCH 1/4] Return empty topics on user settings check failures This exposes less information. Otherwise, the user setting error is detectable. --- spec.bs | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/spec.bs b/spec.bs index c9fe9ed..6abfd6b 100644 --- a/spec.bs +++ b/spec.bs @@ -279,7 +279,7 @@ spec: html; urlPrefix: https://www.rfc-editor.org/rfc/ 1. Let |presumedNextCalculationDelay| be |lastTopicsCalculationTime| + (a [=duration=] of 7 days) − |fromUnixEpochTime|. 1. If |presumedNextCalculationDelay| < (a [=duration=] of 0), then set |presumedNextCalculationDelay| to (a [=duration=] of 0). 1. Else if |presumedNextCalculationDelay| ≥ (a [=duration=] of 14 days), then set |presumedNextCalculationDelay| to (a [=duration=] of 0). - + Note: This could happen if the machine time has gone backward since the last topics calculation. Recalculate immediately to align with the expected schedule rather than potentially stop calculating for a very long time. 1. Schedule the [=calculate user topics=] algorithm to run at [=Unix epoch=] + |fromUnixEpochTime| + |presumedNextCalculationDelay|. @@ -455,21 +455,18 @@ spec: html; urlPrefix: https://www.rfc-editor.org/rfc/ - |document|'s [=Document/origin=] is an [=opaque origin=]. - |document| is not [=allowed to use=] the browsing-topics feature. - |document| is not [=allowed to use=] the interest-cohort feature. - - The user preference setting disallows access to topics from |topLevelDocument| given |document|'s [=Document/origin=]. - - Access to topics from |topLevelDocument| given |document|'s [=Document/origin=] is disabled due to some other user agent-defined mechanism, like lack of enrollment. - - Note: In Chrome's experimentation phase, it will additionally require a valid origin trial token to exist in |document|. then: 1. [=Queue a global task=] on the browsing topics task source given |document|'s [=relevant global object=] to [=reject=] |promise| with a "{{NotAllowedError}}" {{DOMException}}. 1. Abort these steps. 1. Run the following steps [=in parallel=]: - 1. Let |topics| be the result of running the [=calculate the topics for caller=] algorithm, with |topicsCallerContext| as input. - 1. If options["{{BrowsingTopicsOptions/skipObservation}}"] is false: - 1. Run the [=collect page topics calculation input data=] algorithm with |topLevelDocument| as input. - 1. Run the [=collect topics caller domain=] algorithm with |topLevelDocument| and |topicsCallerContext|'s [=topics caller context/caller domain=] as input. - 1. [=Queue a global task=] on the [=browsing topics task source=] given |document|'s [=relevant global object=] to perform the following steps: - 1. [=Resolve=] |promise| with |topics|. + 1. Let |topics| be an empty [=list=]. + 1. If the user preference setting and other user agent-defined mechanisms like enrollment allow access to topics from |topLevelDocument| given |document|'s [=Document/origin=]: + 1. Set |topics| to the result of running the [=calculate the topics for caller=] algorithm, with |topicsCallerContext| as input. + 1. If options["{{BrowsingTopicsOptions/skipObservation}}"] is false: + 1. Run the [=collect page topics calculation input data=] algorithm with |topLevelDocument| as input. + 1. Run the [=collect topics caller domain=] algorithm with |topLevelDocument| and |topicsCallerContext|'s [=topics caller context/caller domain=] as input. + 1. [=Queue a global task=] on the [=browsing topics task source=] given |document|'s [=relevant global object=] to [=Resolve=] |promise| with |topics|. 1. Return |promise|. @@ -557,9 +554,11 @@ spec: html; urlPrefix: https://www.rfc-editor.org/rfc/ 1. Let |moment| be the result of running [=coarsen time=] algorithm given |unsafeMoment| and [=wall clock=] as input. 1. Let |fromUnixEpochTime| be the [=duration from=] the [=Unix epoch=] to |moment|. 1. Set |topicsCallerContext|'s [=topics caller context/timestamp=] to |fromUnixEpochTime|. - 1. If the user preference setting disallows access to topics from |topLevelDocument| given |requestOrigin|, or access to topics from |topLevelDocument| given |requestOrigin| is disabled due to some other user agent-defined mechanism, like lack of enrollment, then return. - 1. Let |topics| be the result of running the [=calculate the topics for caller=] algorithm, with |topicsCallerContext| as input. - 1. Let |numVersionsInEpochs| be the result of running the [=get the number of distinct versions in epochs=] algorithm, with |topicsCallerContext| as input. + 1. Let |topics| be an empty [=list=]. + 1. Let |numVersionsInEpochs| be 0. + 1. If the user preference setting and other user agent-defined mechanisms like enrollment allow access to topics from |topLevelDocument| given |requestOrigin|: + 1. Set |topics| to the result of running the [=calculate the topics for caller=] algorithm, with |topicsCallerContext| as input. + 1. Set |numVersionsInEpochs| to the result of running the [=get the number of distinct versions in epochs=] algorithm, with |topicsCallerContext| as input. 1. Let |versionsToTopics| be an [=ordered map=]. 1. For each |topic| of |topics|: 1. Let |version| be |topic|["{{BrowsingTopic/version}}"]. @@ -631,10 +630,6 @@ spec: html; urlPrefix: https://www.rfc-editor.org/rfc/ The various lengths being returned (that depends on the number of distinct versions) could leak which epochs the user had disabled topics or didn't use the browser, if it coincided with the version change. But this leak is minor. The most common cases (i.e. returning same version topics, or no topics) will have the same length. - -
- In Chrome's experimentation phase, it will additionally require a valid origin trial token to exist in |initiatorWindow|'s associated document for the request to be eligible for topics. -

The \`Observe-Browsing-Topics\` HTTP response header

From 24c8ec49dae9513100d45d94643a464a64032c7a Mon Sep 17 00:00:00 2001 From: Yao Xiao Date: Tue, 14 Nov 2023 15:43:06 -0500 Subject: [PATCH 2/4] Revert unrelated change --- spec.bs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 6abfd6b..f2b1c81 100644 --- a/spec.bs +++ b/spec.bs @@ -466,7 +466,8 @@ spec: html; urlPrefix: https://www.rfc-editor.org/rfc/ 1. If options["{{BrowsingTopicsOptions/skipObservation}}"] is false: 1. Run the [=collect page topics calculation input data=] algorithm with |topLevelDocument| as input. 1. Run the [=collect topics caller domain=] algorithm with |topLevelDocument| and |topicsCallerContext|'s [=topics caller context/caller domain=] as input. - 1. [=Queue a global task=] on the [=browsing topics task source=] given |document|'s [=relevant global object=] to [=Resolve=] |promise| with |topics|. + 1. [=Queue a global task=] on the [=browsing topics task source=] given |document|'s [=relevant global object=] to perform the following steps: + 1. [=Resolve=] |promise| with |topics|. 1. Return |promise|. From 1391d36d39eab03ca180475d48175abc0150f44d Mon Sep 17 00:00:00 2001 From: Yao Xiao Date: Tue, 14 Nov 2023 15:58:52 -0500 Subject: [PATCH 3/4] Add double-check when handling the response --- spec.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec.bs b/spec.bs index f2b1c81..c48530c 100644 --- a/spec.bs +++ b/spec.bs @@ -639,10 +639,10 @@ spec: html; urlPrefix: https://www.rfc-editor.org/rfc/
To handle topics response, given a [=response=] |response| and a [=request=] request: - - 1. If |request|'s [=request/header list=] does not [=list/contain=] [:Sec-Browsing-Topics:] (implying the |request|'s [=request/current URL=] is not eligible for topics), then return. 1. Let |topLevelDocument| be |request|'s [=request/window=]'s [=environment settings object/global object=]'s [=Window/navigable=]'s [=navigable/top-level traversable=]'s [=navigable/active document=]. - 1. Let |callerDomain| be |request|'s [=request/current URL=]'s [=url/origin=]'s [=origin/host=]'s [=host/registrable domain=]. + 1. let |callerOrigin| be |request|'s [=request/current URL=]'s [=url/origin=]. + 1. If the user preference setting or other user agent-defined mechanisms like enrollment disallow access to topics from |topLevelDocument| given |callerOrigin|, then return. + 1. Let |callerDomain| be |callerOrigin|'s [=origin/host=]'s [=host/registrable domain=]. 1. Let |list| be |response|'s [=response/header list=]. 1. Let |observe| be the result of running [=get a structured field value=] algorithm given [:Observe-Browsing-Topics:], "item", and |list| as input. 1. If |observe| is true: From 1b1f933cbc816cd2c5b1a3d64a61a2e137bbafaa Mon Sep 17 00:00:00 2001 From: Yao Xiao Date: Tue, 14 Nov 2023 16:29:17 -0500 Subject: [PATCH 4/4] Add back the check for Sec-Browsing-Topics --- spec.bs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec.bs b/spec.bs index c48530c..bdfe099 100644 --- a/spec.bs +++ b/spec.bs @@ -639,9 +639,10 @@ spec: html; urlPrefix: https://www.rfc-editor.org/rfc/
To handle topics response, given a [=response=] |response| and a [=request=] request: + 1. If |request|'s [=request/header list=] does not [=list/contain=] [:Sec-Browsing-Topics:] (implying the |request|'s [=request/current URL=] is not eligible for topics), then return. 1. Let |topLevelDocument| be |request|'s [=request/window=]'s [=environment settings object/global object=]'s [=Window/navigable=]'s [=navigable/top-level traversable=]'s [=navigable/active document=]. - 1. let |callerOrigin| be |request|'s [=request/current URL=]'s [=url/origin=]. - 1. If the user preference setting or other user agent-defined mechanisms like enrollment disallow access to topics from |topLevelDocument| given |callerOrigin|, then return. + 1. Let |callerOrigin| be |request|'s [=request/current URL=]'s [=url/origin=]. + 1. If the user preference setting or other user agent-defined mechanisms like enrollment disallows access to topics from |topLevelDocument| given |callerOrigin|, then return. 1. Let |callerDomain| be |callerOrigin|'s [=origin/host=]'s [=host/registrable domain=]. 1. Let |list| be |response|'s [=response/header list=]. 1. Let |observe| be the result of running [=get a structured field value=] algorithm given [:Observe-Browsing-Topics:], "item", and |list| as input.