<commit_before>/**
 * Cross Window Messaging
 *
 * Adhocracy -- or parts of it -- can be embedded as iframes.  The iframe provides
 * sufficient isolation to separate our own DOM, JavaScript and CSS from that of the
 * embedder page.
 *
 * Still it is required to be able to communicate between the embedder and the embedde.
 * On the embedee site, this is handled by this module.  On the embedder site it is most
 * likely handled by AdhocracySDK.
 *
 * Messages sent between the two are always of type IMessage.  Currentently the following
 * messages exists:
 *
 * name: "resize"  // from SDK to iframes
 * data: {
 *   height: number
 * }
 *
 * name: "requestSetup"  // from SDK to iframes
 * data: {}
 *
 * name: "setup"  // sent from SDK to iframes
 * data: {
 *   embedderOrigin: string
 * }
 *
 * Message handler callbacks for to-iframes messages are registered by
 * the service factory.
 *
 * Messages are serialized with JSON.stringify before being sent via
 * window.postMessage().  (Reason: browser compatibility; IE prior to
 * 10 in particular, but others may be affected.)
 */

import _ = require("lodash");

import AdhConfig = require("../Config/Config");
import AdhCredentials = require("../User/Credentials");
import AdhUser = require("../User/User");


export interface IMessage {
    data : IMessageData;
    name : string;
}

export interface IMessageData {
    embedderOrigin? : string;
}

export interface IPostMessageService {
    (data : string, origin : string) : void;
}

export interface IService {
    registerMessageHandler : (name : string, callback : (IMessageData) => void) => void;
    postResize : (height : number) => void;
    dummy? : boolean;
}


export class Service implements IService {

    private embedderOrigin : string = "*";

    /**
     * Injection of the User service is only required if login information shall be
     * passed to the embedding website. In that case trustedDomains must be set.
     */
    constructor(
        private _postMessage : IPostMessageService,
        private $location : angular.ILocationService,
        private $window : Window,
        private $rootScope,
        private trustedDomains : string[],
        private adhCredentials? : AdhCredentials.Service,
        private adhUser? : AdhUser.Service
    ) {
        var _self : Service = this;

        _self.registerMessageHandler("setup", _self.setup.bind(_self));
        _self.manageResize();

        _self.postMessage("requestSetup", {});
    }

    public registerMessageHandler(name, callback) {
        var _self : Service = this;

        _self.$window.addEventListener("message", (event) => {
            var message = JSON.parse(event.data);

            if (((message.name === "setup") || (event.origin === _self.embedderOrigin)) && (message.name === name)) {
                callback(message.data);
            }
        });
    }

    private postMessage(name: string, data: IMessageData) : void {
        var _self : Service = this;

        var message : IMessage = {
            name: name,
            data: data
        };

        _self._postMessage(JSON.stringify(message), _self.embedderOrigin);
    }

    public postResize(height) {
        var _self : Service = this;

        _self.postMessage(
            "resize",
            {height: height}
        );
    }

    private sendAuthMessages() {
        var _self : Service = this;

        return typeof _self.adhUser !== "undefined" && _.contains(_self.trustedDomains, _self.embedderOrigin);
    }

    private sendLoginState(loggedIn) {
        var _self : Service = this;

        if (_self.sendAuthMessages()) {
            // the case (loggedIn === undefined) doesn't trigger a message
            if (loggedIn === true) {
                _self.postMessage("login", {
                    token: _self.adhCredentials.token,
                    userPath: _self.adhCredentials.userPath,
                    userData: _self.adhUser.data
                });
            } else if (loggedIn === false) {
                _self.postMessage("logout", {});
            }
        }
    }

    private setup(data: IMessageData) : void {
        var _self : Service = this;

        if (_self.embedderOrigin === "*") {
            _self.embedderOrigin = data.embedderOrigin;

            _self.$rootScope.$watch(() => _self.adhCredentials.loggedIn, (loggedIn) => _self.sendLoginState(loggedIn));

            _self.$rootScope.$watch(() => _self.$location.absUrl(), (absUrl) => {
                _self.postMessage(
                    "urlchange",
                    {url: absUrl}
                );
            });
        }
    }

