# Internal Developer Guide - OIL Documentation

## Development (internal developer guide)

### Quick Links

Jira: https://id-jira.axelspringer.de/browse/OIL

Jenkins: https://kube-jenkins.ipool.asideas.de/view/OIL%20Project/

Overview: https://www.oiljs.org

### Hub Deployment

To deploy the hub you need to deploy the project with an index.html loading the hub.[version].min.js

For compatibility with Internet Explorer 9+ you need to add the following header to the server response to allow 3rd party cookies for POI.

      "p3p": "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"",

### Tealium Deployment

For our PoC we decided to use Tealium to deliver our Javascript artefact to client browsers. To achieve this you have to follow some steps:

As a developer of Oil.js (see image below)

- Open your Tealium lib profile and move to extensions

- Open the predefined Javascript extension "AS Opt-in Overlay"

- Some forms will show up, paste your code (release/oil.[version].min.js) in the "configuration" section

- Save and publish your Tealium configuration changes to your desired stages (Dev, QA, Prod)

Please note that once published, your code will be delivered to all Tealium clients automatically. Tealium clients will be informed of your changes and need to publish/deploy their profile to activate your changes.

### Locale configuration

Texts and labels shown by the Opt-In Layer are provided by the OIL Backend. This server application uses a PostgreSQL database to store texts and labels for different languages and variants. A REST service is provided that allows to request them and to add new ones.

The REST service documentation can be found here: https://oil-backend.herokuapp.com/oil/swagger-ui.html

Note: Adding new languages and variants is allowed for authorized users only.

### FYI: Cross-Origin Messaging

The `postMessage()` method lifts this restriction by providing a way to securely pass messages across domains. The `postMessage()` method accepts two parameters.

- `message` – A string or object that will be sent to the receiving window.

- `targetOrigin` – The URL of the window that the message is being sent to. The protocol, port and hostname of the target window must match this parameter for the message to be sent. Specifying `"*"` will match any URL however this is strongly discouraged for security reasons. This method should be called on the window that the message is being sent to. A reference to the target window can be obtained in a number of different ways:

- When using `window.open()` a reference to the new window will be returned by the `open()` method.

- For iframes you can access the `contentWindow` property on the desired iframe.

When a call to `postMessage()` is executed successfully a `MessageEvent` will be fired on the receiving window. You can use a standard event listener to watch for this event and execute some code when it occurs.

The event passed into the listener callback has a property called `data` that can be used to access the string or object that was sent by `postMessage()`.

So on the OIL hub side an event listener is added:

    window.addEventListener('message', (e) => {
      let data = e.data;
      if (parsedMessage) {
        if (parsedMessage.event && parsedMessage.event.indexOf('oil-') !== -1) {

          let event = parsedMessage.event,
            origin = parsedMessage.origin,
            payload = parsedMessage.payload,
            groupName = parsedMessage.group_name;

          switch (event) {
            case 'oil-poi-activate':
              logInfo('OIL Hub - activating POI ');
              logInfo('Using groupName:', groupName);
              logInfo('Using payload:', JSON.stringify(payload));
              setPoiCookie(groupName, payload);
              break;
            case 'oil-status-read':
              getPoiCookie(groupName).then( (poiOptin) => {
                logInfo('OIL Hub - read the following poi status:', poiOptin.power_opt_in);
                parent.postMessage(JSON.stringify(poiOptin) || false, origin);
              });
              break;
            case 'oil-poi-delete':
              logInfo('OIL Hub - remove POI cookie.');
              removeHubCookie(groupName);
              break;
            default:
              break;
          }
        }
    });

At the subscriber side the `postMessage` happens to trigger an action on the hub:

          // see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#Syntax
          // MSIE needs Strings in postMessage
          let message = JSON.stringify({ event: eventName, origin: origin, group_name: groupName, payload: payload });
          iframe.contentWindow.postMessage(message, hubDomain);

Now the subscriber can listen to messages from the hub:

    window.addEventListener('message', (event) => {
          // only listen to our hub
          let hubOrigin = getHubOrigin();
          if (hubOrigin && hubOrigin.indexOf(event.origin) !== -1) {
            let message;
            if(!checkJsonParse(event.data)) {
              message = event.data;
            } else {
              message = typeof event.data !== 'object' ? JSON.parse(event.data) : event.data;
            }
            logInfo('Message from hub received...', event.origin, message);
            removeMessageListener(handler);
            frameListenerRegistered = false;
            resolve(message);
          }
    });