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        // Step 4. If document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.
58        if !document.is_fully_active() {
59            promise.reject_error_with_cx(cx, Error::InvalidState(None));
60            return Ok(promise);
61        }
62        // Step 5. If options.signal is aborted, then return a promise rejected with options.signal’s abort reason.
63        if options.signal.as_ref().is_some_and(|s| s.aborted()) {
64            promise.reject_error_with_cx(cx, Error::Abort(None));
65            return Ok(promise);
66        }
67        promise.reject_error_with_cx(cx, Error::NotSupported(None));
68        Ok(promise)
69    }
70
71    /// <https://www.w3.org/TR/credential-management-1/#abstract-opdef-store-a-credential>
72    fn store_credential(
73        &self,
74        cx: &mut CurrentRealm,
75        _credential: &Credential,
76    ) -> Fallible<Rc<Promise>> {
77        // Step 1. Let settings be the current settings object.
78        let global = GlobalScope::from_current_realm(cx);
79        // Step 2. Assert: settings is a secure context.
80        assert!(global.is_secure_context());
81
82        let promise = Promise::new_in_realm(cx);
83        // Step 3. If settings’s relevant global object's associated Document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.
84        if !global.as_window().Document().is_fully_active() {
85            promise.reject_error_with_cx(cx, Error::InvalidState(None));
86            return Ok(promise);
87        }
88        promise.reject_error_with_cx(cx, Error::NotSupported(None));
89        Ok(promise)
90    }
91
92    /// <https://www.w3.org/TR/credential-management-1/#abstract-opdef-create-a-credential>
93    fn create_credential(
94        &self,
95        cx: &mut CurrentRealm,
96        _options: &CredentialCreationOptions<DomTypeHolder>,
97    ) -> Fallible<Rc<Promise>> {
98        // Step 1. Let settings be the current settings object.
99        let global = GlobalScope::from_current_realm(cx);
100        // Step 2. Assert: settings is a secure context.
101        assert!(global.is_secure_context());
102        // Step 3. Let global be settings’ global object.
103        // Step 4. Let document be the relevant global object’s associated Document.
104        let document = global.as_window().Document();
105
106        let promise = Promise::new_in_realm(cx);
107        // Step 5. If document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.
108        if !document.is_fully_active() {
109            promise.reject_error_with_cx(cx, Error::InvalidState(None));
110            return Ok(promise);
111        }
112        promise.reject_error_with_cx(cx, Error::NotSupported(None));
113        Ok(promise)
114    }
115}
116
117impl CredentialsContainerMethods<DomTypeHolder> for CredentialsContainer {
118    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-get>
119    fn Get(
120        &self,
121        cx: &mut CurrentRealm,
122        options: &CredentialRequestOptions<DomTypeHolder>,
123    ) -> Fallible<Rc<Promise>> {
124        self.request_credential(cx, options)
125    }
126
127    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-store>
128    fn Store(&self, cx: &mut CurrentRealm, credential: &Credential) -> Fallible<Rc<Promise>> {
129        self.store_credential(cx, credential)
130    }
131
132    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-create>
133    fn Create(
134        &self,
135        cx: &mut CurrentRealm,
136        options: &CredentialCreationOptions<DomTypeHolder>,
137    ) -> Fallible<Rc<Promise>> {
138        self.create_credential(cx, options)
139    }
140
141    /// <https://www.w3.org/TR/credential-management-1/#dom-credentialscontainer-preventsilentaccess>
142    fn PreventSilentAccess(&self, cx: &mut CurrentRealm) -> Fallible<Rc<Promise>> {
143        let promise = Promise::new_in_realm(cx);
144        promise.reject_error_with_cx(cx, Error::NotSupported(None));
145        Ok(promise)
146    }
147}