<!-- This HTML file showcases the integration of Hanko web components. Here are the features it offers: - Hanko Authentication Component: Allows users to authenticate using Hanko. It is represented by the <hanko-auth> tag. - Hanko Profile Component: Displays the user's profile information. It is represented by the <hanko-profile> tag. - Hanko Events Component: Handles various events related to authentication and session management. It is represented by the <hanko-events> tag. - Dialog Element: Presents a dialog to notify the user when a session is over for a certain reason. - Navbar: Includes a logout button and a dropdown menu for selecting the language. - Styling: Provides CSS styles for various elements, including the page, navigation bar, main content, buttons, and the Hanko web components. To use this HTML file, you need a running Hanko API instance configured to allow requests from the address under which this file is hosted. Additionally, the API URL needs to be entered in the designated location within the script block. The HTML file can be served through any HTTP server. The necessary scripts for the Hanko web components can be imported either from a local build or from the CDN. You can find more details and functionality explanations within the code comments. --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hanko Web Component Example</title> <style> /* Page Styling */ body { background-color: black; margin: 0; font-weight: 400; font-size: 14px; font-family: sans-serif; } /* Navigation Bar Styling */ nav { width: 100%; height: 3em; background-color: #01a7c1; display: flex; justify-content: flex-end; align-items: center; gap: 5px; padding: 10px; margin: 0 0 5rem; box-sizing: border-box; } /* Main Content Styling */ main { display: flex; justify-content: center; } /* Main Section Styling */ main section { min-width: 400px; } /* Button and Select Box Styling */ button, select { height: 1.5rem; } /* Hanko Web Components Styling */ .hankoComponent { /* Adjust the CSS variables related to color to create a dark theme for the web components. */ --color: #ccf8ff; --color-shade-1: #01a7c1; --color-shade-2: #546166; --brand-color: #fa00bb; --brand-color-shade-1: #ff2ecb; --brand-contrast-color: white; --link-color: #fac043; --background-color: black; --error-color: #fa0000; /* Slightly increase the border radius for elements within the web components. */ --border-radius: 5px; } .hankoComponent::part(headline1) { /* Adjust CSS properties for the main headlines using the "::part()" selector. */ font-size: 1.3em; font-weight: 400; } #hankoAuth { /* Limit the maximum width and increase the padding of the authentication component. */ --container-max-width: 400px; --container-padding: 25px; } #hankoAuth::part(headline1) { /* Center the main headlines within the authentication component. */ text-align: center; } #hankoAuth::part(container) { /* Add a border to the authentication component. */ border: solid 1px #546166; border-radius: 15px; } #hankoProfile { /* Adjust the profile component to be wider than the authentication component and have less padding. */ --container-max-width: 550px; --container-padding: 25px 10px 0; } </style> </head> <body> <!-- A dialog element to notify the user the session is over for a certain reason --> <dialog id="dialog"> <form> <div> <!-- The dialog message will be displayed here --> </div> <br> <button formmethod="dialog">Back to Login</button> </form> </dialog> <!-- Navbar --> <nav> <!-- Button for logging out --> <button id="logoutButton" hidden>Log out</button> <!-- Dropdown for selecting the language --> <select id="langSelect"> <option value="bn">Bengali</option> <option value="de">German</option> <option value="en" selected>English</option> <option value="fr">French</option> <option value="it">Italian</option> <option value="pt-BR">Brazilian Portuguese</option> <option value="zh">Chinese</option> </select> </nav> <!-- Main Content --> <main> <section> <!-- Hanko Authentication Component --> <hanko-auth id="hankoAuth" class="hankoComponent" lang="en"></hanko-auth> <!-- Hanko Profile Component --> <hanko-profile id="hankoProfile" class="hankoComponent" lang="en" hidden></hanko-profile> <!-- Hanko Events Component --> <hanko-events id="hankoEvents" class="hankoComponent"></hanko-events> </section> </main> <!-- The following script allows either the authentication component or the profile component to be displayed. When the session expires, a dialog appears to inform the user and provides a way to return to the authentication component. Here's a breakdown of what the script does: 1. Imports the necessary modules for Hanko Elements. You can choose to import from a local build or from the CDN by uncommenting the appropriate lines. 2. Registers the Hanko Web Components using the provided API URL and translations. 3. Retrieves DOM elements from the HTML file for further manipulation. 4. Adds event listeners for "onSessionCreated," "onAuthFlowCompleted," "onSessionExpired," "onUserLoggedOut," and "onUserDeleted" events, enabling control over which elements to display or hide based on the event triggers. 5. Adds a click event listener to the logout button to trigger the user logout process. 6. Adds a close event listener to the dialog element to show the authentication component once the dialog is closed. 7. Adds an input event listener to the language select element to update the language of the Hanko components. 8. Defines an initialization function that adds the event listeners, checks for a valid session, and determines whether to display the authentication or the profile component based on the session's validity. 9. Calls the initialization function to set up the integration. Please note that the "onAuthFlowCompleted" event should be handled in your own implementation (to customize the behavior after the user completes the authentication flow), while other events are optional to handle. --> <script type="module"> // Uncomment the following two lines if you want to import the local build, which can be created by changing to // the "/frontend" directory and running "npm run build:elements". // import {register} from "../dist/elements.js"; import {all} from "../dist/i18n/all.js"; // Comment the following two lines if you don't want to import Hanko Elements from the CDN, see comment above. // import {register} from "https://cdn.jsdelivr.net/npm/@teamhanko/hanko-elements/dist/elements.js"; // import {all} from "https://cdn.jsdelivr.net/npm/@teamhanko/hanko-elements/dist/i18n/all.js"; // Change `apiUrl` to the URL where your Hanko-API instance is running. const apiUrl = "http://localhost:8000"; // Register Hanko Web Components const {hanko} = await register(apiUrl, {translations: all, sessionCheckInterval: 5000}); // Get DOM elements const hankoAuthEl = document.getElementById("hankoAuth"), hankoProfileEl = document.getElementById("hankoProfile"), hankoEventsEl = document.getElementById("hankoEvents"), logoutButtonEl = document.getElementById("logoutButton"), langSelectEl = document.getElementById("langSelect"), dialogEl = document.getElementById("dialog"), dialogContentEl = dialogEl.getElementsByTagName("div").item(0); // Function to show or hide individual elements function setVisibility(element, visible) { element.hidden = !visible; } // Function to show the authentication component or the profile component function showAuthComponent(showAuth) { setVisibility(hankoAuthEl, showAuth); setVisibility(hankoProfileEl, !showAuth); } // Function to show the dialog element function showDialog(message) { dialogContentEl.innerText = message; dialogEl.showModal(); } // Function to change the language of the Hanko web components function selectLanguage(lang) { hankoAuthEl.lang = lang; hankoProfileEl.lang = lang; } // Function to add event listeners function addEventListeners() { hankoEventsEl.addEventListener("onSessionCreated", () => { // The user has completed the authentication flow through the hanko-auth component, so we can display the // hanko-profile and hide the hanko-auth component. showAuthComponent(false); // Show profile component setVisibility(logoutButtonEl, true); // Show the logout button // When the dialog was initially opened due to the session expiring in the past, and it has not been closed // manually before re-authentication taking place in another browser window, close the dialog automatically. if (dialogEl.open) { dialogEl.close(); // Close the dialog when it is still open and a new session was created } }); hankoEventsEl.addEventListener("onSessionExpired", () => { // The session has expired, so we can show the dialog to notify the user. Additionally, the logout button // can be hidden. showDialog("Your session has expired"); // Show message on the overlay dialog setVisibility(logoutButtonEl, false); // Hide the logout button }); hankoEventsEl.addEventListener("onUserLoggedOut", () => { // The user has logged out, so we show the hanko-auth component and hide the profile element as well as the // logout button. showAuthComponent(true); // Show authentication component setVisibility(logoutButtonEl, false); }); hankoEventsEl.addEventListener("onUserDeleted", () => { // The user has deleted the account, so we only show the dialog and hide the other elements. setVisibility(hankoProfileEl, false); setVisibility(logoutButtonEl, false); showDialog("Your account has been deleted"); }); logoutButtonEl.addEventListener("click", () => { // Logout the user, triggering the `onUserLoggedOut` event upon success. hanko.user.logout(); }); dialogEl.addEventListener('close', () => { // When the dialog, which informs the user that the session has expired, is closed, check if the session // has been created again, for example, in another browser window. If it has, there is no need to switch to // the hanko-auth component. if (!hanko.session.isValid()) { showAuthComponent(true); // Show authentication component } }); langSelectEl.addEventListener("input", (event) => { // If the user selects a different language from the language select box, update the language of the Hanko // components. selectLanguage(event.target.value); // The value is either "de", "en" or "fr" }); } // Initialization function async function init() { addEventListeners(); // Check if a valid session exists const session = await hanko.sessionClient.validate(); if (session.is_valid) { showAuthComponent(false); // Show profile component setVisibility(logoutButtonEl, true); // Show the logout button } // If the session is not valid, we don't need to do anything since the authentication component is already // visible and the profile component, as well as the logout button, have been hidden in the HTML code using the // "hidden" attribute. } // Call the initialization function await init(); </script> </body> </html>