glass/browser/session/
consent.rs1use super::*;
4
5#[derive(Debug, Clone, Copy, Serialize)]
7#[serde(rename_all = "snake_case")]
8pub enum ConsentDismissalOutcome {
9 Dismissed,
10 NoConsentFound,
11 UnrecognizedFramework,
12}
13
14const CONSENT_DISMISS_FUNCTION: &str = r#"function() {
15 const visible = (el) => {
16 if (!el) return false;
17 const style = getComputedStyle(el);
18 const rect = el.getBoundingClientRect();
19 return style.display !== 'none' && style.visibility !== 'hidden' &&
20 Number(style.opacity) !== 0 && rect.width > 0 && rect.height > 0;
21 };
22 const click = (root, selectors) => {
23 for (const selector of selectors) {
24 const el = root.querySelector(selector);
25 if (visible(el)) { el.click(); return true; }
26 }
27 return false;
28 };
29 const oneTrust = document.querySelector('#onetrust-banner-sdk, #onetrust-consent-sdk, .onetrust-pc-dark-filter');
30 if (oneTrust) {
31 return JSON.stringify({framework:'onetrust', dismissed: click(document, [
32 '#onetrust-accept-btn-handler', '#onetrust-reject-all-handler'
33 ])});
34 }
35 const cookiebot = document.querySelector('#CybotCookiebotDialog, [data-template="cookiebot"]');
36 if (cookiebot) {
37 return JSON.stringify({framework:'cookiebot', dismissed: click(cookiebot, [
38 '#CybotCookiebotDialogBodyLevelButtonAccept', '#CybotCookiebotDialogBodyButtonDecline'
39 ])});
40 }
41 return JSON.stringify({framework:null, dismissed:false});
42}"#;
43
44impl BrowserSession {
45 pub async fn dismiss_consent(&self) -> BrowserResult<ConsentDismissalOutcome> {
49 self.policy.require(PolicyCapability::ConsentDismissal)?;
50 let raw = self.evaluate_value(CONSENT_DISMISS_FUNCTION).await?;
51 let value = raw.as_str().unwrap_or_default();
52 let parsed: Value = serde_json::from_str(value).unwrap_or_default();
53 let outcome = match (
54 parsed["framework"].as_str(),
55 parsed["dismissed"].as_bool().unwrap_or(false),
56 ) {
57 (_, true) => ConsentDismissalOutcome::Dismissed,
58 (Some("onetrust" | "cookiebot"), false) => {
59 ConsentDismissalOutcome::UnrecognizedFramework
60 }
61 (None, false) => ConsentDismissalOutcome::NoConsentFound,
62 _ => ConsentDismissalOutcome::UnrecognizedFramework,
63 };
64 if matches!(outcome, ConsentDismissalOutcome::Dismissed) {
65 self.invalidate_observation();
66 self.record_audit("dismiss_consent", "recognized_framework");
67 }
68 Ok(outcome)
69 }
70}