blob: adc37eae529b09e0e1b890ec2cc48bd67d1e5e1e [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/storage_access/document_storage_access.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_storage_access_types.h"
#include "third_party/blink/renderer/modules/storage_access/storage_access_handle.h"
namespace blink {
namespace {
class RequestExtendedStorageAccess final : public ScriptFunction::Callable {
public:
RequestExtendedStorageAccess(
LocalDOMWindow& window,
const StorageAccessTypes* storage_access_types,
ScriptPromiseResolverTyped<StorageAccessHandle>* resolver)
: window_(&window),
storage_access_types_(storage_access_types),
resolver_(resolver) {}
ScriptValue Call(ScriptState* script_state, ScriptValue) override {
resolver_->Resolve(MakeGarbageCollected<StorageAccessHandle>(
*window_, storage_access_types_));
return ScriptValue();
}
void Trace(Visitor* visitor) const override {
visitor->Trace(window_);
visitor->Trace(storage_access_types_);
visitor->Trace(resolver_);
ScriptFunction::Callable::Trace(visitor);
}
private:
Member<LocalDOMWindow> window_;
Member<const StorageAccessTypes> storage_access_types_;
Member<ScriptPromiseResolverTyped<StorageAccessHandle>> resolver_;
};
} // namespace
// static
const char DocumentStorageAccess::kNoAccessRequested[] =
"You must request access for at least one storage/communication medium.";
// static
const char DocumentStorageAccess::kSupplementName[] = "DocumentStorageAccess";
// static
DocumentStorageAccess& DocumentStorageAccess::From(Document& document) {
DocumentStorageAccess* supplement =
Supplement<Document>::From<DocumentStorageAccess>(document);
if (!supplement) {
supplement = MakeGarbageCollected<DocumentStorageAccess>(document);
ProvideTo(document, supplement);
}
return *supplement;
}
// static
ScriptPromiseTyped<StorageAccessHandle>
DocumentStorageAccess::requestStorageAccess(
ScriptState* script_state,
Document& document,
const StorageAccessTypes* storage_access_types) {
return From(document).requestStorageAccess(script_state,
storage_access_types);
}
// static
ScriptPromiseTyped<IDLBoolean>
DocumentStorageAccess::hasUnpartitionedCookieAccess(ScriptState* script_state,
Document& document) {
return From(document).hasUnpartitionedCookieAccess(script_state);
}
DocumentStorageAccess::DocumentStorageAccess(Document& document)
: Supplement<Document>(document) {}
void DocumentStorageAccess::Trace(Visitor* visitor) const {
Supplement<Document>::Trace(visitor);
}
ScriptPromiseTyped<StorageAccessHandle>
DocumentStorageAccess::requestStorageAccess(
ScriptState* script_state,
const StorageAccessTypes* storage_access_types) {
if (!storage_access_types->all() && !storage_access_types->cookies() &&
!storage_access_types->sessionStorage() &&
!storage_access_types->localStorage() &&
!storage_access_types->indexedDB() && !storage_access_types->locks() &&
!storage_access_types->caches() &&
!storage_access_types->getDirectory() &&
!storage_access_types->estimate() &&
!storage_access_types->createObjectURL() &&
!storage_access_types->revokeObjectURL() &&
!storage_access_types->broadcastChannel() &&
!storage_access_types->sharedWorker()) {
return ScriptPromiseTyped<StorageAccessHandle>::RejectWithDOMException(
script_state, MakeGarbageCollected<DOMException>(
DOMExceptionCode::kSecurityError,
DocumentStorageAccess::kNoAccessRequested));
}
auto* resolver =
MakeGarbageCollected<ScriptPromiseResolverTyped<StorageAccessHandle>>(
script_state);
auto promise = resolver->Promise();
GetSupplementable()
->RequestStorageAccessImpl(
script_state,
storage_access_types->all() || storage_access_types->cookies())
.Then(MakeGarbageCollected<ScriptFunction>(
script_state, MakeGarbageCollected<RequestExtendedStorageAccess>(
*GetSupplementable()->domWindow(),
storage_access_types, resolver)));
return promise;
}
ScriptPromiseTyped<IDLBoolean>
DocumentStorageAccess::hasUnpartitionedCookieAccess(ScriptState* script_state) {
return GetSupplementable()->hasStorageAccess(script_state);
}
} // namespace blink