ToS Policy acceptance in New Universal Login

Problem statement

We want to migrate to new universal login but need to be GDPR compliant and offer our users a ToS and Policy acceptance checkboxes and deny access accordingly.

Solution

We’re announcing a supported way to do this in the short term for those customers who need this functionality now as a blocker for New UL adoption. Now you can get around this using page templates.

https://auth0.com/docs/customize/universal-login-pages/universal-login-page-templates

We have made a change adding a supported custom field element that can be used for this use case. This is a simple approach and comes with limitations.

You can add a Terms of Service/Privacy Policy section to the sign-up prompt using Page Templates. To use Page Templates, review the following guidelines:

  • All signup prompts contain a HTML element of <div id="custom-field-1"></div> at the end of the primary form. You may safely use DOM manipulation techniques on this element.

  • You may target the signUp prompt<form> elements in order to interrupt form submission, e.g. if a user hasn’t consented to the Terms of Service.

    • The username/password form has an attribute of data-form-primary.
    • Each federated connection form has an attribute of data-form-secondary.
  • You may target the submit <button> elements in order to disable or style them.

    • The primary button has an attribute of data-action-button-primary.
    • Federated connection buttons each have an attribute of data-action-button-secondary.

Limitations:

  • Since end-users could have JavaScript disabled, scripts inside a Page Template are not guaranteed to run. Do not depend on Page Template scripts for critical functionality.
  • Localization is not built in and you must embed your own localization. See Add Terms of Service and Privacy Policy Links.
  • You must custom-style any content you add to the prompt.

Examples

Example 1: Add Terms of Service and Privacy Policy Links

This example adds links to the customer’s Terms of Service and Privacy Policy. It leverages Liquid template language to conditionally render different text based on the current language.

<!DOCTYPE html>
<html>

<head>
    {%- auth0:head -%}

    <style>
        #custom-field-1 {
            margin-top: 5px;
        }
    </style>
</head>

<body>
    {%- auth0:widget -%}
</body>

<script>
    {% if prompt.name === 'signup' %}
    var customField = document.querySelector('#custom-field-1');
    if (customField) {
        {% if locale == "es" %}
        customField.innerHTML = 'Estoy de acuerdo con los <a href="https://example.com/tos">Términos y condiciones</a> y nuestra <a href="https://example.com/privacy">Política de Privacidad</a>';
        {% else %}
        customField.innerHTML = 'I accept the <a href="https://example.com/tos">Terms and Conditions</a> and <a href="https://example.com/privacy">Privacy Policy</a>';
        {% endif %}
    }
    {% endif %}
</script>

    </html>

Example 2: Add Terms of Service and Privacy Policy Links Requiring Explicit Consent

This example adds links to the customer’s Terms of Service and Privacy Policy and adds a required checkbox that must be selected before the user is allowed to continue, accomplished by disabling form submission by default and enabling it only if the button is checked. If an end user doesn’t have JavaScript enabled in their browser, the form will submit normally, and the custom links will not be shown.

<!DOCTYPE html>
<html>

<head>
    {%- auth0:head -%}

    <style>
        [data-action-button-primary]:disabled,
        [data-action-button-secondary]:disabled {
            background-color: #ccc;
            color: #444;
            pointer-events: none;
        }
    </style>
</head>

<body>
    {%- auth0:widget -%}
</body>

<script>
    {% if prompt.name === 'signup' %}
    function disableFormSubmitHandler(e) {
        e.preventDefault();
    }

    function disableSubmit() {
        document.querySelector('[data-form-primary]').addEventListener('submit', disableFormSubmitHandler)
        var secondaryForm = document.querySelector('[data-form-secondary]');
        if (secondaryForm) {
            secondaryForm.addEventListener('submit', disableFormSubmitHandler)
        }
        document.querySelector('[data-action-button-primary]').disabled = true;
        var secondaryButtonNodeList = document.querySelectorAll('[data-action-button-secondary]');
        for (var i = 0; i < secondaryButtonNodeList.length; i++) {
            secondaryButtonNodeList[i].disabled = true;
        }
    }

    function enableSubmit() {
        document.querySelector('[data-form-primary]').removeEventListener('submit', disableFormSubmitHandler)
        var secondaryForm = document.querySelector('[data-form-secondary]');
        if (secondaryForm) {
            secondaryForm.removeEventListener('submit', disableFormSubmitHandler)
        } document.querySelector('[data-action-button-primary]').disabled = false;
        var secondaryButtonNodeList = document.querySelectorAll('[data-action-button-secondary]');
        for (var i = 0; i < secondaryButtonNodeList.length; i++) {
            secondaryButtonNodeList[i].disabled = false;
        }
    }

    var customField = document.querySelector('#custom-field-1');
    if (customField) {
        disableSubmit();
        var customContent = "\n    <input id=\"terms-and-policies\" name=\"terms-and-policies\" type=\"checkbox\" required>\n    <label for=\"terms-and-policies\">\n        I accept the <a href=\"https://example.com/tos\">Terms and Conditions</a> and <a href=\"https://example.com/privacy\">Privacy Policy</a>\n    </label>";
        customField.innerHTML = customContent;
        var checkbox = customField.querySelector('input[name="terms-and-policies"]')
        checkbox.addEventListener('change', function(e) { e.currentTarget.checked ? enableSubmit() : disableSubmit() });
    }
    {% endif %}
</script>

</html>
3 Likes