1

Using Sitecore 9.1.1 I need to customise the beaconAPI to better handle the tracking of page visits with an external site with an encoded url (as it's currently triggering OWASP rules in our WAF).

Inside ../sitecore/shell/client/services/assets/lib I can see two beaconAPI related files

enter image description here

I have tried several different minification tools and I cannot seem to minify the vanilla beaconApi.js so that it matches the current minified file (there are fundamental differences and it is 7800+ lines long). Validating the javascript gives lots of warnings about missing semi-colons,etc so I'm a bit worried that the re-minification will introduce new issues.

Ignoring that issue - if I delete the beaconAPI.js and beaconAPI.min.js and upload my modified beaconAPI.js - when I hit this url I am expecting to see different content:

https://..mysite../bundle/beacon

But it doesn't change after I have updated the beaconApi.js file. I have tried clearing sitecore cache and browser cache, so I imagine there's another piece of the puzzle to regenerate this bundle.

In case it makes things clearer. I'm trying to take the pageUrl from the out of the box functionality and encrypt it. So was trying to intercept it in the getOptions function.

function getOptions(options) {
    var contact = cookies.get(extCookieName);
    var session = cookies.get(sessionCookieName);
    var pageUrl = getPage();
    var pageByteArr = str2ByteArr(pageUrl);
    pageUrl = arrayBufferToBase64(pageByteArr);

    var defaults = {
        contactId: contact || '',
        sessionId: session || '',
        page: pageUrl,
        referrer: global.document.referrer,
        rt: new Date().getTime()
    };

    return merge(defaults, options);
};

function str2ByteArr(str) {
    var bytes = [];

    for (var i = 0; i < str.length; ++i) {
        bytes.push(str.charCodeAt(i));
        bytes.push(0);
    }
    return bytes;
};

function arrayBufferToBase64(buffer) {
    var binary = '';
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
};

function getPage() {
    var fxmExternalDomainControl = document.getElementById("sc_fxm_externaldomain");
    if (!fxmExternalDomainControl) {
        return global.location.href;
    }

    var value = fxmExternalDomainControl.getAttribute("data-sc-value");
    if (!value || value == "") {
        console.warn("Couldn't retrieve external domain value, current domain will be used instead.");
        return global.location.href;
    }

    return replaceHost(value);
}
3

Looking at the Sitecore.FXM.Bundle.config shows that the beacon is constructed via a processor in the preprocessRequest pipeline:

  <preprocessRequest>
    <!-- **** Bundles registered when they are first requested **** -->
    <processor type="Sitecore.FXM.Pipelines.PreProcessRequest.HandleBundleRequest, Sitecore.FXM" resolve="true">
      <bundles hint="list">
        <!-- The FXM client javascript bundle - see registration pipeline below. It requires the current Sitecore instance host name
             when creating the bundle, so must be generated as part of a Sitecore request. -->
        <bundle>beacon</bundle>
      </bundles>
    </processor>
  </preprocessRequest>

That uses the bundle.beacon configuration to build the bundled file:

  <!-- **** Bundle Registration Pipelines **** -->
  <!--  Note: pipeline names must be prefixed with $(Bundle.PipelineNamePrefix) - see setting above. -->
  <bundle.beacon>
    <!-- Registers the FXM client Javascript bundle -->
    <processor type="Sitecore.FXM.Pipelines.Bundle.BundleFileProcessor, Sitecore.FXM" resolve="true">
      <paths hint="list:AddPath">
        <path>sitecore/shell/client/services/assets/lib/requireJsTurnOff.js</path>
        <path>sitecore/shell/client/services/assets/lib/beaconApi.js</path>
        <path>sitecore/shell/client/services/assets/lib/requireJsTurnOn.js</path>
      </paths>
    </processor>
    <processor type="Sitecore.FXM.Pipelines.Bundle.BeaconLoaderProcessor, Sitecore.FXM" resolve="true" />
  </bundle.beacon>

There are also some extra processors available for the bundle.beacon:

  <!-- Other bundle processors currently available for use. -->
  <!--<processor type="Sitecore.FXM.Pipelines.Bundle.BundleJsMinifyProcessor, Sitecore.FXM" />-->
  <!--<processor type="Sitecore.FXM.Pipelines.Bundle.BundleCssMinifyProcessor, Sitecore.FXM" />-->

To customize the bundle, rather than modify the beaconApi.js file directly, you could try creating a new js file and adding it to the paths section in the BundleFileProcessor.

From looking at the code, it looks like once a bundle is registered, it will just use the already built bundle. Although I can't find exactly where its storing/caching that. So you might need an application pool recycle for your new file/additions to be picked up.

  • Thanks. I'd love to just add a new file in - but I need to inject something into the GetOptions method to encrypt the pageUrl (I think). Unless there's some way in javascript to reliably do that (my knowledge is a bit rusty.. too much server side coding!) – Jen Aug 12 at 6:56
  • Have added in the code I'm trying to insert - in case its helpful. App recycle was the only thing I didn't try. Thanks for the suggestion. – Jen Aug 12 at 7:08
  • 1
    After restarting the app service I could see the change in the bundle file - thanks! – Jen Aug 13 at 1:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.