import IEvent from "../intefaces/IEvent"; import ATSEvent from "./ATSEvent"; // OAuth consent landing pages: the "Allow" / "Accept" element of the fake // app's access request. data-scopes lists what the app asked for, space // separated ("mail.read files.read"); it is sent as data.type. export const CONSENT_ATTRIBUTE = "data-ats-consent"; const findConsentElement = (event?: Event): HTMLElement | null => { if (!(event?.target instanceof Element)) { return null; } return event.target.closest(`[${CONSENT_ATTRIBUTE}]`); }; const scopesOf = (element: HTMLElement | null): string | null => { const scopes = (element?.getAttribute("data-scopes") || "").trim().split(/\s+/).filter(Boolean); return scopes.length ? scopes.join(" ") : null; }; export default class ConsentGranted extends ATSEvent implements IEvent { get trigger(): string { return "click"; } get source(): Window { return window; } get name(): string { return "consent_granted"; } get hasTypes(): boolean { return false; } get redirectOnFinish(): boolean { return true; } get isBlocking(): boolean { return true; } get allowMultiple(): boolean { return false; } isValid(event: Event): boolean { const element = findConsentElement(event); return !!element && this.basicValidation(element); } typeOf(event?: Event): string | null { // Triggered by the page itself there is no click: read the scopes off // the page's consent element. const element = findConsentElement(event) || document.querySelector(`[${CONSENT_ATTRIBUTE}]`); return scopesOf(element); } }