@foreverholdings/convo-bootstrapdeprecated

This the bootstrap code to embed a convo into a page.

Usage no npm install needed!

<script type="module">
  import foreverholdingsConvoBootstrap from 'https://cdn.skypack.dev/@foreverholdings/convo-bootstrap';
</script>

README

@foreverholdings/convo-bootstrap

This the bootstrap code to embed a convo into a page.

It has a couple of responsibilities

  • Add convo embed to page
  • Resize <convo> containing element
    • Full screen
    • Full viewport
    • Controls to revert to regular size

Add convo embed to page

When the script runs, it turns

<convo>
  <a href="https://convo.example.com/view/the-owls-are-not-what-they-seem">
    View the experience
  </a>
  <script src="https://unpkg.com/@foreverholdings/convo-bootstrap/umd/cb.min.js"></script>
</convo>

into

<convo>
  <iframe src="https://convo.example.com/iframe?id=the-owls-are-not-what-they-seem"></iframe>
</convo>

Resize <convo> containing element

When the user starts the conversation, the experience should move to either fullscreen or full viewport.

This will be achieved by using the postMessage API. convo-bootstrap will be responsible for setting styles on the <convo> element, to achieve this and to use the Fullscren API when supported.

Security concerns

Some integrators will have concerns over including third party scripts in their pages.

The fundamental concern is that adding a third party script to the page will give the script full access to web storage (cookies, localStorage, IndexedDB, etc) and can steal user information or even impersonate users.

These are very valid concerns, which is why you never see third party scripts in e-commerce checkout, login pages for banks, etc.

To address these concerns, we will do a few things:

  • Publish convo-bootstrap to the public npm registry
    • This allows integrators to lock to a specific version (that they have reviewed) and make use of Subresource Integrity to ensure that only that very version can be loaded by browsers.
    • Encourage integrators to load the file from unpkg, which is on Cloudflare's CDN
  • Publish annotated source of convo-bootstrap on a web page (not with an open license), so integrators can review it. The annotations will explain exactly what each part of the script does
  • Create a Caja build of the library, so it's clear that the script is unable to do bad things
  • Create an integrator's guide, that shows how to load a known version and how to calculate the SRI hash using https://www.srihash.org or fetching it from unpkg via the ?meta query parameter

This should remove any reservations integrators might have about including convo-bootstrap script in their web pages.

See:

Locked version example

<convo>
  <a href="https://convo.example.com/view/the-owls-are-not-what-they-seem">
    View the experience
  </a>
  <script
    <!-- load a specific version -->
    src="https://unpkg.com/@foreverholdings/convo-bootstrap@16.7.0/umd/cb.min.js"
    <!-- use Subresource Integrity -->
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
    <!-- browser rejects failed hashes and send no credentials -->
    crossorigin="anonymous"></script>
</convo>

Why do I need to include crossorigin="anonymous"?

When the request is not on the same origin the crossorigin attribute must be present to check the integrity of the file. Without a crossorigin attribute, the browser will choose to 'fail-open' which means it will load the resource as if the integrity attribute was not set, effectively losing all the security SRI brings in the first place. crossorigin="anonymous" ensures that no credentials are sent to the cross-origin site hosting the content. However, it will send an Origin HTTP header. If the server denies including the resource (by not setting the Access-Control-Allow-Origin HTTP header), the resource will not be used by the browser.

From https://www.srihash.org

Local setup

  1. npm ci
  2. npm start
  3. open http://localhost:8080
  4. Open the JavaScript console
  5. Click the button
  6. Observe the action in the console
  7. Turn JavaScript off in the browser
  8. Reload the page
  9. Observe that the link remains visible
  10. 🦉