opensupplyhub / open-apparel-registry

An application for searching, matching, uploading factories.
MIT License
32 stars 13 forks source link

Embedded Map Behavior for existing OAR users when OS Hub Launches #2088

Closed mariel-oar closed 1 year ago

mariel-oar commented 2 years ago

Overview

This ticket specifies requirements for how EMs should behave at the launch of OS Hub. There are two options:

(1) Update the EMs to have the look and feel of OS Hub, while making sure that issues with how the data is populated are avoided (see below in Additional Context related to EM behavior when EP was launched)

(2) Freeze EMs and continue to host them from the OAR - this option implies that the EMs are frozen between Oct 14, when OAR freezes, until we do a re-launch of EM in Q1 2023.

Describe the solution you'd like

Must-have Requirements:

  1. EM maps will continue to work as they do today with the same fields being displayed on the EM as the EM owner has configured
  2. EM maps will only show data points that the EM owner has contributed
  3. EM owners will not need to reconfigure their iframe code, or reconfigure it very minimally

Open Question / Nice to have:

  1. OS Hub branding / font / colors / etc.; OS Hub filter behavior but only the EMs data is populated in each field
  2. All existing EM owners are apparel brands, they should be assigned the value "Apparel" for sector (even in the case where they have contributed a product type)
  3. EM customers will have the ability to edit their map settings (e.g. turn on/off display of custom data points - this will include sector, which did not previously exist in the EM settings menu)

Additional Context

The only reason NOT to move forward with the OS Hub updates on EMs is to avoid issues. For example, when EP was released there were two issues with EMs: (1) all additional data points were displayed on the EMs, even if blank, and (2) additional data points contributed by other brands were showing up on the EM for a that brand. (E.g. if North Face contributed number of workers for a facility that Columbia was affiliated with, it showed up on the Columbia EM)

If the risk of issues cropping up is too great to add to the mix in the lead up to OS Hub launch, another option could be to: 1) Freeze the existing EM sites when the OAR site is frozen on/around Oct 14. i.e. do not redirect EMs to an opensupplyhub.org destination. 2) Don't allow EM customers to update their map data (as it will be frozen along with OAR)

Technical Implementation

QUESTION CloudFront Functions could be used to conditionally redirect based on the value of the embed query string argument. Determine if this is a preferable implementation to have Django middleware handle the redirect https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html ANSWER: It is possible and relatively straightforward to handle the redirect at CloudFront

~A suggested implementation filling the requirements as of 2022-08-24 and aligned with our plans to make OAR read-only as part of the transition to OS Hub~

jwalgran commented 2 years ago

I added a note to the "Technical Implementation" section to consider CloudFront Functions.

jwalgran commented 2 years ago

Here is a proof-of-concept CloudFront Function that allows embeds to continue working on OAR while redirecting other requests

// Adapted from https://devscope.io/code/aws-samples/amazon-cloudfront-functions/issues/11

function objectToQueryString(obj) {
    var str = [];
    for (var param in obj)
        if (obj[param].value === '') {
            str.push(encodeURIComponent(param));
        } else {
            // Normalize single and multiple value query params to a list of
            // param value objects
            var valueObjects = obj[param].multiValue || [obj[param]];
            var encodedValues = valueObjects.map(
                vo => `${encodeURIComponent(param)}=${encodeURIComponent(vo.value)}`);

            str.push(encodedValues.join('&'));
        }

    return str.join('&');
}

function handler(event) {
    console.log('Entering handler');
    var request = event.request;
    var uri = request.uri;

    // If this is an embed request, allow it to proceed to the ALB
    if (request.querystring.embed && request.querystring.embed.value === '1') {
        return request;
    }

    if (uri.substring(1, 5) === 'web/'
        || uri.substring(1, 5) === 'api/'
        || uri.substring(1, 19) === 'api-feature-flags/'
        || uri.substring(1, 10) === 'facvicon/'
        || uri.substring(1, 8) === 'images/'
        || uri.substring(1, 8) === 'static/'
       ) {
        if (request.headers.referer
            && request.headers.referer.value
            && request.headers.referer.value.substring(0, 32) ===
            'https://staging.openapparel.org/'){
            return request;
        }
    }

    // Redirect all other requests
    var location = '';
    var host = 'www.opensupplyhub.org';

    if (Object.keys(request.querystring).length > 0) {
        location = `https://${host}${uri}?${objectToQueryString(request.querystring)}`;    }
    else
        location = `https://${host}${uri}`;

    var response = {
        statusCode: 302,
        statusDescription: 'Found',
        headers: {
            'cloudfront-functions': { value: 'generated-by-CloudFront-Functions' },
            'location': { value: `${location}` }
        }
    };
    return response;
}