Skip to main content

script/dom/credentialmanagement/
credentialscontainer.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4use std::rc::Rc;
5
6use dom_struct::dom_struct;
7use js::realm::CurrentRealm;
8use script_bindings::codegen::GenericBindings::CredentialsContainerBinding::{
9    CredentialCreationOptions, CredentialRequestOptions,
10};
11use script_bindings::codegen::GenericBindings::WindowBinding::WindowMethods;
12use script_bindings::error::{Error, Fallible};
13use script_bindings::reflector::{Reflector, reflect_dom_object};
14
15use crate::dom::bindings::codegen::Bindings::CredentialsContainerBinding::CredentialsContainerMethods;
16use crate::dom::bindings::codegen::DomTypeHolder::DomTypeHolder;
17use crate::dom::bindings::root::DomRoot;
18use crate::dom::credentialmanagement::credential::Credential;
19use crate::dom::globalscope::GlobalScope;
20use crate::dom::promise::Promise;
21use crate::script_runtime::CanGc;
22
23#[dom_struct]
24pub(crate) struct CredentialsContainer {
25    reflector_: Reflector,
26}
27
28impl CredentialsContainer {
29    pub(crate) fn new_inherited() -> CredentialsContainer {
30        CredentialsContainer {
31            reflector_: Reflector::new(),
32        }
33    }
34
35    pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<CredentialsContainer> {
36        reflect_dom_object(
37            Box::new(CredentialsContainer::new_inherited()),
38            global,
39            can_gc,
40        )
41    }
42
43    /// <https://www.w3.org/TR/credential-management-1/#abstract-opdef-request-a-credential>
44    fn request_credential(
45        &self,
46        cx: &mut CurrentRealm,
47        options: &CredentialRequestOptions<DomTypeHolder>,
48    ) -> Fallible<Rc<Promise>> {
49        // Step 1. Let settings be the current settings object.
50        let global = GlobalScope::from_current_realm(cx);
51        // Step 2. Assert: settings is a secure context.
52        assert!(global.is_secure_context());
53        // Step 3. Let document be settings’s relevant global object's associated Document.
54        let document = global.as_window().Document();
55
56        let promise = Promise::new_in_realm(cx);
57        let can_gc = CanGc::from_cx(cx);
58        // Step 4. If document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.
59        if !document.is_fully_active() {
60            promise.reject_error(Error::InvalidState(None), can_gc);
61            return Ok(promise);
62        }
63        // Step 5. If options.signal is aborted, then return a promise rejected with options.signal’s abort reason.
64        if options.signal.as_ref().is_some_and(|s| s.aborted()) {
65            promise.reject_error(Error::Abort(None), can_gc);
66            return Ok(promise);
67        }
68        promise.reject_error(Error::NotSupported(None), can_gc);
69        Ok(promise)
70    }
71
72    /// <https://www.w3.org/TR/credential-management-1/#abstract-opdef-store-a-credential>
73    fn store_credential(
74        &self,
75        cx: &mut CurrentRealm,
76        _credential: &Credential,
77    ) -> Fallible<Rc<Promise>> {
78        // Step 1. Let settings be the current settings object.
79        let global = GlobalScope::from_current_realm(cx);
80        // Step 2. Assert: settings is a secure context.
81        assert!(global.is_secure_context());
82
83        let promise = Promise::new_in_realm(cx);
84        let can_gc = CanGc::from_cx(cx);
85        // Step 3. If settings’s relevant global object's associated Document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.
86        if !global.as_window().Document().is_fully_active() {
87            promise.reject_error(Error::InvalidState(None), can_gc);
88            return Ok(promise);
89        }
90        promise.reject_error(Error::NotSupported(None), can_gc);
91        Ok(promise)
92    }
93
94    /// <https://www.w3.org/TR/credential-management-1/#abstract-opdef-create-a-credential>
95    fn create_credential(
96        &self,
97        cx: &mut CurrentRealm,
98        _options: &CredentialCreationOptions<DomTypeHolder>,
99    ) -> Fallible<Rc<Promise>> {
100        // Step 1. Let settings be the current settings object.
101        let global = GlobalScope::from_current_realm(cx);
102        // Step 2. Assert: settings is a secure context.
103        assert!(global.is_secure_context());
104        // Step 3. Let global be settings’ global object.
105        // Step 4. Let document be the relevant global object’s associated Document.
106        let document = global.as_window().Document();
107
108        let promise = Promise::new_in_realm(cx);
109        let can_gc = CanGc::from_cx(cx);
110        // Step 5. If document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.
111        if !document.is_fully_active() {
112            promise.reject_error(Error::InvalidState(None), can_gc);
113            return Ok(promise);
114        }
115        promise.reject_error(Error::NotSupported(None), can_gc);
116        Ok(promise)
117    }
118}
119
120impl CredentialsContainerMethods<DomTypeHolder> for CredentialsContainer {
121    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-get>
122    fn Get(
123        &self,
124        cx: &mut CurrentRealm,
125        options: &CredentialRequestOptions<DomTypeHolder>,
126    ) -> Fallible<Rc<Promise>> {
127        self.request_credential(cx, options)
128    }
129
130    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-store>
131    fn Store(&self, cx: &mut CurrentRealm, credential: &Credential) -> Fallible<Rc<Promise>> {
132        self.store_credential(cx, credential)
133    }
134
135    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-create>
136    fn Create(
137        &self,
138        cx: &mut CurrentRealm,
139        options: &CredentialCreationOptions<DomTypeHolder>,
140    ) -> Fallible<Rc<Promise>> {
141        self.create_credential(cx, options)
142    }
143
144    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-preventsilentaccess>
145    fn PreventSilentAccess(&self, cx: &mut CurrentRealm) -> Fallible<Rc<Promise>> {
146        let promise = Promise::new_in_realm(cx);
147        promise.reject_error(Error::NotSupported(None), CanGc::from_cx(cx));
148        Ok(promise)
149    }
150}