Lessonspace Docs

Embedding a Space

Embedding a space is a white labeled solution which will enable you to keep your current customer flow while taking full advantage of Lessonspace.

The Space can be embedded in an iframe. When embedding a Space it is important to think of who will have access to the iframe within your application.

For example when the Teacher logs in to your application the iframe src will need to be the client_url created when calling the Launch endpoint with the Teacher's user object; as with our scenrio in Creating Spaces.

Students or guest users who are using your application will also need to be presented with an iframe referencing the correct client_url in the src.

Be sure to set the allow attribute so that all features of the Space work correctly. You can copy and paste the snippet below and replace the src of the iframe tag with the client_url generated from the above launch endpoint.
<!DOCTYPE html>
<html lang="en" style="height:100%; font-family: sans-serif;">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <!--The line below is a requirement and will allow your iframe to resize with device-width-->
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Your Title Here</title>
</head>
<!--
    We're using body tag here but the principle of the recommendation
    is to place your content inside a viewport-sized container
    with a display: flex and flex-direction: column styles
-->
<body style="height:100%; width:100%; margin:0; box-sizing: border-box; display:flex; flex-direction: column;">
  <div style="background:#bada55; padding:1rem;">
    Dynamic Container App Content
  </div>

  <iframe
    id="myiframe"
    style="height: 100%; width: 100%;"
    src="CLIENT_URL_GOES_HERE"
    allow="camera; microphone; display-capture; autoplay"
    allowfullscreen="true"
    frameborder="0">
  </iframe>

</body>
</html>

External Authentication

Lessonspace does allow for external authentication through the use of a redirect to your internal authentication page or any other authentication flow you require.

Note
Session storage is used to store the validated token in redirect mode. If the user has session storage turned off in their browser, the lesson will go into a redirect loop. Private browsing modes such as Incognito have session storage disabled implicitly.

Redirect

The process for an external authentication flow with a redirect is as follows:

  1. You must add the auth_external object to the body of the Launch API POST request when Creating Spaces. This lets Lessonspace know that the client_url requires external authentication when loaded in your iframe.
  "auth_external": {
    "method": "redirect",
    "url": REDIRECT_URL_HERE,
    "token": UNIQUE_TOKEN
  }
  1. The client_url returned from the above request gets loaded, or assigned to an iframe in your application. When the Space loads, an automatic redirect to auth_external.url will take place.
  2. The redirect target will receive a querystring parameter named redirect_url. This is the URL that must be POSTed to at the end of the process. It will also receive a parameter named activity. This will have the value session or playback, depending on whether the auth flow is happening for an active session or a playback.
  3. Once the page specified by the auth_external.url has loaded, you can perform arbitrary opaque operations such as authenticating the user etc.
  4. Upon success, a form will need to be POSTed to the redirect_url given in step 2 above. This is the final hop of the redirect all the way back to Lessonspace.

The POST needs to provide this form value:

  • token This must match the token provided in the original auth_external object sent to Lessonspace when the join link was originally created.
Note
The token sent back from the auth flow is stored in cleartext in the browser during the session and can be modified by the user with minimal effort, so it should not contain secret information or something trivially guessable, nor should it be identical for all sessions. A HMAC of an internal value linked to the session is ideal.

Here is an example redirect handling page. This example does performs no authentication before POSTing:

    <script>
        const redirectUrl = (new URL(window.location)).searchParams.get('redirect_url')

        // Create a form, fill it with a token, and submit as a POST request
        const form = document.createElement('form')
        form.method = 'POST'
        form.action = redirectUrl
        form.enctype = 'application/x-www-form-urlencoded'
        form.style.display = 'none'
        document.body.appendChild(form)

        const token = document.createElement('input')
        token.type = 'text'
        token.name = 'token'
        token.value = 'this-is-a-static-token-for-example-purposes'
        form.appendChild(token)

        form.submit()
    </script>

If authentication fails (ie. the user gave invalid login details) you can return an invalid token and this will cause Lessonspace to show its own error page denying the user access. However, they will be prompted to reload and try again. If you prefer, you can also redirect to a failure page within your own environment.

Ephemeral mode

When redirection mode is in use, then by default, once the auth flow has successfully completed the first time, a value is stored in the browser's session storage to allow the user to refresh or otherwise reload their tab without having to re-authenticate. However, if you create a new join link after a refresh or reload, and if that new link uses a different authentication token, then the user's browser will contain an invalid token. The system will detect this token and send it to the server to auth with, but because the new link has a new token, the server will reject it. The browser will then flush that token, ensuring that on the next load it resends the latest token.

This can lead to behaviour where, after a refresh or reload, the user has to refresh again before the session will load correctly. If you expect to be generating new session links with unique authentication tokens each time the user re-attempts to join a session, then you likely do not want the auth token to be cached for the duration of the session.

You can send an additional parameter named ephemeral to tell the system not to cache the auth token. The auth flow will rerun every time the page is refreshed or otherwise reloaded.

  "auth_external": {
    "method": "redirect",
    "url": REDIRECT_URL_HERE,
    "token": UNIQUE_TOKEN,
    "ephemeral": true
  }

Playback authentication

You can also control access to playbacks using this system, by passing specific values in the querystring when calling the /v2/spaces/:space/:uuid/redirect endpoint using your API key. Playbacks and sessions are independently authenticated; a session that used external auth does not mean the playback will require it.

Note
While the playback URL is also returned as part of the Organisation Session List endpoint, the above endpoint must be used if the final playback link needs to use external authentication. Also note that this endpoint returns a HTTP 302 response; the target URL can be pulled from the Location header if the call is made from a non-browser environment.

The values to be provided are:

  • auth_external: the value of the auth method to use, eg redirect
  • url: the URL to be redirected to. This value must be correctly URL-encoded.
  • token: the auth token. This does not need to be the same as any value used when generating the original session link.

An example quersytring would thus be: ?auth_external=redirect&url=https%3A%2F%2Fwww.thelessonspace.com%2Fauth&token=my-special-token

The resulting playback link will initiate the same sort of authentication flow as is done during an equivalently-authenticated session, allowing you to fully secure playbacks.

Demo Space

If you are looking at using the API to integrate Lessonspace into your own application there's a good chance you will want to show off your fancy Spaces to your users. The Lessonspace API provides a simple endpoint that allows you to create your own demo Space that you can easily embed in an iframe.

Here's a simple example of embedding the demo Space in an iframe using some basic HTML and Javascript:

  <iframe
    id="lessonspaceDemo"
    frameborder="0"
    allow="camera; microphone; display-capture; fullscreen;"
    src="about:blank">
  </iframe>
  // Check if the demo room we have stored (if we have one) is
  // valid or get a new empty demo room
  var stored = localStorage.getItem('demoRoom');
  if (!stored || stored.indexOf('room.sh') === -1) {
    stored = null;
  }
  fetch("https://api.thelessonspace.com/v2/demo/", {
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({desired_room: stored})
  }).then(function (response) {
    response.json().then(function (j) {
        localStorage.setItem('demoRoom', j.url)
        document.getElementById("lessonspaceDemoiframe").src = j.url
    })
  });
Note
A demo Space is transient. This means that, unlike a normal Space created through the Launch API, it's state will only be saved for a few minutes after the end of the session. Do not expect data within transient Spaces to be saved reliably between separate invocations.