    /**
     * Body does not trigger resize events. So we have to guess when its height
     * has changed ourselves.
     *
     * The following options come to mind:
     *
     * 1. polling (check for changes on regular intervals using $interval)
     * 2. angular's $watch
     * 3. triggering a resize manually whenever we change something
     * 4. CSS hack: https://marcj.github.io/css-element-queries/
     *
     * This function uses 2. in combination with the window resize event to
     * also catch changes triggered by the embedder.
     */
    private manageResize() : void {
        var _self : Service = this;

        var getHeight = () : number => _self.$window.document.body.clientHeight;
<commit_msg>do not use adhCredentials in untrusted corssWindowMessaging<commit_after>/**
 * Cross Window Messaging
 *
 * Adhocracy -- or parts of it -- can be embedded as iframes.  The iframe provides
 * sufficient isolation to separate our own DOM, JavaScript and CSS from that of the
 * embedder page.
 *
 * Still it is required to be able to communicate between the embedder and the embedde.
 * On the embedee site, this is handled by this module.  On the embedder site it is most
 * likely handled by AdhocracySDK.
 *
 * Messages sent between the two are always of type IMessage.  Currentently the following
 * messages exists:
 *
 * name: "resize"  // from SDK to iframes
 * data: {
 *   height: number
 * }
 *
 * name: "requestSetup"  // from SDK to iframes
 * data: {}
 *
 * name: "setup"  // sent from SDK to iframes
 * data: {
 *   embedderOrigin: string
 * }
 *
 * Message handler callbacks for to-iframes messages are registered by
 * the service factory.
 *
 * Messages are serialized with JSON.stringify before being sent via
 * window.postMessage().  (Reason: browser compatibility; IE prior to
 * 10 in particular, but others may be affected.)
 */

import _ = require("lodash");

import AdhConfig = require("../Config/Config");
import AdhCredentials = require("../User/Credentials");
import AdhUser = require("../User/User");


export interface IMessage {
    data : IMessageData;
    name : string;
}

export interface IMessageData {
    embedderOrigin? : string;
}

export interface IPostMessageService {
    (data : string, origin : string) : void;
}

export interface IService {
    registerMessageHandler : (name : string, callback : (IMessageData) => void) => void;
    postResize : (height : number) => void;
    dummy? : boolean;
}


export class Service implements IService {

    private embedderOrigin : string = "*";

    /**
     * Injection of the User service is only required if login information shall be
     * passed to the embedding website. In that case trustedDomains must be set.
     */
    constructor(
        private _postMessage : IPostMessageService,
        private $location : angular.ILocationService,
        private $window : Window,
        private $rootScope,
        private trustedDomains : string[],
        private adhCredentials? : AdhCredentials.Service,
        private adhUser? : AdhUser.Service
    ) {
        var _self : Service = this;

        _self.registerMessageHandler("setup", _self.setup.bind(_self));
        _self.manageResize();

        _self.postMessage("requestSetup", {});
    }

    public registerMessageHandler(name, callback) {
        var _self : Service = this;

        _self.$window.addEventListener("message", (event) => {
            var message = JSON.parse(event.data);

            if (((message.name === "setup") || (event.origin === _self.embedderOrigin)) && (message.name === name)) {
                callback(message.data);
            }
        });
    }

    private postMessage(name: string, data: IMessageData) : void {
        var _self : Service = this;

        var message : IMessage = {
            name: name,
            data: data
        };

        _self._postMessage(JSON.stringify(message), _self.embedderOrigin);
    }

    public postResize(height) {
        var _self : Service = this;

        _self.postMessage(
            "resize",
            {height: height}
        );
    }

    private sendAuthMessages() {
        var _self : Service = this;

        return typeof _self.adhUser !== "undefined" && _.contains(_self.trustedDomains, _self.embedderOrigin);
    }

    private sendLoginState(loggedIn) {
        var _self : Service = this;

        if (_self.sendAuthMessages()) {
            // the case (loggedIn === undefined) doesn't trigger a message
            if (loggedIn === true) {
                _self.postMessage("login", {
                    token: _self.adhCredentials.token,
                    userPath: _self.adhCredentials.userPath,
                    userData: _self.adhUser.data
                });
            } else if (loggedIn === false) {
                _self.postMessage("logout", {});
            }
        }
    }

    private setup(data: IMessageData) : void {
        var _self : Service = this;

        if (_self.embedderOrigin === "*") {
            _self.embedderOrigin = data.embedderOrigin;

            if (typeof _self.adhCredentials !== "undefined") {
                _self.$rootScope.$watch(() => _self.adhCredentials.loggedIn, (loggedIn) => _self.sendLoginState(loggedIn));
            }

            _self.$rootScope.$watch(() => _self.$location.absUrl(), (absUrl) => {
                _self.postMessage(
                    "urlchange",
                    {url: absUrl}
                );
            });
        }
    }

    /**
     * Body does not trigger resize events. So we have to guess when its height
     * has changed ourselves.
     *
     * The following options come to mind:
     *
     * 1. polling (check for changes on regular intervals using $interval)
     * 2. angular's $watch
     * 3. triggering a resize manually whenever we change something
     * 4. CSS hack: https://marcj.github.io/css-element-queries/
     *
     * This function uses 2. in combination with the window resize event to
     * also catch changes triggered by the embedder.
     */
    private manageResize() : void {
        var _self : Service = this;

        var getHeight = () : number => _self.$window.document.body.clientHeight;

{'fraction_non_alphanumeric': 0.10714615029967726, 'fraction_numerical': 0.0012909174734900876, 'mean_word_length': 2.2936532037655635, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4946006', 'n_tokens_mistral': 3021, 'n_tokens_neox': 2919, 'n_words': 908}