Embedded Settings Integration

Embed Scanifly Design Settings

Use this guide to embed Scanifly's chrome-less Design Settings screen in a
partner application. The iframe receives its authenticated session through a
postMessage handshake, so access tokens are not placed in a URL.

Requirements

  • Serve the parent application over HTTPS.
  • Obtain a valid Scanifly access-token JWT for the user before loading the
    iframe.
  • Use the exact Portal origin for the environment being embedded. For example,
    https://portal.scanifly.com

Embed URL

Create the iframe using the Portal origin and the Design Settings embed path:

<iframe
  id="scanifly-design-settings"
  src="https://portal.scanifly.com/embed/design-settings"
  title="Scanifly design settings"
  style="width: 100%; height: 80vh; border: 0"
></iframe>

Authentication handshake

After it mounts, the iframe posts a readiness message to its parent:

{ type: 'scanifly:embed-ready' }

The parent must verify that this message came from the expected Portal origin,
then send the access token directly to the iframe:

const portalOrigin = 'https://portal.scanifly.com';
const iframe = document.getElementById('scanifly-design-settings');

window.addEventListener('message', (event) => {
  if (event.origin !== portalOrigin) return;
  if (event.data?.type !== 'scanifly:embed-ready') return;
  if (!iframe?.contentWindow) return;

  iframe.contentWindow.postMessage(
    {
      type: 'scanifly:embed-auth',
      token: accessTokenJwt,
      // refreshToken: optionalRefreshToken,
    },
    portalOrigin,
  );
});

The iframe accepts an authentication message only from its direct parent and
requires a string token. It starts the authenticated Portal session from that
token and then renders Design Settings. If it does not receive a valid message
within 15 seconds, it displays an authentication error.

Security requirements

  • Do not put an access token in the iframe URL, query string, or fragment.
    URLs can be persisted in browser history, logs, and referrer headers.
  • Verify event.origin in the parent before responding to the readiness
    message.
  • Use the explicit Portal origin, rather than '*', as the targetOrigin for
    the token-bearing postMessage call.
  • Treat the token as a credential: never log it and do not forward it to other
    windows or frames.

Troubleshooting

  • The iframe remains on a spinner: confirm the parent received
    scanifly:embed-ready and sent scanifly:embed-auth to the same Portal
    origin used by the iframe URL.
  • The iframe shows an authentication error: confirm the JWT is valid and
    has not expired, and that the user can access the requested company.
  • The parent does not receive the readiness message: confirm the iframe was
    not blocked by the browser or a frame-ancestors / X-Frame-Options policy.