diff --git a/spec.bs b/spec.bs index 447ce12..9c13897 100644 --- a/spec.bs +++ b/spec.bs @@ -292,6 +292,17 @@ Note: A later algorithm [=asserts=] that, for any [=contribution cache entry=] before the [=process contributions for a batching scope=] steps are performed given the entry's [=contribution cache entry/batching scope=]. +APIs exposing Private Aggregation {#apis-exposing-private-aggregation} +---------------------------------------------------------------------- + +This section is non-normative. + +This API is currently exposed in global scopes defined in the specifications of +two APIs: +1. Shared Storage and +1. Protected Audience (via the + monkey patches below). + Structures {#structures} ======================== @@ -1185,269 +1196,6 @@ Note: Without this, [=aggregatable reports=] would be subject to delays, making -Shared Storage API monkey patches {#shared-storage-api-monkey-patches} -====================================================================== - -Issue(43): This should be moved to the Shared Storage spec. - -Issue: Go through all monkey patches and ensure every definition (including) - structures that is needed is exported. - - -partial interface SharedStorageWorkletGlobalScope { - readonly attribute PrivateAggregation privateAggregation; -}; - -dictionary SharedStoragePrivateAggregationConfig { - USVString aggregationCoordinatorOrigin; - USVString contextId; - [EnforceRange] unsigned long long filteringIdMaxBytes; -}; - -partial dictionary SharedStorageRunOperationMethodOptions { - SharedStoragePrivateAggregationConfig privateAggregationConfig; -}; - - -The {{SharedStorageWorkletGlobalScope/privateAggregation}} [=getter steps=] are -to [=get the privateAggregation=] given [=this=]. - -Add the following algorithm in the subsection -"Run -Operation Methods on `SharedStorage`": - -
-To obtain the aggregation coordinator given a -{{SharedStorageRunOperationMethodOptions}} |options|, perform the following -steps. They return an [=aggregation coordinator=], null or a {{DOMException}}: - -1. If - |options|["{{SharedStorageRunOperationMethodOptions/privateAggregationConfig}}"] - does not [=map/exist=], return null. -1. If - |options|["{{SharedStorageRunOperationMethodOptions/privateAggregationConfig}}"]["{{SharedStoragePrivateAggregationConfig/aggregationCoordinatorOrigin}}"] - does not [=map/exist=], return null. -1. Let |url| be the result of running the [=URL parser=] on - |options|["{{SharedStorageRunOperationMethodOptions/privateAggregationConfig}}"]["{{SharedStoragePrivateAggregationConfig/aggregationCoordinatorOrigin}}"]. -1. If |url| is failure or null, return a new {{DOMException}} with name - "`SyntaxError`". - - Issue: Consider throwing an error if the path is not empty. -1. Let |origin| be |url|'s [=url/origin=]. -1. If the result of [=determining if an origin is an aggregation coordinator=] - given |origin| is false, return a new {{DOMException}} with name - "`DataError`". -1. Return |origin|. - -
- -
-To obtain the pre-specified report parameters given a -{{SharedStorageRunOperationMethodOptions}} |options| and a [=browsing context=] -|context|, perform the following steps. They return a [=pre-specified report -parameters=], null, or a {{DOMException}}: -1. If |options|["{{SharedStorageRunOperationMethodOptions/privateAggregationConfig}}"] - does not [=map/exist=], return null. -1. Let |privateAggregationConfig| be - |options|["{{SharedStorageRunOperationMethodOptions/privateAggregationConfig}}"]. -1. Let |contextId| be null. -1. If |privateAggregationConfig|["{{SharedStoragePrivateAggregationConfig/contextId}}"] - [=map/exists=], set |contextId| to - |privateAggregationConfig|["{{SharedStoragePrivateAggregationConfig/contextId}}"]. -1. If |contextId|'s [=string/length=] is greater than 64, return a new - {{DOMException}} with name "`DataError`". -1. Let |filteringIdMaxBytes| be the [=default filtering ID max bytes=]. -1. If |privateAggregationConfig|["{{SharedStoragePrivateAggregationConfig/filteringIdMaxBytes}}"] - [=map/exists=], set |filteringIdMaxBytes| to - |privateAggregationConfig|["{{SharedStoragePrivateAggregationConfig/filteringIdMaxBytes}}"]. -1. If |filteringIdMaxBytes| is not [=set/contained=] in the [=valid filtering ID - max bytes range=], return a new {{DOMException}} with name "`DataError`". -1. If |context|'s [=browsing context/fenced frame config instance=] is not null: - 1. If |filteringIdMaxBytes| is not the [=default filtering ID max bytes=] or - |contextId| is not null, return a new {{DOMException}} with name - "`DataError`". -1. Return a new [=pre-specified report parameters=] with the items: - : [=pre-specified report parameters/context ID=] - :: |contextId| - : [=pre-specified report parameters/filtering ID max bytes=] - :: |filteringIdMaxBytes| - -
- -The {{SharedStorageWorklet}}'s {{SharedStorageWorklet/run()}} method steps are -modified in four ways. First, add the following steps just after step 4 -("[=Assert=]: window is a [=Window=]"), renumbering later -steps as appropriate: -
-5. Let |context| be window's [=Window/browsing context=]. -1. If |context| is null, then return [=a promise rejected with=] a - {{TypeError}}. -1. Let |preSpecifiedParams| be the result of [=obtaining the pre-specified - report parameters=] given |options| and |context|. -1. If |preSpecifiedParams| is a {{DOMException}}, return [=a promise rejected - with=] |preSpecifiedParams|. -1. Let |aggregationCoordinator| be the result of [=obtaining the aggregation - coordinator=] given |options|. -1. If |aggregationCoordinator| is a {{DOMException}}, return [=a promise - rejected with=] |aggregationCoordinator|. - -
-Second, add the following steps in the nested scope just after "Let |operation| -be |operationMap|[|name|]." (renumbering later steps as appropriate): -
-2. Let |batchingScope| be a new [=batching scope=]. -1. Let debugScope be a new [=debug scope=]. -1. Let |privateAggregationTimeout| be null. -1. Let |isDeterministicReport| be false. -1. If |preSpecifiedParams| is not null: - 1. Set |isDeterministicReport| to the result of [=determining if a report - should be sent deterministically=] given |preSpecifiedParams|. - 1. If |isDeterministicReport|: - 1. Set |privateAggregationTimeout| to the [=current wall time=] plus the - [=deterministic operation timeout duration=]. - 1. [=Set the pre-specified report parameters for a batching scope=] given - |preSpecifiedParams| and |batchingScope|. -1. If |aggregationCoordinator| is not null, [=set the aggregation coordinator - for a batching scope=] given |aggregationCoordinator| and |batchingScope|. - -
- -Third, add the following steps in the same nested scope just before the current -penultimate step ("If options -[=map/contains=] data", renumbering the last step as -appropriate): -
-1. Let |hasRunPrivateAggregationCompletionTask| be false. -1. Let |privateAggregationCompletionTask| be an algorithm to perform the - following steps: - 1. If |hasRunPrivateAggregationCompletionTask|, return. - 1. Set |hasRunPrivateAggregationCompletionTask| to true. - 1. [=Mark a debug scope complete=] given debugScope. - 1. [=Process contributions for a batching scope=] given - batchingScope, outsideSettings' - [=environment settings object/origin=], "shared-storage" - and |privateAggregationTimeout|. -1. If isDeterministicReport>, run the following steps [=in - parallel=]: - 1. Wait until |privateAggregationTimeout|. - 1. Run |privateAggregationCompletionTask|. - -
- -Finally, at the end of the same nested scope, add the following step: -
-9. When the above [=call=] returns, perform the following steps: - 1. Run privateAggregationCompletionTask. - -
- -The {{SharedStorageWorklet}}'s {{SharedStorageWorklet/selectURL()}} method steps -are modified in three ways. First, add the following steps just after step 6 -("If context is null..."), renumbering later steps: -
-7. Let |preSpecifiedParams| be the result of [=obtaining the pre-specified - report parameters=] given |options| and context. -1. If |preSpecifiedParams| is a {{DOMException}}, return [=a promise rejected - with=] |preSpecifiedParams|. -1. Let |aggregationCoordinator| be the result of [=obtaining the aggregation - coordinator=] given |options|. -1. If |aggregationCoordinator| is a {{DOMException}}, return [=a promise - rejected with=] |aggregationCoordinator|. - -
-Second, add the following steps in the nested scope just after "Let |operation| -be |operationMap|[|name|]." (renumbering later steps as appropriate): -
-2. Let |batchingScope| be a new [=batching scope=]. -1. Let |debugScope| be a new [=debug scope=]. -1. Let |privateAggregationTimeout| be null. -1. Let |hasRunPrivateAggregationCompletionTask| be false. -1. Let |privateAggregationCompletionTask| be an algorithm to perform the - following steps: - 1. If |hasRunPrivateAggregationCompletionTask|, return. - 1. Set |hasRunPrivateAggregationCompletionTask| to true. - 1. [=Mark a debug scope complete=] given |debugScope|. - 1. [=Process contributions for a batching scope=] given - |batchingScope|, outsideSettings' - [=environment settings object/origin=], "shared-storage" - and |privateAggregationTimeout|. -1. If |aggregationCoordinator| is not null, [=set the aggregation coordinator - for a batching scope=] given |aggregationCoordinator| and |batchingScope|. -1. If |preSpecifiedParams| is not null: - 1. Let |isDeterministicReport| be the result of [=determining if a report - should be sent deterministically=] given |preSpecifiedParams|. - 1. If |isDeterministicReport|: - 1. Set |privateAggregationTimeout| to the [=current wall time=] plus the - [=deterministic operation timeout duration=]. - 1. [=Set the pre-specified report parameters for a batching scope=] given - |preSpecifiedParams| and |batchingScope|. - 1. If |isDeterministicReport|, run the following steps [=in parallel=]: - 1. Wait until |privateAggregationTimeout|. - 1. Run |privateAggregationCompletionTask|. - -
-Finally, at the end of the same nested scope, add the following steps: -
-13. Run privateAggregationCompletionTask. - -
- -Issue: Once - shared-storage/88 is resolved, align the above monkey patches with how - `keepAlive` is handled at operation completion. - -The {{Worklet/addModule()}} steps are modified to add a new step just before -the final step ("Return promise."), renumbering the last step -as appropriate: -
-7. If |this| is a {{SharedStorageWorklet}}, [=upon fulfillment=] of |promise| or - [=upon rejection=] of |promise|, run the following steps: - 1. Let |globalScopes| be |this|'s [=Worklet/global scopes=]. - 1. [=Assert=]: |globalScopes|' [=list/size=] equals 1. - 1. Let |privateAggregationObj| be |globalScopes|[0]'s - {{SharedStorageWorkletGlobalScope/privateAggregation}}. - 1. Set |privateAggregationObj|'s [=PrivateAggregation/allowed to use=] to - the result of determining whether [=this=]'s [=relevant global - object=]'s [=associated document=] is [=allowed to use=] the - "[=private-aggregation=]" [=policy-controlled feature=]. - - Issue: Consider adding an early return here (and equivalently for - Protected Audience) if the permissions policy check is made first. - 1. Set |privateAggregationObj|'s [=PrivateAggregation/scoping details=] to a - new [=scoping details=] with the items: - : [=scoping details/get batching scope steps=] - :: An algorithm that returns the [=batching scope=] that is scheduled to - be passed to [=process contributions for a batching scope=] when the - call currently executing in |scope| returns. - : [=scoping details/get debug scope steps=] - :: An algorithm that returns the [=debug scope=] that is scheduled to be - passed to [=mark a debug scope complete=] when the call currently - executing in |scope| returns. - - Note: Multiple operation invocations can be in-progress at the same - time, each with a different batching scope and debug scope. However, - only one can be currently executing. - -
- -Issue: Once - shared-storage/89 is resolved, align the above monkey patch with how - access to `sharedStorage` is prevented in - {{SharedStorageWorkletGlobalScope}}s until {{Worklet/addModule()}}'s initial - execution is complete. - -Note: This extends Shared Storage's existing {{Worklet/addModule()}} - - monkey patch. - -[=Implementation-defined=] values {#shared-storage-implementation-defined-values} ---------------------------------------------------------------------------------- - -Deterministic operation timeout duration is a non-negative -[=duration=] that controls how long a Shared Storage operation may make Private -Aggregation contributions if it is triggering a deterministic report and, -equivalently, when that report should be sent after the operation begins. - Protected Audience API monkey patches {#protected-audience-api-monkey-patches} ==============================================================================